SkCanvas.cpp revision 6b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 28a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2008 The Android Open Source Project 48a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h" 111f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com#include "SkBitmapDevice.h" 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBounder.h" 139c39744a00573b7133fc765b0a9d50a0ceace7b8senorblanco@chromium.org#include "SkDeviceImageFilterProxy.h" 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDraw.h" 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDrawFilter.h" 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDrawLooper.h" 1774bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org#include "SkMetaData.h" 1845a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com#include "SkPathOps.h" 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPicture.h" 200017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com#include "SkRasterClip.h" 214ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com#include "SkRRect.h" 2279fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org#include "SkSmallAllocator.h" 2397af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com#include "SkSurface_Base.h" 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTemplates.h" 2552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com#include "SkTextFormatParams.h" 26a076e9be17654a60310e72c4f70fcd5337f56dbfreed@google.com#include "SkTLazy.h" 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkUtils.h" 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#if SK_SUPPORT_GPU 30644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#include "GrRenderTarget.h" 31644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#endif 32644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org 33da17f758442f16747af39f8fbaed9c097048519creed@google.com// experimental for faster tiled drawing... 34da17f758442f16747af39f8fbaed9c097048519creed@google.com//#define SK_ENABLE_CLIP_QUICKREJECT 3515e9d3e66e161ce23df30bc13f8a0c87d196b463robertphillips@google.com 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//#define SK_TRACE_SAVERESTORE 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_TRACE_SAVERESTORE 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gLayerCounter; 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_layer() { ++gLayerCounter; printf("----- inc layer %d\n", gLayerCounter); } 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_layer() { --gLayerCounter; printf("----- dec layer %d\n", gLayerCounter); } 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gRecCounter; 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_rec() { ++gRecCounter; printf("----- inc rec %d\n", gRecCounter); } 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_rec() { --gRecCounter; printf("----- dec rec %d\n", gRecCounter); } 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gCanvasCounter; 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_canvas() { ++gCanvasCounter; printf("----- inc canvas %d\n", gCanvasCounter); } 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_canvas() { --gCanvasCounter; printf("----- dec canvas %d\n", gCanvasCounter); } 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_layer() 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_layer() 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_rec() 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_rec() 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_canvas() 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_canvas() 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 59ea033606a06d05d2d42aa7118409fee798e53167reed@google.com#ifdef SK_DEBUG 60ea033606a06d05d2d42aa7118409fee798e53167reed@google.com#include "SkPixelRef.h" 61ea033606a06d05d2d42aa7118409fee798e53167reed@google.com 62f53d0a998b59f922c7e04c94310a83df76bbc400reed@google.com/* 63f53d0a998b59f922c7e04c94310a83df76bbc400reed@google.com * Some pixelref subclasses can support being "locked" from another thread 64f53d0a998b59f922c7e04c94310a83df76bbc400reed@google.com * during the lock-scope of skia calling them. In these instances, this balance 65f53d0a998b59f922c7e04c94310a83df76bbc400reed@google.com * check will fail, but may not be indicative of a problem, so we allow a build 66f53d0a998b59f922c7e04c94310a83df76bbc400reed@google.com * flag to disable this check. 67f53d0a998b59f922c7e04c94310a83df76bbc400reed@google.com * 68f53d0a998b59f922c7e04c94310a83df76bbc400reed@google.com * Potentially another fix would be to have a (debug-only) virtual or flag on 69f53d0a998b59f922c7e04c94310a83df76bbc400reed@google.com * pixelref, which could tell us at runtime if this check is valid. That would 70f53d0a998b59f922c7e04c94310a83df76bbc400reed@google.com * eliminate the need for this heavy-handed build check. 71f53d0a998b59f922c7e04c94310a83df76bbc400reed@google.com */ 72f53d0a998b59f922c7e04c94310a83df76bbc400reed@google.com#ifdef SK_DISABLE_PIXELREF_LOCKCOUNT_BALANCE_CHECK 73f53d0a998b59f922c7e04c94310a83df76bbc400reed@google.comclass AutoCheckLockCountBalance { 74f53d0a998b59f922c7e04c94310a83df76bbc400reed@google.compublic: 75f53d0a998b59f922c7e04c94310a83df76bbc400reed@google.com AutoCheckLockCountBalance(const SkBitmap&) { /* do nothing */ } 76f53d0a998b59f922c7e04c94310a83df76bbc400reed@google.com}; 77f53d0a998b59f922c7e04c94310a83df76bbc400reed@google.com#else 78ea033606a06d05d2d42aa7118409fee798e53167reed@google.comclass AutoCheckLockCountBalance { 79ea033606a06d05d2d42aa7118409fee798e53167reed@google.compublic: 80ea033606a06d05d2d42aa7118409fee798e53167reed@google.com AutoCheckLockCountBalance(const SkBitmap& bm) : fPixelRef(bm.pixelRef()) { 81ea033606a06d05d2d42aa7118409fee798e53167reed@google.com fLockCount = fPixelRef ? fPixelRef->getLockCount() : 0; 82ea033606a06d05d2d42aa7118409fee798e53167reed@google.com } 83ea033606a06d05d2d42aa7118409fee798e53167reed@google.com ~AutoCheckLockCountBalance() { 84ea033606a06d05d2d42aa7118409fee798e53167reed@google.com const int count = fPixelRef ? fPixelRef->getLockCount() : 0; 85ea033606a06d05d2d42aa7118409fee798e53167reed@google.com SkASSERT(count == fLockCount); 86ea033606a06d05d2d42aa7118409fee798e53167reed@google.com } 87ea033606a06d05d2d42aa7118409fee798e53167reed@google.com 88ea033606a06d05d2d42aa7118409fee798e53167reed@google.comprivate: 89ea033606a06d05d2d42aa7118409fee798e53167reed@google.com const SkPixelRef* fPixelRef; 90ea033606a06d05d2d42aa7118409fee798e53167reed@google.com int fLockCount; 91ea033606a06d05d2d42aa7118409fee798e53167reed@google.com}; 92f53d0a998b59f922c7e04c94310a83df76bbc400reed@google.com#endif 93ea033606a06d05d2d42aa7118409fee798e53167reed@google.com 9453783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.orgclass AutoCheckNoSetContext { 9553783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.orgpublic: 9653783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org AutoCheckNoSetContext(const SkPaint& paint) : fPaint(paint) { 9753783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org this->assertNoSetContext(fPaint); 9853783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org } 9953783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org ~AutoCheckNoSetContext() { 10053783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org this->assertNoSetContext(fPaint); 10153783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org } 10253783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org 10353783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.orgprivate: 10453783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org const SkPaint& fPaint; 10553783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org 10653783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org void assertNoSetContext(const SkPaint& paint) { 10753783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org SkShader* s = paint.getShader(); 10853783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org if (s) { 10953783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org SkASSERT(!s->setContextHasBeenCalled()); 11053783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org } 11153783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org } 11253783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org}; 11353783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org 114ea033606a06d05d2d42aa7118409fee798e53167reed@google.com#define CHECK_LOCKCOUNT_BALANCE(bitmap) AutoCheckLockCountBalance clcb(bitmap) 11553783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org#define CHECK_SHADER_NOSETCONTEXT(paint) AutoCheckNoSetContext cshsc(paint) 116ea033606a06d05d2d42aa7118409fee798e53167reed@google.com 117ea033606a06d05d2d42aa7118409fee798e53167reed@google.com#else 118ea033606a06d05d2d42aa7118409fee798e53167reed@google.com #define CHECK_LOCKCOUNT_BALANCE(bitmap) 11953783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org #define CHECK_SHADER_NOSETCONTEXT(paint) 120ea033606a06d05d2d42aa7118409fee798e53167reed@google.com#endif 121ea033606a06d05d2d42aa7118409fee798e53167reed@google.com 1222c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.orgtypedef SkTLazy<SkPaint> SkLazyPaint; 1232c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org 12497af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.comvoid SkCanvas::predrawNotify() { 12597af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com if (fSurfaceBase) { 126c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org fSurfaceBase->aboutToDraw(SkSurface::kRetain_ContentChangeMode); 12797af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com } 12897af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com} 12997af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1321f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com/* This is the record we keep for each SkBaseDevice that the user installs. 1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com The clip/matrix/proc are fields that reflect the top of the save/restore 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stack. Whenever the canvas changes, it marks a dirty flag, and then before 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com these are used (assuming we're not on a layer) we rebuild these cache 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com values: they reflect the top of the save stack, but translated and clipped 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com by the device's XY offset and bitmap-bounds. 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct DeviceCM { 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* fNext; 1411f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* fDevice; 142045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com SkRasterClip fClip; 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix* fMatrix; 1446f8f292aa768869a9e85c314b124875f57504f2creed@google.com SkPaint* fPaint; // may be null (in the future) 1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1461f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com DeviceCM(SkBaseDevice* device, int x, int y, const SkPaint* paint, SkCanvas* canvas) 1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com : fNext(NULL) { 1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL != device) { 1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device->ref(); 15040a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com device->onAttachToCanvas(canvas); 1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1524b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com fDevice = device; 1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint = paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL; 15488edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 15688edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com ~DeviceCM() { 1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL != fDevice) { 15840a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com fDevice->onDetachFromCanvas(); 1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDevice->unref(); 1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 16188edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com SkDELETE(fPaint); 16288edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 1634b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 164045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com void updateMC(const SkMatrix& totalMatrix, const SkRasterClip& totalClip, 165045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com const SkClipStack& clipStack, SkRasterClip* updateClip) { 1666f8f292aa768869a9e85c314b124875f57504f2creed@google.com int x = fDevice->getOrigin().x(); 1676f8f292aa768869a9e85c314b124875f57504f2creed@google.com int y = fDevice->getOrigin().y(); 1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int width = fDevice->width(); 1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int height = fDevice->height(); 1704b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if ((x | y) == 0) { 1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = &totalMatrix; 1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fClip = totalClip; 1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrixStorage = totalMatrix; 1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrixStorage.postTranslate(SkIntToScalar(-x), 1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIntToScalar(-y)); 1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = &fMatrixStorage; 1794b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com totalClip.translate(-x, -y, &fClip); 1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 183045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com fClip.op(SkIRect::MakeWH(width, height), SkRegion::kIntersect_Op); 1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // intersect clip, but don't translate it (yet) 1864b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (updateClip) { 188045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com updateClip->op(SkIRect::MakeXYWH(x, y, width, height), 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRegion::kDifference_Op); 1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1914b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 1923fffb2ee9fa01ae61efb2395973eb7575eda4c96robertphillips@google.com fDevice->setMatrixClip(*fMatrix, fClip.forceGetBW(), clipStack); 1933fffb2ee9fa01ae61efb2395973eb7575eda4c96robertphillips@google.com 1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!fClip.isEmpty()) { 1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIRect deviceR; 1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com deviceR.set(0, 0, width, height); 1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(deviceR.contains(fClip.getBounds())); 1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 201f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 202f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 2040e354aacd84d3bede3f97cbde35a54ba62a89533bsalomon@google.com SkMatrix fMatrixStorage; 2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 2068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* This is the record we keep for each save/restore level in the stack. 2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Since a level optionally copies the matrix and/or stack, we have pointers 2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for these fields. If the value is copied for this level, the copy is 2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stored in the ...Storage field, and the pointer points to that. If the 2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value is not copied for this level, we ignore ...Storage, and just point 2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com at the corresponding value in the previous level in the stack. 2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 2148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkCanvas::MCRec { 2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 2166c157640c27ee2ed6f9a484d21691b7b19dfecdecommit-bot@chromium.org int fFlags; 2170017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com SkMatrix* fMatrix; // points to either fMatrixStorage or prev MCRec 2180017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com SkRasterClip* fRasterClip; // points to either fRegionStorage or prev MCRec 2190017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com SkDrawFilter* fFilter; // the current filter (or null) 2204b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* fLayer; 2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* If there are any layers in the stack, this points to the top-most 2238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com one that is at or below this level in the stack (so we know what 2248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bitmap/device to draw into from this level. This value is NOT 2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com reference counted, since the real owner is either our fLayer field, 2268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com or a previous one in a lower level.) 2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 22888edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com DeviceCM* fTopLayer; 2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2306c157640c27ee2ed6f9a484d21691b7b19dfecdecommit-bot@chromium.org MCRec(const MCRec* prev, int flags) : fFlags(flags) { 2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL != prev) { 2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (flags & SkCanvas::kMatrix_SaveFlag) { 2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrixStorage = *prev->fMatrix; 2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = &fMatrixStorage; 2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = prev->fMatrix; 2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2384b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (flags & SkCanvas::kClip_SaveFlag) { 2400017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com fRasterClipStorage = *prev->fRasterClip; 2410017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com fRasterClip = &fRasterClipStorage; 2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 2430017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com fRasterClip = prev->fRasterClip; 2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFilter = prev->fFilter; 24782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeRef(fFilter); 2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTopLayer = prev->fTopLayer; 2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { // no prev 2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrixStorage.reset(); 2524b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = &fMatrixStorage; 2540017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com fRasterClip = &fRasterClipStorage; 2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFilter = NULL; 2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTopLayer = NULL; 2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLayer = NULL; 2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // don't bother initializing fNext 2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inc_rec(); 2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ~MCRec() { 26482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fFilter); 2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDELETE(fLayer); 2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dec_rec(); 2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2684b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 2700017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com SkMatrix fMatrixStorage; 2710017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com SkRasterClip fRasterClipStorage; 2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkDrawIter : public SkDraw { 2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 2768a0b0291ae4260ef2a46f4341c18a702c0ce3f8btomhudson@google.com SkDrawIter(SkCanvas* canvas, bool skipEmptyClips = true) { 2774370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com canvas = canvas->canvasForDrawIter(); 2788a0b0291ae4260ef2a46f4341c18a702c0ce3f8btomhudson@google.com fCanvas = canvas; 2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com canvas->updateDeviceCMCache(); 2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28190c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com fClipStack = &canvas->fClipStack; 2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBounder = canvas->getBounder(); 2838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = canvas->fMCRec->fTopLayer; 2848a0b0291ae4260ef2a46f4341c18a702c0ce3f8btomhudson@google.com fSkipEmptyClips = skipEmptyClips; 2858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2864b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool next() { 2888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // skip over recs with empty clips 2898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fSkipEmptyClips) { 2908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (fCurrLayer && fCurrLayer->fClip.isEmpty()) { 2918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = fCurrLayer->fNext; 2928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 295f68c5e2f9f05b3af2bae0979ace2684b6041b6e3reed@google.com const DeviceCM* rec = fCurrLayer; 296f68c5e2f9f05b3af2bae0979ace2684b6041b6e3reed@google.com if (rec && rec->fDevice) { 2978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = rec->fMatrix; 299045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com fClip = &((SkRasterClip*)&rec->fClip)->forceGetBW(); 300045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com fRC = &rec->fClip; 3018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDevice = rec->fDevice; 3028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBitmap = &fDevice->accessBitmap(true); 3038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint = rec->fPaint; 304f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com SkDEBUGCODE(this->validate();) 3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = rec->fNext; 3078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fBounder) { 3088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBounder->setClip(fClip); 3098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // fCurrLayer may be NULL now 311199f108f14a5f60a9c2205ffa79b26102a206ad0reed@android.com 3128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 3138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 3158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3164b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 3171f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* getDevice() const { return fDevice; } 3186f8f292aa768869a9e85c314b124875f57504f2creed@google.com int getX() const { return fDevice->getOrigin().x(); } 3196f8f292aa768869a9e85c314b124875f57504f2creed@google.com int getY() const { return fDevice->getOrigin().y(); } 3208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& getMatrix() const { return *fMatrix; } 3218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkRegion& getClip() const { return *fClip; } 3228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* getPaint() const { return fPaint; } 3236f8f292aa768869a9e85c314b124875f57504f2creed@google.com 3248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 3258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkCanvas* fCanvas; 3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const DeviceCM* fCurrLayer; 3278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* fPaint; // May be null. 3288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkBool8 fSkipEmptyClips; 3298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef SkDraw INHERITED; 3318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////// 3348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass AutoDrawLooper { 3368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 3378926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com AutoDrawLooper(SkCanvas* canvas, const SkPaint& paint, 33878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bool skipLayerForImageFilter = false, 33978cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL) : fOrigPaint(paint) { 3404e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fCanvas = canvas; 3418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFilter = canvas->getDrawFilter(); 3424e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fPaint = NULL; 3434e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fSaveCount = canvas->getSaveCount(); 3448926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com fDoClearImageFilter = false; 3454e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fDone = false; 3468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3478926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com if (!skipLayerForImageFilter && fOrigPaint.getImageFilter()) { 3488926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkPaint tmp; 3498926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com tmp.setImageFilter(fOrigPaint.getImageFilter()); 350e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org (void)canvas->internalSaveLayer(bounds, &tmp, SkCanvas::kARGB_ClipLayer_SaveFlag, 351e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org true, SkCanvas::kFullLayer_SaveLayerStrategy); 3528926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com // we'll clear the imageFilter for the actual draws in next(), so 3538926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com // it will only be applied during the restore(). 3548926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com fDoClearImageFilter = true; 3558926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 3568926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 35779fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (SkDrawLooper* looper = paint.getLooper()) { 35879fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org void* buffer = fLooperContextAllocator.reserveT<SkDrawLooper::Context>( 35979fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org looper->contextSize()); 36079fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org fLooperContext = looper->createContext(canvas, buffer); 361129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fIsSimple = false; 362129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else { 36379fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org fLooperContext = NULL; 364129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // can we be marked as simple? 365129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fIsSimple = !fFilter && !fDoClearImageFilter; 3668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 36874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 3694e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com ~AutoDrawLooper() { 3708926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com if (fDoClearImageFilter) { 3718926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com fCanvas->internalRestore(); 3728926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 3734e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkASSERT(fCanvas->getSaveCount() == fSaveCount); 3748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 37574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 3764e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com const SkPaint& paint() const { 3774e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkASSERT(fPaint); 3784e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return *fPaint; 3794e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 38074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 381129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool next(SkDrawFilter::Type drawType) { 382129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com if (fDone) { 383129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return false; 384129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else if (fIsSimple) { 385129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fDone = true; 386129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fPaint = &fOrigPaint; 387129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return !fPaint->nothingToDraw(); 388129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else { 389129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return this->doNext(drawType); 390129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 391fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 39274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 3938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 3942c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkLazyPaint fLazyPaint; 3952c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkCanvas* fCanvas; 3962c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint& fOrigPaint; 3972c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkDrawFilter* fFilter; 3982c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint* fPaint; 3992c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org int fSaveCount; 4008926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com bool fDoClearImageFilter; 4012c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org bool fDone; 402129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool fIsSimple; 40379fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkDrawLooper::Context* fLooperContext; 40479fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkSmallAllocator<1, 32> fLooperContextAllocator; 405129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com 406129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool doNext(SkDrawFilter::Type drawType); 4078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 4088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 409129ec22cb054592261e001294c430c9dd4e90ff4reed@google.combool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) { 410632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com fPaint = NULL; 411129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com SkASSERT(!fIsSimple); 41279fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkASSERT(fLooperContext || fFilter || fDoClearImageFilter); 413632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com 414129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com SkPaint* paint = fLazyPaint.set(fOrigPaint); 4158926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 416129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com if (fDoClearImageFilter) { 417129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com paint->setImageFilter(NULL); 418129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 4198926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 42079fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (fLooperContext && !fLooperContext->next(fCanvas, paint)) { 421129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fDone = true; 422129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return false; 423129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 424129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com if (fFilter) { 425971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com if (!fFilter->filter(paint, drawType)) { 426971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com fDone = true; 427971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com return false; 428971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com } 42979fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (NULL == fLooperContext) { 430129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // no looper means we only draw once 431632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com fDone = true; 432632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com } 433129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 434129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fPaint = paint; 4358926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 436129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // if we only came in here for the imagefilter, mark us as done 43779fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (!fLooperContext && !fFilter) { 4384e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fDone = true; 4394e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 4404e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com 441632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com // call this after any possible paint modifiers 442632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com if (fPaint->nothingToDraw()) { 4434e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fPaint = NULL; 4444e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return false; 4454e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 4464e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return true; 4474e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com} 4484e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com 4498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* Stack helper for managing a SkBounder. In the destructor, if we were 4508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com given a bounder, we call its commit() method, signifying that we are 4518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com done accumulating bounds for that draw. 4528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 4538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkAutoBounderCommit { 4548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 4558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAutoBounderCommit(SkBounder* bounder) : fBounder(bounder) {} 4568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ~SkAutoBounderCommit() { 4578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL != fBounder) { 4588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBounder->commit(); 4598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 4628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkBounder* fBounder; 4638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 464e61a86cfa00ea393ecc4a71fca94e1d476a37ecccommit-bot@chromium.org#define SkAutoBounderCommit(...) SK_REQUIRE_LOCAL_VAR(SkAutoBounderCommit) 4658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorPriv.h" 4678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////// macros to place around the internal draw calls ////////////////// 4698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4708926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com#define LOOPER_BEGIN_DRAWDEVICE(paint, type) \ 47197af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com this->predrawNotify(); \ 4728926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com AutoDrawLooper looper(this, paint, true); \ 4738926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com while (looper.next(type)) { \ 4748926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkAutoBounderCommit ac(fBounder); \ 4758926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkDrawIter iter(this); 4768926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 47778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org#define LOOPER_BEGIN(paint, type, bounds) \ 47897af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com this->predrawNotify(); \ 47978cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org AutoDrawLooper looper(this, paint, false, bounds); \ 4804e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com while (looper.next(type)) { \ 4818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAutoBounderCommit ac(fBounder); \ 4828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDrawIter iter(this); 4834b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 4844e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com#define LOOPER_END } 4858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////// 4878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4881f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::init(SkBaseDevice* device) { 4898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBounder = NULL; 490c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBounds.setEmpty(); 491c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 4928f0a7b8e7334187a5d7d5ab7fde5a3c3009555f5caryclark@google.com fAllowSoftClip = true; 49345a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com fAllowSimplifyClip = false; 494447bcfa8898ce10e7b6493ba9e3e23e08bd13f01agl@chromium.org fDeviceCMDirty = false; 495b0a7ace7cb2a7559bbc254a7c93698bc71bbd245junov@chromium.org fSaveLayerCount = 0; 496210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org fCullCount = 0; 49774bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org fMetaData = NULL; 4988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = (MCRec*)fMCStack.push_back(); 5008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com new (fMCRec) MCRec(NULL, 0); 5018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 50240a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com fMCRec->fLayer = SkNEW_ARGS(DeviceCM, (NULL, 0, 0, NULL, NULL)); 5038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fTopLayer = fMCRec->fLayer; 5048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 50597af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com fSurfaceBase = NULL; 506f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 507403f8d7a052269583175e945689824838e5e0ef4commit-bot@chromium.org return this->setRootDevice(device); 5088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 510cde92111d50a96b6d0f3e166fbac7c9bc6eca349reed@google.comSkCanvas::SkCanvas() 511e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 512e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org{ 5138d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org inc_canvas(); 514ba124485687130183643994f1b4b68d629fbbebaskia.committer@gmail.com 5158d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org this->init(NULL); 5168d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org} 5178d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org 518e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.orgSkCanvas::SkCanvas(int width, int height) 519e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 520e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org{ 521e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org inc_canvas(); 522ba124485687130183643994f1b4b68d629fbbebaskia.committer@gmail.com 523e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org SkBitmap bitmap; 524900ecf2f1579d42c9d2959831787af0346320f86reed@google.com bitmap.setConfig(SkImageInfo::MakeUnknown(width, height)); 525e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org this->init(SkNEW_ARGS(SkBitmapDevice, (bitmap)))->unref(); 526e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org} 527e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org 5281f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkCanvas::SkCanvas(SkBaseDevice* device) 529e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 530e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org{ 5318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inc_canvas(); 5328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->init(device); 5348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::SkCanvas(const SkBitmap& bitmap) 537e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 538e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org{ 5398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inc_canvas(); 5408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5411f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com this->init(SkNEW_ARGS(SkBitmapDevice, (bitmap)))->unref(); 5428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::~SkCanvas() { 5458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // free up the contents of our deque 5468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->restoreToCount(1); // restore everything but the last 547b0a7ace7cb2a7559bbc254a7c93698bc71bbd245junov@chromium.org SkASSERT(0 == fSaveLayerCount); 5487c2029367cea5479fa3b74fb0ca2b0297b42b709reed@google.com 5498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->internalRestore(); // restore the last, since we're going away 5508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5518d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org SkSafeUnref(fBounder); 55274bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org SkDELETE(fMetaData); 553b70ae310bbdaa1b26786773aabce5548c1f48563vandebo@chromium.org 5548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dec_canvas(); 5558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkBounder* SkCanvas::setBounder(SkBounder* bounder) { 5588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fBounder, bounder); 5598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return bounder; 5608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDrawFilter* SkCanvas::getDrawFilter() const { 5638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fMCRec->fFilter; 5648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDrawFilter* SkCanvas::setDrawFilter(SkDrawFilter* filter) { 5678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fMCRec->fFilter, filter); 5688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return filter; 5698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 57174bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.orgSkMetaData& SkCanvas::getMetaData() { 57274bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org // metadata users are rare, so we lazily allocate it. If that changes we 57374bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org // can decide to just make it a field in the device (rather than a ptr) 57474bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org if (NULL == fMetaData) { 57574bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org fMetaData = new SkMetaData; 57674bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org } 57774bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org return *fMetaData; 57874bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org} 57974bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org 5808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 5818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 582bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.orgvoid SkCanvas::flush() { 5831f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* device = this->getDevice(); 584bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org if (device) { 585bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org device->flush(); 586bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org } 587bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org} 588bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org 5894ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.comSkISize SkCanvas::getTopLayerSize() const { 5904ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com SkBaseDevice* d = this->getTopDevice(); 5914ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com return d ? SkISize::Make(d->width(), d->height()) : SkISize::Make(0, 0); 5924ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com} 5934ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com 5944ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.comSkIPoint SkCanvas::getTopLayerOrigin() const { 5954ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com SkBaseDevice* d = this->getTopDevice(); 5964ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com return d ? d->getOrigin() : SkIPoint::Make(0, 0); 5974ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com} 5984ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com 5994ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.comSkISize SkCanvas::getBaseLayerSize() const { 6001f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* d = this->getDevice(); 601210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com return d ? SkISize::Make(d->width(), d->height()) : SkISize::Make(0, 0); 602210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com} 603210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com 6041f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::getDevice() const { 6058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // return root device 606c029062a0312fb747fb6c2677983aba51795c580robertphillips@google.com MCRec* rec = (MCRec*) fMCStack.front(); 6078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(rec && rec->fLayer); 6088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return rec->fLayer->fDevice; 6098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6111f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::getTopDevice(bool updateMatrixClip) const { 6120b53d59a24f667350b4282f88470713902409030reed@google.com if (updateMatrixClip) { 6130b53d59a24f667350b4282f88470713902409030reed@google.com const_cast<SkCanvas*>(this)->updateDeviceCMCache(); 6140b53d59a24f667350b4282f88470713902409030reed@google.com } 6159266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com return fMCRec->fTopLayer->fDevice; 6169266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com} 6179266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com 618403f8d7a052269583175e945689824838e5e0ef4commit-bot@chromium.orgSkBaseDevice* SkCanvas::setRootDevice(SkBaseDevice* device) { 6198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // return root device 6204c09d5cd4b9e6f0be1352f62288efdedc1bc3de3reed@google.com SkDeque::F2BIter iter(fMCStack); 6214c09d5cd4b9e6f0be1352f62288efdedc1bc3de3reed@google.com MCRec* rec = (MCRec*)iter.next(); 6228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(rec && rec->fLayer); 6231f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* rootDevice = rec->fLayer->fDevice; 6248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (rootDevice == device) { 6268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return device; 6278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 6284b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 6298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (device) { 63040a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com device->onAttachToCanvas(this); 6318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 6328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (rootDevice) { 63340a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com rootDevice->onDetachFromCanvas(); 6348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 6358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(rec->fLayer->fDevice, device); 6378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rootDevice = device; 6388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 6404b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 6418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* Now we update our initial region to have the bounds of the new device, 6428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com and then intersect all of the clips in our stack with these bounds, 6438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com to ensure that we can't draw outside of the device's bounds (and trash 6448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memory). 6454b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 6468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com NOTE: this is only a partial-fix, since if the new device is larger than 6478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com the previous one, we don't know how to "enlarge" the clips in our stack, 6484b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com so drawing may be artificially restricted. Without keeping a history of 6498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com all calls to canvas->clipRect() and canvas->clipPath(), we can't exactly 6508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com reconstruct the correct clips, so this approximation will have to do. 6518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com The caller really needs to restore() back to the base if they want to 6528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com accurately take advantage of the new device bounds. 6538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 6548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 65542aea289cbf801997b653a906a37a7f7e948b645reed@google.com SkIRect bounds; 65642aea289cbf801997b653a906a37a7f7e948b645reed@google.com if (device) { 6578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bounds.set(0, 0, device->width(), device->height()); 65842aea289cbf801997b653a906a37a7f7e948b645reed@google.com } else { 65942aea289cbf801997b653a906a37a7f7e948b645reed@google.com bounds.setEmpty(); 6608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 66142aea289cbf801997b653a906a37a7f7e948b645reed@google.com // now jam our 1st clip to be bounds, and intersect the rest with that 66242aea289cbf801997b653a906a37a7f7e948b645reed@google.com rec->fRasterClip->setRect(bounds); 66342aea289cbf801997b653a906a37a7f7e948b645reed@google.com while ((rec = (MCRec*)iter.next()) != NULL) { 66442aea289cbf801997b653a906a37a7f7e948b645reed@google.com (void)rec->fRasterClip->op(bounds, SkRegion::kIntersect_Op); 66542aea289cbf801997b653a906a37a7f7e948b645reed@google.com } 66642aea289cbf801997b653a906a37a7f7e948b645reed@google.com 6678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return device; 6688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 670a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.orgbool SkCanvas::readPixels(SkBitmap* bitmap, int x, int y) { 671a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (kUnknown_SkColorType == bitmap->colorType() || bitmap->getTexture()) { 672a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 673a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 674a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 675a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bool weAllocated = false; 676a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (NULL == bitmap->pixelRef()) { 677a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!bitmap->allocPixels()) { 678a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 679a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 680a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org weAllocated = true; 681a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 682a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 683a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkBitmap bm(*bitmap); 684a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bm.lockPixels(); 685a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (bm.getPixels() && this->readPixels(bm.info(), bm.getPixels(), bm.rowBytes(), x, y)) { 686a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return true; 687a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 688a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 689a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (weAllocated) { 690a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bitmap->setPixelRef(NULL); 691a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 692a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 693a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org} 69451df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 695c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.combool SkCanvas::readPixels(const SkIRect& srcRect, SkBitmap* bitmap) { 696a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkIRect r = srcRect; 697a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 698a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!r.intersect(0, 0, size.width(), size.height())) { 699a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bitmap->reset(); 700ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com return false; 701ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com } 70274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 703a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!bitmap->allocN32Pixels(r.width(), r.height())) { 704a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org // bitmap will already be reset. 705a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 706a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 707a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!this->readPixels(bitmap->info(), bitmap->getPixels(), bitmap->rowBytes(), r.x(), r.y())) { 708a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bitmap->reset(); 709daba14b7d4fc96b915c45d82713b22729c0d0f37bsalomon@google.com return false; 710c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } 711a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return true; 712a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org} 713c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 714a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.orgbool SkCanvas::readPixels(const SkImageInfo& origInfo, void* dstP, size_t rowBytes, int x, int y) { 715a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org switch (origInfo.colorType()) { 716a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org case kUnknown_SkColorType: 717a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org case kIndex_8_SkColorType: 718a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 719a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org default: 720a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org break; 721a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 722a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (NULL == dstP || rowBytes < origInfo.minRowBytes()) { 723a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 724a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 725a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (0 == origInfo.width() || 0 == origInfo.height()) { 72651df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com return false; 72751df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com } 728a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 729a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkBaseDevice* device = this->getDevice(); 730a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!device) { 731a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 732a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 733a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 734a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 735a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkIRect srcR = SkIRect::MakeXYWH(x, y, origInfo.width(), origInfo.height()); 736a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!srcR.intersect(0, 0, size.width(), size.height())) { 737a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 738a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 739db0c8753775774aa3f67114491e26ac1be32f38eskia.committer@gmail.com 740a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkImageInfo info = origInfo; 741a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org // the intersect may have shrunk info's logical size 742a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org info.fWidth = srcR.width(); 743a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org info.fHeight = srcR.height(); 744db0c8753775774aa3f67114491e26ac1be32f38eskia.committer@gmail.com 745a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org // if x or y are negative, then we have to adjust pixels 746a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (x > 0) { 747a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org x = 0; 748a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 749a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (y > 0) { 750a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org y = 0; 751a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 752a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org // here x,y are either 0 or negative 753a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org dstP = ((char*)dstP - y * rowBytes - x * info.bytesPerPixel()); 754db0c8753775774aa3f67114491e26ac1be32f38eskia.committer@gmail.com 755a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org // The device can assert that the requested area is always contained in its bounds 756a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return device->readPixels(info, dstP, rowBytes, srcR.x(), srcR.y()); 75751df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com} 75851df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 7594cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgbool SkCanvas::writePixels(const SkBitmap& bitmap, int x, int y) { 7604cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (bitmap.getTexture()) { 7614cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 7624cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7634cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org SkBitmap bm(bitmap); 7644cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org bm.lockPixels(); 7654cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (bm.getPixels()) { 7664cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return this->writePixels(bm.info(), bm.getPixels(), bm.rowBytes(), x, y); 7674cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7684cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 7694cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org} 7704cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 7714cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgbool SkCanvas::writePixels(const SkImageInfo& origInfo, const void* pixels, size_t rowBytes, 7724cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org int x, int y) { 7734cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org switch (origInfo.colorType()) { 7744cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org case kUnknown_SkColorType: 7754cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org case kIndex_8_SkColorType: 7764cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 7774cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org default: 7784cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org break; 7794cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7804cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (NULL == pixels || rowBytes < origInfo.minRowBytes()) { 7814cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 7824cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7834cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 7844cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 7854cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org SkIRect target = SkIRect::MakeXYWH(x, y, origInfo.width(), origInfo.height()); 7864cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (!target.intersect(0, 0, size.width(), size.height())) { 7874cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 7884cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7894cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 7904cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org SkBaseDevice* device = this->getDevice(); 7914cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (!device) { 7924cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 7934cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7944cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 7954cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org SkImageInfo info = origInfo; 7964cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // the intersect may have shrunk info's logical size 7974cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org info.fWidth = target.width(); 7984cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org info.fHeight = target.height(); 7994cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 8004cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // if x or y are negative, then we have to adjust pixels 8014cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (x > 0) { 8024cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org x = 0; 8034cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 8044cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (y > 0) { 8054cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org y = 0; 8064cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 8074cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // here x,y are either 0 or negative 8084cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org pixels = ((const char*)pixels - y * rowBytes - x * info.bytesPerPixel()); 8094cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 8104cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // The device can assert that the requested area is always contained in its bounds 8114ef54f8d72420a521d4aae04ff5cd438810eca7fcommit-bot@chromium.org return device->writePixels(info, pixels, rowBytes, target.x(), target.y()); 8124cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org} 81351df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 8144370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comSkCanvas* SkCanvas::canvasForDrawIter() { 8154370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com return this; 8164370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 8174370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 8188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 8198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::updateDeviceCMCache() { 8218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fDeviceCMDirty) { 8228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& totalMatrix = this->getTotalMatrix(); 823045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com const SkRasterClip& totalClip = *fMCRec->fRasterClip; 8248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* layer = fMCRec->fTopLayer; 8254b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 8268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == layer->fNext) { // only one layer 82746799cd9f0bded51a189d77731b25af159ab4609reed@google.com layer->updateMC(totalMatrix, totalClip, fClipStack, NULL); 8288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 829045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com SkRasterClip clip(totalClip); 8308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 83146799cd9f0bded51a189d77731b25af159ab4609reed@google.com layer->updateMC(totalMatrix, clip, fClipStack, &clip); 8328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while ((layer = layer->fNext) != NULL); 8338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = false; 8358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 8398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::internalSave(SaveFlags flags) { 8418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int saveCount = this->getSaveCount(); // record this before the actual save 8424b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 8438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com MCRec* newTop = (MCRec*)fMCStack.push_back(); 8448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com new (newTop) MCRec(fMCRec, flags); // balanced in restore() 8454b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 8468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = newTop; 8474b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 8486c157640c27ee2ed6f9a484d21691b7b19dfecdecommit-bot@chromium.org if (SkCanvas::kClip_SaveFlag & flags) { 8496c157640c27ee2ed6f9a484d21691b7b19dfecdecommit-bot@chromium.org fClipStack.save(); 8506c157640c27ee2ed6f9a484d21691b7b19dfecdecommit-bot@chromium.org } 8515c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 8528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return saveCount; 8538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 855e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.orgvoid SkCanvas::willSave(SaveFlags) { 856e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org // Do nothing. Subclasses may do something. 857e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org} 858e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org 8598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::save(SaveFlags flags) { 860e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org this->willSave(flags); 8618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // call shared impl 8628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->internalSave(flags); 8638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic bool bounds_affects_clip(SkCanvas::SaveFlags flags) { 866b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG 8678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (flags & SkCanvas::kClipToLayer_SaveFlag) != 0; 868b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#else 869b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com return true; 870b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#endif 8718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 873a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.orgbool SkCanvas::clipRectBounds(const SkRect* bounds, SaveFlags flags, 874c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org SkIRect* intersection, const SkImageFilter* imageFilter) { 875bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect clipBounds; 876c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org SkRegion::Op op = SkRegion::kIntersect_Op; 877bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (!this->getClipDeviceBounds(&clipBounds)) { 878a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return false; 879f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 880c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org 881c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org if (imageFilter) { 882c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org imageFilter->filterBounds(clipBounds, *fMCRec->fMatrix, &clipBounds); 883c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org // Filters may grow the bounds beyond the device bounds. 884c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org op = SkRegion::kReplace_Op; 885c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org } 886bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect ir; 8878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL != bounds) { 8888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 8894b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 8908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->getTotalMatrix().mapRect(&r, *bounds); 8918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.roundOut(&ir); 8928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // early exit if the layer's bounds are clipped out 8938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!ir.intersect(clipBounds)) { 894bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (bounds_affects_clip(flags)) { 8950017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com fMCRec->fRasterClip->setEmpty(); 896bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 897a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return false; 8988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { // no user bounds, so just use the clip 9008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ir = clipBounds; 9018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 90389f077ced4918ded7e911bc5052b61c90ad57a9asenorblanco@chromium.org if (bounds_affects_clip(flags)) { 90489f077ced4918ded7e911bc5052b61c90ad57a9asenorblanco@chromium.org fClipStack.clipDevRect(ir, op); 90589f077ced4918ded7e911bc5052b61c90ad57a9asenorblanco@chromium.org // early exit if the clip is now empty 90689f077ced4918ded7e911bc5052b61c90ad57a9asenorblanco@chromium.org if (!fMCRec->fRasterClip->op(ir, op)) { 90789f077ced4918ded7e911bc5052b61c90ad57a9asenorblanco@chromium.org return false; 90889f077ced4918ded7e911bc5052b61c90ad57a9asenorblanco@chromium.org } 909a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org } 910a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 911a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org if (intersection) { 912a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org *intersection = ir; 913a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org } 914a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return true; 915a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org} 916a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 917e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.orgSkCanvas::SaveLayerStrategy SkCanvas::willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) { 918e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org 919e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org // Do nothing. Subclasses may do something. 920e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org return kFullLayer_SaveLayerStrategy; 921e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org} 922e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org 923a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.orgint SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint, 924a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org SaveFlags flags) { 925e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org // Overriding classes may return false to signal that we don't need to create a layer. 926e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org SaveLayerStrategy strategy = this->willSaveLayer(bounds, paint, flags); 927e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org return this->internalSaveLayer(bounds, paint, flags, false, strategy); 9288926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com} 9298926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 9302b290cec9825da11d8e09074727cfaac5eca6453commit-bot@chromium.orgstatic SkBaseDevice* create_compatible_device(SkCanvas* canvas, 9312b290cec9825da11d8e09074727cfaac5eca6453commit-bot@chromium.org const SkImageInfo& info) { 93276f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com SkBaseDevice* device = canvas->getDevice(); 93315a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org return device ? device->createCompatibleDevice(info) : NULL; 93476f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com} 93576f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com 936e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.orgint SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags, 937e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org bool justForImageFilter, SaveLayerStrategy strategy) { 938b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG 939b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com flags = (SaveFlags)(flags | kClipToLayer_SaveFlag); 940b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#endif 941b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com 942a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org // do this before we create the layer. We don't call the public save() since 943a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org // that would invoke a possibly overridden virtual 944a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org int count = this->internalSave(flags); 945a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 946a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org fDeviceCMDirty = true; 947a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 948a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org SkIRect ir; 949c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org if (!this->clipRectBounds(bounds, flags, &ir, paint ? paint->getImageFilter() : NULL)) { 9508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return count; 9518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 953e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy really care about 954e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org // the clipRectBounds() call above? 955e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org if (kNoLayer_SaveLayerStrategy == strategy) { 956e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org return count; 957e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org } 958e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org 959b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com // Kill the imagefilter if our device doesn't allow it 960b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com SkLazyPaint lazyP; 961b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com if (paint && paint->getImageFilter()) { 962b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com if (!this->getTopDevice()->allowImageFilter(paint->getImageFilter())) { 9638926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com if (justForImageFilter) { 9648926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com // early exit if the layer was just for the imageFilter 9658926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com return count; 9668926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 967b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com SkPaint* p = lazyP.set(*paint); 968b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com p->setImageFilter(NULL); 969b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com paint = p; 970b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com } 971b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com } 972b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com 97315a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org bool isOpaque = !SkToBool(flags & kHasAlphaLayer_SaveFlag); 97415a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org SkImageInfo info = SkImageInfo::MakeN32(ir.width(), ir.height(), 97515a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType); 9768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9771f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* device; 97876dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com if (paint && paint->getImageFilter()) { 9792b290cec9825da11d8e09074727cfaac5eca6453commit-bot@chromium.org device = create_compatible_device(this, info); 98076dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } else { 98115a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org device = this->createLayerDevice(info); 98276dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } 983e25c68402b38ac01dc1ae196ae8a5265b773c5f2bungeman@google.com if (NULL == device) { 984e25c68402b38ac01dc1ae196ae8a5265b773c5f2bungeman@google.com SkDebugf("Unable to create device for layer."); 985e25c68402b38ac01dc1ae196ae8a5265b773c5f2bungeman@google.com return count; 986e25c68402b38ac01dc1ae196ae8a5265b773c5f2bungeman@google.com } 987e97f0856a8044866b12527819d14cdfbcdfd96f2bsalomon@google.com 9886f8f292aa768869a9e85c314b124875f57504f2creed@google.com device->setOrigin(ir.fLeft, ir.fTop); 98940a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com DeviceCM* layer = SkNEW_ARGS(DeviceCM, (device, ir.fLeft, ir.fTop, paint, this)); 9908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device->unref(); 9918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com layer->fNext = fMCRec->fTopLayer; 9938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fLayer = layer; 9948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fTopLayer = layer; // this field is NOT an owner of layer 9958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 996b0a7ace7cb2a7559bbc254a7c93698bc71bbd245junov@chromium.org fSaveLayerCount += 1; 9978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return count; 9988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha, 10018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SaveFlags flags) { 10028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (0xFF == alpha) { 10038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->saveLayer(bounds, NULL, flags); 10048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 10058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint tmpPaint; 10068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com tmpPaint.setAlpha(alpha); 10078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->saveLayer(bounds, &tmpPaint, flags); 10088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1011e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.orgvoid SkCanvas::willRestore() { 1012e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org // Do nothing. Subclasses may do something. 1013e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org} 1014e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org 10158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::restore() { 10168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // check for underflow 10178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fMCStack.count() > 1) { 1018e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org this->willRestore(); 10198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->internalRestore(); 10208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::internalRestore() { 10248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fMCStack.count() != 0); 10258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1027c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 10288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10296c157640c27ee2ed6f9a484d21691b7b19dfecdecommit-bot@chromium.org if (SkCanvas::kClip_SaveFlag & fMCRec->fFlags) { 10306c157640c27ee2ed6f9a484d21691b7b19dfecdecommit-bot@chromium.org fClipStack.restore(); 10316c157640c27ee2ed6f9a484d21691b7b19dfecdecommit-bot@chromium.org } 10326c157640c27ee2ed6f9a484d21691b7b19dfecdecommit-bot@chromium.org 103388edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com // reserve our layer (if any) 10348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* layer = fMCRec->fLayer; // may be null 10358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now detach it from fMCRec so we can pop(). Gets freed after its drawn 10368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fLayer = NULL; 10378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now do the normal restore() 10398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->~MCRec(); // balanced in save() 10408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCStack.pop_back(); 10418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = (MCRec*)fMCStack.back(); 10428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* Time to draw the layer's offscreen. We can't call the public drawSprite, 10448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com since if we're being recorded, we don't want to record this (the 10458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com recorder will have already recorded the restore). 10468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 10478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL != layer) { 10488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (layer->fNext) { 10496f8f292aa768869a9e85c314b124875f57504f2creed@google.com const SkIPoint& origin = layer->fDevice->getOrigin(); 10508926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(), 10518926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com layer->fPaint); 10528926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com // reset this, since internalDrawDevice will have set it to true 10538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 10547c2029367cea5479fa3b74fb0ca2b0297b42b709reed@google.com 1055b0a7ace7cb2a7559bbc254a7c93698bc71bbd245junov@chromium.org SkASSERT(fSaveLayerCount > 0); 1056b0a7ace7cb2a7559bbc254a7c93698bc71bbd245junov@chromium.org fSaveLayerCount -= 1; 10578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDELETE(layer); 105988edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 10608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::getSaveCount() const { 10638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fMCStack.count(); 10648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::restoreToCount(int count) { 10678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // sanity check 10688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count < 1) { 10698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com count = 1; 10708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 107174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1072b9d1c6a3c43a2cbcbd612f4ec4aaf604a1fa6444reed@google.com int n = this->getSaveCount() - count; 1073b9d1c6a3c43a2cbcbd612f4ec4aaf604a1fa6444reed@google.com for (int i = 0; i < n; ++i) { 10748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->restore(); 10758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10787c2029367cea5479fa3b74fb0ca2b0297b42b709reed@google.combool SkCanvas::isDrawingToLayer() const { 1079b0a7ace7cb2a7559bbc254a7c93698bc71bbd245junov@chromium.org return fSaveLayerCount > 0; 10807c2029367cea5479fa3b74fb0ca2b0297b42b709reed@google.com} 10817c2029367cea5479fa3b74fb0ca2b0297b42b709reed@google.com 108276f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.comSkSurface* SkCanvas::newSurface(const SkImageInfo& info) { 108376f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com return this->onNewSurface(info); 108476f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com} 108576f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com 108676f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.comSkSurface* SkCanvas::onNewSurface(const SkImageInfo& info) { 108776f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com SkBaseDevice* dev = this->getDevice(); 108876f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com return dev ? dev->newSurface(info) : NULL; 108976f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com} 109076f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com 1091c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgSkImageInfo SkCanvas::imageInfo() const { 1092c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkBaseDevice* dev = this->getDevice(); 1093c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (dev) { 1094c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return dev->imageInfo(); 1095c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } else { 1096900ecf2f1579d42c9d2959831787af0346320f86reed@google.com return SkImageInfo::MakeUnknown(0, 0); 1097c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1098c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1099c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1100c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgconst void* SkCanvas::peekPixels(SkImageInfo* info, size_t* rowBytes) { 1101c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return this->onPeekPixels(info, rowBytes); 1102c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1103c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1104c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgconst void* SkCanvas::onPeekPixels(SkImageInfo* info, size_t* rowBytes) { 1105c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkBaseDevice* dev = this->getDevice(); 1106c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return dev ? dev->peekPixels(info, rowBytes) : NULL; 1107c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1108c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 11096b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.orgvoid* SkCanvas::accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin) { 11106b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org void* pixels = this->onAccessTopLayerPixels(info, rowBytes); 11116b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org if (pixels && origin) { 11126b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org *origin = this->getTopDevice(false)->getOrigin(); 11136b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org } 11146b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org return pixels; 11159c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 11169c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 11179c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.comvoid* SkCanvas::onAccessTopLayerPixels(SkImageInfo* info, size_t* rowBytes) { 11189c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com SkBaseDevice* dev = this->getTopDevice(); 11199c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com return dev ? dev->accessPixels(info, rowBytes) : NULL; 11209c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 11219c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1122c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgSkAutoROCanvasPixels::SkAutoROCanvasPixels(SkCanvas* canvas) { 1123c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org fAddr = canvas->peekPixels(&fInfo, &fRowBytes); 1124c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (NULL == fAddr) { 1125c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org fInfo = canvas->imageInfo(); 1126a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (kUnknown_SkColorType == fInfo.colorType() || !fBitmap.allocPixels(fInfo)) { 1127c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return; // failure, fAddr is NULL 1128c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1129c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (!canvas->readPixels(&fBitmap, 0, 0)) { 1130c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return; // failure, fAddr is NULL 1131c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1132c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org fAddr = fBitmap.getPixels(); 1133c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org fRowBytes = fBitmap.rowBytes(); 1134c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1135c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkASSERT(fAddr); // success 1136c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1137c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1138c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgbool SkAutoROCanvasPixels::asROBitmap(SkBitmap* bitmap) const { 1139c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (fAddr) { 1140c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return bitmap->installPixels(fInfo, const_cast<void*>(fAddr), fRowBytes, 1141c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org NULL, NULL); 1142c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } else { 1143c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org bitmap->reset(); 1144c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return false; 1145c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1146c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1147c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1148210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.orgvoid SkCanvas::onPushCull(const SkRect& cullRect) { 1149210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org // do nothing. Subclasses may do something 1150210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org} 1151210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org 1152210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.orgvoid SkCanvas::onPopCull() { 1153210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org // do nothing. Subclasses may do something 1154210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org} 1155210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org 11568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////// 1157520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org#ifdef SK_DEBUG 1158520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org// Ensure that cull rects are monotonically nested in device space. 1159520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.orgvoid SkCanvas::validateCull(const SkIRect& devCull) { 1160520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org if (fCullStack.isEmpty() 1161520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org || devCull.isEmpty() 1162520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org || fCullStack.top().contains(devCull)) { 1163520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org return; 1164520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org } 1165520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1166520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org SkDEBUGF(("Invalid cull: [%d %d %d %d] (previous cull: [%d %d %d %d])\n", 1167520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org devCull.x(), devCull.y(), devCull.right(), devCull.bottom(), 1168520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org fCullStack.top().x(), fCullStack.top().y(), 1169520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org fCullStack.top().right(), fCullStack.top().bottom())); 1170520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1171520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org#ifdef ASSERT_NESTED_CULLING 1172520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org SkDEBUGFAIL("Invalid cull."); 1173520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org#endif 1174520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org} 1175520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org#endif 1176520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1177520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.orgvoid SkCanvas::pushCull(const SkRect& cullRect) { 1178520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org ++fCullCount; 1179520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org this->onPushCull(cullRect); 1180520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1181520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org#ifdef SK_DEBUG 1182520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org // Map the cull rect into device space. 1183520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org SkRect mappedCull; 1184520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org this->getTotalMatrix().mapRect(&mappedCull, cullRect); 1185520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1186520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org // Take clipping into account. 1187520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org SkIRect devClip, devCull; 1188520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org mappedCull.roundOut(&devCull); 1189520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org this->getClipDeviceBounds(&devClip); 1190520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org if (!devCull.intersect(devClip)) { 1191520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org devCull.setEmpty(); 1192520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org } 1193520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1194520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org this->validateCull(devCull); 1195520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org fCullStack.push(devCull); // balanced in popCull 1196520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org#endif 1197520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org} 1198520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1199520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.orgvoid SkCanvas::popCull() { 1200520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org SkASSERT(fCullStack.count() == fCullCount); 1201520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1202520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org if (fCullCount > 0) { 1203520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org --fCullCount; 1204520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org this->onPopCull(); 1205520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1206520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org SkDEBUGCODE(fCullStack.pop()); 1207520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org } 1208520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org} 1209520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1210520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org///////////////////////////////////////////////////////////////////////////// 12118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12129bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.comvoid SkCanvas::internalDrawBitmap(const SkBitmap& bitmap, 12138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& matrix, const SkPaint* paint) { 121450b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org if (bitmap.drawsNothing()) { 12158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 12168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12182c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkLazyPaint lazy; 12198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == paint) { 12202c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org paint = lazy.init(); 12218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12229bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com 12239bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com SkDEBUGCODE(bitmap.validate();) 12249bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com CHECK_LOCKCOUNT_BALANCE(bitmap); 12259bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com 122678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 122778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 122878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (paint && paint->canComputeFastBounds()) { 122978cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bitmap.getBounds(&storage); 123078cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org matrix.mapRect(&storage); 123178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint->computeFastBounds(storage, &storage); 123278cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org } 123378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org 123478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) 12359bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com 12369bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com while (iter.next()) { 12379bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com iter.fDevice->drawBitmap(iter, bitmap, matrix, looper.paint()); 12389bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com } 12399bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com 12409bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com LOOPER_END 12418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12431f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comvoid SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, 12448926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com const SkPaint* paint) { 12458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint tmp; 12468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == paint) { 12478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com tmp.setDither(true); 12488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint = &tmp; 12498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12504b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 12518926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com LOOPER_BEGIN_DRAWDEVICE(*paint, SkDrawFilter::kBitmap_Type) 12528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 12531f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* dstDev = iter.fDevice; 125476dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com paint = &looper.paint(); 125576dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkImageFilter* filter = paint->getImageFilter(); 125676dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkIPoint pos = { x - iter.getX(), y - iter.getY() }; 12578926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com if (filter && !dstDev->canHandleImageFilter(filter)) { 12589c39744a00573b7133fc765b0a9d50a0ceace7b8senorblanco@chromium.org SkDeviceImageFilterProxy proxy(dstDev); 125976dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkBitmap dst; 12606776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org SkIPoint offset = SkIPoint::Make(0, 0); 1261b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com const SkBitmap& src = srcDev->accessBitmap(false); 1262fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org SkMatrix matrix = *iter.fMatrix; 1263d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org matrix.postTranslate(SkIntToScalar(-pos.x()), SkIntToScalar(-pos.y())); 12644cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org SkIRect clipBounds = SkIRect::MakeWH(srcDev->width(), srcDev->height()); 12651a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org SkImageFilter::Cache* cache = SkImageFilter::GetExternalCache(); 12661a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org SkAutoUnref aur(NULL); 12671a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org if (!cache) { 12681a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org cache = SkImageFilter::Cache::Create(); 12691a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org aur.reset(cache); 12701a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org } 1271f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org SkImageFilter::Context ctx(matrix, clipBounds, cache); 12724cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org if (filter->filterImage(&proxy, src, ctx, &dst, &offset)) { 12735efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com SkPaint tmpUnfiltered(*paint); 12745efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com tmpUnfiltered.setImageFilter(NULL); 12756776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org dstDev->drawSprite(iter, dst, pos.x() + offset.x(), pos.y() + offset.y(), 12766776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org tmpUnfiltered); 127776dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } 127876dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } else { 1279b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com dstDev->drawDevice(iter, srcDev, pos.x(), pos.y(), *paint); 128076dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } 12818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12824e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 12838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12858926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.comvoid SkCanvas::drawSprite(const SkBitmap& bitmap, int x, int y, 12868926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com const SkPaint* paint) { 128750b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org if (bitmap.drawsNothing()) { 12888926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com return; 12898926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 129050b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org SkDEBUGCODE(bitmap.validate();) 129150b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org CHECK_LOCKCOUNT_BALANCE(bitmap); 1292fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 12938926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkPaint tmp; 12948926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com if (NULL == paint) { 12958926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com paint = &tmp; 12968926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 1297fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 12988926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com LOOPER_BEGIN_DRAWDEVICE(*paint, SkDrawFilter::kBitmap_Type) 1299fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 13008926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com while (iter.next()) { 13018926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com paint = &looper.paint(); 13028926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkImageFilter* filter = paint->getImageFilter(); 13038926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkIPoint pos = { x - iter.getX(), y - iter.getY() }; 13048926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com if (filter && !iter.fDevice->canHandleImageFilter(filter)) { 13059c39744a00573b7133fc765b0a9d50a0ceace7b8senorblanco@chromium.org SkDeviceImageFilterProxy proxy(iter.fDevice); 13068926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkBitmap dst; 13076776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org SkIPoint offset = SkIPoint::Make(0, 0); 1308fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org SkMatrix matrix = *iter.fMatrix; 1309d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org matrix.postTranslate(SkIntToScalar(-pos.x()), SkIntToScalar(-pos.y())); 13104cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org SkIRect clipBounds = SkIRect::MakeWH(bitmap.width(), bitmap.height()); 13111a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org SkImageFilter::Cache* cache = SkImageFilter::GetExternalCache(); 13121a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org SkAutoUnref aur(NULL); 13131a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org if (!cache) { 13141a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org cache = SkImageFilter::Cache::Create(); 13151a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org aur.reset(cache); 13161a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org } 1317f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org SkImageFilter::Context ctx(matrix, clipBounds, cache); 13184cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org if (filter->filterImage(&proxy, bitmap, ctx, &dst, &offset)) { 13195efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com SkPaint tmpUnfiltered(*paint); 13205efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com tmpUnfiltered.setImageFilter(NULL); 13216776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org iter.fDevice->drawSprite(iter, dst, pos.x() + offset.x(), pos.y() + offset.y(), 13225efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com tmpUnfiltered); 13238926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 13248926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } else { 13258926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com iter.fDevice->drawSprite(iter, bitmap, pos.x(), pos.y(), *paint); 13268926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 13278926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 13288926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com LOOPER_END 13298926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com} 13308926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 13318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////// 133292362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::translate(SkScalar dx, SkScalar dy) { 1333d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1334d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setTranslate(dx, dy); 1335d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 13368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 133892362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::scale(SkScalar sx, SkScalar sy) { 1339d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1340d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setScale(sx, sy); 1341d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 13428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 134492362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::rotate(SkScalar degrees) { 1345d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1346d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setRotate(degrees); 1347d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 13488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 135092362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::skew(SkScalar sx, SkScalar sy) { 1351d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1352d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setSkew(sx, sy); 1353d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 135444c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org} 135544c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 135644c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.orgvoid SkCanvas::didConcat(const SkMatrix&) { 135744c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org // Do nothing. Subclasses may do something. 13588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 136092362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::concat(const SkMatrix& matrix) { 1361d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org if (matrix.isIdentity()) { 1362d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org return; 1363d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org } 1364d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org 13658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1366c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 136792362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.org fMCRec->fMatrix->preConcat(matrix); 136844c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 136944c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org this->didConcat(matrix); 137044c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org} 137144c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 137244c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.orgvoid SkCanvas::didSetMatrix(const SkMatrix&) { 137344c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org // Do nothing. Subclasses may do something. 13748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::setMatrix(const SkMatrix& matrix) { 13778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1378c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 13798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *fMCRec->fMatrix = matrix; 138044c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org this->didSetMatrix(matrix); 13818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::resetMatrix() { 13848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 13854b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 13868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.reset(); 13878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->setMatrix(matrix); 13888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 13918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1392759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { 13938f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 13948f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(rect, op, edgeStyle); 13958f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 13968f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 13978f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 1398da17f758442f16747af39f8fbaed9c097048519creed@google.com#ifdef SK_ENABLE_CLIP_QUICKREJECT 1399da17f758442f16747af39f8fbaed9c097048519creed@google.com if (SkRegion::kIntersect_Op == op) { 1400da17f758442f16747af39f8fbaed9c097048519creed@google.com if (fMCRec->fRasterClip->isEmpty()) { 1401da17f758442f16747af39f8fbaed9c097048519creed@google.com return false; 1402da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1403da17f758442f16747af39f8fbaed9c097048519creed@google.com 14043b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(rect)) { 1405da17f758442f16747af39f8fbaed9c097048519creed@google.com fDeviceCMDirty = true; 1406c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 1407da17f758442f16747af39f8fbaed9c097048519creed@google.com 1408da17f758442f16747af39f8fbaed9c097048519creed@google.com fClipStack.clipEmpty(); 1409da17f758442f16747af39f8fbaed9c097048519creed@google.com return fMCRec->fRasterClip->setEmpty(); 1410da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1411da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1412da17f758442f16747af39f8fbaed9c097048519creed@google.com#endif 1413da17f758442f16747af39f8fbaed9c097048519creed@google.com 14145c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com AutoValidateClip avc(this); 14155c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 14168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1417c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 14188f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!fAllowSoftClip) { 14198f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com edgeStyle = kHard_ClipEdgeStyle; 14208f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 14218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fMCRec->fMatrix->rectStaysRect()) { 1423123671901abfa595d09ca789b487c4bc7c1f7cbcrobertphillips@google.com // for these simpler matrices, we can stay a rect even after applying 142498de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // the matrix. This means we don't have to a) make a path, and b) tell 142598de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // the region code to scan-convert the path, only to discover that it 142698de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // is really just a rect. 14278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 14288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fMatrix->mapRect(&r, rect); 14308f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com fClipStack.clipDevRect(r, op, kSoft_ClipEdgeStyle == edgeStyle); 14318f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com fMCRec->fRasterClip->op(r, op, kSoft_ClipEdgeStyle == edgeStyle); 14328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 1433123671901abfa595d09ca789b487c4bc7c1f7cbcrobertphillips@google.com // since we're rotated or some such thing, we convert the rect to a path 143498de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // and clip against that, since it can handle any matrix. However, to 143598de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // avoid recursion in the case where we are subclassed (e.g. Pictures) 143698de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // we explicitly call "our" version of clipPath. 14378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath path; 14388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.addRect(rect); 14408f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->SkCanvas::onClipPath(path, op, edgeStyle); 14418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 14428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14448f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comstatic void clip_path_helper(const SkCanvas* canvas, SkRasterClip* currClip, 14458f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com const SkPath& devPath, SkRegion::Op op, bool doAA) { 1446759876a9223ef64f9d0db235d7a46750f8193cbcreed@google.com // base is used to limit the size (and therefore memory allocation) of the 1447759876a9223ef64f9d0db235d7a46750f8193cbcreed@google.com // region that results from scan converting devPath. 1448759876a9223ef64f9d0db235d7a46750f8193cbcreed@google.com SkRegion base; 1449759876a9223ef64f9d0db235d7a46750f8193cbcreed@google.com 1450819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com if (SkRegion::kIntersect_Op == op) { 1451759876a9223ef64f9d0db235d7a46750f8193cbcreed@google.com // since we are intersect, we can do better (tighter) with currRgn's 1452759876a9223ef64f9d0db235d7a46750f8193cbcreed@google.com // bounds, than just using the device. However, if currRgn is complex, 1453759876a9223ef64f9d0db235d7a46750f8193cbcreed@google.com // our region blitter may hork, so we do that case in two steps. 14540017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com if (currClip->isRect()) { 1455b446fc7f05d2e3f22d574187b433e02b0c781e1fcommit-bot@chromium.org // FIXME: we should also be able to do this when currClip->isBW(), 1456b446fc7f05d2e3f22d574187b433e02b0c781e1fcommit-bot@chromium.org // but relaxing the test above triggers GM asserts in 1457b446fc7f05d2e3f22d574187b433e02b0c781e1fcommit-bot@chromium.org // SkRgnBuilder::blitH(). We need to investigate what's going on. 14588f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com currClip->setPath(devPath, currClip->bwRgn(), doAA); 1459759876a9223ef64f9d0db235d7a46750f8193cbcreed@google.com } else { 14600017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com base.setRect(currClip->getBounds()); 14610017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com SkRasterClip clip; 14620017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com clip.setPath(devPath, base, doAA); 14638f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com currClip->op(clip, op); 1464759876a9223ef64f9d0db235d7a46750f8193cbcreed@google.com } 1465819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com } else { 14661f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com const SkBaseDevice* device = canvas->getDevice(); 1467ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com if (!device) { 14688f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com currClip->setEmpty(); 14698f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com return; 1470ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com } 1471ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com 1472a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org base.setRect(0, 0, device->width(), device->height()); 1473819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 1474819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com if (SkRegion::kReplace_Op == op) { 14758f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com currClip->setPath(devPath, base, doAA); 1476819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com } else { 14770017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com SkRasterClip clip; 14780017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com clip.setPath(devPath, base, doAA); 14798f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com currClip->op(clip, op); 1480819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com } 1481819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com } 1482819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com} 1483819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 1484759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) { 14858f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 14864ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (rrect.isRect()) { 14878f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(rrect.getBounds(), op, edgeStyle); 14888f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } else { 14898f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRRect(rrect, op, edgeStyle); 14904ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 14918f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 149214e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 14938f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 149414e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org SkRRect transformedRRect; 149514e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org if (rrect.transform(*fMCRec->fMatrix, &transformedRRect)) { 149614e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org AutoValidateClip avc(this); 149714e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 149814e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org fDeviceCMDirty = true; 149914e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org fCachedLocalClipBoundsDirty = true; 15008f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!fAllowSoftClip) { 15018f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com edgeStyle = kHard_ClipEdgeStyle; 15028f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 150314e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 15048f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com fClipStack.clipDevRRect(transformedRRect, op, kSoft_ClipEdgeStyle == edgeStyle); 150514e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 150614e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org SkPath devPath; 150714e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org devPath.addRRect(transformedRRect); 150814e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 15098f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com clip_path_helper(this, fMCRec->fRasterClip, devPath, op, kSoft_ClipEdgeStyle == edgeStyle); 15108f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com return; 151114e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org } 151214e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 151314e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org SkPath path; 151414e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org path.addRRect(rrect); 151514e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org // call the non-virtual version 15168f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->SkCanvas::onClipPath(path, op, edgeStyle); 15174ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 15184ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 1519759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { 15208f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 15218f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com SkRect r; 15228f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!path.isInverseFillType() && path.isRect(&r)) { 15238f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(r, op, edgeStyle); 15248f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } else { 15258f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipPath(path, op, edgeStyle); 15268f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 15278f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 15288f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 15298f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 1530da17f758442f16747af39f8fbaed9c097048519creed@google.com#ifdef SK_ENABLE_CLIP_QUICKREJECT 1531da17f758442f16747af39f8fbaed9c097048519creed@google.com if (SkRegion::kIntersect_Op == op && !path.isInverseFillType()) { 1532da17f758442f16747af39f8fbaed9c097048519creed@google.com if (fMCRec->fRasterClip->isEmpty()) { 1533da17f758442f16747af39f8fbaed9c097048519creed@google.com return false; 1534da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1535fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 15363b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(path.getBounds())) { 1537da17f758442f16747af39f8fbaed9c097048519creed@google.com fDeviceCMDirty = true; 1538c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 1539fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1540da17f758442f16747af39f8fbaed9c097048519creed@google.com fClipStack.clipEmpty(); 1541da17f758442f16747af39f8fbaed9c097048519creed@google.com return fMCRec->fRasterClip->setEmpty(); 1542da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1543da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1544da17f758442f16747af39f8fbaed9c097048519creed@google.com#endif 1545da17f758442f16747af39f8fbaed9c097048519creed@google.com 15465c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com AutoValidateClip avc(this); 15475c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 15488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1549c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 15508f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!fAllowSoftClip) { 15518f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com edgeStyle = kHard_ClipEdgeStyle; 15528f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 15538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 15548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath devPath; 15558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.transform(*fMCRec->fMatrix, &devPath); 15568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1557fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // Check if the transfomation, or the original path itself 1558fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // made us empty. Note this can also happen if we contained NaN 1559fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // values. computing the bounds detects this, and will set our 1560fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // bounds to empty if that is the case. (see SkRect::set(pts, count)) 1561fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com if (devPath.getBounds().isEmpty()) { 1562fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // resetting the path will remove any NaN or other wanky values 1563fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // that might upset our scan converter. 1564fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com devPath.reset(); 1565fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com } 1566fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com 15675c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // if we called path.swap() we could avoid a deep copy of this path 15688f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com fClipStack.clipDevPath(devPath, op, kSoft_ClipEdgeStyle == edgeStyle); 15695c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 157045a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com if (fAllowSimplifyClip) { 157145a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com devPath.reset(); 157245a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com devPath.setFillType(SkPath::kInverseEvenOdd_FillType); 157345a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com const SkClipStack* clipStack = getClipStack(); 157445a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com SkClipStack::Iter iter(*clipStack, SkClipStack::Iter::kBottom_IterStart); 157545a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com const SkClipStack::Element* element; 157645a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com while ((element = iter.next())) { 157745a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com SkClipStack::Element::Type type = element->getType(); 157845a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com if (type == SkClipStack::Element::kEmpty_Type) { 157945a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com continue; 158045a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com } 158145a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com SkPath operand; 1582e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org element->asPath(&operand); 158345a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com SkRegion::Op elementOp = element->getOp(); 158445a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com if (elementOp == SkRegion::kReplace_Op) { 158545a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com devPath = operand; 158645a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com } else { 158745a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com Op(devPath, operand, (SkPathOp) elementOp, &devPath); 158845a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com } 158996fd3440fa489f74f903f30487282af99deb2a4dcaryclark@google.com // if the prev and curr clips disagree about aa -vs- not, favor the aa request. 159096fd3440fa489f74f903f30487282af99deb2a4dcaryclark@google.com // perhaps we need an API change to avoid this sort of mixed-signals about 159196fd3440fa489f74f903f30487282af99deb2a4dcaryclark@google.com // clipping. 15928f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (element->isAA()) { 15938f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com edgeStyle = kSoft_ClipEdgeStyle; 15948f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 159545a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com } 159645a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com op = SkRegion::kReplace_Op; 159745a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com } 159845a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com 15998f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com clip_path_helper(this, fMCRec->fRasterClip, devPath, op, edgeStyle); 16008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1602759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::updateClipConservativelyUsingBounds(const SkRect& bounds, SkRegion::Op op, 1603ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org bool inverseFilled) { 1604ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // This is for updating the clip conservatively using only bounds 1605ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // information. 1606ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // Contract: 1607ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // The current clip must contain the true clip. The true 1608ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // clip is the clip that would have normally been computed 1609ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // by calls to clipPath and clipRRect 1610ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // Objective: 1611ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // Keep the current clip as small as possible without 1612ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // breaking the contract, using only clip bounding rectangles 1613ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // (for performance). 1614ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org 1615ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // N.B.: This *never* calls back through a virtual on canvas, so subclasses 1616ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // don't have to worry about getting caught in a loop. Thus anywhere 1617ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // we call a virtual method, we explicitly prefix it with 1618ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // SkCanvas:: to be sure to call the base-class. 1619a5d3e77420621c912383c3b22e542d9413d68278skia.committer@gmail.com 1620ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org if (inverseFilled) { 1621ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org switch (op) { 1622ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org case SkRegion::kIntersect_Op: 1623ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org case SkRegion::kDifference_Op: 1624ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // These ops can only shrink the current clip. So leaving 16258f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com // the clip unchanged conservatively respects the contract. 16268f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com break; 1627ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org case SkRegion::kUnion_Op: 1628ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org case SkRegion::kReplace_Op: 1629ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org case SkRegion::kReverseDifference_Op: 16308f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com case SkRegion::kXOR_Op: { 1631ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // These ops can grow the current clip up to the extents of 1632ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // the input clip, which is inverse filled, so we just set 1633ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // the current clip to the device bounds. 1634ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org SkRect deviceBounds; 1635ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org SkIRect deviceIBounds; 1636ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org this->getDevice()->getGlobalBounds(&deviceIBounds); 16374469938e92d779dff05e745559e67907bbf21e78reed@google.com deviceBounds = SkRect::Make(deviceIBounds); 1638091a594dbc4116ec2e54724432472bf37dae794acommit-bot@chromium.org 1639ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // set the clip in device space 1640091a594dbc4116ec2e54724432472bf37dae794acommit-bot@chromium.org SkMatrix savedMatrix = this->getTotalMatrix(); 1641ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org this->SkCanvas::setMatrix(SkMatrix::I()); 1642370a89980b2d38a6d01903b484bf404d6c48b496skia.committer@gmail.com this->SkCanvas::onClipRect(deviceBounds, SkRegion::kReplace_Op, 16438f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com kHard_ClipEdgeStyle); 1644091a594dbc4116ec2e54724432472bf37dae794acommit-bot@chromium.org this->setMatrix(savedMatrix); 16458f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com break; 16468f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 1647ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org default: 1648ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org SkASSERT(0); // unhandled op? 1649ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org } 1650ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org } else { 1651ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // Not inverse filled 1652ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org switch (op) { 1653ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org case SkRegion::kIntersect_Op: 1654ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org case SkRegion::kUnion_Op: 1655ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org case SkRegion::kReplace_Op: 16568f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->SkCanvas::onClipRect(bounds, op, kHard_ClipEdgeStyle); 16578f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com break; 1658ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org case SkRegion::kDifference_Op: 1659ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // Difference can only shrink the current clip. 1660ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // Leaving clip unchanged conservatively fullfills the contract. 16618f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com break; 1662ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org case SkRegion::kReverseDifference_Op: 1663ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // To reverse, we swap in the bounds with a replace op. 1664ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // As with difference, leave it unchanged. 16658f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->SkCanvas::onClipRect(bounds, SkRegion::kReplace_Op, kHard_ClipEdgeStyle); 16668f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com break; 1667ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org case SkRegion::kXOR_Op: 1668ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // Be conservative, based on (A XOR B) always included in (A union B), 1669ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // which is always included in (bounds(A) union bounds(B)) 16708f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->SkCanvas::onClipRect(bounds, SkRegion::kUnion_Op, kHard_ClipEdgeStyle); 16718f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com break; 1672ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org default: 1673ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org SkASSERT(0); // unhandled op? 1674ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org } 1675ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org } 1676ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org} 1677ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org 1678759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipRegion(const SkRegion& rgn, SkRegion::Op op) { 16798f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRegion(rgn, op); 16808f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 16818f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 16828f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipRegion(const SkRegion& rgn, SkRegion::Op op) { 16835c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com AutoValidateClip avc(this); 16845c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 16858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1686c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 16878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16885c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // todo: signal fClipStack that we have a region, and therefore (I guess) 16895c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // we have to ignore it, and use the region directly? 1690115d931d2fbd3a109a21b28c8a9c5099e6c49c54reed@google.com fClipStack.clipDevRect(rgn.getBounds(), op); 16915c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 16928f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com fMCRec->fRasterClip->op(rgn, op); 16938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1695819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com#ifdef SK_DEBUG 1696819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.comvoid SkCanvas::validateClip() const { 1697819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com // construct clipRgn from the clipstack 16981f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com const SkBaseDevice* device = this->getDevice(); 1699ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com if (!device) { 17005c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org SkASSERT(this->isClipEmpty()); 1701ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com return; 1702ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com } 1703ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com 1704819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com SkIRect ir; 1705819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com ir.set(0, 0, device->width(), device->height()); 17060017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com SkRasterClip tmpClip(ir); 1707819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 170880214e26c57c5fea954006400852e8999e201923robertphillips@google.com SkClipStack::B2TIter iter(fClipStack); 17098182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const SkClipStack::Element* element; 17108182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com while ((element = iter.next()) != NULL) { 17118182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com switch (element->getType()) { 17128182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kRect_Type: 17138182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com element->getRect().round(&ir); 17148182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com tmpClip.op(ir, element->getOp()); 17158182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 17168182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kEmpty_Type: 17178182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com tmpClip.setEmpty(); 17188182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 17199cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org default: { 17209cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org SkPath path; 17219cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org element->asPath(&path); 17228f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com clip_path_helper(this, &tmpClip, path, element->getOp(), element->isAA()); 17239cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org break; 17249cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org } 1725819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com } 1726819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com } 1727819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com} 1728819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com#endif 1729819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 173090c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.comvoid SkCanvas::replayClips(ClipVisitor* visitor) const { 173180214e26c57c5fea954006400852e8999e201923robertphillips@google.com SkClipStack::B2TIter iter(fClipStack); 17328182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const SkClipStack::Element* element; 17338182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com 17348182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com static const SkRect kEmpty = { 0, 0, 0, 0 }; 17358182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com while ((element = iter.next()) != NULL) { 17368182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com switch (element->getType()) { 17378182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kPath_Type: 17388182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com visitor->clipPath(element->getPath(), element->getOp(), element->isAA()); 17398182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 1740e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org case SkClipStack::Element::kRRect_Type: 1741e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org visitor->clipRRect(element->getRRect(), element->getOp(), element->isAA()); 1742e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org break; 17438182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kRect_Type: 17448182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com visitor->clipRect(element->getRect(), element->getOp(), element->isAA()); 17458182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 17468182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kEmpty_Type: 17478182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com visitor->clipRect(kEmpty, SkRegion::kIntersect_Op, false); 17488182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 174990c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com } 175090c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com } 175190c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com} 175290c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com 17535c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com/////////////////////////////////////////////////////////////////////////////// 17545c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 1755754de5f65b466f721d952a379194cc94de376f42reed@google.combool SkCanvas::isClipEmpty() const { 1756754de5f65b466f721d952a379194cc94de376f42reed@google.com return fMCRec->fRasterClip->isEmpty(); 1757754de5f65b466f721d952a379194cc94de376f42reed@google.com} 1758754de5f65b466f721d952a379194cc94de376f42reed@google.com 17595c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.orgbool SkCanvas::isClipRect() const { 17605c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org return fMCRec->fRasterClip->isRect(); 17615c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org} 17625c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org 17633b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::quickReject(const SkRect& rect) const { 1764116b2bcd2c4c4d4670c7b7e2ea597414713c37fbwjmaclean@chromium.org 17651607863b608b7db6c813228768ed5d72997bbc82reed@google.com if (!rect.isFinite()) 1766116b2bcd2c4c4d4670c7b7e2ea597414713c37fbwjmaclean@chromium.org return true; 1767116b2bcd2c4c4d4670c7b7e2ea597414713c37fbwjmaclean@chromium.org 17680017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com if (fMCRec->fRasterClip->isEmpty()) { 17698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 17708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 17718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17728d430185e08d2067584837a76b7193b803fee7a0tomhudson@google.com if (fMCRec->fMatrix->hasPerspective()) { 1773a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com SkRect dst; 1774a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com fMCRec->fMatrix->mapRect(&dst, rect); 1775a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com SkIRect idst; 1776a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com dst.roundOut(&idst); 17770017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com return !SkIRect::Intersects(idst, fMCRec->fRasterClip->getBounds()); 1778a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com } else { 1779c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com const SkRect& clipR = this->getLocalClipBounds(); 1780d252db03d9650013b545ef9781fe993c07f8f314reed@android.com 1781a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com // for speed, do the most likely reject compares first 1782c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com // TODO: should we use | instead, or compare all 4 at once? 1783c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com if (rect.fTop >= clipR.fBottom || rect.fBottom <= clipR.fTop) { 1784a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com return true; 1785a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com } 1786c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com if (rect.fLeft >= clipR.fRight || rect.fRight <= clipR.fLeft) { 1787a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com return true; 1788a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com } 1789a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com return false; 17908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 17918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17933b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::quickReject(const SkPath& path) const { 17943b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com return path.isEmpty() || this->quickReject(path.getBounds()); 17958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17973b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::getClipBounds(SkRect* bounds) const { 1798bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect ibounds; 17998f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!this->getClipDeviceBounds(&ibounds)) { 18008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 18018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1803d9c0f0b57affec7a472879c5919acac6637d926areed@android.com SkMatrix inverse; 1804d9c0f0b57affec7a472879c5919acac6637d926areed@android.com // if we can't invert the CTM, we can't return local clip bounds 1805d9c0f0b57affec7a472879c5919acac6637d926areed@android.com if (!fMCRec->fMatrix->invert(&inverse)) { 180672dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com if (bounds) { 180772dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com bounds->setEmpty(); 180872dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com } 1809d9c0f0b57affec7a472879c5919acac6637d926areed@android.com return false; 1810d9c0f0b57affec7a472879c5919acac6637d926areed@android.com } 1811d9c0f0b57affec7a472879c5919acac6637d926areed@android.com 18128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL != bounds) { 1813bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkRect r; 18143b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com // adjust it outwards in case we are antialiasing 18153b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com const int inset = 1; 1816fa4d5bd09f8f1a4a92b5ae0324800dd672760898reed@google.com 18178f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com r.iset(ibounds.fLeft - inset, ibounds.fTop - inset, 18188f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com ibounds.fRight + inset, ibounds.fBottom + inset); 18198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inverse.mapRect(bounds, r); 18208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 18228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1824bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.combool SkCanvas::getClipDeviceBounds(SkIRect* bounds) const { 18250017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com const SkRasterClip& clip = *fMCRec->fRasterClip; 1826bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (clip.isEmpty()) { 1827bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (bounds) { 1828bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com bounds->setEmpty(); 1829bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1830bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com return false; 1831bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1832bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com 1833bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (NULL != bounds) { 1834bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com *bounds = clip.getBounds(); 1835bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1836bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com return true; 1837bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com} 1838bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com 18398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkMatrix& SkCanvas::getTotalMatrix() const { 18408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return *fMCRec->fMatrix; 18418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18435c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org#ifdef SK_SUPPORT_LEGACY_GETCLIPTYPE 1844bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.comSkCanvas::ClipType SkCanvas::getClipType() const { 18458f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (fMCRec->fRasterClip->isEmpty()) { 18468f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com return kEmpty_ClipType; 18478f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 18488f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (fMCRec->fRasterClip->isRect()) { 18498f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com return kRect_ClipType; 18508f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 1851bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com return kComplex_ClipType; 1852bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com} 18535c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org#endif 1854bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com 18555c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org#ifdef SK_SUPPORT_LEGACY_GETTOTALCLIP 18568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkRegion& SkCanvas::getTotalClip() const { 18570017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com return fMCRec->fRasterClip->forceGetBW(); 18588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18595c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org#endif 18605c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org 18615c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.orgconst SkRegion& SkCanvas::internal_private_getTotalClip() const { 18625c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org return fMCRec->fRasterClip->forceGetBW(); 18635c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org} 18645c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org 18655c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.orgvoid SkCanvas::internal_private_getTotalClipAsPath(SkPath* path) const { 18665c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org path->reset(); 18675c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org 18685c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org const SkRegion& rgn = fMCRec->fRasterClip->forceGetBW(); 18695c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org if (rgn.isEmpty()) { 18705c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org return; 18715c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org } 18725c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org (void)rgn.getBoundaryPath(path); 18735c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org} 18748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18759c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.comGrRenderTarget* SkCanvas::internal_private_accessTopLayerRenderTarget() { 18769c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com SkBaseDevice* dev = this->getTopDevice(); 18779c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com return dev ? dev->accessRenderTarget() : NULL; 18789c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 18799c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 188015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.orgSkBaseDevice* SkCanvas::createLayerDevice(const SkImageInfo& info) { 18811f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* device = this->getTopDevice(); 188215a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org return device ? device->createCompatibleDeviceForSaveLayer(info) : NULL; 18838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1885644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.orgGrContext* SkCanvas::getGrContext() { 1886644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#if SK_SUPPORT_GPU 1887644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org SkBaseDevice* device = this->getTopDevice(); 1888644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org if (NULL != device) { 1889644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org GrRenderTarget* renderTarget = device->accessRenderTarget(); 1890644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org if (NULL != renderTarget) { 1891644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org return renderTarget->getContext(); 1892644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org } 1893644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org } 1894644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#endif 1895644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org 1896644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org return NULL; 1897644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org 1898644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org} 1899e97f0856a8044866b12527819d14cdfbcdfd96f2bsalomon@google.com 1900ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.orgvoid SkCanvas::drawDRRect(const SkRRect& outer, const SkRRect& inner, 1901ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkPaint& paint) { 1902ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (outer.isEmpty()) { 1903ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 1904ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 1905ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (inner.isEmpty()) { 1906ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->drawRRect(outer, paint); 1907ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 1908ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 1909ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 1910ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // We don't have this method (yet), but technically this is what we should 1911ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // be able to assert... 1912ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // SkASSERT(outer.contains(inner)); 1913ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // 1914ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // For now at least check for containment of bounds 1915ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org SkASSERT(outer.getBounds().contains(inner.getBounds())); 1916ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 1917ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->onDrawDRRect(outer, inner, paint); 1918ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org} 1919ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 19208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 19218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// These are the virtual drawing methods 19228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 19238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19242a98181f048c11f21f52fbd99f803f5fd6118261reed@google.comvoid SkCanvas::clear(SkColor color) { 19252a98181f048c11f21f52fbd99f803f5fd6118261reed@google.com SkDrawIter iter(this); 1926995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org this->predrawNotify(); 19272a98181f048c11f21f52fbd99f803f5fd6118261reed@google.com while (iter.next()) { 19282a98181f048c11f21f52fbd99f803f5fd6118261reed@google.com iter.fDevice->clear(color); 19292a98181f048c11f21f52fbd99f803f5fd6118261reed@google.com } 19302a98181f048c11f21f52fbd99f803f5fd6118261reed@google.com} 19312a98181f048c11f21f52fbd99f803f5fd6118261reed@google.com 193228361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.orgvoid SkCanvas::onDiscard() { 193328361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org if (NULL != fSurfaceBase) { 193428361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org fSurfaceBase->aboutToDraw(SkSurface::kDiscard_ContentChangeMode); 193528361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org } 193628361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org} 193728361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org 19388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPaint(const SkPaint& paint) { 1939fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->internalDrawPaint(paint); 1940fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com} 1941fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com 1942fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.comvoid SkCanvas::internalDrawPaint(const SkPaint& paint) { 194353783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org CHECK_SHADER_NOSETCONTEXT(paint); 194453783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org 194578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPaint_Type, NULL) 19468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 19484e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPaint(iter, looper.paint()); 19498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 19508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19514e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 19528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 19538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPoints(PointMode mode, size_t count, const SkPoint pts[], 19558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 19568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if ((long)count <= 0) { 19578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 19588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 19598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 196053783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org CHECK_SHADER_NOSETCONTEXT(paint); 196153783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org 196278cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect r, storage; 196378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 1964a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com if (paint.canComputeFastBounds()) { 1965a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com // special-case 2 points (common for drawing a single line) 1966a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com if (2 == count) { 1967a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com r.set(pts[0], pts[1]); 1968a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } else { 1969a8c7f7702fb4bbedb615031bc653c5cd161a038ecommit-bot@chromium.org r.set(pts, SkToInt(count)); 1970a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } 197178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint.computeFastStrokeBounds(r, &storage); 197278cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (this->quickReject(*bounds)) { 1973a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com return; 1974a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } 1975fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 1976a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com 19778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(pts != NULL); 19788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 197978cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPoint_Type, bounds) 19804b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 19818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 19824e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPoints(iter, mode, count, pts, looper.paint()); 19838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 19844b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 19854e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 19868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 19878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19887ce564cccb246ec56427085872b2e1458fe74bd1bsalomon@google.comvoid SkCanvas::drawRect(const SkRect& r, const SkPaint& paint) { 198953783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org CHECK_SHADER_NOSETCONTEXT(paint); 199053783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org 199178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 199278cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 19938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.canComputeFastBounds()) { 199478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint.computeFastBounds(r, &storage); 199578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (this->quickReject(*bounds)) { 19968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 19978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 19988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 19994b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 200078cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kRect_Type, bounds) 20018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 20034e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawRect(iter, r, looper.paint()); 20048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 20058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20064e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 20078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 20088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20094ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.comvoid SkCanvas::drawOval(const SkRect& oval, const SkPaint& paint) { 201053783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org CHECK_SHADER_NOSETCONTEXT(paint); 201153783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org 201278cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 201378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 20144ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (paint.canComputeFastBounds()) { 201578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint.computeFastBounds(oval, &storage); 201678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (this->quickReject(*bounds)) { 20174ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com return; 20184ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 20194ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 2020306ab9d5de38f2a547fd1d69aedbe69b5c6617ccskia.committer@gmail.com 202178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, bounds) 202246d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com 202346d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com while (iter.next()) { 202446d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com iter.fDevice->drawOval(iter, oval, looper.paint()); 202546d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com } 202646d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com 202746d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com LOOPER_END 20284ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 20294ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 20304ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.comvoid SkCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) { 203153783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org CHECK_SHADER_NOSETCONTEXT(paint); 203253783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org 203378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 203478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 20354ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (paint.canComputeFastBounds()) { 203678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint.computeFastBounds(rrect.getBounds(), &storage); 203778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (this->quickReject(*bounds)) { 20384ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com return; 20394ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 20404ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 20414ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 20424ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (rrect.isRect()) { 20434ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com // call the non-virtual version 20444ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->SkCanvas::drawRect(rrect.getBounds(), paint); 2045f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org return; 2046f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } else if (rrect.isOval()) { 20474ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com // call the non-virtual version 2048f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org this->SkCanvas::drawOval(rrect.getBounds(), paint); 2049f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org return; 20504ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 2051f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 205278cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) 2053f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 2054f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org while (iter.next()) { 2055f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org iter.fDevice->drawRRect(iter, rrect, looper.paint()); 2056f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } 2057f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 2058f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org LOOPER_END 20594ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 20604ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 2061ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.orgvoid SkCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, 2062ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkPaint& paint) { 206353783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org CHECK_SHADER_NOSETCONTEXT(paint); 206453783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org 2065ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org SkRect storage; 2066ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkRect* bounds = NULL; 2067ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (paint.canComputeFastBounds()) { 2068ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org bounds = &paint.computeFastBounds(outer.getBounds(), &storage); 2069ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (this->quickReject(*bounds)) { 2070ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 2071ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 2072ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 207325c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 2074ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) 207525c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 2076ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org while (iter.next()) { 2077ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org iter.fDevice->drawDRRect(iter, outer, inner, looper.paint()); 2078ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 207925c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 2080ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org LOOPER_END 2081ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org} 20824ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 20837ce564cccb246ec56427085872b2e1458fe74bd1bsalomon@google.comvoid SkCanvas::drawPath(const SkPath& path, const SkPaint& paint) { 208453783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org CHECK_SHADER_NOSETCONTEXT(paint); 208553783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org 20869364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com if (!path.isFinite()) { 20879364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com return; 20889364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com } 20899364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com 209078cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 209178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 2092fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com if (!path.isInverseFillType() && paint.canComputeFastBounds()) { 209378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect& pathBounds = path.getBounds(); 209478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint.computeFastBounds(pathBounds, &storage); 209578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (this->quickReject(*bounds)) { 20968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 20978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 20988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 20990b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org 21000b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org const SkRect& r = path.getBounds(); 21010b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org if (r.width() <= 0 && r.height() <= 0) { 2102fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com if (path.isInverseFillType()) { 2103fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->internalDrawPaint(paint); 2104fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 2105fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com return; 2106fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 21078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 210878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, bounds) 21098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 21114e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPath(iter, path, looper.paint()); 21128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 21138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21144e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 21158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 21168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y, 21188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* paint) { 21198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(bitmap.validate();) 21208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21213d60812865bb034851da777a91413ab584929887reed@google.com if (NULL == paint || paint->canComputeFastBounds()) { 21229efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com SkRect bounds = { 21239efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com x, y, 21249efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com x + SkIntToScalar(bitmap.width()), 21259efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com y + SkIntToScalar(bitmap.height()) 21269efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com }; 21279efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com if (paint) { 21289efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com (void)paint->computeFastBounds(bounds, &bounds); 21299efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com } 21303b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(bounds)) { 21318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 21328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 21338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 21344b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 21358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 21368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.setTranslate(x, y); 21379bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com this->internalDrawBitmap(bitmap, matrix, paint); 21388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 21398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21409987ec3791336bad6af5cbe513564786b2df55aareed@google.com// this one is non-virtual, so it can be called safely by other canvas apis 21417112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.comvoid SkCanvas::internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, 2142eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org const SkRect& dst, const SkPaint* paint, 2143eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org DrawBitmapRectFlags flags) { 214450b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org if (bitmap.drawsNothing() || dst.isEmpty()) { 21458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 21468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 214774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2148ea033606a06d05d2d42aa7118409fee798e53167reed@google.com CHECK_LOCKCOUNT_BALANCE(bitmap); 2149ea033606a06d05d2d42aa7118409fee798e53167reed@google.com 215078cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 215178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = &dst; 21523d60812865bb034851da777a91413ab584929887reed@google.com if (NULL == paint || paint->canComputeFastBounds()) { 21539efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com if (paint) { 21549efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com bounds = &paint->computeFastBounds(dst, &storage); 21559efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com } 21563b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(*bounds)) { 21573d60812865bb034851da777a91413ab584929887reed@google.com return; 21583d60812865bb034851da777a91413ab584929887reed@google.com } 21598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 21603d60812865bb034851da777a91413ab584929887reed@google.com 216133535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com SkLazyPaint lazy; 216233535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com if (NULL == paint) { 216333535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com paint = lazy.init(); 21648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 21657064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 216678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) 21677064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 216833535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com while (iter.next()) { 2169eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org iter.fDevice->drawBitmapRect(iter, bitmap, src, dst, looper.paint(), flags); 2170f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 21717064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 217233535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com LOOPER_END 21738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 21748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21757112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.comvoid SkCanvas::drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src, 2176eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org const SkRect& dst, const SkPaint* paint, 2177eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org DrawBitmapRectFlags flags) { 21789987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkDEBUGCODE(bitmap.validate();) 2179eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org this->internalDrawBitmapRect(bitmap, src, dst, paint, flags); 21809987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 21819987ec3791336bad6af5cbe513564786b2df55aareed@google.com 21828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& matrix, 21838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* paint) { 21848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(bitmap.validate();) 21859bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com this->internalDrawBitmap(bitmap, matrix, paint); 21868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 21878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21889987ec3791336bad6af5cbe513564786b2df55aareed@google.comvoid SkCanvas::internalDrawBitmapNine(const SkBitmap& bitmap, 21899987ec3791336bad6af5cbe513564786b2df55aareed@google.com const SkIRect& center, const SkRect& dst, 21909987ec3791336bad6af5cbe513564786b2df55aareed@google.com const SkPaint* paint) { 219150b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org if (bitmap.drawsNothing()) { 219250b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org return; 219350b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org } 21943d60812865bb034851da777a91413ab584929887reed@google.com if (NULL == paint || paint->canComputeFastBounds()) { 219560abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com SkRect storage; 219660abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com const SkRect* bounds = &dst; 219760abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com if (paint) { 219860abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com bounds = &paint->computeFastBounds(dst, &storage); 219960abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com } 22003b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(*bounds)) { 22013d60812865bb034851da777a91413ab584929887reed@google.com return; 22023d60812865bb034851da777a91413ab584929887reed@google.com } 22033d60812865bb034851da777a91413ab584929887reed@google.com } 22043d60812865bb034851da777a91413ab584929887reed@google.com 22059987ec3791336bad6af5cbe513564786b2df55aareed@google.com const int32_t w = bitmap.width(); 22069987ec3791336bad6af5cbe513564786b2df55aareed@google.com const int32_t h = bitmap.height(); 22079987ec3791336bad6af5cbe513564786b2df55aareed@google.com 22089987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkIRect c = center; 22099987ec3791336bad6af5cbe513564786b2df55aareed@google.com // pin center to the bounds of the bitmap 22109987ec3791336bad6af5cbe513564786b2df55aareed@google.com c.fLeft = SkMax32(0, center.fLeft); 22119987ec3791336bad6af5cbe513564786b2df55aareed@google.com c.fTop = SkMax32(0, center.fTop); 22129987ec3791336bad6af5cbe513564786b2df55aareed@google.com c.fRight = SkPin32(center.fRight, c.fLeft, w); 22139987ec3791336bad6af5cbe513564786b2df55aareed@google.com c.fBottom = SkPin32(center.fBottom, c.fTop, h); 22149987ec3791336bad6af5cbe513564786b2df55aareed@google.com 22157112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com const SkScalar srcX[4] = { 22167d474f8a84a74421bd8d119124daa64ec1710f76rmistry@google.com 0, SkIntToScalar(c.fLeft), SkIntToScalar(c.fRight), SkIntToScalar(w) 22177112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com }; 22187112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com const SkScalar srcY[4] = { 22197d474f8a84a74421bd8d119124daa64ec1710f76rmistry@google.com 0, SkIntToScalar(c.fTop), SkIntToScalar(c.fBottom), SkIntToScalar(h) 22207112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com }; 22219987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkScalar dstX[4] = { 22229987ec3791336bad6af5cbe513564786b2df55aareed@google.com dst.fLeft, dst.fLeft + SkIntToScalar(c.fLeft), 22239987ec3791336bad6af5cbe513564786b2df55aareed@google.com dst.fRight - SkIntToScalar(w - c.fRight), dst.fRight 22249987ec3791336bad6af5cbe513564786b2df55aareed@google.com }; 22259987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkScalar dstY[4] = { 22269987ec3791336bad6af5cbe513564786b2df55aareed@google.com dst.fTop, dst.fTop + SkIntToScalar(c.fTop), 22279987ec3791336bad6af5cbe513564786b2df55aareed@google.com dst.fBottom - SkIntToScalar(h - c.fBottom), dst.fBottom 22289987ec3791336bad6af5cbe513564786b2df55aareed@google.com }; 222974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 22309987ec3791336bad6af5cbe513564786b2df55aareed@google.com if (dstX[1] > dstX[2]) { 22319987ec3791336bad6af5cbe513564786b2df55aareed@google.com dstX[1] = dstX[0] + (dstX[3] - dstX[0]) * c.fLeft / (w - c.width()); 22329987ec3791336bad6af5cbe513564786b2df55aareed@google.com dstX[2] = dstX[1]; 22339987ec3791336bad6af5cbe513564786b2df55aareed@google.com } 223474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 22359987ec3791336bad6af5cbe513564786b2df55aareed@google.com if (dstY[1] > dstY[2]) { 22369987ec3791336bad6af5cbe513564786b2df55aareed@google.com dstY[1] = dstY[0] + (dstY[3] - dstY[0]) * c.fTop / (h - c.height()); 22379987ec3791336bad6af5cbe513564786b2df55aareed@google.com dstY[2] = dstY[1]; 22389987ec3791336bad6af5cbe513564786b2df55aareed@google.com } 223974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 22409987ec3791336bad6af5cbe513564786b2df55aareed@google.com for (int y = 0; y < 3; y++) { 22417112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com SkRect s, d; 22427112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com 22439987ec3791336bad6af5cbe513564786b2df55aareed@google.com s.fTop = srcY[y]; 22449987ec3791336bad6af5cbe513564786b2df55aareed@google.com s.fBottom = srcY[y+1]; 22459987ec3791336bad6af5cbe513564786b2df55aareed@google.com d.fTop = dstY[y]; 22469987ec3791336bad6af5cbe513564786b2df55aareed@google.com d.fBottom = dstY[y+1]; 22479987ec3791336bad6af5cbe513564786b2df55aareed@google.com for (int x = 0; x < 3; x++) { 22489987ec3791336bad6af5cbe513564786b2df55aareed@google.com s.fLeft = srcX[x]; 22499987ec3791336bad6af5cbe513564786b2df55aareed@google.com s.fRight = srcX[x+1]; 22509987ec3791336bad6af5cbe513564786b2df55aareed@google.com d.fLeft = dstX[x]; 22519987ec3791336bad6af5cbe513564786b2df55aareed@google.com d.fRight = dstX[x+1]; 2252eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org this->internalDrawBitmapRect(bitmap, &s, d, paint, 225331acc11977815402e4ef2681350f8559285bec97robertphillips@google.com kNone_DrawBitmapRectFlag); 22549987ec3791336bad6af5cbe513564786b2df55aareed@google.com } 22559987ec3791336bad6af5cbe513564786b2df55aareed@google.com } 22569987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 22579987ec3791336bad6af5cbe513564786b2df55aareed@google.com 22589987ec3791336bad6af5cbe513564786b2df55aareed@google.comvoid SkCanvas::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, 22599987ec3791336bad6af5cbe513564786b2df55aareed@google.com const SkRect& dst, const SkPaint* paint) { 22609987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkDEBUGCODE(bitmap.validate();) 22619987ec3791336bad6af5cbe513564786b2df55aareed@google.com 22629987ec3791336bad6af5cbe513564786b2df55aareed@google.com // Need a device entry-point, so gpu can use a mesh 22639987ec3791336bad6af5cbe513564786b2df55aareed@google.com this->internalDrawBitmapNine(bitmap, center, dst, paint); 22649987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 22659987ec3791336bad6af5cbe513564786b2df55aareed@google.com 2266f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.comclass SkDeviceFilteredPaint { 2267f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.compublic: 22681f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkDeviceFilteredPaint(SkBaseDevice* device, const SkPaint& paint) { 22691f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice::TextFlags flags; 2270f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com if (device->filterTextFlags(paint, &flags)) { 2271a076e9be17654a60310e72c4f70fcd5337f56dbfreed@google.com SkPaint* newPaint = fLazy.set(paint); 2272f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com newPaint->setFlags(flags.fFlags); 2273f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com newPaint->setHinting(flags.fHinting); 2274f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com fPaint = newPaint; 2275f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } else { 2276f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com fPaint = &paint; 2277f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } 2278f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } 2279f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 2280f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com const SkPaint& paint() const { return *fPaint; } 2281f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 2282f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.comprivate: 22832c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint* fPaint; 22842c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkLazyPaint fLazy; 2285f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com}; 2286f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 228752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.comvoid SkCanvas::DrawRect(const SkDraw& draw, const SkPaint& paint, 228852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com const SkRect& r, SkScalar textSize) { 228917b78946096265d80215a6c946286ecaa35ea7edepoger@google.com if (paint.getStyle() == SkPaint::kFill_Style) { 229052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com draw.fDevice->drawRect(draw, r, paint); 229152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } else { 229252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPaint p(paint); 229317b78946096265d80215a6c946286ecaa35ea7edepoger@google.com p.setStrokeWidth(SkScalarMul(textSize, paint.getStrokeWidth())); 229452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com draw.fDevice->drawRect(draw, r, p); 229552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 229652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com} 229752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 229852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.comvoid SkCanvas::DrawTextDecorations(const SkDraw& draw, const SkPaint& paint, 229952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com const char text[], size_t byteLength, 230052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar x, SkScalar y) { 230152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkASSERT(byteLength == 0 || text != NULL); 230252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 230352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com // nothing to draw 230452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (text == NULL || byteLength == 0 || 230552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com draw.fClip->isEmpty() || 230652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com (paint.getAlpha() == 0 && paint.getXfermode() == NULL)) { 230752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com return; 230852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 230952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 231052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar width = 0; 231152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPoint start; 231252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 231352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.set(0, 0); // to avoid warning 231452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (paint.getFlags() & (SkPaint::kUnderlineText_Flag | 231552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPaint::kStrikeThruText_Flag)) { 231652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com width = paint.measureText(text, byteLength); 231752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 231852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar offsetX = 0; 231952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (paint.getTextAlign() == SkPaint::kCenter_Align) { 232052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com offsetX = SkScalarHalf(width); 232152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } else if (paint.getTextAlign() == SkPaint::kRight_Align) { 232252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com offsetX = width; 232352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 232452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.set(x - offsetX, y); 232552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 232652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 232752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (0 == width) { 232852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com return; 232952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 233052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 233152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com uint32_t flags = paint.getFlags(); 233252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 233352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (flags & (SkPaint::kUnderlineText_Flag | 233452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPaint::kStrikeThruText_Flag)) { 233552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar textSize = paint.getTextSize(); 233652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar height = SkScalarMul(textSize, kStdUnderline_Thickness); 233752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkRect r; 233852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 233952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fLeft = start.fX; 234052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fRight = start.fX + width; 234152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 234252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (flags & SkPaint::kUnderlineText_Flag) { 234352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar offset = SkScalarMulAdd(textSize, kStdUnderline_Offset, 234452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.fY); 234552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fTop = offset; 234652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fBottom = offset + height; 234752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com DrawRect(draw, paint, r, textSize); 234852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 234952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (flags & SkPaint::kStrikeThruText_Flag) { 235052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar offset = SkScalarMulAdd(textSize, kStdStrikeThru_Offset, 235152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.fY); 235252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fTop = offset; 235352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fBottom = offset + height; 235452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com DrawRect(draw, paint, r, textSize); 235552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 235652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 235752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com} 235852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 23598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawText(const void* text, size_t byteLength, 23608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar x, SkScalar y, const SkPaint& paint) { 236153783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org CHECK_SHADER_NOSETCONTEXT(paint); 236253783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org 236378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL) 23648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 23664e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 2367f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com iter.fDevice->drawText(iter, text, byteLength, x, y, dfp.paint()); 236852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com DrawTextDecorations(iter, dfp.paint(), 236952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com static_cast<const char*>(text), byteLength, x, y); 23708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23724e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 23738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPosText(const void* text, size_t byteLength, 23768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPoint pos[], const SkPaint& paint) { 237753783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org CHECK_SHADER_NOSETCONTEXT(paint); 237853783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org 237978cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL) 23804b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 23818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 23824e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 23838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawPosText(iter, text, byteLength, &pos->fX, 0, 2, 2384f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com dfp.paint()); 23858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23864b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 23874e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 23888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPosTextH(const void* text, size_t byteLength, 23918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkScalar xpos[], SkScalar constY, 23928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 239353783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org CHECK_SHADER_NOSETCONTEXT(paint); 239453783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org 239578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL) 23964b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 23978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 23984e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 23998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawPosText(iter, text, byteLength, xpos, constY, 1, 2400f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com dfp.paint()); 24018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 24024b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 24034e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 24048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawTextOnPath(const void* text, size_t byteLength, 24078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPath& path, const SkMatrix* matrix, 24088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 240953783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org CHECK_SHADER_NOSETCONTEXT(paint); 241053783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org 241178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL) 24128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 24148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawTextOnPath(iter, text, byteLength, path, 24154e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com matrix, looper.paint()); 24168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 24178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24184e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 24198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawVertices(VertexMode vmode, int vertexCount, 24228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPoint verts[], const SkPoint texs[], 24238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkColor colors[], SkXfermode* xmode, 24248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint16_t indices[], int indexCount, 24258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 242653783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org CHECK_SHADER_NOSETCONTEXT(paint); 242753783b026a00683c1fb504127c3398dabb61ea73commit-bot@chromium.org 242878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, NULL) 24294b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 24308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 24318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawVertices(iter, vmode, vertexCount, verts, texs, 24324e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com colors, xmode, indices, indexCount, 24334e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com looper.paint()); 24348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 24354b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 24364e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 24378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 24408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// These methods are NOT virtual, and therefore must call back into virtual 24418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// methods, rather than actually drawing themselves. 24428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 24438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b, 2445845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com SkXfermode::Mode mode) { 24468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 24478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setARGB(a, r, g, b); 2449845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com if (SkXfermode::kSrcOver_Mode != mode) { 24500baf19375466cfc24c96532df406e7c5b1d1aae8reed@android.com paint.setXfermodeMode(mode); 24518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 24528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPaint(paint); 24538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2455845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.comvoid SkCanvas::drawColor(SkColor c, SkXfermode::Mode mode) { 24568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 24578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setColor(c); 2459845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com if (SkXfermode::kSrcOver_Mode != mode) { 24600baf19375466cfc24c96532df406e7c5b1d1aae8reed@android.com paint.setXfermodeMode(mode); 24618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 24628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPaint(paint); 24638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPoint(SkScalar x, SkScalar y, const SkPaint& paint) { 24668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pt; 24674b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 24688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pt.set(x, y); 24698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kPoints_PointMode, 1, &pt, paint); 24708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPoint(SkScalar x, SkScalar y, SkColor color) { 24738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pt; 24748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 24754b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 24768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pt.set(x, y); 24778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setColor(color); 24788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kPoints_PointMode, 1, &pt, paint); 24798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, 24828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 24838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pts[2]; 24844b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 24858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pts[0].set(x0, y0); 24868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pts[1].set(x1, y1); 24878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kLines_PointMode, 2, pts, paint); 24888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawRectCoords(SkScalar left, SkScalar top, 24918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar right, SkScalar bottom, 24928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 24938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 24948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.set(left, top, right, bottom); 24968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawRect(r, paint); 24978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, 25008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 25018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (radius < 0) { 25028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com radius = 0; 25038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 25048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 25068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.set(cx - radius, cy - radius, cx + radius, cy + radius); 25074ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->drawOval(r, paint); 25088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 25098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawRoundRect(const SkRect& r, SkScalar rx, SkScalar ry, 25118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 25128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (rx > 0 && ry > 0) { 25138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.canComputeFastBounds()) { 25148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect storage; 25153b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(paint.computeFastBounds(r, &storage))) { 25168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 25178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 25188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 25194ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com SkRRect rrect; 25204ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com rrect.setRectXY(r, rx, ry); 25214ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->drawRRect(rrect, paint); 25228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 25238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawRect(r, paint); 25248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 25258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 25268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawArc(const SkRect& oval, SkScalar startAngle, 25288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar sweepAngle, bool useCenter, 25298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 25308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (SkScalarAbs(sweepAngle) >= SkIntToScalar(360)) { 25318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawOval(oval, paint); 25328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 25338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath path; 25348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (useCenter) { 25358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.moveTo(oval.centerX(), oval.centerY()); 25368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 25378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.arcTo(oval, startAngle, sweepAngle, !useCenter); 25388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (useCenter) { 25398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.close(); 25408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 25418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPath(path, paint); 25428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 25438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 25448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawTextOnPathHV(const void* text, size_t byteLength, 25468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPath& path, SkScalar hOffset, 25478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar vOffset, const SkPaint& paint) { 25488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 25494b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 25508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.setTranslate(hOffset, vOffset); 25518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawTextOnPath(text, byteLength, path, &matrix, paint); 25528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 25538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2554f76bacff7f66724072c67edb185abf9e3add11a0reed@android.com/////////////////////////////////////////////////////////////////////////////// 2555145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.orgvoid SkCanvas::EXPERIMENTAL_optimize(SkPicture* picture) { 2556145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org SkBaseDevice* device = this->getDevice(); 2557145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org if (NULL != device) { 2558145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org device->EXPERIMENTAL_optimize(picture); 2559145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org } 2560145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org} 2561f76bacff7f66724072c67edb185abf9e3add11a0reed@android.com 2562c873329ae9ff00b0c45f7294172ad2e9b1ec44c8commit-bot@chromium.orgvoid SkCanvas::EXPERIMENTAL_purge(SkPicture* picture) { 2563c873329ae9ff00b0c45f7294172ad2e9b1ec44c8commit-bot@chromium.org SkBaseDevice* device = this->getTopDevice(); 2564c873329ae9ff00b0c45f7294172ad2e9b1ec44c8commit-bot@chromium.org if (NULL != device) { 2565c873329ae9ff00b0c45f7294172ad2e9b1ec44c8commit-bot@chromium.org device->EXPERIMENTAL_purge(picture); 2566c873329ae9ff00b0c45f7294172ad2e9b1ec44c8commit-bot@chromium.org } 2567c873329ae9ff00b0c45f7294172ad2e9b1ec44c8commit-bot@chromium.org} 2568c873329ae9ff00b0c45f7294172ad2e9b1ec44c8commit-bot@chromium.org 25698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPicture(SkPicture& picture) { 2570145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org SkBaseDevice* device = this->getTopDevice(); 2571145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org if (NULL != device) { 2572145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org // Canvas has to first give the device the opportunity to render 2573145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org // the picture itself. 2574c873329ae9ff00b0c45f7294172ad2e9b1ec44c8commit-bot@chromium.org if (device->EXPERIMENTAL_drawPicture(this, &picture)) { 2575145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org return; // the device has rendered the entire picture 2576145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org } 2577145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org } 2578145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org 25798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com picture.draw(this); 25808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 25818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 25838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 25848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::LayerIter::LayerIter(SkCanvas* canvas, bool skipEmptyClips) { 2586d642329293cce602ac24df8f585c14a98795da87reed@google.com SK_COMPILE_ASSERT(sizeof(fStorage) >= sizeof(SkDrawIter), fStorage_too_small); 25878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(canvas); 25898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fImpl = new (fStorage) SkDrawIter(canvas, skipEmptyClips); 25918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDone = !fImpl->next(); 25928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 25938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::LayerIter::~LayerIter() { 25958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fImpl->~SkDrawIter(); 25968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 25978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::LayerIter::next() { 25998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDone = !fImpl->next(); 26008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 26018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 26021f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::LayerIter::device() const { 26038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fImpl->getDevice(); 26048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 26058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 26068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkMatrix& SkCanvas::LayerIter::matrix() const { 26078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fImpl->getMatrix(); 26088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 26098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 26108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkPaint& SkCanvas::LayerIter::paint() const { 26118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* paint = fImpl->getPaint(); 26128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == paint) { 26138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint = &fDefaultPaint; 26148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 26158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return *paint; 26168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 26178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 26188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkRegion& SkCanvas::LayerIter::clip() const { return fImpl->getClip(); } 26198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::LayerIter::x() const { return fImpl->getX(); } 26208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::LayerIter::y() const { return fImpl->getY(); } 262120a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com 262220a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com/////////////////////////////////////////////////////////////////////////////// 262320a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com 262420a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.comSkCanvas::ClipVisitor::~ClipVisitor() { } 26253107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 26263107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 26273107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 26283107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.orgstatic bool supported_for_raster_canvas(const SkImageInfo& info) { 26293107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org switch (info.alphaType()) { 26303107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kPremul_SkAlphaType: 26313107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kOpaque_SkAlphaType: 26323107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org break; 26333107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org default: 26343107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return false; 26353107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 26363107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 26373107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org switch (info.colorType()) { 26383107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kAlpha_8_SkColorType: 26393107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kRGB_565_SkColorType: 264028fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org case kN32_SkColorType: 26413107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org break; 26423107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org default: 26433107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return false; 26443107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 26453107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 26463107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return true; 26473107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org} 26483107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 26493107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.orgSkCanvas* SkCanvas::NewRaster(const SkImageInfo& info) { 26503107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org if (!supported_for_raster_canvas(info)) { 26513107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return NULL; 26523107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 26533107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 26543107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org SkBitmap bitmap; 26553107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org if (!bitmap.allocPixels(info)) { 26563107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return NULL; 26573107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 26583107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 26593107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org // should this functionality be moved into allocPixels()? 26603107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org if (!bitmap.info().isOpaque()) { 26613107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org bitmap.eraseColor(0); 26623107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 26633107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return SkNEW_ARGS(SkCanvas, (bitmap)); 26643107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org} 266542b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org 266642b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.orgSkCanvas* SkCanvas::NewRasterDirect(const SkImageInfo& info, void* pixels, size_t rowBytes) { 266742b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org if (!supported_for_raster_canvas(info)) { 266842b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org return NULL; 266942b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org } 2670eb849e5fd10cbe00cbc31307ba97fd9efca0b41bskia.committer@gmail.com 267142b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org SkBitmap bitmap; 267242b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org if (!bitmap.installPixels(info, pixels, rowBytes)) { 267342b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org return NULL; 267442b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org } 2675eb849e5fd10cbe00cbc31307ba97fd9efca0b41bskia.committer@gmail.com 267642b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org // should this functionality be moved into allocPixels()? 267742b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org if (!bitmap.info().isOpaque()) { 267842b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org bitmap.eraseColor(0); 267942b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org } 268042b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org return SkNEW_ARGS(SkCanvas, (bitmap)); 268142b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org} 2682