blob: 5fdbfc33cfb915c9e2d86b1937f50ff93b2237a2 [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
reed@google.com67908f22011-06-27 14:47:50 +000088 void defFlattenable(PaintFlats pf, int 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
reed@google.combb6992a2011-04-26 17:41:56 +0000367static void drawPicture_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
368 SkGPipeState* state) {
369 UNIMPLEMENTED
370}
371
372///////////////////////////////////////////////////////////////////////////////
373
reed@google.combb6992a2011-04-26 17:41:56 +0000374static void paintOp_rp(SkCanvas*, SkReader32* reader, uint32_t op32,
375 SkGPipeState* state) {
reed@google.comb55d1182011-05-11 00:42:04 +0000376 size_t offset = reader->offset();
377 size_t stop = offset + PaintOp_unpackData(op32);
reed@google.com31891582011-05-12 03:03:56 +0000378 SkPaint* p = state->editPaint();
reed@google.combb6992a2011-04-26 17:41:56 +0000379
380 do {
381 uint32_t p32 = reader->readU32();
382 unsigned op = PaintOp_unpackOp(p32);
383 unsigned data = PaintOp_unpackData(p32);
reed@google.combb6992a2011-04-26 17:41:56 +0000384
reed@google.comb55d1182011-05-11 00:42:04 +0000385// SkDebugf(" read %08X op=%d flags=%d data=%d\n", p32, op, done, data);
reed@google.combb6992a2011-04-26 17:41:56 +0000386
387 switch (op) {
388 case kReset_PaintOp: p->reset(); break;
389 case kFlags_PaintOp: p->setFlags(data); break;
390 case kColor_PaintOp: p->setColor(reader->readU32()); break;
391 case kStyle_PaintOp: p->setStyle((SkPaint::Style)data); break;
392 case kJoin_PaintOp: p->setStrokeJoin((SkPaint::Join)data); break;
393 case kCap_PaintOp: p->setStrokeCap((SkPaint::Cap)data); break;
394 case kWidth_PaintOp: p->setStrokeWidth(reader->readScalar()); break;
395 case kMiter_PaintOp: p->setStrokeMiter(reader->readScalar()); break;
396 case kEncoding_PaintOp:
397 p->setTextEncoding((SkPaint::TextEncoding)data);
398 break;
399 case kHinting_PaintOp: p->setHinting((SkPaint::Hinting)data); break;
400 case kAlign_PaintOp: p->setTextAlign((SkPaint::Align)data); break;
401 case kTextSize_PaintOp: p->setTextSize(reader->readScalar()); break;
402 case kTextScaleX_PaintOp: p->setTextScaleX(reader->readScalar()); break;
403 case kTextSkewX_PaintOp: p->setTextSkewX(reader->readScalar()); break;
reed@google.combb6793b2011-05-05 15:18:15 +0000404
reed@google.comb55d1182011-05-11 00:42:04 +0000405 case kFlatIndex_PaintOp: {
406 PaintFlats pf = (PaintFlats)PaintOp_unpackFlags(p32);
407 unsigned index = data;
408 set_paintflat(p, state->getFlat(index), pf);
409 break;
410 }
411
reed@google.combb6793b2011-05-05 15:18:15 +0000412 case kTypeface_PaintOp: state->setTypeface(p, data); break;
reed@google.combb6992a2011-04-26 17:41:56 +0000413 default: SkASSERT(!"bad paintop"); return;
414 }
reed@google.comb55d1182011-05-11 00:42:04 +0000415 SkASSERT(reader->offset() <= stop);
reed@google.com31891582011-05-12 03:03:56 +0000416 } while (reader->offset() < stop);
reed@google.combb6992a2011-04-26 17:41:56 +0000417}
418
reed@google.combb6793b2011-05-05 15:18:15 +0000419///////////////////////////////////////////////////////////////////////////////
420
reed@google.com0faac1e2011-05-11 05:58:58 +0000421static void def_Typeface_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState* state) {
422 state->addTypeface();
423}
424
reed@google.comb55d1182011-05-11 00:42:04 +0000425static void def_PaintFlat_rp(SkCanvas*, SkReader32*, uint32_t op32,
426 SkGPipeState* state) {
427 PaintFlats pf = (PaintFlats)DrawOp_unpackFlags(op32);
428 unsigned index = DrawOp_unpackData(op32);
429 state->defFlattenable(pf, index);
430}
431
reed@google.combb6992a2011-04-26 17:41:56 +0000432///////////////////////////////////////////////////////////////////////////////
433
reed@google.comacd471f2011-05-03 21:26:46 +0000434static void skip_rp(SkCanvas*, SkReader32* reader, uint32_t op32, SkGPipeState*) {
435 size_t bytes = DrawOp_unpackData(op32);
436 (void)reader->skip(bytes);
437}
438
reed@google.combb6992a2011-04-26 17:41:56 +0000439static void done_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState*) {}
440
441typedef void (*ReadProc)(SkCanvas*, SkReader32*, uint32_t op32, SkGPipeState*);
442
443static const ReadProc gReadTable[] = {
reed@google.comacd471f2011-05-03 21:26:46 +0000444 skip_rp,
reed@google.combb6992a2011-04-26 17:41:56 +0000445 clipPath_rp,
446 clipRegion_rp,
447 clipRect_rp,
448 concat_rp,
449 drawBitmap_rp,
450 drawBitmapMatrix_rp,
451 drawBitmapRect_rp,
452 drawClear_rp,
453 drawData_rp,
454 drawPaint_rp,
455 drawPath_rp,
456 drawPicture_rp,
457 drawPoints_rp,
458 drawPosText_rp,
459 drawPosTextH_rp,
460 drawRect_rp,
reed@google.combb6992a2011-04-26 17:41:56 +0000461 drawSprite_rp,
462 drawText_rp,
463 drawTextOnPath_rp,
464 drawVertices_rp,
465 restore_rp,
466 rotate_rp,
467 save_rp,
468 saveLayer_rp,
469 scale_rp,
470 setMatrix_rp,
471 skew_rp,
472 translate_rp,
reed@google.com0faac1e2011-05-11 05:58:58 +0000473
reed@google.combb6992a2011-04-26 17:41:56 +0000474 paintOp_rp,
reed@google.combb6793b2011-05-05 15:18:15 +0000475 def_Typeface_rp,
reed@google.com0faac1e2011-05-11 05:58:58 +0000476 def_PaintFlat_rp,
477
reed@google.combb6992a2011-04-26 17:41:56 +0000478 done_rp
479};
480
481///////////////////////////////////////////////////////////////////////////////
482
reed@google.com31891582011-05-12 03:03:56 +0000483SkGPipeState::SkGPipeState() {}
reed@google.combb6992a2011-04-26 17:41:56 +0000484
reed@google.comb55d1182011-05-11 00:42:04 +0000485SkGPipeState::~SkGPipeState() {
reed@google.com6bac9472011-06-21 19:24:00 +0000486 fTypefaces.safeUnrefAll();
487 fFlatArray.safeUnrefAll();
reed@google.combb6992a2011-04-26 17:41:56 +0000488}
489
490///////////////////////////////////////////////////////////////////////////////
491
492#include "SkGPipe.h"
493
494SkGPipeReader::SkGPipeReader(SkCanvas* target) {
495 SkSafeRef(target);
496 fCanvas = target;
497 fState = NULL;
498}
499
500SkGPipeReader::~SkGPipeReader() {
501 SkSafeUnref(fCanvas);
502 delete fState;
503}
504
reed@google.com80b09de2011-05-23 13:54:24 +0000505SkGPipeReader::Status SkGPipeReader::playback(const void* data, size_t length,
yangsu@google.com1bce0a52011-06-16 21:08:19 +0000506 size_t* bytesRead, bool readAtom) {
reed@google.combb6992a2011-04-26 17:41:56 +0000507 if (NULL == fCanvas) {
508 return kError_Status;
509 }
510
511 if (NULL == fState) {
512 fState = new SkGPipeState;
513 }
514
reed@google.com0faac1e2011-05-11 05:58:58 +0000515 SkASSERT(SK_ARRAY_COUNT(gReadTable) == (kDone_DrawOp + 1));
516
reed@google.combb6992a2011-04-26 17:41:56 +0000517 const ReadProc* table = gReadTable;
reed@google.combb6793b2011-05-05 15:18:15 +0000518 SkFlattenableReadBuffer reader(data, length);
reed@google.combb6992a2011-04-26 17:41:56 +0000519 SkCanvas* canvas = fCanvas;
reed@google.com80b09de2011-05-23 13:54:24 +0000520 Status status = kEOF_Status;
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");
reed@google.com80b09de2011-05-23 13:54:24 +0000530 status = kError_Status;
531 break;
reed@google.combb6992a2011-04-26 17:41:56 +0000532 }
533 if (kDone_DrawOp == op) {
reed@google.com80b09de2011-05-23 13:54:24 +0000534 status = kDone_Status;
535 break;
reed@google.combb6992a2011-04-26 17:41:56 +0000536 }
537 table[op](canvas, &reader, op32, fState);
yangsu@google.com1bce0a52011-06-16 21:08:19 +0000538 if (readAtom &&
539 (table[op] != paintOp_rp &&
540 table[op] != def_Typeface_rp &&
reed@google.com6bac9472011-06-21 19:24:00 +0000541 table[op] != def_PaintFlat_rp
yangsu@google.com1bce0a52011-06-16 21:08:19 +0000542 )) {
543 status = kReadAtom_Status;
544 break;
545 }
reed@google.combb6992a2011-04-26 17:41:56 +0000546 }
reed@google.com80b09de2011-05-23 13:54:24 +0000547
548 if (bytesRead) {
reed@google.comac45f002011-05-24 13:50:21 +0000549 *bytesRead = reader.offset();
reed@google.com80b09de2011-05-23 13:54:24 +0000550 }
551 return status;
reed@google.combb6992a2011-04-26 17:41:56 +0000552}
553
554