1/* 2 Copyright 2011 Google Inc. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 18#include "SkCanvas.h" 19#include "SkPaint.h" 20#include "SkGPipe.h" 21#include "SkGPipePriv.h" 22#include "SkReader32.h" 23#include "SkStream.h" 24 25#include "SkColorFilter.h" 26#include "SkDrawLooper.h" 27#include "SkMaskFilter.h" 28#include "SkPathEffect.h" 29#include "SkRasterizer.h" 30#include "SkShader.h" 31#include "SkTypeface.h" 32#include "SkXfermode.h" 33 34static void set_paintflat(SkPaint* paint, SkFlattenable* obj, unsigned paintFlat) { 35 SkASSERT(paintFlat < kCount_PaintFlats); 36 switch (paintFlat) { 37 case kColorFilter_PaintFlat: 38 paint->setColorFilter((SkColorFilter*)obj); 39 break; 40 case kDrawLooper_PaintFlat: 41 paint->setLooper((SkDrawLooper*)obj); 42 break; 43 case kMaskFilter_PaintFlat: 44 paint->setMaskFilter((SkMaskFilter*)obj); 45 break; 46 case kPathEffect_PaintFlat: 47 paint->setPathEffect((SkPathEffect*)obj); 48 break; 49 case kRasterizer_PaintFlat: 50 paint->setRasterizer((SkRasterizer*)obj); 51 break; 52 case kShader_PaintFlat: 53 paint->setShader((SkShader*)obj); 54 break; 55 case kXfermode_PaintFlat: 56 paint->setXfermode((SkXfermode*)obj); 57 break; 58 default: 59 SkASSERT(!"never gets here"); 60 } 61} 62 63template <typename T> class SkRefCntTDArray : public SkTDArray<T> { 64public: 65 ~SkRefCntTDArray() { this->unrefAll(); } 66}; 67 68class SkGPipeState { 69public: 70 SkGPipeState(); 71 ~SkGPipeState(); 72 73 void setReader(SkFlattenableReadBuffer* reader) { 74 fReader = reader; 75 fReader->setFactoryPlayback(fFactoryArray.begin(), fFactoryArray.count()); 76 } 77 78 const SkPaint& paint() const { return fPaint; } 79 SkPaint* editPaint() { return &fPaint; } 80 81 SkFlattenable* getFlat(unsigned index) const { 82 if (0 == index) { 83 return NULL; 84 } 85 return fFlatArray[index - 1]; 86 } 87 88 void defFlattenable(PaintFlats pf, unsigned index) { 89 SkASSERT(index == fFlatArray.count() + 1); 90 SkFlattenable* obj = fReader->readFlattenable(); 91 *fFlatArray.append() = obj; 92 } 93 94 void nameFlattenable(PaintFlats pf, unsigned index) { 95 SkASSERT(index == fFactoryArray.count() + 1); 96 const char* name = fReader->readString(); 97 SkFlattenable::Factory fact = SkFlattenable::NameToFactory(name); 98 *fFactoryArray.append() = fact; 99 100 // update this each time we grow the array 101 fReader->setFactoryPlayback(fFactoryArray.begin(), fFactoryArray.count()); 102 } 103 104 void addTypeface() { 105 size_t size = fReader->readU32(); 106 const void* data = fReader->skip(SkAlign4(size)); 107 SkMemoryStream stream(data, size, false); 108 *fTypefaces.append() = SkTypeface::Deserialize(&stream); 109 } 110 void setTypeface(SkPaint* paint, unsigned id) { 111 paint->setTypeface(id ? fTypefaces[id - 1] : NULL); 112 } 113 114 SkFlattenableReadBuffer* fReader; 115 116private: 117 SkPaint fPaint; 118 SkTDArray<SkFlattenable*> fFlatArray; 119 SkTDArray<SkTypeface*> fTypefaces; 120 SkTDArray<SkFlattenable::Factory> fFactoryArray; 121}; 122 123/////////////////////////////////////////////////////////////////////////////// 124 125template <typename T> const T* skip(SkReader32* reader, int count = 1) { 126 SkASSERT(count >= 0); 127 size_t size = sizeof(T) * count; 128 SkASSERT(SkAlign4(size) == size); 129 return reinterpret_cast<const T*>(reader->skip(size)); 130} 131 132template <typename T> const T* skipAlign(SkReader32* reader, int count = 1) { 133 SkASSERT(count >= 0); 134 size_t size = SkAlign4(sizeof(T) * count); 135 return reinterpret_cast<const T*>(reader->skip(size)); 136} 137 138/////////////////////////////////////////////////////////////////////////////// 139/////////////////////////////////////////////////////////////////////////////// 140 141static void clipPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, 142 SkGPipeState* state) { 143 SkPath path; 144 path.unflatten(*reader); 145 canvas->clipPath(path, (SkRegion::Op)DrawOp_unpackData(op32)); 146} 147 148static void clipRegion_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, 149 SkGPipeState* state) { 150 SkRegion rgn; 151 SkReadRegion(reader, &rgn); 152 canvas->clipRegion(rgn, (SkRegion::Op)DrawOp_unpackData(op32)); 153} 154 155static void clipRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, 156 SkGPipeState* state) { 157 canvas->clipRect(*skip<SkRect>(reader), (SkRegion::Op)DrawOp_unpackData(op32)); 158} 159 160/////////////////////////////////////////////////////////////////////////////// 161 162static void setMatrix_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, 163 SkGPipeState* state) { 164 SkMatrix matrix; 165 SkReadMatrix(reader, &matrix); 166 canvas->setMatrix(matrix); 167} 168 169static void concat_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, 170 SkGPipeState* state) { 171 SkMatrix matrix; 172 SkReadMatrix(reader, &matrix); 173 canvas->concat(matrix); 174} 175 176static void scale_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, 177 SkGPipeState* state) { 178 const SkScalar* param = skip<SkScalar>(reader, 2); 179 canvas->scale(param[0], param[1]); 180} 181 182static void skew_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, 183 SkGPipeState* state) { 184 const SkScalar* param = skip<SkScalar>(reader, 2); 185 canvas->skew(param[0], param[1]); 186} 187 188static void rotate_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, 189 SkGPipeState* state) { 190 canvas->rotate(reader->readScalar()); 191} 192 193static void translate_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, 194 SkGPipeState* state) { 195 const SkScalar* param = skip<SkScalar>(reader, 2); 196 canvas->translate(param[0], param[1]); 197} 198 199/////////////////////////////////////////////////////////////////////////////// 200 201static void save_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, 202 SkGPipeState* state) { 203 canvas->save((SkCanvas::SaveFlags)DrawOp_unpackData(op32)); 204} 205 206static void saveLayer_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, 207 SkGPipeState* state) { 208 unsigned flags = DrawOp_unpackFlags(op32); 209 SkCanvas::SaveFlags saveFlags = (SkCanvas::SaveFlags)DrawOp_unpackData(op32); 210 211 const SkRect* bounds = NULL; 212 if (flags & kSaveLayer_HasBounds_DrawOpFlag) { 213 bounds = skip<SkRect>(reader); 214 } 215 const SkPaint* paint = NULL; 216 if (flags & kSaveLayer_HasPaint_DrawOpFlag) { 217 paint = &state->paint(); 218 } 219 canvas->saveLayer(bounds, paint, saveFlags); 220} 221 222static void restore_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, 223 SkGPipeState* state) { 224 canvas->restore(); 225} 226 227/////////////////////////////////////////////////////////////////////////////// 228 229static void drawClear_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, 230 SkGPipeState* state) { 231 SkColor color = 0; 232 if (DrawOp_unpackFlags(op32) & kClear_HasColor_DrawOpFlag) { 233 color = reader->readU32(); 234 } 235 canvas->clear(color); 236} 237 238static void drawPaint_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, 239 SkGPipeState* state) { 240 canvas->drawPaint(state->paint()); 241} 242 243static void drawPoints_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, 244 SkGPipeState* state) { 245 SkCanvas::PointMode mode = (SkCanvas::PointMode)DrawOp_unpackFlags(op32); 246 size_t count = reader->readU32(); 247 const SkPoint* pts = skip<SkPoint>(reader, count); 248 canvas->drawPoints(mode, count, pts, state->paint()); 249} 250 251static void drawRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, 252 SkGPipeState* state) { 253 canvas->drawRect(*skip<SkRect>(reader), state->paint()); 254} 255 256static void drawPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, 257 SkGPipeState* state) { 258 SkPath path; 259 path.unflatten(*reader); 260 canvas->drawPath(path, state->paint()); 261} 262 263static void drawVertices_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, 264 SkGPipeState* state) { 265 unsigned flags = DrawOp_unpackFlags(op32); 266 267 SkCanvas::VertexMode mode = (SkCanvas::VertexMode)reader->readU32(); 268 int vertexCount = reader->readU32(); 269 const SkPoint* verts = skip<SkPoint>(reader, vertexCount); 270 271 const SkPoint* texs = NULL; 272 if (flags & kDrawVertices_HasTexs_DrawOpFlag) { 273 texs = skip<SkPoint>(reader, vertexCount); 274 } 275 276 const SkColor* colors = NULL; 277 if (flags & kDrawVertices_HasColors_DrawOpFlag) { 278 colors = skip<SkColor>(reader, vertexCount); 279 } 280 281 // TODO: flatten/unflatten xfermodes 282 SkXfermode* xfer = NULL; 283 284 int indexCount = 0; 285 const uint16_t* indices = NULL; 286 if (flags & kDrawVertices_HasIndices_DrawOpFlag) { 287 indexCount = reader->readU32(); 288 indices = skipAlign<uint16_t>(reader, indexCount); 289 } 290 291 canvas->drawVertices(mode, vertexCount, verts, texs, colors, xfer, 292 indices, indexCount, state->paint()); 293} 294 295/////////////////////////////////////////////////////////////////////////////// 296 297static void drawText_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, 298 SkGPipeState* state) { 299 size_t len = reader->readU32(); 300 const void* text = reader->skip(SkAlign4(len)); 301 const SkScalar* xy = skip<SkScalar>(reader, 2); 302 canvas->drawText(text, len, xy[0], xy[1], state->paint()); 303} 304 305static void drawPosText_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, 306 SkGPipeState* state) { 307 size_t len = reader->readU32(); 308 const void* text = reader->skip(SkAlign4(len)); 309 size_t posCount = reader->readU32(); // compute by our writer 310 const SkPoint* pos = skip<SkPoint>(reader, posCount); 311 canvas->drawPosText(text, len, pos, state->paint()); 312} 313 314static void drawPosTextH_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, 315 SkGPipeState* state) { 316 size_t len = reader->readU32(); 317 const void* text = reader->skip(SkAlign4(len)); 318 size_t posCount = reader->readU32(); // compute by our writer 319 const SkScalar* xpos = skip<SkScalar>(reader, posCount); 320 SkScalar constY = reader->readScalar(); 321 canvas->drawPosTextH(text, len, xpos, constY, state->paint()); 322} 323 324static void drawTextOnPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, 325 SkGPipeState* state) { 326 size_t len = reader->readU32(); 327 const void* text = reader->skip(SkAlign4(len)); 328 329 SkPath path; 330 path.unflatten(*reader); 331 332 SkMatrix matrixStorage; 333 const SkMatrix* matrix = NULL; 334 if (DrawOp_unpackFlags(op32) & kDrawTextOnPath_HasMatrix_DrawOpFlag) { 335 SkReadMatrix(reader, &matrixStorage); 336 matrix = &matrixStorage; 337 } 338 339 canvas->drawTextOnPath(text, len, path, matrix, state->paint()); 340} 341 342/////////////////////////////////////////////////////////////////////////////// 343 344static void drawBitmap_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, 345 SkGPipeState* state) { 346 UNIMPLEMENTED 347} 348 349static void drawBitmapMatrix_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, 350 SkGPipeState* state) { 351 UNIMPLEMENTED 352} 353 354static void drawBitmapRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, 355 SkGPipeState* state) { 356 UNIMPLEMENTED 357} 358 359static void drawSprite_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, 360 SkGPipeState* state) { 361 UNIMPLEMENTED 362} 363 364/////////////////////////////////////////////////////////////////////////////// 365 366static void drawData_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, 367 SkGPipeState* state) { 368 // since we don't have a paint, we can use data for our (small) sizes 369 size_t size = DrawOp_unpackData(op32); 370 if (0 == size) { 371 size = reader->readU32(); 372 } 373 const void* data = reader->skip(SkAlign4(size)); 374 canvas->drawData(data, size); 375} 376 377static void drawShape_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, 378 SkGPipeState* state) { 379 UNIMPLEMENTED 380} 381 382static void drawPicture_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, 383 SkGPipeState* state) { 384 UNIMPLEMENTED 385} 386 387/////////////////////////////////////////////////////////////////////////////// 388 389static void paintOp_rp(SkCanvas*, SkReader32* reader, uint32_t op32, 390 SkGPipeState* state) { 391 size_t offset = reader->offset(); 392 size_t stop = offset + PaintOp_unpackData(op32); 393 SkPaint* p = state->editPaint(); 394 395 do { 396 uint32_t p32 = reader->readU32(); 397 unsigned op = PaintOp_unpackOp(p32); 398 unsigned data = PaintOp_unpackData(p32); 399 400// SkDebugf(" read %08X op=%d flags=%d data=%d\n", p32, op, done, data); 401 402 switch (op) { 403 case kReset_PaintOp: p->reset(); break; 404 case kFlags_PaintOp: p->setFlags(data); break; 405 case kColor_PaintOp: p->setColor(reader->readU32()); break; 406 case kStyle_PaintOp: p->setStyle((SkPaint::Style)data); break; 407 case kJoin_PaintOp: p->setStrokeJoin((SkPaint::Join)data); break; 408 case kCap_PaintOp: p->setStrokeCap((SkPaint::Cap)data); break; 409 case kWidth_PaintOp: p->setStrokeWidth(reader->readScalar()); break; 410 case kMiter_PaintOp: p->setStrokeMiter(reader->readScalar()); break; 411 case kEncoding_PaintOp: 412 p->setTextEncoding((SkPaint::TextEncoding)data); 413 break; 414 case kHinting_PaintOp: p->setHinting((SkPaint::Hinting)data); break; 415 case kAlign_PaintOp: p->setTextAlign((SkPaint::Align)data); break; 416 case kTextSize_PaintOp: p->setTextSize(reader->readScalar()); break; 417 case kTextScaleX_PaintOp: p->setTextScaleX(reader->readScalar()); break; 418 case kTextSkewX_PaintOp: p->setTextSkewX(reader->readScalar()); break; 419 420 case kFlatIndex_PaintOp: { 421 PaintFlats pf = (PaintFlats)PaintOp_unpackFlags(p32); 422 unsigned index = data; 423 set_paintflat(p, state->getFlat(index), pf); 424 break; 425 } 426 427 case kTypeface_PaintOp: state->setTypeface(p, data); break; 428 default: SkASSERT(!"bad paintop"); return; 429 } 430 SkASSERT(reader->offset() <= stop); 431 } while (reader->offset() < stop); 432} 433 434/////////////////////////////////////////////////////////////////////////////// 435 436static void def_Typeface_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState* state) { 437 state->addTypeface(); 438} 439 440static void def_PaintFlat_rp(SkCanvas*, SkReader32*, uint32_t op32, 441 SkGPipeState* state) { 442 PaintFlats pf = (PaintFlats)DrawOp_unpackFlags(op32); 443 unsigned index = DrawOp_unpackData(op32); 444 state->defFlattenable(pf, index); 445} 446 447static void name_PaintFlat_rp(SkCanvas*, SkReader32*, uint32_t op32, 448 SkGPipeState* state) { 449 PaintFlats pf = (PaintFlats)DrawOp_unpackFlags(op32); 450 unsigned index = DrawOp_unpackData(op32); 451 state->nameFlattenable(pf, index); 452} 453 454/////////////////////////////////////////////////////////////////////////////// 455 456static void skip_rp(SkCanvas*, SkReader32* reader, uint32_t op32, SkGPipeState*) { 457 size_t bytes = DrawOp_unpackData(op32); 458 (void)reader->skip(bytes); 459} 460 461static void done_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState*) {} 462 463typedef void (*ReadProc)(SkCanvas*, SkReader32*, uint32_t op32, SkGPipeState*); 464 465static const ReadProc gReadTable[] = { 466 skip_rp, 467 clipPath_rp, 468 clipRegion_rp, 469 clipRect_rp, 470 concat_rp, 471 drawBitmap_rp, 472 drawBitmapMatrix_rp, 473 drawBitmapRect_rp, 474 drawClear_rp, 475 drawData_rp, 476 drawPaint_rp, 477 drawPath_rp, 478 drawPicture_rp, 479 drawPoints_rp, 480 drawPosText_rp, 481 drawPosTextH_rp, 482 drawRect_rp, 483 drawShape_rp, 484 drawSprite_rp, 485 drawText_rp, 486 drawTextOnPath_rp, 487 drawVertices_rp, 488 restore_rp, 489 rotate_rp, 490 save_rp, 491 saveLayer_rp, 492 scale_rp, 493 setMatrix_rp, 494 skew_rp, 495 translate_rp, 496 497 paintOp_rp, 498 def_Typeface_rp, 499 def_PaintFlat_rp, 500 name_PaintFlat_rp, 501 502 done_rp 503}; 504 505/////////////////////////////////////////////////////////////////////////////// 506 507SkGPipeState::SkGPipeState() {} 508 509SkGPipeState::~SkGPipeState() { 510 fTypefaces.unrefAll(); 511 fFlatArray.unrefAll(); 512} 513 514/////////////////////////////////////////////////////////////////////////////// 515 516#include "SkGPipe.h" 517 518SkGPipeReader::SkGPipeReader(SkCanvas* target) { 519 SkSafeRef(target); 520 fCanvas = target; 521 fState = NULL; 522} 523 524SkGPipeReader::~SkGPipeReader() { 525 SkSafeUnref(fCanvas); 526 delete fState; 527} 528 529SkGPipeReader::Status SkGPipeReader::playback(const void* data, size_t length, 530 size_t* bytesRead) { 531 if (NULL == fCanvas) { 532 return kError_Status; 533 } 534 535 if (NULL == fState) { 536 fState = new SkGPipeState; 537 } 538 539 SkASSERT(SK_ARRAY_COUNT(gReadTable) == (kDone_DrawOp + 1)); 540 541 const ReadProc* table = gReadTable; 542 SkFlattenableReadBuffer reader(data, length); 543 SkCanvas* canvas = fCanvas; 544 Status status = kEOF_Status; 545 546 fState->setReader(&reader); 547 while (!reader.eof()) { 548 uint32_t op32 = reader.readU32(); 549 unsigned op = DrawOp_unpackOp(op32); 550 SkDEBUGCODE(DrawOps drawOp = (DrawOps)op;) 551 552 if (op >= SK_ARRAY_COUNT(gReadTable)) { 553 SkDebugf("---- bad op during GPipeState::playback\n"); 554 status = kError_Status; 555 break; 556 } 557 if (kDone_DrawOp == op) { 558 status = kDone_Status; 559 break; 560 } 561 table[op](canvas, &reader, op32, fState); 562 } 563 564 if (bytesRead) { 565 *bytesRead = reader.offset(); 566 } 567 return status; 568} 569 570 571