SkCanvas.cpp revision 8f757f540a8378c7b1354aab3d4650eaa920b17a
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 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h" 9d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed#include "SkCanvasPriv.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" 15b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr#include "SkImage.h" 1674bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org#include "SkMetaData.h" 1745a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com#include "SkPathOps.h" 18b3c9d1c33caf325aada244204215eb790c228c12dandov#include "SkPatchUtils.h" 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPicture.h" 200017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com#include "SkRasterClip.h" 214ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com#include "SkRRect.h" 2279fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org#include "SkSmallAllocator.h" 2397af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com#include "SkSurface_Base.h" 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTemplates.h" 257ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita#include "SkTextBlob.h" 2652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com#include "SkTextFormatParams.h" 27a076e9be17654a60310e72c4f70fcd5337f56dbfreed@google.com#include "SkTLazy.h" 288f757f540a8378c7b1354aab3d4650eaa920b17adanakj#include "SkTraceEvent.h" 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkUtils.h" 308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 31644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#if SK_SUPPORT_GPU 32644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#include "GrRenderTarget.h" 33644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#endif 34644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org 35da17f758442f16747af39f8fbaed9c097048519creed@google.com// experimental for faster tiled drawing... 36da17f758442f16747af39f8fbaed9c097048519creed@google.com//#define SK_ENABLE_CLIP_QUICKREJECT 3715e9d3e66e161ce23df30bc13f8a0c87d196b463robertphillips@google.com 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//#define SK_TRACE_SAVERESTORE 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_TRACE_SAVERESTORE 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gLayerCounter; 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_layer() { ++gLayerCounter; printf("----- inc layer %d\n", gLayerCounter); } 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_layer() { --gLayerCounter; printf("----- dec layer %d\n", gLayerCounter); } 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gRecCounter; 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_rec() { ++gRecCounter; printf("----- inc rec %d\n", gRecCounter); } 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_rec() { --gRecCounter; printf("----- dec rec %d\n", gRecCounter); } 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gCanvasCounter; 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_canvas() { ++gCanvasCounter; printf("----- inc canvas %d\n", gCanvasCounter); } 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_canvas() { --gCanvasCounter; printf("----- dec canvas %d\n", gCanvasCounter); } 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_layer() 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_layer() 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_rec() 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_rec() 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_canvas() 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_canvas() 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 612c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.orgtypedef SkTLazy<SkPaint> SkLazyPaint; 622c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org 6397af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.comvoid SkCanvas::predrawNotify() { 6497af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com if (fSurfaceBase) { 65c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org fSurfaceBase->aboutToDraw(SkSurface::kRetain_ContentChangeMode); 6697af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com } 6797af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com} 6897af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 714a8126e7f81384526629b1e21bf89b632ea13cd9reedstatic uint32_t filter_paint_flags(const SkSurfaceProps& props, uint32_t flags) { 724a8126e7f81384526629b1e21bf89b632ea13cd9reed const uint32_t propFlags = props.flags(); 734a8126e7f81384526629b1e21bf89b632ea13cd9reed if (propFlags & SkSurfaceProps::kDisallowDither_Flag) { 744a8126e7f81384526629b1e21bf89b632ea13cd9reed flags &= ~SkPaint::kDither_Flag; 754a8126e7f81384526629b1e21bf89b632ea13cd9reed } 764a8126e7f81384526629b1e21bf89b632ea13cd9reed if (propFlags & SkSurfaceProps::kDisallowAntiAlias_Flag) { 774a8126e7f81384526629b1e21bf89b632ea13cd9reed flags &= ~SkPaint::kAntiAlias_Flag; 784a8126e7f81384526629b1e21bf89b632ea13cd9reed } 794a8126e7f81384526629b1e21bf89b632ea13cd9reed return flags; 804a8126e7f81384526629b1e21bf89b632ea13cd9reed} 814a8126e7f81384526629b1e21bf89b632ea13cd9reed 824a8126e7f81384526629b1e21bf89b632ea13cd9reed/////////////////////////////////////////////////////////////////////////////// 834a8126e7f81384526629b1e21bf89b632ea13cd9reed 841f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com/* This is the record we keep for each SkBaseDevice that the user installs. 858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com The clip/matrix/proc are fields that reflect the top of the save/restore 868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stack. Whenever the canvas changes, it marks a dirty flag, and then before 878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com these are used (assuming we're not on a layer) we rebuild these cache 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com values: they reflect the top of the save stack, but translated and clipped 898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com by the device's XY offset and bitmap-bounds. 908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct DeviceCM { 928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* fNext; 931f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* fDevice; 94045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com SkRasterClip fClip; 958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix* fMatrix; 966f8f292aa768869a9e85c314b124875f57504f2creed@google.com SkPaint* fPaint; // may be null (in the future) 978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 98d954498c01ccf0417feacf89e45d0c62a06a813breed DeviceCM(SkBaseDevice* device, int x, int y, const SkPaint* paint, SkCanvas* canvas, 99d954498c01ccf0417feacf89e45d0c62a06a813breed bool conservativeRasterClip) 100d954498c01ccf0417feacf89e45d0c62a06a813breed : fNext(NULL) 101d954498c01ccf0417feacf89e45d0c62a06a813breed , fClip(conservativeRasterClip) 102d954498c01ccf0417feacf89e45d0c62a06a813breed { 103d954498c01ccf0417feacf89e45d0c62a06a813breed if (NULL != device) { 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device->ref(); 10540a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com device->onAttachToCanvas(canvas); 1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1074b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com fDevice = device; 1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint = paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL; 10988edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11188edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com ~DeviceCM() { 11249f085dddff10473b6ebf832a974288300224e60bsalomon if (fDevice) { 11340a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com fDevice->onDetachFromCanvas(); 1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDevice->unref(); 1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11688edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com SkDELETE(fPaint); 11788edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 1184b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 119045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com void updateMC(const SkMatrix& totalMatrix, const SkRasterClip& totalClip, 120045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com const SkClipStack& clipStack, SkRasterClip* updateClip) { 1216f8f292aa768869a9e85c314b124875f57504f2creed@google.com int x = fDevice->getOrigin().x(); 1226f8f292aa768869a9e85c314b124875f57504f2creed@google.com int y = fDevice->getOrigin().y(); 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int width = fDevice->width(); 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int height = fDevice->height(); 1254b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if ((x | y) == 0) { 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = &totalMatrix; 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fClip = totalClip; 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrixStorage = totalMatrix; 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrixStorage.postTranslate(SkIntToScalar(-x), 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIntToScalar(-y)); 1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = &fMatrixStorage; 1344b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com totalClip.translate(-x, -y, &fClip); 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 138045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com fClip.op(SkIRect::MakeWH(width, height), SkRegion::kIntersect_Op); 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // intersect clip, but don't translate it (yet) 1414b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (updateClip) { 143045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com updateClip->op(SkIRect::MakeXYWH(x, y, width, height), 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRegion::kDifference_Op); 1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1464b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 1473fffb2ee9fa01ae61efb2395973eb7575eda4c96robertphillips@google.com fDevice->setMatrixClip(*fMatrix, fClip.forceGetBW(), clipStack); 1483fffb2ee9fa01ae61efb2395973eb7575eda4c96robertphillips@google.com 1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!fClip.isEmpty()) { 1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIRect deviceR; 1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com deviceR.set(0, 0, width, height); 1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(deviceR.contains(fClip.getBounds())); 1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 156f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 157f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 1590e354aacd84d3bede3f97cbde35a54ba62a89533bsalomon@google.com SkMatrix fMatrixStorage; 1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* This is the record we keep for each save/restore level in the stack. 1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Since a level optionally copies the matrix and/or stack, we have pointers 1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for these fields. If the value is copied for this level, the copy is 1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stored in the ...Storage field, and the pointer points to that. If the 1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value is not copied for this level, we ignore ...Storage, and just point 1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com at the corresponding value in the previous level in the stack. 1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkCanvas::MCRec { 1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 1716f09709519b79a1159f3826645f1c5fbc101ee11reed SkRasterClip fRasterClip; 172d954498c01ccf0417feacf89e45d0c62a06a813breed SkMatrix fMatrix; 1731f836ee096bb988adef4b9757b2629c7afeda36dreed SkDrawFilter* fFilter; // the current filter (or null) 174d954498c01ccf0417feacf89e45d0c62a06a813breed DeviceCM* fLayer; 1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* If there are any layers in the stack, this points to the top-most 1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com one that is at or below this level in the stack (so we know what 1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bitmap/device to draw into from this level. This value is NOT 1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com reference counted, since the real owner is either our fLayer field, 1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com or a previous one in a lower level.) 1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 18188edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com DeviceCM* fTopLayer; 1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 183d954498c01ccf0417feacf89e45d0c62a06a813breed MCRec(bool conservativeRasterClip) : fRasterClip(conservativeRasterClip) { 184d954498c01ccf0417feacf89e45d0c62a06a813breed fMatrix.reset(); 185d954498c01ccf0417feacf89e45d0c62a06a813breed fFilter = NULL; 186d954498c01ccf0417feacf89e45d0c62a06a813breed fLayer = NULL; 187d954498c01ccf0417feacf89e45d0c62a06a813breed fTopLayer = NULL; 188b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 189d954498c01ccf0417feacf89e45d0c62a06a813breed // don't bother initializing fNext 190d954498c01ccf0417feacf89e45d0c62a06a813breed inc_rec(); 191d954498c01ccf0417feacf89e45d0c62a06a813breed } 192d954498c01ccf0417feacf89e45d0c62a06a813breed MCRec(const MCRec& prev) : fRasterClip(prev.fRasterClip) { 193d954498c01ccf0417feacf89e45d0c62a06a813breed fMatrix = prev.fMatrix; 194d954498c01ccf0417feacf89e45d0c62a06a813breed fFilter = SkSafeRef(prev.fFilter); 1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLayer = NULL; 196d954498c01ccf0417feacf89e45d0c62a06a813breed fTopLayer = prev.fTopLayer; 197b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // don't bother initializing fNext 1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inc_rec(); 2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ~MCRec() { 20282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fFilter); 2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDELETE(fLayer); 2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dec_rec(); 2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkDrawIter : public SkDraw { 2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 2108a0b0291ae4260ef2a46f4341c18a702c0ce3f8btomhudson@google.com SkDrawIter(SkCanvas* canvas, bool skipEmptyClips = true) { 2114370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com canvas = canvas->canvasForDrawIter(); 2128a0b0291ae4260ef2a46f4341c18a702c0ce3f8btomhudson@google.com fCanvas = canvas; 2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com canvas->updateDeviceCMCache(); 2148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21590c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com fClipStack = &canvas->fClipStack; 2168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = canvas->fMCRec->fTopLayer; 2178a0b0291ae4260ef2a46f4341c18a702c0ce3f8btomhudson@google.com fSkipEmptyClips = skipEmptyClips; 2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2194b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool next() { 2218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // skip over recs with empty clips 2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fSkipEmptyClips) { 2238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (fCurrLayer && fCurrLayer->fClip.isEmpty()) { 2248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = fCurrLayer->fNext; 2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 228f68c5e2f9f05b3af2bae0979ace2684b6041b6e3reed@google.com const DeviceCM* rec = fCurrLayer; 229f68c5e2f9f05b3af2bae0979ace2684b6041b6e3reed@google.com if (rec && rec->fDevice) { 2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = rec->fMatrix; 232045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com fClip = &((SkRasterClip*)&rec->fClip)->forceGetBW(); 233045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com fRC = &rec->fClip; 2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDevice = rec->fDevice; 2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBitmap = &fDevice->accessBitmap(true); 2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint = rec->fPaint; 237f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com SkDEBUGCODE(this->validate();) 2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = rec->fNext; 2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // fCurrLayer may be NULL now 241199f108f14a5f60a9c2205ffa79b26102a206ad0reed@android.com 2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2464b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2471f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* getDevice() const { return fDevice; } 2486f8f292aa768869a9e85c314b124875f57504f2creed@google.com int getX() const { return fDevice->getOrigin().x(); } 2496f8f292aa768869a9e85c314b124875f57504f2creed@google.com int getY() const { return fDevice->getOrigin().y(); } 2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& getMatrix() const { return *fMatrix; } 2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkRegion& getClip() const { return *fClip; } 2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* getPaint() const { return fPaint; } 2536f8f292aa768869a9e85c314b124875f57504f2creed@google.com 2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkCanvas* fCanvas; 2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const DeviceCM* fCurrLayer; 2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* fPaint; // May be null. 2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkBool8 fSkipEmptyClips; 2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef SkDraw INHERITED; 2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////// 2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass AutoDrawLooper { 2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 2674a8126e7f81384526629b1e21bf89b632ea13cd9reed AutoDrawLooper(SkCanvas* canvas, const SkSurfaceProps& props, const SkPaint& paint, 26878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bool skipLayerForImageFilter = false, 26978cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL) : fOrigPaint(paint) { 2704e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fCanvas = canvas; 2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFilter = canvas->getDrawFilter(); 2724a8126e7f81384526629b1e21bf89b632ea13cd9reed fPaint = &fOrigPaint; 2734e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fSaveCount = canvas->getSaveCount(); 2748926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com fDoClearImageFilter = false; 2754e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fDone = false; 2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2778926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com if (!skipLayerForImageFilter && fOrigPaint.getImageFilter()) { 2788926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkPaint tmp; 2798926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com tmp.setImageFilter(fOrigPaint.getImageFilter()); 280e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org (void)canvas->internalSaveLayer(bounds, &tmp, SkCanvas::kARGB_ClipLayer_SaveFlag, 281e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org true, SkCanvas::kFullLayer_SaveLayerStrategy); 2828926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com // we'll clear the imageFilter for the actual draws in next(), so 2838926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com // it will only be applied during the restore(). 2848926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com fDoClearImageFilter = true; 2858926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 2868926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 28779fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (SkDrawLooper* looper = paint.getLooper()) { 28879fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org void* buffer = fLooperContextAllocator.reserveT<SkDrawLooper::Context>( 28979fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org looper->contextSize()); 29079fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org fLooperContext = looper->createContext(canvas, buffer); 291129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fIsSimple = false; 292129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else { 29379fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org fLooperContext = NULL; 294129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // can we be marked as simple? 295129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fIsSimple = !fFilter && !fDoClearImageFilter; 2968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 297b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 2984a8126e7f81384526629b1e21bf89b632ea13cd9reed uint32_t oldFlags = paint.getFlags(); 2994a8126e7f81384526629b1e21bf89b632ea13cd9reed fNewPaintFlags = filter_paint_flags(props, oldFlags); 3004a8126e7f81384526629b1e21bf89b632ea13cd9reed if (fIsSimple && (fNewPaintFlags != oldFlags)) { 3014a8126e7f81384526629b1e21bf89b632ea13cd9reed SkPaint* paint = fLazyPaint.set(fOrigPaint); 3024a8126e7f81384526629b1e21bf89b632ea13cd9reed paint->setFlags(fNewPaintFlags); 3034a8126e7f81384526629b1e21bf89b632ea13cd9reed fPaint = paint; 3044a8126e7f81384526629b1e21bf89b632ea13cd9reed // if we're not simple, doNext() will take care of calling setFlags() 3054a8126e7f81384526629b1e21bf89b632ea13cd9reed } 3068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 30774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 3084e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com ~AutoDrawLooper() { 3098926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com if (fDoClearImageFilter) { 3108926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com fCanvas->internalRestore(); 3118926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 3124e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkASSERT(fCanvas->getSaveCount() == fSaveCount); 3138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 31474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 3154e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com const SkPaint& paint() const { 3164e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkASSERT(fPaint); 3174e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return *fPaint; 3184e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 31974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 320129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool next(SkDrawFilter::Type drawType) { 321129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com if (fDone) { 322129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return false; 323129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else if (fIsSimple) { 324129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fDone = true; 325129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return !fPaint->nothingToDraw(); 326129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else { 327129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return this->doNext(drawType); 328129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 329fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 33074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 3318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 3322c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkLazyPaint fLazyPaint; 3332c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkCanvas* fCanvas; 3342c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint& fOrigPaint; 3352c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkDrawFilter* fFilter; 3362c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint* fPaint; 3372c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org int fSaveCount; 3384a8126e7f81384526629b1e21bf89b632ea13cd9reed uint32_t fNewPaintFlags; 3398926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com bool fDoClearImageFilter; 3402c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org bool fDone; 341129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool fIsSimple; 34279fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkDrawLooper::Context* fLooperContext; 34379fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkSmallAllocator<1, 32> fLooperContextAllocator; 344129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com 345129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool doNext(SkDrawFilter::Type drawType); 3468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 348129ec22cb054592261e001294c430c9dd4e90ff4reed@google.combool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) { 349632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com fPaint = NULL; 350129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com SkASSERT(!fIsSimple); 35179fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkASSERT(fLooperContext || fFilter || fDoClearImageFilter); 352632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com 353129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com SkPaint* paint = fLazyPaint.set(fOrigPaint); 3544a8126e7f81384526629b1e21bf89b632ea13cd9reed paint->setFlags(fNewPaintFlags); 3558926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 356129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com if (fDoClearImageFilter) { 357129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com paint->setImageFilter(NULL); 358129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 3598926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 36079fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (fLooperContext && !fLooperContext->next(fCanvas, paint)) { 361129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fDone = true; 362129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return false; 363129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 364129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com if (fFilter) { 365971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com if (!fFilter->filter(paint, drawType)) { 366971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com fDone = true; 367971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com return false; 368971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com } 36979fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (NULL == fLooperContext) { 370129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // no looper means we only draw once 371632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com fDone = true; 372632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com } 373129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 374129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fPaint = paint; 3758926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 376129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // if we only came in here for the imagefilter, mark us as done 37779fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (!fLooperContext && !fFilter) { 3784e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fDone = true; 3794e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 3804e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com 381632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com // call this after any possible paint modifiers 382632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com if (fPaint->nothingToDraw()) { 3834e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fPaint = NULL; 3844e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return false; 3854e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 3864e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return true; 3874e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com} 3884e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com 3898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////// macros to place around the internal draw calls ////////////////// 3908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3918926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com#define LOOPER_BEGIN_DRAWDEVICE(paint, type) \ 39297af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com this->predrawNotify(); \ 3934a8126e7f81384526629b1e21bf89b632ea13cd9reed AutoDrawLooper looper(this, fProps, paint, true); \ 3948926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com while (looper.next(type)) { \ 3958926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkDrawIter iter(this); 3968926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 39778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org#define LOOPER_BEGIN(paint, type, bounds) \ 39897af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com this->predrawNotify(); \ 3994a8126e7f81384526629b1e21bf89b632ea13cd9reed AutoDrawLooper looper(this, fProps, paint, false, bounds); \ 4004e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com while (looper.next(type)) { \ 4018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDrawIter iter(this); 4024b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 4034e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com#define LOOPER_END } 4048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////// 4068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4074a8126e7f81384526629b1e21bf89b632ea13cd9reedvoid SkCanvas::setupDevice(SkBaseDevice* device) { 4084a8126e7f81384526629b1e21bf89b632ea13cd9reed device->setPixelGeometry(fProps.pixelGeometry()); 4094a8126e7f81384526629b1e21bf89b632ea13cd9reed} 4104a8126e7f81384526629b1e21bf89b632ea13cd9reed 411d954498c01ccf0417feacf89e45d0c62a06a813breedSkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) { 412d954498c01ccf0417feacf89e45d0c62a06a813breed fConservativeRasterClip = SkToBool(flags & kConservativeRasterClip_InitFlag); 413c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBounds.setEmpty(); 414c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 4158f0a7b8e7334187a5d7d5ab7fde5a3c3009555f5caryclark@google.com fAllowSoftClip = true; 41645a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com fAllowSimplifyClip = false; 417f92c86642a1875da54d54b447f006cb9dfbbb35creed fDeviceCMDirty = true; 418b0a7ace7cb2a7559bbc254a7c93698bc71bbd245junov@chromium.org fSaveLayerCount = 0; 419210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org fCullCount = 0; 42074bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org fMetaData = NULL; 4218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = (MCRec*)fMCStack.push_back(); 423d954498c01ccf0417feacf89e45d0c62a06a813breed new (fMCRec) MCRec(fConservativeRasterClip); 4248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 425d954498c01ccf0417feacf89e45d0c62a06a813breed fMCRec->fLayer = SkNEW_ARGS(DeviceCM, (NULL, 0, 0, NULL, NULL, fConservativeRasterClip)); 4268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fTopLayer = fMCRec->fLayer; 4278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 42897af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com fSurfaceBase = NULL; 429f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 430f92c86642a1875da54d54b447f006cb9dfbbb35creed if (device) { 4314a8126e7f81384526629b1e21bf89b632ea13cd9reed this->setupDevice(device); 4324a8126e7f81384526629b1e21bf89b632ea13cd9reed if (device->forceConservativeRasterClip()) { 4334a8126e7f81384526629b1e21bf89b632ea13cd9reed fConservativeRasterClip = true; 4344a8126e7f81384526629b1e21bf89b632ea13cd9reed } 435f92c86642a1875da54d54b447f006cb9dfbbb35creed device->onAttachToCanvas(this); 436f92c86642a1875da54d54b447f006cb9dfbbb35creed fMCRec->fLayer->fDevice = SkRef(device); 437f92c86642a1875da54d54b447f006cb9dfbbb35creed fMCRec->fRasterClip.setRect(SkIRect::MakeWH(device->width(), device->height())); 438f92c86642a1875da54d54b447f006cb9dfbbb35creed } 439f92c86642a1875da54d54b447f006cb9dfbbb35creed return device; 4408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 442cde92111d50a96b6d0f3e166fbac7c9bc6eca349reed@google.comSkCanvas::SkCanvas() 443e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 4444a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 445e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org{ 4468d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org inc_canvas(); 447ba124485687130183643994f1b4b68d629fbbebaskia.committer@gmail.com 448d954498c01ccf0417feacf89e45d0c62a06a813breed this->init(NULL, kDefault_InitFlags); 4498d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org} 4508d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org 451d954498c01ccf0417feacf89e45d0c62a06a813breedstatic SkBitmap make_nopixels(int width, int height) { 452d954498c01ccf0417feacf89e45d0c62a06a813breed SkBitmap bitmap; 453d954498c01ccf0417feacf89e45d0c62a06a813breed bitmap.setInfo(SkImageInfo::MakeUnknown(width, height)); 454d954498c01ccf0417feacf89e45d0c62a06a813breed return bitmap; 455d954498c01ccf0417feacf89e45d0c62a06a813breed} 456d954498c01ccf0417feacf89e45d0c62a06a813breed 457d954498c01ccf0417feacf89e45d0c62a06a813breedclass SkNoPixelsBitmapDevice : public SkBitmapDevice { 458d954498c01ccf0417feacf89e45d0c62a06a813breedpublic: 459d954498c01ccf0417feacf89e45d0c62a06a813breed SkNoPixelsBitmapDevice(int width, int height) : INHERITED(make_nopixels(width, height)) {} 460d954498c01ccf0417feacf89e45d0c62a06a813breed 461d954498c01ccf0417feacf89e45d0c62a06a813breedprivate: 462b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 463d954498c01ccf0417feacf89e45d0c62a06a813breed typedef SkBitmapDevice INHERITED; 464d954498c01ccf0417feacf89e45d0c62a06a813breed}; 465d954498c01ccf0417feacf89e45d0c62a06a813breed 466e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.orgSkCanvas::SkCanvas(int width, int height) 467e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 4684a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 469e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org{ 470e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org inc_canvas(); 471b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 472d954498c01ccf0417feacf89e45d0c62a06a813breed this->init(SkNEW_ARGS(SkNoPixelsBitmapDevice, (width, height)), kDefault_InitFlags)->unref(); 473d954498c01ccf0417feacf89e45d0c62a06a813breed} 474e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org 475d954498c01ccf0417feacf89e45d0c62a06a813breedSkCanvas::SkCanvas(int width, int height, InitFlags flags) 476d954498c01ccf0417feacf89e45d0c62a06a813breed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 4774a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 478d954498c01ccf0417feacf89e45d0c62a06a813breed{ 479d954498c01ccf0417feacf89e45d0c62a06a813breed inc_canvas(); 480b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 481d954498c01ccf0417feacf89e45d0c62a06a813breed this->init(SkNEW_ARGS(SkNoPixelsBitmapDevice, (width, height)), flags)->unref(); 48227a5e656c3d6ef22f9cb34de18e1b960da3aa241reed} 4838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4844a8126e7f81384526629b1e21bf89b632ea13cd9reedSkCanvas::SkCanvas(SkBaseDevice* device, const SkSurfaceProps* props, InitFlags flags) 48527a5e656c3d6ef22f9cb34de18e1b960da3aa241reed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 4864a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfacePropsCopyOrDefault(props)) 48727a5e656c3d6ef22f9cb34de18e1b960da3aa241reed{ 48827a5e656c3d6ef22f9cb34de18e1b960da3aa241reed inc_canvas(); 489b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 490d954498c01ccf0417feacf89e45d0c62a06a813breed this->init(device, flags); 491d954498c01ccf0417feacf89e45d0c62a06a813breed} 4926f09709519b79a1159f3826645f1c5fbc101ee11reed 493d954498c01ccf0417feacf89e45d0c62a06a813breedSkCanvas::SkCanvas(SkBaseDevice* device) 494d954498c01ccf0417feacf89e45d0c62a06a813breed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 4954a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 496d954498c01ccf0417feacf89e45d0c62a06a813breed{ 497d954498c01ccf0417feacf89e45d0c62a06a813breed inc_canvas(); 498b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 499d954498c01ccf0417feacf89e45d0c62a06a813breed this->init(device, kDefault_InitFlags); 5008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5024a8126e7f81384526629b1e21bf89b632ea13cd9reedSkCanvas::SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props) 5033716fd067a5621bb94a6cb08d72afec8bf3acedareed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 5044a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(props) 5053716fd067a5621bb94a6cb08d72afec8bf3acedareed{ 5063716fd067a5621bb94a6cb08d72afec8bf3acedareed inc_canvas(); 507b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 5084a8126e7f81384526629b1e21bf89b632ea13cd9reed SkAutoTUnref<SkBaseDevice> device(SkNEW_ARGS(SkBitmapDevice, (bitmap))); 5094a8126e7f81384526629b1e21bf89b632ea13cd9reed this->init(device, kDefault_InitFlags); 5104a8126e7f81384526629b1e21bf89b632ea13cd9reed} 51129c857d0f3a1cb837f73406eeb6ba9771879b5e7reed 5124a8126e7f81384526629b1e21bf89b632ea13cd9reedSkCanvas::SkCanvas(const SkBitmap& bitmap) 5134a8126e7f81384526629b1e21bf89b632ea13cd9reed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 5144a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 5154a8126e7f81384526629b1e21bf89b632ea13cd9reed{ 5164a8126e7f81384526629b1e21bf89b632ea13cd9reed inc_canvas(); 517b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 5184a8126e7f81384526629b1e21bf89b632ea13cd9reed SkAutoTUnref<SkBaseDevice> device(SkNEW_ARGS(SkBitmapDevice, (bitmap))); 5194a8126e7f81384526629b1e21bf89b632ea13cd9reed this->init(device, kDefault_InitFlags); 5208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::~SkCanvas() { 5238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // free up the contents of our deque 5248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->restoreToCount(1); // restore everything but the last 525b0a7ace7cb2a7559bbc254a7c93698bc71bbd245junov@chromium.org SkASSERT(0 == fSaveLayerCount); 5267c2029367cea5479fa3b74fb0ca2b0297b42b709reed@google.com 5278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->internalRestore(); // restore the last, since we're going away 5288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 52974bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org SkDELETE(fMetaData); 530b70ae310bbdaa1b26786773aabce5548c1f48563vandebo@chromium.org 5318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dec_canvas(); 5328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDrawFilter* SkCanvas::getDrawFilter() const { 5358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fMCRec->fFilter; 5368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDrawFilter* SkCanvas::setDrawFilter(SkDrawFilter* filter) { 5398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fMCRec->fFilter, filter); 5408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return filter; 5418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 54374bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.orgSkMetaData& SkCanvas::getMetaData() { 54474bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org // metadata users are rare, so we lazily allocate it. If that changes we 54574bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org // can decide to just make it a field in the device (rather than a ptr) 54674bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org if (NULL == fMetaData) { 54774bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org fMetaData = new SkMetaData; 54874bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org } 54974bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org return *fMetaData; 55074bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org} 55174bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org 5528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 5538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 554bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.orgvoid SkCanvas::flush() { 5551f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* device = this->getDevice(); 556bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org if (device) { 557bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org device->flush(); 558bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org } 559bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org} 560bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org 5614ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.comSkISize SkCanvas::getTopLayerSize() const { 5624ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com SkBaseDevice* d = this->getTopDevice(); 5634ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com return d ? SkISize::Make(d->width(), d->height()) : SkISize::Make(0, 0); 5644ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com} 5654ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com 5664ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.comSkIPoint SkCanvas::getTopLayerOrigin() const { 5674ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com SkBaseDevice* d = this->getTopDevice(); 5684ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com return d ? d->getOrigin() : SkIPoint::Make(0, 0); 5694ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com} 5704ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com 5714ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.comSkISize SkCanvas::getBaseLayerSize() const { 5721f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* d = this->getDevice(); 573210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com return d ? SkISize::Make(d->width(), d->height()) : SkISize::Make(0, 0); 574210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com} 575210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com 5761f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::getDevice() const { 5778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // return root device 578c029062a0312fb747fb6c2677983aba51795c580robertphillips@google.com MCRec* rec = (MCRec*) fMCStack.front(); 5798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(rec && rec->fLayer); 5808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return rec->fLayer->fDevice; 5818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5831f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::getTopDevice(bool updateMatrixClip) const { 5840b53d59a24f667350b4282f88470713902409030reed@google.com if (updateMatrixClip) { 5850b53d59a24f667350b4282f88470713902409030reed@google.com const_cast<SkCanvas*>(this)->updateDeviceCMCache(); 5860b53d59a24f667350b4282f88470713902409030reed@google.com } 5879266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com return fMCRec->fTopLayer->fDevice; 5889266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com} 5899266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com 590403f8d7a052269583175e945689824838e5e0ef4commit-bot@chromium.orgSkBaseDevice* SkCanvas::setRootDevice(SkBaseDevice* device) { 5918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // return root device 5924c09d5cd4b9e6f0be1352f62288efdedc1bc3de3reed@google.com SkDeque::F2BIter iter(fMCStack); 5934c09d5cd4b9e6f0be1352f62288efdedc1bc3de3reed@google.com MCRec* rec = (MCRec*)iter.next(); 5948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(rec && rec->fLayer); 5951f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* rootDevice = rec->fLayer->fDevice; 5968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (rootDevice == device) { 5988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return device; 5998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 6004b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 6018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (device) { 60240a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com device->onAttachToCanvas(this); 6038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 6048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (rootDevice) { 60540a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com rootDevice->onDetachFromCanvas(); 6068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 6078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(rec->fLayer->fDevice, device); 6098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rootDevice = device; 6104a8126e7f81384526629b1e21bf89b632ea13cd9reed this->setupDevice(device); 6118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 6134b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 6148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* Now we update our initial region to have the bounds of the new device, 6158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com and then intersect all of the clips in our stack with these bounds, 6168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com to ensure that we can't draw outside of the device's bounds (and trash 6178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memory). 6184b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 6198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com NOTE: this is only a partial-fix, since if the new device is larger than 6208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com the previous one, we don't know how to "enlarge" the clips in our stack, 6214b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com so drawing may be artificially restricted. Without keeping a history of 6228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com all calls to canvas->clipRect() and canvas->clipPath(), we can't exactly 6238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com reconstruct the correct clips, so this approximation will have to do. 6248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com The caller really needs to restore() back to the base if they want to 6258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com accurately take advantage of the new device bounds. 6268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 6278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 62842aea289cbf801997b653a906a37a7f7e948b645reed@google.com SkIRect bounds; 62942aea289cbf801997b653a906a37a7f7e948b645reed@google.com if (device) { 6308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bounds.set(0, 0, device->width(), device->height()); 63142aea289cbf801997b653a906a37a7f7e948b645reed@google.com } else { 63242aea289cbf801997b653a906a37a7f7e948b645reed@google.com bounds.setEmpty(); 6338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 63442aea289cbf801997b653a906a37a7f7e948b645reed@google.com // now jam our 1st clip to be bounds, and intersect the rest with that 6351f836ee096bb988adef4b9757b2629c7afeda36dreed rec->fRasterClip.setRect(bounds); 63642aea289cbf801997b653a906a37a7f7e948b645reed@google.com while ((rec = (MCRec*)iter.next()) != NULL) { 6371f836ee096bb988adef4b9757b2629c7afeda36dreed (void)rec->fRasterClip.op(bounds, SkRegion::kIntersect_Op); 63842aea289cbf801997b653a906a37a7f7e948b645reed@google.com } 63942aea289cbf801997b653a906a37a7f7e948b645reed@google.com 6408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return device; 6418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 643a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.orgbool SkCanvas::readPixels(SkBitmap* bitmap, int x, int y) { 644a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (kUnknown_SkColorType == bitmap->colorType() || bitmap->getTexture()) { 645a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 646a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 647a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 648a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bool weAllocated = false; 649a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (NULL == bitmap->pixelRef()) { 650848250415eddc54075f7eb8795e8db79e749c6abreed if (!bitmap->tryAllocPixels()) { 651a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 652a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 653a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org weAllocated = true; 654a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 655a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 656a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkBitmap bm(*bitmap); 657a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bm.lockPixels(); 658a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (bm.getPixels() && this->readPixels(bm.info(), bm.getPixels(), bm.rowBytes(), x, y)) { 659a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return true; 660a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 661a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 662a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (weAllocated) { 663a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bitmap->setPixelRef(NULL); 664a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 665a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 666a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org} 66751df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 668c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.combool SkCanvas::readPixels(const SkIRect& srcRect, SkBitmap* bitmap) { 669a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkIRect r = srcRect; 670a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 671a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!r.intersect(0, 0, size.width(), size.height())) { 672a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bitmap->reset(); 673ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com return false; 674ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com } 67574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 676848250415eddc54075f7eb8795e8db79e749c6abreed if (!bitmap->tryAllocN32Pixels(r.width(), r.height())) { 677a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org // bitmap will already be reset. 678a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 679a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 680a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!this->readPixels(bitmap->info(), bitmap->getPixels(), bitmap->rowBytes(), r.x(), r.y())) { 681a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bitmap->reset(); 682daba14b7d4fc96b915c45d82713b22729c0d0f37bsalomon@google.com return false; 683c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } 684a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return true; 685a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org} 686c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 687a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.orgbool SkCanvas::readPixels(const SkImageInfo& origInfo, void* dstP, size_t rowBytes, int x, int y) { 688a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org switch (origInfo.colorType()) { 689a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org case kUnknown_SkColorType: 690a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org case kIndex_8_SkColorType: 691a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 692a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org default: 693a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org break; 694a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 695a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (NULL == dstP || rowBytes < origInfo.minRowBytes()) { 696a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 697a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 698a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (0 == origInfo.width() || 0 == origInfo.height()) { 69951df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com return false; 70051df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com } 701a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 702a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkBaseDevice* device = this->getDevice(); 703a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!device) { 704a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 705a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 706a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 707a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 708a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkIRect srcR = SkIRect::MakeXYWH(x, y, origInfo.width(), origInfo.height()); 709a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!srcR.intersect(0, 0, size.width(), size.height())) { 710a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 711a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 712db0c8753775774aa3f67114491e26ac1be32f38eskia.committer@gmail.com 713a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org // the intersect may have shrunk info's logical size 714e5ea500d4714a7d84de2bf913e81be3b65d2de68reed const SkImageInfo info = origInfo.makeWH(srcR.width(), srcR.height()); 715db0c8753775774aa3f67114491e26ac1be32f38eskia.committer@gmail.com 716a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org // if x or y are negative, then we have to adjust pixels 717a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (x > 0) { 718a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org x = 0; 719a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 720a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (y > 0) { 721a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org y = 0; 722a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 723a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org // here x,y are either 0 or negative 724a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org dstP = ((char*)dstP - y * rowBytes - x * info.bytesPerPixel()); 725db0c8753775774aa3f67114491e26ac1be32f38eskia.committer@gmail.com 726a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org // The device can assert that the requested area is always contained in its bounds 727a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return device->readPixels(info, dstP, rowBytes, srcR.x(), srcR.y()); 72851df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com} 72951df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 7304cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgbool SkCanvas::writePixels(const SkBitmap& bitmap, int x, int y) { 7314cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (bitmap.getTexture()) { 7324cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 7334cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7344cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org SkBitmap bm(bitmap); 7354cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org bm.lockPixels(); 7364cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (bm.getPixels()) { 7374cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return this->writePixels(bm.info(), bm.getPixels(), bm.rowBytes(), x, y); 7384cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7394cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 7404cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org} 7414cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 7424cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgbool SkCanvas::writePixels(const SkImageInfo& origInfo, const void* pixels, size_t rowBytes, 7434cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org int x, int y) { 7444cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org switch (origInfo.colorType()) { 7454cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org case kUnknown_SkColorType: 7464cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org case kIndex_8_SkColorType: 7474cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 7484cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org default: 7494cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org break; 7504cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7514cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (NULL == pixels || rowBytes < origInfo.minRowBytes()) { 7524cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 7534cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7544cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 7554cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 7564cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org SkIRect target = SkIRect::MakeXYWH(x, y, origInfo.width(), origInfo.height()); 7574cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (!target.intersect(0, 0, size.width(), size.height())) { 7584cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 7594cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7604cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 7614cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org SkBaseDevice* device = this->getDevice(); 7624cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (!device) { 7634cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 7644cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7654cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 7664cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // the intersect may have shrunk info's logical size 767e5ea500d4714a7d84de2bf913e81be3b65d2de68reed const SkImageInfo info = origInfo.makeWH(target.width(), target.height()); 7684cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 7694cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // if x or y are negative, then we have to adjust pixels 7704cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (x > 0) { 7714cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org x = 0; 7724cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7734cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (y > 0) { 7744cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org y = 0; 7754cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7764cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // here x,y are either 0 or negative 7774cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org pixels = ((const char*)pixels - y * rowBytes - x * info.bytesPerPixel()); 7784cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 7794af35f348b2e2f6c428819118eb7a2f2fff53a74reed // Tell our owning surface to bump its generation ID 7804af35f348b2e2f6c428819118eb7a2f2fff53a74reed this->predrawNotify(); 7814af35f348b2e2f6c428819118eb7a2f2fff53a74reed 7824cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // The device can assert that the requested area is always contained in its bounds 7834ef54f8d72420a521d4aae04ff5cd438810eca7fcommit-bot@chromium.org return device->writePixels(info, pixels, rowBytes, target.x(), target.y()); 7844cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org} 78551df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 7864370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comSkCanvas* SkCanvas::canvasForDrawIter() { 7874370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com return this; 7884370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 7894370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 7908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 7918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::updateDeviceCMCache() { 7938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fDeviceCMDirty) { 7948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& totalMatrix = this->getTotalMatrix(); 7951f836ee096bb988adef4b9757b2629c7afeda36dreed const SkRasterClip& totalClip = fMCRec->fRasterClip; 7968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* layer = fMCRec->fTopLayer; 7974b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 7988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == layer->fNext) { // only one layer 79946799cd9f0bded51a189d77731b25af159ab4609reed@google.com layer->updateMC(totalMatrix, totalClip, fClipStack, NULL); 8008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 801045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com SkRasterClip clip(totalClip); 8028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 80346799cd9f0bded51a189d77731b25af159ab4609reed@google.com layer->updateMC(totalMatrix, clip, fClipStack, &clip); 8048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while ((layer = layer->fNext) != NULL); 8058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = false; 8078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 8118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8125f6102d07982043542343ff0a6c67b1319ac9fc7Florin Malitaint SkCanvas::internalSave() { 8138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int saveCount = this->getSaveCount(); // record this before the actual save 8144b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 8158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com MCRec* newTop = (MCRec*)fMCStack.push_back(); 816d954498c01ccf0417feacf89e45d0c62a06a813breed new (newTop) MCRec(*fMCRec); // balanced in restore() 8178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = newTop; 8184b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 8195f6102d07982043542343ff0a6c67b1319ac9fc7Florin Malita fClipStack.save(); 8205c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 8218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return saveCount; 8228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 824d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.orgint SkCanvas::save() { 8255f6102d07982043542343ff0a6c67b1319ac9fc7Florin Malita this->willSave(); 8265f6102d07982043542343ff0a6c67b1319ac9fc7Florin Malita return this->internalSave(); 8278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic bool bounds_affects_clip(SkCanvas::SaveFlags flags) { 830b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG 8318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (flags & SkCanvas::kClipToLayer_SaveFlag) != 0; 832b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#else 833b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com return true; 834b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#endif 8358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 837a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.orgbool SkCanvas::clipRectBounds(const SkRect* bounds, SaveFlags flags, 838c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org SkIRect* intersection, const SkImageFilter* imageFilter) { 839bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect clipBounds; 840c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org SkRegion::Op op = SkRegion::kIntersect_Op; 841bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (!this->getClipDeviceBounds(&clipBounds)) { 842a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return false; 843f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 844c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org 845c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org if (imageFilter) { 8461f836ee096bb988adef4b9757b2629c7afeda36dreed imageFilter->filterBounds(clipBounds, fMCRec->fMatrix, &clipBounds); 847c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org // Filters may grow the bounds beyond the device bounds. 848c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org op = SkRegion::kReplace_Op; 849c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org } 850bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect ir; 85149f085dddff10473b6ebf832a974288300224e60bsalomon if (bounds) { 8528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 8534b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 8548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->getTotalMatrix().mapRect(&r, *bounds); 8558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.roundOut(&ir); 8568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // early exit if the layer's bounds are clipped out 8578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!ir.intersect(clipBounds)) { 858bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (bounds_affects_clip(flags)) { 8591f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fRasterClip.setEmpty(); 860bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 861a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return false; 8628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { // no user bounds, so just use the clip 8648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ir = clipBounds; 8658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 86789f077ced4918ded7e911bc5052b61c90ad57a9asenorblanco@chromium.org if (bounds_affects_clip(flags)) { 86889f077ced4918ded7e911bc5052b61c90ad57a9asenorblanco@chromium.org fClipStack.clipDevRect(ir, op); 86989f077ced4918ded7e911bc5052b61c90ad57a9asenorblanco@chromium.org // early exit if the clip is now empty 8701f836ee096bb988adef4b9757b2629c7afeda36dreed if (!fMCRec->fRasterClip.op(ir, op)) { 87189f077ced4918ded7e911bc5052b61c90ad57a9asenorblanco@chromium.org return false; 87289f077ced4918ded7e911bc5052b61c90ad57a9asenorblanco@chromium.org } 873a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org } 874a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 875a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org if (intersection) { 876a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org *intersection = ir; 877a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org } 878a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return true; 879a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org} 880a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 881d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.orgint SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint) { 882d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org SaveLayerStrategy strategy = this->willSaveLayer(bounds, paint, kARGB_ClipLayer_SaveFlag); 883d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org return this->internalSaveLayer(bounds, paint, kARGB_ClipLayer_SaveFlag, false, strategy); 884d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org} 885d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org 886a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.orgint SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint, 887a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org SaveFlags flags) { 888e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org SaveLayerStrategy strategy = this->willSaveLayer(bounds, paint, flags); 889e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org return this->internalSaveLayer(bounds, paint, flags, false, strategy); 8908926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com} 8918926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 892e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.orgint SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags, 893e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org bool justForImageFilter, SaveLayerStrategy strategy) { 894b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG 8952a5cd60bfff32c92cf44a8cfc3e8c017b9aee456commit-bot@chromium.org flags |= kClipToLayer_SaveFlag; 896b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#endif 897b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com 898a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org // do this before we create the layer. We don't call the public save() since 899a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org // that would invoke a possibly overridden virtual 9005f6102d07982043542343ff0a6c67b1319ac9fc7Florin Malita int count = this->internalSave(); 901a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 902a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org fDeviceCMDirty = true; 903a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 904a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org SkIRect ir; 905c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org if (!this->clipRectBounds(bounds, flags, &ir, paint ? paint->getImageFilter() : NULL)) { 9068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return count; 9078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 909e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy really care about 910e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org // the clipRectBounds() call above? 911e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org if (kNoLayer_SaveLayerStrategy == strategy) { 912e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org return count; 913e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org } 914e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org 915b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com // Kill the imagefilter if our device doesn't allow it 916b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com SkLazyPaint lazyP; 917b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com if (paint && paint->getImageFilter()) { 918b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com if (!this->getTopDevice()->allowImageFilter(paint->getImageFilter())) { 9198926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com if (justForImageFilter) { 9208926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com // early exit if the layer was just for the imageFilter 9218926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com return count; 9228926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 923b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com SkPaint* p = lazyP.set(*paint); 924b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com p->setImageFilter(NULL); 925b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com paint = p; 926b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com } 927b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com } 928b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com 92915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org bool isOpaque = !SkToBool(flags & kHasAlphaLayer_SaveFlag); 93015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org SkImageInfo info = SkImageInfo::MakeN32(ir.width(), ir.height(), 93115a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType); 9328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9331f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* device; 93476dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com if (paint && paint->getImageFilter()) { 93552d9ac6c92ddf33b3b05eb77ba9509a7aa441657reed device = this->getDevice(); 93652d9ac6c92ddf33b3b05eb77ba9509a7aa441657reed if (device) { 937b0e89dcc1d8c1c2f9f7ffb45e8609cdb4a68104bsenorblanco device = device->createCompatibleDeviceForImageFilter(info); 93852d9ac6c92ddf33b3b05eb77ba9509a7aa441657reed } 93976dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } else { 94015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org device = this->createLayerDevice(info); 94176dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } 942e25c68402b38ac01dc1ae196ae8a5265b773c5f2bungeman@google.com if (NULL == device) { 943e25c68402b38ac01dc1ae196ae8a5265b773c5f2bungeman@google.com SkDebugf("Unable to create device for layer."); 944e25c68402b38ac01dc1ae196ae8a5265b773c5f2bungeman@google.com return count; 945e25c68402b38ac01dc1ae196ae8a5265b773c5f2bungeman@google.com } 9464a8126e7f81384526629b1e21bf89b632ea13cd9reed this->setupDevice(device); 947e97f0856a8044866b12527819d14cdfbcdfd96f2bsalomon@google.com 9486f8f292aa768869a9e85c314b124875f57504f2creed@google.com device->setOrigin(ir.fLeft, ir.fTop); 949d954498c01ccf0417feacf89e45d0c62a06a813breed DeviceCM* layer = SkNEW_ARGS(DeviceCM, 950d954498c01ccf0417feacf89e45d0c62a06a813breed (device, ir.fLeft, ir.fTop, paint, this, fConservativeRasterClip)); 9518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device->unref(); 9528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com layer->fNext = fMCRec->fTopLayer; 9548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fLayer = layer; 9558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fTopLayer = layer; // this field is NOT an owner of layer 9568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 957b0a7ace7cb2a7559bbc254a7c93698bc71bbd245junov@chromium.org fSaveLayerCount += 1; 9588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return count; 9598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 961d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.orgint SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) { 962d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org return this->saveLayerAlpha(bounds, alpha, kARGB_ClipLayer_SaveFlag); 963d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org} 964d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org 9658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha, 9668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SaveFlags flags) { 9678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (0xFF == alpha) { 9688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->saveLayer(bounds, NULL, flags); 9698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 9708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint tmpPaint; 9718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com tmpPaint.setAlpha(alpha); 9728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->saveLayer(bounds, &tmpPaint, flags); 9738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::restore() { 9778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // check for underflow 9788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fMCStack.count() > 1) { 979e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org this->willRestore(); 9808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->internalRestore(); 9816cfa73a29a26edf1d03bca224ad6860396308ffcmtklein this->didRestore(); 9828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::internalRestore() { 9868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fMCStack.count() != 0); 9878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 989c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 9908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9915f6102d07982043542343ff0a6c67b1319ac9fc7Florin Malita fClipStack.restore(); 9926c157640c27ee2ed6f9a484d21691b7b19dfecdecommit-bot@chromium.org 99388edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com // reserve our layer (if any) 9948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* layer = fMCRec->fLayer; // may be null 9958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now detach it from fMCRec so we can pop(). Gets freed after its drawn 9968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fLayer = NULL; 9978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now do the normal restore() 9998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->~MCRec(); // balanced in save() 10008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCStack.pop_back(); 10018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = (MCRec*)fMCStack.back(); 10028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* Time to draw the layer's offscreen. We can't call the public drawSprite, 10048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com since if we're being recorded, we don't want to record this (the 10058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com recorder will have already recorded the restore). 10068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 100749f085dddff10473b6ebf832a974288300224e60bsalomon if (layer) { 10088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (layer->fNext) { 10096f8f292aa768869a9e85c314b124875f57504f2creed@google.com const SkIPoint& origin = layer->fDevice->getOrigin(); 10108926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(), 10118926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com layer->fPaint); 10128926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com // reset this, since internalDrawDevice will have set it to true 10138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 10147c2029367cea5479fa3b74fb0ca2b0297b42b709reed@google.com 1015b0a7ace7cb2a7559bbc254a7c93698bc71bbd245junov@chromium.org SkASSERT(fSaveLayerCount > 0); 1016b0a7ace7cb2a7559bbc254a7c93698bc71bbd245junov@chromium.org fSaveLayerCount -= 1; 10178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDELETE(layer); 101988edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 10208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::getSaveCount() const { 10238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fMCStack.count(); 10248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::restoreToCount(int count) { 10278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // sanity check 10288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count < 1) { 10298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com count = 1; 10308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 103174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 1032b9d1c6a3c43a2cbcbd612f4ec4aaf604a1fa6444reed@google.com int n = this->getSaveCount() - count; 1033b9d1c6a3c43a2cbcbd612f4ec4aaf604a1fa6444reed@google.com for (int i = 0; i < n; ++i) { 10348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->restore(); 10358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10387c2029367cea5479fa3b74fb0ca2b0297b42b709reed@google.combool SkCanvas::isDrawingToLayer() const { 1039b0a7ace7cb2a7559bbc254a7c93698bc71bbd245junov@chromium.org return fSaveLayerCount > 0; 10407c2029367cea5479fa3b74fb0ca2b0297b42b709reed@google.com} 10417c2029367cea5479fa3b74fb0ca2b0297b42b709reed@google.com 10424a8126e7f81384526629b1e21bf89b632ea13cd9reedSkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* props) { 10434a8126e7f81384526629b1e21bf89b632ea13cd9reed if (NULL == props) { 10444a8126e7f81384526629b1e21bf89b632ea13cd9reed props = &fProps; 10454a8126e7f81384526629b1e21bf89b632ea13cd9reed } 10464a8126e7f81384526629b1e21bf89b632ea13cd9reed return this->onNewSurface(info, *props); 104776f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com} 104876f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com 10494a8126e7f81384526629b1e21bf89b632ea13cd9reedSkSurface* SkCanvas::onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props) { 105076f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com SkBaseDevice* dev = this->getDevice(); 10514a8126e7f81384526629b1e21bf89b632ea13cd9reed return dev ? dev->newSurface(info, props) : NULL; 105276f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com} 105376f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com 1054c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgSkImageInfo SkCanvas::imageInfo() const { 1055c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkBaseDevice* dev = this->getDevice(); 1056c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (dev) { 1057c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return dev->imageInfo(); 1058c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } else { 1059900ecf2f1579d42c9d2959831787af0346320f86reed@google.com return SkImageInfo::MakeUnknown(0, 0); 1060c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1061c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1062c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1063c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgconst void* SkCanvas::peekPixels(SkImageInfo* info, size_t* rowBytes) { 1064c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return this->onPeekPixels(info, rowBytes); 1065c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1066c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1067c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgconst void* SkCanvas::onPeekPixels(SkImageInfo* info, size_t* rowBytes) { 1068c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkBaseDevice* dev = this->getDevice(); 1069c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return dev ? dev->peekPixels(info, rowBytes) : NULL; 1070c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1071c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 10726b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.orgvoid* SkCanvas::accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin) { 10736b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org void* pixels = this->onAccessTopLayerPixels(info, rowBytes); 10746b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org if (pixels && origin) { 10756b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org *origin = this->getTopDevice(false)->getOrigin(); 10766b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org } 10776b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org return pixels; 10789c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 10799c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 10809c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.comvoid* SkCanvas::onAccessTopLayerPixels(SkImageInfo* info, size_t* rowBytes) { 10819c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com SkBaseDevice* dev = this->getTopDevice(); 10829c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com return dev ? dev->accessPixels(info, rowBytes) : NULL; 10839c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 10849c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1085c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgSkAutoROCanvasPixels::SkAutoROCanvasPixels(SkCanvas* canvas) { 1086c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org fAddr = canvas->peekPixels(&fInfo, &fRowBytes); 1087c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (NULL == fAddr) { 1088c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org fInfo = canvas->imageInfo(); 1089848250415eddc54075f7eb8795e8db79e749c6abreed if (kUnknown_SkColorType == fInfo.colorType() || !fBitmap.tryAllocPixels(fInfo)) { 1090c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return; // failure, fAddr is NULL 1091c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1092c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (!canvas->readPixels(&fBitmap, 0, 0)) { 1093c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return; // failure, fAddr is NULL 1094c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1095c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org fAddr = fBitmap.getPixels(); 1096c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org fRowBytes = fBitmap.rowBytes(); 1097c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1098c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkASSERT(fAddr); // success 1099c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1100c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1101c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgbool SkAutoROCanvasPixels::asROBitmap(SkBitmap* bitmap) const { 1102c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (fAddr) { 110300f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org return bitmap->installPixels(fInfo, const_cast<void*>(fAddr), fRowBytes); 1104c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } else { 1105c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org bitmap->reset(); 1106c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return false; 1107c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1108c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1109c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1110210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.orgvoid SkCanvas::onPushCull(const SkRect& cullRect) { 1111210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org // do nothing. Subclasses may do something 1112210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org} 1113210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org 1114210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.orgvoid SkCanvas::onPopCull() { 1115210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org // do nothing. Subclasses may do something 1116210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org} 1117210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org 11188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////// 1119520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org#ifdef SK_DEBUG 1120520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org// Ensure that cull rects are monotonically nested in device space. 1121520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.orgvoid SkCanvas::validateCull(const SkIRect& devCull) { 1122520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org if (fCullStack.isEmpty() 1123520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org || devCull.isEmpty() 1124520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org || fCullStack.top().contains(devCull)) { 1125520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org return; 1126520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org } 1127520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1128520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org SkDEBUGF(("Invalid cull: [%d %d %d %d] (previous cull: [%d %d %d %d])\n", 1129520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org devCull.x(), devCull.y(), devCull.right(), devCull.bottom(), 1130520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org fCullStack.top().x(), fCullStack.top().y(), 1131520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org fCullStack.top().right(), fCullStack.top().bottom())); 1132520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1133520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org#ifdef ASSERT_NESTED_CULLING 1134520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org SkDEBUGFAIL("Invalid cull."); 1135520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org#endif 1136520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org} 1137520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org#endif 1138520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1139520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.orgvoid SkCanvas::pushCull(const SkRect& cullRect) { 1140520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org ++fCullCount; 1141520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org this->onPushCull(cullRect); 1142520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1143520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org#ifdef SK_DEBUG 1144520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org // Map the cull rect into device space. 1145520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org SkRect mappedCull; 1146520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org this->getTotalMatrix().mapRect(&mappedCull, cullRect); 1147520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1148520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org // Take clipping into account. 1149520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org SkIRect devClip, devCull; 1150520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org mappedCull.roundOut(&devCull); 1151520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org this->getClipDeviceBounds(&devClip); 1152520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org if (!devCull.intersect(devClip)) { 1153520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org devCull.setEmpty(); 1154520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org } 1155520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1156520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org this->validateCull(devCull); 1157520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org fCullStack.push(devCull); // balanced in popCull 1158520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org#endif 1159520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org} 1160520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1161520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.orgvoid SkCanvas::popCull() { 1162520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org SkASSERT(fCullStack.count() == fCullCount); 1163520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1164520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org if (fCullCount > 0) { 1165520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org --fCullCount; 1166520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org this->onPopCull(); 1167520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1168520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org SkDEBUGCODE(fCullStack.pop()); 1169520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org } 1170520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org} 1171520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1172520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org///////////////////////////////////////////////////////////////////////////// 11738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11749bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.comvoid SkCanvas::internalDrawBitmap(const SkBitmap& bitmap, 11758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& matrix, const SkPaint* paint) { 117650b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org if (bitmap.drawsNothing()) { 11778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 11788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11802c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkLazyPaint lazy; 11818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == paint) { 11822c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org paint = lazy.init(); 11838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11849bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com 11859bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com SkDEBUGCODE(bitmap.validate();) 11869bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com 118778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 118878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 118978cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (paint && paint->canComputeFastBounds()) { 119078cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bitmap.getBounds(&storage); 119178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org matrix.mapRect(&storage); 119278cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint->computeFastBounds(storage, &storage); 119378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org } 119478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org 119578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) 11969bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com 11979bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com while (iter.next()) { 11989bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com iter.fDevice->drawBitmap(iter, bitmap, matrix, looper.paint()); 11999bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com } 12009bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com 12019bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com LOOPER_END 12028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12041f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comvoid SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, 12058926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com const SkPaint* paint) { 12068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint tmp; 12078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == paint) { 12088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint = &tmp; 12098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12104b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 12118926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com LOOPER_BEGIN_DRAWDEVICE(*paint, SkDrawFilter::kBitmap_Type) 12128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 12131f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* dstDev = iter.fDevice; 121476dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com paint = &looper.paint(); 121576dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkImageFilter* filter = paint->getImageFilter(); 121676dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkIPoint pos = { x - iter.getX(), y - iter.getY() }; 12178926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com if (filter && !dstDev->canHandleImageFilter(filter)) { 12189c39744a00573b7133fc765b0a9d50a0ceace7b8senorblanco@chromium.org SkDeviceImageFilterProxy proxy(dstDev); 121976dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkBitmap dst; 12206776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org SkIPoint offset = SkIPoint::Make(0, 0); 1221b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com const SkBitmap& src = srcDev->accessBitmap(false); 1222fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org SkMatrix matrix = *iter.fMatrix; 1223d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org matrix.postTranslate(SkIntToScalar(-pos.x()), SkIntToScalar(-pos.y())); 12244cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org SkIRect clipBounds = SkIRect::MakeWH(srcDev->width(), srcDev->height()); 1225be129b26f13d575fd6b396c6ae759838ecc9bd1asenorblanco SkAutoTUnref<SkImageFilter::Cache> cache(dstDev->getImageFilterCache()); 122655b6d8be997a447ef9ce0f029697677a940bfc24senorblanco SkImageFilter::Context ctx(matrix, clipBounds, cache.get()); 12274cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org if (filter->filterImage(&proxy, src, ctx, &dst, &offset)) { 12285efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com SkPaint tmpUnfiltered(*paint); 12295efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com tmpUnfiltered.setImageFilter(NULL); 12306776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org dstDev->drawSprite(iter, dst, pos.x() + offset.x(), pos.y() + offset.y(), 12316776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org tmpUnfiltered); 123276dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } 123376dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } else { 1234b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com dstDev->drawDevice(iter, srcDev, pos.x(), pos.y(), *paint); 123576dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } 12368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12374e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 12388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12408926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.comvoid SkCanvas::drawSprite(const SkBitmap& bitmap, int x, int y, 12418926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com const SkPaint* paint) { 12428f757f540a8378c7b1354aab3d4650eaa920b17adanakj TRACE_EVENT0("skia", "SkCanvas::drawSprite()"); 124350b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org if (bitmap.drawsNothing()) { 12448926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com return; 12458926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 124650b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org SkDEBUGCODE(bitmap.validate();) 1247fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 12488926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkPaint tmp; 12498926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com if (NULL == paint) { 12508926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com paint = &tmp; 12518926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 1252fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 12538926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com LOOPER_BEGIN_DRAWDEVICE(*paint, SkDrawFilter::kBitmap_Type) 1254fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 12558926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com while (iter.next()) { 12568926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com paint = &looper.paint(); 12578926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkImageFilter* filter = paint->getImageFilter(); 12588926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkIPoint pos = { x - iter.getX(), y - iter.getY() }; 12598926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com if (filter && !iter.fDevice->canHandleImageFilter(filter)) { 12609c39744a00573b7133fc765b0a9d50a0ceace7b8senorblanco@chromium.org SkDeviceImageFilterProxy proxy(iter.fDevice); 12618926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkBitmap dst; 12626776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org SkIPoint offset = SkIPoint::Make(0, 0); 1263fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org SkMatrix matrix = *iter.fMatrix; 1264d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org matrix.postTranslate(SkIntToScalar(-pos.x()), SkIntToScalar(-pos.y())); 1265f622a6c8fd176acf9944de8df00d7f0bb56b67d3halcanary const SkIRect clipBounds = bitmap.bounds(); 1266be129b26f13d575fd6b396c6ae759838ecc9bd1asenorblanco SkAutoTUnref<SkImageFilter::Cache> cache(iter.fDevice->getImageFilterCache()); 126755b6d8be997a447ef9ce0f029697677a940bfc24senorblanco SkImageFilter::Context ctx(matrix, clipBounds, cache.get()); 12684cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org if (filter->filterImage(&proxy, bitmap, ctx, &dst, &offset)) { 12695efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com SkPaint tmpUnfiltered(*paint); 12705efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com tmpUnfiltered.setImageFilter(NULL); 12716776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org iter.fDevice->drawSprite(iter, dst, pos.x() + offset.x(), pos.y() + offset.y(), 12725efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com tmpUnfiltered); 12738926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 12748926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } else { 12758926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com iter.fDevice->drawSprite(iter, bitmap, pos.x(), pos.y(), *paint); 12768926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 12778926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 12788926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com LOOPER_END 12798926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com} 12808926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 12818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////// 128292362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::translate(SkScalar dx, SkScalar dy) { 1283d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1284d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setTranslate(dx, dy); 1285d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 12868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 128892362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::scale(SkScalar sx, SkScalar sy) { 1289d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1290d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setScale(sx, sy); 1291d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 12928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 129492362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::rotate(SkScalar degrees) { 1295d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1296d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setRotate(degrees); 1297d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 12988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 130092362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::skew(SkScalar sx, SkScalar sy) { 1301d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1302d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setSkew(sx, sy); 1303d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 130444c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org} 130544c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 130692362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::concat(const SkMatrix& matrix) { 1307d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org if (matrix.isIdentity()) { 1308d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org return; 1309d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org } 1310d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org 13118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1312c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 13131f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix.preConcat(matrix); 131444c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 131544c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org this->didConcat(matrix); 131644c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org} 131744c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 13188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::setMatrix(const SkMatrix& matrix) { 13198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1320c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 13211f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix = matrix; 132244c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org this->didSetMatrix(matrix); 13238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::resetMatrix() { 13268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 13274b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 13288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.reset(); 13298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->setMatrix(matrix); 13308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 13338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1334759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { 13358f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 13368f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(rect, op, edgeStyle); 13378f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 13388f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 13398f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 1340da17f758442f16747af39f8fbaed9c097048519creed@google.com#ifdef SK_ENABLE_CLIP_QUICKREJECT 1341da17f758442f16747af39f8fbaed9c097048519creed@google.com if (SkRegion::kIntersect_Op == op) { 13421f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fRasterClip.isEmpty()) { 1343da17f758442f16747af39f8fbaed9c097048519creed@google.com return false; 1344da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1345da17f758442f16747af39f8fbaed9c097048519creed@google.com 13463b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(rect)) { 1347da17f758442f16747af39f8fbaed9c097048519creed@google.com fDeviceCMDirty = true; 1348c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 1349da17f758442f16747af39f8fbaed9c097048519creed@google.com 1350da17f758442f16747af39f8fbaed9c097048519creed@google.com fClipStack.clipEmpty(); 13511f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.setEmpty(); 1352da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1353da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1354da17f758442f16747af39f8fbaed9c097048519creed@google.com#endif 1355da17f758442f16747af39f8fbaed9c097048519creed@google.com 13565c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com AutoValidateClip avc(this); 13575c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 13588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1359c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 13608f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!fAllowSoftClip) { 13618f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com edgeStyle = kHard_ClipEdgeStyle; 13628f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 13638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13641f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fMatrix.rectStaysRect()) { 1365123671901abfa595d09ca789b487c4bc7c1f7cbcrobertphillips@google.com // for these simpler matrices, we can stay a rect even after applying 136698de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // the matrix. This means we don't have to a) make a path, and b) tell 136798de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // the region code to scan-convert the path, only to discover that it 136898de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // is really just a rect. 13698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 13708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13711f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix.mapRect(&r, rect); 13728f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com fClipStack.clipDevRect(r, op, kSoft_ClipEdgeStyle == edgeStyle); 1373d954498c01ccf0417feacf89e45d0c62a06a813breed fMCRec->fRasterClip.op(r, this->getBaseLayerSize(), op, kSoft_ClipEdgeStyle == edgeStyle); 13748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 1375123671901abfa595d09ca789b487c4bc7c1f7cbcrobertphillips@google.com // since we're rotated or some such thing, we convert the rect to a path 137698de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // and clip against that, since it can handle any matrix. However, to 137798de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // avoid recursion in the case where we are subclassed (e.g. Pictures) 137898de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // we explicitly call "our" version of clipPath. 13798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath path; 13808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.addRect(rect); 13828f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->SkCanvas::onClipPath(path, op, edgeStyle); 13838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 138673e714eb766617ce06757829a3c0b345c7963faareedstatic void rasterclip_path(SkRasterClip* rc, const SkCanvas* canvas, const SkPath& devPath, 138773e714eb766617ce06757829a3c0b345c7963faareed SkRegion::Op op, bool doAA) { 1388d64c9487135094c83f658319f53ea2005ecc08b2reed rc->op(devPath, canvas->getBaseLayerSize(), op, doAA); 1389819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com} 1390819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 1391759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) { 13928f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 13934ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (rrect.isRect()) { 13948f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(rrect.getBounds(), op, edgeStyle); 13958f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } else { 13968f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRRect(rrect, op, edgeStyle); 13974ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 13988f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 139914e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 14008f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 140114e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org SkRRect transformedRRect; 14021f836ee096bb988adef4b9757b2629c7afeda36dreed if (rrect.transform(fMCRec->fMatrix, &transformedRRect)) { 140314e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org AutoValidateClip avc(this); 140414e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 140514e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org fDeviceCMDirty = true; 140614e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org fCachedLocalClipBoundsDirty = true; 14078f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!fAllowSoftClip) { 14088f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com edgeStyle = kHard_ClipEdgeStyle; 14098f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 141014e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 14118f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com fClipStack.clipDevRRect(transformedRRect, op, kSoft_ClipEdgeStyle == edgeStyle); 141214e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 141314e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org SkPath devPath; 141414e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org devPath.addRRect(transformedRRect); 141514e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 141673e714eb766617ce06757829a3c0b345c7963faareed rasterclip_path(&fMCRec->fRasterClip, this, devPath, op, kSoft_ClipEdgeStyle == edgeStyle); 14178f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com return; 141814e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org } 141914e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 142014e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org SkPath path; 142114e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org path.addRRect(rrect); 142214e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org // call the non-virtual version 14238f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->SkCanvas::onClipPath(path, op, edgeStyle); 14244ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 14254ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 1426759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { 14278f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 14288f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com SkRect r; 14298f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!path.isInverseFillType() && path.isRect(&r)) { 14308f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(r, op, edgeStyle); 14318f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } else { 14328f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipPath(path, op, edgeStyle); 14338f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 14348f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 14358f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 14368f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 1437da17f758442f16747af39f8fbaed9c097048519creed@google.com#ifdef SK_ENABLE_CLIP_QUICKREJECT 1438da17f758442f16747af39f8fbaed9c097048519creed@google.com if (SkRegion::kIntersect_Op == op && !path.isInverseFillType()) { 14391f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fRasterClip.isEmpty()) { 1440da17f758442f16747af39f8fbaed9c097048519creed@google.com return false; 1441da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1442fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 14433b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(path.getBounds())) { 1444da17f758442f16747af39f8fbaed9c097048519creed@google.com fDeviceCMDirty = true; 1445c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 1446fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1447da17f758442f16747af39f8fbaed9c097048519creed@google.com fClipStack.clipEmpty(); 14481f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.setEmpty(); 1449da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1450da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1451da17f758442f16747af39f8fbaed9c097048519creed@google.com#endif 1452da17f758442f16747af39f8fbaed9c097048519creed@google.com 14535c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com AutoValidateClip avc(this); 14545c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 14558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1456c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 14578f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!fAllowSoftClip) { 14588f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com edgeStyle = kHard_ClipEdgeStyle; 14598f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 14608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath devPath; 14621f836ee096bb988adef4b9757b2629c7afeda36dreed path.transform(fMCRec->fMatrix, &devPath); 14638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1464fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // Check if the transfomation, or the original path itself 1465fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // made us empty. Note this can also happen if we contained NaN 1466fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // values. computing the bounds detects this, and will set our 1467fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // bounds to empty if that is the case. (see SkRect::set(pts, count)) 1468fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com if (devPath.getBounds().isEmpty()) { 1469fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // resetting the path will remove any NaN or other wanky values 1470fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // that might upset our scan converter. 1471fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com devPath.reset(); 1472fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com } 1473fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com 14745c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // if we called path.swap() we could avoid a deep copy of this path 14758f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com fClipStack.clipDevPath(devPath, op, kSoft_ClipEdgeStyle == edgeStyle); 14765c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 147745a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com if (fAllowSimplifyClip) { 147845a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com devPath.reset(); 147945a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com devPath.setFillType(SkPath::kInverseEvenOdd_FillType); 148045a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com const SkClipStack* clipStack = getClipStack(); 148145a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com SkClipStack::Iter iter(*clipStack, SkClipStack::Iter::kBottom_IterStart); 148245a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com const SkClipStack::Element* element; 148345a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com while ((element = iter.next())) { 148445a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com SkClipStack::Element::Type type = element->getType(); 148545a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com SkPath operand; 14862a67e123a3e559774a16a58cbe5106bc0fb86740commit-bot@chromium.org if (type != SkClipStack::Element::kEmpty_Type) { 14872a67e123a3e559774a16a58cbe5106bc0fb86740commit-bot@chromium.org element->asPath(&operand); 14882a67e123a3e559774a16a58cbe5106bc0fb86740commit-bot@chromium.org } 148945a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com SkRegion::Op elementOp = element->getOp(); 149045a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com if (elementOp == SkRegion::kReplace_Op) { 149145a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com devPath = operand; 149245a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com } else { 149345a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com Op(devPath, operand, (SkPathOp) elementOp, &devPath); 149445a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com } 149596fd3440fa489f74f903f30487282af99deb2a4dcaryclark@google.com // if the prev and curr clips disagree about aa -vs- not, favor the aa request. 149696fd3440fa489f74f903f30487282af99deb2a4dcaryclark@google.com // perhaps we need an API change to avoid this sort of mixed-signals about 149796fd3440fa489f74f903f30487282af99deb2a4dcaryclark@google.com // clipping. 14988f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (element->isAA()) { 14998f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com edgeStyle = kSoft_ClipEdgeStyle; 15008f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 150145a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com } 150245a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com op = SkRegion::kReplace_Op; 150345a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com } 150445a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com 150573e714eb766617ce06757829a3c0b345c7963faareed rasterclip_path(&fMCRec->fRasterClip, this, devPath, op, edgeStyle); 15068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 15078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1508759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipRegion(const SkRegion& rgn, SkRegion::Op op) { 15098f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRegion(rgn, op); 15108f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 15118f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 15128f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipRegion(const SkRegion& rgn, SkRegion::Op op) { 15135c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com AutoValidateClip avc(this); 15145c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 15158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1516c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 15178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 15185c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // todo: signal fClipStack that we have a region, and therefore (I guess) 15195c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // we have to ignore it, and use the region directly? 1520115d931d2fbd3a109a21b28c8a9c5099e6c49c54reed@google.com fClipStack.clipDevRect(rgn.getBounds(), op); 15215c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 15221f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fRasterClip.op(rgn, op); 15238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 15248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1525819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com#ifdef SK_DEBUG 1526819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.comvoid SkCanvas::validateClip() const { 1527819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com // construct clipRgn from the clipstack 15281f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com const SkBaseDevice* device = this->getDevice(); 1529ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com if (!device) { 15305c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org SkASSERT(this->isClipEmpty()); 1531ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com return; 1532ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com } 1533ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com 1534819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com SkIRect ir; 1535819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com ir.set(0, 0, device->width(), device->height()); 1536d954498c01ccf0417feacf89e45d0c62a06a813breed SkRasterClip tmpClip(ir, fConservativeRasterClip); 1537819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 153880214e26c57c5fea954006400852e8999e201923robertphillips@google.com SkClipStack::B2TIter iter(fClipStack); 15398182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const SkClipStack::Element* element; 15408182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com while ((element = iter.next()) != NULL) { 15418182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com switch (element->getType()) { 15428182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kRect_Type: 15438182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com element->getRect().round(&ir); 15448182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com tmpClip.op(ir, element->getOp()); 15458182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 15468182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kEmpty_Type: 15478182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com tmpClip.setEmpty(); 15488182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 15499cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org default: { 15509cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org SkPath path; 15519cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org element->asPath(&path); 155273e714eb766617ce06757829a3c0b345c7963faareed rasterclip_path(&tmpClip, this, path, element->getOp(), element->isAA()); 15539cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org break; 15549cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org } 1555819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com } 1556819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com } 1557819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com} 1558819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com#endif 1559819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 156090c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.comvoid SkCanvas::replayClips(ClipVisitor* visitor) const { 156180214e26c57c5fea954006400852e8999e201923robertphillips@google.com SkClipStack::B2TIter iter(fClipStack); 15628182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const SkClipStack::Element* element; 15638182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com 15648182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com while ((element = iter.next()) != NULL) { 1565c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita element->replay(visitor); 156690c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com } 156790c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com} 156890c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com 15695c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com/////////////////////////////////////////////////////////////////////////////// 15705c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 1571754de5f65b466f721d952a379194cc94de376f42reed@google.combool SkCanvas::isClipEmpty() const { 15721f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.isEmpty(); 1573754de5f65b466f721d952a379194cc94de376f42reed@google.com} 1574754de5f65b466f721d952a379194cc94de376f42reed@google.com 15755c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.orgbool SkCanvas::isClipRect() const { 15761f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.isRect(); 15775c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org} 15785c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org 15793b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::quickReject(const SkRect& rect) const { 15801607863b608b7db6c813228768ed5d72997bbc82reed@google.com if (!rect.isFinite()) 1581116b2bcd2c4c4d4670c7b7e2ea597414713c37fbwjmaclean@chromium.org return true; 1582116b2bcd2c4c4d4670c7b7e2ea597414713c37fbwjmaclean@chromium.org 15831f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fRasterClip.isEmpty()) { 15848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 15858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 15868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 15871f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fMatrix.hasPerspective()) { 1588a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com SkRect dst; 15891f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix.mapRect(&dst, rect); 1590a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com SkIRect idst; 1591a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com dst.roundOut(&idst); 15921f836ee096bb988adef4b9757b2629c7afeda36dreed return !SkIRect::Intersects(idst, fMCRec->fRasterClip.getBounds()); 1593a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com } else { 1594c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com const SkRect& clipR = this->getLocalClipBounds(); 1595d252db03d9650013b545ef9781fe993c07f8f314reed@android.com 1596a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com // for speed, do the most likely reject compares first 1597c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com // TODO: should we use | instead, or compare all 4 at once? 1598c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com if (rect.fTop >= clipR.fBottom || rect.fBottom <= clipR.fTop) { 1599a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com return true; 1600a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com } 1601c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com if (rect.fLeft >= clipR.fRight || rect.fRight <= clipR.fLeft) { 1602a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com return true; 1603a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com } 1604a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com return false; 16058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 16068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16083b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::quickReject(const SkPath& path) const { 16093b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com return path.isEmpty() || this->quickReject(path.getBounds()); 16108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16123b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::getClipBounds(SkRect* bounds) const { 1613bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect ibounds; 16148f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!this->getClipDeviceBounds(&ibounds)) { 16158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 16168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 16178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1618d9c0f0b57affec7a472879c5919acac6637d926areed@android.com SkMatrix inverse; 1619d9c0f0b57affec7a472879c5919acac6637d926areed@android.com // if we can't invert the CTM, we can't return local clip bounds 16201f836ee096bb988adef4b9757b2629c7afeda36dreed if (!fMCRec->fMatrix.invert(&inverse)) { 162172dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com if (bounds) { 162272dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com bounds->setEmpty(); 162372dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com } 1624d9c0f0b57affec7a472879c5919acac6637d926areed@android.com return false; 1625d9c0f0b57affec7a472879c5919acac6637d926areed@android.com } 1626d9c0f0b57affec7a472879c5919acac6637d926areed@android.com 162749f085dddff10473b6ebf832a974288300224e60bsalomon if (bounds) { 1628bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkRect r; 16293b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com // adjust it outwards in case we are antialiasing 16303b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com const int inset = 1; 1631fa4d5bd09f8f1a4a92b5ae0324800dd672760898reed@google.com 16328f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com r.iset(ibounds.fLeft - inset, ibounds.fTop - inset, 16338f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com ibounds.fRight + inset, ibounds.fBottom + inset); 16348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inverse.mapRect(bounds, r); 16358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 16368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 16378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1639bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.combool SkCanvas::getClipDeviceBounds(SkIRect* bounds) const { 16401f836ee096bb988adef4b9757b2629c7afeda36dreed const SkRasterClip& clip = fMCRec->fRasterClip; 1641bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (clip.isEmpty()) { 1642bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (bounds) { 1643bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com bounds->setEmpty(); 1644bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1645bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com return false; 1646bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1647bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com 164849f085dddff10473b6ebf832a974288300224e60bsalomon if (bounds) { 1649bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com *bounds = clip.getBounds(); 1650bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1651bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com return true; 1652bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com} 1653bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com 16548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkMatrix& SkCanvas::getTotalMatrix() const { 16551f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fMatrix; 16568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16585c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.orgconst SkRegion& SkCanvas::internal_private_getTotalClip() const { 16591f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.forceGetBW(); 16605c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org} 16615c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org 16629c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.comGrRenderTarget* SkCanvas::internal_private_accessTopLayerRenderTarget() { 16639c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com SkBaseDevice* dev = this->getTopDevice(); 16649c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com return dev ? dev->accessRenderTarget() : NULL; 16659c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 16669c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 166715a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.orgSkBaseDevice* SkCanvas::createLayerDevice(const SkImageInfo& info) { 16681f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* device = this->getTopDevice(); 166915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org return device ? device->createCompatibleDeviceForSaveLayer(info) : NULL; 16708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1672644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.orgGrContext* SkCanvas::getGrContext() { 1673644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#if SK_SUPPORT_GPU 1674644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org SkBaseDevice* device = this->getTopDevice(); 167549f085dddff10473b6ebf832a974288300224e60bsalomon if (device) { 1676644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org GrRenderTarget* renderTarget = device->accessRenderTarget(); 167749f085dddff10473b6ebf832a974288300224e60bsalomon if (renderTarget) { 1678644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org return renderTarget->getContext(); 1679644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org } 1680644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org } 1681644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#endif 1682644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org 1683644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org return NULL; 1684644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org 1685644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org} 1686e97f0856a8044866b12527819d14cdfbcdfd96f2bsalomon@google.com 1687ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.orgvoid SkCanvas::drawDRRect(const SkRRect& outer, const SkRRect& inner, 1688ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkPaint& paint) { 16898f757f540a8378c7b1354aab3d4650eaa920b17adanakj TRACE_EVENT0("skia", "SkCanvas::drawDRRect()"); 1690ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (outer.isEmpty()) { 1691ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 1692ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 1693ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (inner.isEmpty()) { 1694ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->drawRRect(outer, paint); 1695ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 1696ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 1697ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 1698ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // We don't have this method (yet), but technically this is what we should 1699ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // be able to assert... 1700ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // SkASSERT(outer.contains(inner)); 1701ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // 1702ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // For now at least check for containment of bounds 1703ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org SkASSERT(outer.getBounds().contains(inner.getBounds())); 1704ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 1705ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->onDrawDRRect(outer, inner, paint); 1706ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org} 1707ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 17088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 17098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// These are the virtual drawing methods 17108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 17118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17122a98181f048c11f21f52fbd99f803f5fd6118261reed@google.comvoid SkCanvas::clear(SkColor color) { 17132a98181f048c11f21f52fbd99f803f5fd6118261reed@google.com SkDrawIter iter(this); 1714995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org this->predrawNotify(); 17152a98181f048c11f21f52fbd99f803f5fd6118261reed@google.com while (iter.next()) { 17162a98181f048c11f21f52fbd99f803f5fd6118261reed@google.com iter.fDevice->clear(color); 17172a98181f048c11f21f52fbd99f803f5fd6118261reed@google.com } 17182a98181f048c11f21f52fbd99f803f5fd6118261reed@google.com} 17192a98181f048c11f21f52fbd99f803f5fd6118261reed@google.com 172028361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.orgvoid SkCanvas::onDiscard() { 172149f085dddff10473b6ebf832a974288300224e60bsalomon if (fSurfaceBase) { 172228361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org fSurfaceBase->aboutToDraw(SkSurface::kDiscard_ContentChangeMode); 172328361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org } 172428361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org} 172528361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org 17268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPaint(const SkPaint& paint) { 17278f757f540a8378c7b1354aab3d4650eaa920b17adanakj TRACE_EVENT0("skia", "SkCanvas::drawPaint()"); 1728fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->internalDrawPaint(paint); 1729fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com} 1730fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com 1731fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.comvoid SkCanvas::internalDrawPaint(const SkPaint& paint) { 173278cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPaint_Type, NULL) 17338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 17354e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPaint(iter, looper.paint()); 17368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 17378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17384e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 17398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPoints(PointMode mode, size_t count, const SkPoint pts[], 17428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 17438f757f540a8378c7b1354aab3d4650eaa920b17adanakj TRACE_EVENT1("skia", "SkCanvas::drawPoints()", "count", static_cast<uint64_t>(count)); 17448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if ((long)count <= 0) { 17458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 17468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 17478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 174878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect r, storage; 174978cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 1750a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com if (paint.canComputeFastBounds()) { 1751a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com // special-case 2 points (common for drawing a single line) 1752a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com if (2 == count) { 1753a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com r.set(pts[0], pts[1]); 1754a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } else { 1755a8c7f7702fb4bbedb615031bc653c5cd161a038ecommit-bot@chromium.org r.set(pts, SkToInt(count)); 1756a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } 175778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint.computeFastStrokeBounds(r, &storage); 175878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (this->quickReject(*bounds)) { 1759a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com return; 1760a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } 1761fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 1762a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com 17638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(pts != NULL); 17648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 176578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPoint_Type, bounds) 17664b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 17678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 17684e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPoints(iter, mode, count, pts, looper.paint()); 17698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 17704b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 17714e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 17728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17747ce564cccb246ec56427085872b2e1458fe74bd1bsalomon@google.comvoid SkCanvas::drawRect(const SkRect& r, const SkPaint& paint) { 17758f757f540a8378c7b1354aab3d4650eaa920b17adanakj TRACE_EVENT0("skia", "SkCanvas::drawRect()"); 177678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 177778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 17788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.canComputeFastBounds()) { 177978cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint.computeFastBounds(r, &storage); 178078cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (this->quickReject(*bounds)) { 17818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 17828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 17838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 17844b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 178578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kRect_Type, bounds) 17868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 17884e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawRect(iter, r, looper.paint()); 17898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 17908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17914e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 17928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17944ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.comvoid SkCanvas::drawOval(const SkRect& oval, const SkPaint& paint) { 17958f757f540a8378c7b1354aab3d4650eaa920b17adanakj TRACE_EVENT0("skia", "SkCanvas::drawOval()"); 179678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 179778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 17984ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (paint.canComputeFastBounds()) { 179978cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint.computeFastBounds(oval, &storage); 180078cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (this->quickReject(*bounds)) { 18014ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com return; 18024ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 18034ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 1804306ab9d5de38f2a547fd1d69aedbe69b5c6617ccskia.committer@gmail.com 180578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, bounds) 180646d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com 180746d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com while (iter.next()) { 180846d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com iter.fDevice->drawOval(iter, oval, looper.paint()); 180946d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com } 181046d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com 181146d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com LOOPER_END 18124ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 18134ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 18144ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.comvoid SkCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) { 18158f757f540a8378c7b1354aab3d4650eaa920b17adanakj TRACE_EVENT0("skia", "SkCanvas::drawRRect()"); 181678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 181778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 18184ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (paint.canComputeFastBounds()) { 181978cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint.computeFastBounds(rrect.getBounds(), &storage); 182078cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (this->quickReject(*bounds)) { 18214ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com return; 18224ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 18234ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 18244ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 18254ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (rrect.isRect()) { 18264ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com // call the non-virtual version 18274ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->SkCanvas::drawRect(rrect.getBounds(), paint); 1828f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org return; 1829f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } else if (rrect.isOval()) { 18304ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com // call the non-virtual version 1831f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org this->SkCanvas::drawOval(rrect.getBounds(), paint); 1832f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org return; 18334ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 1834f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 183578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) 1836f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 1837f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org while (iter.next()) { 1838f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org iter.fDevice->drawRRect(iter, rrect, looper.paint()); 1839f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } 1840f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 1841f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org LOOPER_END 18424ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 18434ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 1844ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.orgvoid SkCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, 1845ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkPaint& paint) { 1846ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org SkRect storage; 1847ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkRect* bounds = NULL; 1848ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (paint.canComputeFastBounds()) { 1849ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org bounds = &paint.computeFastBounds(outer.getBounds(), &storage); 1850ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (this->quickReject(*bounds)) { 1851ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 1852ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 1853ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 185425c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 1855ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) 185625c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 1857ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org while (iter.next()) { 1858ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org iter.fDevice->drawDRRect(iter, outer, inner, looper.paint()); 1859ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 186025c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 1861ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org LOOPER_END 1862ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org} 18634ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 18647ce564cccb246ec56427085872b2e1458fe74bd1bsalomon@google.comvoid SkCanvas::drawPath(const SkPath& path, const SkPaint& paint) { 18658f757f540a8378c7b1354aab3d4650eaa920b17adanakj TRACE_EVENT0("skia", "SkCanvas::drawPath()"); 18669364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com if (!path.isFinite()) { 18679364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com return; 18689364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com } 18699364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com 187078cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 187178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 1872fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com if (!path.isInverseFillType() && paint.canComputeFastBounds()) { 187378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect& pathBounds = path.getBounds(); 187478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint.computeFastBounds(pathBounds, &storage); 187578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (this->quickReject(*bounds)) { 18768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 18778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18790b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org 18800b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org const SkRect& r = path.getBounds(); 18810b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org if (r.width() <= 0 && r.height() <= 0) { 18826803c219dd3be4a73e7bb5c4bb8a5b1f803624d0commit-bot@chromium.org if (path.isInverseFillType()) { 1883fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->internalDrawPaint(paint); 1884fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 1885fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com return; 1886fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 18878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 188878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, bounds) 18898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 18914e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPath(iter, path, looper.paint()); 18928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18944e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 18958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1897b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixrvoid SkCanvas::drawImage(const SkImage* image, SkScalar left, SkScalar top, 1898b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr const SkPaint* paint) { 18998f757f540a8378c7b1354aab3d4650eaa920b17adanakj TRACE_EVENT0("skia", "SkCanvas::drawImage()"); 1900b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr image->draw(this, left, top, paint); 1901b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr} 1902b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 1903b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixrvoid SkCanvas::drawImageRect(const SkImage* image, const SkRect* src, 1904b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr const SkRect& dst, 1905b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr const SkPaint* paint) { 19068f757f540a8378c7b1354aab3d4650eaa920b17adanakj TRACE_EVENT0("skia", "SkCanvas::drawImageRect()"); 19075ceff913cfd458c653358db7f60e995f505bce84piotaixr image->drawRect(this, src, dst, paint); 1908b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr} 1909b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 19108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y, 19118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* paint) { 19128f757f540a8378c7b1354aab3d4650eaa920b17adanakj TRACE_EVENT0("skia", "SkCanvas::drawBitmap()"); 19138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(bitmap.validate();) 19148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19153d60812865bb034851da777a91413ab584929887reed@google.com if (NULL == paint || paint->canComputeFastBounds()) { 19169efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com SkRect bounds = { 19179efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com x, y, 19189efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com x + SkIntToScalar(bitmap.width()), 19199efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com y + SkIntToScalar(bitmap.height()) 19209efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com }; 19219efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com if (paint) { 19229efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com (void)paint->computeFastBounds(bounds, &bounds); 19239efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com } 19243b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(bounds)) { 19258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 19268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 19278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 19284b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 19298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 19308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.setTranslate(x, y); 19319bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com this->internalDrawBitmap(bitmap, matrix, paint); 19328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 19338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19349987ec3791336bad6af5cbe513564786b2df55aareed@google.com// this one is non-virtual, so it can be called safely by other canvas apis 19357112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.comvoid SkCanvas::internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, 1936eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org const SkRect& dst, const SkPaint* paint, 1937eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org DrawBitmapRectFlags flags) { 193850b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org if (bitmap.drawsNothing() || dst.isEmpty()) { 19398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 19408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 194174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 194278cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 194378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = &dst; 19443d60812865bb034851da777a91413ab584929887reed@google.com if (NULL == paint || paint->canComputeFastBounds()) { 19459efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com if (paint) { 19469efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com bounds = &paint->computeFastBounds(dst, &storage); 19479efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com } 19483b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(*bounds)) { 19493d60812865bb034851da777a91413ab584929887reed@google.com return; 19503d60812865bb034851da777a91413ab584929887reed@google.com } 19518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 19523d60812865bb034851da777a91413ab584929887reed@google.com 195333535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com SkLazyPaint lazy; 195433535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com if (NULL == paint) { 195533535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com paint = lazy.init(); 19568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 19577064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 195878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) 19597064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 196033535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com while (iter.next()) { 1961eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org iter.fDevice->drawBitmapRect(iter, bitmap, src, dst, looper.paint(), flags); 1962f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 19637064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 196433535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com LOOPER_END 19658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 19668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19677112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.comvoid SkCanvas::drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src, 1968eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org const SkRect& dst, const SkPaint* paint, 1969eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org DrawBitmapRectFlags flags) { 19708f757f540a8378c7b1354aab3d4650eaa920b17adanakj TRACE_EVENT0("skia", "SkCanvas::drawBitmapRectToRect()"); 19719987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkDEBUGCODE(bitmap.validate();) 1972eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org this->internalDrawBitmapRect(bitmap, src, dst, paint, flags); 19739987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 19749987ec3791336bad6af5cbe513564786b2df55aareed@google.com 19758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& matrix, 19768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* paint) { 19778f757f540a8378c7b1354aab3d4650eaa920b17adanakj TRACE_EVENT0("skia", "SkCanvas::drawBitmapMatrix()"); 19788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(bitmap.validate();) 19799bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com this->internalDrawBitmap(bitmap, matrix, paint); 19808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 19818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19829987ec3791336bad6af5cbe513564786b2df55aareed@google.comvoid SkCanvas::internalDrawBitmapNine(const SkBitmap& bitmap, 19839987ec3791336bad6af5cbe513564786b2df55aareed@google.com const SkIRect& center, const SkRect& dst, 19849987ec3791336bad6af5cbe513564786b2df55aareed@google.com const SkPaint* paint) { 198550b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org if (bitmap.drawsNothing()) { 198650b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org return; 198750b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org } 19883d60812865bb034851da777a91413ab584929887reed@google.com if (NULL == paint || paint->canComputeFastBounds()) { 198960abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com SkRect storage; 199060abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com const SkRect* bounds = &dst; 199160abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com if (paint) { 199260abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com bounds = &paint->computeFastBounds(dst, &storage); 199360abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com } 19943b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(*bounds)) { 19953d60812865bb034851da777a91413ab584929887reed@google.com return; 19963d60812865bb034851da777a91413ab584929887reed@google.com } 19973d60812865bb034851da777a91413ab584929887reed@google.com } 19983d60812865bb034851da777a91413ab584929887reed@google.com 19999987ec3791336bad6af5cbe513564786b2df55aareed@google.com const int32_t w = bitmap.width(); 20009987ec3791336bad6af5cbe513564786b2df55aareed@google.com const int32_t h = bitmap.height(); 20019987ec3791336bad6af5cbe513564786b2df55aareed@google.com 20029987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkIRect c = center; 20039987ec3791336bad6af5cbe513564786b2df55aareed@google.com // pin center to the bounds of the bitmap 20049987ec3791336bad6af5cbe513564786b2df55aareed@google.com c.fLeft = SkMax32(0, center.fLeft); 20059987ec3791336bad6af5cbe513564786b2df55aareed@google.com c.fTop = SkMax32(0, center.fTop); 20069987ec3791336bad6af5cbe513564786b2df55aareed@google.com c.fRight = SkPin32(center.fRight, c.fLeft, w); 20079987ec3791336bad6af5cbe513564786b2df55aareed@google.com c.fBottom = SkPin32(center.fBottom, c.fTop, h); 20089987ec3791336bad6af5cbe513564786b2df55aareed@google.com 20097112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com const SkScalar srcX[4] = { 20107d474f8a84a74421bd8d119124daa64ec1710f76rmistry@google.com 0, SkIntToScalar(c.fLeft), SkIntToScalar(c.fRight), SkIntToScalar(w) 20117112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com }; 20127112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com const SkScalar srcY[4] = { 20137d474f8a84a74421bd8d119124daa64ec1710f76rmistry@google.com 0, SkIntToScalar(c.fTop), SkIntToScalar(c.fBottom), SkIntToScalar(h) 20147112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com }; 20159987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkScalar dstX[4] = { 20169987ec3791336bad6af5cbe513564786b2df55aareed@google.com dst.fLeft, dst.fLeft + SkIntToScalar(c.fLeft), 20179987ec3791336bad6af5cbe513564786b2df55aareed@google.com dst.fRight - SkIntToScalar(w - c.fRight), dst.fRight 20189987ec3791336bad6af5cbe513564786b2df55aareed@google.com }; 20199987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkScalar dstY[4] = { 20209987ec3791336bad6af5cbe513564786b2df55aareed@google.com dst.fTop, dst.fTop + SkIntToScalar(c.fTop), 20219987ec3791336bad6af5cbe513564786b2df55aareed@google.com dst.fBottom - SkIntToScalar(h - c.fBottom), dst.fBottom 20229987ec3791336bad6af5cbe513564786b2df55aareed@google.com }; 202374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 20249987ec3791336bad6af5cbe513564786b2df55aareed@google.com if (dstX[1] > dstX[2]) { 20259987ec3791336bad6af5cbe513564786b2df55aareed@google.com dstX[1] = dstX[0] + (dstX[3] - dstX[0]) * c.fLeft / (w - c.width()); 20269987ec3791336bad6af5cbe513564786b2df55aareed@google.com dstX[2] = dstX[1]; 20279987ec3791336bad6af5cbe513564786b2df55aareed@google.com } 202874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 20299987ec3791336bad6af5cbe513564786b2df55aareed@google.com if (dstY[1] > dstY[2]) { 20309987ec3791336bad6af5cbe513564786b2df55aareed@google.com dstY[1] = dstY[0] + (dstY[3] - dstY[0]) * c.fTop / (h - c.height()); 20319987ec3791336bad6af5cbe513564786b2df55aareed@google.com dstY[2] = dstY[1]; 20329987ec3791336bad6af5cbe513564786b2df55aareed@google.com } 203374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 20349987ec3791336bad6af5cbe513564786b2df55aareed@google.com for (int y = 0; y < 3; y++) { 20357112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com SkRect s, d; 20367112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com 20379987ec3791336bad6af5cbe513564786b2df55aareed@google.com s.fTop = srcY[y]; 20389987ec3791336bad6af5cbe513564786b2df55aareed@google.com s.fBottom = srcY[y+1]; 20399987ec3791336bad6af5cbe513564786b2df55aareed@google.com d.fTop = dstY[y]; 20409987ec3791336bad6af5cbe513564786b2df55aareed@google.com d.fBottom = dstY[y+1]; 20419987ec3791336bad6af5cbe513564786b2df55aareed@google.com for (int x = 0; x < 3; x++) { 20429987ec3791336bad6af5cbe513564786b2df55aareed@google.com s.fLeft = srcX[x]; 20439987ec3791336bad6af5cbe513564786b2df55aareed@google.com s.fRight = srcX[x+1]; 20449987ec3791336bad6af5cbe513564786b2df55aareed@google.com d.fLeft = dstX[x]; 20459987ec3791336bad6af5cbe513564786b2df55aareed@google.com d.fRight = dstX[x+1]; 2046eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org this->internalDrawBitmapRect(bitmap, &s, d, paint, 204731acc11977815402e4ef2681350f8559285bec97robertphillips@google.com kNone_DrawBitmapRectFlag); 20489987ec3791336bad6af5cbe513564786b2df55aareed@google.com } 20499987ec3791336bad6af5cbe513564786b2df55aareed@google.com } 20509987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 20519987ec3791336bad6af5cbe513564786b2df55aareed@google.com 20529987ec3791336bad6af5cbe513564786b2df55aareed@google.comvoid SkCanvas::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, 20539987ec3791336bad6af5cbe513564786b2df55aareed@google.com const SkRect& dst, const SkPaint* paint) { 20548f757f540a8378c7b1354aab3d4650eaa920b17adanakj TRACE_EVENT0("skia", "SkCanvas::drawBitmapNine()"); 20559987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkDEBUGCODE(bitmap.validate();) 20569987ec3791336bad6af5cbe513564786b2df55aareed@google.com 20579987ec3791336bad6af5cbe513564786b2df55aareed@google.com // Need a device entry-point, so gpu can use a mesh 20589987ec3791336bad6af5cbe513564786b2df55aareed@google.com this->internalDrawBitmapNine(bitmap, center, dst, paint); 20599987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 20609987ec3791336bad6af5cbe513564786b2df55aareed@google.com 2061f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.comclass SkDeviceFilteredPaint { 2062f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.compublic: 20631f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkDeviceFilteredPaint(SkBaseDevice* device, const SkPaint& paint) { 20641f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice::TextFlags flags; 2065f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com if (device->filterTextFlags(paint, &flags)) { 2066a076e9be17654a60310e72c4f70fcd5337f56dbfreed@google.com SkPaint* newPaint = fLazy.set(paint); 2067f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com newPaint->setFlags(flags.fFlags); 2068f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com fPaint = newPaint; 2069f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } else { 2070f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com fPaint = &paint; 2071f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } 2072f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } 2073f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 2074f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com const SkPaint& paint() const { return *fPaint; } 2075f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 2076f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.comprivate: 20772c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint* fPaint; 20782c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkLazyPaint fLazy; 2079f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com}; 2080f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 208152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.comvoid SkCanvas::DrawRect(const SkDraw& draw, const SkPaint& paint, 208252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com const SkRect& r, SkScalar textSize) { 208317b78946096265d80215a6c946286ecaa35ea7edepoger@google.com if (paint.getStyle() == SkPaint::kFill_Style) { 208452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com draw.fDevice->drawRect(draw, r, paint); 208552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } else { 208652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPaint p(paint); 208717b78946096265d80215a6c946286ecaa35ea7edepoger@google.com p.setStrokeWidth(SkScalarMul(textSize, paint.getStrokeWidth())); 208852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com draw.fDevice->drawRect(draw, r, p); 208952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 209052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com} 209152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 209252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.comvoid SkCanvas::DrawTextDecorations(const SkDraw& draw, const SkPaint& paint, 209352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com const char text[], size_t byteLength, 209452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar x, SkScalar y) { 209552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkASSERT(byteLength == 0 || text != NULL); 209652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 209752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com // nothing to draw 209852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (text == NULL || byteLength == 0 || 209952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com draw.fClip->isEmpty() || 210052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com (paint.getAlpha() == 0 && paint.getXfermode() == NULL)) { 210152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com return; 210252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 210352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 210452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar width = 0; 210552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPoint start; 210652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 210752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.set(0, 0); // to avoid warning 210852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (paint.getFlags() & (SkPaint::kUnderlineText_Flag | 210952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPaint::kStrikeThruText_Flag)) { 211052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com width = paint.measureText(text, byteLength); 211152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 211252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar offsetX = 0; 211352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (paint.getTextAlign() == SkPaint::kCenter_Align) { 211452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com offsetX = SkScalarHalf(width); 211552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } else if (paint.getTextAlign() == SkPaint::kRight_Align) { 211652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com offsetX = width; 211752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 211852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.set(x - offsetX, y); 211952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 212052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 212152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (0 == width) { 212252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com return; 212352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 212452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 212552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com uint32_t flags = paint.getFlags(); 212652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 212752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (flags & (SkPaint::kUnderlineText_Flag | 212852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPaint::kStrikeThruText_Flag)) { 212952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar textSize = paint.getTextSize(); 213052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar height = SkScalarMul(textSize, kStdUnderline_Thickness); 213152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkRect r; 213252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 213352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fLeft = start.fX; 213452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fRight = start.fX + width; 213552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 213652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (flags & SkPaint::kUnderlineText_Flag) { 213752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar offset = SkScalarMulAdd(textSize, kStdUnderline_Offset, 213852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.fY); 213952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fTop = offset; 214052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fBottom = offset + height; 214152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com DrawRect(draw, paint, r, textSize); 214252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 214352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (flags & SkPaint::kStrikeThruText_Flag) { 214452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar offset = SkScalarMulAdd(textSize, kStdStrikeThru_Offset, 214552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.fY); 214652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fTop = offset; 214752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fBottom = offset + height; 214852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com DrawRect(draw, paint, r, textSize); 214952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 215052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 215152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com} 215252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 2153e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 2154e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 215578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL) 21568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 21584e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 2159f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com iter.fDevice->drawText(iter, text, byteLength, x, y, dfp.paint()); 216052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com DrawTextDecorations(iter, dfp.paint(), 216152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com static_cast<const char*>(text), byteLength, x, y); 21628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 21638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21644e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 21658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 21668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2167e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], 2168e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 216905c4a4322e7d4f3417b7df33825bab8603d52051fmalita SkPoint textOffset = SkPoint::Make(0, 0); 217005c4a4322e7d4f3417b7df33825bab8603d52051fmalita 217178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL) 217287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 21738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 21744e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 217505c4a4322e7d4f3417b7df33825bab8603d52051fmalita iter.fDevice->drawPosText(iter, text, byteLength, &pos->fX, 2, textOffset, 2176f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com dfp.paint()); 21778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2178b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 21794e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 21808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 21818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2182e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], 2183e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com SkScalar constY, const SkPaint& paint) { 218405c4a4322e7d4f3417b7df33825bab8603d52051fmalita 218505c4a4322e7d4f3417b7df33825bab8603d52051fmalita SkPoint textOffset = SkPoint::Make(0, constY); 218605c4a4322e7d4f3417b7df33825bab8603d52051fmalita 218778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL) 218887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 21898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 21904e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 219105c4a4322e7d4f3417b7df33825bab8603d52051fmalita iter.fDevice->drawPosText(iter, text, byteLength, xpos, 1, textOffset, 2192f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com dfp.paint()); 21938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2194b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 21954e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 21968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 21978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2198e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 2199e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkMatrix* matrix, const SkPaint& paint) { 220078cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL) 220187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 22028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 22038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawTextOnPath(iter, text, byteLength, path, 22044e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com matrix, looper.paint()); 22058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2206b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 2207945ec3a2bec668ca845071a65df8ec55e8f43819commit-bot@chromium.org LOOPER_END 22084325d114a5679e46f25ae75b0e43547fd7694998commit-bot@chromium.org} 22094325d114a5679e46f25ae75b0e43547fd7694998commit-bot@chromium.org 221000d5c2c6523321d25b32905ff4822f083a4173eefmalitavoid SkCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 221100d5c2c6523321d25b32905ff4822f083a4173eefmalita const SkPaint& paint) { 22127ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita 221319653d1d004610b4ba07ce563a5701164e120e45fmalita if (paint.canComputeFastBounds()) { 22147ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita SkRect storage; 22157ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita 22167ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita if (this->quickReject(paint.computeFastBounds(blob->bounds().makeOffset(x, y), &storage))) { 22177ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita return; 22187ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita } 22197ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita } 22207ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita 2221aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL) 222200d5c2c6523321d25b32905ff4822f083a4173eefmalita 2223aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita while (iter.next()) { 2224aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 2225aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita iter.fDevice->drawTextBlob(iter, blob, x, y, dfp.paint()); 222600d5c2c6523321d25b32905ff4822f083a4173eefmalita } 222700d5c2c6523321d25b32905ff4822f083a4173eefmalita 2228aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita LOOPER_END 222900d5c2c6523321d25b32905ff4822f083a4173eefmalita} 223000d5c2c6523321d25b32905ff4822f083a4173eefmalita 2231e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com// These will become non-virtual, so they always call the (virtual) onDraw... method 2232e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 2233e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 22348f757f540a8378c7b1354aab3d4650eaa920b17adanakj TRACE_EVENT0("skia", "SkCanvas::drawText()"); 2235e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawText(text, byteLength, x, y, paint); 2236e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2237e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawPosText(const void* text, size_t byteLength, const SkPoint pos[], 2238e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 22398f757f540a8378c7b1354aab3d4650eaa920b17adanakj TRACE_EVENT0("skia", "SkCanvas::drawPosText()"); 2240e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawPosText(text, byteLength, pos, paint); 2241e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2242e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], 2243e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com SkScalar constY, const SkPaint& paint) { 22448f757f540a8378c7b1354aab3d4650eaa920b17adanakj TRACE_EVENT0("skia", "SkCanvas::drawPosTextH()"); 2245e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawPosTextH(text, byteLength, xpos, constY, paint); 2246e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2247e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 2248e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkMatrix* matrix, const SkPaint& paint) { 22498f757f540a8378c7b1354aab3d4650eaa920b17adanakj TRACE_EVENT0("skia", "SkCanvas::drawTextOnPath()"); 2250e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawTextOnPath(text, byteLength, path, matrix, paint); 2251e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 225200d5c2c6523321d25b32905ff4822f083a4173eefmalitavoid SkCanvas::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 225300d5c2c6523321d25b32905ff4822f083a4173eefmalita const SkPaint& paint) { 22548f757f540a8378c7b1354aab3d4650eaa920b17adanakj TRACE_EVENT0("skia", "SkCanvas::drawTextBlob()"); 225549f085dddff10473b6ebf832a974288300224e60bsalomon if (blob) { 225600d5c2c6523321d25b32905ff4822f083a4173eefmalita this->onDrawTextBlob(blob, x, y, paint); 225700d5c2c6523321d25b32905ff4822f083a4173eefmalita } 225800d5c2c6523321d25b32905ff4822f083a4173eefmalita} 2259e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com 22608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawVertices(VertexMode vmode, int vertexCount, 22618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPoint verts[], const SkPoint texs[], 22628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkColor colors[], SkXfermode* xmode, 22638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint16_t indices[], int indexCount, 22648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 22658f757f540a8378c7b1354aab3d4650eaa920b17adanakj TRACE_EVENT0("skia", "SkCanvas::drawVertices()"); 226678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, NULL) 22674b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 22688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 22698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawVertices(iter, vmode, vertexCount, verts, texs, 22704e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com colors, xmode, indices, indexCount, 22714e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com looper.paint()); 22728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 22734b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 22744e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 22758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 22768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2277b3c9d1c33caf325aada244204215eb790c228c12dandovvoid SkCanvas::drawPatch(const SkPoint cubics[12], const SkColor colors[4], 2278b3c9d1c33caf325aada244204215eb790c228c12dandov const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint) { 22798f757f540a8378c7b1354aab3d4650eaa920b17adanakj TRACE_EVENT0("skia", "SkCanvas::drawPatch()"); 2280b3c9d1c33caf325aada244204215eb790c228c12dandov if (NULL == cubics) { 2281b3c9d1c33caf325aada244204215eb790c228c12dandov return; 2282b3c9d1c33caf325aada244204215eb790c228c12dandov } 22836cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2284ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov // Since a patch is always within the convex hull of the control points, we discard it when its 2285ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov // bounding rectangle is completely outside the current clip. 2286ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov SkRect bounds; 2287b3c9d1c33caf325aada244204215eb790c228c12dandov bounds.set(cubics, SkPatchUtils::kNumCtrlPts); 2288ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov if (this->quickReject(bounds)) { 2289ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov return; 2290ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov } 22916cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2292b3c9d1c33caf325aada244204215eb790c228c12dandov this->onDrawPatch(cubics, colors, texCoords, xmode, paint); 2293b3c9d1c33caf325aada244204215eb790c228c12dandov} 2294b3c9d1c33caf325aada244204215eb790c228c12dandov 2295b3c9d1c33caf325aada244204215eb790c228c12dandovvoid SkCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], 2296b3c9d1c33caf325aada244204215eb790c228c12dandov const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint) { 2297b3c9d1c33caf325aada244204215eb790c228c12dandov 2298ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, NULL) 22996cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2300ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov while (iter.next()) { 2301b3c9d1c33caf325aada244204215eb790c228c12dandov iter.fDevice->drawPatch(iter, cubics, colors, texCoords, xmode, paint); 2302ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov } 23036cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2304ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov LOOPER_END 2305ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov} 2306ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov 23078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 23088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// These methods are NOT virtual, and therefore must call back into virtual 23098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// methods, rather than actually drawing themselves. 23108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 23118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b, 2313845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com SkXfermode::Mode mode) { 23148f757f540a8378c7b1354aab3d4650eaa920b17adanakj TRACE_EVENT0("skia", "SkCanvas::drawARGB()"); 23158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 23168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setARGB(a, r, g, b); 2318845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com if (SkXfermode::kSrcOver_Mode != mode) { 23190baf19375466cfc24c96532df406e7c5b1d1aae8reed@android.com paint.setXfermodeMode(mode); 23208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPaint(paint); 23228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2324845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.comvoid SkCanvas::drawColor(SkColor c, SkXfermode::Mode mode) { 23258f757f540a8378c7b1354aab3d4650eaa920b17adanakj TRACE_EVENT0("skia", "SkCanvas::drawColor()"); 23268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 23278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setColor(c); 2329845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com if (SkXfermode::kSrcOver_Mode != mode) { 23300baf19375466cfc24c96532df406e7c5b1d1aae8reed@android.com paint.setXfermodeMode(mode); 23318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPaint(paint); 23338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPoint(SkScalar x, SkScalar y, const SkPaint& paint) { 23368f757f540a8378c7b1354aab3d4650eaa920b17adanakj TRACE_EVENT0("skia", "SkCanvas::drawPoint(SkPaint)"); 23378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pt; 23384b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 23398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pt.set(x, y); 23408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kPoints_PointMode, 1, &pt, paint); 23418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPoint(SkScalar x, SkScalar y, SkColor color) { 23448f757f540a8378c7b1354aab3d4650eaa920b17adanakj TRACE_EVENT0("skia", "SkCanvas::drawPoint(SkColor)"); 23458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pt; 23468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 23474b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 23488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pt.set(x, y); 23498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setColor(color); 23508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kPoints_PointMode, 1, &pt, paint); 23518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, 23548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 23558f757f540a8378c7b1354aab3d4650eaa920b17adanakj TRACE_EVENT0("skia", "SkCanvas::drawLine()"); 23568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pts[2]; 23574b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 23588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pts[0].set(x0, y0); 23598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pts[1].set(x1, y1); 23608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kLines_PointMode, 2, pts, paint); 23618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawRectCoords(SkScalar left, SkScalar top, 23648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar right, SkScalar bottom, 23658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 23668f757f540a8378c7b1354aab3d4650eaa920b17adanakj TRACE_EVENT0("skia", "SkCanvas::drawRectCoords()"); 23678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 23688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.set(left, top, right, bottom); 23708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawRect(r, paint); 23718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, 23748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 23758f757f540a8378c7b1354aab3d4650eaa920b17adanakj TRACE_EVENT0("skia", "SkCanvas::drawCircle()"); 23768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (radius < 0) { 23778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com radius = 0; 23788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 23818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.set(cx - radius, cy - radius, cx + radius, cy + radius); 23824ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->drawOval(r, paint); 23838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawRoundRect(const SkRect& r, SkScalar rx, SkScalar ry, 23868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 23878f757f540a8378c7b1354aab3d4650eaa920b17adanakj TRACE_EVENT0("skia", "SkCanvas::drawRoundRect()"); 23888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (rx > 0 && ry > 0) { 23898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.canComputeFastBounds()) { 23908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect storage; 23913b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(paint.computeFastBounds(r, &storage))) { 23928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 23938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23954ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com SkRRect rrect; 23964ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com rrect.setRectXY(r, rx, ry); 23974ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->drawRRect(rrect, paint); 23988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 23998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawRect(r, paint); 24008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 24018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawArc(const SkRect& oval, SkScalar startAngle, 24048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar sweepAngle, bool useCenter, 24058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 24068f757f540a8378c7b1354aab3d4650eaa920b17adanakj TRACE_EVENT0("skia", "SkCanvas::drawArc()"); 24078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (SkScalarAbs(sweepAngle) >= SkIntToScalar(360)) { 24088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawOval(oval, paint); 24098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 24108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath path; 24118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (useCenter) { 24128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.moveTo(oval.centerX(), oval.centerY()); 24138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 24148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.arcTo(oval, startAngle, sweepAngle, !useCenter); 24158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (useCenter) { 24168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.close(); 24178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 24188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPath(path, paint); 24198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 24208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawTextOnPathHV(const void* text, size_t byteLength, 24238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPath& path, SkScalar hOffset, 24248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar vOffset, const SkPaint& paint) { 24258f757f540a8378c7b1354aab3d4650eaa920b17adanakj TRACE_EVENT0("skia", "SkCanvas::drawTextOnPathHV()"); 24268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 24274b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 24288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.setTranslate(hOffset, vOffset); 24298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawTextOnPath(text, byteLength, path, &matrix, paint); 24308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2432f76bacff7f66724072c67edb185abf9e3add11a0reed@android.com/////////////////////////////////////////////////////////////////////////////// 24339b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillipsvoid SkCanvas::EXPERIMENTAL_optimize(const SkPicture* picture) { 2434145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org SkBaseDevice* device = this->getDevice(); 243549f085dddff10473b6ebf832a974288300224e60bsalomon if (device) { 2436145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org device->EXPERIMENTAL_optimize(picture); 2437145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org } 2438145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org} 2439f76bacff7f66724072c67edb185abf9e3add11a0reed@android.com 24409b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillipsvoid SkCanvas::drawPicture(const SkPicture* picture) { 24418f757f540a8378c7b1354aab3d4650eaa920b17adanakj TRACE_EVENT0("skia", "SkCanvas::drawPicture()"); 244249f085dddff10473b6ebf832a974288300224e60bsalomon if (picture) { 2443d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed this->onDrawPicture(picture, NULL, NULL); 24449b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips } 24459b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips} 24469b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips 2447d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedvoid SkCanvas::drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint) { 24488f757f540a8378c7b1354aab3d4650eaa920b17adanakj TRACE_EVENT0("skia", "SkCanvas::drawPicture(SkMatrix, SkPaint)"); 244949f085dddff10473b6ebf832a974288300224e60bsalomon if (picture) { 2450d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed if (matrix && matrix->isIdentity()) { 2451d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed matrix = NULL; 2452d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 2453d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed this->onDrawPicture(picture, matrix, paint); 2454d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 2455d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 24569b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips 2457d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedvoid SkCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix, 2458d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed const SkPaint* paint) { 2459145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org SkBaseDevice* device = this->getTopDevice(); 246049f085dddff10473b6ebf832a974288300224e60bsalomon if (device) { 2461145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org // Canvas has to first give the device the opportunity to render 2462145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org // the picture itself. 2463d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed if (device->EXPERIMENTAL_drawPicture(this, picture, matrix, paint)) { 2464145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org return; // the device has rendered the entire picture 2465145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org } 2466145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org } 2467145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org 2468a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); 2469d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 2470c5ba71d2e5cd426def66fa49dcf003e5b2c98dc7robertphillips picture->playback(this); 24718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 24748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 24758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::LayerIter::LayerIter(SkCanvas* canvas, bool skipEmptyClips) { 2477d642329293cce602ac24df8f585c14a98795da87reed@google.com SK_COMPILE_ASSERT(sizeof(fStorage) >= sizeof(SkDrawIter), fStorage_too_small); 24788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(canvas); 24808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fImpl = new (fStorage) SkDrawIter(canvas, skipEmptyClips); 24828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDone = !fImpl->next(); 24838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::LayerIter::~LayerIter() { 24868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fImpl->~SkDrawIter(); 24878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::LayerIter::next() { 24908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDone = !fImpl->next(); 24918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24931f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::LayerIter::device() const { 24948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fImpl->getDevice(); 24958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkMatrix& SkCanvas::LayerIter::matrix() const { 24988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fImpl->getMatrix(); 24998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 25008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkPaint& SkCanvas::LayerIter::paint() const { 25028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* paint = fImpl->getPaint(); 25038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == paint) { 25048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint = &fDefaultPaint; 25058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 25068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return *paint; 25078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 25088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkRegion& SkCanvas::LayerIter::clip() const { return fImpl->getClip(); } 25108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::LayerIter::x() const { return fImpl->getX(); } 25118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::LayerIter::y() const { return fImpl->getY(); } 251220a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com 251320a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com/////////////////////////////////////////////////////////////////////////////// 251420a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com 2515c3b589a24eb4d567a906189f882c259ecf5c2f58fmalitaSkCanvasClipVisitor::~SkCanvasClipVisitor() { } 25163107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 25173107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 25183107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 25193107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.orgstatic bool supported_for_raster_canvas(const SkImageInfo& info) { 25203107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org switch (info.alphaType()) { 25213107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kPremul_SkAlphaType: 25223107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kOpaque_SkAlphaType: 25233107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org break; 25243107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org default: 25253107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return false; 25263107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 25273107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 25283107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org switch (info.colorType()) { 25293107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kAlpha_8_SkColorType: 25303107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kRGB_565_SkColorType: 253128fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org case kN32_SkColorType: 25323107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org break; 25333107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org default: 25343107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return false; 25353107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 25363107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 25373107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return true; 25383107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org} 25393107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 25403107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.orgSkCanvas* SkCanvas::NewRaster(const SkImageInfo& info) { 25413107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org if (!supported_for_raster_canvas(info)) { 25423107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return NULL; 25433107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 25443107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 25453107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org SkBitmap bitmap; 2546848250415eddc54075f7eb8795e8db79e749c6abreed if (!bitmap.tryAllocPixels(info)) { 25473107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return NULL; 25483107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 25493107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 25503107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org // should this functionality be moved into allocPixels()? 25513107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org if (!bitmap.info().isOpaque()) { 25523107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org bitmap.eraseColor(0); 25533107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 25543107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return SkNEW_ARGS(SkCanvas, (bitmap)); 25553107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org} 255642b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org 255742b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.orgSkCanvas* SkCanvas::NewRasterDirect(const SkImageInfo& info, void* pixels, size_t rowBytes) { 255842b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org if (!supported_for_raster_canvas(info)) { 255942b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org return NULL; 256042b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org } 2561eb849e5fd10cbe00cbc31307ba97fd9efca0b41bskia.committer@gmail.com 256242b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org SkBitmap bitmap; 256342b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org if (!bitmap.installPixels(info, pixels, rowBytes)) { 256442b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org return NULL; 256542b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org } 256642b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org return SkNEW_ARGS(SkCanvas, (bitmap)); 256742b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org} 2568d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 2569d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed/////////////////////////////////////////////////////////////////////////////// 2570d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 2571d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedSkAutoCanvasMatrixPaint::SkAutoCanvasMatrixPaint(SkCanvas* canvas, const SkMatrix* matrix, 2572a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips const SkPaint* paint, const SkRect& bounds) 2573d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed : fCanvas(canvas) 2574d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed , fSaveCount(canvas->getSaveCount()) 2575d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed{ 257649f085dddff10473b6ebf832a974288300224e60bsalomon if (paint) { 2577a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkRect newBounds = bounds; 2578d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed if (matrix) { 2579a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips matrix->mapRect(&newBounds); 2580d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 2581a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips canvas->saveLayer(&newBounds, paint); 258249f085dddff10473b6ebf832a974288300224e60bsalomon } else if (matrix) { 2583d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed canvas->save(); 2584d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 25856cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 258649f085dddff10473b6ebf832a974288300224e60bsalomon if (matrix) { 2587d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed canvas->concat(*matrix); 2588d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 2589d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 2590d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 2591d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedSkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { 2592d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed fCanvas->restoreToCount(fSaveCount); 2593d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 2594