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