SkCanvas.cpp revision d954498c01ccf0417feacf89e45d0c62a06a813b
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 89f0147143fbedba10bdae496d812a14995304924reed 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h" 10d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed#include "SkCanvasPriv.h" 111f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com#include "SkBitmapDevice.h" 129c39744a00573b7133fc765b0a9d50a0ceace7b8senorblanco@chromium.org#include "SkDeviceImageFilterProxy.h" 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDraw.h" 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDrawFilter.h" 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDrawLooper.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" 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkUtils.h" 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#if SK_SUPPORT_GPU 31644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#include "GrRenderTarget.h" 32644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#endif 33644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org 34da17f758442f16747af39f8fbaed9c097048519creed@google.com// experimental for faster tiled drawing... 35da17f758442f16747af39f8fbaed9c097048519creed@google.com//#define SK_ENABLE_CLIP_QUICKREJECT 3615e9d3e66e161ce23df30bc13f8a0c87d196b463robertphillips@google.com 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//#define SK_TRACE_SAVERESTORE 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_TRACE_SAVERESTORE 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gLayerCounter; 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_layer() { ++gLayerCounter; printf("----- inc layer %d\n", gLayerCounter); } 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_layer() { --gLayerCounter; printf("----- dec layer %d\n", gLayerCounter); } 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gRecCounter; 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_rec() { ++gRecCounter; printf("----- inc rec %d\n", gRecCounter); } 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_rec() { --gRecCounter; printf("----- dec rec %d\n", gRecCounter); } 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gCanvasCounter; 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_canvas() { ++gCanvasCounter; printf("----- inc canvas %d\n", gCanvasCounter); } 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_canvas() { --gCanvasCounter; printf("----- dec canvas %d\n", gCanvasCounter); } 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_layer() 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_layer() 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_rec() 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_rec() 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_canvas() 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_canvas() 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 602c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.orgtypedef SkTLazy<SkPaint> SkLazyPaint; 612c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org 6297af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.comvoid SkCanvas::predrawNotify() { 6397af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com if (fSurfaceBase) { 64c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org fSurfaceBase->aboutToDraw(SkSurface::kRetain_ContentChangeMode); 6597af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com } 6697af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com} 6797af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 701f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com/* This is the record we keep for each SkBaseDevice that the user installs. 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com The clip/matrix/proc are fields that reflect the top of the save/restore 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stack. Whenever the canvas changes, it marks a dirty flag, and then before 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com these are used (assuming we're not on a layer) we rebuild these cache 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com values: they reflect the top of the save stack, but translated and clipped 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com by the device's XY offset and bitmap-bounds. 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct DeviceCM { 788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* fNext; 791f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* fDevice; 80045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com SkRasterClip fClip; 818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix* fMatrix; 826f8f292aa768869a9e85c314b124875f57504f2creed@google.com SkPaint* fPaint; // may be null (in the future) 838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 84d954498c01ccf0417feacf89e45d0c62a06a813breed DeviceCM(SkBaseDevice* device, int x, int y, const SkPaint* paint, SkCanvas* canvas, 85d954498c01ccf0417feacf89e45d0c62a06a813breed bool conservativeRasterClip) 86d954498c01ccf0417feacf89e45d0c62a06a813breed : fNext(NULL) 87d954498c01ccf0417feacf89e45d0c62a06a813breed , fClip(conservativeRasterClip) 88d954498c01ccf0417feacf89e45d0c62a06a813breed { 89d954498c01ccf0417feacf89e45d0c62a06a813breed if (NULL != device) { 908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device->ref(); 9140a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com device->onAttachToCanvas(canvas); 928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 934b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com fDevice = device; 948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint = paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL; 9588edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9788edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com ~DeviceCM() { 9849f085dddff10473b6ebf832a974288300224e60bsalomon if (fDevice) { 9940a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com fDevice->onDetachFromCanvas(); 1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDevice->unref(); 1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10288edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com SkDELETE(fPaint); 10388edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 1044b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 105045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com void updateMC(const SkMatrix& totalMatrix, const SkRasterClip& totalClip, 106045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com const SkClipStack& clipStack, SkRasterClip* updateClip) { 1076f8f292aa768869a9e85c314b124875f57504f2creed@google.com int x = fDevice->getOrigin().x(); 1086f8f292aa768869a9e85c314b124875f57504f2creed@google.com int y = fDevice->getOrigin().y(); 1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int width = fDevice->width(); 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int height = fDevice->height(); 1114b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if ((x | y) == 0) { 1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = &totalMatrix; 1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fClip = totalClip; 1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrixStorage = totalMatrix; 1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrixStorage.postTranslate(SkIntToScalar(-x), 1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIntToScalar(-y)); 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = &fMatrixStorage; 1204b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com totalClip.translate(-x, -y, &fClip); 1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 124045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com fClip.op(SkIRect::MakeWH(width, height), SkRegion::kIntersect_Op); 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // intersect clip, but don't translate it (yet) 1274b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (updateClip) { 129045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com updateClip->op(SkIRect::MakeXYWH(x, y, width, height), 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRegion::kDifference_Op); 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1324b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 1333fffb2ee9fa01ae61efb2395973eb7575eda4c96robertphillips@google.com fDevice->setMatrixClip(*fMatrix, fClip.forceGetBW(), clipStack); 1343fffb2ee9fa01ae61efb2395973eb7575eda4c96robertphillips@google.com 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!fClip.isEmpty()) { 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIRect deviceR; 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com deviceR.set(0, 0, width, height); 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(deviceR.contains(fClip.getBounds())); 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 142f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 143f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 1450e354aacd84d3bede3f97cbde35a54ba62a89533bsalomon@google.com SkMatrix fMatrixStorage; 1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* This is the record we keep for each save/restore level in the stack. 1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Since a level optionally copies the matrix and/or stack, we have pointers 1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for these fields. If the value is copied for this level, the copy is 1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stored in the ...Storage field, and the pointer points to that. If the 1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value is not copied for this level, we ignore ...Storage, and just point 1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com at the corresponding value in the previous level in the stack. 1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkCanvas::MCRec { 1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 1576f09709519b79a1159f3826645f1c5fbc101ee11reed SkRasterClip fRasterClip; 158d954498c01ccf0417feacf89e45d0c62a06a813breed SkMatrix fMatrix; 1591f836ee096bb988adef4b9757b2629c7afeda36dreed SkDrawFilter* fFilter; // the current filter (or null) 160d954498c01ccf0417feacf89e45d0c62a06a813breed DeviceCM* fLayer; 1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* If there are any layers in the stack, this points to the top-most 1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com one that is at or below this level in the stack (so we know what 1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bitmap/device to draw into from this level. This value is NOT 1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com reference counted, since the real owner is either our fLayer field, 1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com or a previous one in a lower level.) 1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 16788edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com DeviceCM* fTopLayer; 1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 169d954498c01ccf0417feacf89e45d0c62a06a813breed MCRec(bool conservativeRasterClip) : fRasterClip(conservativeRasterClip) { 170d954498c01ccf0417feacf89e45d0c62a06a813breed fMatrix.reset(); 171d954498c01ccf0417feacf89e45d0c62a06a813breed fFilter = NULL; 172d954498c01ccf0417feacf89e45d0c62a06a813breed fLayer = NULL; 173d954498c01ccf0417feacf89e45d0c62a06a813breed fTopLayer = NULL; 174d954498c01ccf0417feacf89e45d0c62a06a813breed 175d954498c01ccf0417feacf89e45d0c62a06a813breed // don't bother initializing fNext 176d954498c01ccf0417feacf89e45d0c62a06a813breed inc_rec(); 177d954498c01ccf0417feacf89e45d0c62a06a813breed } 178d954498c01ccf0417feacf89e45d0c62a06a813breed MCRec(const MCRec& prev) : fRasterClip(prev.fRasterClip) { 179d954498c01ccf0417feacf89e45d0c62a06a813breed fMatrix = prev.fMatrix; 180d954498c01ccf0417feacf89e45d0c62a06a813breed fFilter = SkSafeRef(prev.fFilter); 1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLayer = NULL; 182d954498c01ccf0417feacf89e45d0c62a06a813breed fTopLayer = prev.fTopLayer; 183d954498c01ccf0417feacf89e45d0c62a06a813breed 1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // don't bother initializing fNext 1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inc_rec(); 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ~MCRec() { 18882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fFilter); 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDELETE(fLayer); 1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dec_rec(); 1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkDrawIter : public SkDraw { 1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 1968a0b0291ae4260ef2a46f4341c18a702c0ce3f8btomhudson@google.com SkDrawIter(SkCanvas* canvas, bool skipEmptyClips = true) { 1974370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com canvas = canvas->canvasForDrawIter(); 1988a0b0291ae4260ef2a46f4341c18a702c0ce3f8btomhudson@google.com fCanvas = canvas; 1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com canvas->updateDeviceCMCache(); 2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20190c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com fClipStack = &canvas->fClipStack; 2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = canvas->fMCRec->fTopLayer; 2038a0b0291ae4260ef2a46f4341c18a702c0ce3f8btomhudson@google.com fSkipEmptyClips = skipEmptyClips; 2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2054b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool next() { 2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // skip over recs with empty clips 2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fSkipEmptyClips) { 2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (fCurrLayer && fCurrLayer->fClip.isEmpty()) { 2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = fCurrLayer->fNext; 2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 214f68c5e2f9f05b3af2bae0979ace2684b6041b6e3reed@google.com const DeviceCM* rec = fCurrLayer; 215f68c5e2f9f05b3af2bae0979ace2684b6041b6e3reed@google.com if (rec && rec->fDevice) { 2168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = rec->fMatrix; 218045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com fClip = &((SkRasterClip*)&rec->fClip)->forceGetBW(); 219045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com fRC = &rec->fClip; 2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDevice = rec->fDevice; 2218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBitmap = &fDevice->accessBitmap(true); 2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint = rec->fPaint; 223f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com SkDEBUGCODE(this->validate();) 2248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = rec->fNext; 2268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // fCurrLayer may be NULL now 227199f108f14a5f60a9c2205ffa79b26102a206ad0reed@android.com 2288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2324b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2331f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* getDevice() const { return fDevice; } 2346f8f292aa768869a9e85c314b124875f57504f2creed@google.com int getX() const { return fDevice->getOrigin().x(); } 2356f8f292aa768869a9e85c314b124875f57504f2creed@google.com int getY() const { return fDevice->getOrigin().y(); } 2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& getMatrix() const { return *fMatrix; } 2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkRegion& getClip() const { return *fClip; } 2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* getPaint() const { return fPaint; } 2396f8f292aa768869a9e85c314b124875f57504f2creed@google.com 2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkCanvas* fCanvas; 2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const DeviceCM* fCurrLayer; 2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* fPaint; // May be null. 2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkBool8 fSkipEmptyClips; 2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef SkDraw INHERITED; 2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////// 2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass AutoDrawLooper { 2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 2538926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com AutoDrawLooper(SkCanvas* canvas, const SkPaint& paint, 25478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bool skipLayerForImageFilter = false, 25578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL) : fOrigPaint(paint) { 2564e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fCanvas = canvas; 2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFilter = canvas->getDrawFilter(); 2584e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fPaint = NULL; 2594e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fSaveCount = canvas->getSaveCount(); 2608926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com fDoClearImageFilter = false; 2614e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fDone = false; 2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2638926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com if (!skipLayerForImageFilter && fOrigPaint.getImageFilter()) { 2648926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkPaint tmp; 2658926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com tmp.setImageFilter(fOrigPaint.getImageFilter()); 266e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org (void)canvas->internalSaveLayer(bounds, &tmp, SkCanvas::kARGB_ClipLayer_SaveFlag, 267e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org true, SkCanvas::kFullLayer_SaveLayerStrategy); 2688926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com // we'll clear the imageFilter for the actual draws in next(), so 2698926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com // it will only be applied during the restore(). 2708926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com fDoClearImageFilter = true; 2718926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 2728926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 27379fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (SkDrawLooper* looper = paint.getLooper()) { 27479fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org void* buffer = fLooperContextAllocator.reserveT<SkDrawLooper::Context>( 27579fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org looper->contextSize()); 27679fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org fLooperContext = looper->createContext(canvas, buffer); 277129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fIsSimple = false; 278129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else { 27979fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org fLooperContext = NULL; 280129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // can we be marked as simple? 281129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fIsSimple = !fFilter && !fDoClearImageFilter; 2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 28474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2854e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com ~AutoDrawLooper() { 2868926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com if (fDoClearImageFilter) { 2878926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com fCanvas->internalRestore(); 2888926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 2894e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkASSERT(fCanvas->getSaveCount() == fSaveCount); 2908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 29174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2924e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com const SkPaint& paint() const { 2934e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkASSERT(fPaint); 2944e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return *fPaint; 2954e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 29674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 297129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool next(SkDrawFilter::Type drawType) { 298129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com if (fDone) { 299129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return false; 300129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else if (fIsSimple) { 301129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fDone = true; 302129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fPaint = &fOrigPaint; 303129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return !fPaint->nothingToDraw(); 304129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else { 305129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return this->doNext(drawType); 306129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 307fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 30874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 3098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 3102c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkLazyPaint fLazyPaint; 3112c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkCanvas* fCanvas; 3122c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint& fOrigPaint; 3132c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkDrawFilter* fFilter; 3142c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint* fPaint; 3152c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org int fSaveCount; 3168926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com bool fDoClearImageFilter; 3172c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org bool fDone; 318129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool fIsSimple; 31979fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkDrawLooper::Context* fLooperContext; 32079fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkSmallAllocator<1, 32> fLooperContextAllocator; 321129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com 322129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool doNext(SkDrawFilter::Type drawType); 3238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 325129ec22cb054592261e001294c430c9dd4e90ff4reed@google.combool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) { 326632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com fPaint = NULL; 327129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com SkASSERT(!fIsSimple); 32879fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkASSERT(fLooperContext || fFilter || fDoClearImageFilter); 329632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com 330129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com SkPaint* paint = fLazyPaint.set(fOrigPaint); 3318926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 332129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com if (fDoClearImageFilter) { 333129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com paint->setImageFilter(NULL); 334129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 3358926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 33679fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (fLooperContext && !fLooperContext->next(fCanvas, paint)) { 337129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fDone = true; 338129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return false; 339129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 340129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com if (fFilter) { 341971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com if (!fFilter->filter(paint, drawType)) { 342971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com fDone = true; 343971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com return false; 344971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com } 34579fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (NULL == fLooperContext) { 346129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // no looper means we only draw once 347632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com fDone = true; 348632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com } 349129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 350129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fPaint = paint; 3518926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 352129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // if we only came in here for the imagefilter, mark us as done 35379fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (!fLooperContext && !fFilter) { 3544e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fDone = true; 3554e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 3564e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com 357632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com // call this after any possible paint modifiers 358632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com if (fPaint->nothingToDraw()) { 3594e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fPaint = NULL; 3604e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return false; 3614e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 3624e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return true; 3634e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com} 3644e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com 3658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorPriv.h" 3668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////// macros to place around the internal draw calls ////////////////// 3688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3698926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com#define LOOPER_BEGIN_DRAWDEVICE(paint, type) \ 37097af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com this->predrawNotify(); \ 3718926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com AutoDrawLooper looper(this, paint, true); \ 3728926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com while (looper.next(type)) { \ 3738926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkDrawIter iter(this); 3748926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 37578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org#define LOOPER_BEGIN(paint, type, bounds) \ 37697af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com this->predrawNotify(); \ 37778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org AutoDrawLooper looper(this, paint, false, bounds); \ 3784e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com while (looper.next(type)) { \ 3798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDrawIter iter(this); 3804b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 3814e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com#define LOOPER_END } 3828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////// 3848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 385d954498c01ccf0417feacf89e45d0c62a06a813breedSkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) { 386d954498c01ccf0417feacf89e45d0c62a06a813breed fConservativeRasterClip = SkToBool(flags & kConservativeRasterClip_InitFlag); 387c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBounds.setEmpty(); 388c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 3898f0a7b8e7334187a5d7d5ab7fde5a3c3009555f5caryclark@google.com fAllowSoftClip = true; 39045a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com fAllowSimplifyClip = false; 391f92c86642a1875da54d54b447f006cb9dfbbb35creed fDeviceCMDirty = true; 392b0a7ace7cb2a7559bbc254a7c93698bc71bbd245junov@chromium.org fSaveLayerCount = 0; 393210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org fCullCount = 0; 39474bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org fMetaData = NULL; 3958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 396d954498c01ccf0417feacf89e45d0c62a06a813breed if (device && device->forceConservativeRasterClip()) { 397d954498c01ccf0417feacf89e45d0c62a06a813breed fConservativeRasterClip = true; 398d954498c01ccf0417feacf89e45d0c62a06a813breed } 399d954498c01ccf0417feacf89e45d0c62a06a813breed 4008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = (MCRec*)fMCStack.push_back(); 401d954498c01ccf0417feacf89e45d0c62a06a813breed new (fMCRec) MCRec(fConservativeRasterClip); 4028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 403d954498c01ccf0417feacf89e45d0c62a06a813breed fMCRec->fLayer = SkNEW_ARGS(DeviceCM, (NULL, 0, 0, NULL, NULL, fConservativeRasterClip)); 4048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fTopLayer = fMCRec->fLayer; 4058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 40697af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com fSurfaceBase = NULL; 407f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 408f92c86642a1875da54d54b447f006cb9dfbbb35creed if (device) { 409f92c86642a1875da54d54b447f006cb9dfbbb35creed device->onAttachToCanvas(this); 410f92c86642a1875da54d54b447f006cb9dfbbb35creed fMCRec->fLayer->fDevice = SkRef(device); 411f92c86642a1875da54d54b447f006cb9dfbbb35creed fMCRec->fRasterClip.setRect(SkIRect::MakeWH(device->width(), device->height())); 412f92c86642a1875da54d54b447f006cb9dfbbb35creed } 413f92c86642a1875da54d54b447f006cb9dfbbb35creed return device; 4148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 416cde92111d50a96b6d0f3e166fbac7c9bc6eca349reed@google.comSkCanvas::SkCanvas() 417e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 418e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org{ 4198d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org inc_canvas(); 420ba124485687130183643994f1b4b68d629fbbebaskia.committer@gmail.com 421d954498c01ccf0417feacf89e45d0c62a06a813breed this->init(NULL, kDefault_InitFlags); 4228d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org} 4238d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org 424d954498c01ccf0417feacf89e45d0c62a06a813breedstatic SkBitmap make_nopixels(int width, int height) { 425d954498c01ccf0417feacf89e45d0c62a06a813breed SkBitmap bitmap; 426d954498c01ccf0417feacf89e45d0c62a06a813breed bitmap.setInfo(SkImageInfo::MakeUnknown(width, height)); 427d954498c01ccf0417feacf89e45d0c62a06a813breed return bitmap; 428d954498c01ccf0417feacf89e45d0c62a06a813breed} 429d954498c01ccf0417feacf89e45d0c62a06a813breed 430d954498c01ccf0417feacf89e45d0c62a06a813breedclass SkNoPixelsBitmapDevice : public SkBitmapDevice { 431d954498c01ccf0417feacf89e45d0c62a06a813breedpublic: 432d954498c01ccf0417feacf89e45d0c62a06a813breed SkNoPixelsBitmapDevice(int width, int height) : INHERITED(make_nopixels(width, height)) {} 433d954498c01ccf0417feacf89e45d0c62a06a813breed 434d954498c01ccf0417feacf89e45d0c62a06a813breedprivate: 435d954498c01ccf0417feacf89e45d0c62a06a813breed 436d954498c01ccf0417feacf89e45d0c62a06a813breed typedef SkBitmapDevice INHERITED; 437d954498c01ccf0417feacf89e45d0c62a06a813breed}; 438d954498c01ccf0417feacf89e45d0c62a06a813breed 439e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.orgSkCanvas::SkCanvas(int width, int height) 440e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 441e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org{ 442e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org inc_canvas(); 443d954498c01ccf0417feacf89e45d0c62a06a813breed 444d954498c01ccf0417feacf89e45d0c62a06a813breed this->init(SkNEW_ARGS(SkNoPixelsBitmapDevice, (width, height)), kDefault_InitFlags)->unref(); 445d954498c01ccf0417feacf89e45d0c62a06a813breed} 446e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org 447d954498c01ccf0417feacf89e45d0c62a06a813breedSkCanvas::SkCanvas(int width, int height, InitFlags flags) 448d954498c01ccf0417feacf89e45d0c62a06a813breed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 449d954498c01ccf0417feacf89e45d0c62a06a813breed{ 450d954498c01ccf0417feacf89e45d0c62a06a813breed inc_canvas(); 451d954498c01ccf0417feacf89e45d0c62a06a813breed 452d954498c01ccf0417feacf89e45d0c62a06a813breed this->init(SkNEW_ARGS(SkNoPixelsBitmapDevice, (width, height)), flags)->unref(); 45327a5e656c3d6ef22f9cb34de18e1b960da3aa241reed} 4548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 455d954498c01ccf0417feacf89e45d0c62a06a813breedSkCanvas::SkCanvas(SkBaseDevice* device, InitFlags flags) 45627a5e656c3d6ef22f9cb34de18e1b960da3aa241reed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 45727a5e656c3d6ef22f9cb34de18e1b960da3aa241reed{ 45827a5e656c3d6ef22f9cb34de18e1b960da3aa241reed inc_canvas(); 459d954498c01ccf0417feacf89e45d0c62a06a813breed 460d954498c01ccf0417feacf89e45d0c62a06a813breed this->init(device, flags); 461d954498c01ccf0417feacf89e45d0c62a06a813breed} 4626f09709519b79a1159f3826645f1c5fbc101ee11reed 463d954498c01ccf0417feacf89e45d0c62a06a813breedSkCanvas::SkCanvas(SkBaseDevice* device) 464d954498c01ccf0417feacf89e45d0c62a06a813breed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 465d954498c01ccf0417feacf89e45d0c62a06a813breed{ 466d954498c01ccf0417feacf89e45d0c62a06a813breed inc_canvas(); 467d954498c01ccf0417feacf89e45d0c62a06a813breed 468d954498c01ccf0417feacf89e45d0c62a06a813breed this->init(device, kDefault_InitFlags); 4698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::SkCanvas(const SkBitmap& bitmap) 472e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 473e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org{ 4748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inc_canvas(); 4758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 476d954498c01ccf0417feacf89e45d0c62a06a813breed this->init(SkNEW_ARGS(SkBitmapDevice, (bitmap)), kDefault_InitFlags)->unref(); 4778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::~SkCanvas() { 4808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // free up the contents of our deque 4818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->restoreToCount(1); // restore everything but the last 482b0a7ace7cb2a7559bbc254a7c93698bc71bbd245junov@chromium.org SkASSERT(0 == fSaveLayerCount); 4837c2029367cea5479fa3b74fb0ca2b0297b42b709reed@google.com 4848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->internalRestore(); // restore the last, since we're going away 4858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 48674bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org SkDELETE(fMetaData); 487b70ae310bbdaa1b26786773aabce5548c1f48563vandebo@chromium.org 4888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dec_canvas(); 4898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDrawFilter* SkCanvas::getDrawFilter() const { 4928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fMCRec->fFilter; 4938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDrawFilter* SkCanvas::setDrawFilter(SkDrawFilter* filter) { 4968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fMCRec->fFilter, filter); 4978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return filter; 4988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 50074bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.orgSkMetaData& SkCanvas::getMetaData() { 50174bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org // metadata users are rare, so we lazily allocate it. If that changes we 50274bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org // can decide to just make it a field in the device (rather than a ptr) 50374bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org if (NULL == fMetaData) { 50474bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org fMetaData = new SkMetaData; 50574bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org } 50674bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org return *fMetaData; 50774bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org} 50874bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org 5098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 5108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 511bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.orgvoid SkCanvas::flush() { 5121f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* device = this->getDevice(); 513bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org if (device) { 514bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org device->flush(); 515bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org } 516bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org} 517bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org 5184ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.comSkISize SkCanvas::getTopLayerSize() const { 5194ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com SkBaseDevice* d = this->getTopDevice(); 5204ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com return d ? SkISize::Make(d->width(), d->height()) : SkISize::Make(0, 0); 5214ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com} 5224ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com 5234ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.comSkIPoint SkCanvas::getTopLayerOrigin() const { 5244ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com SkBaseDevice* d = this->getTopDevice(); 5254ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com return d ? d->getOrigin() : SkIPoint::Make(0, 0); 5264ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com} 5274ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com 5284ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.comSkISize SkCanvas::getBaseLayerSize() const { 5291f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* d = this->getDevice(); 530210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com return d ? SkISize::Make(d->width(), d->height()) : SkISize::Make(0, 0); 531210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com} 532210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com 5331f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::getDevice() const { 5348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // return root device 535c029062a0312fb747fb6c2677983aba51795c580robertphillips@google.com MCRec* rec = (MCRec*) fMCStack.front(); 5368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(rec && rec->fLayer); 5378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return rec->fLayer->fDevice; 5388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5401f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::getTopDevice(bool updateMatrixClip) const { 5410b53d59a24f667350b4282f88470713902409030reed@google.com if (updateMatrixClip) { 5420b53d59a24f667350b4282f88470713902409030reed@google.com const_cast<SkCanvas*>(this)->updateDeviceCMCache(); 5430b53d59a24f667350b4282f88470713902409030reed@google.com } 5449266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com return fMCRec->fTopLayer->fDevice; 5459266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com} 5469266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com 547403f8d7a052269583175e945689824838e5e0ef4commit-bot@chromium.orgSkBaseDevice* SkCanvas::setRootDevice(SkBaseDevice* device) { 5488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // return root device 5494c09d5cd4b9e6f0be1352f62288efdedc1bc3de3reed@google.com SkDeque::F2BIter iter(fMCStack); 5504c09d5cd4b9e6f0be1352f62288efdedc1bc3de3reed@google.com MCRec* rec = (MCRec*)iter.next(); 5518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(rec && rec->fLayer); 5521f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* rootDevice = rec->fLayer->fDevice; 5538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (rootDevice == device) { 5558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return device; 5568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5574b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 5588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (device) { 55940a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com device->onAttachToCanvas(this); 5608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (rootDevice) { 56240a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com rootDevice->onDetachFromCanvas(); 5638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(rec->fLayer->fDevice, device); 5668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rootDevice = device; 5678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 5694b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 5708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* Now we update our initial region to have the bounds of the new device, 5718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com and then intersect all of the clips in our stack with these bounds, 5728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com to ensure that we can't draw outside of the device's bounds (and trash 5738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memory). 5744b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 5758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com NOTE: this is only a partial-fix, since if the new device is larger than 5768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com the previous one, we don't know how to "enlarge" the clips in our stack, 5774b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com so drawing may be artificially restricted. Without keeping a history of 5788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com all calls to canvas->clipRect() and canvas->clipPath(), we can't exactly 5798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com reconstruct the correct clips, so this approximation will have to do. 5808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com The caller really needs to restore() back to the base if they want to 5818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com accurately take advantage of the new device bounds. 5828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 5838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 58442aea289cbf801997b653a906a37a7f7e948b645reed@google.com SkIRect bounds; 58542aea289cbf801997b653a906a37a7f7e948b645reed@google.com if (device) { 5868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bounds.set(0, 0, device->width(), device->height()); 58742aea289cbf801997b653a906a37a7f7e948b645reed@google.com } else { 58842aea289cbf801997b653a906a37a7f7e948b645reed@google.com bounds.setEmpty(); 5898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 59042aea289cbf801997b653a906a37a7f7e948b645reed@google.com // now jam our 1st clip to be bounds, and intersect the rest with that 5911f836ee096bb988adef4b9757b2629c7afeda36dreed rec->fRasterClip.setRect(bounds); 59242aea289cbf801997b653a906a37a7f7e948b645reed@google.com while ((rec = (MCRec*)iter.next()) != NULL) { 5931f836ee096bb988adef4b9757b2629c7afeda36dreed (void)rec->fRasterClip.op(bounds, SkRegion::kIntersect_Op); 59442aea289cbf801997b653a906a37a7f7e948b645reed@google.com } 59542aea289cbf801997b653a906a37a7f7e948b645reed@google.com 5968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return device; 5978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 599a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.orgbool SkCanvas::readPixels(SkBitmap* bitmap, int x, int y) { 600a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (kUnknown_SkColorType == bitmap->colorType() || bitmap->getTexture()) { 601a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 602a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 603a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 604a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bool weAllocated = false; 605a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (NULL == bitmap->pixelRef()) { 606848250415eddc54075f7eb8795e8db79e749c6abreed if (!bitmap->tryAllocPixels()) { 607a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 608a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 609a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org weAllocated = true; 610a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 611a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 612a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkBitmap bm(*bitmap); 613a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bm.lockPixels(); 614a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (bm.getPixels() && this->readPixels(bm.info(), bm.getPixels(), bm.rowBytes(), x, y)) { 615a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return true; 616a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 617a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 618a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (weAllocated) { 619a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bitmap->setPixelRef(NULL); 620a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 621a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 622a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org} 62351df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 624c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.combool SkCanvas::readPixels(const SkIRect& srcRect, SkBitmap* bitmap) { 625a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkIRect r = srcRect; 626a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 627a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!r.intersect(0, 0, size.width(), size.height())) { 628a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bitmap->reset(); 629ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com return false; 630ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com } 63174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 632848250415eddc54075f7eb8795e8db79e749c6abreed if (!bitmap->tryAllocN32Pixels(r.width(), r.height())) { 633a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org // bitmap will already be reset. 634a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 635a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 636a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!this->readPixels(bitmap->info(), bitmap->getPixels(), bitmap->rowBytes(), r.x(), r.y())) { 637a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bitmap->reset(); 638daba14b7d4fc96b915c45d82713b22729c0d0f37bsalomon@google.com return false; 639c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } 640a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return true; 641a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org} 642c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 643a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.orgbool SkCanvas::readPixels(const SkImageInfo& origInfo, void* dstP, size_t rowBytes, int x, int y) { 644a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org switch (origInfo.colorType()) { 645a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org case kUnknown_SkColorType: 646a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org case kIndex_8_SkColorType: 647a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 648a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org default: 649a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org break; 650a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 651a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (NULL == dstP || rowBytes < origInfo.minRowBytes()) { 652a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 653a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 654a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (0 == origInfo.width() || 0 == origInfo.height()) { 65551df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com return false; 65651df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com } 657a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 658a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkBaseDevice* device = this->getDevice(); 659a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!device) { 660a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 661a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 662a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 663a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 664a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkIRect srcR = SkIRect::MakeXYWH(x, y, origInfo.width(), origInfo.height()); 665a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!srcR.intersect(0, 0, size.width(), size.height())) { 666a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 667a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 668db0c8753775774aa3f67114491e26ac1be32f38eskia.committer@gmail.com 669a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org // the intersect may have shrunk info's logical size 670e5ea500d4714a7d84de2bf913e81be3b65d2de68reed const SkImageInfo info = origInfo.makeWH(srcR.width(), srcR.height()); 671db0c8753775774aa3f67114491e26ac1be32f38eskia.committer@gmail.com 672a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org // if x or y are negative, then we have to adjust pixels 673a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (x > 0) { 674a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org x = 0; 675a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 676a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (y > 0) { 677a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org y = 0; 678a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 679a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org // here x,y are either 0 or negative 680a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org dstP = ((char*)dstP - y * rowBytes - x * info.bytesPerPixel()); 681db0c8753775774aa3f67114491e26ac1be32f38eskia.committer@gmail.com 682a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org // The device can assert that the requested area is always contained in its bounds 683a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return device->readPixels(info, dstP, rowBytes, srcR.x(), srcR.y()); 68451df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com} 68551df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 6864cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgbool SkCanvas::writePixels(const SkBitmap& bitmap, int x, int y) { 6874cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (bitmap.getTexture()) { 6884cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 6894cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 6904cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org SkBitmap bm(bitmap); 6914cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org bm.lockPixels(); 6924cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (bm.getPixels()) { 6934cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return this->writePixels(bm.info(), bm.getPixels(), bm.rowBytes(), x, y); 6944cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 6954cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 6964cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org} 6974cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 6984cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgbool SkCanvas::writePixels(const SkImageInfo& origInfo, const void* pixels, size_t rowBytes, 6994cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org int x, int y) { 7004cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org switch (origInfo.colorType()) { 7014cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org case kUnknown_SkColorType: 7024cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org case kIndex_8_SkColorType: 7034cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 7044cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org default: 7054cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org break; 7064cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7074cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (NULL == pixels || rowBytes < origInfo.minRowBytes()) { 7084cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 7094cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7104cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 7114cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 7124cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org SkIRect target = SkIRect::MakeXYWH(x, y, origInfo.width(), origInfo.height()); 7134cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (!target.intersect(0, 0, size.width(), size.height())) { 7144cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 7154cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7164cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 7174cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org SkBaseDevice* device = this->getDevice(); 7184cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (!device) { 7194cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 7204cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7214cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 7224cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // the intersect may have shrunk info's logical size 723e5ea500d4714a7d84de2bf913e81be3b65d2de68reed const SkImageInfo info = origInfo.makeWH(target.width(), target.height()); 7244cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 7254cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // if x or y are negative, then we have to adjust pixels 7264cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (x > 0) { 7274cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org x = 0; 7284cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7294cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (y > 0) { 7304cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org y = 0; 7314cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7324cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // here x,y are either 0 or negative 7334cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org pixels = ((const char*)pixels - y * rowBytes - x * info.bytesPerPixel()); 7344cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 7354af35f348b2e2f6c428819118eb7a2f2fff53a74reed // Tell our owning surface to bump its generation ID 7364af35f348b2e2f6c428819118eb7a2f2fff53a74reed this->predrawNotify(); 7374af35f348b2e2f6c428819118eb7a2f2fff53a74reed 7384cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // The device can assert that the requested area is always contained in its bounds 7394ef54f8d72420a521d4aae04ff5cd438810eca7fcommit-bot@chromium.org return device->writePixels(info, pixels, rowBytes, target.x(), target.y()); 7404cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org} 74151df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 7424370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comSkCanvas* SkCanvas::canvasForDrawIter() { 7434370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com return this; 7444370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 7454370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 7468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 7478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::updateDeviceCMCache() { 7498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fDeviceCMDirty) { 7508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& totalMatrix = this->getTotalMatrix(); 7511f836ee096bb988adef4b9757b2629c7afeda36dreed const SkRasterClip& totalClip = fMCRec->fRasterClip; 7528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* layer = fMCRec->fTopLayer; 7534b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 7548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == layer->fNext) { // only one layer 75546799cd9f0bded51a189d77731b25af159ab4609reed@google.com layer->updateMC(totalMatrix, totalClip, fClipStack, NULL); 7568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 757045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com SkRasterClip clip(totalClip); 7588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 75946799cd9f0bded51a189d77731b25af159ab4609reed@google.com layer->updateMC(totalMatrix, clip, fClipStack, &clip); 7608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while ((layer = layer->fNext) != NULL); 7618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = false; 7638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 7678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7685f6102d07982043542343ff0a6c67b1319ac9fc7Florin Malitaint SkCanvas::internalSave() { 7698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int saveCount = this->getSaveCount(); // record this before the actual save 7704b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 7718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com MCRec* newTop = (MCRec*)fMCStack.push_back(); 772d954498c01ccf0417feacf89e45d0c62a06a813breed new (newTop) MCRec(*fMCRec); // balanced in restore() 7738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = newTop; 7744b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 7755f6102d07982043542343ff0a6c67b1319ac9fc7Florin Malita fClipStack.save(); 7765c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 7778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return saveCount; 7788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 780d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.orgint SkCanvas::save() { 7815f6102d07982043542343ff0a6c67b1319ac9fc7Florin Malita this->willSave(); 7825f6102d07982043542343ff0a6c67b1319ac9fc7Florin Malita return this->internalSave(); 7838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic bool bounds_affects_clip(SkCanvas::SaveFlags flags) { 786b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG 7878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (flags & SkCanvas::kClipToLayer_SaveFlag) != 0; 788b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#else 789b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com return true; 790b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#endif 7918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 793a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.orgbool SkCanvas::clipRectBounds(const SkRect* bounds, SaveFlags flags, 794c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org SkIRect* intersection, const SkImageFilter* imageFilter) { 795bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect clipBounds; 796c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org SkRegion::Op op = SkRegion::kIntersect_Op; 797bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (!this->getClipDeviceBounds(&clipBounds)) { 798a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return false; 799f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 800c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org 801c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org if (imageFilter) { 8021f836ee096bb988adef4b9757b2629c7afeda36dreed imageFilter->filterBounds(clipBounds, fMCRec->fMatrix, &clipBounds); 803c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org // Filters may grow the bounds beyond the device bounds. 804c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org op = SkRegion::kReplace_Op; 805c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org } 806bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect ir; 80749f085dddff10473b6ebf832a974288300224e60bsalomon if (bounds) { 8088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 8094b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 8108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->getTotalMatrix().mapRect(&r, *bounds); 8118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.roundOut(&ir); 8128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // early exit if the layer's bounds are clipped out 8138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!ir.intersect(clipBounds)) { 814bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (bounds_affects_clip(flags)) { 8151f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fRasterClip.setEmpty(); 816bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 817a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return false; 8188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { // no user bounds, so just use the clip 8208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ir = clipBounds; 8218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 82389f077ced4918ded7e911bc5052b61c90ad57a9asenorblanco@chromium.org if (bounds_affects_clip(flags)) { 82489f077ced4918ded7e911bc5052b61c90ad57a9asenorblanco@chromium.org fClipStack.clipDevRect(ir, op); 82589f077ced4918ded7e911bc5052b61c90ad57a9asenorblanco@chromium.org // early exit if the clip is now empty 8261f836ee096bb988adef4b9757b2629c7afeda36dreed if (!fMCRec->fRasterClip.op(ir, op)) { 82789f077ced4918ded7e911bc5052b61c90ad57a9asenorblanco@chromium.org return false; 82889f077ced4918ded7e911bc5052b61c90ad57a9asenorblanco@chromium.org } 829a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org } 830a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 831a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org if (intersection) { 832a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org *intersection = ir; 833a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org } 834a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return true; 835a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org} 836a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 837d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.orgint SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint) { 838d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org SaveLayerStrategy strategy = this->willSaveLayer(bounds, paint, kARGB_ClipLayer_SaveFlag); 839d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org return this->internalSaveLayer(bounds, paint, kARGB_ClipLayer_SaveFlag, false, strategy); 840d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org} 841d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org 842a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.orgint SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint, 843a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org SaveFlags flags) { 844e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org SaveLayerStrategy strategy = this->willSaveLayer(bounds, paint, flags); 845e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org return this->internalSaveLayer(bounds, paint, flags, false, strategy); 8468926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com} 8478926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 848e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.orgint SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags, 849e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org bool justForImageFilter, SaveLayerStrategy strategy) { 850b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG 8512a5cd60bfff32c92cf44a8cfc3e8c017b9aee456commit-bot@chromium.org flags |= kClipToLayer_SaveFlag; 852b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#endif 853b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com 854a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org // do this before we create the layer. We don't call the public save() since 855a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org // that would invoke a possibly overridden virtual 8565f6102d07982043542343ff0a6c67b1319ac9fc7Florin Malita int count = this->internalSave(); 857a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 858a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org fDeviceCMDirty = true; 859a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 860a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org SkIRect ir; 861c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org if (!this->clipRectBounds(bounds, flags, &ir, paint ? paint->getImageFilter() : NULL)) { 8628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return count; 8638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 865e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy really care about 866e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org // the clipRectBounds() call above? 867e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org if (kNoLayer_SaveLayerStrategy == strategy) { 868e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org return count; 869e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org } 870e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org 871b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com // Kill the imagefilter if our device doesn't allow it 872b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com SkLazyPaint lazyP; 873b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com if (paint && paint->getImageFilter()) { 874b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com if (!this->getTopDevice()->allowImageFilter(paint->getImageFilter())) { 8758926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com if (justForImageFilter) { 8768926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com // early exit if the layer was just for the imageFilter 8778926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com return count; 8788926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 879b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com SkPaint* p = lazyP.set(*paint); 880b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com p->setImageFilter(NULL); 881b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com paint = p; 882b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com } 883b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com } 884b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com 88515a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org bool isOpaque = !SkToBool(flags & kHasAlphaLayer_SaveFlag); 88615a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org SkImageInfo info = SkImageInfo::MakeN32(ir.width(), ir.height(), 88715a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType); 8888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8891f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* device; 89076dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com if (paint && paint->getImageFilter()) { 89152d9ac6c92ddf33b3b05eb77ba9509a7aa441657reed device = this->getDevice(); 89252d9ac6c92ddf33b3b05eb77ba9509a7aa441657reed if (device) { 89352d9ac6c92ddf33b3b05eb77ba9509a7aa441657reed device = device->createCompatibleDevice(info); 89452d9ac6c92ddf33b3b05eb77ba9509a7aa441657reed } 89576dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } else { 89615a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org device = this->createLayerDevice(info); 89776dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } 898e25c68402b38ac01dc1ae196ae8a5265b773c5f2bungeman@google.com if (NULL == device) { 899e25c68402b38ac01dc1ae196ae8a5265b773c5f2bungeman@google.com SkDebugf("Unable to create device for layer."); 900e25c68402b38ac01dc1ae196ae8a5265b773c5f2bungeman@google.com return count; 901e25c68402b38ac01dc1ae196ae8a5265b773c5f2bungeman@google.com } 902e97f0856a8044866b12527819d14cdfbcdfd96f2bsalomon@google.com 9036f8f292aa768869a9e85c314b124875f57504f2creed@google.com device->setOrigin(ir.fLeft, ir.fTop); 904d954498c01ccf0417feacf89e45d0c62a06a813breed DeviceCM* layer = SkNEW_ARGS(DeviceCM, 905d954498c01ccf0417feacf89e45d0c62a06a813breed (device, ir.fLeft, ir.fTop, paint, this, fConservativeRasterClip)); 9068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device->unref(); 9078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com layer->fNext = fMCRec->fTopLayer; 9098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fLayer = layer; 9108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fTopLayer = layer; // this field is NOT an owner of layer 9118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 912b0a7ace7cb2a7559bbc254a7c93698bc71bbd245junov@chromium.org fSaveLayerCount += 1; 9138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return count; 9148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 916d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.orgint SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) { 917d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org return this->saveLayerAlpha(bounds, alpha, kARGB_ClipLayer_SaveFlag); 918d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org} 919d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org 9208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha, 9218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SaveFlags flags) { 9228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (0xFF == alpha) { 9238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->saveLayer(bounds, NULL, flags); 9248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 9258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint tmpPaint; 9268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com tmpPaint.setAlpha(alpha); 9278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->saveLayer(bounds, &tmpPaint, flags); 9288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::restore() { 9328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // check for underflow 9338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fMCStack.count() > 1) { 934e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org this->willRestore(); 9358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->internalRestore(); 9366cfa73a29a26edf1d03bca224ad6860396308ffcmtklein this->didRestore(); 9378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::internalRestore() { 9418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fMCStack.count() != 0); 9428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 944c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 9458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9465f6102d07982043542343ff0a6c67b1319ac9fc7Florin Malita fClipStack.restore(); 9476c157640c27ee2ed6f9a484d21691b7b19dfecdecommit-bot@chromium.org 94888edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com // reserve our layer (if any) 9498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* layer = fMCRec->fLayer; // may be null 9508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now detach it from fMCRec so we can pop(). Gets freed after its drawn 9518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fLayer = NULL; 9528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now do the normal restore() 9548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->~MCRec(); // balanced in save() 9558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCStack.pop_back(); 9568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = (MCRec*)fMCStack.back(); 9578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* Time to draw the layer's offscreen. We can't call the public drawSprite, 9598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com since if we're being recorded, we don't want to record this (the 9608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com recorder will have already recorded the restore). 9618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 96249f085dddff10473b6ebf832a974288300224e60bsalomon if (layer) { 9638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (layer->fNext) { 9646f8f292aa768869a9e85c314b124875f57504f2creed@google.com const SkIPoint& origin = layer->fDevice->getOrigin(); 9658926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(), 9668926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com layer->fPaint); 9678926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com // reset this, since internalDrawDevice will have set it to true 9688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 9697c2029367cea5479fa3b74fb0ca2b0297b42b709reed@google.com 970b0a7ace7cb2a7559bbc254a7c93698bc71bbd245junov@chromium.org SkASSERT(fSaveLayerCount > 0); 971b0a7ace7cb2a7559bbc254a7c93698bc71bbd245junov@chromium.org fSaveLayerCount -= 1; 9728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDELETE(layer); 97488edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 9758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::getSaveCount() const { 9788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fMCStack.count(); 9798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::restoreToCount(int count) { 9828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // sanity check 9838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count < 1) { 9848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com count = 1; 9858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 98674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 987b9d1c6a3c43a2cbcbd612f4ec4aaf604a1fa6444reed@google.com int n = this->getSaveCount() - count; 988b9d1c6a3c43a2cbcbd612f4ec4aaf604a1fa6444reed@google.com for (int i = 0; i < n; ++i) { 9898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->restore(); 9908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9937c2029367cea5479fa3b74fb0ca2b0297b42b709reed@google.combool SkCanvas::isDrawingToLayer() const { 994b0a7ace7cb2a7559bbc254a7c93698bc71bbd245junov@chromium.org return fSaveLayerCount > 0; 9957c2029367cea5479fa3b74fb0ca2b0297b42b709reed@google.com} 9967c2029367cea5479fa3b74fb0ca2b0297b42b709reed@google.com 99776f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.comSkSurface* SkCanvas::newSurface(const SkImageInfo& info) { 99876f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com return this->onNewSurface(info); 99976f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com} 100076f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com 100176f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.comSkSurface* SkCanvas::onNewSurface(const SkImageInfo& info) { 100276f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com SkBaseDevice* dev = this->getDevice(); 100376f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com return dev ? dev->newSurface(info) : NULL; 100476f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com} 100576f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com 1006c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgSkImageInfo SkCanvas::imageInfo() const { 1007c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkBaseDevice* dev = this->getDevice(); 1008c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (dev) { 1009c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return dev->imageInfo(); 1010c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } else { 1011900ecf2f1579d42c9d2959831787af0346320f86reed@google.com return SkImageInfo::MakeUnknown(0, 0); 1012c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1013c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1014c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1015c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgconst void* SkCanvas::peekPixels(SkImageInfo* info, size_t* rowBytes) { 1016c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return this->onPeekPixels(info, rowBytes); 1017c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1018c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1019c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgconst void* SkCanvas::onPeekPixels(SkImageInfo* info, size_t* rowBytes) { 1020c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkBaseDevice* dev = this->getDevice(); 1021c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return dev ? dev->peekPixels(info, rowBytes) : NULL; 1022c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1023c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 10246b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.orgvoid* SkCanvas::accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin) { 10256b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org void* pixels = this->onAccessTopLayerPixels(info, rowBytes); 10266b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org if (pixels && origin) { 10276b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org *origin = this->getTopDevice(false)->getOrigin(); 10286b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org } 10296b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org return pixels; 10309c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 10319c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 10329c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.comvoid* SkCanvas::onAccessTopLayerPixels(SkImageInfo* info, size_t* rowBytes) { 10339c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com SkBaseDevice* dev = this->getTopDevice(); 10349c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com return dev ? dev->accessPixels(info, rowBytes) : NULL; 10359c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 10369c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1037c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgSkAutoROCanvasPixels::SkAutoROCanvasPixels(SkCanvas* canvas) { 1038c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org fAddr = canvas->peekPixels(&fInfo, &fRowBytes); 1039c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (NULL == fAddr) { 1040c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org fInfo = canvas->imageInfo(); 1041848250415eddc54075f7eb8795e8db79e749c6abreed if (kUnknown_SkColorType == fInfo.colorType() || !fBitmap.tryAllocPixels(fInfo)) { 1042c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return; // failure, fAddr is NULL 1043c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1044c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (!canvas->readPixels(&fBitmap, 0, 0)) { 1045c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return; // failure, fAddr is NULL 1046c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1047c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org fAddr = fBitmap.getPixels(); 1048c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org fRowBytes = fBitmap.rowBytes(); 1049c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1050c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkASSERT(fAddr); // success 1051c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1052c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1053c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgbool SkAutoROCanvasPixels::asROBitmap(SkBitmap* bitmap) const { 1054c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (fAddr) { 105500f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org return bitmap->installPixels(fInfo, const_cast<void*>(fAddr), fRowBytes); 1056c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } else { 1057c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org bitmap->reset(); 1058c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return false; 1059c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1060c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1061c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1062210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.orgvoid SkCanvas::onPushCull(const SkRect& cullRect) { 1063210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org // do nothing. Subclasses may do something 1064210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org} 1065210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org 1066210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.orgvoid SkCanvas::onPopCull() { 1067210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org // do nothing. Subclasses may do something 1068210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org} 1069210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org 10708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////// 1071520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org#ifdef SK_DEBUG 1072520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org// Ensure that cull rects are monotonically nested in device space. 1073520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.orgvoid SkCanvas::validateCull(const SkIRect& devCull) { 1074520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org if (fCullStack.isEmpty() 1075520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org || devCull.isEmpty() 1076520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org || fCullStack.top().contains(devCull)) { 1077520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org return; 1078520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org } 1079520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1080520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org SkDEBUGF(("Invalid cull: [%d %d %d %d] (previous cull: [%d %d %d %d])\n", 1081520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org devCull.x(), devCull.y(), devCull.right(), devCull.bottom(), 1082520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org fCullStack.top().x(), fCullStack.top().y(), 1083520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org fCullStack.top().right(), fCullStack.top().bottom())); 1084520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1085520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org#ifdef ASSERT_NESTED_CULLING 1086520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org SkDEBUGFAIL("Invalid cull."); 1087520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org#endif 1088520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org} 1089520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org#endif 1090520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1091520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.orgvoid SkCanvas::pushCull(const SkRect& cullRect) { 1092520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org ++fCullCount; 1093520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org this->onPushCull(cullRect); 1094520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1095520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org#ifdef SK_DEBUG 1096520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org // Map the cull rect into device space. 1097520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org SkRect mappedCull; 1098520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org this->getTotalMatrix().mapRect(&mappedCull, cullRect); 1099520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1100520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org // Take clipping into account. 1101520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org SkIRect devClip, devCull; 1102520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org mappedCull.roundOut(&devCull); 1103520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org this->getClipDeviceBounds(&devClip); 1104520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org if (!devCull.intersect(devClip)) { 1105520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org devCull.setEmpty(); 1106520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org } 1107520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1108520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org this->validateCull(devCull); 1109520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org fCullStack.push(devCull); // balanced in popCull 1110520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org#endif 1111520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org} 1112520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1113520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.orgvoid SkCanvas::popCull() { 1114520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org SkASSERT(fCullStack.count() == fCullCount); 1115520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1116520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org if (fCullCount > 0) { 1117520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org --fCullCount; 1118520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org this->onPopCull(); 1119520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1120520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org SkDEBUGCODE(fCullStack.pop()); 1121520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org } 1122520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org} 1123520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org 1124520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org///////////////////////////////////////////////////////////////////////////// 11258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11269bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.comvoid SkCanvas::internalDrawBitmap(const SkBitmap& bitmap, 11278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& matrix, const SkPaint* paint) { 112850b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org if (bitmap.drawsNothing()) { 11298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 11308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11322c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkLazyPaint lazy; 11338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == paint) { 11342c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org paint = lazy.init(); 11358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11369bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com 11379bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com SkDEBUGCODE(bitmap.validate();) 11389bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com 113978cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 114078cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 114178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (paint && paint->canComputeFastBounds()) { 114278cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bitmap.getBounds(&storage); 114378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org matrix.mapRect(&storage); 114478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint->computeFastBounds(storage, &storage); 114578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org } 114678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org 114778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) 11489bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com 11499bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com while (iter.next()) { 11509bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com iter.fDevice->drawBitmap(iter, bitmap, matrix, looper.paint()); 11519bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com } 11529bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com 11539bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com LOOPER_END 11548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 11558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11561f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comvoid SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, 11578926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com const SkPaint* paint) { 11588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint tmp; 11598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == paint) { 11608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com tmp.setDither(true); 11618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint = &tmp; 11628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11634b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 11648926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com LOOPER_BEGIN_DRAWDEVICE(*paint, SkDrawFilter::kBitmap_Type) 11658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 11661f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* dstDev = iter.fDevice; 116776dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com paint = &looper.paint(); 116876dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkImageFilter* filter = paint->getImageFilter(); 116976dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkIPoint pos = { x - iter.getX(), y - iter.getY() }; 11708926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com if (filter && !dstDev->canHandleImageFilter(filter)) { 11719c39744a00573b7133fc765b0a9d50a0ceace7b8senorblanco@chromium.org SkDeviceImageFilterProxy proxy(dstDev); 117276dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkBitmap dst; 11736776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org SkIPoint offset = SkIPoint::Make(0, 0); 1174b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com const SkBitmap& src = srcDev->accessBitmap(false); 1175fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org SkMatrix matrix = *iter.fMatrix; 1176d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org matrix.postTranslate(SkIntToScalar(-pos.x()), SkIntToScalar(-pos.y())); 11774cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org SkIRect clipBounds = SkIRect::MakeWH(srcDev->width(), srcDev->height()); 1178be129b26f13d575fd6b396c6ae759838ecc9bd1asenorblanco SkAutoTUnref<SkImageFilter::Cache> cache(dstDev->getImageFilterCache()); 117955b6d8be997a447ef9ce0f029697677a940bfc24senorblanco SkImageFilter::Context ctx(matrix, clipBounds, cache.get()); 11804cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org if (filter->filterImage(&proxy, src, ctx, &dst, &offset)) { 11815efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com SkPaint tmpUnfiltered(*paint); 11825efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com tmpUnfiltered.setImageFilter(NULL); 11836776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org dstDev->drawSprite(iter, dst, pos.x() + offset.x(), pos.y() + offset.y(), 11846776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org tmpUnfiltered); 118576dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } 118676dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } else { 1187b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com dstDev->drawDevice(iter, srcDev, pos.x(), pos.y(), *paint); 118876dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } 11898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11904e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 11918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 11928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11938926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.comvoid SkCanvas::drawSprite(const SkBitmap& bitmap, int x, int y, 11948926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com const SkPaint* paint) { 119550b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org if (bitmap.drawsNothing()) { 11968926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com return; 11978926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 119850b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org SkDEBUGCODE(bitmap.validate();) 1199fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 12008926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkPaint tmp; 12018926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com if (NULL == paint) { 12028926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com paint = &tmp; 12038926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 1204fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 12058926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com LOOPER_BEGIN_DRAWDEVICE(*paint, SkDrawFilter::kBitmap_Type) 1206fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 12078926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com while (iter.next()) { 12088926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com paint = &looper.paint(); 12098926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkImageFilter* filter = paint->getImageFilter(); 12108926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkIPoint pos = { x - iter.getX(), y - iter.getY() }; 12118926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com if (filter && !iter.fDevice->canHandleImageFilter(filter)) { 12129c39744a00573b7133fc765b0a9d50a0ceace7b8senorblanco@chromium.org SkDeviceImageFilterProxy proxy(iter.fDevice); 12138926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkBitmap dst; 12146776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org SkIPoint offset = SkIPoint::Make(0, 0); 1215fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org SkMatrix matrix = *iter.fMatrix; 1216d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org matrix.postTranslate(SkIntToScalar(-pos.x()), SkIntToScalar(-pos.y())); 12174cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org SkIRect clipBounds = SkIRect::MakeWH(bitmap.width(), bitmap.height()); 1218be129b26f13d575fd6b396c6ae759838ecc9bd1asenorblanco SkAutoTUnref<SkImageFilter::Cache> cache(iter.fDevice->getImageFilterCache()); 121955b6d8be997a447ef9ce0f029697677a940bfc24senorblanco SkImageFilter::Context ctx(matrix, clipBounds, cache.get()); 12204cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org if (filter->filterImage(&proxy, bitmap, ctx, &dst, &offset)) { 12215efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com SkPaint tmpUnfiltered(*paint); 12225efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com tmpUnfiltered.setImageFilter(NULL); 12236776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org iter.fDevice->drawSprite(iter, dst, pos.x() + offset.x(), pos.y() + offset.y(), 12245efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com tmpUnfiltered); 12258926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 12268926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } else { 12278926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com iter.fDevice->drawSprite(iter, bitmap, pos.x(), pos.y(), *paint); 12288926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 12298926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 12308926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com LOOPER_END 12318926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com} 12328926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 12338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////// 123492362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::translate(SkScalar dx, SkScalar dy) { 1235d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1236d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setTranslate(dx, dy); 1237d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 12388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 124092362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::scale(SkScalar sx, SkScalar sy) { 1241d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1242d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setScale(sx, sy); 1243d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 12448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 124692362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::rotate(SkScalar degrees) { 1247d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1248d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setRotate(degrees); 1249d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 12508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 125292362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::skew(SkScalar sx, SkScalar sy) { 1253d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1254d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setSkew(sx, sy); 1255d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 125644c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org} 125744c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 125892362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::concat(const SkMatrix& matrix) { 1259d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org if (matrix.isIdentity()) { 1260d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org return; 1261d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org } 1262d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org 12638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1264c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 12651f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix.preConcat(matrix); 126644c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 126744c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org this->didConcat(matrix); 126844c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org} 126944c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 12708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::setMatrix(const SkMatrix& matrix) { 12718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1272c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 12731f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix = matrix; 127444c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org this->didSetMatrix(matrix); 12758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::resetMatrix() { 12788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 12794b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 12808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.reset(); 12818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->setMatrix(matrix); 12828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 12858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1286759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { 12878f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 12888f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(rect, op, edgeStyle); 12898f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 12908f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 12918f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 1292da17f758442f16747af39f8fbaed9c097048519creed@google.com#ifdef SK_ENABLE_CLIP_QUICKREJECT 1293da17f758442f16747af39f8fbaed9c097048519creed@google.com if (SkRegion::kIntersect_Op == op) { 12941f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fRasterClip.isEmpty()) { 1295da17f758442f16747af39f8fbaed9c097048519creed@google.com return false; 1296da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1297da17f758442f16747af39f8fbaed9c097048519creed@google.com 12983b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(rect)) { 1299da17f758442f16747af39f8fbaed9c097048519creed@google.com fDeviceCMDirty = true; 1300c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 1301da17f758442f16747af39f8fbaed9c097048519creed@google.com 1302da17f758442f16747af39f8fbaed9c097048519creed@google.com fClipStack.clipEmpty(); 13031f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.setEmpty(); 1304da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1305da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1306da17f758442f16747af39f8fbaed9c097048519creed@google.com#endif 1307da17f758442f16747af39f8fbaed9c097048519creed@google.com 13085c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com AutoValidateClip avc(this); 13095c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 13108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1311c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 13128f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!fAllowSoftClip) { 13138f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com edgeStyle = kHard_ClipEdgeStyle; 13148f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 13158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13161f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fMatrix.rectStaysRect()) { 1317123671901abfa595d09ca789b487c4bc7c1f7cbcrobertphillips@google.com // for these simpler matrices, we can stay a rect even after applying 131898de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // the matrix. This means we don't have to a) make a path, and b) tell 131998de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // the region code to scan-convert the path, only to discover that it 132098de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // is really just a rect. 13218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 13228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13231f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix.mapRect(&r, rect); 13248f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com fClipStack.clipDevRect(r, op, kSoft_ClipEdgeStyle == edgeStyle); 1325d954498c01ccf0417feacf89e45d0c62a06a813breed fMCRec->fRasterClip.op(r, this->getBaseLayerSize(), op, kSoft_ClipEdgeStyle == edgeStyle); 13268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 1327123671901abfa595d09ca789b487c4bc7c1f7cbcrobertphillips@google.com // since we're rotated or some such thing, we convert the rect to a path 132898de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // and clip against that, since it can handle any matrix. However, to 132998de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // avoid recursion in the case where we are subclassed (e.g. Pictures) 133098de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // we explicitly call "our" version of clipPath. 13318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath path; 13328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.addRect(rect); 13348f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->SkCanvas::onClipPath(path, op, edgeStyle); 13358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 133873e714eb766617ce06757829a3c0b345c7963faareedstatic void rasterclip_path(SkRasterClip* rc, const SkCanvas* canvas, const SkPath& devPath, 133973e714eb766617ce06757829a3c0b345c7963faareed SkRegion::Op op, bool doAA) { 1340d64c9487135094c83f658319f53ea2005ecc08b2reed rc->op(devPath, canvas->getBaseLayerSize(), op, doAA); 1341819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com} 1342819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 1343759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) { 13448f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 13454ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (rrect.isRect()) { 13468f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(rrect.getBounds(), op, edgeStyle); 13478f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } else { 13488f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRRect(rrect, op, edgeStyle); 13494ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 13508f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 135114e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 13528f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 135314e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org SkRRect transformedRRect; 13541f836ee096bb988adef4b9757b2629c7afeda36dreed if (rrect.transform(fMCRec->fMatrix, &transformedRRect)) { 135514e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org AutoValidateClip avc(this); 135614e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 135714e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org fDeviceCMDirty = true; 135814e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org fCachedLocalClipBoundsDirty = true; 13598f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!fAllowSoftClip) { 13608f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com edgeStyle = kHard_ClipEdgeStyle; 13618f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 136214e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 13638f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com fClipStack.clipDevRRect(transformedRRect, op, kSoft_ClipEdgeStyle == edgeStyle); 136414e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 136514e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org SkPath devPath; 136614e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org devPath.addRRect(transformedRRect); 136714e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 136873e714eb766617ce06757829a3c0b345c7963faareed rasterclip_path(&fMCRec->fRasterClip, this, devPath, op, kSoft_ClipEdgeStyle == edgeStyle); 13698f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com return; 137014e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org } 137114e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 137214e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org SkPath path; 137314e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org path.addRRect(rrect); 137414e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org // call the non-virtual version 13758f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->SkCanvas::onClipPath(path, op, edgeStyle); 13764ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 13774ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 1378759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { 13798f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 13808f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com SkRect r; 13818f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!path.isInverseFillType() && path.isRect(&r)) { 13828f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(r, op, edgeStyle); 13838f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } else { 13848f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipPath(path, op, edgeStyle); 13858f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 13868f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 13878f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 13888f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 1389da17f758442f16747af39f8fbaed9c097048519creed@google.com#ifdef SK_ENABLE_CLIP_QUICKREJECT 1390da17f758442f16747af39f8fbaed9c097048519creed@google.com if (SkRegion::kIntersect_Op == op && !path.isInverseFillType()) { 13911f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fRasterClip.isEmpty()) { 1392da17f758442f16747af39f8fbaed9c097048519creed@google.com return false; 1393da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1394fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 13953b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(path.getBounds())) { 1396da17f758442f16747af39f8fbaed9c097048519creed@google.com fDeviceCMDirty = true; 1397c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 1398fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1399da17f758442f16747af39f8fbaed9c097048519creed@google.com fClipStack.clipEmpty(); 14001f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.setEmpty(); 1401da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1402da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1403da17f758442f16747af39f8fbaed9c097048519creed@google.com#endif 1404da17f758442f16747af39f8fbaed9c097048519creed@google.com 14055c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com AutoValidateClip avc(this); 14065c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 14078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1408c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 14098f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!fAllowSoftClip) { 14108f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com edgeStyle = kHard_ClipEdgeStyle; 14118f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 14128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath devPath; 14141f836ee096bb988adef4b9757b2629c7afeda36dreed path.transform(fMCRec->fMatrix, &devPath); 14158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1416fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // Check if the transfomation, or the original path itself 1417fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // made us empty. Note this can also happen if we contained NaN 1418fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // values. computing the bounds detects this, and will set our 1419fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // bounds to empty if that is the case. (see SkRect::set(pts, count)) 1420fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com if (devPath.getBounds().isEmpty()) { 1421fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // resetting the path will remove any NaN or other wanky values 1422fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // that might upset our scan converter. 1423fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com devPath.reset(); 1424fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com } 1425fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com 14265c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // if we called path.swap() we could avoid a deep copy of this path 14278f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com fClipStack.clipDevPath(devPath, op, kSoft_ClipEdgeStyle == edgeStyle); 14285c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 142945a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com if (fAllowSimplifyClip) { 143045a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com devPath.reset(); 143145a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com devPath.setFillType(SkPath::kInverseEvenOdd_FillType); 143245a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com const SkClipStack* clipStack = getClipStack(); 143345a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com SkClipStack::Iter iter(*clipStack, SkClipStack::Iter::kBottom_IterStart); 143445a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com const SkClipStack::Element* element; 143545a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com while ((element = iter.next())) { 143645a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com SkClipStack::Element::Type type = element->getType(); 143745a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com SkPath operand; 14382a67e123a3e559774a16a58cbe5106bc0fb86740commit-bot@chromium.org if (type != SkClipStack::Element::kEmpty_Type) { 14392a67e123a3e559774a16a58cbe5106bc0fb86740commit-bot@chromium.org element->asPath(&operand); 14402a67e123a3e559774a16a58cbe5106bc0fb86740commit-bot@chromium.org } 144145a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com SkRegion::Op elementOp = element->getOp(); 144245a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com if (elementOp == SkRegion::kReplace_Op) { 144345a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com devPath = operand; 144445a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com } else { 144545a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com Op(devPath, operand, (SkPathOp) elementOp, &devPath); 144645a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com } 144796fd3440fa489f74f903f30487282af99deb2a4dcaryclark@google.com // if the prev and curr clips disagree about aa -vs- not, favor the aa request. 144896fd3440fa489f74f903f30487282af99deb2a4dcaryclark@google.com // perhaps we need an API change to avoid this sort of mixed-signals about 144996fd3440fa489f74f903f30487282af99deb2a4dcaryclark@google.com // clipping. 14508f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (element->isAA()) { 14518f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com edgeStyle = kSoft_ClipEdgeStyle; 14528f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 145345a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com } 145445a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com op = SkRegion::kReplace_Op; 145545a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com } 145645a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com 145773e714eb766617ce06757829a3c0b345c7963faareed rasterclip_path(&fMCRec->fRasterClip, this, devPath, op, edgeStyle); 14588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1460759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipRegion(const SkRegion& rgn, SkRegion::Op op) { 14618f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRegion(rgn, op); 14628f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 14638f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 14648f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipRegion(const SkRegion& rgn, SkRegion::Op op) { 14655c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com AutoValidateClip avc(this); 14665c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 14678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1468c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 14698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14705c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // todo: signal fClipStack that we have a region, and therefore (I guess) 14715c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // we have to ignore it, and use the region directly? 1472115d931d2fbd3a109a21b28c8a9c5099e6c49c54reed@google.com fClipStack.clipDevRect(rgn.getBounds(), op); 14735c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 14741f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fRasterClip.op(rgn, op); 14758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1477819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com#ifdef SK_DEBUG 1478819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.comvoid SkCanvas::validateClip() const { 1479819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com // construct clipRgn from the clipstack 14801f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com const SkBaseDevice* device = this->getDevice(); 1481ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com if (!device) { 14825c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org SkASSERT(this->isClipEmpty()); 1483ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com return; 1484ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com } 1485ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com 1486819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com SkIRect ir; 1487819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com ir.set(0, 0, device->width(), device->height()); 1488d954498c01ccf0417feacf89e45d0c62a06a813breed SkRasterClip tmpClip(ir, fConservativeRasterClip); 1489819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 149080214e26c57c5fea954006400852e8999e201923robertphillips@google.com SkClipStack::B2TIter iter(fClipStack); 14918182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const SkClipStack::Element* element; 14928182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com while ((element = iter.next()) != NULL) { 14938182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com switch (element->getType()) { 14948182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kRect_Type: 14958182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com element->getRect().round(&ir); 14968182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com tmpClip.op(ir, element->getOp()); 14978182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 14988182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kEmpty_Type: 14998182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com tmpClip.setEmpty(); 15008182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 15019cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org default: { 15029cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org SkPath path; 15039cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org element->asPath(&path); 150473e714eb766617ce06757829a3c0b345c7963faareed rasterclip_path(&tmpClip, this, path, element->getOp(), element->isAA()); 15059cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org break; 15069cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org } 1507819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com } 1508819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com } 1509819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com} 1510819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com#endif 1511819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 151290c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.comvoid SkCanvas::replayClips(ClipVisitor* visitor) const { 151380214e26c57c5fea954006400852e8999e201923robertphillips@google.com SkClipStack::B2TIter iter(fClipStack); 15148182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const SkClipStack::Element* element; 15158182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com 15168182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com while ((element = iter.next()) != NULL) { 1517c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita element->replay(visitor); 151890c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com } 151990c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com} 152090c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com 15215c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com/////////////////////////////////////////////////////////////////////////////// 15225c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 1523754de5f65b466f721d952a379194cc94de376f42reed@google.combool SkCanvas::isClipEmpty() const { 15241f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.isEmpty(); 1525754de5f65b466f721d952a379194cc94de376f42reed@google.com} 1526754de5f65b466f721d952a379194cc94de376f42reed@google.com 15275c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.orgbool SkCanvas::isClipRect() const { 15281f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.isRect(); 15295c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org} 15305c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org 15313b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::quickReject(const SkRect& rect) const { 15321607863b608b7db6c813228768ed5d72997bbc82reed@google.com if (!rect.isFinite()) 1533116b2bcd2c4c4d4670c7b7e2ea597414713c37fbwjmaclean@chromium.org return true; 1534116b2bcd2c4c4d4670c7b7e2ea597414713c37fbwjmaclean@chromium.org 15351f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fRasterClip.isEmpty()) { 15368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 15378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 15388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 15391f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fMatrix.hasPerspective()) { 1540a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com SkRect dst; 15411f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix.mapRect(&dst, rect); 1542a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com SkIRect idst; 1543a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com dst.roundOut(&idst); 15441f836ee096bb988adef4b9757b2629c7afeda36dreed return !SkIRect::Intersects(idst, fMCRec->fRasterClip.getBounds()); 1545a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com } else { 1546c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com const SkRect& clipR = this->getLocalClipBounds(); 1547d252db03d9650013b545ef9781fe993c07f8f314reed@android.com 1548a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com // for speed, do the most likely reject compares first 1549c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com // TODO: should we use | instead, or compare all 4 at once? 1550c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com if (rect.fTop >= clipR.fBottom || rect.fBottom <= clipR.fTop) { 1551a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com return true; 1552a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com } 1553c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com if (rect.fLeft >= clipR.fRight || rect.fRight <= clipR.fLeft) { 1554a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com return true; 1555a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com } 1556a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com return false; 15578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 15588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 15598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 15603b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::quickReject(const SkPath& path) const { 15613b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com return path.isEmpty() || this->quickReject(path.getBounds()); 15628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 15638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 15643b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::getClipBounds(SkRect* bounds) const { 1565bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect ibounds; 15668f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!this->getClipDeviceBounds(&ibounds)) { 15678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 15688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 15698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1570d9c0f0b57affec7a472879c5919acac6637d926areed@android.com SkMatrix inverse; 1571d9c0f0b57affec7a472879c5919acac6637d926areed@android.com // if we can't invert the CTM, we can't return local clip bounds 15721f836ee096bb988adef4b9757b2629c7afeda36dreed if (!fMCRec->fMatrix.invert(&inverse)) { 157372dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com if (bounds) { 157472dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com bounds->setEmpty(); 157572dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com } 1576d9c0f0b57affec7a472879c5919acac6637d926areed@android.com return false; 1577d9c0f0b57affec7a472879c5919acac6637d926areed@android.com } 1578d9c0f0b57affec7a472879c5919acac6637d926areed@android.com 157949f085dddff10473b6ebf832a974288300224e60bsalomon if (bounds) { 1580bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkRect r; 15813b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com // adjust it outwards in case we are antialiasing 15823b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com const int inset = 1; 1583fa4d5bd09f8f1a4a92b5ae0324800dd672760898reed@google.com 15848f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com r.iset(ibounds.fLeft - inset, ibounds.fTop - inset, 15858f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com ibounds.fRight + inset, ibounds.fBottom + inset); 15868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inverse.mapRect(bounds, r); 15878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 15888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 15898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 15908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1591bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.combool SkCanvas::getClipDeviceBounds(SkIRect* bounds) const { 15921f836ee096bb988adef4b9757b2629c7afeda36dreed const SkRasterClip& clip = fMCRec->fRasterClip; 1593bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (clip.isEmpty()) { 1594bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (bounds) { 1595bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com bounds->setEmpty(); 1596bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1597bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com return false; 1598bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1599bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com 160049f085dddff10473b6ebf832a974288300224e60bsalomon if (bounds) { 1601bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com *bounds = clip.getBounds(); 1602bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1603bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com return true; 1604bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com} 1605bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com 16068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkMatrix& SkCanvas::getTotalMatrix() const { 16071f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fMatrix; 16088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16105c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.orgconst SkRegion& SkCanvas::internal_private_getTotalClip() const { 16111f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.forceGetBW(); 16125c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org} 16135c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org 16149c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.comGrRenderTarget* SkCanvas::internal_private_accessTopLayerRenderTarget() { 16159c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com SkBaseDevice* dev = this->getTopDevice(); 16169c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com return dev ? dev->accessRenderTarget() : NULL; 16179c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 16189c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 161915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.orgSkBaseDevice* SkCanvas::createLayerDevice(const SkImageInfo& info) { 16201f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* device = this->getTopDevice(); 162115a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org return device ? device->createCompatibleDeviceForSaveLayer(info) : NULL; 16228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1624644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.orgGrContext* SkCanvas::getGrContext() { 1625644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#if SK_SUPPORT_GPU 1626644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org SkBaseDevice* device = this->getTopDevice(); 162749f085dddff10473b6ebf832a974288300224e60bsalomon if (device) { 1628644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org GrRenderTarget* renderTarget = device->accessRenderTarget(); 162949f085dddff10473b6ebf832a974288300224e60bsalomon if (renderTarget) { 1630644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org return renderTarget->getContext(); 1631644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org } 1632644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org } 1633644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#endif 1634644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org 1635644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org return NULL; 1636644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org 1637644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org} 1638e97f0856a8044866b12527819d14cdfbcdfd96f2bsalomon@google.com 1639ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.orgvoid SkCanvas::drawDRRect(const SkRRect& outer, const SkRRect& inner, 1640ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkPaint& paint) { 1641ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (outer.isEmpty()) { 1642ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 1643ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 1644ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (inner.isEmpty()) { 1645ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->drawRRect(outer, paint); 1646ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 1647ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 1648ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 1649ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // We don't have this method (yet), but technically this is what we should 1650ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // be able to assert... 1651ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // SkASSERT(outer.contains(inner)); 1652ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // 1653ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // For now at least check for containment of bounds 1654ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org SkASSERT(outer.getBounds().contains(inner.getBounds())); 1655ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 1656ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->onDrawDRRect(outer, inner, paint); 1657ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org} 1658ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 16598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 16608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// These are the virtual drawing methods 16618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 16628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16632a98181f048c11f21f52fbd99f803f5fd6118261reed@google.comvoid SkCanvas::clear(SkColor color) { 16642a98181f048c11f21f52fbd99f803f5fd6118261reed@google.com SkDrawIter iter(this); 1665995beb6b00afc0e28f5effc8a22a7a3dcb2544e8junov@chromium.org this->predrawNotify(); 16662a98181f048c11f21f52fbd99f803f5fd6118261reed@google.com while (iter.next()) { 16672a98181f048c11f21f52fbd99f803f5fd6118261reed@google.com iter.fDevice->clear(color); 16682a98181f048c11f21f52fbd99f803f5fd6118261reed@google.com } 16692a98181f048c11f21f52fbd99f803f5fd6118261reed@google.com} 16702a98181f048c11f21f52fbd99f803f5fd6118261reed@google.com 167128361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.orgvoid SkCanvas::onDiscard() { 167249f085dddff10473b6ebf832a974288300224e60bsalomon if (fSurfaceBase) { 167328361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org fSurfaceBase->aboutToDraw(SkSurface::kDiscard_ContentChangeMode); 167428361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org } 167528361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org} 167628361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org 16778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPaint(const SkPaint& paint) { 1678fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->internalDrawPaint(paint); 1679fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com} 1680fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com 1681fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.comvoid SkCanvas::internalDrawPaint(const SkPaint& paint) { 168278cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPaint_Type, NULL) 16838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 16854e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPaint(iter, looper.paint()); 16868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 16878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16884e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 16898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPoints(PointMode mode, size_t count, const SkPoint pts[], 16928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 16938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if ((long)count <= 0) { 16948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 16958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 16968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 169778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect r, storage; 169878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 1699a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com if (paint.canComputeFastBounds()) { 1700a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com // special-case 2 points (common for drawing a single line) 1701a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com if (2 == count) { 1702a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com r.set(pts[0], pts[1]); 1703a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } else { 1704a8c7f7702fb4bbedb615031bc653c5cd161a038ecommit-bot@chromium.org r.set(pts, SkToInt(count)); 1705a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } 170678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint.computeFastStrokeBounds(r, &storage); 170778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (this->quickReject(*bounds)) { 1708a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com return; 1709a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } 1710fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 1711a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com 17128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(pts != NULL); 17138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 171478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPoint_Type, bounds) 17154b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 17168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 17174e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPoints(iter, mode, count, pts, looper.paint()); 17188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 17194b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 17204e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 17218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17237ce564cccb246ec56427085872b2e1458fe74bd1bsalomon@google.comvoid SkCanvas::drawRect(const SkRect& r, const SkPaint& paint) { 172478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 172578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 17268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.canComputeFastBounds()) { 172778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint.computeFastBounds(r, &storage); 172878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (this->quickReject(*bounds)) { 17298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 17308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 17318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 17324b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 173378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kRect_Type, bounds) 17348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 17364e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawRect(iter, r, looper.paint()); 17378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 17388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17394e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 17408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17424ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.comvoid SkCanvas::drawOval(const SkRect& oval, const SkPaint& paint) { 174378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 174478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 17454ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (paint.canComputeFastBounds()) { 174678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint.computeFastBounds(oval, &storage); 174778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (this->quickReject(*bounds)) { 17484ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com return; 17494ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 17504ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 1751306ab9d5de38f2a547fd1d69aedbe69b5c6617ccskia.committer@gmail.com 175278cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, bounds) 175346d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com 175446d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com while (iter.next()) { 175546d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com iter.fDevice->drawOval(iter, oval, looper.paint()); 175646d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com } 175746d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com 175846d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com LOOPER_END 17594ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 17604ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 17614ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.comvoid SkCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) { 176278cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 176378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 17644ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (paint.canComputeFastBounds()) { 176578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint.computeFastBounds(rrect.getBounds(), &storage); 176678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (this->quickReject(*bounds)) { 17674ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com return; 17684ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 17694ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 17704ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 17714ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (rrect.isRect()) { 17724ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com // call the non-virtual version 17734ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->SkCanvas::drawRect(rrect.getBounds(), paint); 1774f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org return; 1775f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } else if (rrect.isOval()) { 17764ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com // call the non-virtual version 1777f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org this->SkCanvas::drawOval(rrect.getBounds(), paint); 1778f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org return; 17794ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 1780f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 178178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) 1782f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 1783f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org while (iter.next()) { 1784f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org iter.fDevice->drawRRect(iter, rrect, looper.paint()); 1785f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } 1786f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 1787f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org LOOPER_END 17884ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 17894ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 1790ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.orgvoid SkCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, 1791ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkPaint& paint) { 1792ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org SkRect storage; 1793ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkRect* bounds = NULL; 1794ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (paint.canComputeFastBounds()) { 1795ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org bounds = &paint.computeFastBounds(outer.getBounds(), &storage); 1796ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (this->quickReject(*bounds)) { 1797ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 1798ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 1799ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 180025c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 1801ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) 180225c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 1803ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org while (iter.next()) { 1804ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org iter.fDevice->drawDRRect(iter, outer, inner, looper.paint()); 1805ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 180625c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 1807ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org LOOPER_END 1808ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org} 18094ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 18107ce564cccb246ec56427085872b2e1458fe74bd1bsalomon@google.comvoid SkCanvas::drawPath(const SkPath& path, const SkPaint& paint) { 18119364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com if (!path.isFinite()) { 18129364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com return; 18139364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com } 18149364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com 181578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 181678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 1817fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com if (!path.isInverseFillType() && paint.canComputeFastBounds()) { 181878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect& pathBounds = path.getBounds(); 181978cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint.computeFastBounds(pathBounds, &storage); 182078cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (this->quickReject(*bounds)) { 18218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 18228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18240b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org 18250b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org const SkRect& r = path.getBounds(); 18260b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org if (r.width() <= 0 && r.height() <= 0) { 18276803c219dd3be4a73e7bb5c4bb8a5b1f803624d0commit-bot@chromium.org if (path.isInverseFillType()) { 1828fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->internalDrawPaint(paint); 1829fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 1830fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com return; 1831fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 18328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 183378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, bounds) 18348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 18364e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPath(iter, path, looper.paint()); 18378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18394e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 18408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y, 18438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* paint) { 18448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(bitmap.validate();) 18458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18463d60812865bb034851da777a91413ab584929887reed@google.com if (NULL == paint || paint->canComputeFastBounds()) { 18479efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com SkRect bounds = { 18489efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com x, y, 18499efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com x + SkIntToScalar(bitmap.width()), 18509efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com y + SkIntToScalar(bitmap.height()) 18519efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com }; 18529efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com if (paint) { 18539efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com (void)paint->computeFastBounds(bounds, &bounds); 18549efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com } 18553b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(bounds)) { 18568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 18578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18594b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 18608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 18618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.setTranslate(x, y); 18629bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com this->internalDrawBitmap(bitmap, matrix, paint); 18638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18659987ec3791336bad6af5cbe513564786b2df55aareed@google.com// this one is non-virtual, so it can be called safely by other canvas apis 18667112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.comvoid SkCanvas::internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, 1867eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org const SkRect& dst, const SkPaint* paint, 1868eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org DrawBitmapRectFlags flags) { 186950b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org if (bitmap.drawsNothing() || dst.isEmpty()) { 18708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 18718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 187274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 187378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 187478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = &dst; 18753d60812865bb034851da777a91413ab584929887reed@google.com if (NULL == paint || paint->canComputeFastBounds()) { 18769efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com if (paint) { 18779efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com bounds = &paint->computeFastBounds(dst, &storage); 18789efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com } 18793b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(*bounds)) { 18803d60812865bb034851da777a91413ab584929887reed@google.com return; 18813d60812865bb034851da777a91413ab584929887reed@google.com } 18828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18833d60812865bb034851da777a91413ab584929887reed@google.com 188433535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com SkLazyPaint lazy; 188533535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com if (NULL == paint) { 188633535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com paint = lazy.init(); 18878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18887064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 188978cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) 18907064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 189133535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com while (iter.next()) { 1892eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org iter.fDevice->drawBitmapRect(iter, bitmap, src, dst, looper.paint(), flags); 1893f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 18947064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 189533535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com LOOPER_END 18968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18987112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.comvoid SkCanvas::drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src, 1899eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org const SkRect& dst, const SkPaint* paint, 1900eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org DrawBitmapRectFlags flags) { 19019987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkDEBUGCODE(bitmap.validate();) 1902eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org this->internalDrawBitmapRect(bitmap, src, dst, paint, flags); 19039987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 19049987ec3791336bad6af5cbe513564786b2df55aareed@google.com 19058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& matrix, 19068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* paint) { 19078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(bitmap.validate();) 19089bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com this->internalDrawBitmap(bitmap, matrix, paint); 19098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 19108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19119987ec3791336bad6af5cbe513564786b2df55aareed@google.comvoid SkCanvas::internalDrawBitmapNine(const SkBitmap& bitmap, 19129987ec3791336bad6af5cbe513564786b2df55aareed@google.com const SkIRect& center, const SkRect& dst, 19139987ec3791336bad6af5cbe513564786b2df55aareed@google.com const SkPaint* paint) { 191450b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org if (bitmap.drawsNothing()) { 191550b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org return; 191650b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org } 19173d60812865bb034851da777a91413ab584929887reed@google.com if (NULL == paint || paint->canComputeFastBounds()) { 191860abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com SkRect storage; 191960abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com const SkRect* bounds = &dst; 192060abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com if (paint) { 192160abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com bounds = &paint->computeFastBounds(dst, &storage); 192260abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com } 19233b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(*bounds)) { 19243d60812865bb034851da777a91413ab584929887reed@google.com return; 19253d60812865bb034851da777a91413ab584929887reed@google.com } 19263d60812865bb034851da777a91413ab584929887reed@google.com } 19273d60812865bb034851da777a91413ab584929887reed@google.com 19289987ec3791336bad6af5cbe513564786b2df55aareed@google.com const int32_t w = bitmap.width(); 19299987ec3791336bad6af5cbe513564786b2df55aareed@google.com const int32_t h = bitmap.height(); 19309987ec3791336bad6af5cbe513564786b2df55aareed@google.com 19319987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkIRect c = center; 19329987ec3791336bad6af5cbe513564786b2df55aareed@google.com // pin center to the bounds of the bitmap 19339987ec3791336bad6af5cbe513564786b2df55aareed@google.com c.fLeft = SkMax32(0, center.fLeft); 19349987ec3791336bad6af5cbe513564786b2df55aareed@google.com c.fTop = SkMax32(0, center.fTop); 19359987ec3791336bad6af5cbe513564786b2df55aareed@google.com c.fRight = SkPin32(center.fRight, c.fLeft, w); 19369987ec3791336bad6af5cbe513564786b2df55aareed@google.com c.fBottom = SkPin32(center.fBottom, c.fTop, h); 19379987ec3791336bad6af5cbe513564786b2df55aareed@google.com 19387112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com const SkScalar srcX[4] = { 19397d474f8a84a74421bd8d119124daa64ec1710f76rmistry@google.com 0, SkIntToScalar(c.fLeft), SkIntToScalar(c.fRight), SkIntToScalar(w) 19407112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com }; 19417112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com const SkScalar srcY[4] = { 19427d474f8a84a74421bd8d119124daa64ec1710f76rmistry@google.com 0, SkIntToScalar(c.fTop), SkIntToScalar(c.fBottom), SkIntToScalar(h) 19437112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com }; 19449987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkScalar dstX[4] = { 19459987ec3791336bad6af5cbe513564786b2df55aareed@google.com dst.fLeft, dst.fLeft + SkIntToScalar(c.fLeft), 19469987ec3791336bad6af5cbe513564786b2df55aareed@google.com dst.fRight - SkIntToScalar(w - c.fRight), dst.fRight 19479987ec3791336bad6af5cbe513564786b2df55aareed@google.com }; 19489987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkScalar dstY[4] = { 19499987ec3791336bad6af5cbe513564786b2df55aareed@google.com dst.fTop, dst.fTop + SkIntToScalar(c.fTop), 19509987ec3791336bad6af5cbe513564786b2df55aareed@google.com dst.fBottom - SkIntToScalar(h - c.fBottom), dst.fBottom 19519987ec3791336bad6af5cbe513564786b2df55aareed@google.com }; 195274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 19539987ec3791336bad6af5cbe513564786b2df55aareed@google.com if (dstX[1] > dstX[2]) { 19549987ec3791336bad6af5cbe513564786b2df55aareed@google.com dstX[1] = dstX[0] + (dstX[3] - dstX[0]) * c.fLeft / (w - c.width()); 19559987ec3791336bad6af5cbe513564786b2df55aareed@google.com dstX[2] = dstX[1]; 19569987ec3791336bad6af5cbe513564786b2df55aareed@google.com } 195774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 19589987ec3791336bad6af5cbe513564786b2df55aareed@google.com if (dstY[1] > dstY[2]) { 19599987ec3791336bad6af5cbe513564786b2df55aareed@google.com dstY[1] = dstY[0] + (dstY[3] - dstY[0]) * c.fTop / (h - c.height()); 19609987ec3791336bad6af5cbe513564786b2df55aareed@google.com dstY[2] = dstY[1]; 19619987ec3791336bad6af5cbe513564786b2df55aareed@google.com } 196274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 19639987ec3791336bad6af5cbe513564786b2df55aareed@google.com for (int y = 0; y < 3; y++) { 19647112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com SkRect s, d; 19657112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com 19669987ec3791336bad6af5cbe513564786b2df55aareed@google.com s.fTop = srcY[y]; 19679987ec3791336bad6af5cbe513564786b2df55aareed@google.com s.fBottom = srcY[y+1]; 19689987ec3791336bad6af5cbe513564786b2df55aareed@google.com d.fTop = dstY[y]; 19699987ec3791336bad6af5cbe513564786b2df55aareed@google.com d.fBottom = dstY[y+1]; 19709987ec3791336bad6af5cbe513564786b2df55aareed@google.com for (int x = 0; x < 3; x++) { 19719987ec3791336bad6af5cbe513564786b2df55aareed@google.com s.fLeft = srcX[x]; 19729987ec3791336bad6af5cbe513564786b2df55aareed@google.com s.fRight = srcX[x+1]; 19739987ec3791336bad6af5cbe513564786b2df55aareed@google.com d.fLeft = dstX[x]; 19749987ec3791336bad6af5cbe513564786b2df55aareed@google.com d.fRight = dstX[x+1]; 1975eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org this->internalDrawBitmapRect(bitmap, &s, d, paint, 197631acc11977815402e4ef2681350f8559285bec97robertphillips@google.com kNone_DrawBitmapRectFlag); 19779987ec3791336bad6af5cbe513564786b2df55aareed@google.com } 19789987ec3791336bad6af5cbe513564786b2df55aareed@google.com } 19799987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 19809987ec3791336bad6af5cbe513564786b2df55aareed@google.com 19819987ec3791336bad6af5cbe513564786b2df55aareed@google.comvoid SkCanvas::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, 19829987ec3791336bad6af5cbe513564786b2df55aareed@google.com const SkRect& dst, const SkPaint* paint) { 19839987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkDEBUGCODE(bitmap.validate();) 19849987ec3791336bad6af5cbe513564786b2df55aareed@google.com 19859987ec3791336bad6af5cbe513564786b2df55aareed@google.com // Need a device entry-point, so gpu can use a mesh 19869987ec3791336bad6af5cbe513564786b2df55aareed@google.com this->internalDrawBitmapNine(bitmap, center, dst, paint); 19879987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 19889987ec3791336bad6af5cbe513564786b2df55aareed@google.com 1989f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.comclass SkDeviceFilteredPaint { 1990f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.compublic: 19911f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkDeviceFilteredPaint(SkBaseDevice* device, const SkPaint& paint) { 19921f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice::TextFlags flags; 1993f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com if (device->filterTextFlags(paint, &flags)) { 1994a076e9be17654a60310e72c4f70fcd5337f56dbfreed@google.com SkPaint* newPaint = fLazy.set(paint); 1995f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com newPaint->setFlags(flags.fFlags); 1996f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com newPaint->setHinting(flags.fHinting); 1997f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com fPaint = newPaint; 1998f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } else { 1999f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com fPaint = &paint; 2000f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } 2001f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } 2002f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 2003f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com const SkPaint& paint() const { return *fPaint; } 2004f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 2005f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.comprivate: 20062c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint* fPaint; 20072c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkLazyPaint fLazy; 2008f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com}; 2009f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 201052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.comvoid SkCanvas::DrawRect(const SkDraw& draw, const SkPaint& paint, 201152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com const SkRect& r, SkScalar textSize) { 201217b78946096265d80215a6c946286ecaa35ea7edepoger@google.com if (paint.getStyle() == SkPaint::kFill_Style) { 201352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com draw.fDevice->drawRect(draw, r, paint); 201452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } else { 201552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPaint p(paint); 201617b78946096265d80215a6c946286ecaa35ea7edepoger@google.com p.setStrokeWidth(SkScalarMul(textSize, paint.getStrokeWidth())); 201752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com draw.fDevice->drawRect(draw, r, p); 201852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 201952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com} 202052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 202152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.comvoid SkCanvas::DrawTextDecorations(const SkDraw& draw, const SkPaint& paint, 202252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com const char text[], size_t byteLength, 202352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar x, SkScalar y) { 202452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkASSERT(byteLength == 0 || text != NULL); 202552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 202652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com // nothing to draw 202752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (text == NULL || byteLength == 0 || 202852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com draw.fClip->isEmpty() || 202952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com (paint.getAlpha() == 0 && paint.getXfermode() == NULL)) { 203052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com return; 203152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 203252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 203352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar width = 0; 203452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPoint start; 203552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 203652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.set(0, 0); // to avoid warning 203752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (paint.getFlags() & (SkPaint::kUnderlineText_Flag | 203852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPaint::kStrikeThruText_Flag)) { 203952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com width = paint.measureText(text, byteLength); 204052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 204152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar offsetX = 0; 204252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (paint.getTextAlign() == SkPaint::kCenter_Align) { 204352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com offsetX = SkScalarHalf(width); 204452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } else if (paint.getTextAlign() == SkPaint::kRight_Align) { 204552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com offsetX = width; 204652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 204752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.set(x - offsetX, y); 204852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 204952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 205052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (0 == width) { 205152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com return; 205252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 205352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 205452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com uint32_t flags = paint.getFlags(); 205552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 205652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (flags & (SkPaint::kUnderlineText_Flag | 205752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPaint::kStrikeThruText_Flag)) { 205852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar textSize = paint.getTextSize(); 205952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar height = SkScalarMul(textSize, kStdUnderline_Thickness); 206052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkRect r; 206152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 206252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fLeft = start.fX; 206352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fRight = start.fX + width; 206452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 206552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (flags & SkPaint::kUnderlineText_Flag) { 206652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar offset = SkScalarMulAdd(textSize, kStdUnderline_Offset, 206752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.fY); 206852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fTop = offset; 206952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fBottom = offset + height; 207052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com DrawRect(draw, paint, r, textSize); 207152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 207252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (flags & SkPaint::kStrikeThruText_Flag) { 207352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar offset = SkScalarMulAdd(textSize, kStdStrikeThru_Offset, 207452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.fY); 207552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fTop = offset; 207652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fBottom = offset + height; 207752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com DrawRect(draw, paint, r, textSize); 207852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 207952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 208052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com} 208152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 2082e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 2083e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 208478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL) 20858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 20874e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 2088f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com iter.fDevice->drawText(iter, text, byteLength, x, y, dfp.paint()); 208952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com DrawTextDecorations(iter, dfp.paint(), 209052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com static_cast<const char*>(text), byteLength, x, y); 20918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 20928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20934e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 20948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 20958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2096e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], 2097e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 209878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL) 209987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 21008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 21014e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 21028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawPosText(iter, text, byteLength, &pos->fX, 0, 2, 2103f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com dfp.paint()); 21048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2105b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 21064e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 21078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 21088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2109e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], 2110e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com SkScalar constY, const SkPaint& paint) { 211178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL) 211287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 21138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 21144e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 21158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawPosText(iter, text, byteLength, xpos, constY, 1, 2116f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com dfp.paint()); 21178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2118b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 21194e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 21208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 21218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2122e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 2123e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkMatrix* matrix, const SkPaint& paint) { 212478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL) 212587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 21268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 21278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawTextOnPath(iter, text, byteLength, path, 21284e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com matrix, looper.paint()); 21298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2130b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 2131945ec3a2bec668ca845071a65df8ec55e8f43819commit-bot@chromium.org LOOPER_END 21324325d114a5679e46f25ae75b0e43547fd7694998commit-bot@chromium.org} 21334325d114a5679e46f25ae75b0e43547fd7694998commit-bot@chromium.org 213400d5c2c6523321d25b32905ff4822f083a4173eefmalitavoid SkCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 213500d5c2c6523321d25b32905ff4822f083a4173eefmalita const SkPaint& paint) { 21367ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita 21377ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita // FIXME: temporarily disable quickreject for empty bounds, 21387ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita // pending implicit blob bounds implementation. 21397ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita if (!blob->bounds().isEmpty() && paint.canComputeFastBounds()) { 21407ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita SkRect storage; 21417ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita 21427ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita if (this->quickReject(paint.computeFastBounds(blob->bounds().makeOffset(x, y), &storage))) { 21437ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita return; 21447ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita } 21457ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita } 21467ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita 2147aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL) 214800d5c2c6523321d25b32905ff4822f083a4173eefmalita 2149aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita while (iter.next()) { 2150aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 2151aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita iter.fDevice->drawTextBlob(iter, blob, x, y, dfp.paint()); 215200d5c2c6523321d25b32905ff4822f083a4173eefmalita } 215300d5c2c6523321d25b32905ff4822f083a4173eefmalita 2154aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita LOOPER_END 215500d5c2c6523321d25b32905ff4822f083a4173eefmalita} 215600d5c2c6523321d25b32905ff4822f083a4173eefmalita 2157e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com// These will become non-virtual, so they always call the (virtual) onDraw... method 2158e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 2159e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 2160e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawText(text, byteLength, x, y, paint); 2161e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2162e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawPosText(const void* text, size_t byteLength, const SkPoint pos[], 2163e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 2164e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawPosText(text, byteLength, pos, paint); 2165e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2166e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], 2167e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com SkScalar constY, const SkPaint& paint) { 2168e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawPosTextH(text, byteLength, xpos, constY, paint); 2169e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2170e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 2171e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkMatrix* matrix, const SkPaint& paint) { 2172e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawTextOnPath(text, byteLength, path, matrix, paint); 2173e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 217400d5c2c6523321d25b32905ff4822f083a4173eefmalitavoid SkCanvas::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 217500d5c2c6523321d25b32905ff4822f083a4173eefmalita const SkPaint& paint) { 217649f085dddff10473b6ebf832a974288300224e60bsalomon if (blob) { 217700d5c2c6523321d25b32905ff4822f083a4173eefmalita this->onDrawTextBlob(blob, x, y, paint); 217800d5c2c6523321d25b32905ff4822f083a4173eefmalita } 217900d5c2c6523321d25b32905ff4822f083a4173eefmalita} 2180e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com 21818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawVertices(VertexMode vmode, int vertexCount, 21828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPoint verts[], const SkPoint texs[], 21838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkColor colors[], SkXfermode* xmode, 21848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint16_t indices[], int indexCount, 21858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 218678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, NULL) 21874b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 21888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 21898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawVertices(iter, vmode, vertexCount, verts, texs, 21904e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com colors, xmode, indices, indexCount, 21914e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com looper.paint()); 21928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 21934b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 21944e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 21958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 21968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2197b3c9d1c33caf325aada244204215eb790c228c12dandovvoid SkCanvas::drawPatch(const SkPoint cubics[12], const SkColor colors[4], 2198b3c9d1c33caf325aada244204215eb790c228c12dandov const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint) { 2199b3c9d1c33caf325aada244204215eb790c228c12dandov if (NULL == cubics) { 2200b3c9d1c33caf325aada244204215eb790c228c12dandov return; 2201b3c9d1c33caf325aada244204215eb790c228c12dandov } 22026cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2203ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov // Since a patch is always within the convex hull of the control points, we discard it when its 2204ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov // bounding rectangle is completely outside the current clip. 2205ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov SkRect bounds; 2206b3c9d1c33caf325aada244204215eb790c228c12dandov bounds.set(cubics, SkPatchUtils::kNumCtrlPts); 2207ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov if (this->quickReject(bounds)) { 2208ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov return; 2209ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov } 22106cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2211b3c9d1c33caf325aada244204215eb790c228c12dandov this->onDrawPatch(cubics, colors, texCoords, xmode, paint); 2212b3c9d1c33caf325aada244204215eb790c228c12dandov} 2213b3c9d1c33caf325aada244204215eb790c228c12dandov 2214b3c9d1c33caf325aada244204215eb790c228c12dandovvoid SkCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], 2215b3c9d1c33caf325aada244204215eb790c228c12dandov const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint) { 2216b3c9d1c33caf325aada244204215eb790c228c12dandov 2217ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, NULL) 22186cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2219ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov while (iter.next()) { 2220b3c9d1c33caf325aada244204215eb790c228c12dandov iter.fDevice->drawPatch(iter, cubics, colors, texCoords, xmode, paint); 2221ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov } 22226cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2223ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov LOOPER_END 2224ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov} 2225ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov 22268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 22278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// These methods are NOT virtual, and therefore must call back into virtual 22288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// methods, rather than actually drawing themselves. 22298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 22308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b, 2232845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com SkXfermode::Mode mode) { 22338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 22348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setARGB(a, r, g, b); 2236845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com if (SkXfermode::kSrcOver_Mode != mode) { 22370baf19375466cfc24c96532df406e7c5b1d1aae8reed@android.com paint.setXfermodeMode(mode); 22388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 22398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPaint(paint); 22408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 22418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2242845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.comvoid SkCanvas::drawColor(SkColor c, SkXfermode::Mode mode) { 22438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 22448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setColor(c); 2246845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com if (SkXfermode::kSrcOver_Mode != mode) { 22470baf19375466cfc24c96532df406e7c5b1d1aae8reed@android.com paint.setXfermodeMode(mode); 22488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 22498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPaint(paint); 22508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 22518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPoint(SkScalar x, SkScalar y, const SkPaint& paint) { 22538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pt; 22544b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 22558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pt.set(x, y); 22568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kPoints_PointMode, 1, &pt, paint); 22578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 22588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPoint(SkScalar x, SkScalar y, SkColor color) { 22608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pt; 22618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 22624b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 22638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pt.set(x, y); 22648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setColor(color); 22658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kPoints_PointMode, 1, &pt, paint); 22668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 22678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, 22698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 22708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pts[2]; 22714b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 22728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pts[0].set(x0, y0); 22738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pts[1].set(x1, y1); 22748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kLines_PointMode, 2, pts, paint); 22758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 22768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawRectCoords(SkScalar left, SkScalar top, 22788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar right, SkScalar bottom, 22798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 22808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 22818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.set(left, top, right, bottom); 22838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawRect(r, paint); 22848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 22858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, 22878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 22888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (radius < 0) { 22898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com radius = 0; 22908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 22918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 22938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.set(cx - radius, cy - radius, cx + radius, cy + radius); 22944ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->drawOval(r, paint); 22958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 22968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawRoundRect(const SkRect& r, SkScalar rx, SkScalar ry, 22988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 22998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (rx > 0 && ry > 0) { 23008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.canComputeFastBounds()) { 23018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect storage; 23023b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(paint.computeFastBounds(r, &storage))) { 23038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 23048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23064ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com SkRRect rrect; 23074ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com rrect.setRectXY(r, rx, ry); 23084ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->drawRRect(rrect, paint); 23098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 23108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawRect(r, paint); 23118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawArc(const SkRect& oval, SkScalar startAngle, 23158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar sweepAngle, bool useCenter, 23168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 23178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (SkScalarAbs(sweepAngle) >= SkIntToScalar(360)) { 23188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawOval(oval, paint); 23198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 23208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath path; 23218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (useCenter) { 23228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.moveTo(oval.centerX(), oval.centerY()); 23238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.arcTo(oval, startAngle, sweepAngle, !useCenter); 23258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (useCenter) { 23268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.close(); 23278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPath(path, paint); 23298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawTextOnPathHV(const void* text, size_t byteLength, 23338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPath& path, SkScalar hOffset, 23348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar vOffset, const SkPaint& paint) { 23358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 23364b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 23378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.setTranslate(hOffset, vOffset); 23388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawTextOnPath(text, byteLength, path, &matrix, paint); 23398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2341f76bacff7f66724072c67edb185abf9e3add11a0reed@android.com/////////////////////////////////////////////////////////////////////////////// 23429b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillipsvoid SkCanvas::EXPERIMENTAL_optimize(const SkPicture* picture) { 2343145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org SkBaseDevice* device = this->getDevice(); 234449f085dddff10473b6ebf832a974288300224e60bsalomon if (device) { 2345145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org device->EXPERIMENTAL_optimize(picture); 2346145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org } 2347145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org} 2348f76bacff7f66724072c67edb185abf9e3add11a0reed@android.com 23499b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillipsvoid SkCanvas::drawPicture(const SkPicture* picture) { 235049f085dddff10473b6ebf832a974288300224e60bsalomon if (picture) { 2351d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed this->onDrawPicture(picture, NULL, NULL); 23529b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips } 23539b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips} 23549b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips 2355d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedvoid SkCanvas::drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint) { 235649f085dddff10473b6ebf832a974288300224e60bsalomon if (picture) { 2357d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed if (matrix && matrix->isIdentity()) { 2358d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed matrix = NULL; 2359d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 2360d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed this->onDrawPicture(picture, matrix, paint); 2361d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 2362d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 23639b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips 2364d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedvoid SkCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix, 2365d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed const SkPaint* paint) { 2366145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org SkBaseDevice* device = this->getTopDevice(); 236749f085dddff10473b6ebf832a974288300224e60bsalomon if (device) { 2368145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org // Canvas has to first give the device the opportunity to render 2369145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org // the picture itself. 2370d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed if (device->EXPERIMENTAL_drawPicture(this, picture, matrix, paint)) { 2371145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org return; // the device has rendered the entire picture 2372145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org } 2373145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org } 2374145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org 2375a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); 2376d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 2377c5ba71d2e5cd426def66fa49dcf003e5b2c98dc7robertphillips picture->playback(this); 23788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 23818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 23828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::LayerIter::LayerIter(SkCanvas* canvas, bool skipEmptyClips) { 2384d642329293cce602ac24df8f585c14a98795da87reed@google.com SK_COMPILE_ASSERT(sizeof(fStorage) >= sizeof(SkDrawIter), fStorage_too_small); 23858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(canvas); 23878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fImpl = new (fStorage) SkDrawIter(canvas, skipEmptyClips); 23898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDone = !fImpl->next(); 23908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::LayerIter::~LayerIter() { 23938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fImpl->~SkDrawIter(); 23948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::LayerIter::next() { 23978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDone = !fImpl->next(); 23988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24001f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::LayerIter::device() const { 24018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fImpl->getDevice(); 24028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkMatrix& SkCanvas::LayerIter::matrix() const { 24058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fImpl->getMatrix(); 24068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkPaint& SkCanvas::LayerIter::paint() const { 24098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* paint = fImpl->getPaint(); 24108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == paint) { 24118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint = &fDefaultPaint; 24128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 24138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return *paint; 24148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkRegion& SkCanvas::LayerIter::clip() const { return fImpl->getClip(); } 24178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::LayerIter::x() const { return fImpl->getX(); } 24188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::LayerIter::y() const { return fImpl->getY(); } 241920a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com 242020a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com/////////////////////////////////////////////////////////////////////////////// 242120a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com 2422c3b589a24eb4d567a906189f882c259ecf5c2f58fmalitaSkCanvasClipVisitor::~SkCanvasClipVisitor() { } 24233107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 24243107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 24253107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 24263107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.orgstatic bool supported_for_raster_canvas(const SkImageInfo& info) { 24273107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org switch (info.alphaType()) { 24283107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kPremul_SkAlphaType: 24293107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kOpaque_SkAlphaType: 24303107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org break; 24313107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org default: 24323107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return false; 24333107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 24343107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 24353107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org switch (info.colorType()) { 24363107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kAlpha_8_SkColorType: 24373107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kRGB_565_SkColorType: 243828fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org case kN32_SkColorType: 24393107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org break; 24403107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org default: 24413107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return false; 24423107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 24433107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 24443107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return true; 24453107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org} 24463107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 24473107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.orgSkCanvas* SkCanvas::NewRaster(const SkImageInfo& info) { 24483107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org if (!supported_for_raster_canvas(info)) { 24493107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return NULL; 24503107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 24513107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 24523107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org SkBitmap bitmap; 2453848250415eddc54075f7eb8795e8db79e749c6abreed if (!bitmap.tryAllocPixels(info)) { 24543107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return NULL; 24553107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 24563107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 24573107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org // should this functionality be moved into allocPixels()? 24583107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org if (!bitmap.info().isOpaque()) { 24593107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org bitmap.eraseColor(0); 24603107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 24613107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return SkNEW_ARGS(SkCanvas, (bitmap)); 24623107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org} 246342b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org 246442b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.orgSkCanvas* SkCanvas::NewRasterDirect(const SkImageInfo& info, void* pixels, size_t rowBytes) { 246542b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org if (!supported_for_raster_canvas(info)) { 246642b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org return NULL; 246742b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org } 2468eb849e5fd10cbe00cbc31307ba97fd9efca0b41bskia.committer@gmail.com 246942b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org SkBitmap bitmap; 247042b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org if (!bitmap.installPixels(info, pixels, rowBytes)) { 247142b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org return NULL; 247242b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org } 247342b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org return SkNEW_ARGS(SkCanvas, (bitmap)); 247442b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org} 2475d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 2476d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed/////////////////////////////////////////////////////////////////////////////// 2477d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 2478d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedSkAutoCanvasMatrixPaint::SkAutoCanvasMatrixPaint(SkCanvas* canvas, const SkMatrix* matrix, 2479a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips const SkPaint* paint, const SkRect& bounds) 2480d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed : fCanvas(canvas) 2481d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed , fSaveCount(canvas->getSaveCount()) 2482d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed{ 248349f085dddff10473b6ebf832a974288300224e60bsalomon if (paint) { 2484a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkRect newBounds = bounds; 2485d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed if (matrix) { 2486a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips matrix->mapRect(&newBounds); 2487d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 2488a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips canvas->saveLayer(&newBounds, paint); 248949f085dddff10473b6ebf832a974288300224e60bsalomon } else if (matrix) { 2490d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed canvas->save(); 2491d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 24926cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 249349f085dddff10473b6ebf832a974288300224e60bsalomon if (matrix) { 2494d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed canvas->concat(*matrix); 2495d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 2496d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 2497d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 2498d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedSkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { 2499d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed fCanvas->restoreToCount(fSaveCount); 2500d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 2501