blob: 6ea289738e0ff03c9034eae379544eb2616449ac [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
34template <typename T> class SkRefCntTDArray : public SkTDArray<T> {
35public:
36 ~SkRefCntTDArray() { this->unrefAll(); }
37};
reed@google.combb6992a2011-04-26 17:41:56 +000038
39class SkGPipeState {
40public:
41 SkGPipeState();
42 ~SkGPipeState();
reed@google.combb6793b2011-05-05 15:18:15 +000043
44 void setReader(SkFlattenableReadBuffer* reader) { fReader = reader; }
45
reed@google.combb6992a2011-04-26 17:41:56 +000046 const SkPaint& getPaint(uint32_t drawOp32) const;
47
48 // Extracts index from DrawOp_unpackData().
49 // Returns the specified paint from our list, or creates a new paint if
50 // index == count. If index > count, return NULL
51 SkPaint* editPaint(uint32_t drawOp32);
reed@google.comf5842f72011-05-04 18:30:04 +000052
reed@google.combb6793b2011-05-05 15:18:15 +000053 void addTypeface() {
54 size_t size = fReader->readU32();
55 const void* data = fReader->skip(SkAlign4(size));
reed@google.comf5842f72011-05-04 18:30:04 +000056 SkMemoryStream stream(data, size, false);
reed@google.comf5842f72011-05-04 18:30:04 +000057 *fTypefaces.append() = SkTypeface::Deserialize(&stream);
58 }
reed@google.combb6793b2011-05-05 15:18:15 +000059 void addColorFilter() {
60 *fColorFilters.append() = (SkColorFilter*)fReader->readFlattenable();
61 }
62 void addDrawLooper() {
63 *fDrawLoopers.append() = (SkDrawLooper*)fReader->readFlattenable();
64 }
65 void addMaskFilter() {
66 *fMaskFilters.append() = (SkMaskFilter*)fReader->readFlattenable();
67 }
68 void addPathEffect() {
69 *fPathEffects.append() = (SkPathEffect*)fReader->readFlattenable();
70 }
71 void addRasterizer() {
72 *fRasterizers.append() = (SkRasterizer*)fReader->readFlattenable();
73 }
74 void addShader() {
75 *fShaders.append() = (SkShader*)fReader->readFlattenable();
76 }
77 void addXfermode() {
78 *fXfermodes.append() = (SkXfermode*)fReader->readFlattenable();
79 }
80
81 void setColorFilter(SkPaint* paint, unsigned id) {
82 paint->setColorFilter(id ? fColorFilters[id - 1] : NULL);
83 }
84 void setLooper(SkPaint* paint, unsigned id) {
85 paint->setLooper(id ? fDrawLoopers[id - 1] : NULL);
86 }
87 void setMaskFilter(SkPaint* paint, unsigned id) {
88 paint->setMaskFilter(id ? fMaskFilters[id - 1] : NULL);
89 }
90 void setPathEffect(SkPaint* paint, unsigned id) {
91 paint->setPathEffect(id ? fPathEffects[id - 1] : NULL);
92 }
93 void setRasterizer(SkPaint* paint, unsigned id) {
94 paint->setRasterizer(id ? fRasterizers[id - 1] : NULL);
95 }
96 void setShader(SkPaint* paint, unsigned id) {
97 paint->setShader(id ? fShaders[id - 1] : NULL);
98 }
99 void setTypeface(SkPaint* paint, unsigned id) {
100 paint->setTypeface(id ? fTypefaces[id - 1] : NULL);
101 }
102 void setXfermode(SkPaint* paint, unsigned id) {
103 paint->setXfermode(id ? fXfermodes[id - 1] : NULL);
104 }
105
reed@google.combb6992a2011-04-26 17:41:56 +0000106private:
reed@google.combb6793b2011-05-05 15:18:15 +0000107 SkFlattenableReadBuffer* fReader;
108
reed@google.combb6992a2011-04-26 17:41:56 +0000109 SkTDArray<SkPaint*> fPaints;
reed@google.combb6793b2011-05-05 15:18:15 +0000110
111 SkRefCntTDArray<SkColorFilter*> fColorFilters;
112 SkRefCntTDArray<SkDrawLooper*> fDrawLoopers;
113 SkRefCntTDArray<SkMaskFilter*> fMaskFilters;
114 SkRefCntTDArray<SkPathEffect*> fPathEffects;
115 SkRefCntTDArray<SkRasterizer*> fRasterizers;
116 SkRefCntTDArray<SkShader*> fShaders;
117 SkRefCntTDArray<SkTypeface*> fTypefaces;
118 SkRefCntTDArray<SkXfermode*> fXfermodes;
reed@google.combb6992a2011-04-26 17:41:56 +0000119};
120
121///////////////////////////////////////////////////////////////////////////////
122
123template <typename T> const T* skip(SkReader32* reader, int count = 1) {
124 SkASSERT(count >= 0);
125 size_t size = sizeof(T) * count;
126 SkASSERT(SkAlign4(size) == size);
127 return reinterpret_cast<const T*>(reader->skip(size));
128}
129
130template <typename T> const T* skipAlign(SkReader32* reader, int count = 1) {
131 SkASSERT(count >= 0);
132 size_t size = SkAlign4(sizeof(T) * count);
133 return reinterpret_cast<const T*>(reader->skip(size));
134}
135
136static void readRegion(SkReader32* reader, SkRegion* rgn) {
137 size_t size = rgn->unflatten(reader->peek());
138 SkASSERT(SkAlign4(size) == size);
139 (void)reader->skip(size);
140}
141
142static void readMatrix(SkReader32* reader, SkMatrix* matrix) {
143 size_t size = matrix->unflatten(reader->peek());
144 SkASSERT(SkAlign4(size) == size);
145 (void)reader->skip(size);
146}
147
148const SkPaint& SkGPipeState::getPaint(uint32_t op32) const {
149 unsigned index = DrawOp_unpackData(op32);
150 if (index >= fPaints.count()) {
151 SkASSERT(!"paint index out of range");
152 index = 0; // we always have at least 1 paint
153 }
154 return *fPaints[index];
155}
156
157SkPaint* SkGPipeState::editPaint(uint32_t op32) {
158 unsigned index = DrawOp_unpackData(op32);
159
160 if (index > fPaints.count()) {
161 SkASSERT(!"paint index out of range");
162 return NULL;
163 }
164
165 if (index == fPaints.count()) {
166 *fPaints.append() = SkNEW(SkPaint);
167 }
168 return fPaints[index];
169}
170
171///////////////////////////////////////////////////////////////////////////////
172///////////////////////////////////////////////////////////////////////////////
173
174static void clipPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
175 SkGPipeState* state) {
176 SkPath path;
177 path.unflatten(*reader);
178 canvas->clipPath(path, (SkRegion::Op)DrawOp_unpackData(op32));
179}
180
181static void clipRegion_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
182 SkGPipeState* state) {
183 SkRegion rgn;
184 readRegion(reader, &rgn);
185 canvas->clipRegion(rgn, (SkRegion::Op)DrawOp_unpackData(op32));
186}
187
188static void clipRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
189 SkGPipeState* state) {
190 canvas->clipRect(*skip<SkRect>(reader), (SkRegion::Op)DrawOp_unpackData(op32));
191}
192
193///////////////////////////////////////////////////////////////////////////////
194
195static void setMatrix_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
196 SkGPipeState* state) {
197 SkMatrix matrix;
198 readMatrix(reader, &matrix);
199 canvas->setMatrix(matrix);
200}
201
202static void concat_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
203 SkGPipeState* state) {
204 SkMatrix matrix;
205 readMatrix(reader, &matrix);
206 canvas->concat(matrix);
207}
208
209static void scale_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
210 SkGPipeState* state) {
211 const SkScalar* param = skip<SkScalar>(reader, 2);
212 canvas->scale(param[0], param[1]);
213}
214
215static void skew_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
216 SkGPipeState* state) {
217 const SkScalar* param = skip<SkScalar>(reader, 2);
218 canvas->skew(param[0], param[1]);
219}
220
221static void rotate_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
222 SkGPipeState* state) {
223 canvas->rotate(reader->readScalar());
224}
225
226static void translate_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
227 SkGPipeState* state) {
228 const SkScalar* param = skip<SkScalar>(reader, 2);
229 canvas->translate(param[0], param[1]);
230}
231
232///////////////////////////////////////////////////////////////////////////////
233
234static void save_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
235 SkGPipeState* state) {
236 canvas->save((SkCanvas::SaveFlags)DrawOp_unpackData(op32));
237}
238
239static void saveLayer_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
240 SkGPipeState* state) {
reed@google.comacd471f2011-05-03 21:26:46 +0000241 unsigned flags = DrawOp_unpackFlags(op32);
242 SkCanvas::SaveFlags saveFlags = (SkCanvas::SaveFlags)DrawOp_unpackData(op32);
reed@google.combb6992a2011-04-26 17:41:56 +0000243
244 const SkRect* bounds = NULL;
245 if (flags & kSaveLayer_HasBounds_DrawOpFlag) {
246 bounds = skip<SkRect>(reader);
247 }
248 const SkPaint* paint = NULL;
249 if (flags & kSaveLayer_HasPaint_DrawOpFlag) {
250 paint = &state->getPaint(reader->readU32());
251 }
reed@google.comacd471f2011-05-03 21:26:46 +0000252 canvas->saveLayer(bounds, paint, saveFlags);
reed@google.combb6992a2011-04-26 17:41:56 +0000253}
254
255static void restore_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
256 SkGPipeState* state) {
257 canvas->restore();
258}
259
260///////////////////////////////////////////////////////////////////////////////
261
262static void drawClear_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
263 SkGPipeState* state) {
264 SkColor color = 0;
265 if (DrawOp_unpackFlags(op32) & kClear_HasColor_DrawOpFlag) {
266 color = reader->readU32();
267 }
268 canvas->clear(color);
269}
270
271static void drawPaint_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
272 SkGPipeState* state) {
273 canvas->drawPaint(state->getPaint(op32));
274}
275
276static void drawPoints_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
277 SkGPipeState* state) {
278 SkCanvas::PointMode mode = (SkCanvas::PointMode)DrawOp_unpackFlags(op32);
279 size_t count = reader->readU32();
280 const SkPoint* pts = skip<SkPoint>(reader, count);
281 canvas->drawPoints(mode, count, pts, state->getPaint(op32));
282}
283
284static void drawRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
285 SkGPipeState* state) {
286 canvas->drawRect(*skip<SkRect>(reader), state->getPaint(op32));
287}
288
289static void drawPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
290 SkGPipeState* state) {
291 SkPath path;
292 path.unflatten(*reader);
293 canvas->drawPath(path, state->getPaint(op32));
294}
295
296static void drawVertices_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
297 SkGPipeState* state) {
298 unsigned flags = DrawOp_unpackFlags(op32);
299
300 SkCanvas::VertexMode mode = (SkCanvas::VertexMode)reader->readU32();
301 int vertexCount = reader->readU32();
302 const SkPoint* verts = skip<SkPoint>(reader, vertexCount);
303
304 const SkPoint* texs = NULL;
305 if (flags & kDrawVertices_HasTexs_DrawOpFlag) {
306 texs = skip<SkPoint>(reader, vertexCount);
307 }
308
309 const SkColor* colors = NULL;
310 if (flags & kDrawVertices_HasColors_DrawOpFlag) {
311 colors = skip<SkColor>(reader, vertexCount);
312 }
313
314 // TODO: flatten/unflatten xfermodes
315 SkXfermode* xfer = NULL;
316
317 int indexCount = 0;
318 const uint16_t* indices = NULL;
319 if (flags & kDrawVertices_HasIndices_DrawOpFlag) {
320 indexCount = reader->readU32();
321 indices = skipAlign<uint16_t>(reader, indexCount);
322 }
323
324 canvas->drawVertices(mode, vertexCount, verts, texs, colors, xfer,
325 indices, indexCount, state->getPaint(op32));
326}
327
328///////////////////////////////////////////////////////////////////////////////
329
330static void drawText_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
331 SkGPipeState* state) {
332 size_t len = reader->readU32();
333 const void* text = reader->skip(SkAlign4(len));
334 const SkScalar* xy = skip<SkScalar>(reader, 2);
335 canvas->drawText(text, len, xy[0], xy[1], state->getPaint(op32));
336}
337
338static void drawPosText_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
339 SkGPipeState* state) {
340 size_t len = reader->readU32();
341 const void* text = reader->skip(SkAlign4(len));
342 size_t posCount = reader->readU32(); // compute by our writer
343 const SkPoint* pos = skip<SkPoint>(reader, posCount);
344 canvas->drawPosText(text, len, pos, state->getPaint(op32));
345}
346
347static void drawPosTextH_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
348 SkGPipeState* state) {
349 size_t len = reader->readU32();
350 const void* text = reader->skip(SkAlign4(len));
351 size_t posCount = reader->readU32(); // compute by our writer
352 const SkScalar* xpos = skip<SkScalar>(reader, posCount);
353 SkScalar constY = reader->readScalar();
354 canvas->drawPosTextH(text, len, xpos, constY, state->getPaint(op32));
355}
356
357static void drawTextOnPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
358 SkGPipeState* state) {
359 size_t len = reader->readU32();
360 const void* text = reader->skip(SkAlign4(len));
361
362 SkPath path;
363 path.unflatten(*reader);
364
365 SkMatrix matrixStorage;
366 const SkMatrix* matrix = NULL;
367 if (DrawOp_unpackFlags(op32) & kDrawTextOnPath_HasMatrix_DrawOpFlag) {
368 readMatrix(reader, &matrixStorage);
369 matrix = &matrixStorage;
370 }
371
372 canvas->drawTextOnPath(text, len, path, matrix, state->getPaint(op32));
373}
374
375///////////////////////////////////////////////////////////////////////////////
376
377static void drawBitmap_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
378 SkGPipeState* state) {
379 UNIMPLEMENTED
380}
381
382static void drawBitmapMatrix_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
383 SkGPipeState* state) {
384 UNIMPLEMENTED
385}
386
387static void drawBitmapRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
388 SkGPipeState* state) {
389 UNIMPLEMENTED
390}
391
392static void drawSprite_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
393 SkGPipeState* state) {
394 UNIMPLEMENTED
395}
396
397///////////////////////////////////////////////////////////////////////////////
398
399static void drawData_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
400 SkGPipeState* state) {
401 // since we don't have a paint, we can use data for our (small) sizes
402 size_t size = DrawOp_unpackData(op32);
403 if (0 == size) {
404 size = reader->readU32();
405 }
406 const void* data = reader->skip(SkAlign4(size));
407 canvas->drawData(data, size);
408}
409
410static void drawShape_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
411 SkGPipeState* state) {
412 UNIMPLEMENTED
413}
414
415static void drawPicture_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
416 SkGPipeState* state) {
417 UNIMPLEMENTED
418}
419
420///////////////////////////////////////////////////////////////////////////////
421
reed@google.combb6992a2011-04-26 17:41:56 +0000422static void paintOp_rp(SkCanvas*, SkReader32* reader, uint32_t op32,
423 SkGPipeState* state) {
424 SkPaint* p = state->editPaint(op32);
425 int done;
426
427 do {
428 uint32_t p32 = reader->readU32();
429 unsigned op = PaintOp_unpackOp(p32);
430 unsigned data = PaintOp_unpackData(p32);
431 done = PaintOp_unpackFlags(p32) & kLastOp_PaintOpFlag;
432
433 SkDebugf(" read %08X op=%d flags=%d data=%d\n", p32, op, done, data);
434
435 switch (op) {
436 case kReset_PaintOp: p->reset(); break;
437 case kFlags_PaintOp: p->setFlags(data); break;
438 case kColor_PaintOp: p->setColor(reader->readU32()); break;
439 case kStyle_PaintOp: p->setStyle((SkPaint::Style)data); break;
440 case kJoin_PaintOp: p->setStrokeJoin((SkPaint::Join)data); break;
441 case kCap_PaintOp: p->setStrokeCap((SkPaint::Cap)data); break;
442 case kWidth_PaintOp: p->setStrokeWidth(reader->readScalar()); break;
443 case kMiter_PaintOp: p->setStrokeMiter(reader->readScalar()); break;
444 case kEncoding_PaintOp:
445 p->setTextEncoding((SkPaint::TextEncoding)data);
446 break;
447 case kHinting_PaintOp: p->setHinting((SkPaint::Hinting)data); break;
448 case kAlign_PaintOp: p->setTextAlign((SkPaint::Align)data); break;
449 case kTextSize_PaintOp: p->setTextSize(reader->readScalar()); break;
450 case kTextScaleX_PaintOp: p->setTextScaleX(reader->readScalar()); break;
451 case kTextSkewX_PaintOp: p->setTextSkewX(reader->readScalar()); break;
reed@google.combb6793b2011-05-05 15:18:15 +0000452
453 case kTypeface_PaintOp: state->setTypeface(p, data); break;
454 case kPathEffect_PaintOp: state->setPathEffect(p, data); break;
455 case kShader_PaintOp: state->setShader(p, data); break;
456 case kXfermode_PaintOp: state->setXfermode(p, data); break;
457 case kMaskFilter_PaintOp: state->setMaskFilter(p, data); break;
458 case kColorFilter_PaintOp: state->setColorFilter(p, data); break;
459 case kRasterizer_PaintOp: state->setRasterizer(p, data); break;
460 case kDrawLooper_PaintOp: state->setLooper(p, data); break;
reed@google.combb6992a2011-04-26 17:41:56 +0000461 default: SkASSERT(!"bad paintop"); return;
462 }
463 } while (!done);
464}
465
reed@google.combb6793b2011-05-05 15:18:15 +0000466///////////////////////////////////////////////////////////////////////////////
467
468static void def_ColorFilter_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState* state) {
469 state->addColorFilter();
470}
471
472static void def_DrawLooper_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState* state) {
473 state->addDrawLooper();
474}
475
476static void def_MaskFilter_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState* state) {
477 state->addMaskFilter();
478}
479
480static void def_PathEffect_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState* state) {
481 state->addPathEffect();
482}
483
484static void def_Rasterizer_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState* state) {
485 state->addRasterizer();
486}
487
488static void def_Shader_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState* state) {
489 state->addShader();
490}
491
492static void def_Typeface_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState* state) {
493 state->addTypeface();
494}
495
496static void def_Xfermode_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState* state) {
497 state->addXfermode();
reed@google.comf5842f72011-05-04 18:30:04 +0000498}
499
reed@google.combb6992a2011-04-26 17:41:56 +0000500///////////////////////////////////////////////////////////////////////////////
501
reed@google.comacd471f2011-05-03 21:26:46 +0000502static void skip_rp(SkCanvas*, SkReader32* reader, uint32_t op32, SkGPipeState*) {
503 size_t bytes = DrawOp_unpackData(op32);
504 (void)reader->skip(bytes);
505}
506
reed@google.combb6992a2011-04-26 17:41:56 +0000507static void done_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState*) {}
508
509typedef void (*ReadProc)(SkCanvas*, SkReader32*, uint32_t op32, SkGPipeState*);
510
511static const ReadProc gReadTable[] = {
reed@google.comacd471f2011-05-03 21:26:46 +0000512 skip_rp,
reed@google.combb6992a2011-04-26 17:41:56 +0000513 clipPath_rp,
514 clipRegion_rp,
515 clipRect_rp,
516 concat_rp,
517 drawBitmap_rp,
518 drawBitmapMatrix_rp,
519 drawBitmapRect_rp,
520 drawClear_rp,
521 drawData_rp,
522 drawPaint_rp,
523 drawPath_rp,
524 drawPicture_rp,
525 drawPoints_rp,
526 drawPosText_rp,
527 drawPosTextH_rp,
528 drawRect_rp,
529 drawShape_rp,
530 drawSprite_rp,
531 drawText_rp,
532 drawTextOnPath_rp,
533 drawVertices_rp,
534 restore_rp,
535 rotate_rp,
536 save_rp,
537 saveLayer_rp,
538 scale_rp,
539 setMatrix_rp,
540 skew_rp,
541 translate_rp,
542 paintOp_rp,
reed@google.combb6793b2011-05-05 15:18:15 +0000543 def_ColorFilter_rp,
544 def_DrawLooper_rp,
545 def_MaskFilter_rp,
546 def_PathEffect_rp,
547 def_Rasterizer_rp,
548 def_Shader_rp,
549 def_Typeface_rp,
550 def_Xfermode_rp,
reed@google.combb6992a2011-04-26 17:41:56 +0000551 done_rp
552};
553
554///////////////////////////////////////////////////////////////////////////////
555
556SkGPipeState::SkGPipeState() {
557 // start out with one paint in default state
558 *fPaints.append() = SkNEW(SkPaint);
559}
560
reed@google.combb6793b2011-05-05 15:18:15 +0000561SkGPipeState::~SkGPipeState() {
reed@google.combb6992a2011-04-26 17:41:56 +0000562 fPaints.deleteAll();
563}
564
565///////////////////////////////////////////////////////////////////////////////
566
567#include "SkGPipe.h"
568
569SkGPipeReader::SkGPipeReader(SkCanvas* target) {
570 SkSafeRef(target);
571 fCanvas = target;
572 fState = NULL;
573}
574
575SkGPipeReader::~SkGPipeReader() {
576 SkSafeUnref(fCanvas);
577 delete fState;
578}
579
580SkGPipeReader::Status SkGPipeReader::playback(const void* data, size_t length) {
581 if (NULL == fCanvas) {
582 return kError_Status;
583 }
584
585 if (NULL == fState) {
586 fState = new SkGPipeState;
587 }
588
589 const ReadProc* table = gReadTable;
reed@google.combb6793b2011-05-05 15:18:15 +0000590 SkFlattenableReadBuffer reader(data, length);
reed@google.combb6992a2011-04-26 17:41:56 +0000591 SkCanvas* canvas = fCanvas;
reed@google.combb6793b2011-05-05 15:18:15 +0000592
593 fState->setReader(&reader);
reed@google.combb6992a2011-04-26 17:41:56 +0000594 while (!reader.eof()) {
595 uint32_t op32 = reader.readU32();
596 unsigned op = DrawOp_unpackOp(op32);
reed@google.combb6793b2011-05-05 15:18:15 +0000597 SkDEBUGCODE(DrawOps drawOp = (DrawOps)op;)
reed@google.combb6992a2011-04-26 17:41:56 +0000598
599 if (op >= SK_ARRAY_COUNT(gReadTable)) {
600 SkDebugf("---- bad op during GPipeState::playback\n");
601 return kError_Status;
602 }
603 if (kDone_DrawOp == op) {
604 return kDone_Status;
605 }
606 table[op](canvas, &reader, op32, fState);
607 }
608 return kEOF_Status;
609}
610
611