1/*
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"
20#include "SkGPipe.h"
21#include "SkGPipePriv.h"
22#include "SkReader32.h"
23#include "SkStream.h"
24
25#include "SkColorFilter.h"
26#include "SkDrawLooper.h"
27#include "SkMaskFilter.h"
28#include "SkPathEffect.h"
29#include "SkRasterizer.h"
30#include "SkShader.h"
31#include "SkTypeface.h"
32#include "SkXfermode.h"
33
34static 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;
40        case kDrawLooper_PaintFlat:
41            paint->setLooper((SkDrawLooper*)obj);
42            break;
43        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
63template <typename T> class SkRefCntTDArray : public SkTDArray<T> {
64public:
65    ~SkRefCntTDArray() { this->unrefAll(); }
66};
67
68class SkGPipeState {
69public:
70    SkGPipeState();
71    ~SkGPipeState();
72
73    void setReader(SkFlattenableReadBuffer* reader) {
74        fReader = reader;
75        fReader->setFactoryPlayback(fFactoryArray.begin(), fFactoryArray.count());
76    }
77
78    const SkPaint& paint() const { return fPaint; }
79    SkPaint* editPaint() { return &fPaint; }
80
81    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) {
89        SkASSERT(index == fFlatArray.count() + 1);
90        SkFlattenable* obj = fReader->readFlattenable();
91        *fFlatArray.append() = obj;
92    }
93
94    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
104    void addTypeface() {
105        size_t size = fReader->readU32();
106        const void* data = fReader->skip(SkAlign4(size));
107        SkMemoryStream stream(data, size, false);
108        *fTypefaces.append() = SkTypeface::Deserialize(&stream);
109    }
110    void setTypeface(SkPaint* paint, unsigned id) {
111        paint->setTypeface(id ? fTypefaces[id - 1] : NULL);
112    }
113
114    SkFlattenableReadBuffer* fReader;
115
116private:
117    SkPaint                   fPaint;
118    SkTDArray<SkFlattenable*> fFlatArray;
119    SkTDArray<SkTypeface*>    fTypefaces;
120    SkTDArray<SkFlattenable::Factory> fFactoryArray;
121};
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
138///////////////////////////////////////////////////////////////////////////////
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;
151    SkReadRegion(reader, &rgn);
152    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;
165    SkReadMatrix(reader, &matrix);
166    canvas->setMatrix(matrix);
167}
168
169static void concat_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
170                      SkGPipeState* state) {
171    SkMatrix matrix;
172    SkReadMatrix(reader, &matrix);
173    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) {
208    unsigned flags = DrawOp_unpackFlags(op32);
209    SkCanvas::SaveFlags saveFlags = (SkCanvas::SaveFlags)DrawOp_unpackData(op32);
210
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) {
217        paint = &state->paint();
218    }
219    canvas->saveLayer(bounds, paint, saveFlags);
220}
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) {
240    canvas->drawPaint(state->paint());
241}
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);
248    canvas->drawPoints(mode, count, pts, state->paint());
249}
250
251static void drawRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
252                        SkGPipeState* state) {
253    canvas->drawRect(*skip<SkRect>(reader), state->paint());
254}
255
256static void drawPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
257                        SkGPipeState* state) {
258    SkPath path;
259    path.unflatten(*reader);
260    canvas->drawPath(path, state->paint());
261}
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,
292                         indices, indexCount, state->paint());
293}
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);
302    canvas->drawText(text, len, xy[0], xy[1], state->paint());
303}
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);
311    canvas->drawPosText(text, len, pos, state->paint());
312}
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();
321    canvas->drawPosTextH(text, len, xpos, constY, state->paint());
322}
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) {
335        SkReadMatrix(reader, &matrixStorage);
336        matrix = &matrixStorage;
337    }
338
339    canvas->drawTextOnPath(text, len, path, matrix, state->paint());
340}
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
389static void paintOp_rp(SkCanvas*, SkReader32* reader, uint32_t op32,
390                       SkGPipeState* state) {
391    size_t offset = reader->offset();
392    size_t stop = offset + PaintOp_unpackData(op32);
393    SkPaint* p = state->editPaint();
394
395    do {
396        uint32_t p32 = reader->readU32();
397        unsigned op = PaintOp_unpackOp(p32);
398        unsigned data = PaintOp_unpackData(p32);
399
400//        SkDebugf(" read %08X op=%d flags=%d data=%d\n", p32, op, done, data);
401
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;
419
420            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
427            case kTypeface_PaintOp: state->setTypeface(p, data); break;
428            default: SkASSERT(!"bad paintop"); return;
429        }
430        SkASSERT(reader->offset() <= stop);
431    } while (reader->offset() < stop);
432}
433
434///////////////////////////////////////////////////////////////////////////////
435
436static void def_Typeface_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState* state) {
437    state->addTypeface();
438}
439
440static 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
447static 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
454///////////////////////////////////////////////////////////////////////////////
455
456static void skip_rp(SkCanvas*, SkReader32* reader, uint32_t op32, SkGPipeState*) {
457    size_t bytes = DrawOp_unpackData(op32);
458    (void)reader->skip(bytes);
459}
460
461static void done_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState*) {}
462
463typedef void (*ReadProc)(SkCanvas*, SkReader32*, uint32_t op32, SkGPipeState*);
464
465static const ReadProc gReadTable[] = {
466    skip_rp,
467    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,
496
497    paintOp_rp,
498    def_Typeface_rp,
499    def_PaintFlat_rp,
500    name_PaintFlat_rp,
501
502    done_rp
503};
504
505///////////////////////////////////////////////////////////////////////////////
506
507SkGPipeState::SkGPipeState() {}
508
509SkGPipeState::~SkGPipeState() {
510    fTypefaces.unrefAll();
511    fFlatArray.unrefAll();
512}
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
529SkGPipeReader::Status SkGPipeReader::playback(const void* data, size_t length,
530                                              size_t* bytesRead) {
531    if (NULL == fCanvas) {
532        return kError_Status;
533    }
534
535    if (NULL == fState) {
536        fState = new SkGPipeState;
537    }
538
539    SkASSERT(SK_ARRAY_COUNT(gReadTable) == (kDone_DrawOp + 1));
540
541    const ReadProc* table = gReadTable;
542    SkFlattenableReadBuffer reader(data, length);
543    SkCanvas* canvas = fCanvas;
544    Status status = kEOF_Status;
545
546    fState->setReader(&reader);
547    while (!reader.eof()) {
548        uint32_t op32 = reader.readU32();
549        unsigned op = DrawOp_unpackOp(op32);
550        SkDEBUGCODE(DrawOps drawOp = (DrawOps)op;)
551
552        if (op >= SK_ARRAY_COUNT(gReadTable)) {
553            SkDebugf("---- bad op during GPipeState::playback\n");
554            status = kError_Status;
555            break;
556        }
557        if (kDone_DrawOp == op) {
558            status = kDone_Status;
559            break;
560        }
561        table[op](canvas, &reader, op32, fState);
562    }
563
564    if (bytesRead) {
565        *bytesRead = reader.offset();
566    }
567    return status;
568}
569
570
571