1ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips/* 2ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips * Copyright 2014 Google Inc. 3ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips * 4ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips * Use of this source code is governed by a BSD-style license that can be 5ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips * found in the LICENSE file. 6ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips */ 7ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips 8ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips#include "SkCanvas.h" 9b3c9d1c33caf325aada244204215eb790c228c12dandov#include "SkPatchUtils.h" 10ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips#include "SkPictureData.h" 11ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips#include "SkPicturePlayback.h" 12ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips#include "SkPictureRecord.h" 13ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips#include "SkReader32.h" 14b7425173f96e93b090787e2386ba5f022b6c2869fmalita#include "SkTextBlob.h" 15ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips#include "SkTDArray.h" 16ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips#include "SkTypes.h" 17ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips 18ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips/* 191ad00e4b245d464c16ba78bdaa377281f29972cdrobertphillips * Read the next op code and chunk size from 'reader'. The returned size 201ad00e4b245d464c16ba78bdaa377281f29972cdrobertphillips * is the entire size of the chunk (including the opcode). Thus, the 211ad00e4b245d464c16ba78bdaa377281f29972cdrobertphillips * offset just prior to calling ReadOpAndSize + 'size' is the offset 221ad00e4b245d464c16ba78bdaa377281f29972cdrobertphillips * to the next chunk's op code. This also means that the size of a chunk 231ad00e4b245d464c16ba78bdaa377281f29972cdrobertphillips * with no arguments (just an opcode) will be 4. 241ad00e4b245d464c16ba78bdaa377281f29972cdrobertphillips */ 251ad00e4b245d464c16ba78bdaa377281f29972cdrobertphillipsDrawType SkPicturePlayback::ReadOpAndSize(SkReader32* reader, uint32_t* size) { 26ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips uint32_t temp = reader->readInt(); 27ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips uint32_t op; 28ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips if (((uint8_t)temp) == temp) { 29ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips // old skp file - no size information 30ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips op = temp; 31ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips *size = 0; 32ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } else { 33ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips UNPACK_8_24(temp, op, *size); 34ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips if (MASK_24 == *size) { 35ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips *size = reader->readInt(); 36ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 37ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 38ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips return (DrawType)op; 39ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips} 40ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips 41ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips 423afef1f75f710b8f183113cdc5188416f7d01f28robertphillipsstatic const SkRect* get_rect_ptr(SkReader32* reader) { 433afef1f75f710b8f183113cdc5188416f7d01f28robertphillips if (reader->readBool()) { 443afef1f75f710b8f183113cdc5188416f7d01f28robertphillips return &reader->skipT<SkRect>(); 45ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } else { 46ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips return NULL; 47ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 48ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips} 49ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips 50ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillipsclass TextContainer { 51ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillipspublic: 52ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips size_t length() { return fByteLength; } 53ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const void* text() { return (const void*)fText; } 54ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips size_t fByteLength; 55ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const char* fText; 56ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips}; 57ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips 58ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillipsvoid get_text(SkReader32* reader, TextContainer* text) { 59ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips size_t length = text->fByteLength = reader->readInt(); 60ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips text->fText = (const char*)reader->skip(length); 61ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips} 62ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips 63eeb1f15891ee9f96f2c5d6e1c3d5a656208f3760mtklein// FIXME: SkBitmaps are stateful, so we need to copy them to play back in multiple threads. 64eeb1f15891ee9f96f2c5d6e1c3d5a656208f3760mtkleinstatic SkBitmap shallow_copy(const SkBitmap& bitmap) { 65eeb1f15891ee9f96f2c5d6e1c3d5a656208f3760mtklein return bitmap; 66eeb1f15891ee9f96f2c5d6e1c3d5a656208f3760mtklein} 67eeb1f15891ee9f96f2c5d6e1c3d5a656208f3760mtklein 68783fe16b8ed1cd1cff34eacc33296874a32f293brobertphillipsvoid SkPicturePlayback::draw(SkCanvas* canvas, SkPicture::AbortCallback* callback) { 69ec66e6264de5110802c3d9927380d913242c9d5frobertphillips AutoResetOpID aroi(this); 70ec66e6264de5110802c3d9927380d913242c9d5frobertphillips SkASSERT(0 == fCurOffset); 71ec66e6264de5110802c3d9927380d913242c9d5frobertphillips 72ec66e6264de5110802c3d9927380d913242c9d5frobertphillips SkReader32 reader(fPictureData->opData()->bytes(), fPictureData->opData()->size()); 73ec66e6264de5110802c3d9927380d913242c9d5frobertphillips 74ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips // Record this, so we can concat w/ it if we encounter a setMatrix() 75ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips SkMatrix initialMatrix = canvas->getTotalMatrix(); 76ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips 77ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips SkAutoCanvasRestore acr(canvas, false); 78ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips 79ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips while (!reader.eof()) { 80783fe16b8ed1cd1cff34eacc33296874a32f293brobertphillips if (callback && callback->abort()) { 81ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips return; 82ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 83ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips 84ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips fCurOffset = reader.offset(); 85ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips uint32_t size; 861ad00e4b245d464c16ba78bdaa377281f29972cdrobertphillips DrawType op = ReadOpAndSize(&reader, &size); 87ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips 883afef1f75f710b8f183113cdc5188416f7d01f28robertphillips this->handleOp(&reader, op, size, canvas, initialMatrix); 893afef1f75f710b8f183113cdc5188416f7d01f28robertphillips } 903afef1f75f710b8f183113cdc5188416f7d01f28robertphillips} 913afef1f75f710b8f183113cdc5188416f7d01f28robertphillips 92533eb782edaa0b6fece6166d3001edf72ec39f11mtkleinvoid SkPicturePlayback::handleOp(SkReader32* reader, 93533eb782edaa0b6fece6166d3001edf72ec39f11mtklein DrawType op, 94533eb782edaa0b6fece6166d3001edf72ec39f11mtklein uint32_t size, 953afef1f75f710b8f183113cdc5188416f7d01f28robertphillips SkCanvas* canvas, 963afef1f75f710b8f183113cdc5188416f7d01f28robertphillips const SkMatrix& initialMatrix) { 973afef1f75f710b8f183113cdc5188416f7d01f28robertphillips switch (op) { 9846616af01b412ea984a516fda1ed8ec08e689f29mtklein case NOOP: { 9946616af01b412ea984a516fda1ed8ec08e689f29mtklein SkASSERT(size >= 4); 10046616af01b412ea984a516fda1ed8ec08e689f29mtklein reader->skip(size - 4); 10146616af01b412ea984a516fda1ed8ec08e689f29mtklein } break; 102ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case CLIP_PATH: { 103ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPath& path = fPictureData->getPath(reader); 1043afef1f75f710b8f183113cdc5188416f7d01f28robertphillips uint32_t packed = reader->readInt(); 105ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips SkRegion::Op regionOp = ClipParams_unpackRegionOp(packed); 106ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips bool doAA = ClipParams_unpackDoAA(packed); 1073afef1f75f710b8f183113cdc5188416f7d01f28robertphillips size_t offsetToRestore = reader->readInt(); 1083afef1f75f710b8f183113cdc5188416f7d01f28robertphillips SkASSERT(!offsetToRestore || offsetToRestore >= reader->offset()); 109ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->clipPath(path, regionOp, doAA); 110ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips if (canvas->isClipEmpty() && offsetToRestore) { 1113afef1f75f710b8f183113cdc5188416f7d01f28robertphillips reader->setOffset(offsetToRestore); 112ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 113ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 114ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case CLIP_REGION: { 115ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips SkRegion region; 1163afef1f75f710b8f183113cdc5188416f7d01f28robertphillips reader->readRegion(®ion); 1173afef1f75f710b8f183113cdc5188416f7d01f28robertphillips uint32_t packed = reader->readInt(); 118ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips SkRegion::Op regionOp = ClipParams_unpackRegionOp(packed); 1193afef1f75f710b8f183113cdc5188416f7d01f28robertphillips size_t offsetToRestore = reader->readInt(); 1203afef1f75f710b8f183113cdc5188416f7d01f28robertphillips SkASSERT(!offsetToRestore || offsetToRestore >= reader->offset()); 121ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->clipRegion(region, regionOp); 122ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips if (canvas->isClipEmpty() && offsetToRestore) { 1233afef1f75f710b8f183113cdc5188416f7d01f28robertphillips reader->setOffset(offsetToRestore); 124ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 125ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 126ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case CLIP_RECT: { 1273afef1f75f710b8f183113cdc5188416f7d01f28robertphillips const SkRect& rect = reader->skipT<SkRect>(); 1283afef1f75f710b8f183113cdc5188416f7d01f28robertphillips uint32_t packed = reader->readInt(); 129ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips SkRegion::Op regionOp = ClipParams_unpackRegionOp(packed); 130ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips bool doAA = ClipParams_unpackDoAA(packed); 1313afef1f75f710b8f183113cdc5188416f7d01f28robertphillips size_t offsetToRestore = reader->readInt(); 1323afef1f75f710b8f183113cdc5188416f7d01f28robertphillips SkASSERT(!offsetToRestore || offsetToRestore >= reader->offset()); 133ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->clipRect(rect, regionOp, doAA); 134ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips if (canvas->isClipEmpty() && offsetToRestore) { 1353afef1f75f710b8f183113cdc5188416f7d01f28robertphillips reader->setOffset(offsetToRestore); 136ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 137ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 138ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case CLIP_RRECT: { 139ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips SkRRect rrect; 1403afef1f75f710b8f183113cdc5188416f7d01f28robertphillips reader->readRRect(&rrect); 1413afef1f75f710b8f183113cdc5188416f7d01f28robertphillips uint32_t packed = reader->readInt(); 142ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips SkRegion::Op regionOp = ClipParams_unpackRegionOp(packed); 143ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips bool doAA = ClipParams_unpackDoAA(packed); 1443afef1f75f710b8f183113cdc5188416f7d01f28robertphillips size_t offsetToRestore = reader->readInt(); 1453afef1f75f710b8f183113cdc5188416f7d01f28robertphillips SkASSERT(!offsetToRestore || offsetToRestore >= reader->offset()); 146ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->clipRRect(rrect, regionOp, doAA); 147ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips if (canvas->isClipEmpty() && offsetToRestore) { 1483afef1f75f710b8f183113cdc5188416f7d01f28robertphillips reader->setOffset(offsetToRestore); 149ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 150ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 151f0f14113431ace669f278fdd97b50950f2cf4c80mtklein case PUSH_CULL: break; // Deprecated, safe to ignore both push and pop. 152f0f14113431ace669f278fdd97b50950f2cf4c80mtklein case POP_CULL: break; 153ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case CONCAT: { 154ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips SkMatrix matrix; 1553afef1f75f710b8f183113cdc5188416f7d01f28robertphillips reader->readMatrix(&matrix); 156ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->concat(matrix); 157ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips break; 158ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 159ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_BITMAP: { 160ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint* paint = fPictureData->getPaint(reader); 161eeb1f15891ee9f96f2c5d6e1c3d5a656208f3760mtklein const SkBitmap bitmap = shallow_copy(fPictureData->getBitmap(reader)); 1623afef1f75f710b8f183113cdc5188416f7d01f28robertphillips const SkPoint& loc = reader->skipT<SkPoint>(); 163ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->drawBitmap(bitmap, loc.fX, loc.fY, paint); 164ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 165ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_BITMAP_RECT_TO_RECT: { 166ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint* paint = fPictureData->getPaint(reader); 167eeb1f15891ee9f96f2c5d6e1c3d5a656208f3760mtklein const SkBitmap bitmap = shallow_copy(fPictureData->getBitmap(reader)); 168ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkRect* src = get_rect_ptr(reader); // may be null 1693afef1f75f710b8f183113cdc5188416f7d01f28robertphillips const SkRect& dst = reader->skipT<SkRect>(); // required 170ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips SkCanvas::DrawBitmapRectFlags flags; 1713afef1f75f710b8f183113cdc5188416f7d01f28robertphillips flags = (SkCanvas::DrawBitmapRectFlags) reader->readInt(); 172ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->drawBitmapRectToRect(bitmap, src, dst, paint, flags); 173ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 174ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_BITMAP_MATRIX: { 175ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint* paint = fPictureData->getPaint(reader); 176eeb1f15891ee9f96f2c5d6e1c3d5a656208f3760mtklein const SkBitmap bitmap = shallow_copy(fPictureData->getBitmap(reader)); 177ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips SkMatrix matrix; 1783afef1f75f710b8f183113cdc5188416f7d01f28robertphillips reader->readMatrix(&matrix); 179c54d8db4d169ea5f2af2a9a2349df007bd428475Florin Malita 180c54d8db4d169ea5f2af2a9a2349df007bd428475Florin Malita SkAutoCanvasRestore acr(canvas, true); 181c54d8db4d169ea5f2af2a9a2349df007bd428475Florin Malita canvas->concat(matrix); 182c54d8db4d169ea5f2af2a9a2349df007bd428475Florin Malita canvas->drawBitmap(bitmap, 0, 0, paint); 183ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 184ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_BITMAP_NINE: { 185ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint* paint = fPictureData->getPaint(reader); 186eeb1f15891ee9f96f2c5d6e1c3d5a656208f3760mtklein const SkBitmap bitmap = shallow_copy(fPictureData->getBitmap(reader)); 1873afef1f75f710b8f183113cdc5188416f7d01f28robertphillips const SkIRect& src = reader->skipT<SkIRect>(); 1883afef1f75f710b8f183113cdc5188416f7d01f28robertphillips const SkRect& dst = reader->skipT<SkRect>(); 189ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->drawBitmapNine(bitmap, src, dst, paint); 190ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 191ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_CLEAR: 1923afef1f75f710b8f183113cdc5188416f7d01f28robertphillips canvas->clear(reader->readInt()); 193ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips break; 194ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_DATA: { 195c4fda92f45b9649f233a5b8636618a6431aa59cbreed // This opcode is now dead, just need to skip it for backwards compatibility 1963afef1f75f710b8f183113cdc5188416f7d01f28robertphillips size_t length = reader->readInt(); 197c4fda92f45b9649f233a5b8636618a6431aa59cbreed (void)reader->skip(length); 198ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips // skip handles padding the read out to a multiple of 4 199ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 200ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_DRRECT: { 201ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint& paint = *fPictureData->getPaint(reader); 202ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips SkRRect outer, inner; 2033afef1f75f710b8f183113cdc5188416f7d01f28robertphillips reader->readRRect(&outer); 2043afef1f75f710b8f183113cdc5188416f7d01f28robertphillips reader->readRRect(&inner); 205ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->drawDRRect(outer, inner, paint); 206ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 207ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case BEGIN_COMMENT_GROUP: { 2083afef1f75f710b8f183113cdc5188416f7d01f28robertphillips const char* desc = reader->readString(); 209ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->beginCommentGroup(desc); 210ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 211ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case COMMENT: { 2123afef1f75f710b8f183113cdc5188416f7d01f28robertphillips const char* kywd = reader->readString(); 2133afef1f75f710b8f183113cdc5188416f7d01f28robertphillips const char* value = reader->readString(); 214ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->addComment(kywd, value); 215ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 216ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case END_COMMENT_GROUP: { 217ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->endCommentGroup(); 218ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 219ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_OVAL: { 220ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint& paint = *fPictureData->getPaint(reader); 2213afef1f75f710b8f183113cdc5188416f7d01f28robertphillips canvas->drawOval(reader->skipT<SkRect>(), paint); 222ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 223ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_PAINT: 224ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->drawPaint(*fPictureData->getPaint(reader)); 225ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips break; 226963137b75c0a1fe91f35e9826742f36309f5e65ddandov case DRAW_PATCH: { 227963137b75c0a1fe91f35e9826742f36309f5e65ddandov const SkPaint& paint = *fPictureData->getPaint(reader); 228533eb782edaa0b6fece6166d3001edf72ec39f11mtklein 229b3c9d1c33caf325aada244204215eb790c228c12dandov const SkPoint* cubics = (const SkPoint*)reader->skip(SkPatchUtils::kNumCtrlPts * 230b3c9d1c33caf325aada244204215eb790c228c12dandov sizeof(SkPoint)); 231b3c9d1c33caf325aada244204215eb790c228c12dandov uint32_t flag = reader->readInt(); 232b3c9d1c33caf325aada244204215eb790c228c12dandov const SkColor* colors = NULL; 233b3c9d1c33caf325aada244204215eb790c228c12dandov if (flag & DRAW_VERTICES_HAS_COLORS) { 234b3c9d1c33caf325aada244204215eb790c228c12dandov colors = (const SkColor*)reader->skip(SkPatchUtils::kNumCorners * sizeof(SkColor)); 235b3c9d1c33caf325aada244204215eb790c228c12dandov } 236b3c9d1c33caf325aada244204215eb790c228c12dandov const SkPoint* texCoords = NULL; 237b3c9d1c33caf325aada244204215eb790c228c12dandov if (flag & DRAW_VERTICES_HAS_TEXS) { 238b3c9d1c33caf325aada244204215eb790c228c12dandov texCoords = (const SkPoint*)reader->skip(SkPatchUtils::kNumCorners * 239b3c9d1c33caf325aada244204215eb790c228c12dandov sizeof(SkPoint)); 240b3c9d1c33caf325aada244204215eb790c228c12dandov } 241b3c9d1c33caf325aada244204215eb790c228c12dandov SkAutoTUnref<SkXfermode> xfer; 242b3c9d1c33caf325aada244204215eb790c228c12dandov if (flag & DRAW_VERTICES_HAS_XFER) { 243b3c9d1c33caf325aada244204215eb790c228c12dandov int mode = reader->readInt(); 244b3c9d1c33caf325aada244204215eb790c228c12dandov if (mode < 0 || mode > SkXfermode::kLastMode) { 245b3c9d1c33caf325aada244204215eb790c228c12dandov mode = SkXfermode::kModulate_Mode; 246b3c9d1c33caf325aada244204215eb790c228c12dandov } 247b3c9d1c33caf325aada244204215eb790c228c12dandov xfer.reset(SkXfermode::Create((SkXfermode::Mode)mode)); 248b3c9d1c33caf325aada244204215eb790c228c12dandov } 249b3c9d1c33caf325aada244204215eb790c228c12dandov canvas->drawPatch(cubics, colors, texCoords, xfer, paint); 250963137b75c0a1fe91f35e9826742f36309f5e65ddandov } break; 251ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_PATH: { 252ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint& paint = *fPictureData->getPaint(reader); 253ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->drawPath(fPictureData->getPath(reader), paint); 254ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 255ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_PICTURE: 256ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->drawPicture(fPictureData->getPicture(reader)); 257ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips break; 258d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed case DRAW_PICTURE_MATRIX_PAINT: { 2599f49cfdbf6493b953775890d7f9c97a1dce0d341fmalita const SkPaint* paint = fPictureData->getPaint(reader); 260d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed SkMatrix matrix; 261d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed reader->readMatrix(&matrix); 2629f49cfdbf6493b953775890d7f9c97a1dce0d341fmalita const SkPicture* pic = fPictureData->getPicture(reader); 263d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed canvas->drawPicture(pic, &matrix, paint); 264d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } break; 265ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_POINTS: { 266ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint& paint = *fPictureData->getPaint(reader); 2673afef1f75f710b8f183113cdc5188416f7d01f28robertphillips SkCanvas::PointMode mode = (SkCanvas::PointMode)reader->readInt(); 2683afef1f75f710b8f183113cdc5188416f7d01f28robertphillips size_t count = reader->readInt(); 2693afef1f75f710b8f183113cdc5188416f7d01f28robertphillips const SkPoint* pts = (const SkPoint*)reader->skip(sizeof(SkPoint)* count); 270ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->drawPoints(mode, count, pts, paint); 271ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 272ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_POS_TEXT: { 273ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint& paint = *fPictureData->getPaint(reader); 2743afef1f75f710b8f183113cdc5188416f7d01f28robertphillips TextContainer text; 2753afef1f75f710b8f183113cdc5188416f7d01f28robertphillips get_text(reader, &text); 2763afef1f75f710b8f183113cdc5188416f7d01f28robertphillips size_t points = reader->readInt(); 2773afef1f75f710b8f183113cdc5188416f7d01f28robertphillips const SkPoint* pos = (const SkPoint*)reader->skip(points * sizeof(SkPoint)); 278ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->drawPosText(text.text(), text.length(), pos, paint); 279ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 280ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_POS_TEXT_TOP_BOTTOM: { 281ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint& paint = *fPictureData->getPaint(reader); 2823afef1f75f710b8f183113cdc5188416f7d01f28robertphillips TextContainer text; 2833afef1f75f710b8f183113cdc5188416f7d01f28robertphillips get_text(reader, &text); 2843afef1f75f710b8f183113cdc5188416f7d01f28robertphillips size_t points = reader->readInt(); 2853afef1f75f710b8f183113cdc5188416f7d01f28robertphillips const SkPoint* pos = (const SkPoint*)reader->skip(points * sizeof(SkPoint)); 2863afef1f75f710b8f183113cdc5188416f7d01f28robertphillips const SkScalar top = reader->readScalar(); 2873afef1f75f710b8f183113cdc5188416f7d01f28robertphillips const SkScalar bottom = reader->readScalar(); 288ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips if (!canvas->quickRejectY(top, bottom)) { 289ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->drawPosText(text.text(), text.length(), pos, paint); 290ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 291ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 292ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_POS_TEXT_H: { 293ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint& paint = *fPictureData->getPaint(reader); 2943afef1f75f710b8f183113cdc5188416f7d01f28robertphillips TextContainer text; 2953afef1f75f710b8f183113cdc5188416f7d01f28robertphillips get_text(reader, &text); 2963afef1f75f710b8f183113cdc5188416f7d01f28robertphillips size_t xCount = reader->readInt(); 2973afef1f75f710b8f183113cdc5188416f7d01f28robertphillips const SkScalar constY = reader->readScalar(); 2983afef1f75f710b8f183113cdc5188416f7d01f28robertphillips const SkScalar* xpos = (const SkScalar*)reader->skip(xCount * sizeof(SkScalar)); 299ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->drawPosTextH(text.text(), text.length(), xpos, constY, paint); 300ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 301ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_POS_TEXT_H_TOP_BOTTOM: { 302ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint& paint = *fPictureData->getPaint(reader); 3033afef1f75f710b8f183113cdc5188416f7d01f28robertphillips TextContainer text; 3043afef1f75f710b8f183113cdc5188416f7d01f28robertphillips get_text(reader, &text); 3053afef1f75f710b8f183113cdc5188416f7d01f28robertphillips size_t xCount = reader->readInt(); 3063afef1f75f710b8f183113cdc5188416f7d01f28robertphillips const SkScalar* xpos = (const SkScalar*)reader->skip((3 + xCount) * sizeof(SkScalar)); 307ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkScalar top = *xpos++; 308ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkScalar bottom = *xpos++; 309ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkScalar constY = *xpos++; 310ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips if (!canvas->quickRejectY(top, bottom)) { 311ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->drawPosTextH(text.text(), text.length(), xpos, constY, paint); 312ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 313ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 314ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_RECT: { 315ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint& paint = *fPictureData->getPaint(reader); 3163afef1f75f710b8f183113cdc5188416f7d01f28robertphillips canvas->drawRect(reader->skipT<SkRect>(), paint); 317ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 318ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_RRECT: { 319ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint& paint = *fPictureData->getPaint(reader); 320ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips SkRRect rrect; 3213afef1f75f710b8f183113cdc5188416f7d01f28robertphillips reader->readRRect(&rrect); 322ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->drawRRect(rrect, paint); 323ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 324ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_SPRITE: { 325ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint* paint = fPictureData->getPaint(reader); 326eeb1f15891ee9f96f2c5d6e1c3d5a656208f3760mtklein const SkBitmap bitmap = shallow_copy(fPictureData->getBitmap(reader)); 3273afef1f75f710b8f183113cdc5188416f7d01f28robertphillips int left = reader->readInt(); 3283afef1f75f710b8f183113cdc5188416f7d01f28robertphillips int top = reader->readInt(); 329ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->drawSprite(bitmap, left, top, paint); 330ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 331ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_TEXT: { 332ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint& paint = *fPictureData->getPaint(reader); 3333afef1f75f710b8f183113cdc5188416f7d01f28robertphillips TextContainer text; 3343afef1f75f710b8f183113cdc5188416f7d01f28robertphillips get_text(reader, &text); 3353afef1f75f710b8f183113cdc5188416f7d01f28robertphillips SkScalar x = reader->readScalar(); 3363afef1f75f710b8f183113cdc5188416f7d01f28robertphillips SkScalar y = reader->readScalar(); 337ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->drawText(text.text(), text.length(), x, y, paint); 338ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 339b7425173f96e93b090787e2386ba5f022b6c2869fmalita case DRAW_TEXT_BLOB: { 340b7425173f96e93b090787e2386ba5f022b6c2869fmalita const SkPaint& paint = *fPictureData->getPaint(reader); 341b7425173f96e93b090787e2386ba5f022b6c2869fmalita const SkTextBlob* blob = fPictureData->getTextBlob(reader); 342b7425173f96e93b090787e2386ba5f022b6c2869fmalita SkScalar x = reader->readScalar(); 343b7425173f96e93b090787e2386ba5f022b6c2869fmalita SkScalar y = reader->readScalar(); 344b7425173f96e93b090787e2386ba5f022b6c2869fmalita canvas->drawTextBlob(blob, x, y, paint); 345b7425173f96e93b090787e2386ba5f022b6c2869fmalita } break; 346ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_TEXT_TOP_BOTTOM: { 347ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint& paint = *fPictureData->getPaint(reader); 3483afef1f75f710b8f183113cdc5188416f7d01f28robertphillips TextContainer text; 3493afef1f75f710b8f183113cdc5188416f7d01f28robertphillips get_text(reader, &text); 3503afef1f75f710b8f183113cdc5188416f7d01f28robertphillips const SkScalar* ptr = (const SkScalar*)reader->skip(4 * sizeof(SkScalar)); 351ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips // ptr[0] == x 352ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips // ptr[1] == y 353ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips // ptr[2] == top 354ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips // ptr[3] == bottom 355ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips if (!canvas->quickRejectY(ptr[2], ptr[3])) { 356ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->drawText(text.text(), text.length(), ptr[0], ptr[1], paint); 357ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 358ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 359ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_TEXT_ON_PATH: { 360ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint& paint = *fPictureData->getPaint(reader); 3613afef1f75f710b8f183113cdc5188416f7d01f28robertphillips TextContainer text; 3623afef1f75f710b8f183113cdc5188416f7d01f28robertphillips get_text(reader, &text); 363ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPath& path = fPictureData->getPath(reader); 364ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips SkMatrix matrix; 3653afef1f75f710b8f183113cdc5188416f7d01f28robertphillips reader->readMatrix(&matrix); 366ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->drawTextOnPath(text.text(), text.length(), path, &matrix, paint); 367ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 368ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_VERTICES: { 369ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips SkAutoTUnref<SkXfermode> xfer; 370ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint& paint = *fPictureData->getPaint(reader); 3713afef1f75f710b8f183113cdc5188416f7d01f28robertphillips DrawVertexFlags flags = (DrawVertexFlags)reader->readInt(); 3723afef1f75f710b8f183113cdc5188416f7d01f28robertphillips SkCanvas::VertexMode vmode = (SkCanvas::VertexMode)reader->readInt(); 3733afef1f75f710b8f183113cdc5188416f7d01f28robertphillips int vCount = reader->readInt(); 3743afef1f75f710b8f183113cdc5188416f7d01f28robertphillips const SkPoint* verts = (const SkPoint*)reader->skip(vCount * sizeof(SkPoint)); 375ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPoint* texs = NULL; 376ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkColor* colors = NULL; 377ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const uint16_t* indices = NULL; 378ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips int iCount = 0; 379ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips if (flags & DRAW_VERTICES_HAS_TEXS) { 3803afef1f75f710b8f183113cdc5188416f7d01f28robertphillips texs = (const SkPoint*)reader->skip(vCount * sizeof(SkPoint)); 381ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 382ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips if (flags & DRAW_VERTICES_HAS_COLORS) { 3833afef1f75f710b8f183113cdc5188416f7d01f28robertphillips colors = (const SkColor*)reader->skip(vCount * sizeof(SkColor)); 384ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 385ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips if (flags & DRAW_VERTICES_HAS_INDICES) { 3863afef1f75f710b8f183113cdc5188416f7d01f28robertphillips iCount = reader->readInt(); 3873afef1f75f710b8f183113cdc5188416f7d01f28robertphillips indices = (const uint16_t*)reader->skip(iCount * sizeof(uint16_t)); 388ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 389ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips if (flags & DRAW_VERTICES_HAS_XFER) { 3903afef1f75f710b8f183113cdc5188416f7d01f28robertphillips int mode = reader->readInt(); 391ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips if (mode < 0 || mode > SkXfermode::kLastMode) { 392ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips mode = SkXfermode::kModulate_Mode; 393ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 394ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips xfer.reset(SkXfermode::Create((SkXfermode::Mode)mode)); 395ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 396ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->drawVertices(vmode, vCount, verts, texs, colors, xfer, indices, iCount, paint); 397ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 398ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case RESTORE: 399ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->restore(); 400ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips break; 401ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case ROTATE: 4023afef1f75f710b8f183113cdc5188416f7d01f28robertphillips canvas->rotate(reader->readScalar()); 403ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips break; 404ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case SAVE: 405ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips // SKPs with version < 29 also store a SaveFlags param. 406ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips if (size > 4) { 407ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips SkASSERT(8 == size); 4083afef1f75f710b8f183113cdc5188416f7d01f28robertphillips reader->readInt(); 409ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 410ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->save(); 411ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips break; 412ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case SAVE_LAYER: { 413ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkRect* boundsPtr = get_rect_ptr(reader); 414ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint* paint = fPictureData->getPaint(reader); 4153afef1f75f710b8f183113cdc5188416f7d01f28robertphillips canvas->saveLayer(boundsPtr, paint, (SkCanvas::SaveFlags) reader->readInt()); 416ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 417ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case SCALE: { 4183afef1f75f710b8f183113cdc5188416f7d01f28robertphillips SkScalar sx = reader->readScalar(); 4193afef1f75f710b8f183113cdc5188416f7d01f28robertphillips SkScalar sy = reader->readScalar(); 420ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->scale(sx, sy); 421ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 422ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case SET_MATRIX: { 423ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips SkMatrix matrix; 4243afef1f75f710b8f183113cdc5188416f7d01f28robertphillips reader->readMatrix(&matrix); 425ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips matrix.postConcat(initialMatrix); 426ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->setMatrix(matrix); 427ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 428ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case SKEW: { 4293afef1f75f710b8f183113cdc5188416f7d01f28robertphillips SkScalar sx = reader->readScalar(); 4303afef1f75f710b8f183113cdc5188416f7d01f28robertphillips SkScalar sy = reader->readScalar(); 431ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->skew(sx, sy); 432ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 433ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case TRANSLATE: { 4343afef1f75f710b8f183113cdc5188416f7d01f28robertphillips SkScalar dx = reader->readScalar(); 4353afef1f75f710b8f183113cdc5188416f7d01f28robertphillips SkScalar dy = reader->readScalar(); 436ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->translate(dx, dy); 437ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 438ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips default: 43946616af01b412ea984a516fda1ed8ec08e689f29mtklein SkASSERTF(false, "Unknown draw type: %d", op); 440ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 441ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips} 442ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips 443