1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2014 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "include/core/SkCanvas.h" 9cb93a386Sopenharmony_ci#include "include/core/SkRSXform.h" 10cb93a386Sopenharmony_ci#include "include/core/SkTextBlob.h" 11cb93a386Sopenharmony_ci#include "include/core/SkTypes.h" 12cb93a386Sopenharmony_ci#include "include/private/SkTDArray.h" 13cb93a386Sopenharmony_ci#include "src/core/SkCanvasPriv.h" 14cb93a386Sopenharmony_ci#include "src/core/SkDrawShadowInfo.h" 15cb93a386Sopenharmony_ci#include "src/core/SkFontPriv.h" 16cb93a386Sopenharmony_ci#include "src/core/SkPaintPriv.h" 17cb93a386Sopenharmony_ci#include "src/core/SkPictureData.h" 18cb93a386Sopenharmony_ci#include "src/core/SkPicturePlayback.h" 19cb93a386Sopenharmony_ci#include "src/core/SkPictureRecord.h" 20cb93a386Sopenharmony_ci#include "src/core/SkReadBuffer.h" 21cb93a386Sopenharmony_ci#include "src/core/SkSafeMath.h" 22cb93a386Sopenharmony_ci#include "src/core/SkSamplingPriv.h" 23cb93a386Sopenharmony_ci#include "src/core/SkVerticesPriv.h" 24cb93a386Sopenharmony_ci#include "src/utils/SkPatchUtils.h" 25cb93a386Sopenharmony_ci 26cb93a386Sopenharmony_cistatic const SkRect* get_rect_ptr(SkReadBuffer* reader, SkRect* storage) { 27cb93a386Sopenharmony_ci if (reader->readBool()) { 28cb93a386Sopenharmony_ci reader->readRect(storage); 29cb93a386Sopenharmony_ci return storage; 30cb93a386Sopenharmony_ci } else { 31cb93a386Sopenharmony_ci return nullptr; 32cb93a386Sopenharmony_ci } 33cb93a386Sopenharmony_ci} 34cb93a386Sopenharmony_ci 35cb93a386Sopenharmony_civoid SkPicturePlayback::draw(SkCanvas* canvas, 36cb93a386Sopenharmony_ci SkPicture::AbortCallback* callback, 37cb93a386Sopenharmony_ci SkReadBuffer* buffer) { 38cb93a386Sopenharmony_ci AutoResetOpID aroi(this); 39cb93a386Sopenharmony_ci SkASSERT(0 == fCurOffset); 40cb93a386Sopenharmony_ci 41cb93a386Sopenharmony_ci SkReadBuffer reader(fPictureData->opData()->bytes(), 42cb93a386Sopenharmony_ci fPictureData->opData()->size()); 43cb93a386Sopenharmony_ci 44cb93a386Sopenharmony_ci // Record this, so we can concat w/ it if we encounter a setMatrix() 45cb93a386Sopenharmony_ci SkM44 initialMatrix = canvas->getLocalToDevice(); 46cb93a386Sopenharmony_ci 47cb93a386Sopenharmony_ci SkAutoCanvasRestore acr(canvas, false); 48cb93a386Sopenharmony_ci 49cb93a386Sopenharmony_ci while (!reader.eof() && reader.isValid()) { 50cb93a386Sopenharmony_ci if (callback && callback->abort()) { 51cb93a386Sopenharmony_ci return; 52cb93a386Sopenharmony_ci } 53cb93a386Sopenharmony_ci 54cb93a386Sopenharmony_ci fCurOffset = reader.offset(); 55cb93a386Sopenharmony_ci 56cb93a386Sopenharmony_ci uint32_t bits = reader.readInt(); 57cb93a386Sopenharmony_ci uint32_t op = bits >> 24, 58cb93a386Sopenharmony_ci size = bits & 0xffffff; 59cb93a386Sopenharmony_ci if (size == 0xffffff) { 60cb93a386Sopenharmony_ci size = reader.readInt(); 61cb93a386Sopenharmony_ci } 62cb93a386Sopenharmony_ci 63cb93a386Sopenharmony_ci if (!reader.validate(size > 0 && op > UNUSED && op <= LAST_DRAWTYPE_ENUM)) { 64cb93a386Sopenharmony_ci return; 65cb93a386Sopenharmony_ci } 66cb93a386Sopenharmony_ci 67cb93a386Sopenharmony_ci this->handleOp(&reader, (DrawType)op, size, canvas, initialMatrix); 68cb93a386Sopenharmony_ci } 69cb93a386Sopenharmony_ci 70cb93a386Sopenharmony_ci // need to propagate invalid state to the parent reader 71cb93a386Sopenharmony_ci if (buffer) { 72cb93a386Sopenharmony_ci buffer->validate(reader.isValid()); 73cb93a386Sopenharmony_ci } 74cb93a386Sopenharmony_ci} 75cb93a386Sopenharmony_ci 76cb93a386Sopenharmony_cistatic void validate_offsetToRestore(SkReadBuffer* reader, size_t offsetToRestore) { 77cb93a386Sopenharmony_ci if (offsetToRestore) { 78cb93a386Sopenharmony_ci reader->validate(SkIsAlign4(offsetToRestore) && offsetToRestore >= reader->offset()); 79cb93a386Sopenharmony_ci } 80cb93a386Sopenharmony_ci} 81cb93a386Sopenharmony_ci 82cb93a386Sopenharmony_cistatic bool do_clip_op(SkReadBuffer* reader, SkCanvas* canvas, SkRegion::Op op, 83cb93a386Sopenharmony_ci SkClipOp* clipOpToUse) { 84cb93a386Sopenharmony_ci switch(op) { 85cb93a386Sopenharmony_ci case SkRegion::kDifference_Op: 86cb93a386Sopenharmony_ci case SkRegion::kIntersect_Op: 87cb93a386Sopenharmony_ci // Fully supported, identity mapping between SkClipOp and Region::Op 88cb93a386Sopenharmony_ci *clipOpToUse = static_cast<SkClipOp>(op); 89cb93a386Sopenharmony_ci return true; 90cb93a386Sopenharmony_ci case SkRegion::kReplace_Op: 91cb93a386Sopenharmony_ci // Emulate the replace by resetting first and following it up with an intersect 92cb93a386Sopenharmony_ci SkASSERT(reader->isVersionLT(SkPicturePriv::kNoExpandingClipOps)); 93cb93a386Sopenharmony_ci SkCanvasPriv::ResetClip(canvas); 94cb93a386Sopenharmony_ci *clipOpToUse = SkClipOp::kIntersect; 95cb93a386Sopenharmony_ci return true; 96cb93a386Sopenharmony_ci default: 97cb93a386Sopenharmony_ci // An expanding clip op, which if encountered on an old SKP, we just silently ignore 98cb93a386Sopenharmony_ci SkASSERT(reader->isVersionLT(SkPicturePriv::kNoExpandingClipOps)); 99cb93a386Sopenharmony_ci return false; 100cb93a386Sopenharmony_ci } 101cb93a386Sopenharmony_ci} 102cb93a386Sopenharmony_ci 103cb93a386Sopenharmony_civoid SkPicturePlayback::handleOp(SkReadBuffer* reader, 104cb93a386Sopenharmony_ci DrawType op, 105cb93a386Sopenharmony_ci uint32_t size, 106cb93a386Sopenharmony_ci SkCanvas* canvas, 107cb93a386Sopenharmony_ci const SkM44& initialMatrix) { 108cb93a386Sopenharmony_ci#define BREAK_ON_READ_ERROR(r) if (!r->isValid()) break 109cb93a386Sopenharmony_ci 110cb93a386Sopenharmony_ci switch (op) { 111cb93a386Sopenharmony_ci case NOOP: { 112cb93a386Sopenharmony_ci SkASSERT(size >= 4); 113cb93a386Sopenharmony_ci reader->skip(size - 4); 114cb93a386Sopenharmony_ci } break; 115cb93a386Sopenharmony_ci case FLUSH: 116cb93a386Sopenharmony_ci canvas->flush(); 117cb93a386Sopenharmony_ci break; 118cb93a386Sopenharmony_ci case CLIP_PATH: { 119cb93a386Sopenharmony_ci const SkPath& path = fPictureData->getPath(reader); 120cb93a386Sopenharmony_ci uint32_t packed = reader->readInt(); 121cb93a386Sopenharmony_ci SkRegion::Op rgnOp = ClipParams_unpackRegionOp(reader, packed); 122cb93a386Sopenharmony_ci bool doAA = ClipParams_unpackDoAA(packed); 123cb93a386Sopenharmony_ci size_t offsetToRestore = reader->readInt(); 124cb93a386Sopenharmony_ci validate_offsetToRestore(reader, offsetToRestore); 125cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 126cb93a386Sopenharmony_ci 127cb93a386Sopenharmony_ci SkClipOp clipOp; 128cb93a386Sopenharmony_ci if (do_clip_op(reader, canvas, rgnOp, &clipOp)) { 129cb93a386Sopenharmony_ci canvas->clipPath(path, clipOp, doAA); 130cb93a386Sopenharmony_ci } 131cb93a386Sopenharmony_ci if (canvas->isClipEmpty() && offsetToRestore) { 132cb93a386Sopenharmony_ci reader->skip(offsetToRestore - reader->offset()); 133cb93a386Sopenharmony_ci } 134cb93a386Sopenharmony_ci } break; 135cb93a386Sopenharmony_ci case CLIP_REGION: { 136cb93a386Sopenharmony_ci SkRegion region; 137cb93a386Sopenharmony_ci reader->readRegion(®ion); 138cb93a386Sopenharmony_ci uint32_t packed = reader->readInt(); 139cb93a386Sopenharmony_ci SkRegion::Op rgnOp = ClipParams_unpackRegionOp(reader, packed); 140cb93a386Sopenharmony_ci size_t offsetToRestore = reader->readInt(); 141cb93a386Sopenharmony_ci validate_offsetToRestore(reader, offsetToRestore); 142cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 143cb93a386Sopenharmony_ci 144cb93a386Sopenharmony_ci SkClipOp clipOp; 145cb93a386Sopenharmony_ci if (do_clip_op(reader, canvas, rgnOp, &clipOp)) { 146cb93a386Sopenharmony_ci canvas->clipRegion(region, clipOp); 147cb93a386Sopenharmony_ci } 148cb93a386Sopenharmony_ci if (canvas->isClipEmpty() && offsetToRestore) { 149cb93a386Sopenharmony_ci reader->skip(offsetToRestore - reader->offset()); 150cb93a386Sopenharmony_ci } 151cb93a386Sopenharmony_ci } break; 152cb93a386Sopenharmony_ci case CLIP_RECT: { 153cb93a386Sopenharmony_ci SkRect rect; 154cb93a386Sopenharmony_ci reader->readRect(&rect); 155cb93a386Sopenharmony_ci uint32_t packed = reader->readInt(); 156cb93a386Sopenharmony_ci SkRegion::Op rgnOp = ClipParams_unpackRegionOp(reader, packed); 157cb93a386Sopenharmony_ci bool doAA = ClipParams_unpackDoAA(packed); 158cb93a386Sopenharmony_ci size_t offsetToRestore = reader->readInt(); 159cb93a386Sopenharmony_ci validate_offsetToRestore(reader, offsetToRestore); 160cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 161cb93a386Sopenharmony_ci 162cb93a386Sopenharmony_ci SkClipOp clipOp; 163cb93a386Sopenharmony_ci if (do_clip_op(reader, canvas, rgnOp, &clipOp)) { 164cb93a386Sopenharmony_ci canvas->clipRect(rect, clipOp, doAA); 165cb93a386Sopenharmony_ci } 166cb93a386Sopenharmony_ci if (canvas->isClipEmpty() && offsetToRestore) { 167cb93a386Sopenharmony_ci reader->skip(offsetToRestore - reader->offset()); 168cb93a386Sopenharmony_ci } 169cb93a386Sopenharmony_ci } break; 170cb93a386Sopenharmony_ci case CLIP_RRECT: { 171cb93a386Sopenharmony_ci SkRRect rrect; 172cb93a386Sopenharmony_ci reader->readRRect(&rrect); 173cb93a386Sopenharmony_ci uint32_t packed = reader->readInt(); 174cb93a386Sopenharmony_ci SkRegion::Op rgnOp = ClipParams_unpackRegionOp(reader, packed); 175cb93a386Sopenharmony_ci bool doAA = ClipParams_unpackDoAA(packed); 176cb93a386Sopenharmony_ci size_t offsetToRestore = reader->readInt(); 177cb93a386Sopenharmony_ci validate_offsetToRestore(reader, offsetToRestore); 178cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 179cb93a386Sopenharmony_ci 180cb93a386Sopenharmony_ci SkClipOp clipOp; 181cb93a386Sopenharmony_ci if (do_clip_op(reader, canvas, rgnOp, &clipOp)) { 182cb93a386Sopenharmony_ci canvas->clipRRect(rrect, clipOp, doAA); 183cb93a386Sopenharmony_ci } 184cb93a386Sopenharmony_ci if (canvas->isClipEmpty() && offsetToRestore) { 185cb93a386Sopenharmony_ci reader->skip(offsetToRestore - reader->offset()); 186cb93a386Sopenharmony_ci } 187cb93a386Sopenharmony_ci } break; 188cb93a386Sopenharmony_ci case CLIP_SHADER_IN_PAINT: { 189cb93a386Sopenharmony_ci const SkPaint& paint = fPictureData->requiredPaint(reader); 190cb93a386Sopenharmony_ci // clipShader() was never used in conjunction with deprecated, expanding clip ops, so 191cb93a386Sopenharmony_ci // it requires the op to just be intersect or difference. 192cb93a386Sopenharmony_ci SkClipOp clipOp = reader->checkRange(SkClipOp::kDifference, SkClipOp::kIntersect); 193cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 194cb93a386Sopenharmony_ci 195cb93a386Sopenharmony_ci canvas->clipShader(paint.refShader(), clipOp); 196cb93a386Sopenharmony_ci } break; 197cb93a386Sopenharmony_ci case RESET_CLIP: 198cb93a386Sopenharmony_ci // For Android, an emulated "replace" clip op appears as a manual reset followed by 199cb93a386Sopenharmony_ci // an intersect operation (equivalent to the above handling of replace ops encountered 200cb93a386Sopenharmony_ci // in old serialized pictures). 201cb93a386Sopenharmony_ci SkCanvasPriv::ResetClip(canvas); 202cb93a386Sopenharmony_ci break; 203cb93a386Sopenharmony_ci case PUSH_CULL: break; // Deprecated, safe to ignore both push and pop. 204cb93a386Sopenharmony_ci case POP_CULL: break; 205cb93a386Sopenharmony_ci case CONCAT: { 206cb93a386Sopenharmony_ci SkMatrix matrix; 207cb93a386Sopenharmony_ci reader->readMatrix(&matrix); 208cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 209cb93a386Sopenharmony_ci 210cb93a386Sopenharmony_ci canvas->concat(matrix); 211cb93a386Sopenharmony_ci break; 212cb93a386Sopenharmony_ci } 213cb93a386Sopenharmony_ci case CONCAT44: { 214cb93a386Sopenharmony_ci const SkScalar* colMaj = reader->skipT<SkScalar>(16); 215cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 216cb93a386Sopenharmony_ci canvas->concat(SkM44::ColMajor(colMaj)); 217cb93a386Sopenharmony_ci break; 218cb93a386Sopenharmony_ci } 219cb93a386Sopenharmony_ci case DRAW_ANNOTATION: { 220cb93a386Sopenharmony_ci SkRect rect; 221cb93a386Sopenharmony_ci reader->readRect(&rect); 222cb93a386Sopenharmony_ci SkString key; 223cb93a386Sopenharmony_ci reader->readString(&key); 224cb93a386Sopenharmony_ci sk_sp<SkData> data = reader->readByteArrayAsData(); 225cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 226cb93a386Sopenharmony_ci SkASSERT(data); 227cb93a386Sopenharmony_ci 228cb93a386Sopenharmony_ci canvas->drawAnnotation(rect, key.c_str(), data.get()); 229cb93a386Sopenharmony_ci } break; 230cb93a386Sopenharmony_ci case DRAW_ARC: { 231cb93a386Sopenharmony_ci const SkPaint& paint = fPictureData->requiredPaint(reader); 232cb93a386Sopenharmony_ci SkRect rect; 233cb93a386Sopenharmony_ci reader->readRect(&rect); 234cb93a386Sopenharmony_ci SkScalar startAngle = reader->readScalar(); 235cb93a386Sopenharmony_ci SkScalar sweepAngle = reader->readScalar(); 236cb93a386Sopenharmony_ci int useCenter = reader->readInt(); 237cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 238cb93a386Sopenharmony_ci 239cb93a386Sopenharmony_ci canvas->drawArc(rect, startAngle, sweepAngle, SkToBool(useCenter), paint); 240cb93a386Sopenharmony_ci } break; 241cb93a386Sopenharmony_ci case DRAW_ATLAS: { 242cb93a386Sopenharmony_ci const SkPaint* paint = fPictureData->optionalPaint(reader); 243cb93a386Sopenharmony_ci const SkImage* atlas = fPictureData->getImage(reader); 244cb93a386Sopenharmony_ci const uint32_t flags = reader->readUInt(); 245cb93a386Sopenharmony_ci const int count = reader->readUInt(); 246cb93a386Sopenharmony_ci const SkRSXform* xform = (const SkRSXform*)reader->skip(count, sizeof(SkRSXform)); 247cb93a386Sopenharmony_ci const SkRect* tex = (const SkRect*)reader->skip(count, sizeof(SkRect)); 248cb93a386Sopenharmony_ci const SkColor* colors = nullptr; 249cb93a386Sopenharmony_ci SkBlendMode mode = SkBlendMode::kDst; 250cb93a386Sopenharmony_ci if (flags & DRAW_ATLAS_HAS_COLORS) { 251cb93a386Sopenharmony_ci colors = (const SkColor*)reader->skip(count, sizeof(SkColor)); 252cb93a386Sopenharmony_ci mode = (SkBlendMode)reader->readUInt(); 253cb93a386Sopenharmony_ci } 254cb93a386Sopenharmony_ci const SkRect* cull = nullptr; 255cb93a386Sopenharmony_ci if (flags & DRAW_ATLAS_HAS_CULL) { 256cb93a386Sopenharmony_ci cull = (const SkRect*)reader->skip(sizeof(SkRect)); 257cb93a386Sopenharmony_ci } 258cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 259cb93a386Sopenharmony_ci 260cb93a386Sopenharmony_ci SkSamplingOptions sampling; 261cb93a386Sopenharmony_ci if (flags & DRAW_ATLAS_HAS_SAMPLING) { 262cb93a386Sopenharmony_ci sampling = reader->readSampling(); 263cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 264cb93a386Sopenharmony_ci } 265cb93a386Sopenharmony_ci canvas->drawAtlas(atlas, xform, tex, colors, count, mode, sampling, cull, paint); 266cb93a386Sopenharmony_ci } break; 267cb93a386Sopenharmony_ci case DRAW_CLEAR: { 268cb93a386Sopenharmony_ci auto c = reader->readInt(); 269cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 270cb93a386Sopenharmony_ci 271cb93a386Sopenharmony_ci canvas->clear(c); 272cb93a386Sopenharmony_ci } break; 273cb93a386Sopenharmony_ci case DRAW_DATA: { 274cb93a386Sopenharmony_ci // This opcode is now dead, just need to skip it for backwards compatibility 275cb93a386Sopenharmony_ci size_t length = reader->readInt(); 276cb93a386Sopenharmony_ci (void)reader->skip(length); 277cb93a386Sopenharmony_ci // skip handles padding the read out to a multiple of 4 278cb93a386Sopenharmony_ci } break; 279cb93a386Sopenharmony_ci case DRAW_DRAWABLE: { 280cb93a386Sopenharmony_ci auto* d = fPictureData->getDrawable(reader); 281cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 282cb93a386Sopenharmony_ci 283cb93a386Sopenharmony_ci canvas->drawDrawable(d); 284cb93a386Sopenharmony_ci } break; 285cb93a386Sopenharmony_ci case DRAW_DRAWABLE_MATRIX: { 286cb93a386Sopenharmony_ci SkMatrix matrix; 287cb93a386Sopenharmony_ci reader->readMatrix(&matrix); 288cb93a386Sopenharmony_ci SkDrawable* drawable = fPictureData->getDrawable(reader); 289cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 290cb93a386Sopenharmony_ci 291cb93a386Sopenharmony_ci canvas->drawDrawable(drawable, &matrix); 292cb93a386Sopenharmony_ci } break; 293cb93a386Sopenharmony_ci case DRAW_DRRECT: { 294cb93a386Sopenharmony_ci const SkPaint& paint = fPictureData->requiredPaint(reader); 295cb93a386Sopenharmony_ci SkRRect outer, inner; 296cb93a386Sopenharmony_ci reader->readRRect(&outer); 297cb93a386Sopenharmony_ci reader->readRRect(&inner); 298cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 299cb93a386Sopenharmony_ci 300cb93a386Sopenharmony_ci canvas->drawDRRect(outer, inner, paint); 301cb93a386Sopenharmony_ci } break; 302cb93a386Sopenharmony_ci case DRAW_EDGEAA_QUAD: { 303cb93a386Sopenharmony_ci SkRect rect; 304cb93a386Sopenharmony_ci reader->readRect(&rect); 305cb93a386Sopenharmony_ci SkCanvas::QuadAAFlags aaFlags = static_cast<SkCanvas::QuadAAFlags>(reader->read32()); 306cb93a386Sopenharmony_ci SkColor4f color; 307cb93a386Sopenharmony_ci reader->readColor4f(&color); 308cb93a386Sopenharmony_ci SkBlendMode blend = static_cast<SkBlendMode>(reader->read32()); 309cb93a386Sopenharmony_ci bool hasClip = reader->readInt(); 310cb93a386Sopenharmony_ci SkPoint* clip = nullptr; 311cb93a386Sopenharmony_ci if (hasClip) { 312cb93a386Sopenharmony_ci clip = (SkPoint*) reader->skip(4, sizeof(SkPoint)); 313cb93a386Sopenharmony_ci } 314cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 315cb93a386Sopenharmony_ci canvas->experimental_DrawEdgeAAQuad(rect, clip, aaFlags, color, blend); 316cb93a386Sopenharmony_ci } break; 317cb93a386Sopenharmony_ci case DRAW_EDGEAA_IMAGE_SET: 318cb93a386Sopenharmony_ci case DRAW_EDGEAA_IMAGE_SET2: { 319cb93a386Sopenharmony_ci static const size_t kEntryReadSize = 320cb93a386Sopenharmony_ci 4 * sizeof(uint32_t) + 2 * sizeof(SkRect) + sizeof(SkScalar); 321cb93a386Sopenharmony_ci static const size_t kMatrixSize = 9 * sizeof(SkScalar); // != sizeof(SkMatrix) 322cb93a386Sopenharmony_ci 323cb93a386Sopenharmony_ci int cnt = reader->readInt(); 324cb93a386Sopenharmony_ci if (!reader->validate(cnt >= 0)) { 325cb93a386Sopenharmony_ci break; 326cb93a386Sopenharmony_ci } 327cb93a386Sopenharmony_ci const SkPaint* paint = fPictureData->optionalPaint(reader); 328cb93a386Sopenharmony_ci 329cb93a386Sopenharmony_ci SkSamplingOptions sampling; 330cb93a386Sopenharmony_ci if (op == DRAW_EDGEAA_IMAGE_SET2) { 331cb93a386Sopenharmony_ci sampling = reader->readSampling(); 332cb93a386Sopenharmony_ci } else { 333cb93a386Sopenharmony_ci sampling = SkSamplingOptions(SkFilterMode::kNearest); 334cb93a386Sopenharmony_ci } 335cb93a386Sopenharmony_ci 336cb93a386Sopenharmony_ci SkCanvas::SrcRectConstraint constraint = 337cb93a386Sopenharmony_ci reader->checkRange(SkCanvas::kStrict_SrcRectConstraint, 338cb93a386Sopenharmony_ci SkCanvas::kFast_SrcRectConstraint); 339cb93a386Sopenharmony_ci 340cb93a386Sopenharmony_ci if (!reader->validate(SkSafeMath::Mul(cnt, kEntryReadSize) <= reader->available())) { 341cb93a386Sopenharmony_ci break; 342cb93a386Sopenharmony_ci } 343cb93a386Sopenharmony_ci 344cb93a386Sopenharmony_ci // Track minimum necessary clip points and matrices that must be provided to satisfy 345cb93a386Sopenharmony_ci // the entries. 346cb93a386Sopenharmony_ci int expectedClips = 0; 347cb93a386Sopenharmony_ci int maxMatrixIndex = -1; 348cb93a386Sopenharmony_ci SkAutoTArray<SkCanvas::ImageSetEntry> set(cnt); 349cb93a386Sopenharmony_ci for (int i = 0; i < cnt && reader->isValid(); ++i) { 350cb93a386Sopenharmony_ci set[i].fImage = sk_ref_sp(fPictureData->getImage(reader)); 351cb93a386Sopenharmony_ci reader->readRect(&set[i].fSrcRect); 352cb93a386Sopenharmony_ci reader->readRect(&set[i].fDstRect); 353cb93a386Sopenharmony_ci set[i].fMatrixIndex = reader->readInt(); 354cb93a386Sopenharmony_ci set[i].fAlpha = reader->readScalar(); 355cb93a386Sopenharmony_ci set[i].fAAFlags = reader->readUInt(); 356cb93a386Sopenharmony_ci set[i].fHasClip = reader->readInt(); 357cb93a386Sopenharmony_ci 358cb93a386Sopenharmony_ci expectedClips += set[i].fHasClip ? 1 : 0; 359cb93a386Sopenharmony_ci if (set[i].fMatrixIndex > maxMatrixIndex) { 360cb93a386Sopenharmony_ci maxMatrixIndex = set[i].fMatrixIndex; 361cb93a386Sopenharmony_ci } 362cb93a386Sopenharmony_ci } 363cb93a386Sopenharmony_ci 364cb93a386Sopenharmony_ci int dstClipCount = reader->readInt(); 365cb93a386Sopenharmony_ci SkPoint* dstClips = nullptr; 366cb93a386Sopenharmony_ci if (!reader->validate(expectedClips <= dstClipCount)) { 367cb93a386Sopenharmony_ci // Entries request more dstClip points than are provided in the buffer 368cb93a386Sopenharmony_ci break; 369cb93a386Sopenharmony_ci } else if (dstClipCount > 0) { 370cb93a386Sopenharmony_ci dstClips = (SkPoint*) reader->skip(dstClipCount, sizeof(SkPoint)); 371cb93a386Sopenharmony_ci if (dstClips == nullptr) { 372cb93a386Sopenharmony_ci // Not enough bytes remaining so the reader has been invalidated 373cb93a386Sopenharmony_ci break; 374cb93a386Sopenharmony_ci } 375cb93a386Sopenharmony_ci } 376cb93a386Sopenharmony_ci int matrixCount = reader->readInt(); 377cb93a386Sopenharmony_ci if (!reader->validate((maxMatrixIndex + 1) <= matrixCount) || 378cb93a386Sopenharmony_ci !reader->validate( 379cb93a386Sopenharmony_ci SkSafeMath::Mul(matrixCount, kMatrixSize) <= reader->available())) { 380cb93a386Sopenharmony_ci // Entries access out-of-bound matrix indices, given provided matrices or 381cb93a386Sopenharmony_ci // there aren't enough bytes to provide that many matrices 382cb93a386Sopenharmony_ci break; 383cb93a386Sopenharmony_ci } 384cb93a386Sopenharmony_ci SkTArray<SkMatrix> matrices(matrixCount); 385cb93a386Sopenharmony_ci for (int i = 0; i < matrixCount && reader->isValid(); ++i) { 386cb93a386Sopenharmony_ci reader->readMatrix(&matrices.push_back()); 387cb93a386Sopenharmony_ci } 388cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 389cb93a386Sopenharmony_ci 390cb93a386Sopenharmony_ci canvas->experimental_DrawEdgeAAImageSet(set.get(), cnt, dstClips, matrices.begin(), 391cb93a386Sopenharmony_ci sampling, paint, constraint); 392cb93a386Sopenharmony_ci } break; 393cb93a386Sopenharmony_ci case DRAW_IMAGE: { 394cb93a386Sopenharmony_ci const SkPaint* paint = fPictureData->optionalPaint(reader); 395cb93a386Sopenharmony_ci const SkImage* image = fPictureData->getImage(reader); 396cb93a386Sopenharmony_ci SkPoint loc; 397cb93a386Sopenharmony_ci reader->readPoint(&loc); 398cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 399cb93a386Sopenharmony_ci 400cb93a386Sopenharmony_ci canvas->drawImage(image, loc.fX, loc.fY, 401cb93a386Sopenharmony_ci SkSamplingOptions(SkFilterMode::kNearest), 402cb93a386Sopenharmony_ci paint); 403cb93a386Sopenharmony_ci } break; 404cb93a386Sopenharmony_ci case DRAW_IMAGE2: { 405cb93a386Sopenharmony_ci const SkPaint* paint = fPictureData->optionalPaint(reader); 406cb93a386Sopenharmony_ci const SkImage* image = fPictureData->getImage(reader); 407cb93a386Sopenharmony_ci SkPoint loc; 408cb93a386Sopenharmony_ci reader->readPoint(&loc); 409cb93a386Sopenharmony_ci SkSamplingOptions sampling = reader->readSampling(); 410cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 411cb93a386Sopenharmony_ci 412cb93a386Sopenharmony_ci canvas->drawImage(image, loc.fX, loc.fY, sampling, paint); 413cb93a386Sopenharmony_ci } break; 414cb93a386Sopenharmony_ci case DRAW_IMAGE_LATTICE: { 415cb93a386Sopenharmony_ci const SkPaint* paint = fPictureData->optionalPaint(reader); 416cb93a386Sopenharmony_ci const SkImage* image = fPictureData->getImage(reader); 417cb93a386Sopenharmony_ci SkCanvas::Lattice lattice; 418cb93a386Sopenharmony_ci (void)SkCanvasPriv::ReadLattice(*reader, &lattice); 419cb93a386Sopenharmony_ci const SkRect* dst = reader->skipT<SkRect>(); 420cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 421cb93a386Sopenharmony_ci 422cb93a386Sopenharmony_ci canvas->drawImageLattice(image, lattice, *dst, SkFilterMode::kNearest, paint); 423cb93a386Sopenharmony_ci } break; 424cb93a386Sopenharmony_ci case DRAW_IMAGE_LATTICE2: { 425cb93a386Sopenharmony_ci const SkPaint* paint = fPictureData->optionalPaint(reader); 426cb93a386Sopenharmony_ci const SkImage* image = fPictureData->getImage(reader); 427cb93a386Sopenharmony_ci SkCanvas::Lattice lattice; 428cb93a386Sopenharmony_ci (void)SkCanvasPriv::ReadLattice(*reader, &lattice); 429cb93a386Sopenharmony_ci const SkRect* dst = reader->skipT<SkRect>(); 430cb93a386Sopenharmony_ci SkFilterMode filter = reader->read32LE(SkFilterMode::kLinear); 431cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 432cb93a386Sopenharmony_ci 433cb93a386Sopenharmony_ci canvas->drawImageLattice(image, lattice, *dst, filter, paint); 434cb93a386Sopenharmony_ci } break; 435cb93a386Sopenharmony_ci case DRAW_IMAGE_NINE: { 436cb93a386Sopenharmony_ci const SkPaint* paint = fPictureData->optionalPaint(reader); 437cb93a386Sopenharmony_ci const SkImage* image = fPictureData->getImage(reader); 438cb93a386Sopenharmony_ci SkIRect center; 439cb93a386Sopenharmony_ci reader->readIRect(¢er); 440cb93a386Sopenharmony_ci SkRect dst; 441cb93a386Sopenharmony_ci reader->readRect(&dst); 442cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 443cb93a386Sopenharmony_ci 444cb93a386Sopenharmony_ci canvas->drawImageNine(image, center, dst, SkFilterMode::kNearest, paint); 445cb93a386Sopenharmony_ci } break; 446cb93a386Sopenharmony_ci case DRAW_IMAGE_RECT: { 447cb93a386Sopenharmony_ci const SkPaint* paint = fPictureData->optionalPaint(reader); 448cb93a386Sopenharmony_ci const SkImage* image = fPictureData->getImage(reader); 449cb93a386Sopenharmony_ci SkRect storage; 450cb93a386Sopenharmony_ci const SkRect* src = get_rect_ptr(reader, &storage); // may be null 451cb93a386Sopenharmony_ci SkRect dst; 452cb93a386Sopenharmony_ci reader->readRect(&dst); // required 453cb93a386Sopenharmony_ci // DRAW_IMAGE_RECT_STRICT assumes this constraint, and doesn't store it 454cb93a386Sopenharmony_ci SkCanvas::SrcRectConstraint constraint = SkCanvas::kStrict_SrcRectConstraint; 455cb93a386Sopenharmony_ci if (DRAW_IMAGE_RECT == op) { 456cb93a386Sopenharmony_ci // newer op-code stores the constraint explicitly 457cb93a386Sopenharmony_ci constraint = reader->checkRange(SkCanvas::kStrict_SrcRectConstraint, 458cb93a386Sopenharmony_ci SkCanvas::kFast_SrcRectConstraint); 459cb93a386Sopenharmony_ci } 460cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 461cb93a386Sopenharmony_ci 462cb93a386Sopenharmony_ci auto sampling = SkSamplingOptions(SkFilterMode::kNearest); 463cb93a386Sopenharmony_ci if (src) { 464cb93a386Sopenharmony_ci canvas->drawImageRect(image, *src, dst, sampling, paint, constraint); 465cb93a386Sopenharmony_ci } else { 466cb93a386Sopenharmony_ci canvas->drawImageRect(image, dst, sampling, paint); 467cb93a386Sopenharmony_ci } 468cb93a386Sopenharmony_ci } break; 469cb93a386Sopenharmony_ci case DRAW_IMAGE_RECT2: { 470cb93a386Sopenharmony_ci const SkPaint* paint = fPictureData->optionalPaint(reader); 471cb93a386Sopenharmony_ci const SkImage* image = fPictureData->getImage(reader); 472cb93a386Sopenharmony_ci SkRect src = reader->readRect(); 473cb93a386Sopenharmony_ci SkRect dst = reader->readRect(); 474cb93a386Sopenharmony_ci SkSamplingOptions sampling = reader->readSampling(); 475cb93a386Sopenharmony_ci auto constraint = reader->read32LE(SkCanvas::kFast_SrcRectConstraint); 476cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 477cb93a386Sopenharmony_ci 478cb93a386Sopenharmony_ci canvas->drawImageRect(image, src, dst, sampling, paint, constraint); 479cb93a386Sopenharmony_ci } break; 480cb93a386Sopenharmony_ci case DRAW_OVAL: { 481cb93a386Sopenharmony_ci const SkPaint& paint = fPictureData->requiredPaint(reader); 482cb93a386Sopenharmony_ci SkRect rect; 483cb93a386Sopenharmony_ci reader->readRect(&rect); 484cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 485cb93a386Sopenharmony_ci 486cb93a386Sopenharmony_ci canvas->drawOval(rect, paint); 487cb93a386Sopenharmony_ci } break; 488cb93a386Sopenharmony_ci case DRAW_PAINT: { 489cb93a386Sopenharmony_ci const SkPaint& paint = fPictureData->requiredPaint(reader); 490cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 491cb93a386Sopenharmony_ci 492cb93a386Sopenharmony_ci canvas->drawPaint(paint); 493cb93a386Sopenharmony_ci } break; 494cb93a386Sopenharmony_ci case DRAW_BEHIND_PAINT: { 495cb93a386Sopenharmony_ci const SkPaint& paint = fPictureData->requiredPaint(reader); 496cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 497cb93a386Sopenharmony_ci 498cb93a386Sopenharmony_ci SkCanvasPriv::DrawBehind(canvas, paint); 499cb93a386Sopenharmony_ci } break; 500cb93a386Sopenharmony_ci case DRAW_PATCH: { 501cb93a386Sopenharmony_ci const SkPaint& paint = fPictureData->requiredPaint(reader); 502cb93a386Sopenharmony_ci 503cb93a386Sopenharmony_ci const SkPoint* cubics = (const SkPoint*)reader->skip(SkPatchUtils::kNumCtrlPts, 504cb93a386Sopenharmony_ci sizeof(SkPoint)); 505cb93a386Sopenharmony_ci uint32_t flag = reader->readInt(); 506cb93a386Sopenharmony_ci const SkColor* colors = nullptr; 507cb93a386Sopenharmony_ci if (flag & DRAW_VERTICES_HAS_COLORS) { 508cb93a386Sopenharmony_ci colors = (const SkColor*)reader->skip(SkPatchUtils::kNumCorners, sizeof(SkColor)); 509cb93a386Sopenharmony_ci } 510cb93a386Sopenharmony_ci const SkPoint* texCoords = nullptr; 511cb93a386Sopenharmony_ci if (flag & DRAW_VERTICES_HAS_TEXS) { 512cb93a386Sopenharmony_ci texCoords = (const SkPoint*)reader->skip(SkPatchUtils::kNumCorners, 513cb93a386Sopenharmony_ci sizeof(SkPoint)); 514cb93a386Sopenharmony_ci } 515cb93a386Sopenharmony_ci SkBlendMode bmode = SkBlendMode::kModulate; 516cb93a386Sopenharmony_ci if (flag & DRAW_VERTICES_HAS_XFER) { 517cb93a386Sopenharmony_ci unsigned mode = reader->readInt(); 518cb93a386Sopenharmony_ci if (mode <= (unsigned)SkBlendMode::kLastMode) { 519cb93a386Sopenharmony_ci bmode = (SkBlendMode)mode; 520cb93a386Sopenharmony_ci } 521cb93a386Sopenharmony_ci } 522cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 523cb93a386Sopenharmony_ci 524cb93a386Sopenharmony_ci canvas->drawPatch(cubics, colors, texCoords, bmode, paint); 525cb93a386Sopenharmony_ci } break; 526cb93a386Sopenharmony_ci case DRAW_PATH: { 527cb93a386Sopenharmony_ci const SkPaint& paint = fPictureData->requiredPaint(reader); 528cb93a386Sopenharmony_ci const auto& path = fPictureData->getPath(reader); 529cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 530cb93a386Sopenharmony_ci 531cb93a386Sopenharmony_ci canvas->drawPath(path, paint); 532cb93a386Sopenharmony_ci } break; 533cb93a386Sopenharmony_ci case DRAW_PICTURE: { 534cb93a386Sopenharmony_ci const auto* pic = fPictureData->getPicture(reader); 535cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 536cb93a386Sopenharmony_ci 537cb93a386Sopenharmony_ci canvas->drawPicture(pic); 538cb93a386Sopenharmony_ci } break; 539cb93a386Sopenharmony_ci case DRAW_PICTURE_MATRIX_PAINT: { 540cb93a386Sopenharmony_ci const SkPaint* paint = fPictureData->optionalPaint(reader); 541cb93a386Sopenharmony_ci SkMatrix matrix; 542cb93a386Sopenharmony_ci reader->readMatrix(&matrix); 543cb93a386Sopenharmony_ci const SkPicture* pic = fPictureData->getPicture(reader); 544cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 545cb93a386Sopenharmony_ci 546cb93a386Sopenharmony_ci canvas->drawPicture(pic, &matrix, paint); 547cb93a386Sopenharmony_ci } break; 548cb93a386Sopenharmony_ci case DRAW_POINTS: { 549cb93a386Sopenharmony_ci const SkPaint& paint = fPictureData->requiredPaint(reader); 550cb93a386Sopenharmony_ci SkCanvas::PointMode mode = reader->checkRange(SkCanvas::kPoints_PointMode, 551cb93a386Sopenharmony_ci SkCanvas::kPolygon_PointMode); 552cb93a386Sopenharmony_ci size_t count = reader->readInt(); 553cb93a386Sopenharmony_ci const SkPoint* pts = (const SkPoint*)reader->skip(count, sizeof(SkPoint)); 554cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 555cb93a386Sopenharmony_ci 556cb93a386Sopenharmony_ci canvas->drawPoints(mode, count, pts, paint); 557cb93a386Sopenharmony_ci } break; 558cb93a386Sopenharmony_ci case DRAW_RECT: { 559cb93a386Sopenharmony_ci const SkPaint& paint = fPictureData->requiredPaint(reader); 560cb93a386Sopenharmony_ci SkRect rect; 561cb93a386Sopenharmony_ci reader->readRect(&rect); 562cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 563cb93a386Sopenharmony_ci 564cb93a386Sopenharmony_ci canvas->drawRect(rect, paint); 565cb93a386Sopenharmony_ci } break; 566cb93a386Sopenharmony_ci case DRAW_REGION: { 567cb93a386Sopenharmony_ci const SkPaint& paint = fPictureData->requiredPaint(reader); 568cb93a386Sopenharmony_ci SkRegion region; 569cb93a386Sopenharmony_ci reader->readRegion(®ion); 570cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 571cb93a386Sopenharmony_ci 572cb93a386Sopenharmony_ci canvas->drawRegion(region, paint); 573cb93a386Sopenharmony_ci } break; 574cb93a386Sopenharmony_ci case DRAW_RRECT: { 575cb93a386Sopenharmony_ci const SkPaint& paint = fPictureData->requiredPaint(reader); 576cb93a386Sopenharmony_ci SkRRect rrect; 577cb93a386Sopenharmony_ci reader->readRRect(&rrect); 578cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 579cb93a386Sopenharmony_ci 580cb93a386Sopenharmony_ci canvas->drawRRect(rrect, paint); 581cb93a386Sopenharmony_ci } break; 582cb93a386Sopenharmony_ci case DRAW_SHADOW_REC: { 583cb93a386Sopenharmony_ci const auto& path = fPictureData->getPath(reader); 584cb93a386Sopenharmony_ci SkDrawShadowRec rec; 585cb93a386Sopenharmony_ci reader->readPoint3(&rec.fZPlaneParams); 586cb93a386Sopenharmony_ci reader->readPoint3(&rec.fLightPos); 587cb93a386Sopenharmony_ci rec.fLightRadius = reader->readScalar(); 588cb93a386Sopenharmony_ci rec.fAmbientColor = reader->read32(); 589cb93a386Sopenharmony_ci rec.fSpotColor = reader->read32(); 590cb93a386Sopenharmony_ci rec.fFlags = reader->read32(); 591cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 592cb93a386Sopenharmony_ci 593cb93a386Sopenharmony_ci canvas->private_draw_shadow_rec(path, rec); 594cb93a386Sopenharmony_ci } break; 595cb93a386Sopenharmony_ci case DRAW_TEXT_BLOB: { 596cb93a386Sopenharmony_ci const SkPaint& paint = fPictureData->requiredPaint(reader); 597cb93a386Sopenharmony_ci const SkTextBlob* blob = fPictureData->getTextBlob(reader); 598cb93a386Sopenharmony_ci SkScalar x = reader->readScalar(); 599cb93a386Sopenharmony_ci SkScalar y = reader->readScalar(); 600cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 601cb93a386Sopenharmony_ci 602cb93a386Sopenharmony_ci canvas->drawTextBlob(blob, x, y, paint); 603cb93a386Sopenharmony_ci } break; 604cb93a386Sopenharmony_ci case DRAW_VERTICES_OBJECT: { 605cb93a386Sopenharmony_ci const SkPaint& paint = fPictureData->requiredPaint(reader); 606cb93a386Sopenharmony_ci const SkVertices* vertices = fPictureData->getVertices(reader); 607cb93a386Sopenharmony_ci const int boneCount = reader->readInt(); 608cb93a386Sopenharmony_ci (void)reader->skip(boneCount, sizeof(SkVertices_DeprecatedBone)); 609cb93a386Sopenharmony_ci SkBlendMode bmode = reader->read32LE(SkBlendMode::kLastMode); 610cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 611cb93a386Sopenharmony_ci 612cb93a386Sopenharmony_ci if (vertices) { // TODO: read error if vertices == null? 613cb93a386Sopenharmony_ci canvas->drawVertices(vertices, bmode, paint); 614cb93a386Sopenharmony_ci } 615cb93a386Sopenharmony_ci } break; 616cb93a386Sopenharmony_ci case MARK_CTM: { 617cb93a386Sopenharmony_ci SkString name; 618cb93a386Sopenharmony_ci reader->readString(&name); 619cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 620cb93a386Sopenharmony_ci canvas->markCTM(name.c_str()); 621cb93a386Sopenharmony_ci } break; 622cb93a386Sopenharmony_ci case RESTORE: 623cb93a386Sopenharmony_ci canvas->restore(); 624cb93a386Sopenharmony_ci break; 625cb93a386Sopenharmony_ci case ROTATE: { 626cb93a386Sopenharmony_ci auto deg = reader->readScalar(); 627cb93a386Sopenharmony_ci canvas->rotate(deg); 628cb93a386Sopenharmony_ci } break; 629cb93a386Sopenharmony_ci case SAVE: 630cb93a386Sopenharmony_ci canvas->save(); 631cb93a386Sopenharmony_ci break; 632cb93a386Sopenharmony_ci case SAVE_BEHIND: { 633cb93a386Sopenharmony_ci uint32_t flags = reader->readInt(); 634cb93a386Sopenharmony_ci const SkRect* subset = nullptr; 635cb93a386Sopenharmony_ci SkRect storage; 636cb93a386Sopenharmony_ci if (flags & SAVEBEHIND_HAS_SUBSET) { 637cb93a386Sopenharmony_ci reader->readRect(&storage); 638cb93a386Sopenharmony_ci subset = &storage; 639cb93a386Sopenharmony_ci } 640cb93a386Sopenharmony_ci SkCanvasPriv::SaveBehind(canvas, subset); 641cb93a386Sopenharmony_ci } break; 642cb93a386Sopenharmony_ci case SAVE_LAYER_SAVELAYERREC: { 643cb93a386Sopenharmony_ci SkCanvas::SaveLayerRec rec(nullptr, nullptr, nullptr, 0); 644cb93a386Sopenharmony_ci const uint32_t flatFlags = reader->readInt(); 645cb93a386Sopenharmony_ci SkRect bounds; 646cb93a386Sopenharmony_ci if (flatFlags & SAVELAYERREC_HAS_BOUNDS) { 647cb93a386Sopenharmony_ci reader->readRect(&bounds); 648cb93a386Sopenharmony_ci rec.fBounds = &bounds; 649cb93a386Sopenharmony_ci } 650cb93a386Sopenharmony_ci if (flatFlags & SAVELAYERREC_HAS_PAINT) { 651cb93a386Sopenharmony_ci rec.fPaint = &fPictureData->requiredPaint(reader); 652cb93a386Sopenharmony_ci } 653cb93a386Sopenharmony_ci if (flatFlags & SAVELAYERREC_HAS_BACKDROP) { 654cb93a386Sopenharmony_ci const SkPaint& paint = fPictureData->requiredPaint(reader); 655cb93a386Sopenharmony_ci rec.fBackdrop = paint.getImageFilter(); 656cb93a386Sopenharmony_ci } 657cb93a386Sopenharmony_ci if (flatFlags & SAVELAYERREC_HAS_FLAGS) { 658cb93a386Sopenharmony_ci rec.fSaveLayerFlags = reader->readInt(); 659cb93a386Sopenharmony_ci } 660cb93a386Sopenharmony_ci if (flatFlags & SAVELAYERREC_HAS_CLIPMASK_OBSOLETE) { 661cb93a386Sopenharmony_ci (void)fPictureData->getImage(reader); 662cb93a386Sopenharmony_ci } 663cb93a386Sopenharmony_ci if (flatFlags & SAVELAYERREC_HAS_CLIPMATRIX_OBSOLETE) { 664cb93a386Sopenharmony_ci SkMatrix clipMatrix_ignored; 665cb93a386Sopenharmony_ci reader->readMatrix(&clipMatrix_ignored); 666cb93a386Sopenharmony_ci } 667cb93a386Sopenharmony_ci if (!reader->isVersionLT(SkPicturePriv::Version::kBackdropScaleFactor) && 668cb93a386Sopenharmony_ci (flatFlags & SAVELAYERREC_HAS_BACKDROP_SCALE)) { 669cb93a386Sopenharmony_ci SkCanvasPriv::SetBackdropScaleFactor(&rec, reader->readScalar()); 670cb93a386Sopenharmony_ci } 671cb93a386Sopenharmony_ci BREAK_ON_READ_ERROR(reader); 672cb93a386Sopenharmony_ci 673cb93a386Sopenharmony_ci canvas->saveLayer(rec); 674cb93a386Sopenharmony_ci } break; 675cb93a386Sopenharmony_ci case SCALE: { 676cb93a386Sopenharmony_ci SkScalar sx = reader->readScalar(); 677cb93a386Sopenharmony_ci SkScalar sy = reader->readScalar(); 678cb93a386Sopenharmony_ci canvas->scale(sx, sy); 679cb93a386Sopenharmony_ci } break; 680cb93a386Sopenharmony_ci case SET_M44: { 681cb93a386Sopenharmony_ci SkM44 m; 682cb93a386Sopenharmony_ci reader->read(&m); 683cb93a386Sopenharmony_ci canvas->setMatrix(initialMatrix * m); 684cb93a386Sopenharmony_ci } break; 685cb93a386Sopenharmony_ci case SET_MATRIX: { 686cb93a386Sopenharmony_ci SkMatrix matrix; 687cb93a386Sopenharmony_ci reader->readMatrix(&matrix); 688cb93a386Sopenharmony_ci canvas->setMatrix(initialMatrix * SkM44(matrix)); 689cb93a386Sopenharmony_ci } break; 690cb93a386Sopenharmony_ci case SKEW: { 691cb93a386Sopenharmony_ci SkScalar sx = reader->readScalar(); 692cb93a386Sopenharmony_ci SkScalar sy = reader->readScalar(); 693cb93a386Sopenharmony_ci canvas->skew(sx, sy); 694cb93a386Sopenharmony_ci } break; 695cb93a386Sopenharmony_ci case TRANSLATE: { 696cb93a386Sopenharmony_ci SkScalar dx = reader->readScalar(); 697cb93a386Sopenharmony_ci SkScalar dy = reader->readScalar(); 698cb93a386Sopenharmony_ci canvas->translate(dx, dy); 699cb93a386Sopenharmony_ci } break; 700cb93a386Sopenharmony_ci default: 701cb93a386Sopenharmony_ci reader->validate(false); // unknown op 702cb93a386Sopenharmony_ci break; 703cb93a386Sopenharmony_ci } 704cb93a386Sopenharmony_ci 705cb93a386Sopenharmony_ci#undef BREAK_ON_READ_ERROR 706cb93a386Sopenharmony_ci} 707