18a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2008 The Android Open Source Project 38a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 68a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h" 101f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com#include "SkBitmapDevice.h" 119c39744a00573b7133fc765b0a9d50a0ceace7b8senorblanco@chromium.org#include "SkDeviceImageFilterProxy.h" 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDraw.h" 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDrawFilter.h" 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDrawLooper.h" 1574bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org#include "SkMetaData.h" 1645a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com#include "SkPathOps.h" 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPicture.h" 180017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com#include "SkRasterClip.h" 194ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com#include "SkRRect.h" 2079fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org#include "SkSmallAllocator.h" 2197af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com#include "SkSurface_Base.h" 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTemplates.h" 2352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com#include "SkTextFormatParams.h" 24a076e9be17654a60310e72c4f70fcd5337f56dbfreed@google.com#include "SkTLazy.h" 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkUtils.h" 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#if SK_SUPPORT_GPU 28644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#include "GrRenderTarget.h" 29644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#endif 30644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org 31da17f758442f16747af39f8fbaed9c097048519creed@google.com// experimental for faster tiled drawing... 32da17f758442f16747af39f8fbaed9c097048519creed@google.com//#define SK_ENABLE_CLIP_QUICKREJECT 3315e9d3e66e161ce23df30bc13f8a0c87d196b463robertphillips@google.com 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//#define SK_TRACE_SAVERESTORE 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_TRACE_SAVERESTORE 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gLayerCounter; 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_layer() { ++gLayerCounter; printf("----- inc layer %d\n", gLayerCounter); } 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_layer() { --gLayerCounter; printf("----- dec layer %d\n", gLayerCounter); } 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gRecCounter; 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_rec() { ++gRecCounter; printf("----- inc rec %d\n", gRecCounter); } 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_rec() { --gRecCounter; printf("----- dec rec %d\n", gRecCounter); } 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gCanvasCounter; 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_canvas() { ++gCanvasCounter; printf("----- inc canvas %d\n", gCanvasCounter); } 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_canvas() { --gCanvasCounter; printf("----- dec canvas %d\n", gCanvasCounter); } 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_layer() 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_layer() 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_rec() 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_rec() 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_canvas() 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_canvas() 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 57ea033606a06d05d2d42aa7118409fee798e53167reed@google.com#ifdef SK_DEBUG 58ea033606a06d05d2d42aa7118409fee798e53167reed@google.com#include "SkPixelRef.h" 59ea033606a06d05d2d42aa7118409fee798e53167reed@google.com 60f53d0a998b59f922c7e04c94310a83df76bbc400reed@google.com/* 61f53d0a998b59f922c7e04c94310a83df76bbc400reed@google.com * Some pixelref subclasses can support being "locked" from another thread 62f53d0a998b59f922c7e04c94310a83df76bbc400reed@google.com * during the lock-scope of skia calling them. In these instances, this balance 63f53d0a998b59f922c7e04c94310a83df76bbc400reed@google.com * check will fail, but may not be indicative of a problem, so we allow a build 64f53d0a998b59f922c7e04c94310a83df76bbc400reed@google.com * flag to disable this check. 65f53d0a998b59f922c7e04c94310a83df76bbc400reed@google.com * 66f53d0a998b59f922c7e04c94310a83df76bbc400reed@google.com * Potentially another fix would be to have a (debug-only) virtual or flag on 67f53d0a998b59f922c7e04c94310a83df76bbc400reed@google.com * pixelref, which could tell us at runtime if this check is valid. That would 68f53d0a998b59f922c7e04c94310a83df76bbc400reed@google.com * eliminate the need for this heavy-handed build check. 69f53d0a998b59f922c7e04c94310a83df76bbc400reed@google.com */ 70f53d0a998b59f922c7e04c94310a83df76bbc400reed@google.com#ifdef SK_DISABLE_PIXELREF_LOCKCOUNT_BALANCE_CHECK 71f53d0a998b59f922c7e04c94310a83df76bbc400reed@google.comclass AutoCheckLockCountBalance { 72f53d0a998b59f922c7e04c94310a83df76bbc400reed@google.compublic: 73f53d0a998b59f922c7e04c94310a83df76bbc400reed@google.com AutoCheckLockCountBalance(const SkBitmap&) { /* do nothing */ } 74f53d0a998b59f922c7e04c94310a83df76bbc400reed@google.com}; 75f53d0a998b59f922c7e04c94310a83df76bbc400reed@google.com#else 76ea033606a06d05d2d42aa7118409fee798e53167reed@google.comclass AutoCheckLockCountBalance { 77ea033606a06d05d2d42aa7118409fee798e53167reed@google.compublic: 78ea033606a06d05d2d42aa7118409fee798e53167reed@google.com AutoCheckLockCountBalance(const SkBitmap& bm) : fPixelRef(bm.pixelRef()) { 79ea033606a06d05d2d42aa7118409fee798e53167reed@google.com fLockCount = fPixelRef ? fPixelRef->getLockCount() : 0; 80ea033606a06d05d2d42aa7118409fee798e53167reed@google.com } 81ea033606a06d05d2d42aa7118409fee798e53167reed@google.com ~AutoCheckLockCountBalance() { 82ea033606a06d05d2d42aa7118409fee798e53167reed@google.com const int count = fPixelRef ? fPixelRef->getLockCount() : 0; 83ea033606a06d05d2d42aa7118409fee798e53167reed@google.com SkASSERT(count == fLockCount); 84ea033606a06d05d2d42aa7118409fee798e53167reed@google.com } 85ea033606a06d05d2d42aa7118409fee798e53167reed@google.com 86ea033606a06d05d2d42aa7118409fee798e53167reed@google.comprivate: 87ea033606a06d05d2d42aa7118409fee798e53167reed@google.com const SkPixelRef* fPixelRef; 88ea033606a06d05d2d42aa7118409fee798e53167reed@google.com int fLockCount; 89ea033606a06d05d2d42aa7118409fee798e53167reed@google.com}; 90f53d0a998b59f922c7e04c94310a83df76bbc400reed@google.com#endif 91ea033606a06d05d2d42aa7118409fee798e53167reed@google.com 92ea033606a06d05d2d42aa7118409fee798e53167reed@google.com#define CHECK_LOCKCOUNT_BALANCE(bitmap) AutoCheckLockCountBalance clcb(bitmap) 93ea033606a06d05d2d42aa7118409fee798e53167reed@google.com 94ea033606a06d05d2d42aa7118409fee798e53167reed@google.com#else 95ea033606a06d05d2d42aa7118409fee798e53167reed@google.com #define CHECK_LOCKCOUNT_BALANCE(bitmap) 96ea033606a06d05d2d42aa7118409fee798e53167reed@google.com#endif 97ea033606a06d05d2d42aa7118409fee798e53167reed@google.com 982c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.orgtypedef SkTLazy<SkPaint> SkLazyPaint; 992c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org 10097af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.comvoid SkCanvas::predrawNotify() { 10197af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com if (fSurfaceBase) { 102c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org fSurfaceBase->aboutToDraw(SkSurface::kRetain_ContentChangeMode); 10397af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com } 10497af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com} 10597af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com 1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1081f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com/* This is the record we keep for each SkBaseDevice that the user installs. 1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com The clip/matrix/proc are fields that reflect the top of the save/restore 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stack. Whenever the canvas changes, it marks a dirty flag, and then before 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com these are used (assuming we're not on a layer) we rebuild these cache 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com values: they reflect the top of the save stack, but translated and clipped 1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com by the device's XY offset and bitmap-bounds. 1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct DeviceCM { 1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* fNext; 1171f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* fDevice; 118045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com SkRasterClip fClip; 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix* fMatrix; 1206f8f292aa768869a9e85c314b124875f57504f2creed@google.com SkPaint* fPaint; // may be null (in the future) 1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1221f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com DeviceCM(SkBaseDevice* device, int x, int y, const SkPaint* paint, SkCanvas* canvas) 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com : fNext(NULL) { 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL != device) { 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device->ref(); 12640a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com device->onAttachToCanvas(canvas); 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1284b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com fDevice = device; 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint = paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL; 13088edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13288edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com ~DeviceCM() { 1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL != fDevice) { 13440a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com fDevice->onDetachFromCanvas(); 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDevice->unref(); 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13788edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com SkDELETE(fPaint); 13888edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 1394b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 140045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com void updateMC(const SkMatrix& totalMatrix, const SkRasterClip& totalClip, 141045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com const SkClipStack& clipStack, SkRasterClip* updateClip) { 1426f8f292aa768869a9e85c314b124875f57504f2creed@google.com int x = fDevice->getOrigin().x(); 1436f8f292aa768869a9e85c314b124875f57504f2creed@google.com int y = fDevice->getOrigin().y(); 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int width = fDevice->width(); 1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int height = fDevice->height(); 1464b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if ((x | y) == 0) { 1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = &totalMatrix; 1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fClip = totalClip; 1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrixStorage = totalMatrix; 1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrixStorage.postTranslate(SkIntToScalar(-x), 1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIntToScalar(-y)); 1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = &fMatrixStorage; 1554b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com totalClip.translate(-x, -y, &fClip); 1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 159045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com fClip.op(SkIRect::MakeWH(width, height), SkRegion::kIntersect_Op); 1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // intersect clip, but don't translate it (yet) 1624b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (updateClip) { 164045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com updateClip->op(SkIRect::MakeXYWH(x, y, width, height), 1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRegion::kDifference_Op); 1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1674b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 1683fffb2ee9fa01ae61efb2395973eb7575eda4c96robertphillips@google.com fDevice->setMatrixClip(*fMatrix, fClip.forceGetBW(), clipStack); 1693fffb2ee9fa01ae61efb2395973eb7575eda4c96robertphillips@google.com 1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!fClip.isEmpty()) { 1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIRect deviceR; 1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com deviceR.set(0, 0, width, height); 1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(deviceR.contains(fClip.getBounds())); 1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 177f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 178f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 1800e354aacd84d3bede3f97cbde35a54ba62a89533bsalomon@google.com SkMatrix fMatrixStorage; 1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* This is the record we keep for each save/restore level in the stack. 1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Since a level optionally copies the matrix and/or stack, we have pointers 1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for these fields. If the value is copied for this level, the copy is 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stored in the ...Storage field, and the pointer points to that. If the 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value is not copied for this level, we ignore ...Storage, and just point 1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com at the corresponding value in the previous level in the stack. 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkCanvas::MCRec { 1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 1926c157640c27ee2ed6f9a484d21691b7b19dfecdecommit-bot@chromium.org int fFlags; 1930017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com SkMatrix* fMatrix; // points to either fMatrixStorage or prev MCRec 1940017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com SkRasterClip* fRasterClip; // points to either fRegionStorage or prev MCRec 1950017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com SkDrawFilter* fFilter; // the current filter (or null) 1964b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* fLayer; 1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* If there are any layers in the stack, this points to the top-most 1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com one that is at or below this level in the stack (so we know what 2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bitmap/device to draw into from this level. This value is NOT 2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com reference counted, since the real owner is either our fLayer field, 2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com or a previous one in a lower level.) 2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 20488edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com DeviceCM* fTopLayer; 2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2066c157640c27ee2ed6f9a484d21691b7b19dfecdecommit-bot@chromium.org MCRec(const MCRec* prev, int flags) : fFlags(flags) { 2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL != prev) { 2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (flags & SkCanvas::kMatrix_SaveFlag) { 2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrixStorage = *prev->fMatrix; 2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = &fMatrixStorage; 2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = prev->fMatrix; 2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2144b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (flags & SkCanvas::kClip_SaveFlag) { 2160017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com fRasterClipStorage = *prev->fRasterClip; 2170017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com fRasterClip = &fRasterClipStorage; 2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 2190017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com fRasterClip = prev->fRasterClip; 2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFilter = prev->fFilter; 22382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeRef(fFilter); 2248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTopLayer = prev->fTopLayer; 2268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { // no prev 2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrixStorage.reset(); 2284b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = &fMatrixStorage; 2300017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com fRasterClip = &fRasterClipStorage; 2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFilter = NULL; 2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTopLayer = NULL; 2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLayer = NULL; 2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // don't bother initializing fNext 2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inc_rec(); 2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ~MCRec() { 24082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fFilter); 2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDELETE(fLayer); 2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dec_rec(); 2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2444b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 2460017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com SkMatrix fMatrixStorage; 2470017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com SkRasterClip fRasterClipStorage; 2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkDrawIter : public SkDraw { 2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 2528a0b0291ae4260ef2a46f4341c18a702c0ce3f8btomhudson@google.com SkDrawIter(SkCanvas* canvas, bool skipEmptyClips = true) { 2534370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com canvas = canvas->canvasForDrawIter(); 2548a0b0291ae4260ef2a46f4341c18a702c0ce3f8btomhudson@google.com fCanvas = canvas; 2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com canvas->updateDeviceCMCache(); 2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25790c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com fClipStack = &canvas->fClipStack; 2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = canvas->fMCRec->fTopLayer; 2598a0b0291ae4260ef2a46f4341c18a702c0ce3f8btomhudson@google.com fSkipEmptyClips = skipEmptyClips; 2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2614b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool next() { 2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // skip over recs with empty clips 2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fSkipEmptyClips) { 2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (fCurrLayer && fCurrLayer->fClip.isEmpty()) { 2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = fCurrLayer->fNext; 2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 270f68c5e2f9f05b3af2bae0979ace2684b6041b6e3reed@google.com const DeviceCM* rec = fCurrLayer; 271f68c5e2f9f05b3af2bae0979ace2684b6041b6e3reed@google.com if (rec && rec->fDevice) { 2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = rec->fMatrix; 274045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com fClip = &((SkRasterClip*)&rec->fClip)->forceGetBW(); 275045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com fRC = &rec->fClip; 2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDevice = rec->fDevice; 2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBitmap = &fDevice->accessBitmap(true); 2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint = rec->fPaint; 279f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com SkDEBUGCODE(this->validate();) 2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = rec->fNext; 2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // fCurrLayer may be NULL now 283199f108f14a5f60a9c2205ffa79b26102a206ad0reed@android.com 2848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 2858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 2878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2884b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2891f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* getDevice() const { return fDevice; } 2906f8f292aa768869a9e85c314b124875f57504f2creed@google.com int getX() const { return fDevice->getOrigin().x(); } 2916f8f292aa768869a9e85c314b124875f57504f2creed@google.com int getY() const { return fDevice->getOrigin().y(); } 2928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& getMatrix() const { return *fMatrix; } 2938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkRegion& getClip() const { return *fClip; } 2948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* getPaint() const { return fPaint; } 2956f8f292aa768869a9e85c314b124875f57504f2creed@google.com 2968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 2978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkCanvas* fCanvas; 2988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const DeviceCM* fCurrLayer; 2998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* fPaint; // May be null. 3008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkBool8 fSkipEmptyClips; 3018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef SkDraw INHERITED; 3038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////// 3068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass AutoDrawLooper { 3088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 3098926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com AutoDrawLooper(SkCanvas* canvas, const SkPaint& paint, 31078cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bool skipLayerForImageFilter = false, 31178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL) : fOrigPaint(paint) { 3124e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fCanvas = canvas; 3138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFilter = canvas->getDrawFilter(); 3144e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fPaint = NULL; 3154e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fSaveCount = canvas->getSaveCount(); 3168926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com fDoClearImageFilter = false; 3174e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fDone = false; 3188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3198926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com if (!skipLayerForImageFilter && fOrigPaint.getImageFilter()) { 3208926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkPaint tmp; 3218926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com tmp.setImageFilter(fOrigPaint.getImageFilter()); 322e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org (void)canvas->internalSaveLayer(bounds, &tmp, SkCanvas::kARGB_ClipLayer_SaveFlag, 323e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org true, SkCanvas::kFullLayer_SaveLayerStrategy); 3248926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com // we'll clear the imageFilter for the actual draws in next(), so 3258926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com // it will only be applied during the restore(). 3268926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com fDoClearImageFilter = true; 3278926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 3288926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 32979fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (SkDrawLooper* looper = paint.getLooper()) { 33079fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org void* buffer = fLooperContextAllocator.reserveT<SkDrawLooper::Context>( 33179fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org looper->contextSize()); 33279fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org fLooperContext = looper->createContext(canvas, buffer); 333129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fIsSimple = false; 334129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else { 33579fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org fLooperContext = NULL; 336129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // can we be marked as simple? 337129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fIsSimple = !fFilter && !fDoClearImageFilter; 3388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 34074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 3414e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com ~AutoDrawLooper() { 3428926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com if (fDoClearImageFilter) { 3438926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com fCanvas->internalRestore(); 3448926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 3454e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkASSERT(fCanvas->getSaveCount() == fSaveCount); 3468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 34774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 3484e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com const SkPaint& paint() const { 3494e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkASSERT(fPaint); 3504e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return *fPaint; 3514e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 35274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 353129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool next(SkDrawFilter::Type drawType) { 354129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com if (fDone) { 355129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return false; 356129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else if (fIsSimple) { 357129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fDone = true; 358129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fPaint = &fOrigPaint; 359129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return !fPaint->nothingToDraw(); 360129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else { 361129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return this->doNext(drawType); 362129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 363fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 36474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 3658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 3662c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkLazyPaint fLazyPaint; 3672c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkCanvas* fCanvas; 3682c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint& fOrigPaint; 3692c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkDrawFilter* fFilter; 3702c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint* fPaint; 3712c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org int fSaveCount; 3728926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com bool fDoClearImageFilter; 3732c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org bool fDone; 374129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool fIsSimple; 37579fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkDrawLooper::Context* fLooperContext; 37679fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkSmallAllocator<1, 32> fLooperContextAllocator; 377129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com 378129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool doNext(SkDrawFilter::Type drawType); 3798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 381129ec22cb054592261e001294c430c9dd4e90ff4reed@google.combool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) { 382632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com fPaint = NULL; 383129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com SkASSERT(!fIsSimple); 38479fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkASSERT(fLooperContext || fFilter || fDoClearImageFilter); 385632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com 386129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com SkPaint* paint = fLazyPaint.set(fOrigPaint); 3878926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 388129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com if (fDoClearImageFilter) { 389129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com paint->setImageFilter(NULL); 390129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 3918926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 39279fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (fLooperContext && !fLooperContext->next(fCanvas, paint)) { 393129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fDone = true; 394129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return false; 395129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 396129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com if (fFilter) { 397971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com if (!fFilter->filter(paint, drawType)) { 398971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com fDone = true; 399971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com return false; 400971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com } 40179fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (NULL == fLooperContext) { 402129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // no looper means we only draw once 403632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com fDone = true; 404632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com } 405129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 406129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fPaint = paint; 4078926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 408129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // if we only came in here for the imagefilter, mark us as done 40979fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (!fLooperContext && !fFilter) { 4104e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fDone = true; 4114e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 4124e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com 413632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com // call this after any possible paint modifiers 414632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com if (fPaint->nothingToDraw()) { 4154e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fPaint = NULL; 4164e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return false; 4174e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 4184e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return true; 4194e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com} 4204e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com 4218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorPriv.h" 4228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////// macros to place around the internal draw calls ////////////////// 4248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4258926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com#define LOOPER_BEGIN_DRAWDEVICE(paint, type) \ 42697af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com this->predrawNotify(); \ 4278926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com AutoDrawLooper looper(this, paint, true); \ 4288926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com while (looper.next(type)) { \ 4298926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkDrawIter iter(this); 4308926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 43178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org#define LOOPER_BEGIN(paint, type, bounds) \ 43297af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com this->predrawNotify(); \ 43378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org AutoDrawLooper looper(this, paint, false, bounds); \ 4344e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com while (looper.next(type)) { \ 4358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDrawIter iter(this); 4364b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 4374e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com#define LOOPER_END } 4388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////// 4408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4411f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::init(SkBaseDevice* device) { 442c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBounds.setEmpty(); 443c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 4448f0a7b8e7334187a5d7d5ab7fde5a3c3009555f5caryclark@google.com fAllowSoftClip = true; 44545a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com fAllowSimplifyClip = false; 446447bcfa8898ce10e7b6493ba9e3e23e08bd13f01agl@chromium.org fDeviceCMDirty = false; 447b0a7ace7cb2a7559bbc254a7c93698bc71bbd245junov@chromium.org fSaveLayerCount = 0; 448210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org fCullCount = 0; 44974bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org fMetaData = NULL; 4508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = (MCRec*)fMCStack.push_back(); 4528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com new (fMCRec) MCRec(NULL, 0); 4538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 45440a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com fMCRec->fLayer = SkNEW_ARGS(DeviceCM, (NULL, 0, 0, NULL, NULL)); 4558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fTopLayer = fMCRec->fLayer; 4568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 45797af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com fSurfaceBase = NULL; 458f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 459403f8d7a052269583175e945689824838e5e0ef4commit-bot@chromium.org return this->setRootDevice(device); 4608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 462cde92111d50a96b6d0f3e166fbac7c9bc6eca349reed@google.comSkCanvas::SkCanvas() 463e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 464e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org{ 4658d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org inc_canvas(); 466ba124485687130183643994f1b4b68d629fbbebaskia.committer@gmail.com 4678d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org this->init(NULL); 4688d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org} 4698d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org 470e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.orgSkCanvas::SkCanvas(int width, int height) 471e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 472e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org{ 473e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org inc_canvas(); 474ba124485687130183643994f1b4b68d629fbbebaskia.committer@gmail.com 475e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org SkBitmap bitmap; 476a3264e53ee3f3c5d6a2c813df7e44b5b96d207f2commit-bot@chromium.org bitmap.setInfo(SkImageInfo::MakeUnknown(width, height)); 477e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org this->init(SkNEW_ARGS(SkBitmapDevice, (bitmap)))->unref(); 478e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org} 479e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org 4801f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkCanvas::SkCanvas(SkBaseDevice* device) 481e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 482e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org{ 4838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inc_canvas(); 4848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->init(device); 4868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::SkCanvas(const SkBitmap& bitmap) 489e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 490e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org{ 4918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inc_canvas(); 4928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4931f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com this->init(SkNEW_ARGS(SkBitmapDevice, (bitmap)))->unref(); 4948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::~SkCanvas() { 4978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // free up the contents of our deque 4988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->restoreToCount(1); // restore everything but the last 499b0a7ace7cb2a7559bbc254a7c93698bc71bbd245junov@chromium.org SkASSERT(0 == fSaveLayerCount); 5007c2029367cea5479fa3b74fb0ca2b0297b42b709reed@google.com 5018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->internalRestore(); // restore the last, since we're going away 5028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 50374bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org SkDELETE(fMetaData); 504b70ae310bbdaa1b26786773aabce5548c1f48563vandebo@chromium.org 5058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dec_canvas(); 5068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDrawFilter* SkCanvas::getDrawFilter() const { 5098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fMCRec->fFilter; 5108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDrawFilter* SkCanvas::setDrawFilter(SkDrawFilter* filter) { 5138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fMCRec->fFilter, filter); 5148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return filter; 5158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 51774bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.orgSkMetaData& SkCanvas::getMetaData() { 51874bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org // metadata users are rare, so we lazily allocate it. If that changes we 51974bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org // can decide to just make it a field in the device (rather than a ptr) 52074bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org if (NULL == fMetaData) { 52174bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org fMetaData = new SkMetaData; 52274bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org } 52374bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org return *fMetaData; 52474bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org} 52574bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org 5268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 5278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 528bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.orgvoid SkCanvas::flush() { 5291f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* device = this->getDevice(); 530bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org if (device) { 531bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org device->flush(); 532bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org } 533bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org} 534bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org 5354ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.comSkISize SkCanvas::getTopLayerSize() const { 5364ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com SkBaseDevice* d = this->getTopDevice(); 5374ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com return d ? SkISize::Make(d->width(), d->height()) : SkISize::Make(0, 0); 5384ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com} 5394ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com 5404ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.comSkIPoint SkCanvas::getTopLayerOrigin() const { 5414ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com SkBaseDevice* d = this->getTopDevice(); 5424ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com return d ? d->getOrigin() : SkIPoint::Make(0, 0); 5434ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com} 5444ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com 5454ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.comSkISize SkCanvas::getBaseLayerSize() const { 5461f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* d = this->getDevice(); 547210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com return d ? SkISize::Make(d->width(), d->height()) : SkISize::Make(0, 0); 548210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com} 549210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com 5501f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::getDevice() const { 5518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // return root device 552c029062a0312fb747fb6c2677983aba51795c580robertphillips@google.com MCRec* rec = (MCRec*) fMCStack.front(); 5538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(rec && rec->fLayer); 5548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return rec->fLayer->fDevice; 5558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5571f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::getTopDevice(bool updateMatrixClip) const { 5580b53d59a24f667350b4282f88470713902409030reed@google.com if (updateMatrixClip) { 5590b53d59a24f667350b4282f88470713902409030reed@google.com const_cast<SkCanvas*>(this)->updateDeviceCMCache(); 5600b53d59a24f667350b4282f88470713902409030reed@google.com } 5619266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com return fMCRec->fTopLayer->fDevice; 5629266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com} 5639266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com 564403f8d7a052269583175e945689824838e5e0ef4commit-bot@chromium.orgSkBaseDevice* SkCanvas::setRootDevice(SkBaseDevice* device) { 5658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // return root device 5664c09d5cd4b9e6f0be1352f62288efdedc1bc3de3reed@google.com SkDeque::F2BIter iter(fMCStack); 5674c09d5cd4b9e6f0be1352f62288efdedc1bc3de3reed@google.com MCRec* rec = (MCRec*)iter.next(); 5688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(rec && rec->fLayer); 5691f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* rootDevice = rec->fLayer->fDevice; 5708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (rootDevice == device) { 5728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return device; 5738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5744b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 5758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (device) { 57640a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com device->onAttachToCanvas(this); 5778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (rootDevice) { 57940a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com rootDevice->onDetachFromCanvas(); 5808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(rec->fLayer->fDevice, device); 5838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rootDevice = device; 5848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 5864b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 5878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* Now we update our initial region to have the bounds of the new device, 5888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com and then intersect all of the clips in our stack with these bounds, 5898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com to ensure that we can't draw outside of the device's bounds (and trash 5908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memory). 5914b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 5928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com NOTE: this is only a partial-fix, since if the new device is larger than 5938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com the previous one, we don't know how to "enlarge" the clips in our stack, 5944b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com so drawing may be artificially restricted. Without keeping a history of 5958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com all calls to canvas->clipRect() and canvas->clipPath(), we can't exactly 5968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com reconstruct the correct clips, so this approximation will have to do. 5978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com The caller really needs to restore() back to the base if they want to 5988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com accurately take advantage of the new device bounds. 5998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 6008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 60142aea289cbf801997b653a906a37a7f7e948b645reed@google.com SkIRect bounds; 60242aea289cbf801997b653a906a37a7f7e948b645reed@google.com if (device) { 6038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bounds.set(0, 0, device->width(), device->height()); 60442aea289cbf801997b653a906a37a7f7e948b645reed@google.com } else { 60542aea289cbf801997b653a906a37a7f7e948b645reed@google.com bounds.setEmpty(); 6068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 60742aea289cbf801997b653a906a37a7f7e948b645reed@google.com // now jam our 1st clip to be bounds, and intersect the rest with that 60842aea289cbf801997b653a906a37a7f7e948b645reed@google.com rec->fRasterClip->setRect(bounds); 60942aea289cbf801997b653a906a37a7f7e948b645reed@google.com while ((rec = (MCRec*)iter.next()) != NULL) { 61042aea289cbf801997b653a906a37a7f7e948b645reed@google.com (void)rec->fRasterClip->op(bounds, SkRegion::kIntersect_Op); 61142aea289cbf801997b653a906a37a7f7e948b645reed@google.com } 61242aea289cbf801997b653a906a37a7f7e948b645reed@google.com 6138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return device; 6148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 616a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.orgbool SkCanvas::readPixels(SkBitmap* bitmap, int x, int y) { 617a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (kUnknown_SkColorType == bitmap->colorType() || bitmap->getTexture()) { 618a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 619a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 620a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 621a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bool weAllocated = false; 622a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (NULL == bitmap->pixelRef()) { 623a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!bitmap->allocPixels()) { 624a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 625a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 626a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org weAllocated = true; 627a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 628a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 629a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkBitmap bm(*bitmap); 630a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bm.lockPixels(); 631a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (bm.getPixels() && this->readPixels(bm.info(), bm.getPixels(), bm.rowBytes(), x, y)) { 632a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return true; 633a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 634a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 635a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (weAllocated) { 636a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bitmap->setPixelRef(NULL); 637a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 638a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 639a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org} 64051df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 641c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.combool SkCanvas::readPixels(const SkIRect& srcRect, SkBitmap* bitmap) { 642a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkIRect r = srcRect; 643a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 644a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!r.intersect(0, 0, size.width(), size.height())) { 645a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bitmap->reset(); 646ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com return false; 647ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com } 64874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 649a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!bitmap->allocN32Pixels(r.width(), r.height())) { 650a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org // bitmap will already be reset. 651a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 652a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 653a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!this->readPixels(bitmap->info(), bitmap->getPixels(), bitmap->rowBytes(), r.x(), r.y())) { 654a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bitmap->reset(); 655daba14b7d4fc96b915c45d82713b22729c0d0f37bsalomon@google.com return false; 656c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } 657a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return true; 658a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org} 659c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 660a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.orgbool SkCanvas::readPixels(const SkImageInfo& origInfo, void* dstP, size_t rowBytes, int x, int y) { 661a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org switch (origInfo.colorType()) { 662a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org case kUnknown_SkColorType: 663a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org case kIndex_8_SkColorType: 664a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 665a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org default: 666a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org break; 667a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 668a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (NULL == dstP || rowBytes < origInfo.minRowBytes()) { 669a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 670a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 671a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (0 == origInfo.width() || 0 == origInfo.height()) { 67251df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com return false; 67351df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com } 674a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 675a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkBaseDevice* device = this->getDevice(); 676a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!device) { 677a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 678a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 679a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 680a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 681a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkIRect srcR = SkIRect::MakeXYWH(x, y, origInfo.width(), origInfo.height()); 682a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!srcR.intersect(0, 0, size.width(), size.height())) { 683a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 684a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 685db0c8753775774aa3f67114491e26ac1be32f38eskia.committer@gmail.com 686a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkImageInfo info = origInfo; 687a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org // the intersect may have shrunk info's logical size 688a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org info.fWidth = srcR.width(); 689a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org info.fHeight = srcR.height(); 690db0c8753775774aa3f67114491e26ac1be32f38eskia.committer@gmail.com 691a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org // if x or y are negative, then we have to adjust pixels 692a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (x > 0) { 693a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org x = 0; 694a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 695a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (y > 0) { 696a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org y = 0; 697a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 698a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org // here x,y are either 0 or negative 699a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org dstP = ((char*)dstP - y * rowBytes - x * info.bytesPerPixel()); 700db0c8753775774aa3f67114491e26ac1be32f38eskia.committer@gmail.com 701a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org // The device can assert that the requested area is always contained in its bounds 702a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return device->readPixels(info, dstP, rowBytes, srcR.x(), srcR.y()); 70351df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com} 70451df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 7054cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgbool SkCanvas::writePixels(const SkBitmap& bitmap, int x, int y) { 7064cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (bitmap.getTexture()) { 7074cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 7084cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7094cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org SkBitmap bm(bitmap); 7104cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org bm.lockPixels(); 7114cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (bm.getPixels()) { 7124cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return this->writePixels(bm.info(), bm.getPixels(), bm.rowBytes(), x, y); 7134cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7144cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 7154cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org} 7164cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 7174cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgbool SkCanvas::writePixels(const SkImageInfo& origInfo, const void* pixels, size_t rowBytes, 7184cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org int x, int y) { 7194cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org switch (origInfo.colorType()) { 7204cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org case kUnknown_SkColorType: 7214cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org case kIndex_8_SkColorType: 7224cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 7234cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org default: 7244cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org break; 7254cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7264cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (NULL == pixels || rowBytes < origInfo.minRowBytes()) { 7274cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 7284cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7294cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 7304cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 7314cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org SkIRect target = SkIRect::MakeXYWH(x, y, origInfo.width(), origInfo.height()); 7324cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (!target.intersect(0, 0, size.width(), size.height())) { 7334cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 7344cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7354cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 7364cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org SkBaseDevice* device = this->getDevice(); 7374cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (!device) { 7384cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 7394cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7404cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 7414cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org SkImageInfo info = origInfo; 7424cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // the intersect may have shrunk info's logical size 7434cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org info.fWidth = target.width(); 7444cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org info.fHeight = target.height(); 7454cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 7464cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // if x or y are negative, then we have to adjust pixels 7474cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (x > 0) { 7484cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org x = 0; 7494cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7504cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (y > 0) { 7514cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org y = 0; 7524cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7534cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // here x,y are either 0 or negative 7544cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org pixels = ((const char*)pixels - y * rowBytes - x * info.bytesPerPixel()); 7554cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 7564cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // The device can assert that the requested area is always contained in its bounds 7574ef54f8d72420a521d4aae04ff5cd438810eca7fcommit-bot@chromium.org return device->writePixels(info, pixels, rowBytes, target.x(), target.y()); 7584cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org} 75951df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 7604370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comSkCanvas* SkCanvas::canvasForDrawIter() { 7614370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com return this; 7624370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 7634370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 7648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 7658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::updateDeviceCMCache() { 7678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fDeviceCMDirty) { 7688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& totalMatrix = this->getTotalMatrix(); 769045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com const SkRasterClip& totalClip = *fMCRec->fRasterClip; 7708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* layer = fMCRec->fTopLayer; 7714b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 7728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == layer->fNext) { // only one layer 77346799cd9f0bded51a189d77731b25af159ab4609reed@google.com layer->updateMC(totalMatrix, totalClip, fClipStack, NULL); 7748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 775045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com SkRasterClip clip(totalClip); 7768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 77746799cd9f0bded51a189d77731b25af159ab4609reed@google.com layer->updateMC(totalMatrix, clip, fClipStack, &clip); 7788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while ((layer = layer->fNext) != NULL); 7798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = false; 7818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 7858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::internalSave(SaveFlags flags) { 7878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int saveCount = this->getSaveCount(); // record this before the actual save 7884b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 7898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com MCRec* newTop = (MCRec*)fMCStack.push_back(); 7908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com new (newTop) MCRec(fMCRec, flags); // balanced in restore() 7914b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 7928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = newTop; 7934b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 7946c157640c27ee2ed6f9a484d21691b7b19dfecdecommit-bot@chromium.org if (SkCanvas::kClip_SaveFlag & flags) { 7956c157640c27ee2ed6f9a484d21691b7b19dfecdecommit-bot@chromium.org fClipStack.save(); 7966c157640c27ee2ed6f9a484d21691b7b19dfecdecommit-bot@chromium.org } 7975c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 7988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return saveCount; 7998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 801d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.orgint SkCanvas::save() { 802d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org this->willSave(kMatrixClip_SaveFlag); 803d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org return this->internalSave(kMatrixClip_SaveFlag); 804d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org} 805d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org 8068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::save(SaveFlags flags) { 807e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org this->willSave(flags); 8088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // call shared impl 8098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->internalSave(flags); 8108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic bool bounds_affects_clip(SkCanvas::SaveFlags flags) { 813b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG 8148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (flags & SkCanvas::kClipToLayer_SaveFlag) != 0; 815b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#else 816b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com return true; 817b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#endif 8188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 820a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.orgbool SkCanvas::clipRectBounds(const SkRect* bounds, SaveFlags flags, 821c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org SkIRect* intersection, const SkImageFilter* imageFilter) { 822bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect clipBounds; 823c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org SkRegion::Op op = SkRegion::kIntersect_Op; 824bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (!this->getClipDeviceBounds(&clipBounds)) { 825a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return false; 826f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 827c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org 828c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org if (imageFilter) { 829c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org imageFilter->filterBounds(clipBounds, *fMCRec->fMatrix, &clipBounds); 830c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org // Filters may grow the bounds beyond the device bounds. 831c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org op = SkRegion::kReplace_Op; 832c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org } 833bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect ir; 8348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL != bounds) { 8358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 8364b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 8378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->getTotalMatrix().mapRect(&r, *bounds); 8388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.roundOut(&ir); 8398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // early exit if the layer's bounds are clipped out 8408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!ir.intersect(clipBounds)) { 841bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (bounds_affects_clip(flags)) { 8420017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com fMCRec->fRasterClip->setEmpty(); 843bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 844a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return false; 8458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { // no user bounds, so just use the clip 8478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ir = clipBounds; 8488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 85089f077ced4918ded7e911bc5052b61c90ad57a9asenorblanco@chromium.org if (bounds_affects_clip(flags)) { 85189f077ced4918ded7e911bc5052b61c90ad57a9asenorblanco@chromium.org fClipStack.clipDevRect(ir, op); 85289f077ced4918ded7e911bc5052b61c90ad57a9asenorblanco@chromium.org // early exit if the clip is now empty 85389f077ced4918ded7e911bc5052b61c90ad57a9asenorblanco@chromium.org if (!fMCRec->fRasterClip->op(ir, op)) { 85489f077ced4918ded7e911bc5052b61c90ad57a9asenorblanco@chromium.org return false; 85589f077ced4918ded7e911bc5052b61c90ad57a9asenorblanco@chromium.org } 856a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org } 857a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 858a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org if (intersection) { 859a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org *intersection = ir; 860a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org } 861a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return true; 862a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org} 863a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 864d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.orgint SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint) { 865d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org SaveLayerStrategy strategy = this->willSaveLayer(bounds, paint, kARGB_ClipLayer_SaveFlag); 866d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org return this->internalSaveLayer(bounds, paint, kARGB_ClipLayer_SaveFlag, false, strategy); 867d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org} 868d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org 869a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.orgint SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint, 870a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org SaveFlags flags) { 871e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org SaveLayerStrategy strategy = this->willSaveLayer(bounds, paint, flags); 872e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org return this->internalSaveLayer(bounds, paint, flags, false, strategy); 8738926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com} 8748926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 8752b290cec9825da11d8e09074727cfaac5eca6453commit-bot@chromium.orgstatic SkBaseDevice* create_compatible_device(SkCanvas* canvas, 8762b290cec9825da11d8e09074727cfaac5eca6453commit-bot@chromium.org const SkImageInfo& info) { 87776f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com SkBaseDevice* device = canvas->getDevice(); 87815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org return device ? device->createCompatibleDevice(info) : NULL; 87976f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com} 88076f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com 881e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.orgint SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags, 882e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org bool justForImageFilter, SaveLayerStrategy strategy) { 883b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG 8842a5cd60bfff32c92cf44a8cfc3e8c017b9aee456commit-bot@chromium.org flags |= kClipToLayer_SaveFlag; 885b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#endif 886b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com 887a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org // do this before we create the layer. We don't call the public save() since 888a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org // that would invoke a possibly overridden virtual 889a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org int count = this->internalSave(flags); 890a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 891a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org fDeviceCMDirty = true; 892a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 893a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org SkIRect ir; 894c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org if (!this->clipRectBounds(bounds, flags, &ir, paint ? paint->getImageFilter() : NULL)) { 8958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return count; 8968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 898e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy really care about 899e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org // the clipRectBounds() call above? 900e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org if (kNoLayer_SaveLayerStrategy == strategy) { 901e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org return count; 902e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org } 903e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org 904b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com // Kill the imagefilter if our device doesn't allow it 905b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com SkLazyPaint lazyP; 906b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com if (paint && paint->getImageFilter()) { 907b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com if (!this->getTopDevice()->allowImageFilter(paint->getImageFilter())) { 9088926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com if (justForImageFilter) { 9098926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com // early exit if the layer was just for the imageFilter 9108926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com return count; 9118926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 912b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com SkPaint* p = lazyP.set(*paint); 913b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com p->setImageFilter(NULL); 914b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com paint = p; 915b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com } 916b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com } 917b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com 91815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org bool isOpaque = !SkToBool(flags & kHasAlphaLayer_SaveFlag); 91915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org SkImageInfo info = SkImageInfo::MakeN32(ir.width(), ir.height(), 92015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType); 9218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9221f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* device; 92376dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com if (paint && paint->getImageFilter()) { 9242b290cec9825da11d8e09074727cfaac5eca6453commit-bot@chromium.org device = create_compatible_device(this, info); 92576dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } else { 92615a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org device = this->createLayerDevice(info); 92776dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } 928e25c68402b38ac01dc1ae196ae8a5265b773c5f2bungeman@google.com if (NULL == device) { 929e25c68402b38ac01dc1ae196ae8a5265b773c5f2bungeman@google.com SkDebugf("Unable to create device for layer."); 930e25c68402b38ac01dc1ae196ae8a5265b773c5f2bungeman@google.com return count; 931e25c68402b38ac01dc1ae196ae8a5265b773c5f2bungeman@google.com } 932e97f0856a8044866b12527819d14cdfbcdfd96f2bsalomon@google.com 9336f8f292aa768869a9e85c314b124875f57504f2creed@google.com device->setOrigin(ir.fLeft, ir.fTop); 93440a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com DeviceCM* layer = SkNEW_ARGS(DeviceCM, (device, ir.fLeft, ir.fTop, paint, this)); 9358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device->unref(); 9368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com layer->fNext = fMCRec->fTopLayer; 9388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fLayer = layer; 9398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fTopLayer = layer; // this field is NOT an owner of layer 9408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 941b0a7ace7cb2a7559bbc254a7c93698bc71bbd245junov@chromium.org fSaveLayerCount += 1; 9428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return count; 9438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 945d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.orgint SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) { 946d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org return this->saveLayerAlpha(bounds, alpha, kARGB_ClipLayer_SaveFlag); 947d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org} 948d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org 9498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha, 9508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SaveFlags flags) { 9518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (0xFF == alpha) { 9528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->saveLayer(bounds, NULL, flags); 9538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 9548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint tmpPaint; 9558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com tmpPaint.setAlpha(alpha); 9568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->saveLayer(bounds, &tmpPaint, flags); 9578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::restore() { 9618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // check for underflow 9628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fMCStack.count() > 1) { 963e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org this->willRestore(); 9648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->internalRestore(); 9658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::internalRestore() { 9698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fMCStack.count() != 0); 9708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 972c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 9738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9746c157640c27ee2ed6f9a484d21691b7b19dfecdecommit-bot@chromium.org if (SkCanvas::kClip_SaveFlag & fMCRec->fFlags) { 9756c157640c27ee2ed6f9a484d21691b7b19dfecdecommit-bot@chromium.org fClipStack.restore(); 9766c157640c27ee2ed6f9a484d21691b7b19dfecdecommit-bot@chromium.org } 9776c157640c27ee2ed6f9a484d21691b7b19dfecdecommit-bot@chromium.org 97888edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com // reserve our layer (if any) 9798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* layer = fMCRec->fLayer; // may be null 9808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now detach it from fMCRec so we can pop(). Gets freed after its drawn 9818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fLayer = NULL; 9828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now do the normal restore() 9848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->~MCRec(); // balanced in save() 9858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCStack.pop_back(); 9868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = (MCRec*)fMCStack.back(); 9878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* Time to draw the layer's offscreen. We can't call the public drawSprite, 9898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com since if we're being recorded, we don't want to record this (the 9908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com recorder will have already recorded the restore). 9918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 9928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL != layer) { 9938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (layer->fNext) { 9946f8f292aa768869a9e85c314b124875f57504f2creed@google.com const SkIPoint& origin = layer->fDevice->getOrigin(); 9958926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(), 9968926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com layer->fPaint); 9978926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com // reset this, since internalDrawDevice will have set it to true 9988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 9997c2029367cea5479fa3b74fb0ca2b0297b42b709reed@google.com 1000b0a7ace7cb2a7559bbc254a7c93698bc71bbd245junov@chromium.org SkASSERT(fSaveLayerCount > 0); 1001b0a7ace7cb2a7559bbc254a7c93698bc71bbd245junov@chromium.org fSaveLayerCount -= 1; 10028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDELETE(layer); 100488edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 10058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::getSaveCount() const { 10088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fMCStack.count(); 10098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::restoreToCount(int count) { 10128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // sanity check 10138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count < 1) { 10148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com count = 1; 10158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 101674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1017b9d1c6a3c43a2cbcbd612f4ec4aaf604a1fa6444reed@google.com int n = this->getSaveCount() - count; 1018b9d1c6a3c43a2cbcbd612f4ec4aaf604a1fa6444reed@google.com for (int i = 0; i < n; ++i) { 10198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->restore(); 10208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10237c2029367cea5479fa3b74fb0ca2b0297b42b709reed@google.combool SkCanvas::isDrawingToLayer() const { 1024b0a7ace7cb2a7559bbc254a7c93698bc71bbd245junov@chromium.org return fSaveLayerCount > 0; 10257c2029367cea5479fa3b74fb0ca2b0297b42b709reed@google.com} 10267c2029367cea5479fa3b74fb0ca2b0297b42b709reed@google.com 102776f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.comSkSurface* SkCanvas::newSurface(const SkImageInfo& info) { 102876f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com return this->onNewSurface(info); 102976f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com} 103076f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com 103176f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.comSkSurface* SkCanvas::onNewSurface(const SkImageInfo& info) { 103276f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com SkBaseDevice* dev = this->getDevice(); 103376f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com return dev ? dev->newSurface(info) : NULL; 103476f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com} 103576f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com 1036c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgSkImageInfo SkCanvas::imageInfo() const { 1037c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkBaseDevice* dev = this->getDevice(); 1038c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (dev) { 1039c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return dev->imageInfo(); 1040c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } else { 1041900ecf2f1579d42c9d2959831787af0346320f86reed@google.com return SkImageInfo::MakeUnknown(0, 0); 1042c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1043c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1044c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1045c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgconst void* SkCanvas::peekPixels(SkImageInfo* info, size_t* rowBytes) { 1046c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return this->onPeekPixels(info, rowBytes); 1047c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1048c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1049c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgconst void* SkCanvas::onPeekPixels(SkImageInfo* info, size_t* rowBytes) { 1050c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkBaseDevice* dev = this->getDevice(); 1051c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return dev ? dev->peekPixels(info, rowBytes) : NULL; 1052c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1053c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 10546b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.orgvoid* SkCanvas::accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin) { 10556b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org void* pixels = this->onAccessTopLayerPixels(info, rowBytes); 10566b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org if (pixels && origin) { 10576b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org *origin = this->getTopDevice(false)->getOrigin(); 10586b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org } 10596b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org return pixels; 10609c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 10619c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 10629c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.comvoid* SkCanvas::onAccessTopLayerPixels(SkImageInfo* info, size_t* rowBytes) { 10639c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com SkBaseDevice* dev = this->getTopDevice(); 10649c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com return dev ? dev->accessPixels(info, rowBytes) : NULL; 10659c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 10669c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1067c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgSkAutoROCanvasPixels::SkAutoROCanvasPixels(SkCanvas* canvas) { 1068c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org fAddr = canvas->peekPixels(&fInfo, &fRowBytes); 1069c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (NULL == fAddr) { 1070c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org fInfo = canvas->imageInfo(); 1071a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (kUnknown_SkColorType == fInfo.colorType() || !fBitmap.allocPixels(fInfo)) { 1072c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return; // failure, fAddr is NULL 1073c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1074c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (!canvas->readPixels(&fBitmap, 0, 0)) { 1075c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return; // failure, fAddr is NULL 1076c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1077c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org fAddr = fBitmap.getPixels(); 1078c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org fRowBytes = fBitmap.rowBytes(); 1079c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1080c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkASSERT(fAddr); // success 1081c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1082c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1083c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgbool SkAutoROCanvasPixels::asROBitmap(SkBitmap* bitmap) const { 1084c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (fAddr) { 108500f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org return bitmap->installPixels(fInfo, const_cast<void*>(fAddr), fRowBytes); 1086c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } else { 1087c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org bitmap->reset(); 1088c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return false; 1089c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1090c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1091c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1092210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.orgvoid SkCanvas::onPushCull(const SkRect& cullRect) { 1093210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org // do nothing. Subclasses may do something 1094210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org} 1095210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org 1096210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.orgvoid SkCanvas::onPopCull() { 1097210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org // do nothing. Subclasses may do something 1098210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org} 1099210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org 11008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////// 1101520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org#ifdef SK_DEBUG 1102520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org// Ensure that cull rects are monotonically nested in device space. 1103520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.orgvoid SkCanvas::validateCull(const SkIRect& devCull) { 1104520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org if (fCullStack.isEmpty() 1105520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org || devCull.isEmpty() 1106520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org || fCullStack.top().contains(devCull)) { 1107520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org return; 1108520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org } 1109520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1110520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org SkDEBUGF(("Invalid cull: [%d %d %d %d] (previous cull: [%d %d %d %d])\n", 1111520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org devCull.x(), devCull.y(), devCull.right(), devCull.bottom(), 1112520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org fCullStack.top().x(), fCullStack.top().y(), 1113520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org fCullStack.top().right(), fCullStack.top().bottom())); 1114520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1115520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org#ifdef ASSERT_NESTED_CULLING 1116520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org SkDEBUGFAIL("Invalid cull."); 1117520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org#endif 1118520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org} 1119520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org#endif 1120520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1121520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.orgvoid SkCanvas::pushCull(const SkRect& cullRect) { 1122520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org ++fCullCount; 1123520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org this->onPushCull(cullRect); 1124520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1125520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org#ifdef SK_DEBUG 1126520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org // Map the cull rect into device space. 1127520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org SkRect mappedCull; 1128520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org this->getTotalMatrix().mapRect(&mappedCull, cullRect); 1129520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1130520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org // Take clipping into account. 1131520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org SkIRect devClip, devCull; 1132520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org mappedCull.roundOut(&devCull); 1133520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org this->getClipDeviceBounds(&devClip); 1134520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org if (!devCull.intersect(devClip)) { 1135520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org devCull.setEmpty(); 1136520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org } 1137520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1138520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org this->validateCull(devCull); 1139520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org fCullStack.push(devCull); // balanced in popCull 1140520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org#endif 1141520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org} 1142520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1143520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.orgvoid SkCanvas::popCull() { 1144520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org SkASSERT(fCullStack.count() == fCullCount); 1145520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1146520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org if (fCullCount > 0) { 1147520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org --fCullCount; 1148520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org this->onPopCull(); 1149520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1150520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org SkDEBUGCODE(fCullStack.pop()); 1151520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org } 1152520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org} 1153520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1154520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org///////////////////////////////////////////////////////////////////////////// 11558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11569bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.comvoid SkCanvas::internalDrawBitmap(const SkBitmap& bitmap, 11578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& matrix, const SkPaint* paint) { 115850b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org if (bitmap.drawsNothing()) { 11598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 11608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11622c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkLazyPaint lazy; 11638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == paint) { 11642c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org paint = lazy.init(); 11658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11669bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com 11679bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com SkDEBUGCODE(bitmap.validate();) 11689bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com CHECK_LOCKCOUNT_BALANCE(bitmap); 11699bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com 117078cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 117178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 117278cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (paint && paint->canComputeFastBounds()) { 117378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bitmap.getBounds(&storage); 117478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org matrix.mapRect(&storage); 117578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint->computeFastBounds(storage, &storage); 117678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org } 117778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org 117878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) 11799bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com 11809bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com while (iter.next()) { 11819bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com iter.fDevice->drawBitmap(iter, bitmap, matrix, looper.paint()); 11829bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com } 11839bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com 11849bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com LOOPER_END 11858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 11868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11871f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comvoid SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, 11888926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com const SkPaint* paint) { 11898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint tmp; 11908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == paint) { 11918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com tmp.setDither(true); 11928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint = &tmp; 11938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11944b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 11958926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com LOOPER_BEGIN_DRAWDEVICE(*paint, SkDrawFilter::kBitmap_Type) 11968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 11971f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* dstDev = iter.fDevice; 119876dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com paint = &looper.paint(); 119976dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkImageFilter* filter = paint->getImageFilter(); 120076dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkIPoint pos = { x - iter.getX(), y - iter.getY() }; 12018926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com if (filter && !dstDev->canHandleImageFilter(filter)) { 12029c39744a00573b7133fc765b0a9d50a0ceace7b8senorblanco@chromium.org SkDeviceImageFilterProxy proxy(dstDev); 120376dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkBitmap dst; 12046776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org SkIPoint offset = SkIPoint::Make(0, 0); 1205b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com const SkBitmap& src = srcDev->accessBitmap(false); 1206fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org SkMatrix matrix = *iter.fMatrix; 1207d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org matrix.postTranslate(SkIntToScalar(-pos.x()), SkIntToScalar(-pos.y())); 12084cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org SkIRect clipBounds = SkIRect::MakeWH(srcDev->width(), srcDev->height()); 12091a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org SkImageFilter::Cache* cache = SkImageFilter::GetExternalCache(); 12101a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org SkAutoUnref aur(NULL); 12111a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org if (!cache) { 12121a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org cache = SkImageFilter::Cache::Create(); 12131a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org aur.reset(cache); 12141a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org } 1215f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org SkImageFilter::Context ctx(matrix, clipBounds, cache); 12164cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org if (filter->filterImage(&proxy, src, ctx, &dst, &offset)) { 12175efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com SkPaint tmpUnfiltered(*paint); 12185efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com tmpUnfiltered.setImageFilter(NULL); 12196776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org dstDev->drawSprite(iter, dst, pos.x() + offset.x(), pos.y() + offset.y(), 12206776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org tmpUnfiltered); 122176dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } 122276dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } else { 1223b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com dstDev->drawDevice(iter, srcDev, pos.x(), pos.y(), *paint); 122476dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } 12258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12264e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 12278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12298926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.comvoid SkCanvas::drawSprite(const SkBitmap& bitmap, int x, int y, 12308926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com const SkPaint* paint) { 123150b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org if (bitmap.drawsNothing()) { 12328926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com return; 12338926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 123450b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org SkDEBUGCODE(bitmap.validate();) 123550b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org CHECK_LOCKCOUNT_BALANCE(bitmap); 1236fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 12378926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkPaint tmp; 12388926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com if (NULL == paint) { 12398926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com paint = &tmp; 12408926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 1241fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 12428926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com LOOPER_BEGIN_DRAWDEVICE(*paint, SkDrawFilter::kBitmap_Type) 1243fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 12448926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com while (iter.next()) { 12458926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com paint = &looper.paint(); 12468926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkImageFilter* filter = paint->getImageFilter(); 12478926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkIPoint pos = { x - iter.getX(), y - iter.getY() }; 12488926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com if (filter && !iter.fDevice->canHandleImageFilter(filter)) { 12499c39744a00573b7133fc765b0a9d50a0ceace7b8senorblanco@chromium.org SkDeviceImageFilterProxy proxy(iter.fDevice); 12508926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkBitmap dst; 12516776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org SkIPoint offset = SkIPoint::Make(0, 0); 1252fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org SkMatrix matrix = *iter.fMatrix; 1253d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org matrix.postTranslate(SkIntToScalar(-pos.x()), SkIntToScalar(-pos.y())); 12544cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org SkIRect clipBounds = SkIRect::MakeWH(bitmap.width(), bitmap.height()); 12551a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org SkImageFilter::Cache* cache = SkImageFilter::GetExternalCache(); 12561a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org SkAutoUnref aur(NULL); 12571a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org if (!cache) { 12581a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org cache = SkImageFilter::Cache::Create(); 12591a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org aur.reset(cache); 12601a479e7547d4efe2d1d06fab5c9442b77ec6c954senorblanco@chromium.org } 1261f7efa502d62af80bd15b03e1131603fb6577c3dfcommit-bot@chromium.org SkImageFilter::Context ctx(matrix, clipBounds, cache); 12624cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org if (filter->filterImage(&proxy, bitmap, ctx, &dst, &offset)) { 12635efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com SkPaint tmpUnfiltered(*paint); 12645efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com tmpUnfiltered.setImageFilter(NULL); 12656776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org iter.fDevice->drawSprite(iter, dst, pos.x() + offset.x(), pos.y() + offset.y(), 12665efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com tmpUnfiltered); 12678926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 12688926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } else { 12698926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com iter.fDevice->drawSprite(iter, bitmap, pos.x(), pos.y(), *paint); 12708926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 12718926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 12728926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com LOOPER_END 12738926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com} 12748926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 12758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////// 127692362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::translate(SkScalar dx, SkScalar dy) { 1277d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1278d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setTranslate(dx, dy); 1279d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 12808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 128292362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::scale(SkScalar sx, SkScalar sy) { 1283d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1284d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setScale(sx, sy); 1285d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 12868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 128892362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::rotate(SkScalar degrees) { 1289d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1290d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setRotate(degrees); 1291d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 12928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 129492362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::skew(SkScalar sx, SkScalar sy) { 1295d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1296d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setSkew(sx, sy); 1297d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 129844c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org} 129944c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 130092362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::concat(const SkMatrix& matrix) { 1301d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org if (matrix.isIdentity()) { 1302d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org return; 1303d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org } 1304d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org 13058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1306c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 130792362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.org fMCRec->fMatrix->preConcat(matrix); 130844c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 130944c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org this->didConcat(matrix); 131044c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org} 131144c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 13128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::setMatrix(const SkMatrix& matrix) { 13138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1314c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 13158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *fMCRec->fMatrix = matrix; 131644c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org this->didSetMatrix(matrix); 13178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::resetMatrix() { 13208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 13214b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 13228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.reset(); 13238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->setMatrix(matrix); 13248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 13278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1328759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { 13298f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 13308f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(rect, op, edgeStyle); 13318f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 13328f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 13338f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 1334da17f758442f16747af39f8fbaed9c097048519creed@google.com#ifdef SK_ENABLE_CLIP_QUICKREJECT 1335da17f758442f16747af39f8fbaed9c097048519creed@google.com if (SkRegion::kIntersect_Op == op) { 1336da17f758442f16747af39f8fbaed9c097048519creed@google.com if (fMCRec->fRasterClip->isEmpty()) { 1337da17f758442f16747af39f8fbaed9c097048519creed@google.com return false; 1338da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1339da17f758442f16747af39f8fbaed9c097048519creed@google.com 13403b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(rect)) { 1341da17f758442f16747af39f8fbaed9c097048519creed@google.com fDeviceCMDirty = true; 1342c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 1343da17f758442f16747af39f8fbaed9c097048519creed@google.com 1344da17f758442f16747af39f8fbaed9c097048519creed@google.com fClipStack.clipEmpty(); 1345da17f758442f16747af39f8fbaed9c097048519creed@google.com return fMCRec->fRasterClip->setEmpty(); 1346da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1347da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1348da17f758442f16747af39f8fbaed9c097048519creed@google.com#endif 1349da17f758442f16747af39f8fbaed9c097048519creed@google.com 13505c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com AutoValidateClip avc(this); 13515c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 13528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1353c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 13548f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!fAllowSoftClip) { 13558f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com edgeStyle = kHard_ClipEdgeStyle; 13568f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 13578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fMCRec->fMatrix->rectStaysRect()) { 1359123671901abfa595d09ca789b487c4bc7c1f7cbcrobertphillips@google.com // for these simpler matrices, we can stay a rect even after applying 136098de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // the matrix. This means we don't have to a) make a path, and b) tell 136198de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // the region code to scan-convert the path, only to discover that it 136298de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // is really just a rect. 13638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 13648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fMatrix->mapRect(&r, rect); 13668f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com fClipStack.clipDevRect(r, op, kSoft_ClipEdgeStyle == edgeStyle); 13678f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com fMCRec->fRasterClip->op(r, op, kSoft_ClipEdgeStyle == edgeStyle); 13688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 1369123671901abfa595d09ca789b487c4bc7c1f7cbcrobertphillips@google.com // since we're rotated or some such thing, we convert the rect to a path 137098de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // and clip against that, since it can handle any matrix. However, to 137198de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // avoid recursion in the case where we are subclassed (e.g. Pictures) 137298de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // we explicitly call "our" version of clipPath. 13738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath path; 13748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.addRect(rect); 13768f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->SkCanvas::onClipPath(path, op, edgeStyle); 13778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13808f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comstatic void clip_path_helper(const SkCanvas* canvas, SkRasterClip* currClip, 13818f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com const SkPath& devPath, SkRegion::Op op, bool doAA) { 1382759876a9223ef64f9d0db235d7a46750f8193cbcreed@google.com // base is used to limit the size (and therefore memory allocation) of the 1383759876a9223ef64f9d0db235d7a46750f8193cbcreed@google.com // region that results from scan converting devPath. 1384759876a9223ef64f9d0db235d7a46750f8193cbcreed@google.com SkRegion base; 1385759876a9223ef64f9d0db235d7a46750f8193cbcreed@google.com 1386819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com if (SkRegion::kIntersect_Op == op) { 1387759876a9223ef64f9d0db235d7a46750f8193cbcreed@google.com // since we are intersect, we can do better (tighter) with currRgn's 1388759876a9223ef64f9d0db235d7a46750f8193cbcreed@google.com // bounds, than just using the device. However, if currRgn is complex, 1389759876a9223ef64f9d0db235d7a46750f8193cbcreed@google.com // our region blitter may hork, so we do that case in two steps. 13900017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com if (currClip->isRect()) { 1391b446fc7f05d2e3f22d574187b433e02b0c781e1fcommit-bot@chromium.org // FIXME: we should also be able to do this when currClip->isBW(), 1392b446fc7f05d2e3f22d574187b433e02b0c781e1fcommit-bot@chromium.org // but relaxing the test above triggers GM asserts in 1393b446fc7f05d2e3f22d574187b433e02b0c781e1fcommit-bot@chromium.org // SkRgnBuilder::blitH(). We need to investigate what's going on. 13948f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com currClip->setPath(devPath, currClip->bwRgn(), doAA); 1395759876a9223ef64f9d0db235d7a46750f8193cbcreed@google.com } else { 13960017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com base.setRect(currClip->getBounds()); 13970017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com SkRasterClip clip; 13980017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com clip.setPath(devPath, base, doAA); 13998f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com currClip->op(clip, op); 1400759876a9223ef64f9d0db235d7a46750f8193cbcreed@google.com } 1401819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com } else { 14021f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com const SkBaseDevice* device = canvas->getDevice(); 1403ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com if (!device) { 14048f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com currClip->setEmpty(); 14058f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com return; 1406ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com } 1407ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com 1408a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org base.setRect(0, 0, device->width(), device->height()); 1409819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 1410819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com if (SkRegion::kReplace_Op == op) { 14118f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com currClip->setPath(devPath, base, doAA); 1412819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com } else { 14130017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com SkRasterClip clip; 14140017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com clip.setPath(devPath, base, doAA); 14158f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com currClip->op(clip, op); 1416819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com } 1417819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com } 1418819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com} 1419819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 1420759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) { 14218f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 14224ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (rrect.isRect()) { 14238f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(rrect.getBounds(), op, edgeStyle); 14248f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } else { 14258f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRRect(rrect, op, edgeStyle); 14264ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 14278f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 142814e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 14298f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 143014e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org SkRRect transformedRRect; 143114e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org if (rrect.transform(*fMCRec->fMatrix, &transformedRRect)) { 143214e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org AutoValidateClip avc(this); 143314e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 143414e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org fDeviceCMDirty = true; 143514e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org fCachedLocalClipBoundsDirty = true; 14368f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!fAllowSoftClip) { 14378f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com edgeStyle = kHard_ClipEdgeStyle; 14388f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 143914e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 14408f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com fClipStack.clipDevRRect(transformedRRect, op, kSoft_ClipEdgeStyle == edgeStyle); 144114e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 144214e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org SkPath devPath; 144314e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org devPath.addRRect(transformedRRect); 144414e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 14458f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com clip_path_helper(this, fMCRec->fRasterClip, devPath, op, kSoft_ClipEdgeStyle == edgeStyle); 14468f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com return; 144714e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org } 144814e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 144914e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org SkPath path; 145014e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org path.addRRect(rrect); 145114e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org // call the non-virtual version 14528f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->SkCanvas::onClipPath(path, op, edgeStyle); 14534ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 14544ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 1455759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { 14568f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 14578f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com SkRect r; 14588f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!path.isInverseFillType() && path.isRect(&r)) { 14598f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(r, op, edgeStyle); 14608f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } else { 14618f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipPath(path, op, edgeStyle); 14628f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 14638f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 14648f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 14658f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 1466da17f758442f16747af39f8fbaed9c097048519creed@google.com#ifdef SK_ENABLE_CLIP_QUICKREJECT 1467da17f758442f16747af39f8fbaed9c097048519creed@google.com if (SkRegion::kIntersect_Op == op && !path.isInverseFillType()) { 1468da17f758442f16747af39f8fbaed9c097048519creed@google.com if (fMCRec->fRasterClip->isEmpty()) { 1469da17f758442f16747af39f8fbaed9c097048519creed@google.com return false; 1470da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1471fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 14723b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(path.getBounds())) { 1473da17f758442f16747af39f8fbaed9c097048519creed@google.com fDeviceCMDirty = true; 1474c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 1475fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1476da17f758442f16747af39f8fbaed9c097048519creed@google.com fClipStack.clipEmpty(); 1477da17f758442f16747af39f8fbaed9c097048519creed@google.com return fMCRec->fRasterClip->setEmpty(); 1478da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1479da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1480da17f758442f16747af39f8fbaed9c097048519creed@google.com#endif 1481da17f758442f16747af39f8fbaed9c097048519creed@google.com 14825c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com AutoValidateClip avc(this); 14835c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 14848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1485c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 14868f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!fAllowSoftClip) { 14878f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com edgeStyle = kHard_ClipEdgeStyle; 14888f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 14898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath devPath; 14918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.transform(*fMCRec->fMatrix, &devPath); 14928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1493fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // Check if the transfomation, or the original path itself 1494fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // made us empty. Note this can also happen if we contained NaN 1495fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // values. computing the bounds detects this, and will set our 1496fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // bounds to empty if that is the case. (see SkRect::set(pts, count)) 1497fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com if (devPath.getBounds().isEmpty()) { 1498fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // resetting the path will remove any NaN or other wanky values 1499fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // that might upset our scan converter. 1500fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com devPath.reset(); 1501fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com } 1502fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com 15035c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // if we called path.swap() we could avoid a deep copy of this path 15048f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com fClipStack.clipDevPath(devPath, op, kSoft_ClipEdgeStyle == edgeStyle); 15055c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 150645a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com if (fAllowSimplifyClip) { 150745a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com devPath.reset(); 150845a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com devPath.setFillType(SkPath::kInverseEvenOdd_FillType); 150945a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com const SkClipStack* clipStack = getClipStack(); 151045a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com SkClipStack::Iter iter(*clipStack, SkClipStack::Iter::kBottom_IterStart); 151145a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com const SkClipStack::Element* element; 151245a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com while ((element = iter.next())) { 151345a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com SkClipStack::Element::Type type = element->getType(); 151445a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com SkPath operand; 15152a67e123a3e559774a16a58cbe5106bc0fb86740commit-bot@chromium.org if (type != SkClipStack::Element::kEmpty_Type) { 15162a67e123a3e559774a16a58cbe5106bc0fb86740commit-bot@chromium.org element->asPath(&operand); 15172a67e123a3e559774a16a58cbe5106bc0fb86740commit-bot@chromium.org } 151845a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com SkRegion::Op elementOp = element->getOp(); 151945a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com if (elementOp == SkRegion::kReplace_Op) { 152045a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com devPath = operand; 152145a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com } else { 152245a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com Op(devPath, operand, (SkPathOp) elementOp, &devPath); 152345a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com } 152496fd3440fa489f74f903f30487282af99deb2a4dcaryclark@google.com // if the prev and curr clips disagree about aa -vs- not, favor the aa request. 152596fd3440fa489f74f903f30487282af99deb2a4dcaryclark@google.com // perhaps we need an API change to avoid this sort of mixed-signals about 152696fd3440fa489f74f903f30487282af99deb2a4dcaryclark@google.com // clipping. 15278f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (element->isAA()) { 15288f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com edgeStyle = kSoft_ClipEdgeStyle; 15298f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 153045a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com } 153145a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com op = SkRegion::kReplace_Op; 153245a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com } 153345a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com 15348f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com clip_path_helper(this, fMCRec->fRasterClip, devPath, op, edgeStyle); 15358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 15368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1537759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::updateClipConservativelyUsingBounds(const SkRect& bounds, SkRegion::Op op, 1538ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org bool inverseFilled) { 1539ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // This is for updating the clip conservatively using only bounds 1540ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // information. 1541ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // Contract: 1542ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // The current clip must contain the true clip. The true 1543ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // clip is the clip that would have normally been computed 1544ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // by calls to clipPath and clipRRect 1545ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // Objective: 1546ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // Keep the current clip as small as possible without 1547ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // breaking the contract, using only clip bounding rectangles 1548ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // (for performance). 1549ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org 1550ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // N.B.: This *never* calls back through a virtual on canvas, so subclasses 1551ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // don't have to worry about getting caught in a loop. Thus anywhere 1552ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // we call a virtual method, we explicitly prefix it with 1553ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // SkCanvas:: to be sure to call the base-class. 1554a5d3e77420621c912383c3b22e542d9413d68278skia.committer@gmail.com 1555ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org if (inverseFilled) { 1556ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org switch (op) { 1557ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org case SkRegion::kIntersect_Op: 1558ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org case SkRegion::kDifference_Op: 1559ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // These ops can only shrink the current clip. So leaving 15608f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com // the clip unchanged conservatively respects the contract. 15618f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com break; 1562ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org case SkRegion::kUnion_Op: 1563ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org case SkRegion::kReplace_Op: 1564ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org case SkRegion::kReverseDifference_Op: 15658f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com case SkRegion::kXOR_Op: { 1566ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // These ops can grow the current clip up to the extents of 1567ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // the input clip, which is inverse filled, so we just set 1568ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // the current clip to the device bounds. 1569ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org SkRect deviceBounds; 1570ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org SkIRect deviceIBounds; 1571ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org this->getDevice()->getGlobalBounds(&deviceIBounds); 15724469938e92d779dff05e745559e67907bbf21e78reed@google.com deviceBounds = SkRect::Make(deviceIBounds); 1573091a594dbc4116ec2e54724432472bf37dae794acommit-bot@chromium.org 1574ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // set the clip in device space 1575091a594dbc4116ec2e54724432472bf37dae794acommit-bot@chromium.org SkMatrix savedMatrix = this->getTotalMatrix(); 1576ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org this->SkCanvas::setMatrix(SkMatrix::I()); 1577370a89980b2d38a6d01903b484bf404d6c48b496skia.committer@gmail.com this->SkCanvas::onClipRect(deviceBounds, SkRegion::kReplace_Op, 15788f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com kHard_ClipEdgeStyle); 1579091a594dbc4116ec2e54724432472bf37dae794acommit-bot@chromium.org this->setMatrix(savedMatrix); 15808f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com break; 15818f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 1582ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org default: 1583ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org SkASSERT(0); // unhandled op? 1584ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org } 1585ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org } else { 1586ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // Not inverse filled 1587ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org switch (op) { 1588ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org case SkRegion::kIntersect_Op: 1589ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org case SkRegion::kUnion_Op: 1590ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org case SkRegion::kReplace_Op: 15918f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->SkCanvas::onClipRect(bounds, op, kHard_ClipEdgeStyle); 15928f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com break; 1593ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org case SkRegion::kDifference_Op: 1594ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // Difference can only shrink the current clip. 1595ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // Leaving clip unchanged conservatively fullfills the contract. 15968f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com break; 1597ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org case SkRegion::kReverseDifference_Op: 1598ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // To reverse, we swap in the bounds with a replace op. 1599ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // As with difference, leave it unchanged. 16008f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->SkCanvas::onClipRect(bounds, SkRegion::kReplace_Op, kHard_ClipEdgeStyle); 16018f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com break; 1602ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org case SkRegion::kXOR_Op: 1603ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // Be conservative, based on (A XOR B) always included in (A union B), 1604ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org // which is always included in (bounds(A) union bounds(B)) 16058f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->SkCanvas::onClipRect(bounds, SkRegion::kUnion_Op, kHard_ClipEdgeStyle); 16068f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com break; 1607ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org default: 1608ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org SkASSERT(0); // unhandled op? 1609ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org } 1610ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org } 1611ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org} 1612ed8d6bb2be0ed6a20841573682afaa46dea15175junov@chromium.org 1613759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipRegion(const SkRegion& rgn, SkRegion::Op op) { 16148f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRegion(rgn, op); 16158f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 16168f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 16178f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipRegion(const SkRegion& rgn, SkRegion::Op op) { 16185c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com AutoValidateClip avc(this); 16195c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 16208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1621c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 16228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16235c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // todo: signal fClipStack that we have a region, and therefore (I guess) 16245c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // we have to ignore it, and use the region directly? 1625115d931d2fbd3a109a21b28c8a9c5099e6c49c54reed@google.com fClipStack.clipDevRect(rgn.getBounds(), op); 16265c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 16278f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com fMCRec->fRasterClip->op(rgn, op); 16288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1630819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com#ifdef SK_DEBUG 1631819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.comvoid SkCanvas::validateClip() const { 1632819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com // construct clipRgn from the clipstack 16331f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com const SkBaseDevice* device = this->getDevice(); 1634ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com if (!device) { 16355c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org SkASSERT(this->isClipEmpty()); 1636ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com return; 1637ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com } 1638ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com 1639819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com SkIRect ir; 1640819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com ir.set(0, 0, device->width(), device->height()); 16410017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com SkRasterClip tmpClip(ir); 1642819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 164380214e26c57c5fea954006400852e8999e201923robertphillips@google.com SkClipStack::B2TIter iter(fClipStack); 16448182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const SkClipStack::Element* element; 16458182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com while ((element = iter.next()) != NULL) { 16468182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com switch (element->getType()) { 16478182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kRect_Type: 16488182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com element->getRect().round(&ir); 16498182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com tmpClip.op(ir, element->getOp()); 16508182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 16518182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kEmpty_Type: 16528182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com tmpClip.setEmpty(); 16538182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 16549cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org default: { 16559cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org SkPath path; 16569cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org element->asPath(&path); 16578f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com clip_path_helper(this, &tmpClip, path, element->getOp(), element->isAA()); 16589cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org break; 16599cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org } 1660819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com } 1661819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com } 1662819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com} 1663819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com#endif 1664819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 166590c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.comvoid SkCanvas::replayClips(ClipVisitor* visitor) const { 166680214e26c57c5fea954006400852e8999e201923robertphillips@google.com SkClipStack::B2TIter iter(fClipStack); 16678182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const SkClipStack::Element* element; 16688182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com 16698182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com while ((element = iter.next()) != NULL) { 1670c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita element->replay(visitor); 167190c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com } 167290c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com} 167390c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com 16745c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com/////////////////////////////////////////////////////////////////////////////// 16755c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 1676754de5f65b466f721d952a379194cc94de376f42reed@google.combool SkCanvas::isClipEmpty() const { 1677754de5f65b466f721d952a379194cc94de376f42reed@google.com return fMCRec->fRasterClip->isEmpty(); 1678754de5f65b466f721d952a379194cc94de376f42reed@google.com} 1679754de5f65b466f721d952a379194cc94de376f42reed@google.com 16805c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.orgbool SkCanvas::isClipRect() const { 16815c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org return fMCRec->fRasterClip->isRect(); 16825c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org} 16835c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org 16843b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::quickReject(const SkRect& rect) const { 1685116b2bcd2c4c4d4670c7b7e2ea597414713c37fbwjmaclean@chromium.org 16861607863b608b7db6c813228768ed5d72997bbc82reed@google.com if (!rect.isFinite()) 1687116b2bcd2c4c4d4670c7b7e2ea597414713c37fbwjmaclean@chromium.org return true; 1688116b2bcd2c4c4d4670c7b7e2ea597414713c37fbwjmaclean@chromium.org 16890017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com if (fMCRec->fRasterClip->isEmpty()) { 16908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 16918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 16928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16938d430185e08d2067584837a76b7193b803fee7a0tomhudson@google.com if (fMCRec->fMatrix->hasPerspective()) { 1694a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com SkRect dst; 1695a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com fMCRec->fMatrix->mapRect(&dst, rect); 1696a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com SkIRect idst; 1697a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com dst.roundOut(&idst); 16980017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com return !SkIRect::Intersects(idst, fMCRec->fRasterClip->getBounds()); 1699a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com } else { 1700c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com const SkRect& clipR = this->getLocalClipBounds(); 1701d252db03d9650013b545ef9781fe993c07f8f314reed@android.com 1702a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com // for speed, do the most likely reject compares first 1703c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com // TODO: should we use | instead, or compare all 4 at once? 1704c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com if (rect.fTop >= clipR.fBottom || rect.fBottom <= clipR.fTop) { 1705a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com return true; 1706a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com } 1707c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com if (rect.fLeft >= clipR.fRight || rect.fRight <= clipR.fLeft) { 1708a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com return true; 1709a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com } 1710a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com return false; 17118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 17128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17143b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::quickReject(const SkPath& path) const { 17153b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com return path.isEmpty() || this->quickReject(path.getBounds()); 17168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17183b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::getClipBounds(SkRect* bounds) const { 1719bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect ibounds; 17208f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!this->getClipDeviceBounds(&ibounds)) { 17218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 17228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 17238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1724d9c0f0b57affec7a472879c5919acac6637d926areed@android.com SkMatrix inverse; 1725d9c0f0b57affec7a472879c5919acac6637d926areed@android.com // if we can't invert the CTM, we can't return local clip bounds 1726d9c0f0b57affec7a472879c5919acac6637d926areed@android.com if (!fMCRec->fMatrix->invert(&inverse)) { 172772dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com if (bounds) { 172872dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com bounds->setEmpty(); 172972dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com } 1730d9c0f0b57affec7a472879c5919acac6637d926areed@android.com return false; 1731d9c0f0b57affec7a472879c5919acac6637d926areed@android.com } 1732d9c0f0b57affec7a472879c5919acac6637d926areed@android.com 17338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL != bounds) { 1734bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkRect r; 17353b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com // adjust it outwards in case we are antialiasing 17363b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com const int inset = 1; 1737fa4d5bd09f8f1a4a92b5ae0324800dd672760898reed@google.com 17388f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com r.iset(ibounds.fLeft - inset, ibounds.fTop - inset, 17398f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com ibounds.fRight + inset, ibounds.fBottom + inset); 17408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inverse.mapRect(bounds, r); 17418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 17428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 17438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1745bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.combool SkCanvas::getClipDeviceBounds(SkIRect* bounds) const { 17460017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com const SkRasterClip& clip = *fMCRec->fRasterClip; 1747bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (clip.isEmpty()) { 1748bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (bounds) { 1749bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com bounds->setEmpty(); 1750bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1751bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com return false; 1752bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1753bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com 1754bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (NULL != bounds) { 1755bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com *bounds = clip.getBounds(); 1756bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1757bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com return true; 1758bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com} 1759bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com 17608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkMatrix& SkCanvas::getTotalMatrix() const { 17618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return *fMCRec->fMatrix; 17628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17645c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org#ifdef SK_SUPPORT_LEGACY_GETCLIPTYPE 1765bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.comSkCanvas::ClipType SkCanvas::getClipType() const { 17668f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (fMCRec->fRasterClip->isEmpty()) { 17678f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com return kEmpty_ClipType; 17688f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 17698f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (fMCRec->fRasterClip->isRect()) { 17708f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com return kRect_ClipType; 17718f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 1772bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com return kComplex_ClipType; 1773bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com} 17745c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org#endif 1775bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com 17765c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org#ifdef SK_SUPPORT_LEGACY_GETTOTALCLIP 17778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkRegion& SkCanvas::getTotalClip() const { 17780017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com return fMCRec->fRasterClip->forceGetBW(); 17798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17805c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org#endif 17815c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org 17825c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.orgconst SkRegion& SkCanvas::internal_private_getTotalClip() const { 17835c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org return fMCRec->fRasterClip->forceGetBW(); 17845c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org} 17855c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org 17865c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.orgvoid SkCanvas::internal_private_getTotalClipAsPath(SkPath* path) const { 17875c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org path->reset(); 17885c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org 17895c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org const SkRegion& rgn = fMCRec->fRasterClip->forceGetBW(); 17905c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org if (rgn.isEmpty()) { 17915c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org return; 17925c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org } 17935c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org (void)rgn.getBoundaryPath(path); 17945c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org} 17958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17969c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.comGrRenderTarget* SkCanvas::internal_private_accessTopLayerRenderTarget() { 17979c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com SkBaseDevice* dev = this->getTopDevice(); 17989c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com return dev ? dev->accessRenderTarget() : NULL; 17999c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 18009c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 180115a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.orgSkBaseDevice* SkCanvas::createLayerDevice(const SkImageInfo& info) { 18021f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* device = this->getTopDevice(); 180315a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org return device ? device->createCompatibleDeviceForSaveLayer(info) : NULL; 18048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1806644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.orgGrContext* SkCanvas::getGrContext() { 1807644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#if SK_SUPPORT_GPU 1808644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org SkBaseDevice* device = this->getTopDevice(); 1809644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org if (NULL != device) { 1810644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org GrRenderTarget* renderTarget = device->accessRenderTarget(); 1811644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org if (NULL != renderTarget) { 1812644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org return renderTarget->getContext(); 1813644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org } 1814644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org } 1815644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#endif 1816644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org 1817644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org return NULL; 1818644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org 1819644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org} 1820e97f0856a8044866b12527819d14cdfbcdfd96f2bsalomon@google.com 1821ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.orgvoid SkCanvas::drawDRRect(const SkRRect& outer, const SkRRect& inner, 1822ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkPaint& paint) { 1823ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (outer.isEmpty()) { 1824ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 1825ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 1826ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (inner.isEmpty()) { 1827ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->drawRRect(outer, paint); 1828ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 1829ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 1830ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 1831ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // We don't have this method (yet), but technically this is what we should 1832ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // be able to assert... 1833ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // SkASSERT(outer.contains(inner)); 1834ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // 1835ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // For now at least check for containment of bounds 1836ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org SkASSERT(outer.getBounds().contains(inner.getBounds())); 1837ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 1838ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->onDrawDRRect(outer, inner, paint); 1839ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org} 1840ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 18418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 18428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// These are the virtual drawing methods 18438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 18448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18452a98181f048c11f21f52fbd99f803f5fd6118261reed@google.comvoid SkCanvas::clear(SkColor color) { 18462a98181f048c11f21f52fbd99f803f5fd6118261reed@google.com SkDrawIter iter(this); 1847995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org this->predrawNotify(); 18482a98181f048c11f21f52fbd99f803f5fd6118261reed@google.com while (iter.next()) { 18492a98181f048c11f21f52fbd99f803f5fd6118261reed@google.com iter.fDevice->clear(color); 18502a98181f048c11f21f52fbd99f803f5fd6118261reed@google.com } 18512a98181f048c11f21f52fbd99f803f5fd6118261reed@google.com} 18522a98181f048c11f21f52fbd99f803f5fd6118261reed@google.com 185328361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.orgvoid SkCanvas::onDiscard() { 185428361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org if (NULL != fSurfaceBase) { 185528361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org fSurfaceBase->aboutToDraw(SkSurface::kDiscard_ContentChangeMode); 185628361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org } 185728361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org} 185828361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org 18598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPaint(const SkPaint& paint) { 1860fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->internalDrawPaint(paint); 1861fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com} 1862fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com 1863fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.comvoid SkCanvas::internalDrawPaint(const SkPaint& paint) { 186478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPaint_Type, NULL) 18658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 18674e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPaint(iter, looper.paint()); 18688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18704e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 18718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPoints(PointMode mode, size_t count, const SkPoint pts[], 18748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 18758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if ((long)count <= 0) { 18768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 18778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 187978cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect r, storage; 188078cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 1881a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com if (paint.canComputeFastBounds()) { 1882a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com // special-case 2 points (common for drawing a single line) 1883a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com if (2 == count) { 1884a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com r.set(pts[0], pts[1]); 1885a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } else { 1886a8c7f7702fb4bbedb615031bc653c5cd161a038ecommit-bot@chromium.org r.set(pts, SkToInt(count)); 1887a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } 188878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint.computeFastStrokeBounds(r, &storage); 188978cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (this->quickReject(*bounds)) { 1890a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com return; 1891a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } 1892fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 1893a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com 18948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(pts != NULL); 18958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 189678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPoint_Type, bounds) 18974b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 18988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 18994e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPoints(iter, mode, count, pts, looper.paint()); 19008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 19014b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 19024e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 19038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 19048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19057ce564cccb246ec56427085872b2e1458fe74bd1bsalomon@google.comvoid SkCanvas::drawRect(const SkRect& r, const SkPaint& paint) { 190678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 190778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 19088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.canComputeFastBounds()) { 190978cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint.computeFastBounds(r, &storage); 191078cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (this->quickReject(*bounds)) { 19118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 19128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 19138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 19144b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 191578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kRect_Type, bounds) 19168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 19184e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawRect(iter, r, looper.paint()); 19198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 19208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19214e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 19228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 19238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19244ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.comvoid SkCanvas::drawOval(const SkRect& oval, const SkPaint& paint) { 192578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 192678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 19274ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (paint.canComputeFastBounds()) { 192878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint.computeFastBounds(oval, &storage); 192978cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (this->quickReject(*bounds)) { 19304ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com return; 19314ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 19324ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 1933306ab9d5de38f2a547fd1d69aedbe69b5c6617ccskia.committer@gmail.com 193478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, bounds) 193546d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com 193646d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com while (iter.next()) { 193746d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com iter.fDevice->drawOval(iter, oval, looper.paint()); 193846d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com } 193946d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com 194046d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com LOOPER_END 19414ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 19424ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 19434ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.comvoid SkCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) { 194478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 194578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 19464ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (paint.canComputeFastBounds()) { 194778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint.computeFastBounds(rrect.getBounds(), &storage); 194878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (this->quickReject(*bounds)) { 19494ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com return; 19504ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 19514ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 19524ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 19534ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (rrect.isRect()) { 19544ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com // call the non-virtual version 19554ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->SkCanvas::drawRect(rrect.getBounds(), paint); 1956f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org return; 1957f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } else if (rrect.isOval()) { 19584ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com // call the non-virtual version 1959f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org this->SkCanvas::drawOval(rrect.getBounds(), paint); 1960f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org return; 19614ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 1962f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 196378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) 1964f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 1965f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org while (iter.next()) { 1966f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org iter.fDevice->drawRRect(iter, rrect, looper.paint()); 1967f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } 1968f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 1969f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org LOOPER_END 19704ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 19714ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 1972ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.orgvoid SkCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, 1973ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkPaint& paint) { 1974ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org SkRect storage; 1975ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkRect* bounds = NULL; 1976ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (paint.canComputeFastBounds()) { 1977ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org bounds = &paint.computeFastBounds(outer.getBounds(), &storage); 1978ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (this->quickReject(*bounds)) { 1979ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 1980ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 1981ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 198225c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 1983ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) 198425c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 1985ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org while (iter.next()) { 1986ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org iter.fDevice->drawDRRect(iter, outer, inner, looper.paint()); 1987ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 198825c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 1989ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org LOOPER_END 1990ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org} 19914ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 19927ce564cccb246ec56427085872b2e1458fe74bd1bsalomon@google.comvoid SkCanvas::drawPath(const SkPath& path, const SkPaint& paint) { 19939364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com if (!path.isFinite()) { 19949364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com return; 19959364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com } 19969364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com 199778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 199878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 1999fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com if (!path.isInverseFillType() && paint.canComputeFastBounds()) { 200078cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect& pathBounds = path.getBounds(); 200178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint.computeFastBounds(pathBounds, &storage); 200278cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (this->quickReject(*bounds)) { 20038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 20048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 20058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 20060b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org 20070b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org const SkRect& r = path.getBounds(); 20080b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org if (r.width() <= 0 && r.height() <= 0) { 20096803c219dd3be4a73e7bb5c4bb8a5b1f803624d0commit-bot@chromium.org if (path.isInverseFillType()) { 2010fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->internalDrawPaint(paint); 2011fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 2012fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com return; 2013fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 20148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 201578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, bounds) 20168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 20184e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPath(iter, path, looper.paint()); 20198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 20208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20214e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 20228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 20238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y, 20258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* paint) { 20268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(bitmap.validate();) 20278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20283d60812865bb034851da777a91413ab584929887reed@google.com if (NULL == paint || paint->canComputeFastBounds()) { 20299efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com SkRect bounds = { 20309efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com x, y, 20319efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com x + SkIntToScalar(bitmap.width()), 20329efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com y + SkIntToScalar(bitmap.height()) 20339efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com }; 20349efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com if (paint) { 20359efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com (void)paint->computeFastBounds(bounds, &bounds); 20369efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com } 20373b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(bounds)) { 20388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 20398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 20408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 20414b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 20428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 20438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.setTranslate(x, y); 20449bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com this->internalDrawBitmap(bitmap, matrix, paint); 20458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 20468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20479987ec3791336bad6af5cbe513564786b2df55aareed@google.com// this one is non-virtual, so it can be called safely by other canvas apis 20487112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.comvoid SkCanvas::internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, 2049eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org const SkRect& dst, const SkPaint* paint, 2050eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org DrawBitmapRectFlags flags) { 205150b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org if (bitmap.drawsNothing() || dst.isEmpty()) { 20528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 20538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 205474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2055ea033606a06d05d2d42aa7118409fee798e53167reed@google.com CHECK_LOCKCOUNT_BALANCE(bitmap); 2056ea033606a06d05d2d42aa7118409fee798e53167reed@google.com 205778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 205878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = &dst; 20593d60812865bb034851da777a91413ab584929887reed@google.com if (NULL == paint || paint->canComputeFastBounds()) { 20609efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com if (paint) { 20619efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com bounds = &paint->computeFastBounds(dst, &storage); 20629efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com } 20633b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(*bounds)) { 20643d60812865bb034851da777a91413ab584929887reed@google.com return; 20653d60812865bb034851da777a91413ab584929887reed@google.com } 20668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 20673d60812865bb034851da777a91413ab584929887reed@google.com 206833535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com SkLazyPaint lazy; 206933535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com if (NULL == paint) { 207033535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com paint = lazy.init(); 20718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 20727064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 207378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) 20747064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 207533535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com while (iter.next()) { 2076eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org iter.fDevice->drawBitmapRect(iter, bitmap, src, dst, looper.paint(), flags); 2077f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 20787064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 207933535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com LOOPER_END 20808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 20818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20827112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.comvoid SkCanvas::drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src, 2083eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org const SkRect& dst, const SkPaint* paint, 2084eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org DrawBitmapRectFlags flags) { 20859987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkDEBUGCODE(bitmap.validate();) 2086eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org this->internalDrawBitmapRect(bitmap, src, dst, paint, flags); 20879987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 20889987ec3791336bad6af5cbe513564786b2df55aareed@google.com 20898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& matrix, 20908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* paint) { 20918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(bitmap.validate();) 20929bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com this->internalDrawBitmap(bitmap, matrix, paint); 20938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 20948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20959987ec3791336bad6af5cbe513564786b2df55aareed@google.comvoid SkCanvas::internalDrawBitmapNine(const SkBitmap& bitmap, 20969987ec3791336bad6af5cbe513564786b2df55aareed@google.com const SkIRect& center, const SkRect& dst, 20979987ec3791336bad6af5cbe513564786b2df55aareed@google.com const SkPaint* paint) { 209850b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org if (bitmap.drawsNothing()) { 209950b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org return; 210050b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org } 21013d60812865bb034851da777a91413ab584929887reed@google.com if (NULL == paint || paint->canComputeFastBounds()) { 210260abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com SkRect storage; 210360abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com const SkRect* bounds = &dst; 210460abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com if (paint) { 210560abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com bounds = &paint->computeFastBounds(dst, &storage); 210660abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com } 21073b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(*bounds)) { 21083d60812865bb034851da777a91413ab584929887reed@google.com return; 21093d60812865bb034851da777a91413ab584929887reed@google.com } 21103d60812865bb034851da777a91413ab584929887reed@google.com } 21113d60812865bb034851da777a91413ab584929887reed@google.com 21129987ec3791336bad6af5cbe513564786b2df55aareed@google.com const int32_t w = bitmap.width(); 21139987ec3791336bad6af5cbe513564786b2df55aareed@google.com const int32_t h = bitmap.height(); 21149987ec3791336bad6af5cbe513564786b2df55aareed@google.com 21159987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkIRect c = center; 21169987ec3791336bad6af5cbe513564786b2df55aareed@google.com // pin center to the bounds of the bitmap 21179987ec3791336bad6af5cbe513564786b2df55aareed@google.com c.fLeft = SkMax32(0, center.fLeft); 21189987ec3791336bad6af5cbe513564786b2df55aareed@google.com c.fTop = SkMax32(0, center.fTop); 21199987ec3791336bad6af5cbe513564786b2df55aareed@google.com c.fRight = SkPin32(center.fRight, c.fLeft, w); 21209987ec3791336bad6af5cbe513564786b2df55aareed@google.com c.fBottom = SkPin32(center.fBottom, c.fTop, h); 21219987ec3791336bad6af5cbe513564786b2df55aareed@google.com 21227112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com const SkScalar srcX[4] = { 21237d474f8a84a74421bd8d119124daa64ec1710f76rmistry@google.com 0, SkIntToScalar(c.fLeft), SkIntToScalar(c.fRight), SkIntToScalar(w) 21247112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com }; 21257112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com const SkScalar srcY[4] = { 21267d474f8a84a74421bd8d119124daa64ec1710f76rmistry@google.com 0, SkIntToScalar(c.fTop), SkIntToScalar(c.fBottom), SkIntToScalar(h) 21277112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com }; 21289987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkScalar dstX[4] = { 21299987ec3791336bad6af5cbe513564786b2df55aareed@google.com dst.fLeft, dst.fLeft + SkIntToScalar(c.fLeft), 21309987ec3791336bad6af5cbe513564786b2df55aareed@google.com dst.fRight - SkIntToScalar(w - c.fRight), dst.fRight 21319987ec3791336bad6af5cbe513564786b2df55aareed@google.com }; 21329987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkScalar dstY[4] = { 21339987ec3791336bad6af5cbe513564786b2df55aareed@google.com dst.fTop, dst.fTop + SkIntToScalar(c.fTop), 21349987ec3791336bad6af5cbe513564786b2df55aareed@google.com dst.fBottom - SkIntToScalar(h - c.fBottom), dst.fBottom 21359987ec3791336bad6af5cbe513564786b2df55aareed@google.com }; 213674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 21379987ec3791336bad6af5cbe513564786b2df55aareed@google.com if (dstX[1] > dstX[2]) { 21389987ec3791336bad6af5cbe513564786b2df55aareed@google.com dstX[1] = dstX[0] + (dstX[3] - dstX[0]) * c.fLeft / (w - c.width()); 21399987ec3791336bad6af5cbe513564786b2df55aareed@google.com dstX[2] = dstX[1]; 21409987ec3791336bad6af5cbe513564786b2df55aareed@google.com } 214174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 21429987ec3791336bad6af5cbe513564786b2df55aareed@google.com if (dstY[1] > dstY[2]) { 21439987ec3791336bad6af5cbe513564786b2df55aareed@google.com dstY[1] = dstY[0] + (dstY[3] - dstY[0]) * c.fTop / (h - c.height()); 21449987ec3791336bad6af5cbe513564786b2df55aareed@google.com dstY[2] = dstY[1]; 21459987ec3791336bad6af5cbe513564786b2df55aareed@google.com } 214674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 21479987ec3791336bad6af5cbe513564786b2df55aareed@google.com for (int y = 0; y < 3; y++) { 21487112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com SkRect s, d; 21497112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com 21509987ec3791336bad6af5cbe513564786b2df55aareed@google.com s.fTop = srcY[y]; 21519987ec3791336bad6af5cbe513564786b2df55aareed@google.com s.fBottom = srcY[y+1]; 21529987ec3791336bad6af5cbe513564786b2df55aareed@google.com d.fTop = dstY[y]; 21539987ec3791336bad6af5cbe513564786b2df55aareed@google.com d.fBottom = dstY[y+1]; 21549987ec3791336bad6af5cbe513564786b2df55aareed@google.com for (int x = 0; x < 3; x++) { 21559987ec3791336bad6af5cbe513564786b2df55aareed@google.com s.fLeft = srcX[x]; 21569987ec3791336bad6af5cbe513564786b2df55aareed@google.com s.fRight = srcX[x+1]; 21579987ec3791336bad6af5cbe513564786b2df55aareed@google.com d.fLeft = dstX[x]; 21589987ec3791336bad6af5cbe513564786b2df55aareed@google.com d.fRight = dstX[x+1]; 2159eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org this->internalDrawBitmapRect(bitmap, &s, d, paint, 216031acc11977815402e4ef2681350f8559285bec97robertphillips@google.com kNone_DrawBitmapRectFlag); 21619987ec3791336bad6af5cbe513564786b2df55aareed@google.com } 21629987ec3791336bad6af5cbe513564786b2df55aareed@google.com } 21639987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 21649987ec3791336bad6af5cbe513564786b2df55aareed@google.com 21659987ec3791336bad6af5cbe513564786b2df55aareed@google.comvoid SkCanvas::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, 21669987ec3791336bad6af5cbe513564786b2df55aareed@google.com const SkRect& dst, const SkPaint* paint) { 21679987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkDEBUGCODE(bitmap.validate();) 21689987ec3791336bad6af5cbe513564786b2df55aareed@google.com 21699987ec3791336bad6af5cbe513564786b2df55aareed@google.com // Need a device entry-point, so gpu can use a mesh 21709987ec3791336bad6af5cbe513564786b2df55aareed@google.com this->internalDrawBitmapNine(bitmap, center, dst, paint); 21719987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 21729987ec3791336bad6af5cbe513564786b2df55aareed@google.com 2173f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.comclass SkDeviceFilteredPaint { 2174f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.compublic: 21751f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkDeviceFilteredPaint(SkBaseDevice* device, const SkPaint& paint) { 21761f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice::TextFlags flags; 2177f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com if (device->filterTextFlags(paint, &flags)) { 2178a076e9be17654a60310e72c4f70fcd5337f56dbfreed@google.com SkPaint* newPaint = fLazy.set(paint); 2179f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com newPaint->setFlags(flags.fFlags); 2180f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com newPaint->setHinting(flags.fHinting); 2181f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com fPaint = newPaint; 2182f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } else { 2183f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com fPaint = &paint; 2184f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } 2185f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } 2186f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 2187f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com const SkPaint& paint() const { return *fPaint; } 2188f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 2189f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.comprivate: 21902c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint* fPaint; 21912c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkLazyPaint fLazy; 2192f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com}; 2193f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 219452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.comvoid SkCanvas::DrawRect(const SkDraw& draw, const SkPaint& paint, 219552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com const SkRect& r, SkScalar textSize) { 219617b78946096265d80215a6c946286ecaa35ea7edepoger@google.com if (paint.getStyle() == SkPaint::kFill_Style) { 219752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com draw.fDevice->drawRect(draw, r, paint); 219852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } else { 219952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPaint p(paint); 220017b78946096265d80215a6c946286ecaa35ea7edepoger@google.com p.setStrokeWidth(SkScalarMul(textSize, paint.getStrokeWidth())); 220152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com draw.fDevice->drawRect(draw, r, p); 220252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 220352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com} 220452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 220552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.comvoid SkCanvas::DrawTextDecorations(const SkDraw& draw, const SkPaint& paint, 220652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com const char text[], size_t byteLength, 220752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar x, SkScalar y) { 220852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkASSERT(byteLength == 0 || text != NULL); 220952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 221052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com // nothing to draw 221152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (text == NULL || byteLength == 0 || 221252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com draw.fClip->isEmpty() || 221352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com (paint.getAlpha() == 0 && paint.getXfermode() == NULL)) { 221452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com return; 221552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 221652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 221752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar width = 0; 221852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPoint start; 221952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 222052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.set(0, 0); // to avoid warning 222152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (paint.getFlags() & (SkPaint::kUnderlineText_Flag | 222252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPaint::kStrikeThruText_Flag)) { 222352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com width = paint.measureText(text, byteLength); 222452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 222552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar offsetX = 0; 222652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (paint.getTextAlign() == SkPaint::kCenter_Align) { 222752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com offsetX = SkScalarHalf(width); 222852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } else if (paint.getTextAlign() == SkPaint::kRight_Align) { 222952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com offsetX = width; 223052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 223152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.set(x - offsetX, y); 223252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 223352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 223452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (0 == width) { 223552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com return; 223652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 223752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 223852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com uint32_t flags = paint.getFlags(); 223952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 224052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (flags & (SkPaint::kUnderlineText_Flag | 224152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPaint::kStrikeThruText_Flag)) { 224252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar textSize = paint.getTextSize(); 224352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar height = SkScalarMul(textSize, kStdUnderline_Thickness); 224452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkRect r; 224552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 224652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fLeft = start.fX; 224752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fRight = start.fX + width; 224852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 224952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (flags & SkPaint::kUnderlineText_Flag) { 225052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar offset = SkScalarMulAdd(textSize, kStdUnderline_Offset, 225152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.fY); 225252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fTop = offset; 225352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fBottom = offset + height; 225452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com DrawRect(draw, paint, r, textSize); 225552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 225652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (flags & SkPaint::kStrikeThruText_Flag) { 225752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar offset = SkScalarMulAdd(textSize, kStdStrikeThru_Offset, 225852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.fY); 225952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fTop = offset; 226052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fBottom = offset + height; 226152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com DrawRect(draw, paint, r, textSize); 226252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 226352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 226452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com} 226552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 2266e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 2267e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 226878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL) 22698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 22714e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 2272f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com iter.fDevice->drawText(iter, text, byteLength, x, y, dfp.paint()); 227352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com DrawTextDecorations(iter, dfp.paint(), 227452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com static_cast<const char*>(text), byteLength, x, y); 22758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 22768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22774e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 22788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 22798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2280e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], 2281e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 228278cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL) 228387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 22848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 22854e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 22868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawPosText(iter, text, byteLength, &pos->fX, 0, 2, 2287f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com dfp.paint()); 22888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2289b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 22904e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 22918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 22928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2293e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], 2294e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com SkScalar constY, const SkPaint& paint) { 229578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL) 229687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 22978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 22984e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 22998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawPosText(iter, text, byteLength, xpos, constY, 1, 2300f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com dfp.paint()); 23018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2302b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 23034e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 23048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2306e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 2307e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkMatrix* matrix, const SkPaint& paint) { 230878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL) 230987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 23108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 23118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawTextOnPath(iter, text, byteLength, path, 23124e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com matrix, looper.paint()); 23138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2314b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 2315945ec3a2bec668ca845071a65df8ec55e8f43819commit-bot@chromium.org LOOPER_END 23164325d114a5679e46f25ae75b0e43547fd7694998commit-bot@chromium.org} 23174325d114a5679e46f25ae75b0e43547fd7694998commit-bot@chromium.org 2318e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com// These will become non-virtual, so they always call the (virtual) onDraw... method 2319e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 2320e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 2321e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawText(text, byteLength, x, y, paint); 2322e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2323e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawPosText(const void* text, size_t byteLength, const SkPoint pos[], 2324e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 2325e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawPosText(text, byteLength, pos, paint); 2326e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2327e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], 2328e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com SkScalar constY, const SkPaint& paint) { 2329e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawPosTextH(text, byteLength, xpos, constY, paint); 2330e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2331e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 2332e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkMatrix* matrix, const SkPaint& paint) { 2333e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawTextOnPath(text, byteLength, path, matrix, paint); 2334e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2335e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com 23368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawVertices(VertexMode vmode, int vertexCount, 23378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPoint verts[], const SkPoint texs[], 23388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkColor colors[], SkXfermode* xmode, 23398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint16_t indices[], int indexCount, 23408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 234178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, NULL) 23424b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 23438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 23448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawVertices(iter, vmode, vertexCount, verts, texs, 23454e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com colors, xmode, indices, indexCount, 23464e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com looper.paint()); 23478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23484b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 23494e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 23508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 23538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// These methods are NOT virtual, and therefore must call back into virtual 23548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// methods, rather than actually drawing themselves. 23558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 23568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b, 2358845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com SkXfermode::Mode mode) { 23598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 23608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setARGB(a, r, g, b); 2362845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com if (SkXfermode::kSrcOver_Mode != mode) { 23630baf19375466cfc24c96532df406e7c5b1d1aae8reed@android.com paint.setXfermodeMode(mode); 23648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPaint(paint); 23668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2368845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.comvoid SkCanvas::drawColor(SkColor c, SkXfermode::Mode mode) { 23698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 23708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setColor(c); 2372845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com if (SkXfermode::kSrcOver_Mode != mode) { 23730baf19375466cfc24c96532df406e7c5b1d1aae8reed@android.com paint.setXfermodeMode(mode); 23748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPaint(paint); 23768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPoint(SkScalar x, SkScalar y, const SkPaint& paint) { 23798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pt; 23804b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 23818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pt.set(x, y); 23828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kPoints_PointMode, 1, &pt, paint); 23838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPoint(SkScalar x, SkScalar y, SkColor color) { 23868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pt; 23878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 23884b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 23898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pt.set(x, y); 23908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setColor(color); 23918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kPoints_PointMode, 1, &pt, paint); 23928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, 23958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 23968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pts[2]; 23974b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 23988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pts[0].set(x0, y0); 23998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pts[1].set(x1, y1); 24008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kLines_PointMode, 2, pts, paint); 24018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawRectCoords(SkScalar left, SkScalar top, 24048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar right, SkScalar bottom, 24058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 24068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 24078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.set(left, top, right, bottom); 24098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawRect(r, paint); 24108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, 24138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 24148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (radius < 0) { 24158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com radius = 0; 24168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 24178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 24198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.set(cx - radius, cy - radius, cx + radius, cy + radius); 24204ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->drawOval(r, paint); 24218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawRoundRect(const SkRect& r, SkScalar rx, SkScalar ry, 24248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 24258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (rx > 0 && ry > 0) { 24268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.canComputeFastBounds()) { 24278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect storage; 24283b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(paint.computeFastBounds(r, &storage))) { 24298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 24308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 24318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 24324ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com SkRRect rrect; 24334ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com rrect.setRectXY(r, rx, ry); 24344ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->drawRRect(rrect, paint); 24358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 24368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawRect(r, paint); 24378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 24388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawArc(const SkRect& oval, SkScalar startAngle, 24418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar sweepAngle, bool useCenter, 24428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 24438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (SkScalarAbs(sweepAngle) >= SkIntToScalar(360)) { 24448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawOval(oval, paint); 24458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 24468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath path; 24478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (useCenter) { 24488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.moveTo(oval.centerX(), oval.centerY()); 24498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 24508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.arcTo(oval, startAngle, sweepAngle, !useCenter); 24518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (useCenter) { 24528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.close(); 24538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 24548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPath(path, paint); 24558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 24568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawTextOnPathHV(const void* text, size_t byteLength, 24598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPath& path, SkScalar hOffset, 24608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar vOffset, const SkPaint& paint) { 24618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 24624b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 24638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.setTranslate(hOffset, vOffset); 24648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawTextOnPath(text, byteLength, path, &matrix, paint); 24658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2467f76bacff7f66724072c67edb185abf9e3add11a0reed@android.com/////////////////////////////////////////////////////////////////////////////// 24689b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillipsvoid SkCanvas::EXPERIMENTAL_optimize(const SkPicture* picture) { 2469145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org SkBaseDevice* device = this->getDevice(); 2470145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org if (NULL != device) { 2471145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org device->EXPERIMENTAL_optimize(picture); 2472145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org } 2473145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org} 2474f76bacff7f66724072c67edb185abf9e3add11a0reed@android.com 24759b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillipsvoid SkCanvas::EXPERIMENTAL_purge(const SkPicture* picture) { 2476c873329ae9ff00b0c45f7294172ad2e9b1ec44c8commit-bot@chromium.org SkBaseDevice* device = this->getTopDevice(); 2477c873329ae9ff00b0c45f7294172ad2e9b1ec44c8commit-bot@chromium.org if (NULL != device) { 2478c873329ae9ff00b0c45f7294172ad2e9b1ec44c8commit-bot@chromium.org device->EXPERIMENTAL_purge(picture); 2479c873329ae9ff00b0c45f7294172ad2e9b1ec44c8commit-bot@chromium.org } 2480c873329ae9ff00b0c45f7294172ad2e9b1ec44c8commit-bot@chromium.org} 2481c873329ae9ff00b0c45f7294172ad2e9b1ec44c8commit-bot@chromium.org 24829b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillipsvoid SkCanvas::drawPicture(const SkPicture* picture) { 24839b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips if (NULL != picture) { 24849b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips this->onDrawPicture(picture); 24859b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips } 24869b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips} 24879b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips 24889b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillipsvoid SkCanvas::onDrawPicture(const SkPicture* picture) { 24899b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips SkASSERT(NULL != picture); 24909b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips 2491145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org SkBaseDevice* device = this->getTopDevice(); 2492145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org if (NULL != device) { 2493145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org // Canvas has to first give the device the opportunity to render 2494145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org // the picture itself. 24959b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips if (device->EXPERIMENTAL_drawPicture(this, picture)) { 2496145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org return; // the device has rendered the entire picture 2497145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org } 2498145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org } 2499145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org 25009b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips picture->draw(this); 25018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 25028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 25048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 25058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::LayerIter::LayerIter(SkCanvas* canvas, bool skipEmptyClips) { 2507d642329293cce602ac24df8f585c14a98795da87reed@google.com SK_COMPILE_ASSERT(sizeof(fStorage) >= sizeof(SkDrawIter), fStorage_too_small); 25088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(canvas); 25108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fImpl = new (fStorage) SkDrawIter(canvas, skipEmptyClips); 25128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDone = !fImpl->next(); 25138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 25148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::LayerIter::~LayerIter() { 25168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fImpl->~SkDrawIter(); 25178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 25188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::LayerIter::next() { 25208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDone = !fImpl->next(); 25218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 25228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25231f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::LayerIter::device() const { 25248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fImpl->getDevice(); 25258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 25268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkMatrix& SkCanvas::LayerIter::matrix() const { 25288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fImpl->getMatrix(); 25298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 25308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkPaint& SkCanvas::LayerIter::paint() const { 25328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* paint = fImpl->getPaint(); 25338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == paint) { 25348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint = &fDefaultPaint; 25358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 25368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return *paint; 25378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 25388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkRegion& SkCanvas::LayerIter::clip() const { return fImpl->getClip(); } 25408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::LayerIter::x() const { return fImpl->getX(); } 25418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::LayerIter::y() const { return fImpl->getY(); } 254220a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com 254320a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com/////////////////////////////////////////////////////////////////////////////// 254420a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com 2545c3b589a24eb4d567a906189f882c259ecf5c2f58fmalitaSkCanvasClipVisitor::~SkCanvasClipVisitor() { } 25463107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 25473107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 25483107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 25493107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.orgstatic bool supported_for_raster_canvas(const SkImageInfo& info) { 25503107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org switch (info.alphaType()) { 25513107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kPremul_SkAlphaType: 25523107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kOpaque_SkAlphaType: 25533107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org break; 25543107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org default: 25553107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return false; 25563107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 25573107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 25583107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org switch (info.colorType()) { 25593107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kAlpha_8_SkColorType: 25603107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kRGB_565_SkColorType: 256128fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org case kN32_SkColorType: 25623107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org break; 25633107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org default: 25643107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return false; 25653107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 25663107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 25673107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return true; 25683107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org} 25693107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 25703107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.orgSkCanvas* SkCanvas::NewRaster(const SkImageInfo& info) { 25713107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org if (!supported_for_raster_canvas(info)) { 25723107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return NULL; 25733107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 25743107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 25753107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org SkBitmap bitmap; 25763107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org if (!bitmap.allocPixels(info)) { 25773107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return NULL; 25783107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 25793107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 25803107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org // should this functionality be moved into allocPixels()? 25813107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org if (!bitmap.info().isOpaque()) { 25823107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org bitmap.eraseColor(0); 25833107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 25843107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return SkNEW_ARGS(SkCanvas, (bitmap)); 25853107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org} 258642b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org 258742b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.orgSkCanvas* SkCanvas::NewRasterDirect(const SkImageInfo& info, void* pixels, size_t rowBytes) { 258842b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org if (!supported_for_raster_canvas(info)) { 258942b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org return NULL; 259042b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org } 2591eb849e5fd10cbe00cbc31307ba97fd9efca0b41bskia.committer@gmail.com 259242b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org SkBitmap bitmap; 259342b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org if (!bitmap.installPixels(info, pixels, rowBytes)) { 259442b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org return NULL; 259542b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org } 259642b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org return SkNEW_ARGS(SkCanvas, (bitmap)); 259742b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org} 2598