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 "SkPictureStateTree.h" 14ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips#include "SkReader32.h" 15b7425173f96e93b090787e2386ba5f022b6c2869fmalita#include "SkTextBlob.h" 16ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips#include "SkTDArray.h" 17ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips#include "SkTypes.h" 18ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips 19ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips/* 201ad00e4b245d464c16ba78bdaa377281f29972cdrobertphillips * Read the next op code and chunk size from 'reader'. The returned size 211ad00e4b245d464c16ba78bdaa377281f29972cdrobertphillips * is the entire size of the chunk (including the opcode). Thus, the 221ad00e4b245d464c16ba78bdaa377281f29972cdrobertphillips * offset just prior to calling ReadOpAndSize + 'size' is the offset 231ad00e4b245d464c16ba78bdaa377281f29972cdrobertphillips * to the next chunk's op code. This also means that the size of a chunk 241ad00e4b245d464c16ba78bdaa377281f29972cdrobertphillips * with no arguments (just an opcode) will be 4. 251ad00e4b245d464c16ba78bdaa377281f29972cdrobertphillips */ 261ad00e4b245d464c16ba78bdaa377281f29972cdrobertphillipsDrawType SkPicturePlayback::ReadOpAndSize(SkReader32* reader, uint32_t* size) { 27ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips uint32_t temp = reader->readInt(); 28ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips uint32_t op; 29ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips if (((uint8_t)temp) == temp) { 30ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips // old skp file - no size information 31ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips op = temp; 32ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips *size = 0; 33ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } else { 34ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips UNPACK_8_24(temp, op, *size); 35ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips if (MASK_24 == *size) { 36ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips *size = reader->readInt(); 37ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 38ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 39ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips return (DrawType)op; 40ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips} 41ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips 42ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips 433afef1f75f710b8f183113cdc5188416f7d01f28robertphillipsstatic const SkRect* get_rect_ptr(SkReader32* reader) { 443afef1f75f710b8f183113cdc5188416f7d01f28robertphillips if (reader->readBool()) { 453afef1f75f710b8f183113cdc5188416f7d01f28robertphillips return &reader->skipT<SkRect>(); 46ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } else { 47ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips return NULL; 48ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 49ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips} 50ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips 51ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillipsclass TextContainer { 52ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillipspublic: 53ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips size_t length() { return fByteLength; } 54ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const void* text() { return (const void*)fText; } 55ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips size_t fByteLength; 56ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const char* fText; 57ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips}; 58ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips 59ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillipsvoid get_text(SkReader32* reader, TextContainer* text) { 60ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips size_t length = text->fByteLength = reader->readInt(); 61ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips text->fText = (const char*)reader->skip(length); 62ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips} 63ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips 64eeb1f15891ee9f96f2c5d6e1c3d5a656208f3760mtklein// FIXME: SkBitmaps are stateful, so we need to copy them to play back in multiple threads. 65eeb1f15891ee9f96f2c5d6e1c3d5a656208f3760mtkleinstatic SkBitmap shallow_copy(const SkBitmap& bitmap) { 66eeb1f15891ee9f96f2c5d6e1c3d5a656208f3760mtklein return bitmap; 67eeb1f15891ee9f96f2c5d6e1c3d5a656208f3760mtklein} 68eeb1f15891ee9f96f2c5d6e1c3d5a656208f3760mtklein 69ec66e6264de5110802c3d9927380d913242c9d5frobertphillipsconst SkPicture::OperationList* SkPicturePlayback::getActiveOps(const SkCanvas* canvas) { 70ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips 716142609b22814283210f79d698182b651a93136crobertphillips if (fUseBBH) { 721ad00e4b245d464c16ba78bdaa377281f29972cdrobertphillips SkRect clipBounds; 731ad00e4b245d464c16ba78bdaa377281f29972cdrobertphillips if (canvas->getClipBounds(&clipBounds)) { 74533eb782edaa0b6fece6166d3001edf72ec39f11mtklein return fPictureData->getActiveOps(clipBounds); 75ec66e6264de5110802c3d9927380d913242c9d5frobertphillips } 76533eb782edaa0b6fece6166d3001edf72ec39f11mtklein } 77ec66e6264de5110802c3d9927380d913242c9d5frobertphillips 78ec66e6264de5110802c3d9927380d913242c9d5frobertphillips return NULL; 79ec66e6264de5110802c3d9927380d913242c9d5frobertphillips} 80ec66e6264de5110802c3d9927380d913242c9d5frobertphillips 81ec66e6264de5110802c3d9927380d913242c9d5frobertphillips// Initialize the state tree iterator. Return false if there is nothing left to draw. 82533eb782edaa0b6fece6166d3001edf72ec39f11mtkleinbool SkPicturePlayback::initIterator(SkPictureStateTree::Iterator* iter, 83ec66e6264de5110802c3d9927380d913242c9d5frobertphillips SkCanvas* canvas, 84ec66e6264de5110802c3d9927380d913242c9d5frobertphillips const SkPicture::OperationList *activeOpsList) { 85ec66e6264de5110802c3d9927380d913242c9d5frobertphillips 8649f085dddff10473b6ebf832a974288300224e60bsalomon if (activeOpsList) { 87ec66e6264de5110802c3d9927380d913242c9d5frobertphillips if (0 == activeOpsList->numOps()) { 88ec66e6264de5110802c3d9927380d913242c9d5frobertphillips return false; // nothing to draw 89ec66e6264de5110802c3d9927380d913242c9d5frobertphillips } 90ec66e6264de5110802c3d9927380d913242c9d5frobertphillips 916142609b22814283210f79d698182b651a93136crobertphillips fPictureData->initIterator(iter, activeOpsList->fOps, canvas); 92ec66e6264de5110802c3d9927380d913242c9d5frobertphillips } 93ec66e6264de5110802c3d9927380d913242c9d5frobertphillips 94ec66e6264de5110802c3d9927380d913242c9d5frobertphillips return true; 95ec66e6264de5110802c3d9927380d913242c9d5frobertphillips} 96ec66e6264de5110802c3d9927380d913242c9d5frobertphillips 97ec66e6264de5110802c3d9927380d913242c9d5frobertphillips// If 'iter' is valid use it to skip forward through the picture. 98ec66e6264de5110802c3d9927380d913242c9d5frobertphillipsvoid SkPicturePlayback::StepIterator(SkPictureStateTree::Iterator* iter, SkReader32* reader) { 99ec66e6264de5110802c3d9927380d913242c9d5frobertphillips if (iter->isValid()) { 100ec66e6264de5110802c3d9927380d913242c9d5frobertphillips uint32_t skipTo = iter->nextDraw(); 101ec66e6264de5110802c3d9927380d913242c9d5frobertphillips if (SkPictureStateTree::Iterator::kDrawComplete == skipTo) { 102ec66e6264de5110802c3d9927380d913242c9d5frobertphillips reader->setOffset(reader->size()); // skip to end 103ec66e6264de5110802c3d9927380d913242c9d5frobertphillips } else { 104ec66e6264de5110802c3d9927380d913242c9d5frobertphillips reader->setOffset(skipTo); 105ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 106ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 107ec66e6264de5110802c3d9927380d913242c9d5frobertphillips} 108ec66e6264de5110802c3d9927380d913242c9d5frobertphillips 109ec66e6264de5110802c3d9927380d913242c9d5frobertphillips// Update the iterator and state tree to catch up with the skipped ops. 110ec66e6264de5110802c3d9927380d913242c9d5frobertphillipsvoid SkPicturePlayback::SkipIterTo(SkPictureStateTree::Iterator* iter, 111ec66e6264de5110802c3d9927380d913242c9d5frobertphillips SkReader32* reader, 112ec66e6264de5110802c3d9927380d913242c9d5frobertphillips uint32_t skipTo) { 113ec66e6264de5110802c3d9927380d913242c9d5frobertphillips SkASSERT(skipTo <= reader->size()); 114ec66e6264de5110802c3d9927380d913242c9d5frobertphillips SkASSERT(reader->offset() <= skipTo); // should only be skipping forward 115ec66e6264de5110802c3d9927380d913242c9d5frobertphillips 116ec66e6264de5110802c3d9927380d913242c9d5frobertphillips if (iter->isValid()) { 117ec66e6264de5110802c3d9927380d913242c9d5frobertphillips // If using a bounding box hierarchy, advance the state tree 118ec66e6264de5110802c3d9927380d913242c9d5frobertphillips // iterator until at or after skipTo 119ec66e6264de5110802c3d9927380d913242c9d5frobertphillips uint32_t adjustedSkipTo; 120ec66e6264de5110802c3d9927380d913242c9d5frobertphillips do { 121ec66e6264de5110802c3d9927380d913242c9d5frobertphillips adjustedSkipTo = iter->nextDraw(); 122ec66e6264de5110802c3d9927380d913242c9d5frobertphillips } while (adjustedSkipTo < skipTo); 123ec66e6264de5110802c3d9927380d913242c9d5frobertphillips skipTo = adjustedSkipTo; 124ec66e6264de5110802c3d9927380d913242c9d5frobertphillips } 125ec66e6264de5110802c3d9927380d913242c9d5frobertphillips if (SkPictureStateTree::Iterator::kDrawComplete == skipTo) { 126ec66e6264de5110802c3d9927380d913242c9d5frobertphillips reader->setOffset(reader->size()); // skip to end 127ec66e6264de5110802c3d9927380d913242c9d5frobertphillips } else { 128ec66e6264de5110802c3d9927380d913242c9d5frobertphillips reader->setOffset(skipTo); 129ec66e6264de5110802c3d9927380d913242c9d5frobertphillips } 130ec66e6264de5110802c3d9927380d913242c9d5frobertphillips} 131ec66e6264de5110802c3d9927380d913242c9d5frobertphillips 132ec66e6264de5110802c3d9927380d913242c9d5frobertphillipsvoid SkPicturePlayback::draw(SkCanvas* canvas, SkDrawPictureCallback* callback) { 133ec66e6264de5110802c3d9927380d913242c9d5frobertphillips AutoResetOpID aroi(this); 134ec66e6264de5110802c3d9927380d913242c9d5frobertphillips SkASSERT(0 == fCurOffset); 135ec66e6264de5110802c3d9927380d913242c9d5frobertphillips 136ec66e6264de5110802c3d9927380d913242c9d5frobertphillips SkAutoTDelete<const SkPicture::OperationList> activeOpsList(this->getActiveOps(canvas)); 137ec66e6264de5110802c3d9927380d913242c9d5frobertphillips SkPictureStateTree::Iterator it; 138ec66e6264de5110802c3d9927380d913242c9d5frobertphillips 139ec66e6264de5110802c3d9927380d913242c9d5frobertphillips if (!this->initIterator(&it, canvas, activeOpsList.get())) { 140ec66e6264de5110802c3d9927380d913242c9d5frobertphillips return; // nothing to draw 141ec66e6264de5110802c3d9927380d913242c9d5frobertphillips } 142ec66e6264de5110802c3d9927380d913242c9d5frobertphillips 143ec66e6264de5110802c3d9927380d913242c9d5frobertphillips SkReader32 reader(fPictureData->opData()->bytes(), fPictureData->opData()->size()); 144ec66e6264de5110802c3d9927380d913242c9d5frobertphillips 145ec66e6264de5110802c3d9927380d913242c9d5frobertphillips StepIterator(&it, &reader); 146ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips 147ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips // Record this, so we can concat w/ it if we encounter a setMatrix() 148ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips SkMatrix initialMatrix = canvas->getTotalMatrix(); 149ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips 150ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips SkAutoCanvasRestore acr(canvas, false); 151ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips 152ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips while (!reader.eof()) { 15349f085dddff10473b6ebf832a974288300224e60bsalomon if (callback && callback->abortDrawing()) { 154ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips return; 155ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 156ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips 157ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips fCurOffset = reader.offset(); 158ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips uint32_t size; 1591ad00e4b245d464c16ba78bdaa377281f29972cdrobertphillips DrawType op = ReadOpAndSize(&reader, &size); 160ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips if (NOOP == op) { 161ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips // NOOPs are to be ignored - do not propagate them any further 162ec66e6264de5110802c3d9927380d913242c9d5frobertphillips SkipIterTo(&it, &reader, fCurOffset + size); 163ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips continue; 164ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 165ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips 1663afef1f75f710b8f183113cdc5188416f7d01f28robertphillips this->handleOp(&reader, op, size, canvas, initialMatrix); 1673afef1f75f710b8f183113cdc5188416f7d01f28robertphillips 168ec66e6264de5110802c3d9927380d913242c9d5frobertphillips StepIterator(&it, &reader); 1693afef1f75f710b8f183113cdc5188416f7d01f28robertphillips } 1703afef1f75f710b8f183113cdc5188416f7d01f28robertphillips} 1713afef1f75f710b8f183113cdc5188416f7d01f28robertphillips 172533eb782edaa0b6fece6166d3001edf72ec39f11mtkleinvoid SkPicturePlayback::handleOp(SkReader32* reader, 173533eb782edaa0b6fece6166d3001edf72ec39f11mtklein DrawType op, 174533eb782edaa0b6fece6166d3001edf72ec39f11mtklein uint32_t size, 1753afef1f75f710b8f183113cdc5188416f7d01f28robertphillips SkCanvas* canvas, 1763afef1f75f710b8f183113cdc5188416f7d01f28robertphillips const SkMatrix& initialMatrix) { 1773afef1f75f710b8f183113cdc5188416f7d01f28robertphillips switch (op) { 178ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case CLIP_PATH: { 179ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPath& path = fPictureData->getPath(reader); 1803afef1f75f710b8f183113cdc5188416f7d01f28robertphillips uint32_t packed = reader->readInt(); 181ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips SkRegion::Op regionOp = ClipParams_unpackRegionOp(packed); 182ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips bool doAA = ClipParams_unpackDoAA(packed); 1833afef1f75f710b8f183113cdc5188416f7d01f28robertphillips size_t offsetToRestore = reader->readInt(); 1843afef1f75f710b8f183113cdc5188416f7d01f28robertphillips SkASSERT(!offsetToRestore || offsetToRestore >= reader->offset()); 185ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->clipPath(path, regionOp, doAA); 186ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips if (canvas->isClipEmpty() && offsetToRestore) { 1873afef1f75f710b8f183113cdc5188416f7d01f28robertphillips reader->setOffset(offsetToRestore); 188ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 189ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 190ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case CLIP_REGION: { 191ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips SkRegion region; 1923afef1f75f710b8f183113cdc5188416f7d01f28robertphillips reader->readRegion(®ion); 1933afef1f75f710b8f183113cdc5188416f7d01f28robertphillips uint32_t packed = reader->readInt(); 194ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips SkRegion::Op regionOp = ClipParams_unpackRegionOp(packed); 1953afef1f75f710b8f183113cdc5188416f7d01f28robertphillips size_t offsetToRestore = reader->readInt(); 1963afef1f75f710b8f183113cdc5188416f7d01f28robertphillips SkASSERT(!offsetToRestore || offsetToRestore >= reader->offset()); 197ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->clipRegion(region, regionOp); 198ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips if (canvas->isClipEmpty() && offsetToRestore) { 1993afef1f75f710b8f183113cdc5188416f7d01f28robertphillips reader->setOffset(offsetToRestore); 200ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 201ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 202ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case CLIP_RECT: { 2033afef1f75f710b8f183113cdc5188416f7d01f28robertphillips const SkRect& rect = reader->skipT<SkRect>(); 2043afef1f75f710b8f183113cdc5188416f7d01f28robertphillips uint32_t packed = reader->readInt(); 205ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips SkRegion::Op regionOp = ClipParams_unpackRegionOp(packed); 206ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips bool doAA = ClipParams_unpackDoAA(packed); 2073afef1f75f710b8f183113cdc5188416f7d01f28robertphillips size_t offsetToRestore = reader->readInt(); 2083afef1f75f710b8f183113cdc5188416f7d01f28robertphillips SkASSERT(!offsetToRestore || offsetToRestore >= reader->offset()); 209ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->clipRect(rect, regionOp, doAA); 210ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips if (canvas->isClipEmpty() && offsetToRestore) { 2113afef1f75f710b8f183113cdc5188416f7d01f28robertphillips reader->setOffset(offsetToRestore); 212ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 213ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 214ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case CLIP_RRECT: { 215ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips SkRRect rrect; 2163afef1f75f710b8f183113cdc5188416f7d01f28robertphillips reader->readRRect(&rrect); 2173afef1f75f710b8f183113cdc5188416f7d01f28robertphillips uint32_t packed = reader->readInt(); 218ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips SkRegion::Op regionOp = ClipParams_unpackRegionOp(packed); 219ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips bool doAA = ClipParams_unpackDoAA(packed); 2203afef1f75f710b8f183113cdc5188416f7d01f28robertphillips size_t offsetToRestore = reader->readInt(); 2213afef1f75f710b8f183113cdc5188416f7d01f28robertphillips SkASSERT(!offsetToRestore || offsetToRestore >= reader->offset()); 222ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->clipRRect(rrect, regionOp, doAA); 223ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips if (canvas->isClipEmpty() && offsetToRestore) { 2243afef1f75f710b8f183113cdc5188416f7d01f28robertphillips reader->setOffset(offsetToRestore); 225ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 226ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 227ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case PUSH_CULL: { 2283afef1f75f710b8f183113cdc5188416f7d01f28robertphillips const SkRect& cullRect = reader->skipT<SkRect>(); 2293afef1f75f710b8f183113cdc5188416f7d01f28robertphillips size_t offsetToRestore = reader->readInt(); 230ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips if (offsetToRestore && canvas->quickReject(cullRect)) { 2313afef1f75f710b8f183113cdc5188416f7d01f28robertphillips reader->setOffset(offsetToRestore); 232ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } else { 233ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->pushCull(cullRect); 234ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 235ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 236ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case POP_CULL: 237ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->popCull(); 238ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips break; 239ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case CONCAT: { 240ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips SkMatrix matrix; 2413afef1f75f710b8f183113cdc5188416f7d01f28robertphillips reader->readMatrix(&matrix); 242ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->concat(matrix); 243ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips break; 244ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 245ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_BITMAP: { 246ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint* paint = fPictureData->getPaint(reader); 247eeb1f15891ee9f96f2c5d6e1c3d5a656208f3760mtklein const SkBitmap bitmap = shallow_copy(fPictureData->getBitmap(reader)); 2483afef1f75f710b8f183113cdc5188416f7d01f28robertphillips const SkPoint& loc = reader->skipT<SkPoint>(); 249ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->drawBitmap(bitmap, loc.fX, loc.fY, paint); 250ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 251ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_BITMAP_RECT_TO_RECT: { 252ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint* paint = fPictureData->getPaint(reader); 253eeb1f15891ee9f96f2c5d6e1c3d5a656208f3760mtklein const SkBitmap bitmap = shallow_copy(fPictureData->getBitmap(reader)); 254ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkRect* src = get_rect_ptr(reader); // may be null 2553afef1f75f710b8f183113cdc5188416f7d01f28robertphillips const SkRect& dst = reader->skipT<SkRect>(); // required 256ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips SkCanvas::DrawBitmapRectFlags flags; 2573afef1f75f710b8f183113cdc5188416f7d01f28robertphillips flags = (SkCanvas::DrawBitmapRectFlags) reader->readInt(); 258ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->drawBitmapRectToRect(bitmap, src, dst, paint, flags); 259ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 260ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_BITMAP_MATRIX: { 261ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint* paint = fPictureData->getPaint(reader); 262eeb1f15891ee9f96f2c5d6e1c3d5a656208f3760mtklein const SkBitmap bitmap = shallow_copy(fPictureData->getBitmap(reader)); 263ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips SkMatrix matrix; 2643afef1f75f710b8f183113cdc5188416f7d01f28robertphillips reader->readMatrix(&matrix); 265ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->drawBitmapMatrix(bitmap, matrix, paint); 266ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 267ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_BITMAP_NINE: { 268ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint* paint = fPictureData->getPaint(reader); 269eeb1f15891ee9f96f2c5d6e1c3d5a656208f3760mtklein const SkBitmap bitmap = shallow_copy(fPictureData->getBitmap(reader)); 2703afef1f75f710b8f183113cdc5188416f7d01f28robertphillips const SkIRect& src = reader->skipT<SkIRect>(); 2713afef1f75f710b8f183113cdc5188416f7d01f28robertphillips const SkRect& dst = reader->skipT<SkRect>(); 272ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->drawBitmapNine(bitmap, src, dst, paint); 273ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 274ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_CLEAR: 2753afef1f75f710b8f183113cdc5188416f7d01f28robertphillips canvas->clear(reader->readInt()); 276ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips break; 277ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_DATA: { 2783afef1f75f710b8f183113cdc5188416f7d01f28robertphillips size_t length = reader->readInt(); 2793afef1f75f710b8f183113cdc5188416f7d01f28robertphillips canvas->drawData(reader->skip(length), length); 280ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips // skip handles padding the read out to a multiple of 4 281ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 282ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_DRRECT: { 283ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint& paint = *fPictureData->getPaint(reader); 284ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips SkRRect outer, inner; 2853afef1f75f710b8f183113cdc5188416f7d01f28robertphillips reader->readRRect(&outer); 2863afef1f75f710b8f183113cdc5188416f7d01f28robertphillips reader->readRRect(&inner); 287ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->drawDRRect(outer, inner, paint); 288ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 289ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case BEGIN_COMMENT_GROUP: { 2903afef1f75f710b8f183113cdc5188416f7d01f28robertphillips const char* desc = reader->readString(); 291ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->beginCommentGroup(desc); 292ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 293ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case COMMENT: { 2943afef1f75f710b8f183113cdc5188416f7d01f28robertphillips const char* kywd = reader->readString(); 2953afef1f75f710b8f183113cdc5188416f7d01f28robertphillips const char* value = reader->readString(); 296ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->addComment(kywd, value); 297ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 298ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case END_COMMENT_GROUP: { 299ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->endCommentGroup(); 300ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 301ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_OVAL: { 302ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint& paint = *fPictureData->getPaint(reader); 3033afef1f75f710b8f183113cdc5188416f7d01f28robertphillips canvas->drawOval(reader->skipT<SkRect>(), paint); 304ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 305ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_PAINT: 306ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->drawPaint(*fPictureData->getPaint(reader)); 307ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips break; 308963137b75c0a1fe91f35e9826742f36309f5e65ddandov case DRAW_PATCH: { 309963137b75c0a1fe91f35e9826742f36309f5e65ddandov const SkPaint& paint = *fPictureData->getPaint(reader); 310533eb782edaa0b6fece6166d3001edf72ec39f11mtklein 311b3c9d1c33caf325aada244204215eb790c228c12dandov const SkPoint* cubics = (const SkPoint*)reader->skip(SkPatchUtils::kNumCtrlPts * 312b3c9d1c33caf325aada244204215eb790c228c12dandov sizeof(SkPoint)); 313b3c9d1c33caf325aada244204215eb790c228c12dandov uint32_t flag = reader->readInt(); 314b3c9d1c33caf325aada244204215eb790c228c12dandov const SkColor* colors = NULL; 315b3c9d1c33caf325aada244204215eb790c228c12dandov if (flag & DRAW_VERTICES_HAS_COLORS) { 316b3c9d1c33caf325aada244204215eb790c228c12dandov colors = (const SkColor*)reader->skip(SkPatchUtils::kNumCorners * sizeof(SkColor)); 317b3c9d1c33caf325aada244204215eb790c228c12dandov } 318b3c9d1c33caf325aada244204215eb790c228c12dandov const SkPoint* texCoords = NULL; 319b3c9d1c33caf325aada244204215eb790c228c12dandov if (flag & DRAW_VERTICES_HAS_TEXS) { 320b3c9d1c33caf325aada244204215eb790c228c12dandov texCoords = (const SkPoint*)reader->skip(SkPatchUtils::kNumCorners * 321b3c9d1c33caf325aada244204215eb790c228c12dandov sizeof(SkPoint)); 322b3c9d1c33caf325aada244204215eb790c228c12dandov } 323b3c9d1c33caf325aada244204215eb790c228c12dandov SkAutoTUnref<SkXfermode> xfer; 324b3c9d1c33caf325aada244204215eb790c228c12dandov if (flag & DRAW_VERTICES_HAS_XFER) { 325b3c9d1c33caf325aada244204215eb790c228c12dandov int mode = reader->readInt(); 326b3c9d1c33caf325aada244204215eb790c228c12dandov if (mode < 0 || mode > SkXfermode::kLastMode) { 327b3c9d1c33caf325aada244204215eb790c228c12dandov mode = SkXfermode::kModulate_Mode; 328b3c9d1c33caf325aada244204215eb790c228c12dandov } 329b3c9d1c33caf325aada244204215eb790c228c12dandov xfer.reset(SkXfermode::Create((SkXfermode::Mode)mode)); 330b3c9d1c33caf325aada244204215eb790c228c12dandov } 331b3c9d1c33caf325aada244204215eb790c228c12dandov canvas->drawPatch(cubics, colors, texCoords, xfer, paint); 332963137b75c0a1fe91f35e9826742f36309f5e65ddandov } break; 333ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_PATH: { 334ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint& paint = *fPictureData->getPaint(reader); 335ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->drawPath(fPictureData->getPath(reader), paint); 336ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 337ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_PICTURE: 338ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->drawPicture(fPictureData->getPicture(reader)); 339ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips break; 340d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed case DRAW_PICTURE_MATRIX_PAINT: { 3419f49cfdbf6493b953775890d7f9c97a1dce0d341fmalita const SkPaint* paint = fPictureData->getPaint(reader); 342d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed SkMatrix matrix; 343d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed reader->readMatrix(&matrix); 3449f49cfdbf6493b953775890d7f9c97a1dce0d341fmalita const SkPicture* pic = fPictureData->getPicture(reader); 345d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed canvas->drawPicture(pic, &matrix, paint); 346d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } break; 347ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_POINTS: { 348ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint& paint = *fPictureData->getPaint(reader); 3493afef1f75f710b8f183113cdc5188416f7d01f28robertphillips SkCanvas::PointMode mode = (SkCanvas::PointMode)reader->readInt(); 3503afef1f75f710b8f183113cdc5188416f7d01f28robertphillips size_t count = reader->readInt(); 3513afef1f75f710b8f183113cdc5188416f7d01f28robertphillips const SkPoint* pts = (const SkPoint*)reader->skip(sizeof(SkPoint)* count); 352ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->drawPoints(mode, count, pts, paint); 353ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 354ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_POS_TEXT: { 355ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint& paint = *fPictureData->getPaint(reader); 3563afef1f75f710b8f183113cdc5188416f7d01f28robertphillips TextContainer text; 3573afef1f75f710b8f183113cdc5188416f7d01f28robertphillips get_text(reader, &text); 3583afef1f75f710b8f183113cdc5188416f7d01f28robertphillips size_t points = reader->readInt(); 3593afef1f75f710b8f183113cdc5188416f7d01f28robertphillips const SkPoint* pos = (const SkPoint*)reader->skip(points * sizeof(SkPoint)); 360ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->drawPosText(text.text(), text.length(), pos, paint); 361ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 362ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_POS_TEXT_TOP_BOTTOM: { 363ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint& paint = *fPictureData->getPaint(reader); 3643afef1f75f710b8f183113cdc5188416f7d01f28robertphillips TextContainer text; 3653afef1f75f710b8f183113cdc5188416f7d01f28robertphillips get_text(reader, &text); 3663afef1f75f710b8f183113cdc5188416f7d01f28robertphillips size_t points = reader->readInt(); 3673afef1f75f710b8f183113cdc5188416f7d01f28robertphillips const SkPoint* pos = (const SkPoint*)reader->skip(points * sizeof(SkPoint)); 3683afef1f75f710b8f183113cdc5188416f7d01f28robertphillips const SkScalar top = reader->readScalar(); 3693afef1f75f710b8f183113cdc5188416f7d01f28robertphillips const SkScalar bottom = reader->readScalar(); 370ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips if (!canvas->quickRejectY(top, bottom)) { 371ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->drawPosText(text.text(), text.length(), pos, paint); 372ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 373ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 374ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_POS_TEXT_H: { 375ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint& paint = *fPictureData->getPaint(reader); 3763afef1f75f710b8f183113cdc5188416f7d01f28robertphillips TextContainer text; 3773afef1f75f710b8f183113cdc5188416f7d01f28robertphillips get_text(reader, &text); 3783afef1f75f710b8f183113cdc5188416f7d01f28robertphillips size_t xCount = reader->readInt(); 3793afef1f75f710b8f183113cdc5188416f7d01f28robertphillips const SkScalar constY = reader->readScalar(); 3803afef1f75f710b8f183113cdc5188416f7d01f28robertphillips const SkScalar* xpos = (const SkScalar*)reader->skip(xCount * sizeof(SkScalar)); 381ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->drawPosTextH(text.text(), text.length(), xpos, constY, paint); 382ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 383ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_POS_TEXT_H_TOP_BOTTOM: { 384ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint& paint = *fPictureData->getPaint(reader); 3853afef1f75f710b8f183113cdc5188416f7d01f28robertphillips TextContainer text; 3863afef1f75f710b8f183113cdc5188416f7d01f28robertphillips get_text(reader, &text); 3873afef1f75f710b8f183113cdc5188416f7d01f28robertphillips size_t xCount = reader->readInt(); 3883afef1f75f710b8f183113cdc5188416f7d01f28robertphillips const SkScalar* xpos = (const SkScalar*)reader->skip((3 + xCount) * sizeof(SkScalar)); 389ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkScalar top = *xpos++; 390ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkScalar bottom = *xpos++; 391ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkScalar constY = *xpos++; 392ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips if (!canvas->quickRejectY(top, bottom)) { 393ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->drawPosTextH(text.text(), text.length(), xpos, constY, paint); 394ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 395ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 396ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_RECT: { 397ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint& paint = *fPictureData->getPaint(reader); 3983afef1f75f710b8f183113cdc5188416f7d01f28robertphillips canvas->drawRect(reader->skipT<SkRect>(), paint); 399ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 400ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_RRECT: { 401ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint& paint = *fPictureData->getPaint(reader); 402ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips SkRRect rrect; 4033afef1f75f710b8f183113cdc5188416f7d01f28robertphillips reader->readRRect(&rrect); 404ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->drawRRect(rrect, paint); 405ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 406ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_SPRITE: { 407ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint* paint = fPictureData->getPaint(reader); 408eeb1f15891ee9f96f2c5d6e1c3d5a656208f3760mtklein const SkBitmap bitmap = shallow_copy(fPictureData->getBitmap(reader)); 4093afef1f75f710b8f183113cdc5188416f7d01f28robertphillips int left = reader->readInt(); 4103afef1f75f710b8f183113cdc5188416f7d01f28robertphillips int top = reader->readInt(); 411ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->drawSprite(bitmap, left, top, paint); 412ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 413ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_TEXT: { 414ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint& paint = *fPictureData->getPaint(reader); 4153afef1f75f710b8f183113cdc5188416f7d01f28robertphillips TextContainer text; 4163afef1f75f710b8f183113cdc5188416f7d01f28robertphillips get_text(reader, &text); 4173afef1f75f710b8f183113cdc5188416f7d01f28robertphillips SkScalar x = reader->readScalar(); 4183afef1f75f710b8f183113cdc5188416f7d01f28robertphillips SkScalar y = reader->readScalar(); 419ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->drawText(text.text(), text.length(), x, y, paint); 420ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 421b7425173f96e93b090787e2386ba5f022b6c2869fmalita case DRAW_TEXT_BLOB: { 422b7425173f96e93b090787e2386ba5f022b6c2869fmalita const SkPaint& paint = *fPictureData->getPaint(reader); 423b7425173f96e93b090787e2386ba5f022b6c2869fmalita const SkTextBlob* blob = fPictureData->getTextBlob(reader); 424b7425173f96e93b090787e2386ba5f022b6c2869fmalita SkScalar x = reader->readScalar(); 425b7425173f96e93b090787e2386ba5f022b6c2869fmalita SkScalar y = reader->readScalar(); 426b7425173f96e93b090787e2386ba5f022b6c2869fmalita canvas->drawTextBlob(blob, x, y, paint); 427b7425173f96e93b090787e2386ba5f022b6c2869fmalita } break; 428ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_TEXT_TOP_BOTTOM: { 429ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint& paint = *fPictureData->getPaint(reader); 4303afef1f75f710b8f183113cdc5188416f7d01f28robertphillips TextContainer text; 4313afef1f75f710b8f183113cdc5188416f7d01f28robertphillips get_text(reader, &text); 4323afef1f75f710b8f183113cdc5188416f7d01f28robertphillips const SkScalar* ptr = (const SkScalar*)reader->skip(4 * sizeof(SkScalar)); 433ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips // ptr[0] == x 434ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips // ptr[1] == y 435ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips // ptr[2] == top 436ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips // ptr[3] == bottom 437ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips if (!canvas->quickRejectY(ptr[2], ptr[3])) { 438ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->drawText(text.text(), text.length(), ptr[0], ptr[1], paint); 439ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 440ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 441ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_TEXT_ON_PATH: { 442ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint& paint = *fPictureData->getPaint(reader); 4433afef1f75f710b8f183113cdc5188416f7d01f28robertphillips TextContainer text; 4443afef1f75f710b8f183113cdc5188416f7d01f28robertphillips get_text(reader, &text); 445ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPath& path = fPictureData->getPath(reader); 446ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips SkMatrix matrix; 4473afef1f75f710b8f183113cdc5188416f7d01f28robertphillips reader->readMatrix(&matrix); 448ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->drawTextOnPath(text.text(), text.length(), path, &matrix, paint); 449ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 450ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case DRAW_VERTICES: { 451ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips SkAutoTUnref<SkXfermode> xfer; 452ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint& paint = *fPictureData->getPaint(reader); 4533afef1f75f710b8f183113cdc5188416f7d01f28robertphillips DrawVertexFlags flags = (DrawVertexFlags)reader->readInt(); 4543afef1f75f710b8f183113cdc5188416f7d01f28robertphillips SkCanvas::VertexMode vmode = (SkCanvas::VertexMode)reader->readInt(); 4553afef1f75f710b8f183113cdc5188416f7d01f28robertphillips int vCount = reader->readInt(); 4563afef1f75f710b8f183113cdc5188416f7d01f28robertphillips const SkPoint* verts = (const SkPoint*)reader->skip(vCount * sizeof(SkPoint)); 457ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPoint* texs = NULL; 458ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkColor* colors = NULL; 459ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const uint16_t* indices = NULL; 460ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips int iCount = 0; 461ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips if (flags & DRAW_VERTICES_HAS_TEXS) { 4623afef1f75f710b8f183113cdc5188416f7d01f28robertphillips texs = (const SkPoint*)reader->skip(vCount * sizeof(SkPoint)); 463ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 464ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips if (flags & DRAW_VERTICES_HAS_COLORS) { 4653afef1f75f710b8f183113cdc5188416f7d01f28robertphillips colors = (const SkColor*)reader->skip(vCount * sizeof(SkColor)); 466ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 467ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips if (flags & DRAW_VERTICES_HAS_INDICES) { 4683afef1f75f710b8f183113cdc5188416f7d01f28robertphillips iCount = reader->readInt(); 4693afef1f75f710b8f183113cdc5188416f7d01f28robertphillips indices = (const uint16_t*)reader->skip(iCount * sizeof(uint16_t)); 470ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 471ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips if (flags & DRAW_VERTICES_HAS_XFER) { 4723afef1f75f710b8f183113cdc5188416f7d01f28robertphillips int mode = reader->readInt(); 473ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips if (mode < 0 || mode > SkXfermode::kLastMode) { 474ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips mode = SkXfermode::kModulate_Mode; 475ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 476ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips xfer.reset(SkXfermode::Create((SkXfermode::Mode)mode)); 477ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 478ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->drawVertices(vmode, vCount, verts, texs, colors, xfer, indices, iCount, paint); 479ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 480ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case RESTORE: 481ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->restore(); 482ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips break; 483ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case ROTATE: 4843afef1f75f710b8f183113cdc5188416f7d01f28robertphillips canvas->rotate(reader->readScalar()); 485ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips break; 486ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case SAVE: 487ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips // SKPs with version < 29 also store a SaveFlags param. 488ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips if (size > 4) { 489ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips SkASSERT(8 == size); 4903afef1f75f710b8f183113cdc5188416f7d01f28robertphillips reader->readInt(); 491ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 492ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->save(); 493ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips break; 494ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case SAVE_LAYER: { 495ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkRect* boundsPtr = get_rect_ptr(reader); 496ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips const SkPaint* paint = fPictureData->getPaint(reader); 4973afef1f75f710b8f183113cdc5188416f7d01f28robertphillips canvas->saveLayer(boundsPtr, paint, (SkCanvas::SaveFlags) reader->readInt()); 498ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 499ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case SCALE: { 5003afef1f75f710b8f183113cdc5188416f7d01f28robertphillips SkScalar sx = reader->readScalar(); 5013afef1f75f710b8f183113cdc5188416f7d01f28robertphillips SkScalar sy = reader->readScalar(); 502ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->scale(sx, sy); 503ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 504ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case SET_MATRIX: { 505ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips SkMatrix matrix; 5063afef1f75f710b8f183113cdc5188416f7d01f28robertphillips reader->readMatrix(&matrix); 507ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips matrix.postConcat(initialMatrix); 508ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->setMatrix(matrix); 509ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 510ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case SKEW: { 5113afef1f75f710b8f183113cdc5188416f7d01f28robertphillips SkScalar sx = reader->readScalar(); 5123afef1f75f710b8f183113cdc5188416f7d01f28robertphillips SkScalar sy = reader->readScalar(); 513ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->skew(sx, sy); 514ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 515ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips case TRANSLATE: { 5163afef1f75f710b8f183113cdc5188416f7d01f28robertphillips SkScalar dx = reader->readScalar(); 5173afef1f75f710b8f183113cdc5188416f7d01f28robertphillips SkScalar dy = reader->readScalar(); 518ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips canvas->translate(dx, dy); 519ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } break; 520ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips default: 521ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips SkASSERT(0); 522ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips } 523ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips} 524ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips 525