blob: ecb19fd0592925ab102ec7fc22d93840f7876716 [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;
75 fReader->setFactoryPlayback(fFactoryArray.begin(), fFactoryArray.count());
76 }
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.comdde09562011-05-23 12:21:05 +000094 void nameFlattenable(PaintFlats pf, unsigned index) {
95 SkASSERT(index == fFactoryArray.count() + 1);
96 const char* name = fReader->readString();
97 SkFlattenable::Factory fact = SkFlattenable::NameToFactory(name);
98 *fFactoryArray.append() = fact;
99
100 // update this each time we grow the array
101 fReader->setFactoryPlayback(fFactoryArray.begin(), fFactoryArray.count());
102 }
103
reed@google.combb6793b2011-05-05 15:18:15 +0000104 void addTypeface() {
105 size_t size = fReader->readU32();
106 const void* data = fReader->skip(SkAlign4(size));
reed@google.comf5842f72011-05-04 18:30:04 +0000107 SkMemoryStream stream(data, size, false);
reed@google.comf5842f72011-05-04 18:30:04 +0000108 *fTypefaces.append() = SkTypeface::Deserialize(&stream);
reed@google.com0faac1e2011-05-11 05:58:58 +0000109 }
reed@google.combb6793b2011-05-05 15:18:15 +0000110 void setTypeface(SkPaint* paint, unsigned id) {
111 paint->setTypeface(id ? fTypefaces[id - 1] : NULL);
112 }
reed@google.combb6793b2011-05-05 15:18:15 +0000113
reed@google.combb6793b2011-05-05 15:18:15 +0000114 SkFlattenableReadBuffer* fReader;
reed@google.comb55d1182011-05-11 00:42:04 +0000115
116private:
reed@google.com31891582011-05-12 03:03:56 +0000117 SkPaint fPaint;
118 SkTDArray<SkFlattenable*> fFlatArray;
119 SkTDArray<SkTypeface*> fTypefaces;
reed@google.comdde09562011-05-23 12:21:05 +0000120 SkTDArray<SkFlattenable::Factory> fFactoryArray;
reed@google.combb6992a2011-04-26 17:41:56 +0000121};
122
123///////////////////////////////////////////////////////////////////////////////
124
125template <typename T> const T* skip(SkReader32* reader, int count = 1) {
126 SkASSERT(count >= 0);
127 size_t size = sizeof(T) * count;
128 SkASSERT(SkAlign4(size) == size);
129 return reinterpret_cast<const T*>(reader->skip(size));
130}
131
132template <typename T> const T* skipAlign(SkReader32* reader, int count = 1) {
133 SkASSERT(count >= 0);
134 size_t size = SkAlign4(sizeof(T) * count);
135 return reinterpret_cast<const T*>(reader->skip(size));
136}
137
reed@google.combb6992a2011-04-26 17:41:56 +0000138///////////////////////////////////////////////////////////////////////////////
139///////////////////////////////////////////////////////////////////////////////
140
141static void clipPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
142 SkGPipeState* state) {
143 SkPath path;
144 path.unflatten(*reader);
145 canvas->clipPath(path, (SkRegion::Op)DrawOp_unpackData(op32));
146}
147
148static void clipRegion_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
149 SkGPipeState* state) {
150 SkRegion rgn;
reed@google.comb55d1182011-05-11 00:42:04 +0000151 SkReadRegion(reader, &rgn);
reed@google.combb6992a2011-04-26 17:41:56 +0000152 canvas->clipRegion(rgn, (SkRegion::Op)DrawOp_unpackData(op32));
153}
154
155static void clipRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
156 SkGPipeState* state) {
157 canvas->clipRect(*skip<SkRect>(reader), (SkRegion::Op)DrawOp_unpackData(op32));
158}
159
160///////////////////////////////////////////////////////////////////////////////
161
162static void setMatrix_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
163 SkGPipeState* state) {
164 SkMatrix matrix;
reed@google.comb55d1182011-05-11 00:42:04 +0000165 SkReadMatrix(reader, &matrix);
reed@google.combb6992a2011-04-26 17:41:56 +0000166 canvas->setMatrix(matrix);
167}
168
169static void concat_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
170 SkGPipeState* state) {
171 SkMatrix matrix;
reed@google.comb55d1182011-05-11 00:42:04 +0000172 SkReadMatrix(reader, &matrix);
reed@google.combb6992a2011-04-26 17:41:56 +0000173 canvas->concat(matrix);
174}
175
176static void scale_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
177 SkGPipeState* state) {
178 const SkScalar* param = skip<SkScalar>(reader, 2);
179 canvas->scale(param[0], param[1]);
180}
181
182static void skew_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
183 SkGPipeState* state) {
184 const SkScalar* param = skip<SkScalar>(reader, 2);
185 canvas->skew(param[0], param[1]);
186}
187
188static void rotate_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
189 SkGPipeState* state) {
190 canvas->rotate(reader->readScalar());
191}
192
193static void translate_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
194 SkGPipeState* state) {
195 const SkScalar* param = skip<SkScalar>(reader, 2);
196 canvas->translate(param[0], param[1]);
197}
198
199///////////////////////////////////////////////////////////////////////////////
200
201static void save_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
202 SkGPipeState* state) {
203 canvas->save((SkCanvas::SaveFlags)DrawOp_unpackData(op32));
204}
205
206static void saveLayer_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
207 SkGPipeState* state) {
reed@google.comacd471f2011-05-03 21:26:46 +0000208 unsigned flags = DrawOp_unpackFlags(op32);
209 SkCanvas::SaveFlags saveFlags = (SkCanvas::SaveFlags)DrawOp_unpackData(op32);
reed@google.combb6992a2011-04-26 17:41:56 +0000210
211 const SkRect* bounds = NULL;
212 if (flags & kSaveLayer_HasBounds_DrawOpFlag) {
213 bounds = skip<SkRect>(reader);
214 }
215 const SkPaint* paint = NULL;
216 if (flags & kSaveLayer_HasPaint_DrawOpFlag) {
reed@google.com31891582011-05-12 03:03:56 +0000217 paint = &state->paint();
reed@google.combb6992a2011-04-26 17:41:56 +0000218 }
reed@google.comacd471f2011-05-03 21:26:46 +0000219 canvas->saveLayer(bounds, paint, saveFlags);
reed@google.combb6992a2011-04-26 17:41:56 +0000220}
221
222static void restore_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
223 SkGPipeState* state) {
224 canvas->restore();
225}
226
227///////////////////////////////////////////////////////////////////////////////
228
229static void drawClear_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
230 SkGPipeState* state) {
231 SkColor color = 0;
232 if (DrawOp_unpackFlags(op32) & kClear_HasColor_DrawOpFlag) {
233 color = reader->readU32();
234 }
235 canvas->clear(color);
236}
237
238static void drawPaint_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
239 SkGPipeState* state) {
reed@google.com31891582011-05-12 03:03:56 +0000240 canvas->drawPaint(state->paint());
reed@google.combb6992a2011-04-26 17:41:56 +0000241}
242
243static void drawPoints_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
244 SkGPipeState* state) {
245 SkCanvas::PointMode mode = (SkCanvas::PointMode)DrawOp_unpackFlags(op32);
246 size_t count = reader->readU32();
247 const SkPoint* pts = skip<SkPoint>(reader, count);
reed@google.com31891582011-05-12 03:03:56 +0000248 canvas->drawPoints(mode, count, pts, state->paint());
reed@google.combb6992a2011-04-26 17:41:56 +0000249}
250
251static void drawRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
252 SkGPipeState* state) {
reed@google.com31891582011-05-12 03:03:56 +0000253 canvas->drawRect(*skip<SkRect>(reader), state->paint());
reed@google.combb6992a2011-04-26 17:41:56 +0000254}
255
256static void drawPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
257 SkGPipeState* state) {
258 SkPath path;
259 path.unflatten(*reader);
reed@google.com31891582011-05-12 03:03:56 +0000260 canvas->drawPath(path, state->paint());
reed@google.combb6992a2011-04-26 17:41:56 +0000261}
262
263static void drawVertices_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
264 SkGPipeState* state) {
265 unsigned flags = DrawOp_unpackFlags(op32);
266
267 SkCanvas::VertexMode mode = (SkCanvas::VertexMode)reader->readU32();
268 int vertexCount = reader->readU32();
269 const SkPoint* verts = skip<SkPoint>(reader, vertexCount);
270
271 const SkPoint* texs = NULL;
272 if (flags & kDrawVertices_HasTexs_DrawOpFlag) {
273 texs = skip<SkPoint>(reader, vertexCount);
274 }
275
276 const SkColor* colors = NULL;
277 if (flags & kDrawVertices_HasColors_DrawOpFlag) {
278 colors = skip<SkColor>(reader, vertexCount);
279 }
280
281 // TODO: flatten/unflatten xfermodes
282 SkXfermode* xfer = NULL;
283
284 int indexCount = 0;
285 const uint16_t* indices = NULL;
286 if (flags & kDrawVertices_HasIndices_DrawOpFlag) {
287 indexCount = reader->readU32();
288 indices = skipAlign<uint16_t>(reader, indexCount);
289 }
290
291 canvas->drawVertices(mode, vertexCount, verts, texs, colors, xfer,
reed@google.com31891582011-05-12 03:03:56 +0000292 indices, indexCount, state->paint());
reed@google.combb6992a2011-04-26 17:41:56 +0000293}
294
295///////////////////////////////////////////////////////////////////////////////
296
297static void drawText_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
298 SkGPipeState* state) {
299 size_t len = reader->readU32();
300 const void* text = reader->skip(SkAlign4(len));
301 const SkScalar* xy = skip<SkScalar>(reader, 2);
reed@google.com31891582011-05-12 03:03:56 +0000302 canvas->drawText(text, len, xy[0], xy[1], state->paint());
reed@google.combb6992a2011-04-26 17:41:56 +0000303}
304
305static void drawPosText_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
306 SkGPipeState* state) {
307 size_t len = reader->readU32();
308 const void* text = reader->skip(SkAlign4(len));
309 size_t posCount = reader->readU32(); // compute by our writer
310 const SkPoint* pos = skip<SkPoint>(reader, posCount);
reed@google.com31891582011-05-12 03:03:56 +0000311 canvas->drawPosText(text, len, pos, state->paint());
reed@google.combb6992a2011-04-26 17:41:56 +0000312}
313
314static void drawPosTextH_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 size_t posCount = reader->readU32(); // compute by our writer
319 const SkScalar* xpos = skip<SkScalar>(reader, posCount);
320 SkScalar constY = reader->readScalar();
reed@google.com31891582011-05-12 03:03:56 +0000321 canvas->drawPosTextH(text, len, xpos, constY, state->paint());
reed@google.combb6992a2011-04-26 17:41:56 +0000322}
323
324static void drawTextOnPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
325 SkGPipeState* state) {
326 size_t len = reader->readU32();
327 const void* text = reader->skip(SkAlign4(len));
328
329 SkPath path;
330 path.unflatten(*reader);
331
332 SkMatrix matrixStorage;
333 const SkMatrix* matrix = NULL;
334 if (DrawOp_unpackFlags(op32) & kDrawTextOnPath_HasMatrix_DrawOpFlag) {
reed@google.comb55d1182011-05-11 00:42:04 +0000335 SkReadMatrix(reader, &matrixStorage);
reed@google.combb6992a2011-04-26 17:41:56 +0000336 matrix = &matrixStorage;
337 }
338
reed@google.com31891582011-05-12 03:03:56 +0000339 canvas->drawTextOnPath(text, len, path, matrix, state->paint());
reed@google.combb6992a2011-04-26 17:41:56 +0000340}
341
342///////////////////////////////////////////////////////////////////////////////
343
344static void drawBitmap_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
345 SkGPipeState* state) {
346 UNIMPLEMENTED
347}
348
349static void drawBitmapMatrix_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
350 SkGPipeState* state) {
351 UNIMPLEMENTED
352}
353
354static void drawBitmapRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
355 SkGPipeState* state) {
356 UNIMPLEMENTED
357}
358
359static void drawSprite_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
360 SkGPipeState* state) {
361 UNIMPLEMENTED
362}
363
364///////////////////////////////////////////////////////////////////////////////
365
366static void drawData_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
367 SkGPipeState* state) {
368 // since we don't have a paint, we can use data for our (small) sizes
369 size_t size = DrawOp_unpackData(op32);
370 if (0 == size) {
371 size = reader->readU32();
372 }
373 const void* data = reader->skip(SkAlign4(size));
374 canvas->drawData(data, size);
375}
376
377static void drawShape_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
378 SkGPipeState* state) {
379 UNIMPLEMENTED
380}
381
382static void drawPicture_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
383 SkGPipeState* state) {
384 UNIMPLEMENTED
385}
386
387///////////////////////////////////////////////////////////////////////////////
388
reed@google.combb6992a2011-04-26 17:41:56 +0000389static void paintOp_rp(SkCanvas*, SkReader32* reader, uint32_t op32,
390 SkGPipeState* state) {
reed@google.comb55d1182011-05-11 00:42:04 +0000391 size_t offset = reader->offset();
392 size_t stop = offset + PaintOp_unpackData(op32);
reed@google.com31891582011-05-12 03:03:56 +0000393 SkPaint* p = state->editPaint();
reed@google.combb6992a2011-04-26 17:41:56 +0000394
395 do {
396 uint32_t p32 = reader->readU32();
397 unsigned op = PaintOp_unpackOp(p32);
398 unsigned data = PaintOp_unpackData(p32);
reed@google.combb6992a2011-04-26 17:41:56 +0000399
reed@google.comb55d1182011-05-11 00:42:04 +0000400// SkDebugf(" read %08X op=%d flags=%d data=%d\n", p32, op, done, data);
reed@google.combb6992a2011-04-26 17:41:56 +0000401
402 switch (op) {
403 case kReset_PaintOp: p->reset(); break;
404 case kFlags_PaintOp: p->setFlags(data); break;
405 case kColor_PaintOp: p->setColor(reader->readU32()); break;
406 case kStyle_PaintOp: p->setStyle((SkPaint::Style)data); break;
407 case kJoin_PaintOp: p->setStrokeJoin((SkPaint::Join)data); break;
408 case kCap_PaintOp: p->setStrokeCap((SkPaint::Cap)data); break;
409 case kWidth_PaintOp: p->setStrokeWidth(reader->readScalar()); break;
410 case kMiter_PaintOp: p->setStrokeMiter(reader->readScalar()); break;
411 case kEncoding_PaintOp:
412 p->setTextEncoding((SkPaint::TextEncoding)data);
413 break;
414 case kHinting_PaintOp: p->setHinting((SkPaint::Hinting)data); break;
415 case kAlign_PaintOp: p->setTextAlign((SkPaint::Align)data); break;
416 case kTextSize_PaintOp: p->setTextSize(reader->readScalar()); break;
417 case kTextScaleX_PaintOp: p->setTextScaleX(reader->readScalar()); break;
418 case kTextSkewX_PaintOp: p->setTextSkewX(reader->readScalar()); break;
reed@google.combb6793b2011-05-05 15:18:15 +0000419
reed@google.comb55d1182011-05-11 00:42:04 +0000420 case kFlatIndex_PaintOp: {
421 PaintFlats pf = (PaintFlats)PaintOp_unpackFlags(p32);
422 unsigned index = data;
423 set_paintflat(p, state->getFlat(index), pf);
424 break;
425 }
426
reed@google.combb6793b2011-05-05 15:18:15 +0000427 case kTypeface_PaintOp: state->setTypeface(p, data); break;
reed@google.combb6992a2011-04-26 17:41:56 +0000428 default: SkASSERT(!"bad paintop"); return;
429 }
reed@google.comb55d1182011-05-11 00:42:04 +0000430 SkASSERT(reader->offset() <= stop);
reed@google.com31891582011-05-12 03:03:56 +0000431 } while (reader->offset() < stop);
reed@google.combb6992a2011-04-26 17:41:56 +0000432}
433
reed@google.combb6793b2011-05-05 15:18:15 +0000434///////////////////////////////////////////////////////////////////////////////
435
reed@google.com0faac1e2011-05-11 05:58:58 +0000436static void def_Typeface_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState* state) {
437 state->addTypeface();
438}
439
reed@google.comb55d1182011-05-11 00:42:04 +0000440static void def_PaintFlat_rp(SkCanvas*, SkReader32*, uint32_t op32,
441 SkGPipeState* state) {
442 PaintFlats pf = (PaintFlats)DrawOp_unpackFlags(op32);
443 unsigned index = DrawOp_unpackData(op32);
444 state->defFlattenable(pf, index);
445}
446
reed@google.comdde09562011-05-23 12:21:05 +0000447static void name_PaintFlat_rp(SkCanvas*, SkReader32*, uint32_t op32,
448 SkGPipeState* state) {
449 PaintFlats pf = (PaintFlats)DrawOp_unpackFlags(op32);
450 unsigned index = DrawOp_unpackData(op32);
451 state->nameFlattenable(pf, index);
452}
453
reed@google.combb6992a2011-04-26 17:41:56 +0000454///////////////////////////////////////////////////////////////////////////////
455
reed@google.comacd471f2011-05-03 21:26:46 +0000456static void skip_rp(SkCanvas*, SkReader32* reader, uint32_t op32, SkGPipeState*) {
457 size_t bytes = DrawOp_unpackData(op32);
458 (void)reader->skip(bytes);
459}
460
reed@google.combb6992a2011-04-26 17:41:56 +0000461static void done_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState*) {}
462
463typedef void (*ReadProc)(SkCanvas*, SkReader32*, uint32_t op32, SkGPipeState*);
464
465static const ReadProc gReadTable[] = {
reed@google.comacd471f2011-05-03 21:26:46 +0000466 skip_rp,
reed@google.combb6992a2011-04-26 17:41:56 +0000467 clipPath_rp,
468 clipRegion_rp,
469 clipRect_rp,
470 concat_rp,
471 drawBitmap_rp,
472 drawBitmapMatrix_rp,
473 drawBitmapRect_rp,
474 drawClear_rp,
475 drawData_rp,
476 drawPaint_rp,
477 drawPath_rp,
478 drawPicture_rp,
479 drawPoints_rp,
480 drawPosText_rp,
481 drawPosTextH_rp,
482 drawRect_rp,
483 drawShape_rp,
484 drawSprite_rp,
485 drawText_rp,
486 drawTextOnPath_rp,
487 drawVertices_rp,
488 restore_rp,
489 rotate_rp,
490 save_rp,
491 saveLayer_rp,
492 scale_rp,
493 setMatrix_rp,
494 skew_rp,
495 translate_rp,
reed@google.com0faac1e2011-05-11 05:58:58 +0000496
reed@google.combb6992a2011-04-26 17:41:56 +0000497 paintOp_rp,
reed@google.combb6793b2011-05-05 15:18:15 +0000498 def_Typeface_rp,
reed@google.com0faac1e2011-05-11 05:58:58 +0000499 def_PaintFlat_rp,
reed@google.comdde09562011-05-23 12:21:05 +0000500 name_PaintFlat_rp,
reed@google.com0faac1e2011-05-11 05:58:58 +0000501
reed@google.combb6992a2011-04-26 17:41:56 +0000502 done_rp
503};
504
505///////////////////////////////////////////////////////////////////////////////
506
reed@google.com31891582011-05-12 03:03:56 +0000507SkGPipeState::SkGPipeState() {}
reed@google.combb6992a2011-04-26 17:41:56 +0000508
reed@google.comb55d1182011-05-11 00:42:04 +0000509SkGPipeState::~SkGPipeState() {
reed@google.com31891582011-05-12 03:03:56 +0000510 fTypefaces.unrefAll();
reed@google.comb55d1182011-05-11 00:42:04 +0000511 fFlatArray.unrefAll();
reed@google.combb6992a2011-04-26 17:41:56 +0000512}
513
514///////////////////////////////////////////////////////////////////////////////
515
516#include "SkGPipe.h"
517
518SkGPipeReader::SkGPipeReader(SkCanvas* target) {
519 SkSafeRef(target);
520 fCanvas = target;
521 fState = NULL;
522}
523
524SkGPipeReader::~SkGPipeReader() {
525 SkSafeUnref(fCanvas);
526 delete fState;
527}
528
reed@google.com80b09de2011-05-23 13:54:24 +0000529SkGPipeReader::Status SkGPipeReader::playback(const void* data, size_t length,
530 size_t* bytesRead) {
reed@google.combb6992a2011-04-26 17:41:56 +0000531 if (NULL == fCanvas) {
532 return kError_Status;
533 }
534
535 if (NULL == fState) {
536 fState = new SkGPipeState;
537 }
538
reed@google.com0faac1e2011-05-11 05:58:58 +0000539 SkASSERT(SK_ARRAY_COUNT(gReadTable) == (kDone_DrawOp + 1));
540
reed@google.combb6992a2011-04-26 17:41:56 +0000541 const ReadProc* table = gReadTable;
reed@google.combb6793b2011-05-05 15:18:15 +0000542 SkFlattenableReadBuffer reader(data, length);
reed@google.combb6992a2011-04-26 17:41:56 +0000543 SkCanvas* canvas = fCanvas;
reed@google.com80b09de2011-05-23 13:54:24 +0000544 Status status = kEOF_Status;
reed@google.combb6793b2011-05-05 15:18:15 +0000545
546 fState->setReader(&reader);
reed@google.combb6992a2011-04-26 17:41:56 +0000547 while (!reader.eof()) {
548 uint32_t op32 = reader.readU32();
549 unsigned op = DrawOp_unpackOp(op32);
reed@google.combb6793b2011-05-05 15:18:15 +0000550 SkDEBUGCODE(DrawOps drawOp = (DrawOps)op;)
reed@google.combb6992a2011-04-26 17:41:56 +0000551
552 if (op >= SK_ARRAY_COUNT(gReadTable)) {
553 SkDebugf("---- bad op during GPipeState::playback\n");
reed@google.com80b09de2011-05-23 13:54:24 +0000554 status = kError_Status;
555 break;
reed@google.combb6992a2011-04-26 17:41:56 +0000556 }
557 if (kDone_DrawOp == op) {
reed@google.com80b09de2011-05-23 13:54:24 +0000558 status = kDone_Status;
559 break;
reed@google.combb6992a2011-04-26 17:41:56 +0000560 }
561 table[op](canvas, &reader, op32, fState);
562 }
reed@google.com80b09de2011-05-23 13:54:24 +0000563
564 if (bytesRead) {
reed@google.comac45f002011-05-24 13:50:21 +0000565 *bytesRead = reader.offset();
reed@google.com80b09de2011-05-23 13:54:24 +0000566 }
567 return status;
reed@google.combb6992a2011-04-26 17:41:56 +0000568}
569
570