| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2008 The Android Open Source Project | 2 * Copyright 2008 The Android Open Source Project |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 | 8 |
| 9 #include "SkCanvas.h" | 9 #include "SkCanvas.h" |
| 10 #include "SkCanvasPriv.h" | 10 #include "SkCanvasPriv.h" |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 typedef SkTLazy<SkPaint> SkLazyPaint; | 60 typedef SkTLazy<SkPaint> SkLazyPaint; |
| 61 | 61 |
| 62 void SkCanvas::predrawNotify() { | 62 void SkCanvas::predrawNotify() { |
| 63 if (fSurfaceBase) { | 63 if (fSurfaceBase) { |
| 64 fSurfaceBase->aboutToDraw(SkSurface::kRetain_ContentChangeMode); | 64 fSurfaceBase->aboutToDraw(SkSurface::kRetain_ContentChangeMode); |
| 65 } | 65 } |
| 66 } | 66 } |
| 67 | 67 |
| 68 /////////////////////////////////////////////////////////////////////////////// | 68 /////////////////////////////////////////////////////////////////////////////// |
| 69 | 69 |
| 70 static bool disable_lcd(const SkSurfaceProps& props) { |
| 71 return kUnknown_SkPixelGeometry == props.pixelGeometry(); |
| 72 } |
| 73 |
| 74 static bool disable_lcd(const SkPaint& paint) { |
| 75 return paint.getRasterizer() || paint.getPathEffect() || paint.isFakeBoldTex
t() || |
| 76 paint.getStyle() != SkPaint::kFill_Style || |
| 77 !SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode); |
| 78 } |
| 79 |
| 80 void apply_props_to_paint(const SkSurfaceProps& props, SkPaint* paint) { |
| 81 const uint32_t propFlags = props.flags(); |
| 82 uint32_t clearMask = 0; |
| 83 |
| 84 if (paint->isDither() && (propFlags & SkSurfaceProps::kDisallowDither_Flag))
{ |
| 85 clearMask |= SkPaint::kDither_Flag; |
| 86 } |
| 87 if (paint->isAntiAlias()) { |
| 88 if (propFlags & SkSurfaceProps::kDisallowAntiAlias_Flag) { |
| 89 clearMask |= SkPaint::kAntiAlias_Flag; |
| 90 } else if (paint->isLCDRenderText() && (disable_lcd(props) || disable_lc
d(*paint))) { |
| 91 clearMask |= SkPaint::kLCDRenderText_Flag; |
| 92 } |
| 93 } |
| 94 |
| 95 if (clearMask) { |
| 96 paint->setFlags(paint->getFlags() & ~clearMask); |
| 97 } |
| 98 } |
| 99 |
| 100 /////////////////////////////////////////////////////////////////////////////// |
| 101 |
| 70 /* This is the record we keep for each SkBaseDevice that the user installs. | 102 /* This is the record we keep for each SkBaseDevice that the user installs. |
| 71 The clip/matrix/proc are fields that reflect the top of the save/restore | 103 The clip/matrix/proc are fields that reflect the top of the save/restore |
| 72 stack. Whenever the canvas changes, it marks a dirty flag, and then before | 104 stack. Whenever the canvas changes, it marks a dirty flag, and then before |
| 73 these are used (assuming we're not on a layer) we rebuild these cache | 105 these are used (assuming we're not on a layer) we rebuild these cache |
| 74 values: they reflect the top of the save stack, but translated and clipped | 106 values: they reflect the top of the save stack, but translated and clipped |
| 75 by the device's XY offset and bitmap-bounds. | 107 by the device's XY offset and bitmap-bounds. |
| 76 */ | 108 */ |
| 77 struct DeviceCM { | 109 struct DeviceCM { |
| 78 DeviceCM* fNext; | 110 DeviceCM* fNext; |
| 79 SkBaseDevice* fDevice; | 111 SkBaseDevice* fDevice; |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 const SkPaint* fPaint; // May be null. | 275 const SkPaint* fPaint; // May be null. |
| 244 SkBool8 fSkipEmptyClips; | 276 SkBool8 fSkipEmptyClips; |
| 245 | 277 |
| 246 typedef SkDraw INHERITED; | 278 typedef SkDraw INHERITED; |
| 247 }; | 279 }; |
| 248 | 280 |
| 249 ///////////////////////////////////////////////////////////////////////////// | 281 ///////////////////////////////////////////////////////////////////////////// |
| 250 | 282 |
| 251 class AutoDrawLooper { | 283 class AutoDrawLooper { |
| 252 public: | 284 public: |
| 253 AutoDrawLooper(SkCanvas* canvas, const SkPaint& paint, | 285 AutoDrawLooper(SkCanvas* canvas, const SkSurfaceProps& props, const SkPaint&
paint, |
| 254 bool skipLayerForImageFilter = false, | 286 bool skipLayerForImageFilter = false, |
| 255 const SkRect* bounds = NULL) : fOrigPaint(paint) { | 287 const SkRect* bounds = NULL) : fProps(props), fOrigPaint(pain
t) { |
| 256 fCanvas = canvas; | 288 fCanvas = canvas; |
| 257 fFilter = canvas->getDrawFilter(); | 289 fFilter = canvas->getDrawFilter(); |
| 258 fPaint = NULL; | 290 fPaint = NULL; |
| 259 fSaveCount = canvas->getSaveCount(); | 291 fSaveCount = canvas->getSaveCount(); |
| 260 fDoClearImageFilter = false; | 292 fDoClearImageFilter = false; |
| 261 fDone = false; | 293 fDone = false; |
| 262 | 294 |
| 263 if (!skipLayerForImageFilter && fOrigPaint.getImageFilter()) { | 295 if (!skipLayerForImageFilter && fOrigPaint.getImageFilter()) { |
| 264 SkPaint tmp; | 296 SkPaint tmp; |
| 265 tmp.setImageFilter(fOrigPaint.getImageFilter()); | 297 tmp.setImageFilter(fOrigPaint.getImageFilter()); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 302 fPaint = &fOrigPaint; | 334 fPaint = &fOrigPaint; |
| 303 return !fPaint->nothingToDraw(); | 335 return !fPaint->nothingToDraw(); |
| 304 } else { | 336 } else { |
| 305 return this->doNext(drawType); | 337 return this->doNext(drawType); |
| 306 } | 338 } |
| 307 } | 339 } |
| 308 | 340 |
| 309 private: | 341 private: |
| 310 SkLazyPaint fLazyPaint; | 342 SkLazyPaint fLazyPaint; |
| 311 SkCanvas* fCanvas; | 343 SkCanvas* fCanvas; |
| 344 const SkSurfaceProps& fProps; |
| 312 const SkPaint& fOrigPaint; | 345 const SkPaint& fOrigPaint; |
| 313 SkDrawFilter* fFilter; | 346 SkDrawFilter* fFilter; |
| 314 const SkPaint* fPaint; | 347 const SkPaint* fPaint; |
| 315 int fSaveCount; | 348 int fSaveCount; |
| 316 bool fDoClearImageFilter; | 349 bool fDoClearImageFilter; |
| 317 bool fDone; | 350 bool fDone; |
| 318 bool fIsSimple; | 351 bool fIsSimple; |
| 319 SkDrawLooper::Context* fLooperContext; | 352 SkDrawLooper::Context* fLooperContext; |
| 320 SkSmallAllocator<1, 32> fLooperContextAllocator; | 353 SkSmallAllocator<1, 32> fLooperContextAllocator; |
| 321 | 354 |
| 322 bool doNext(SkDrawFilter::Type drawType); | 355 bool doNext(SkDrawFilter::Type drawType); |
| 323 }; | 356 }; |
| 324 | 357 |
| 325 bool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) { | 358 bool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) { |
| 326 fPaint = NULL; | 359 fPaint = NULL; |
| 327 SkASSERT(!fIsSimple); | 360 SkASSERT(!fIsSimple); |
| 328 SkASSERT(fLooperContext || fFilter || fDoClearImageFilter); | 361 SkASSERT(fLooperContext || fFilter || fDoClearImageFilter); |
| 329 | 362 |
| 330 SkPaint* paint = fLazyPaint.set(fOrigPaint); | 363 SkPaint* paint = fLazyPaint.set(fOrigPaint); |
| 331 | 364 |
| 332 if (fDoClearImageFilter) { | 365 if (fDoClearImageFilter) { |
| 333 paint->setImageFilter(NULL); | 366 paint->setImageFilter(NULL); |
| 334 } | 367 } |
| 368 apply_props_to_paint(fProps, paint); |
| 335 | 369 |
| 336 if (fLooperContext && !fLooperContext->next(fCanvas, paint)) { | 370 if (fLooperContext && !fLooperContext->next(fCanvas, paint)) { |
| 337 fDone = true; | 371 fDone = true; |
| 338 return false; | 372 return false; |
| 339 } | 373 } |
| 340 if (fFilter) { | 374 if (fFilter) { |
| 341 if (!fFilter->filter(paint, drawType)) { | 375 if (!fFilter->filter(paint, drawType)) { |
| 342 fDone = true; | 376 fDone = true; |
| 343 return false; | 377 return false; |
| 344 } | 378 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 361 } | 395 } |
| 362 return true; | 396 return true; |
| 363 } | 397 } |
| 364 | 398 |
| 365 #include "SkColorPriv.h" | 399 #include "SkColorPriv.h" |
| 366 | 400 |
| 367 ////////// macros to place around the internal draw calls ////////////////// | 401 ////////// macros to place around the internal draw calls ////////////////// |
| 368 | 402 |
| 369 #define LOOPER_BEGIN_DRAWDEVICE(paint, type) \ | 403 #define LOOPER_BEGIN_DRAWDEVICE(paint, type) \ |
| 370 this->predrawNotify(); \ | 404 this->predrawNotify(); \ |
| 371 AutoDrawLooper looper(this, paint, true); \ | 405 AutoDrawLooper looper(this, fProps, paint, true); \ |
| 372 while (looper.next(type)) { \ | 406 while (looper.next(type)) { \ |
| 373 SkDrawIter iter(this); | 407 SkDrawIter iter(this); |
| 374 | 408 |
| 375 #define LOOPER_BEGIN(paint, type, bounds) \ | 409 #define LOOPER_BEGIN(paint, type, bounds) \ |
| 376 this->predrawNotify(); \ | 410 this->predrawNotify(); \ |
| 377 AutoDrawLooper looper(this, paint, false, bounds); \ | 411 AutoDrawLooper looper(this, fProps, paint, false, bounds); \ |
| 378 while (looper.next(type)) { \ | 412 while (looper.next(type)) { \ |
| 379 SkDrawIter iter(this); | 413 SkDrawIter iter(this); |
| 380 | 414 |
| 381 #define LOOPER_END } | 415 #define LOOPER_END } |
| 382 | 416 |
| 383 //////////////////////////////////////////////////////////////////////////// | 417 //////////////////////////////////////////////////////////////////////////// |
| 384 | 418 |
| 385 SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) { | 419 SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) { |
| 386 fConservativeRasterClip = SkToBool(flags & kConservativeRasterClip_InitFlag)
; | 420 fConservativeRasterClip = SkToBool(flags & kConservativeRasterClip_InitFlag)
; |
| 387 fCachedLocalClipBounds.setEmpty(); | 421 fCachedLocalClipBounds.setEmpty(); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 461 } | 495 } |
| 462 | 496 |
| 463 SkCanvas::SkCanvas(SkBaseDevice* device) | 497 SkCanvas::SkCanvas(SkBaseDevice* device) |
| 464 : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) | 498 : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) |
| 465 { | 499 { |
| 466 inc_canvas(); | 500 inc_canvas(); |
| 467 | 501 |
| 468 this->init(device, kDefault_InitFlags); | 502 this->init(device, kDefault_InitFlags); |
| 469 } | 503 } |
| 470 | 504 |
| 471 SkCanvas::SkCanvas(const SkBitmap& bitmap) | 505 SkCanvas::SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps* props) |
| 472 : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) | 506 : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) |
| 507 , fProps(props ? *props : SkSurfaceProps()) |
| 473 { | 508 { |
| 474 inc_canvas(); | 509 inc_canvas(); |
| 475 | 510 |
| 476 this->init(SkNEW_ARGS(SkBitmapDevice, (bitmap)), kDefault_InitFlags)->unref(
); | 511 SkAutoTUnref<SkBaseDevice> device(SkNEW_ARGS(SkBitmapDevice, (bitmap))); |
| 512 this->init(device, kDefault_InitFlags); |
| 477 } | 513 } |
| 478 | 514 |
| 479 SkCanvas::~SkCanvas() { | 515 SkCanvas::~SkCanvas() { |
| 480 // free up the contents of our deque | 516 // free up the contents of our deque |
| 481 this->restoreToCount(1); // restore everything but the last | 517 this->restoreToCount(1); // restore everything but the last |
| 482 SkASSERT(0 == fSaveLayerCount); | 518 SkASSERT(0 == fSaveLayerCount); |
| 483 | 519 |
| 484 this->internalRestore(); // restore the last, since we're going away | 520 this->internalRestore(); // restore the last, since we're going away |
| 485 | 521 |
| 486 SkDELETE(fMetaData); | 522 SkDELETE(fMetaData); |
| (...skipping 2004 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2491 } | 2527 } |
| 2492 | 2528 |
| 2493 if (matrix) { | 2529 if (matrix) { |
| 2494 canvas->concat(*matrix); | 2530 canvas->concat(*matrix); |
| 2495 } | 2531 } |
| 2496 } | 2532 } |
| 2497 | 2533 |
| 2498 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { | 2534 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { |
| 2499 fCanvas->restoreToCount(fSaveCount); | 2535 fCanvas->restoreToCount(fSaveCount); |
| 2500 } | 2536 } |
| OLD | NEW |