blob: fb0fbc497e70147e958745e67700feb0c8b8c694 [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
reed@google.comdde09562011-05-23 12:21:05 +000073 void setReader(SkFlattenableReadBuffer* reader) {
74 fReader = reader;
reed@google.com6bac9472011-06-21 19:24:00 +000075 fReader->setFactoryArray(&fFactoryArray);
reed@google.comdde09562011-05-23 12:21:05 +000076 }
reed@google.combb6793b2011-05-05 15:18:15 +000077
reed@google.com31891582011-05-12 03:03:56 +000078 const SkPaint& paint() const { return fPaint; }
79 SkPaint* editPaint() { return &fPaint; }
reed@google.combb6992a2011-04-26 17:41:56 +000080
reed@google.comb55d1182011-05-11 00:42:04 +000081 SkFlattenable* getFlat(unsigned index) const {
82 if (0 == index) {
83 return NULL;
84 }
85 return fFlatArray[index - 1];
86 }
87
88 void defFlattenable(PaintFlats pf, unsigned index) {
reed@google.comdde09562011-05-23 12:21:05 +000089 SkASSERT(index == fFlatArray.count() + 1);
reed@google.comb55d1182011-05-11 00:42:04 +000090 SkFlattenable* obj = fReader->readFlattenable();
91 *fFlatArray.append() = obj;
reed@google.comb55d1182011-05-11 00:42:04 +000092 }
93
reed@google.combb6793b2011-05-05 15:18:15 +000094 void addTypeface() {
95 size_t size = fReader->readU32();
96 const void* data = fReader->skip(SkAlign4(size));
reed@google.comf5842f72011-05-04 18:30:04 +000097 SkMemoryStream stream(data, size, false);
reed@google.comf5842f72011-05-04 18:30:04 +000098 *fTypefaces.append() = SkTypeface::Deserialize(&stream);
reed@google.com0faac1e2011-05-11 05:58:58 +000099 }
reed@google.combb6793b2011-05-05 15:18:15 +0000100 void setTypeface(SkPaint* paint, unsigned id) {
101 paint->setTypeface(id ? fTypefaces[id - 1] : NULL);
102 }
reed@google.combb6793b2011-05-05 15:18:15 +0000103
reed@google.combb6793b2011-05-05 15:18:15 +0000104 SkFlattenableReadBuffer* fReader;
reed@google.comb55d1182011-05-11 00:42:04 +0000105
106private:
reed@google.com31891582011-05-12 03:03:56 +0000107 SkPaint fPaint;
108 SkTDArray<SkFlattenable*> fFlatArray;
109 SkTDArray<SkTypeface*> fTypefaces;
reed@google.comdde09562011-05-23 12:21:05 +0000110 SkTDArray<SkFlattenable::Factory> fFactoryArray;
reed@google.combb6992a2011-04-26 17:41:56 +0000111};
112
113///////////////////////////////////////////////////////////////////////////////
114
115template <typename T> const T* skip(SkReader32* reader, int count = 1) {
116 SkASSERT(count >= 0);
117 size_t size = sizeof(T) * count;
118 SkASSERT(SkAlign4(size) == size);
119 return reinterpret_cast<const T*>(reader->skip(size));
120}
121
122template <typename T> const T* skipAlign(SkReader32* reader, int count = 1) {
123 SkASSERT(count >= 0);
124 size_t size = SkAlign4(sizeof(T) * count);
125 return reinterpret_cast<const T*>(reader->skip(size));
126}
127
reed@google.combb6992a2011-04-26 17:41:56 +0000128///////////////////////////////////////////////////////////////////////////////
129///////////////////////////////////////////////////////////////////////////////
130
131static void clipPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
132 SkGPipeState* state) {
133 SkPath path;
134 path.unflatten(*reader);
135 canvas->clipPath(path, (SkRegion::Op)DrawOp_unpackData(op32));
136}
137
138static void clipRegion_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
139 SkGPipeState* state) {
140 SkRegion rgn;
reed@google.comb55d1182011-05-11 00:42:04 +0000141 SkReadRegion(reader, &rgn);
reed@google.combb6992a2011-04-26 17:41:56 +0000142 canvas->clipRegion(rgn, (SkRegion::Op)DrawOp_unpackData(op32));
143}
144
145static void clipRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
146 SkGPipeState* state) {
147 canvas->clipRect(*skip<SkRect>(reader), (SkRegion::Op)DrawOp_unpackData(op32));
148}
149
150///////////////////////////////////////////////////////////////////////////////
151
152static void setMatrix_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
153 SkGPipeState* state) {
154 SkMatrix matrix;
reed@google.comb55d1182011-05-11 00:42:04 +0000155 SkReadMatrix(reader, &matrix);
reed@google.combb6992a2011-04-26 17:41:56 +0000156 canvas->setMatrix(matrix);
157}
158
159static void concat_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
160 SkGPipeState* state) {
161 SkMatrix matrix;
reed@google.comb55d1182011-05-11 00:42:04 +0000162 SkReadMatrix(reader, &matrix);
reed@google.combb6992a2011-04-26 17:41:56 +0000163 canvas->concat(matrix);
164}
165
166static void scale_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
167 SkGPipeState* state) {
168 const SkScalar* param = skip<SkScalar>(reader, 2);
169 canvas->scale(param[0], param[1]);
170}
171
172static void skew_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
173 SkGPipeState* state) {
174 const SkScalar* param = skip<SkScalar>(reader, 2);
175 canvas->skew(param[0], param[1]);
176}
177
178static void rotate_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
179 SkGPipeState* state) {
180 canvas->rotate(reader->readScalar());
181}
182
183static void translate_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
184 SkGPipeState* state) {
185 const SkScalar* param = skip<SkScalar>(reader, 2);
186 canvas->translate(param[0], param[1]);
187}
188
189///////////////////////////////////////////////////////////////////////////////
190
191static void save_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
192 SkGPipeState* state) {
193 canvas->save((SkCanvas::SaveFlags)DrawOp_unpackData(op32));
194}
195
196static void saveLayer_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
197 SkGPipeState* state) {
reed@google.comacd471f2011-05-03 21:26:46 +0000198 unsigned flags = DrawOp_unpackFlags(op32);
199 SkCanvas::SaveFlags saveFlags = (SkCanvas::SaveFlags)DrawOp_unpackData(op32);
reed@google.combb6992a2011-04-26 17:41:56 +0000200
201 const SkRect* bounds = NULL;
202 if (flags & kSaveLayer_HasBounds_DrawOpFlag) {
203 bounds = skip<SkRect>(reader);
204 }
205 const SkPaint* paint = NULL;
206 if (flags & kSaveLayer_HasPaint_DrawOpFlag) {
reed@google.com31891582011-05-12 03:03:56 +0000207 paint = &state->paint();
reed@google.combb6992a2011-04-26 17:41:56 +0000208 }
reed@google.comacd471f2011-05-03 21:26:46 +0000209 canvas->saveLayer(bounds, paint, saveFlags);
reed@google.combb6992a2011-04-26 17:41:56 +0000210}
211
212static void restore_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
213 SkGPipeState* state) {
214 canvas->restore();
215}
216
217///////////////////////////////////////////////////////////////////////////////
218
219static void drawClear_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
220 SkGPipeState* state) {
221 SkColor color = 0;
222 if (DrawOp_unpackFlags(op32) & kClear_HasColor_DrawOpFlag) {
223 color = reader->readU32();
224 }
225 canvas->clear(color);
226}
227
228static void drawPaint_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
229 SkGPipeState* state) {
reed@google.com31891582011-05-12 03:03:56 +0000230 canvas->drawPaint(state->paint());
reed@google.combb6992a2011-04-26 17:41:56 +0000231}
232
233static void drawPoints_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
234 SkGPipeState* state) {
235 SkCanvas::PointMode mode = (SkCanvas::PointMode)DrawOp_unpackFlags(op32);
236 size_t count = reader->readU32();
237 const SkPoint* pts = skip<SkPoint>(reader, count);
reed@google.com31891582011-05-12 03:03:56 +0000238 canvas->drawPoints(mode, count, pts, state->paint());
reed@google.combb6992a2011-04-26 17:41:56 +0000239}
240
241static void drawRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
242 SkGPipeState* state) {
reed@google.com31891582011-05-12 03:03:56 +0000243 canvas->drawRect(*skip<SkRect>(reader), state->paint());
reed@google.combb6992a2011-04-26 17:41:56 +0000244}
245
246static void drawPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
247 SkGPipeState* state) {
248 SkPath path;
249 path.unflatten(*reader);
reed@google.com31891582011-05-12 03:03:56 +0000250 canvas->drawPath(path, state->paint());
reed@google.combb6992a2011-04-26 17:41:56 +0000251}
252
253static void drawVertices_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
254 SkGPipeState* state) {
255 unsigned flags = DrawOp_unpackFlags(op32);
256
257 SkCanvas::VertexMode mode = (SkCanvas::VertexMode)reader->readU32();
258 int vertexCount = reader->readU32();
259 const SkPoint* verts = skip<SkPoint>(reader, vertexCount);
260
261 const SkPoint* texs = NULL;
262 if (flags & kDrawVertices_HasTexs_DrawOpFlag) {
263 texs = skip<SkPoint>(reader, vertexCount);
264 }
265
266 const SkColor* colors = NULL;
267 if (flags & kDrawVertices_HasColors_DrawOpFlag) {
268 colors = skip<SkColor>(reader, vertexCount);
269 }
270
271 // TODO: flatten/unflatten xfermodes
272 SkXfermode* xfer = NULL;
273
274 int indexCount = 0;
275 const uint16_t* indices = NULL;
276 if (flags & kDrawVertices_HasIndices_DrawOpFlag) {
277 indexCount = reader->readU32();
278 indices = skipAlign<uint16_t>(reader, indexCount);
279 }
280
281 canvas->drawVertices(mode, vertexCount, verts, texs, colors, xfer,
reed@google.com31891582011-05-12 03:03:56 +0000282 indices, indexCount, state->paint());
reed@google.combb6992a2011-04-26 17:41:56 +0000283}
284
285///////////////////////////////////////////////////////////////////////////////
286
287static void drawText_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
288 SkGPipeState* state) {
289 size_t len = reader->readU32();
290 const void* text = reader->skip(SkAlign4(len));
291 const SkScalar* xy = skip<SkScalar>(reader, 2);
reed@google.com31891582011-05-12 03:03:56 +0000292 canvas->drawText(text, len, xy[0], xy[1], state->paint());
reed@google.combb6992a2011-04-26 17:41:56 +0000293}
294
295static void drawPosText_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
296 SkGPipeState* state) {
297 size_t len = reader->readU32();
298 const void* text = reader->skip(SkAlign4(len));
299 size_t posCount = reader->readU32(); // compute by our writer
300 const SkPoint* pos = skip<SkPoint>(reader, posCount);
reed@google.com31891582011-05-12 03:03:56 +0000301 canvas->drawPosText(text, len, pos, state->paint());
reed@google.combb6992a2011-04-26 17:41:56 +0000302}
303
304static void drawPosTextH_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
305 SkGPipeState* state) {
306 size_t len = reader->readU32();
307 const void* text = reader->skip(SkAlign4(len));
308 size_t posCount = reader->readU32(); // compute by our writer
309 const SkScalar* xpos = skip<SkScalar>(reader, posCount);
310 SkScalar constY = reader->readScalar();
reed@google.com31891582011-05-12 03:03:56 +0000311 canvas->drawPosTextH(text, len, xpos, constY, state->paint());
reed@google.combb6992a2011-04-26 17:41:56 +0000312}
313
314static void drawTextOnPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
315 SkGPipeState* state) {
316 size_t len = reader->readU32();
317 const void* text = reader->skip(SkAlign4(len));
318
319 SkPath path;
320 path.unflatten(*reader);
321
322 SkMatrix matrixStorage;
323 const SkMatrix* matrix = NULL;
324 if (DrawOp_unpackFlags(op32) & kDrawTextOnPath_HasMatrix_DrawOpFlag) {
reed@google.comb55d1182011-05-11 00:42:04 +0000325 SkReadMatrix(reader, &matrixStorage);
reed@google.combb6992a2011-04-26 17:41:56 +0000326 matrix = &matrixStorage;
327 }
328
reed@google.com31891582011-05-12 03:03:56 +0000329 canvas->drawTextOnPath(text, len, path, matrix, state->paint());
reed@google.combb6992a2011-04-26 17:41:56 +0000330}
331
332///////////////////////////////////////////////////////////////////////////////
333
334static void drawBitmap_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
335 SkGPipeState* state) {
336 UNIMPLEMENTED
337}
338
339static void drawBitmapMatrix_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
340 SkGPipeState* state) {
341 UNIMPLEMENTED
342}
343
344static void drawBitmapRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
345 SkGPipeState* state) {
346 UNIMPLEMENTED
347}
348
349static void drawSprite_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
350 SkGPipeState* state) {
351 UNIMPLEMENTED
352}
353
354///////////////////////////////////////////////////////////////////////////////
355
356static void drawData_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
357 SkGPipeState* state) {
358 // since we don't have a paint, we can use data for our (small) sizes
359 size_t size = DrawOp_unpackData(op32);
360 if (0 == size) {
361 size = reader->readU32();
362 }
363 const void* data = reader->skip(SkAlign4(size));
364 canvas->drawData(data, size);
365}
366
367static void drawShape_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
368 SkGPipeState* state) {
369 UNIMPLEMENTED
370}
371
372static void drawPicture_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
373 SkGPipeState* state) {
374 UNIMPLEMENTED
375}
376
377///////////////////////////////////////////////////////////////////////////////
378
reed@google.combb6992a2011-04-26 17:41:56 +0000379static void paintOp_rp(SkCanvas*, SkReader32* reader, uint32_t op32,
380 SkGPipeState* state) {
reed@google.comb55d1182011-05-11 00:42:04 +0000381 size_t offset = reader->offset();
382 size_t stop = offset + PaintOp_unpackData(op32);
reed@google.com31891582011-05-12 03:03:56 +0000383 SkPaint* p = state->editPaint();
reed@google.combb6992a2011-04-26 17:41:56 +0000384
385 do {
386 uint32_t p32 = reader->readU32();
387 unsigned op = PaintOp_unpackOp(p32);
388 unsigned data = PaintOp_unpackData(p32);
reed@google.combb6992a2011-04-26 17:41:56 +0000389
reed@google.comb55d1182011-05-11 00:42:04 +0000390// SkDebugf(" read %08X op=%d flags=%d data=%d\n", p32, op, done, data);
reed@google.combb6992a2011-04-26 17:41:56 +0000391
392 switch (op) {
393 case kReset_PaintOp: p->reset(); break;
394 case kFlags_PaintOp: p->setFlags(data); break;
395 case kColor_PaintOp: p->setColor(reader->readU32()); break;
396 case kStyle_PaintOp: p->setStyle((SkPaint::Style)data); break;
397 case kJoin_PaintOp: p->setStrokeJoin((SkPaint::Join)data); break;
398 case kCap_PaintOp: p->setStrokeCap((SkPaint::Cap)data); break;
399 case kWidth_PaintOp: p->setStrokeWidth(reader->readScalar()); break;
400 case kMiter_PaintOp: p->setStrokeMiter(reader->readScalar()); break;
401 case kEncoding_PaintOp:
402 p->setTextEncoding((SkPaint::TextEncoding)data);
403 break;
404 case kHinting_PaintOp: p->setHinting((SkPaint::Hinting)data); break;
405 case kAlign_PaintOp: p->setTextAlign((SkPaint::Align)data); break;
406 case kTextSize_PaintOp: p->setTextSize(reader->readScalar()); break;
407 case kTextScaleX_PaintOp: p->setTextScaleX(reader->readScalar()); break;
408 case kTextSkewX_PaintOp: p->setTextSkewX(reader->readScalar()); break;
reed@google.combb6793b2011-05-05 15:18:15 +0000409
reed@google.comb55d1182011-05-11 00:42:04 +0000410 case kFlatIndex_PaintOp: {
411 PaintFlats pf = (PaintFlats)PaintOp_unpackFlags(p32);
412 unsigned index = data;
413 set_paintflat(p, state->getFlat(index), pf);
414 break;
415 }
416
reed@google.combb6793b2011-05-05 15:18:15 +0000417 case kTypeface_PaintOp: state->setTypeface(p, data); break;
reed@google.combb6992a2011-04-26 17:41:56 +0000418 default: SkASSERT(!"bad paintop"); return;
419 }
reed@google.comb55d1182011-05-11 00:42:04 +0000420 SkASSERT(reader->offset() <= stop);
reed@google.com31891582011-05-12 03:03:56 +0000421 } while (reader->offset() < stop);
reed@google.combb6992a2011-04-26 17:41:56 +0000422}
423
reed@google.combb6793b2011-05-05 15:18:15 +0000424///////////////////////////////////////////////////////////////////////////////
425
reed@google.com0faac1e2011-05-11 05:58:58 +0000426static void def_Typeface_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState* state) {
427 state->addTypeface();
428}
429
reed@google.comb55d1182011-05-11 00:42:04 +0000430static void def_PaintFlat_rp(SkCanvas*, SkReader32*, uint32_t op32,
431 SkGPipeState* state) {
432 PaintFlats pf = (PaintFlats)DrawOp_unpackFlags(op32);
433 unsigned index = DrawOp_unpackData(op32);
434 state->defFlattenable(pf, index);
435}
436
reed@google.combb6992a2011-04-26 17:41:56 +0000437///////////////////////////////////////////////////////////////////////////////
438
reed@google.comacd471f2011-05-03 21:26:46 +0000439static void skip_rp(SkCanvas*, SkReader32* reader, uint32_t op32, SkGPipeState*) {
440 size_t bytes = DrawOp_unpackData(op32);
441 (void)reader->skip(bytes);
442}
443
reed@google.combb6992a2011-04-26 17:41:56 +0000444static void done_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState*) {}
445
446typedef void (*ReadProc)(SkCanvas*, SkReader32*, uint32_t op32, SkGPipeState*);
447
448static const ReadProc gReadTable[] = {
reed@google.comacd471f2011-05-03 21:26:46 +0000449 skip_rp,
reed@google.combb6992a2011-04-26 17:41:56 +0000450 clipPath_rp,
451 clipRegion_rp,
452 clipRect_rp,
453 concat_rp,
454 drawBitmap_rp,
455 drawBitmapMatrix_rp,
456 drawBitmapRect_rp,
457 drawClear_rp,
458 drawData_rp,
459 drawPaint_rp,
460 drawPath_rp,
461 drawPicture_rp,
462 drawPoints_rp,
463 drawPosText_rp,
464 drawPosTextH_rp,
465 drawRect_rp,
466 drawShape_rp,
467 drawSprite_rp,
468 drawText_rp,
469 drawTextOnPath_rp,
470 drawVertices_rp,
471 restore_rp,
472 rotate_rp,
473 save_rp,
474 saveLayer_rp,
475 scale_rp,
476 setMatrix_rp,
477 skew_rp,
478 translate_rp,
reed@google.com0faac1e2011-05-11 05:58:58 +0000479
reed@google.combb6992a2011-04-26 17:41:56 +0000480 paintOp_rp,
reed@google.combb6793b2011-05-05 15:18:15 +0000481 def_Typeface_rp,
reed@google.com0faac1e2011-05-11 05:58:58 +0000482 def_PaintFlat_rp,
483
reed@google.combb6992a2011-04-26 17:41:56 +0000484 done_rp
485};
486
487///////////////////////////////////////////////////////////////////////////////
488
reed@google.com31891582011-05-12 03:03:56 +0000489SkGPipeState::SkGPipeState() {}
reed@google.combb6992a2011-04-26 17:41:56 +0000490
reed@google.comb55d1182011-05-11 00:42:04 +0000491SkGPipeState::~SkGPipeState() {
reed@google.com6bac9472011-06-21 19:24:00 +0000492 fTypefaces.safeUnrefAll();
493 fFlatArray.safeUnrefAll();
reed@google.combb6992a2011-04-26 17:41:56 +0000494}
495
496///////////////////////////////////////////////////////////////////////////////
497
498#include "SkGPipe.h"
499
500SkGPipeReader::SkGPipeReader(SkCanvas* target) {
501 SkSafeRef(target);
502 fCanvas = target;
503 fState = NULL;
504}
505
506SkGPipeReader::~SkGPipeReader() {
507 SkSafeUnref(fCanvas);
508 delete fState;
509}
510
reed@google.com80b09de2011-05-23 13:54:24 +0000511SkGPipeReader::Status SkGPipeReader::playback(const void* data, size_t length,
yangsu@google.com1bce0a52011-06-16 21:08:19 +0000512 size_t* bytesRead, bool readAtom) {
reed@google.combb6992a2011-04-26 17:41:56 +0000513 if (NULL == fCanvas) {
514 return kError_Status;
515 }
516
517 if (NULL == fState) {
518 fState = new SkGPipeState;
519 }
520
reed@google.com0faac1e2011-05-11 05:58:58 +0000521 SkASSERT(SK_ARRAY_COUNT(gReadTable) == (kDone_DrawOp + 1));
522
reed@google.combb6992a2011-04-26 17:41:56 +0000523 const ReadProc* table = gReadTable;
reed@google.combb6793b2011-05-05 15:18:15 +0000524 SkFlattenableReadBuffer reader(data, length);
reed@google.combb6992a2011-04-26 17:41:56 +0000525 SkCanvas* canvas = fCanvas;
reed@google.com80b09de2011-05-23 13:54:24 +0000526 Status status = kEOF_Status;
reed@google.combb6793b2011-05-05 15:18:15 +0000527
528 fState->setReader(&reader);
reed@google.combb6992a2011-04-26 17:41:56 +0000529 while (!reader.eof()) {
530 uint32_t op32 = reader.readU32();
531 unsigned op = DrawOp_unpackOp(op32);
reed@google.combb6793b2011-05-05 15:18:15 +0000532 SkDEBUGCODE(DrawOps drawOp = (DrawOps)op;)
reed@google.combb6992a2011-04-26 17:41:56 +0000533
534 if (op >= SK_ARRAY_COUNT(gReadTable)) {
535 SkDebugf("---- bad op during GPipeState::playback\n");
reed@google.com80b09de2011-05-23 13:54:24 +0000536 status = kError_Status;
537 break;
reed@google.combb6992a2011-04-26 17:41:56 +0000538 }
539 if (kDone_DrawOp == op) {
reed@google.com80b09de2011-05-23 13:54:24 +0000540 status = kDone_Status;
541 break;
reed@google.combb6992a2011-04-26 17:41:56 +0000542 }
543 table[op](canvas, &reader, op32, fState);
yangsu@google.com1bce0a52011-06-16 21:08:19 +0000544 if (readAtom &&
545 (table[op] != paintOp_rp &&
546 table[op] != def_Typeface_rp &&
reed@google.com6bac9472011-06-21 19:24:00 +0000547 table[op] != def_PaintFlat_rp
yangsu@google.com1bce0a52011-06-16 21:08:19 +0000548 )) {
549 status = kReadAtom_Status;
550 break;
551 }
reed@google.combb6992a2011-04-26 17:41:56 +0000552 }
reed@google.com80b09de2011-05-23 13:54:24 +0000553
554 if (bytesRead) {
reed@google.comac45f002011-05-24 13:50:21 +0000555 *bytesRead = reader.offset();
reed@google.com80b09de2011-05-23 13:54:24 +0000556 }
557 return status;
reed@google.combb6992a2011-04-26 17:41:56 +0000558}
559
560