SkCanvas.cpp revision 0acf1b4b3645772d220c720313821bac389751b5
18a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2008 The Android Open Source Project 38a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 68a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h" 96a070dc06af4e9f305f9d08a69e34d18ade473cbreed#include "SkCanvasDrawable.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" 16b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr#include "SkImage.h" 1774bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org#include "SkMetaData.h" 1845a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com#include "SkPathOps.h" 19b3c9d1c33caf325aada244204215eb790c228c12dandov#include "SkPatchUtils.h" 208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPicture.h" 210017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com#include "SkRasterClip.h" 2296472deea70169396b8e1f576e470138f55fdb1freed#include "SkReadPixelsRec.h" 234ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com#include "SkRRect.h" 2479fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org#include "SkSmallAllocator.h" 2597af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com#include "SkSurface_Base.h" 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTemplates.h" 277ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita#include "SkTextBlob.h" 2852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com#include "SkTextFormatParams.h" 29a076e9be17654a60310e72c4f70fcd5337f56dbfreed@google.com#include "SkTLazy.h" 308f757f540a8378c7b1354aab3d4650eaa920b17adanakj#include "SkTraceEvent.h" 318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkUtils.h" 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 33644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#if SK_SUPPORT_GPU 34644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#include "GrRenderTarget.h" 35644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#endif 36644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org 37d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareedstatic bool gIgnoreSaveLayerBounds; 38d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareedvoid SkCanvas::Internal_Private_SetIgnoreSaveLayerBounds(bool ignore) { 39d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed gIgnoreSaveLayerBounds = ignore; 40d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed} 41d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareedbool SkCanvas::Internal_Private_GetIgnoreSaveLayerBounds() { 42d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed return gIgnoreSaveLayerBounds; 43d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed} 44d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed 450acf1b4b3645772d220c720313821bac389751b5reedstatic bool gTreatSpriteAsBitmap; 460acf1b4b3645772d220c720313821bac389751b5reedvoid SkCanvas::Internal_Private_SetTreatSpriteAsBitmap(bool spriteAsBitmap) { 470acf1b4b3645772d220c720313821bac389751b5reed gTreatSpriteAsBitmap = spriteAsBitmap; 480acf1b4b3645772d220c720313821bac389751b5reed} 490acf1b4b3645772d220c720313821bac389751b5reedbool SkCanvas::Internal_Private_GetTreatSpriteAsBitmap() { 500acf1b4b3645772d220c720313821bac389751b5reed return gTreatSpriteAsBitmap; 510acf1b4b3645772d220c720313821bac389751b5reed} 520acf1b4b3645772d220c720313821bac389751b5reed 53da17f758442f16747af39f8fbaed9c097048519creed@google.com// experimental for faster tiled drawing... 54da17f758442f16747af39f8fbaed9c097048519creed@google.com//#define SK_ENABLE_CLIP_QUICKREJECT 5515e9d3e66e161ce23df30bc13f8a0c87d196b463robertphillips@google.com 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//#define SK_TRACE_SAVERESTORE 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_TRACE_SAVERESTORE 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gLayerCounter; 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_layer() { ++gLayerCounter; printf("----- inc layer %d\n", gLayerCounter); } 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_layer() { --gLayerCounter; printf("----- dec layer %d\n", gLayerCounter); } 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gRecCounter; 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_rec() { ++gRecCounter; printf("----- inc rec %d\n", gRecCounter); } 658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_rec() { --gRecCounter; printf("----- dec rec %d\n", gRecCounter); } 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gCanvasCounter; 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_canvas() { ++gCanvasCounter; printf("----- inc canvas %d\n", gCanvasCounter); } 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_canvas() { --gCanvasCounter; printf("----- dec canvas %d\n", gCanvasCounter); } 708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_layer() 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_layer() 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_rec() 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_rec() 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_canvas() 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_canvas() 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 792c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.orgtypedef SkTLazy<SkPaint> SkLazyPaint; 802c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org 8197af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.comvoid SkCanvas::predrawNotify() { 8297af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com if (fSurfaceBase) { 83c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org fSurfaceBase->aboutToDraw(SkSurface::kRetain_ContentChangeMode); 8497af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com } 8597af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com} 8697af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com 878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 894a8126e7f81384526629b1e21bf89b632ea13cd9reedstatic uint32_t filter_paint_flags(const SkSurfaceProps& props, uint32_t flags) { 904a8126e7f81384526629b1e21bf89b632ea13cd9reed const uint32_t propFlags = props.flags(); 914a8126e7f81384526629b1e21bf89b632ea13cd9reed if (propFlags & SkSurfaceProps::kDisallowDither_Flag) { 924a8126e7f81384526629b1e21bf89b632ea13cd9reed flags &= ~SkPaint::kDither_Flag; 934a8126e7f81384526629b1e21bf89b632ea13cd9reed } 944a8126e7f81384526629b1e21bf89b632ea13cd9reed if (propFlags & SkSurfaceProps::kDisallowAntiAlias_Flag) { 954a8126e7f81384526629b1e21bf89b632ea13cd9reed flags &= ~SkPaint::kAntiAlias_Flag; 964a8126e7f81384526629b1e21bf89b632ea13cd9reed } 974a8126e7f81384526629b1e21bf89b632ea13cd9reed return flags; 984a8126e7f81384526629b1e21bf89b632ea13cd9reed} 994a8126e7f81384526629b1e21bf89b632ea13cd9reed 1004a8126e7f81384526629b1e21bf89b632ea13cd9reed/////////////////////////////////////////////////////////////////////////////// 1014a8126e7f81384526629b1e21bf89b632ea13cd9reed 1021f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com/* This is the record we keep for each SkBaseDevice that the user installs. 1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com The clip/matrix/proc are fields that reflect the top of the save/restore 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stack. Whenever the canvas changes, it marks a dirty flag, and then before 1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com these are used (assuming we're not on a layer) we rebuild these cache 1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com values: they reflect the top of the save stack, but translated and clipped 1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com by the device's XY offset and bitmap-bounds. 1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct DeviceCM { 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* fNext; 1111f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* fDevice; 112045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com SkRasterClip fClip; 1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix* fMatrix; 1146f8f292aa768869a9e85c314b124875f57504f2creed@google.com SkPaint* fPaint; // may be null (in the future) 1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 116d954498c01ccf0417feacf89e45d0c62a06a813breed DeviceCM(SkBaseDevice* device, int x, int y, const SkPaint* paint, SkCanvas* canvas, 117d954498c01ccf0417feacf89e45d0c62a06a813breed bool conservativeRasterClip) 118d954498c01ccf0417feacf89e45d0c62a06a813breed : fNext(NULL) 119d954498c01ccf0417feacf89e45d0c62a06a813breed , fClip(conservativeRasterClip) 120d954498c01ccf0417feacf89e45d0c62a06a813breed { 121d954498c01ccf0417feacf89e45d0c62a06a813breed if (NULL != device) { 1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device->ref(); 12340a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com device->onAttachToCanvas(canvas); 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1254b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com fDevice = device; 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint = paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL; 12788edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12988edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com ~DeviceCM() { 13049f085dddff10473b6ebf832a974288300224e60bsalomon if (fDevice) { 13140a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com fDevice->onDetachFromCanvas(); 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDevice->unref(); 1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13488edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com SkDELETE(fPaint); 13588edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 1364b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 137045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com void updateMC(const SkMatrix& totalMatrix, const SkRasterClip& totalClip, 138045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com const SkClipStack& clipStack, SkRasterClip* updateClip) { 1396f8f292aa768869a9e85c314b124875f57504f2creed@google.com int x = fDevice->getOrigin().x(); 1406f8f292aa768869a9e85c314b124875f57504f2creed@google.com int y = fDevice->getOrigin().y(); 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int width = fDevice->width(); 1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int height = fDevice->height(); 1434b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if ((x | y) == 0) { 1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = &totalMatrix; 1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fClip = totalClip; 1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrixStorage = totalMatrix; 1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrixStorage.postTranslate(SkIntToScalar(-x), 1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIntToScalar(-y)); 1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = &fMatrixStorage; 1524b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com totalClip.translate(-x, -y, &fClip); 1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 156045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com fClip.op(SkIRect::MakeWH(width, height), SkRegion::kIntersect_Op); 1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // intersect clip, but don't translate it (yet) 1594b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (updateClip) { 161045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com updateClip->op(SkIRect::MakeXYWH(x, y, width, height), 1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRegion::kDifference_Op); 1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1644b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 1653fffb2ee9fa01ae61efb2395973eb7575eda4c96robertphillips@google.com fDevice->setMatrixClip(*fMatrix, fClip.forceGetBW(), clipStack); 1663fffb2ee9fa01ae61efb2395973eb7575eda4c96robertphillips@google.com 1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!fClip.isEmpty()) { 1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIRect deviceR; 1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com deviceR.set(0, 0, width, height); 1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(deviceR.contains(fClip.getBounds())); 1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 174f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 175f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 1770e354aacd84d3bede3f97cbde35a54ba62a89533bsalomon@google.com SkMatrix fMatrixStorage; 1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* This is the record we keep for each save/restore level in the stack. 1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Since a level optionally copies the matrix and/or stack, we have pointers 1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for these fields. If the value is copied for this level, the copy is 1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stored in the ...Storage field, and the pointer points to that. If the 1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value is not copied for this level, we ignore ...Storage, and just point 1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com at the corresponding value in the previous level in the stack. 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkCanvas::MCRec { 1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 1891f836ee096bb988adef4b9757b2629c7afeda36dreed SkDrawFilter* fFilter; // the current filter (or null) 190d954498c01ccf0417feacf89e45d0c62a06a813breed DeviceCM* fLayer; 1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* If there are any layers in the stack, this points to the top-most 1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com one that is at or below this level in the stack (so we know what 1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bitmap/device to draw into from this level. This value is NOT 1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com reference counted, since the real owner is either our fLayer field, 1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com or a previous one in a lower level.) 1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 1972ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed DeviceCM* fTopLayer; 1982ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkRasterClip fRasterClip; 1992ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkMatrix fMatrix; 2002ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed int fDeferredSaveCount; 2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 202d954498c01ccf0417feacf89e45d0c62a06a813breed MCRec(bool conservativeRasterClip) : fRasterClip(conservativeRasterClip) { 203d954498c01ccf0417feacf89e45d0c62a06a813breed fFilter = NULL; 204d954498c01ccf0417feacf89e45d0c62a06a813breed fLayer = NULL; 205d954498c01ccf0417feacf89e45d0c62a06a813breed fTopLayer = NULL; 2062ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fMatrix.reset(); 2072ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fDeferredSaveCount = 0; 208b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 209d954498c01ccf0417feacf89e45d0c62a06a813breed // don't bother initializing fNext 210d954498c01ccf0417feacf89e45d0c62a06a813breed inc_rec(); 211d954498c01ccf0417feacf89e45d0c62a06a813breed } 2122ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed MCRec(const MCRec& prev) : fRasterClip(prev.fRasterClip), fMatrix(prev.fMatrix) { 213d954498c01ccf0417feacf89e45d0c62a06a813breed fFilter = SkSafeRef(prev.fFilter); 2148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLayer = NULL; 215d954498c01ccf0417feacf89e45d0c62a06a813breed fTopLayer = prev.fTopLayer; 2162ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fDeferredSaveCount = 0; 217b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // don't bother initializing fNext 2198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inc_rec(); 2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ~MCRec() { 22282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fFilter); 2238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDELETE(fLayer); 2248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dec_rec(); 2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkDrawIter : public SkDraw { 2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 2308a0b0291ae4260ef2a46f4341c18a702c0ce3f8btomhudson@google.com SkDrawIter(SkCanvas* canvas, bool skipEmptyClips = true) { 2314370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com canvas = canvas->canvasForDrawIter(); 2328a0b0291ae4260ef2a46f4341c18a702c0ce3f8btomhudson@google.com fCanvas = canvas; 2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com canvas->updateDeviceCMCache(); 2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23590c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com fClipStack = &canvas->fClipStack; 2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = canvas->fMCRec->fTopLayer; 2378a0b0291ae4260ef2a46f4341c18a702c0ce3f8btomhudson@google.com fSkipEmptyClips = skipEmptyClips; 2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2394b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool next() { 2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // skip over recs with empty clips 2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fSkipEmptyClips) { 2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (fCurrLayer && fCurrLayer->fClip.isEmpty()) { 2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = fCurrLayer->fNext; 2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 248f68c5e2f9f05b3af2bae0979ace2684b6041b6e3reed@google.com const DeviceCM* rec = fCurrLayer; 249f68c5e2f9f05b3af2bae0979ace2684b6041b6e3reed@google.com if (rec && rec->fDevice) { 2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = rec->fMatrix; 252045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com fClip = &((SkRasterClip*)&rec->fClip)->forceGetBW(); 253045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com fRC = &rec->fClip; 2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDevice = rec->fDevice; 2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBitmap = &fDevice->accessBitmap(true); 2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint = rec->fPaint; 257f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com SkDEBUGCODE(this->validate();) 2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = rec->fNext; 2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // fCurrLayer may be NULL now 261199f108f14a5f60a9c2205ffa79b26102a206ad0reed@android.com 2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2664b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2671f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* getDevice() const { return fDevice; } 2686f8f292aa768869a9e85c314b124875f57504f2creed@google.com int getX() const { return fDevice->getOrigin().x(); } 2696f8f292aa768869a9e85c314b124875f57504f2creed@google.com int getY() const { return fDevice->getOrigin().y(); } 2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& getMatrix() const { return *fMatrix; } 2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkRegion& getClip() const { return *fClip; } 2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* getPaint() const { return fPaint; } 2736f8f292aa768869a9e85c314b124875f57504f2creed@google.com 2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkCanvas* fCanvas; 2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const DeviceCM* fCurrLayer; 2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* fPaint; // May be null. 2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkBool8 fSkipEmptyClips; 2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef SkDraw INHERITED; 2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////// 2848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass AutoDrawLooper { 2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 2874a8126e7f81384526629b1e21bf89b632ea13cd9reed AutoDrawLooper(SkCanvas* canvas, const SkSurfaceProps& props, const SkPaint& paint, 28878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bool skipLayerForImageFilter = false, 28978cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL) : fOrigPaint(paint) { 2904e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fCanvas = canvas; 2918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFilter = canvas->getDrawFilter(); 2924a8126e7f81384526629b1e21bf89b632ea13cd9reed fPaint = &fOrigPaint; 2934e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fSaveCount = canvas->getSaveCount(); 2948926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com fDoClearImageFilter = false; 2954e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fDone = false; 2968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2978926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com if (!skipLayerForImageFilter && fOrigPaint.getImageFilter()) { 2988926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkPaint tmp; 2998926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com tmp.setImageFilter(fOrigPaint.getImageFilter()); 300e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org (void)canvas->internalSaveLayer(bounds, &tmp, SkCanvas::kARGB_ClipLayer_SaveFlag, 301e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org true, SkCanvas::kFullLayer_SaveLayerStrategy); 3028926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com // we'll clear the imageFilter for the actual draws in next(), so 3038926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com // it will only be applied during the restore(). 3048926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com fDoClearImageFilter = true; 3058926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 3068926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 30779fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (SkDrawLooper* looper = paint.getLooper()) { 30879fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org void* buffer = fLooperContextAllocator.reserveT<SkDrawLooper::Context>( 30979fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org looper->contextSize()); 31079fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org fLooperContext = looper->createContext(canvas, buffer); 311129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fIsSimple = false; 312129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else { 31379fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org fLooperContext = NULL; 314129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // can we be marked as simple? 315129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fIsSimple = !fFilter && !fDoClearImageFilter; 3168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 317b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 3184a8126e7f81384526629b1e21bf89b632ea13cd9reed uint32_t oldFlags = paint.getFlags(); 3194a8126e7f81384526629b1e21bf89b632ea13cd9reed fNewPaintFlags = filter_paint_flags(props, oldFlags); 3204a8126e7f81384526629b1e21bf89b632ea13cd9reed if (fIsSimple && (fNewPaintFlags != oldFlags)) { 3214a8126e7f81384526629b1e21bf89b632ea13cd9reed SkPaint* paint = fLazyPaint.set(fOrigPaint); 3224a8126e7f81384526629b1e21bf89b632ea13cd9reed paint->setFlags(fNewPaintFlags); 3234a8126e7f81384526629b1e21bf89b632ea13cd9reed fPaint = paint; 3244a8126e7f81384526629b1e21bf89b632ea13cd9reed // if we're not simple, doNext() will take care of calling setFlags() 3254a8126e7f81384526629b1e21bf89b632ea13cd9reed } 3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 32774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 3284e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com ~AutoDrawLooper() { 3298926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com if (fDoClearImageFilter) { 3308926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com fCanvas->internalRestore(); 3318926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 3324e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkASSERT(fCanvas->getSaveCount() == fSaveCount); 3338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 33474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 3354e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com const SkPaint& paint() const { 3364e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkASSERT(fPaint); 3374e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return *fPaint; 3384e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 33974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 340129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool next(SkDrawFilter::Type drawType) { 341129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com if (fDone) { 342129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return false; 343129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else if (fIsSimple) { 344129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fDone = true; 345129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return !fPaint->nothingToDraw(); 346129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else { 347129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return this->doNext(drawType); 348129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 349fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 35074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 3518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 3522c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkLazyPaint fLazyPaint; 3532c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkCanvas* fCanvas; 3542c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint& fOrigPaint; 3552c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkDrawFilter* fFilter; 3562c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint* fPaint; 3572c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org int fSaveCount; 3584a8126e7f81384526629b1e21bf89b632ea13cd9reed uint32_t fNewPaintFlags; 3598926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com bool fDoClearImageFilter; 3602c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org bool fDone; 361129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool fIsSimple; 36279fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkDrawLooper::Context* fLooperContext; 36379fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkSmallAllocator<1, 32> fLooperContextAllocator; 364129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com 365129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool doNext(SkDrawFilter::Type drawType); 3668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 368129ec22cb054592261e001294c430c9dd4e90ff4reed@google.combool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) { 369632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com fPaint = NULL; 370129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com SkASSERT(!fIsSimple); 37179fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkASSERT(fLooperContext || fFilter || fDoClearImageFilter); 372632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com 373129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com SkPaint* paint = fLazyPaint.set(fOrigPaint); 3744a8126e7f81384526629b1e21bf89b632ea13cd9reed paint->setFlags(fNewPaintFlags); 3758926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 376129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com if (fDoClearImageFilter) { 377129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com paint->setImageFilter(NULL); 378129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 3798926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 38079fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (fLooperContext && !fLooperContext->next(fCanvas, paint)) { 381129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fDone = true; 382129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return false; 383129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 384129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com if (fFilter) { 385971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com if (!fFilter->filter(paint, drawType)) { 386971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com fDone = true; 387971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com return false; 388971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com } 38979fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (NULL == fLooperContext) { 390129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // no looper means we only draw once 391632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com fDone = true; 392632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com } 393129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 394129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fPaint = paint; 3958926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 396129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // if we only came in here for the imagefilter, mark us as done 39779fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (!fLooperContext && !fFilter) { 3984e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fDone = true; 3994e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 4004e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com 401632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com // call this after any possible paint modifiers 402632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com if (fPaint->nothingToDraw()) { 4034e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fPaint = NULL; 4044e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return false; 4054e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 4064e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return true; 4074e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com} 4084e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com 4098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////// macros to place around the internal draw calls ////////////////// 4108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4118926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com#define LOOPER_BEGIN_DRAWDEVICE(paint, type) \ 41297af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com this->predrawNotify(); \ 4134a8126e7f81384526629b1e21bf89b632ea13cd9reed AutoDrawLooper looper(this, fProps, paint, true); \ 4148926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com while (looper.next(type)) { \ 4158926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkDrawIter iter(this); 4168926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 41778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org#define LOOPER_BEGIN(paint, type, bounds) \ 41897af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com this->predrawNotify(); \ 4194a8126e7f81384526629b1e21bf89b632ea13cd9reed AutoDrawLooper looper(this, fProps, paint, false, bounds); \ 4204e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com while (looper.next(type)) { \ 4218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDrawIter iter(this); 4224b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 4234e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com#define LOOPER_END } 4248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////// 4268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 427d954498c01ccf0417feacf89e45d0c62a06a813breedSkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) { 428d954498c01ccf0417feacf89e45d0c62a06a813breed fConservativeRasterClip = SkToBool(flags & kConservativeRasterClip_InitFlag); 429c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBounds.setEmpty(); 430c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 4318f0a7b8e7334187a5d7d5ab7fde5a3c3009555f5caryclark@google.com fAllowSoftClip = true; 43245a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com fAllowSimplifyClip = false; 433f92c86642a1875da54d54b447f006cb9dfbbb35creed fDeviceCMDirty = true; 4342ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount = 1; 43574bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org fMetaData = NULL; 4368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = (MCRec*)fMCStack.push_back(); 438d954498c01ccf0417feacf89e45d0c62a06a813breed new (fMCRec) MCRec(fConservativeRasterClip); 4398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 440d954498c01ccf0417feacf89e45d0c62a06a813breed fMCRec->fLayer = SkNEW_ARGS(DeviceCM, (NULL, 0, 0, NULL, NULL, fConservativeRasterClip)); 4418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fTopLayer = fMCRec->fLayer; 4428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 44397af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com fSurfaceBase = NULL; 444f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 445f92c86642a1875da54d54b447f006cb9dfbbb35creed if (device) { 446b2db898573e3cdcc8234eebf51961bfc4977ebbcreed device->initForRootLayer(fProps.pixelGeometry()); 4474a8126e7f81384526629b1e21bf89b632ea13cd9reed if (device->forceConservativeRasterClip()) { 4484a8126e7f81384526629b1e21bf89b632ea13cd9reed fConservativeRasterClip = true; 4494a8126e7f81384526629b1e21bf89b632ea13cd9reed } 450f92c86642a1875da54d54b447f006cb9dfbbb35creed device->onAttachToCanvas(this); 451f92c86642a1875da54d54b447f006cb9dfbbb35creed fMCRec->fLayer->fDevice = SkRef(device); 45278e276889795454891cbba48ab11927968114953reed fMCRec->fRasterClip.setRect(device->getGlobalBounds()); 453f92c86642a1875da54d54b447f006cb9dfbbb35creed } 454f92c86642a1875da54d54b447f006cb9dfbbb35creed return device; 4558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 457cde92111d50a96b6d0f3e166fbac7c9bc6eca349reed@google.comSkCanvas::SkCanvas() 458e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 4594a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 460e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org{ 4618d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org inc_canvas(); 462ba124485687130183643994f1b4b68d629fbbebaskia.committer@gmail.com 463d954498c01ccf0417feacf89e45d0c62a06a813breed this->init(NULL, kDefault_InitFlags); 4648d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org} 4658d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org 466d954498c01ccf0417feacf89e45d0c62a06a813breedstatic SkBitmap make_nopixels(int width, int height) { 467d954498c01ccf0417feacf89e45d0c62a06a813breed SkBitmap bitmap; 468d954498c01ccf0417feacf89e45d0c62a06a813breed bitmap.setInfo(SkImageInfo::MakeUnknown(width, height)); 469d954498c01ccf0417feacf89e45d0c62a06a813breed return bitmap; 470d954498c01ccf0417feacf89e45d0c62a06a813breed} 471d954498c01ccf0417feacf89e45d0c62a06a813breed 472d954498c01ccf0417feacf89e45d0c62a06a813breedclass SkNoPixelsBitmapDevice : public SkBitmapDevice { 473d954498c01ccf0417feacf89e45d0c62a06a813breedpublic: 47478e276889795454891cbba48ab11927968114953reed SkNoPixelsBitmapDevice(const SkIRect& bounds) 47578e276889795454891cbba48ab11927968114953reed : INHERITED(make_nopixels(bounds.width(), bounds.height())) 47678e276889795454891cbba48ab11927968114953reed { 47778e276889795454891cbba48ab11927968114953reed this->setOrigin(bounds.x(), bounds.y()); 47878e276889795454891cbba48ab11927968114953reed } 479d954498c01ccf0417feacf89e45d0c62a06a813breed 480d954498c01ccf0417feacf89e45d0c62a06a813breedprivate: 481b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 482d954498c01ccf0417feacf89e45d0c62a06a813breed typedef SkBitmapDevice INHERITED; 483d954498c01ccf0417feacf89e45d0c62a06a813breed}; 484d954498c01ccf0417feacf89e45d0c62a06a813breed 485e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.orgSkCanvas::SkCanvas(int width, int height) 486e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 4874a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 488e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org{ 489e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org inc_canvas(); 490b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 49178e276889795454891cbba48ab11927968114953reed this->init(SkNEW_ARGS(SkNoPixelsBitmapDevice, 49278e276889795454891cbba48ab11927968114953reed (SkIRect::MakeWH(width, height))), kDefault_InitFlags)->unref(); 493d954498c01ccf0417feacf89e45d0c62a06a813breed} 494e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org 49578e276889795454891cbba48ab11927968114953reedSkCanvas::SkCanvas(const SkIRect& bounds, InitFlags flags) 496d954498c01ccf0417feacf89e45d0c62a06a813breed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 4974a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 498d954498c01ccf0417feacf89e45d0c62a06a813breed{ 499d954498c01ccf0417feacf89e45d0c62a06a813breed inc_canvas(); 500b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 50178e276889795454891cbba48ab11927968114953reed this->init(SkNEW_ARGS(SkNoPixelsBitmapDevice, (bounds)), flags)->unref(); 50227a5e656c3d6ef22f9cb34de18e1b960da3aa241reed} 5038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5044a8126e7f81384526629b1e21bf89b632ea13cd9reedSkCanvas::SkCanvas(SkBaseDevice* device, const SkSurfaceProps* props, InitFlags flags) 50527a5e656c3d6ef22f9cb34de18e1b960da3aa241reed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 5064a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfacePropsCopyOrDefault(props)) 50727a5e656c3d6ef22f9cb34de18e1b960da3aa241reed{ 50827a5e656c3d6ef22f9cb34de18e1b960da3aa241reed inc_canvas(); 509b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 510d954498c01ccf0417feacf89e45d0c62a06a813breed this->init(device, flags); 511d954498c01ccf0417feacf89e45d0c62a06a813breed} 5126f09709519b79a1159f3826645f1c5fbc101ee11reed 513d954498c01ccf0417feacf89e45d0c62a06a813breedSkCanvas::SkCanvas(SkBaseDevice* device) 514d954498c01ccf0417feacf89e45d0c62a06a813breed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 5154a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 516d954498c01ccf0417feacf89e45d0c62a06a813breed{ 517d954498c01ccf0417feacf89e45d0c62a06a813breed inc_canvas(); 518b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 519d954498c01ccf0417feacf89e45d0c62a06a813breed this->init(device, kDefault_InitFlags); 5208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5224a8126e7f81384526629b1e21bf89b632ea13cd9reedSkCanvas::SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props) 5233716fd067a5621bb94a6cb08d72afec8bf3acedareed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 5244a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(props) 5253716fd067a5621bb94a6cb08d72afec8bf3acedareed{ 5263716fd067a5621bb94a6cb08d72afec8bf3acedareed inc_canvas(); 527b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 5284a8126e7f81384526629b1e21bf89b632ea13cd9reed SkAutoTUnref<SkBaseDevice> device(SkNEW_ARGS(SkBitmapDevice, (bitmap))); 5294a8126e7f81384526629b1e21bf89b632ea13cd9reed this->init(device, kDefault_InitFlags); 5304a8126e7f81384526629b1e21bf89b632ea13cd9reed} 53129c857d0f3a1cb837f73406eeb6ba9771879b5e7reed 5324a8126e7f81384526629b1e21bf89b632ea13cd9reedSkCanvas::SkCanvas(const SkBitmap& bitmap) 5334a8126e7f81384526629b1e21bf89b632ea13cd9reed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 5344a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 5354a8126e7f81384526629b1e21bf89b632ea13cd9reed{ 5364a8126e7f81384526629b1e21bf89b632ea13cd9reed inc_canvas(); 537b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 5384a8126e7f81384526629b1e21bf89b632ea13cd9reed SkAutoTUnref<SkBaseDevice> device(SkNEW_ARGS(SkBitmapDevice, (bitmap))); 5394a8126e7f81384526629b1e21bf89b632ea13cd9reed this->init(device, kDefault_InitFlags); 5408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::~SkCanvas() { 5438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // free up the contents of our deque 5448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->restoreToCount(1); // restore everything but the last 5457c2029367cea5479fa3b74fb0ca2b0297b42b709reed@google.com 5468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->internalRestore(); // restore the last, since we're going away 5478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 54874bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org SkDELETE(fMetaData); 549b70ae310bbdaa1b26786773aabce5548c1f48563vandebo@chromium.org 5508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dec_canvas(); 5518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDrawFilter* SkCanvas::getDrawFilter() const { 5548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fMCRec->fFilter; 5558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDrawFilter* SkCanvas::setDrawFilter(SkDrawFilter* filter) { 5588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fMCRec->fFilter, filter); 5598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return filter; 5608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 56274bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.orgSkMetaData& SkCanvas::getMetaData() { 56374bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org // metadata users are rare, so we lazily allocate it. If that changes we 56474bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org // can decide to just make it a field in the device (rather than a ptr) 56574bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org if (NULL == fMetaData) { 56674bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org fMetaData = new SkMetaData; 56774bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org } 56874bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org return *fMetaData; 56974bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org} 57074bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org 5718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 5728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 573bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.orgvoid SkCanvas::flush() { 5741f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* device = this->getDevice(); 575bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org if (device) { 576bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org device->flush(); 577bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org } 578bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org} 579bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org 5804ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.comSkISize SkCanvas::getTopLayerSize() const { 5814ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com SkBaseDevice* d = this->getTopDevice(); 5824ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com return d ? SkISize::Make(d->width(), d->height()) : SkISize::Make(0, 0); 5834ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com} 5844ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com 5854ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.comSkIPoint SkCanvas::getTopLayerOrigin() const { 5864ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com SkBaseDevice* d = this->getTopDevice(); 5874ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com return d ? d->getOrigin() : SkIPoint::Make(0, 0); 5884ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com} 5894ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com 5904ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.comSkISize SkCanvas::getBaseLayerSize() const { 5911f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* d = this->getDevice(); 592210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com return d ? SkISize::Make(d->width(), d->height()) : SkISize::Make(0, 0); 593210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com} 594210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com 5951f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::getDevice() const { 5968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // return root device 597c029062a0312fb747fb6c2677983aba51795c580robertphillips@google.com MCRec* rec = (MCRec*) fMCStack.front(); 5988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(rec && rec->fLayer); 5998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return rec->fLayer->fDevice; 6008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6021f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::getTopDevice(bool updateMatrixClip) const { 6030b53d59a24f667350b4282f88470713902409030reed@google.com if (updateMatrixClip) { 6040b53d59a24f667350b4282f88470713902409030reed@google.com const_cast<SkCanvas*>(this)->updateDeviceCMCache(); 6050b53d59a24f667350b4282f88470713902409030reed@google.com } 6069266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com return fMCRec->fTopLayer->fDevice; 6079266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com} 6089266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com 609403f8d7a052269583175e945689824838e5e0ef4commit-bot@chromium.orgSkBaseDevice* SkCanvas::setRootDevice(SkBaseDevice* device) { 6108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // return root device 6114c09d5cd4b9e6f0be1352f62288efdedc1bc3de3reed@google.com SkDeque::F2BIter iter(fMCStack); 6124c09d5cd4b9e6f0be1352f62288efdedc1bc3de3reed@google.com MCRec* rec = (MCRec*)iter.next(); 6138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(rec && rec->fLayer); 6141f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* rootDevice = rec->fLayer->fDevice; 6158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (rootDevice == device) { 6178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return device; 6188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 6194b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 6208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (device) { 62140a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com device->onAttachToCanvas(this); 622b2db898573e3cdcc8234eebf51961bfc4977ebbcreed device->initForRootLayer(fProps.pixelGeometry()); 6238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 6248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (rootDevice) { 62540a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com rootDevice->onDetachFromCanvas(); 6268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 6278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(rec->fLayer->fDevice, device); 6298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rootDevice = device; 6308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 6324b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 6338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* Now we update our initial region to have the bounds of the new device, 6348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com and then intersect all of the clips in our stack with these bounds, 6358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com to ensure that we can't draw outside of the device's bounds (and trash 6368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memory). 6374b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 6388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com NOTE: this is only a partial-fix, since if the new device is larger than 6398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com the previous one, we don't know how to "enlarge" the clips in our stack, 6404b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com so drawing may be artificially restricted. Without keeping a history of 6418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com all calls to canvas->clipRect() and canvas->clipPath(), we can't exactly 6428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com reconstruct the correct clips, so this approximation will have to do. 6438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com The caller really needs to restore() back to the base if they want to 6448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com accurately take advantage of the new device bounds. 6458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 6468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 64742aea289cbf801997b653a906a37a7f7e948b645reed@google.com SkIRect bounds; 64842aea289cbf801997b653a906a37a7f7e948b645reed@google.com if (device) { 6498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bounds.set(0, 0, device->width(), device->height()); 65042aea289cbf801997b653a906a37a7f7e948b645reed@google.com } else { 65142aea289cbf801997b653a906a37a7f7e948b645reed@google.com bounds.setEmpty(); 6528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 65342aea289cbf801997b653a906a37a7f7e948b645reed@google.com // now jam our 1st clip to be bounds, and intersect the rest with that 6541f836ee096bb988adef4b9757b2629c7afeda36dreed rec->fRasterClip.setRect(bounds); 65542aea289cbf801997b653a906a37a7f7e948b645reed@google.com while ((rec = (MCRec*)iter.next()) != NULL) { 6561f836ee096bb988adef4b9757b2629c7afeda36dreed (void)rec->fRasterClip.op(bounds, SkRegion::kIntersect_Op); 65742aea289cbf801997b653a906a37a7f7e948b645reed@google.com } 65842aea289cbf801997b653a906a37a7f7e948b645reed@google.com 6598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return device; 6608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 662a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.orgbool SkCanvas::readPixels(SkBitmap* bitmap, int x, int y) { 663a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (kUnknown_SkColorType == bitmap->colorType() || bitmap->getTexture()) { 664a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 665a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 666a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 667a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bool weAllocated = false; 668a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (NULL == bitmap->pixelRef()) { 669848250415eddc54075f7eb8795e8db79e749c6abreed if (!bitmap->tryAllocPixels()) { 670a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 671a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 672a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org weAllocated = true; 673a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 674a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 675a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkBitmap bm(*bitmap); 676a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bm.lockPixels(); 677a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (bm.getPixels() && this->readPixels(bm.info(), bm.getPixels(), bm.rowBytes(), x, y)) { 678a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return true; 679a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 680a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 681a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (weAllocated) { 682a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bitmap->setPixelRef(NULL); 683a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 684a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 685a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org} 68651df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 687c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.combool SkCanvas::readPixels(const SkIRect& srcRect, SkBitmap* bitmap) { 688a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkIRect r = srcRect; 689a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 690a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!r.intersect(0, 0, size.width(), size.height())) { 691a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bitmap->reset(); 692ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com return false; 693ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com } 69474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 695848250415eddc54075f7eb8795e8db79e749c6abreed if (!bitmap->tryAllocN32Pixels(r.width(), r.height())) { 696a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org // bitmap will already be reset. 697a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 698a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 699a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!this->readPixels(bitmap->info(), bitmap->getPixels(), bitmap->rowBytes(), r.x(), r.y())) { 700a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bitmap->reset(); 701daba14b7d4fc96b915c45d82713b22729c0d0f37bsalomon@google.com return false; 702c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } 703a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return true; 704a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org} 705c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 70696472deea70169396b8e1f576e470138f55fdb1freedbool SkCanvas::readPixels(const SkImageInfo& dstInfo, void* dstP, size_t rowBytes, int x, int y) { 707a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkBaseDevice* device = this->getDevice(); 708a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!device) { 709a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 710a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 711a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 712f0f14113431ace669f278fdd97b50950f2cf4c80mtklein 71396472deea70169396b8e1f576e470138f55fdb1freed SkReadPixelsRec rec(dstInfo, dstP, rowBytes, x, y); 71496472deea70169396b8e1f576e470138f55fdb1freed if (!rec.trim(size.width(), size.height())) { 715a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 716a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 717db0c8753775774aa3f67114491e26ac1be32f38eskia.committer@gmail.com 718a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org // The device can assert that the requested area is always contained in its bounds 71996472deea70169396b8e1f576e470138f55fdb1freed return device->readPixels(rec.fInfo, rec.fPixels, rec.fRowBytes, rec.fX, rec.fY); 72051df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com} 72151df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 7224cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgbool SkCanvas::writePixels(const SkBitmap& bitmap, int x, int y) { 7234cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (bitmap.getTexture()) { 7244cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 7254cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7264cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org SkBitmap bm(bitmap); 7274cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org bm.lockPixels(); 7284cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (bm.getPixels()) { 7294cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return this->writePixels(bm.info(), bm.getPixels(), bm.rowBytes(), x, y); 7304cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7314cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 7324cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org} 7334cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 7344cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgbool SkCanvas::writePixels(const SkImageInfo& origInfo, const void* pixels, size_t rowBytes, 7354cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org int x, int y) { 7364cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org switch (origInfo.colorType()) { 7374cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org case kUnknown_SkColorType: 7384cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org case kIndex_8_SkColorType: 7394cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 7404cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org default: 7414cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org break; 7424cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7434cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (NULL == pixels || rowBytes < origInfo.minRowBytes()) { 7444cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 7454cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7464cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 7474cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 7484cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org SkIRect target = SkIRect::MakeXYWH(x, y, origInfo.width(), origInfo.height()); 7494cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (!target.intersect(0, 0, size.width(), size.height())) { 7504cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 7514cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7524cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 7534cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org SkBaseDevice* device = this->getDevice(); 7544cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (!device) { 7554cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 7564cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7574cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 7584cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // the intersect may have shrunk info's logical size 759e5ea500d4714a7d84de2bf913e81be3b65d2de68reed const SkImageInfo info = origInfo.makeWH(target.width(), target.height()); 7604cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 7614cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // if x or y are negative, then we have to adjust pixels 7624cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (x > 0) { 7634cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org x = 0; 7644cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7654cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (y > 0) { 7664cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org y = 0; 7674cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7684cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // here x,y are either 0 or negative 7694cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org pixels = ((const char*)pixels - y * rowBytes - x * info.bytesPerPixel()); 7704cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 7714af35f348b2e2f6c428819118eb7a2f2fff53a74reed // Tell our owning surface to bump its generation ID 7724af35f348b2e2f6c428819118eb7a2f2fff53a74reed this->predrawNotify(); 7734af35f348b2e2f6c428819118eb7a2f2fff53a74reed 7744cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // The device can assert that the requested area is always contained in its bounds 7754ef54f8d72420a521d4aae04ff5cd438810eca7fcommit-bot@chromium.org return device->writePixels(info, pixels, rowBytes, target.x(), target.y()); 7764cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org} 77751df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 7784370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comSkCanvas* SkCanvas::canvasForDrawIter() { 7794370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com return this; 7804370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 7814370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 7828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 7838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::updateDeviceCMCache() { 7858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fDeviceCMDirty) { 7868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& totalMatrix = this->getTotalMatrix(); 7871f836ee096bb988adef4b9757b2629c7afeda36dreed const SkRasterClip& totalClip = fMCRec->fRasterClip; 7888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* layer = fMCRec->fTopLayer; 7894b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 7908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == layer->fNext) { // only one layer 79146799cd9f0bded51a189d77731b25af159ab4609reed@google.com layer->updateMC(totalMatrix, totalClip, fClipStack, NULL); 7928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 793045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com SkRasterClip clip(totalClip); 7948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 79546799cd9f0bded51a189d77731b25af159ab4609reed@google.com layer->updateMC(totalMatrix, clip, fClipStack, &clip); 7968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while ((layer = layer->fNext) != NULL); 7978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = false; 7998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 8038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8042ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::checkForDeferredSave() { 8052ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (fMCRec->fDeferredSaveCount > 0) { 8062ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fMCRec->fDeferredSaveCount -= 1; 8072ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->doSave(); 8082ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 8092ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed} 8102ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed 811f0090cb80ab10a49e511aa5450ae38917fa058d9reedint SkCanvas::getSaveCount() const { 8122ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed#ifdef SK_DEBUG 8132ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed int count = 0; 8142ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkDeque::Iter iter(fMCStack, SkDeque::Iter::kFront_IterStart); 8152ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed for (;;) { 8162ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed const MCRec* rec = (const MCRec*)iter.next(); 8172ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (!rec) { 8182ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed break; 8192ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 8202ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed count += 1 + rec->fDeferredSaveCount; 8212ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 8222ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(count == fSaveCount); 8232ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed#endif 8242ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return fSaveCount; 825f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 826f0090cb80ab10a49e511aa5450ae38917fa058d9reed 827f0090cb80ab10a49e511aa5450ae38917fa058d9reedint SkCanvas::save() { 8282ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount += 1; 8292ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fMCRec->fDeferredSaveCount += 1; 8302ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return this->getSaveCount() - 1; // return our prev value 8312ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed} 8322ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed 8332ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::doSave() { 834f0090cb80ab10a49e511aa5450ae38917fa058d9reed this->willSave(); 8352ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalSave(); 836f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 837f0090cb80ab10a49e511aa5450ae38917fa058d9reed 838f0090cb80ab10a49e511aa5450ae38917fa058d9reedvoid SkCanvas::restore() { 8392ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (fMCRec->fDeferredSaveCount > 0) { 8402ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(fSaveCount > 1); 8412ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount -= 1; 8422ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fMCRec->fDeferredSaveCount -= 1; 8432ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } else { 8442ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed // check for underflow 8452ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (fMCStack.count() > 1) { 8462ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->willRestore(); 8472ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(fSaveCount > 1); 8482ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount -= 1; 8492ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalRestore(); 8502ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->didRestore(); 8512ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 852f0090cb80ab10a49e511aa5450ae38917fa058d9reed } 853f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 854f0090cb80ab10a49e511aa5450ae38917fa058d9reed 855f0090cb80ab10a49e511aa5450ae38917fa058d9reedvoid SkCanvas::restoreToCount(int count) { 856f0090cb80ab10a49e511aa5450ae38917fa058d9reed // sanity check 857f0090cb80ab10a49e511aa5450ae38917fa058d9reed if (count < 1) { 858f0090cb80ab10a49e511aa5450ae38917fa058d9reed count = 1; 859f0090cb80ab10a49e511aa5450ae38917fa058d9reed } 860f0f14113431ace669f278fdd97b50950f2cf4c80mtklein 861f0090cb80ab10a49e511aa5450ae38917fa058d9reed int n = this->getSaveCount() - count; 862f0090cb80ab10a49e511aa5450ae38917fa058d9reed for (int i = 0; i < n; ++i) { 863f0090cb80ab10a49e511aa5450ae38917fa058d9reed this->restore(); 864f0090cb80ab10a49e511aa5450ae38917fa058d9reed } 865f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 866f0090cb80ab10a49e511aa5450ae38917fa058d9reed 8672ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::internalSave() { 8688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com MCRec* newTop = (MCRec*)fMCStack.push_back(); 869d954498c01ccf0417feacf89e45d0c62a06a813breed new (newTop) MCRec(*fMCRec); // balanced in restore() 8708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = newTop; 8714b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 8725f6102d07982043542343ff0a6c67b1319ac9fc7Florin Malita fClipStack.save(); 8738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic bool bounds_affects_clip(SkCanvas::SaveFlags flags) { 876b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG 8778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (flags & SkCanvas::kClipToLayer_SaveFlag) != 0; 878b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#else 879b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com return true; 880b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#endif 8818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 883a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.orgbool SkCanvas::clipRectBounds(const SkRect* bounds, SaveFlags flags, 884c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org SkIRect* intersection, const SkImageFilter* imageFilter) { 885bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect clipBounds; 886c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org SkRegion::Op op = SkRegion::kIntersect_Op; 887bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (!this->getClipDeviceBounds(&clipBounds)) { 888a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return false; 889f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 890c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org 891c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org if (imageFilter) { 8921f836ee096bb988adef4b9757b2629c7afeda36dreed imageFilter->filterBounds(clipBounds, fMCRec->fMatrix, &clipBounds); 893c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org // Filters may grow the bounds beyond the device bounds. 894c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org op = SkRegion::kReplace_Op; 895c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org } 896bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect ir; 89749f085dddff10473b6ebf832a974288300224e60bsalomon if (bounds) { 8988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 8994b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 9008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->getTotalMatrix().mapRect(&r, *bounds); 9018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.roundOut(&ir); 9028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // early exit if the layer's bounds are clipped out 9038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!ir.intersect(clipBounds)) { 904bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (bounds_affects_clip(flags)) { 9051f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fRasterClip.setEmpty(); 906bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 907a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return false; 9088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { // no user bounds, so just use the clip 9108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ir = clipBounds; 9118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 91389f077ced4918ded7e911bc5052b61c90ad57a9asenorblanco@chromium.org if (bounds_affects_clip(flags)) { 91489f077ced4918ded7e911bc5052b61c90ad57a9asenorblanco@chromium.org fClipStack.clipDevRect(ir, op); 91589f077ced4918ded7e911bc5052b61c90ad57a9asenorblanco@chromium.org // early exit if the clip is now empty 9161f836ee096bb988adef4b9757b2629c7afeda36dreed if (!fMCRec->fRasterClip.op(ir, op)) { 91789f077ced4918ded7e911bc5052b61c90ad57a9asenorblanco@chromium.org return false; 91889f077ced4918ded7e911bc5052b61c90ad57a9asenorblanco@chromium.org } 919a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org } 920a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 921a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org if (intersection) { 922a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org *intersection = ir; 923a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org } 924a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return true; 925a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org} 926a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 927d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.orgint SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint) { 928d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed if (gIgnoreSaveLayerBounds) { 929d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed bounds = NULL; 930d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed } 931d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org SaveLayerStrategy strategy = this->willSaveLayer(bounds, paint, kARGB_ClipLayer_SaveFlag); 9322ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount += 1; 9332ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalSaveLayer(bounds, paint, kARGB_ClipLayer_SaveFlag, false, strategy); 9342ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return this->getSaveCount() - 1; 935d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org} 936d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org 9372ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedint SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags) { 938d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed if (gIgnoreSaveLayerBounds) { 939d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed bounds = NULL; 940d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed } 941e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org SaveLayerStrategy strategy = this->willSaveLayer(bounds, paint, flags); 9422ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount += 1; 9432ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalSaveLayer(bounds, paint, flags, false, strategy); 9442ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return this->getSaveCount() - 1; 9458926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com} 9468926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 9472ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags, 948e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org bool justForImageFilter, SaveLayerStrategy strategy) { 949b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG 9502a5cd60bfff32c92cf44a8cfc3e8c017b9aee456commit-bot@chromium.org flags |= kClipToLayer_SaveFlag; 951b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#endif 952b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com 953a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org // do this before we create the layer. We don't call the public save() since 954a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org // that would invoke a possibly overridden virtual 9552ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalSave(); 956a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 957a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org fDeviceCMDirty = true; 958a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 959a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org SkIRect ir; 960c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org if (!this->clipRectBounds(bounds, flags, &ir, paint ? paint->getImageFilter() : NULL)) { 9612ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 9628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 964e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy really care about 965e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org // the clipRectBounds() call above? 966e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org if (kNoLayer_SaveLayerStrategy == strategy) { 9672ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 968e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org } 969e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org 970b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com // Kill the imagefilter if our device doesn't allow it 971b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com SkLazyPaint lazyP; 972b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com if (paint && paint->getImageFilter()) { 973b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com if (!this->getTopDevice()->allowImageFilter(paint->getImageFilter())) { 9748926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com if (justForImageFilter) { 9758926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com // early exit if the layer was just for the imageFilter 9762ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 9778926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 978b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com SkPaint* p = lazyP.set(*paint); 979b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com p->setImageFilter(NULL); 980b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com paint = p; 981b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com } 982b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com } 983b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com 98415a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org bool isOpaque = !SkToBool(flags & kHasAlphaLayer_SaveFlag); 98515a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org SkImageInfo info = SkImageInfo::MakeN32(ir.width(), ir.height(), 98615a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType); 9878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 988b2db898573e3cdcc8234eebf51961bfc4977ebbcreed SkBaseDevice* device = this->getTopDevice(); 989b2db898573e3cdcc8234eebf51961bfc4977ebbcreed if (NULL == device) { 990b2db898573e3cdcc8234eebf51961bfc4977ebbcreed SkDebugf("Unable to find device for layer."); 9912ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 992b2db898573e3cdcc8234eebf51961bfc4977ebbcreed } 993b2db898573e3cdcc8234eebf51961bfc4977ebbcreed 994b2db898573e3cdcc8234eebf51961bfc4977ebbcreed SkBaseDevice::Usage usage = SkBaseDevice::kSaveLayer_Usage; 99576dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com if (paint && paint->getImageFilter()) { 996b2db898573e3cdcc8234eebf51961bfc4977ebbcreed usage = SkBaseDevice::kImageFilter_Usage; 99776dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } 998b2db898573e3cdcc8234eebf51961bfc4977ebbcreed device = device->onCreateCompatibleDevice(SkBaseDevice::CreateInfo(info, usage, 999b2db898573e3cdcc8234eebf51961bfc4977ebbcreed fProps.pixelGeometry())); 1000e25c68402b38ac01dc1ae196ae8a5265b773c5f2bungeman@google.com if (NULL == device) { 1001e25c68402b38ac01dc1ae196ae8a5265b773c5f2bungeman@google.com SkDebugf("Unable to create device for layer."); 10022ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 1003e25c68402b38ac01dc1ae196ae8a5265b773c5f2bungeman@google.com } 1004e97f0856a8044866b12527819d14cdfbcdfd96f2bsalomon@google.com 10056f8f292aa768869a9e85c314b124875f57504f2creed@google.com device->setOrigin(ir.fLeft, ir.fTop); 1006d954498c01ccf0417feacf89e45d0c62a06a813breed DeviceCM* layer = SkNEW_ARGS(DeviceCM, 1007d954498c01ccf0417feacf89e45d0c62a06a813breed (device, ir.fLeft, ir.fTop, paint, this, fConservativeRasterClip)); 10088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device->unref(); 10098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com layer->fNext = fMCRec->fTopLayer; 10118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fLayer = layer; 10128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fTopLayer = layer; // this field is NOT an owner of layer 10138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1015d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.orgint SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) { 1016d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org return this->saveLayerAlpha(bounds, alpha, kARGB_ClipLayer_SaveFlag); 1017d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org} 1018d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org 10198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha, 10208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SaveFlags flags) { 10218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (0xFF == alpha) { 10228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->saveLayer(bounds, NULL, flags); 10238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 10248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint tmpPaint; 10258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com tmpPaint.setAlpha(alpha); 10268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->saveLayer(bounds, &tmpPaint, flags); 10278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::internalRestore() { 10318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fMCStack.count() != 0); 10328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1034c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 10358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10365f6102d07982043542343ff0a6c67b1319ac9fc7Florin Malita fClipStack.restore(); 10376c157640c27ee2ed6f9a484d21691b7b19dfecdecommit-bot@chromium.org 103888edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com // reserve our layer (if any) 10398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* layer = fMCRec->fLayer; // may be null 10408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now detach it from fMCRec so we can pop(). Gets freed after its drawn 10418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fLayer = NULL; 10428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now do the normal restore() 10448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->~MCRec(); // balanced in save() 10458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCStack.pop_back(); 10468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = (MCRec*)fMCStack.back(); 10478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* Time to draw the layer's offscreen. We can't call the public drawSprite, 10498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com since if we're being recorded, we don't want to record this (the 10508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com recorder will have already recorded the restore). 10518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 105249f085dddff10473b6ebf832a974288300224e60bsalomon if (layer) { 10538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (layer->fNext) { 10546f8f292aa768869a9e85c314b124875f57504f2creed@google.com const SkIPoint& origin = layer->fDevice->getOrigin(); 10558926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(), 10568926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com layer->fPaint); 10578926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com // reset this, since internalDrawDevice will have set it to true 10588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 10598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDELETE(layer); 106188edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 10628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10644a8126e7f81384526629b1e21bf89b632ea13cd9reedSkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* props) { 10654a8126e7f81384526629b1e21bf89b632ea13cd9reed if (NULL == props) { 10664a8126e7f81384526629b1e21bf89b632ea13cd9reed props = &fProps; 10674a8126e7f81384526629b1e21bf89b632ea13cd9reed } 10684a8126e7f81384526629b1e21bf89b632ea13cd9reed return this->onNewSurface(info, *props); 106976f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com} 107076f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com 10714a8126e7f81384526629b1e21bf89b632ea13cd9reedSkSurface* SkCanvas::onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props) { 107276f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com SkBaseDevice* dev = this->getDevice(); 10734a8126e7f81384526629b1e21bf89b632ea13cd9reed return dev ? dev->newSurface(info, props) : NULL; 107476f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com} 107576f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com 1076c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgSkImageInfo SkCanvas::imageInfo() const { 1077c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkBaseDevice* dev = this->getDevice(); 1078c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (dev) { 1079c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return dev->imageInfo(); 1080c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } else { 1081900ecf2f1579d42c9d2959831787af0346320f86reed@google.com return SkImageInfo::MakeUnknown(0, 0); 1082c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1083c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1084c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1085c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgconst void* SkCanvas::peekPixels(SkImageInfo* info, size_t* rowBytes) { 1086c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return this->onPeekPixels(info, rowBytes); 1087c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1088c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1089c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgconst void* SkCanvas::onPeekPixels(SkImageInfo* info, size_t* rowBytes) { 1090c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkBaseDevice* dev = this->getDevice(); 1091c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return dev ? dev->peekPixels(info, rowBytes) : NULL; 1092c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1093c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 10946b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.orgvoid* SkCanvas::accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin) { 10956b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org void* pixels = this->onAccessTopLayerPixels(info, rowBytes); 10966b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org if (pixels && origin) { 10976b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org *origin = this->getTopDevice(false)->getOrigin(); 10986b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org } 10996b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org return pixels; 11009c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 11019c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 11029c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.comvoid* SkCanvas::onAccessTopLayerPixels(SkImageInfo* info, size_t* rowBytes) { 11039c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com SkBaseDevice* dev = this->getTopDevice(); 11049c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com return dev ? dev->accessPixels(info, rowBytes) : NULL; 11059c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 11069c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1107c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgSkAutoROCanvasPixels::SkAutoROCanvasPixels(SkCanvas* canvas) { 1108c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org fAddr = canvas->peekPixels(&fInfo, &fRowBytes); 1109c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (NULL == fAddr) { 1110c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org fInfo = canvas->imageInfo(); 1111848250415eddc54075f7eb8795e8db79e749c6abreed if (kUnknown_SkColorType == fInfo.colorType() || !fBitmap.tryAllocPixels(fInfo)) { 1112c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return; // failure, fAddr is NULL 1113c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1114c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (!canvas->readPixels(&fBitmap, 0, 0)) { 1115c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return; // failure, fAddr is NULL 1116c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1117c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org fAddr = fBitmap.getPixels(); 1118c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org fRowBytes = fBitmap.rowBytes(); 1119c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1120c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkASSERT(fAddr); // success 1121c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1122c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1123c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgbool SkAutoROCanvasPixels::asROBitmap(SkBitmap* bitmap) const { 1124c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (fAddr) { 112500f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org return bitmap->installPixels(fInfo, const_cast<void*>(fAddr), fRowBytes); 1126c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } else { 1127c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org bitmap->reset(); 1128c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return false; 1129c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1130c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1131c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1132520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org///////////////////////////////////////////////////////////////////////////// 11339bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.comvoid SkCanvas::internalDrawBitmap(const SkBitmap& bitmap, 11348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& matrix, const SkPaint* paint) { 113550b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org if (bitmap.drawsNothing()) { 11368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 11378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11392c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkLazyPaint lazy; 11408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == paint) { 11412c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org paint = lazy.init(); 11428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11439bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com 11449bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com SkDEBUGCODE(bitmap.validate();) 11459bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com 114678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 114778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 114878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (paint && paint->canComputeFastBounds()) { 114978cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bitmap.getBounds(&storage); 115078cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org matrix.mapRect(&storage); 115178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint->computeFastBounds(storage, &storage); 115278cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org } 115378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org 115478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) 11559bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com 11569bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com while (iter.next()) { 11579bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com iter.fDevice->drawBitmap(iter, bitmap, matrix, looper.paint()); 11589bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com } 11599bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com 11609bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com LOOPER_END 11618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 11628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11631f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comvoid SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, 11648926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com const SkPaint* paint) { 11658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint tmp; 11668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == paint) { 11678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint = &tmp; 11688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11694b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 11708926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com LOOPER_BEGIN_DRAWDEVICE(*paint, SkDrawFilter::kBitmap_Type) 11718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 11721f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* dstDev = iter.fDevice; 117376dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com paint = &looper.paint(); 117476dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkImageFilter* filter = paint->getImageFilter(); 117576dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkIPoint pos = { x - iter.getX(), y - iter.getY() }; 11768926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com if (filter && !dstDev->canHandleImageFilter(filter)) { 11772d97bc139a7de5813468bd3dbfd0037351ae5606fmalita SkDeviceImageFilterProxy proxy(dstDev, fProps); 117876dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkBitmap dst; 11796776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org SkIPoint offset = SkIPoint::Make(0, 0); 1180b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com const SkBitmap& src = srcDev->accessBitmap(false); 1181fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org SkMatrix matrix = *iter.fMatrix; 1182d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org matrix.postTranslate(SkIntToScalar(-pos.x()), SkIntToScalar(-pos.y())); 11834cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org SkIRect clipBounds = SkIRect::MakeWH(srcDev->width(), srcDev->height()); 1184be129b26f13d575fd6b396c6ae759838ecc9bd1asenorblanco SkAutoTUnref<SkImageFilter::Cache> cache(dstDev->getImageFilterCache()); 118555b6d8be997a447ef9ce0f029697677a940bfc24senorblanco SkImageFilter::Context ctx(matrix, clipBounds, cache.get()); 11864cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org if (filter->filterImage(&proxy, src, ctx, &dst, &offset)) { 11875efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com SkPaint tmpUnfiltered(*paint); 11885efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com tmpUnfiltered.setImageFilter(NULL); 11896776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org dstDev->drawSprite(iter, dst, pos.x() + offset.x(), pos.y() + offset.y(), 11906776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org tmpUnfiltered); 119176dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } 119276dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } else { 1193b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com dstDev->drawDevice(iter, srcDev, pos.x(), pos.y(), *paint); 119476dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } 11958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11964e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 11978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 11988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11998926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.comvoid SkCanvas::drawSprite(const SkBitmap& bitmap, int x, int y, 12008926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com const SkPaint* paint) { 12010acf1b4b3645772d220c720313821bac389751b5reed if (gTreatSpriteAsBitmap) { 12020acf1b4b3645772d220c720313821bac389751b5reed this->save(); 12030acf1b4b3645772d220c720313821bac389751b5reed this->resetMatrix(); 12040acf1b4b3645772d220c720313821bac389751b5reed this->drawBitmap(bitmap, SkIntToScalar(x), SkIntToScalar(y), paint); 12050acf1b4b3645772d220c720313821bac389751b5reed this->restore(); 12060acf1b4b3645772d220c720313821bac389751b5reed return; 12070acf1b4b3645772d220c720313821bac389751b5reed } 12080acf1b4b3645772d220c720313821bac389751b5reed 12099881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawSprite()"); 121050b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org if (bitmap.drawsNothing()) { 12118926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com return; 12128926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 121350b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org SkDEBUGCODE(bitmap.validate();) 1214fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 12158926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkPaint tmp; 12168926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com if (NULL == paint) { 12178926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com paint = &tmp; 12188926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 1219fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 12208926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com LOOPER_BEGIN_DRAWDEVICE(*paint, SkDrawFilter::kBitmap_Type) 1221fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 12228926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com while (iter.next()) { 12238926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com paint = &looper.paint(); 12248926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkImageFilter* filter = paint->getImageFilter(); 12258926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkIPoint pos = { x - iter.getX(), y - iter.getY() }; 12268926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com if (filter && !iter.fDevice->canHandleImageFilter(filter)) { 12272d97bc139a7de5813468bd3dbfd0037351ae5606fmalita SkDeviceImageFilterProxy proxy(iter.fDevice, fProps); 12288926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkBitmap dst; 12296776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org SkIPoint offset = SkIPoint::Make(0, 0); 1230fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org SkMatrix matrix = *iter.fMatrix; 1231d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org matrix.postTranslate(SkIntToScalar(-pos.x()), SkIntToScalar(-pos.y())); 1232f622a6c8fd176acf9944de8df00d7f0bb56b67d3halcanary const SkIRect clipBounds = bitmap.bounds(); 1233be129b26f13d575fd6b396c6ae759838ecc9bd1asenorblanco SkAutoTUnref<SkImageFilter::Cache> cache(iter.fDevice->getImageFilterCache()); 123455b6d8be997a447ef9ce0f029697677a940bfc24senorblanco SkImageFilter::Context ctx(matrix, clipBounds, cache.get()); 12354cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org if (filter->filterImage(&proxy, bitmap, ctx, &dst, &offset)) { 12365efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com SkPaint tmpUnfiltered(*paint); 12375efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com tmpUnfiltered.setImageFilter(NULL); 12386776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org iter.fDevice->drawSprite(iter, dst, pos.x() + offset.x(), pos.y() + offset.y(), 12395efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com tmpUnfiltered); 12408926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 12418926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } else { 12428926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com iter.fDevice->drawSprite(iter, bitmap, pos.x(), pos.y(), *paint); 12438926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 12448926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 12458926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com LOOPER_END 12468926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com} 12478926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 12488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////// 124992362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::translate(SkScalar dx, SkScalar dy) { 1250d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1251d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setTranslate(dx, dy); 1252d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 12538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 125592362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::scale(SkScalar sx, SkScalar sy) { 1256d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1257d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setScale(sx, sy); 1258d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 12598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 126192362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::rotate(SkScalar degrees) { 1262d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1263d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setRotate(degrees); 1264d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 12658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 126792362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::skew(SkScalar sx, SkScalar sy) { 1268d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1269d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setSkew(sx, sy); 1270d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 127144c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org} 127244c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 127392362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::concat(const SkMatrix& matrix) { 1274d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org if (matrix.isIdentity()) { 1275d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org return; 1276d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org } 1277d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org 12782ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 12798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1280c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 12811f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix.preConcat(matrix); 128244c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 128344c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org this->didConcat(matrix); 128444c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org} 128544c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 12868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::setMatrix(const SkMatrix& matrix) { 12872ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 12888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1289c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 12901f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix = matrix; 129144c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org this->didSetMatrix(matrix); 12928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::resetMatrix() { 12958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 12964b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 12978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.reset(); 12988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->setMatrix(matrix); 12998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 13028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1303759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { 13042ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 13058f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 13068f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(rect, op, edgeStyle); 13078f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 13088f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 13098f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 1310da17f758442f16747af39f8fbaed9c097048519creed@google.com#ifdef SK_ENABLE_CLIP_QUICKREJECT 1311da17f758442f16747af39f8fbaed9c097048519creed@google.com if (SkRegion::kIntersect_Op == op) { 13121f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fRasterClip.isEmpty()) { 1313da17f758442f16747af39f8fbaed9c097048519creed@google.com return false; 1314da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1315da17f758442f16747af39f8fbaed9c097048519creed@google.com 13163b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(rect)) { 1317da17f758442f16747af39f8fbaed9c097048519creed@google.com fDeviceCMDirty = true; 1318c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 1319da17f758442f16747af39f8fbaed9c097048519creed@google.com 1320da17f758442f16747af39f8fbaed9c097048519creed@google.com fClipStack.clipEmpty(); 13211f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.setEmpty(); 1322da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1323da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1324da17f758442f16747af39f8fbaed9c097048519creed@google.com#endif 1325da17f758442f16747af39f8fbaed9c097048519creed@google.com 13265c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com AutoValidateClip avc(this); 13275c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 13288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1329c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 13308f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!fAllowSoftClip) { 13318f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com edgeStyle = kHard_ClipEdgeStyle; 13328f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 13338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13341f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fMatrix.rectStaysRect()) { 1335123671901abfa595d09ca789b487c4bc7c1f7cbcrobertphillips@google.com // for these simpler matrices, we can stay a rect even after applying 133698de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // the matrix. This means we don't have to a) make a path, and b) tell 133798de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // the region code to scan-convert the path, only to discover that it 133898de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // is really just a rect. 13398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 13408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13411f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix.mapRect(&r, rect); 13428f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com fClipStack.clipDevRect(r, op, kSoft_ClipEdgeStyle == edgeStyle); 1343d954498c01ccf0417feacf89e45d0c62a06a813breed fMCRec->fRasterClip.op(r, this->getBaseLayerSize(), op, kSoft_ClipEdgeStyle == edgeStyle); 13448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 1345123671901abfa595d09ca789b487c4bc7c1f7cbcrobertphillips@google.com // since we're rotated or some such thing, we convert the rect to a path 134698de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // and clip against that, since it can handle any matrix. However, to 134798de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // avoid recursion in the case where we are subclassed (e.g. Pictures) 134898de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // we explicitly call "our" version of clipPath. 13498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath path; 13508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.addRect(rect); 13528f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->SkCanvas::onClipPath(path, op, edgeStyle); 13538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 135673e714eb766617ce06757829a3c0b345c7963faareedstatic void rasterclip_path(SkRasterClip* rc, const SkCanvas* canvas, const SkPath& devPath, 135773e714eb766617ce06757829a3c0b345c7963faareed SkRegion::Op op, bool doAA) { 1358d64c9487135094c83f658319f53ea2005ecc08b2reed rc->op(devPath, canvas->getBaseLayerSize(), op, doAA); 1359819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com} 1360819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 1361759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) { 13622ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 13638f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 13644ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (rrect.isRect()) { 13658f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(rrect.getBounds(), op, edgeStyle); 13668f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } else { 13678f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRRect(rrect, op, edgeStyle); 13684ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 13698f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 137014e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 13718f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 137214e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org SkRRect transformedRRect; 13731f836ee096bb988adef4b9757b2629c7afeda36dreed if (rrect.transform(fMCRec->fMatrix, &transformedRRect)) { 137414e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org AutoValidateClip avc(this); 137514e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 137614e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org fDeviceCMDirty = true; 137714e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org fCachedLocalClipBoundsDirty = true; 13788f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!fAllowSoftClip) { 13798f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com edgeStyle = kHard_ClipEdgeStyle; 13808f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 138114e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 13828f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com fClipStack.clipDevRRect(transformedRRect, op, kSoft_ClipEdgeStyle == edgeStyle); 138314e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 138414e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org SkPath devPath; 138514e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org devPath.addRRect(transformedRRect); 138614e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 138773e714eb766617ce06757829a3c0b345c7963faareed rasterclip_path(&fMCRec->fRasterClip, this, devPath, op, kSoft_ClipEdgeStyle == edgeStyle); 13888f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com return; 138914e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org } 139014e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 139114e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org SkPath path; 139214e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org path.addRRect(rrect); 139314e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org // call the non-virtual version 13948f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->SkCanvas::onClipPath(path, op, edgeStyle); 13954ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 13964ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 1397759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { 13982ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 13998f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 14008f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com SkRect r; 14018f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!path.isInverseFillType() && path.isRect(&r)) { 14028f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(r, op, edgeStyle); 14038f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } else { 14048f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipPath(path, op, edgeStyle); 14058f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 14068f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 14078f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 14088f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 1409da17f758442f16747af39f8fbaed9c097048519creed@google.com#ifdef SK_ENABLE_CLIP_QUICKREJECT 1410da17f758442f16747af39f8fbaed9c097048519creed@google.com if (SkRegion::kIntersect_Op == op && !path.isInverseFillType()) { 14111f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fRasterClip.isEmpty()) { 1412da17f758442f16747af39f8fbaed9c097048519creed@google.com return false; 1413da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1414fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 14153b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(path.getBounds())) { 1416da17f758442f16747af39f8fbaed9c097048519creed@google.com fDeviceCMDirty = true; 1417c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 1418fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1419da17f758442f16747af39f8fbaed9c097048519creed@google.com fClipStack.clipEmpty(); 14201f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.setEmpty(); 1421da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1422da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1423da17f758442f16747af39f8fbaed9c097048519creed@google.com#endif 1424da17f758442f16747af39f8fbaed9c097048519creed@google.com 14255c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com AutoValidateClip avc(this); 14265c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 14278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1428c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 14298f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!fAllowSoftClip) { 14308f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com edgeStyle = kHard_ClipEdgeStyle; 14318f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 14328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath devPath; 14341f836ee096bb988adef4b9757b2629c7afeda36dreed path.transform(fMCRec->fMatrix, &devPath); 14358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1436fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // Check if the transfomation, or the original path itself 1437fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // made us empty. Note this can also happen if we contained NaN 1438fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // values. computing the bounds detects this, and will set our 1439fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // bounds to empty if that is the case. (see SkRect::set(pts, count)) 1440fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com if (devPath.getBounds().isEmpty()) { 1441fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // resetting the path will remove any NaN or other wanky values 1442fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // that might upset our scan converter. 1443fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com devPath.reset(); 1444fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com } 1445fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com 14465c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // if we called path.swap() we could avoid a deep copy of this path 14478f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com fClipStack.clipDevPath(devPath, op, kSoft_ClipEdgeStyle == edgeStyle); 14485c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 144945a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com if (fAllowSimplifyClip) { 145045a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com devPath.reset(); 145145a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com devPath.setFillType(SkPath::kInverseEvenOdd_FillType); 145245a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com const SkClipStack* clipStack = getClipStack(); 145345a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com SkClipStack::Iter iter(*clipStack, SkClipStack::Iter::kBottom_IterStart); 145445a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com const SkClipStack::Element* element; 145545a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com while ((element = iter.next())) { 145645a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com SkClipStack::Element::Type type = element->getType(); 145745a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com SkPath operand; 14582a67e123a3e559774a16a58cbe5106bc0fb86740commit-bot@chromium.org if (type != SkClipStack::Element::kEmpty_Type) { 14592a67e123a3e559774a16a58cbe5106bc0fb86740commit-bot@chromium.org element->asPath(&operand); 14602a67e123a3e559774a16a58cbe5106bc0fb86740commit-bot@chromium.org } 146145a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com SkRegion::Op elementOp = element->getOp(); 146245a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com if (elementOp == SkRegion::kReplace_Op) { 146345a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com devPath = operand; 146445a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com } else { 146545a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com Op(devPath, operand, (SkPathOp) elementOp, &devPath); 146645a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com } 146796fd3440fa489f74f903f30487282af99deb2a4dcaryclark@google.com // if the prev and curr clips disagree about aa -vs- not, favor the aa request. 146896fd3440fa489f74f903f30487282af99deb2a4dcaryclark@google.com // perhaps we need an API change to avoid this sort of mixed-signals about 146996fd3440fa489f74f903f30487282af99deb2a4dcaryclark@google.com // clipping. 14708f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (element->isAA()) { 14718f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com edgeStyle = kSoft_ClipEdgeStyle; 14728f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 147345a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com } 147445a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com op = SkRegion::kReplace_Op; 147545a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com } 147645a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com 147773e714eb766617ce06757829a3c0b345c7963faareed rasterclip_path(&fMCRec->fRasterClip, this, devPath, op, edgeStyle); 14788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1480759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipRegion(const SkRegion& rgn, SkRegion::Op op) { 14812ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 14828f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRegion(rgn, op); 14838f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 14848f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 14858f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipRegion(const SkRegion& rgn, SkRegion::Op op) { 14865c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com AutoValidateClip avc(this); 14875c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 14888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1489c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 14908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14915c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // todo: signal fClipStack that we have a region, and therefore (I guess) 14925c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // we have to ignore it, and use the region directly? 1493115d931d2fbd3a109a21b28c8a9c5099e6c49c54reed@google.com fClipStack.clipDevRect(rgn.getBounds(), op); 14945c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 14951f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fRasterClip.op(rgn, op); 14968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1498819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com#ifdef SK_DEBUG 1499819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.comvoid SkCanvas::validateClip() const { 1500819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com // construct clipRgn from the clipstack 15011f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com const SkBaseDevice* device = this->getDevice(); 1502ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com if (!device) { 15035c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org SkASSERT(this->isClipEmpty()); 1504ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com return; 1505ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com } 1506ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com 1507819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com SkIRect ir; 1508819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com ir.set(0, 0, device->width(), device->height()); 1509d954498c01ccf0417feacf89e45d0c62a06a813breed SkRasterClip tmpClip(ir, fConservativeRasterClip); 1510819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 151180214e26c57c5fea954006400852e8999e201923robertphillips@google.com SkClipStack::B2TIter iter(fClipStack); 15128182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const SkClipStack::Element* element; 15138182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com while ((element = iter.next()) != NULL) { 15148182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com switch (element->getType()) { 15158182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kRect_Type: 15168182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com element->getRect().round(&ir); 15178182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com tmpClip.op(ir, element->getOp()); 15188182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 15198182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kEmpty_Type: 15208182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com tmpClip.setEmpty(); 15218182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 15229cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org default: { 15239cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org SkPath path; 15249cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org element->asPath(&path); 152573e714eb766617ce06757829a3c0b345c7963faareed rasterclip_path(&tmpClip, this, path, element->getOp(), element->isAA()); 15269cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org break; 15279cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org } 1528819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com } 1529819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com } 1530819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com} 1531819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com#endif 1532819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 153390c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.comvoid SkCanvas::replayClips(ClipVisitor* visitor) const { 153480214e26c57c5fea954006400852e8999e201923robertphillips@google.com SkClipStack::B2TIter iter(fClipStack); 15358182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const SkClipStack::Element* element; 15368182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com 15378182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com while ((element = iter.next()) != NULL) { 1538c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita element->replay(visitor); 153990c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com } 154090c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com} 154190c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com 15425c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com/////////////////////////////////////////////////////////////////////////////// 15435c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 1544754de5f65b466f721d952a379194cc94de376f42reed@google.combool SkCanvas::isClipEmpty() const { 15451f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.isEmpty(); 1546754de5f65b466f721d952a379194cc94de376f42reed@google.com} 1547754de5f65b466f721d952a379194cc94de376f42reed@google.com 15485c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.orgbool SkCanvas::isClipRect() const { 15491f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.isRect(); 15505c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org} 15515c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org 15523b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::quickReject(const SkRect& rect) const { 15531607863b608b7db6c813228768ed5d72997bbc82reed@google.com if (!rect.isFinite()) 1554116b2bcd2c4c4d4670c7b7e2ea597414713c37fbwjmaclean@chromium.org return true; 1555116b2bcd2c4c4d4670c7b7e2ea597414713c37fbwjmaclean@chromium.org 15561f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fRasterClip.isEmpty()) { 15578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 15588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 15598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 15601f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fMatrix.hasPerspective()) { 1561a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com SkRect dst; 15621f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix.mapRect(&dst, rect); 1563b07a94f1cba3976596ae1a7f23d8c2043ba353f3reed return !SkIRect::Intersects(dst.roundOut(), fMCRec->fRasterClip.getBounds()); 1564a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com } else { 1565c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com const SkRect& clipR = this->getLocalClipBounds(); 1566d252db03d9650013b545ef9781fe993c07f8f314reed@android.com 1567a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com // for speed, do the most likely reject compares first 1568c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com // TODO: should we use | instead, or compare all 4 at once? 1569c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com if (rect.fTop >= clipR.fBottom || rect.fBottom <= clipR.fTop) { 1570a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com return true; 1571a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com } 1572c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com if (rect.fLeft >= clipR.fRight || rect.fRight <= clipR.fLeft) { 1573a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com return true; 1574a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com } 1575a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com return false; 15768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 15778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 15788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 15793b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::quickReject(const SkPath& path) const { 15803b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com return path.isEmpty() || this->quickReject(path.getBounds()); 15818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 15828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 15833b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::getClipBounds(SkRect* bounds) const { 1584bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect ibounds; 15858f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!this->getClipDeviceBounds(&ibounds)) { 15868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 15878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 15888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1589d9c0f0b57affec7a472879c5919acac6637d926areed@android.com SkMatrix inverse; 1590d9c0f0b57affec7a472879c5919acac6637d926areed@android.com // if we can't invert the CTM, we can't return local clip bounds 15911f836ee096bb988adef4b9757b2629c7afeda36dreed if (!fMCRec->fMatrix.invert(&inverse)) { 159272dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com if (bounds) { 159372dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com bounds->setEmpty(); 159472dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com } 1595d9c0f0b57affec7a472879c5919acac6637d926areed@android.com return false; 1596d9c0f0b57affec7a472879c5919acac6637d926areed@android.com } 1597d9c0f0b57affec7a472879c5919acac6637d926areed@android.com 159849f085dddff10473b6ebf832a974288300224e60bsalomon if (bounds) { 1599bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkRect r; 16003b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com // adjust it outwards in case we are antialiasing 16013b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com const int inset = 1; 1602fa4d5bd09f8f1a4a92b5ae0324800dd672760898reed@google.com 16038f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com r.iset(ibounds.fLeft - inset, ibounds.fTop - inset, 16048f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com ibounds.fRight + inset, ibounds.fBottom + inset); 16058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inverse.mapRect(bounds, r); 16068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 16078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 16088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1610bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.combool SkCanvas::getClipDeviceBounds(SkIRect* bounds) const { 16111f836ee096bb988adef4b9757b2629c7afeda36dreed const SkRasterClip& clip = fMCRec->fRasterClip; 1612bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (clip.isEmpty()) { 1613bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (bounds) { 1614bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com bounds->setEmpty(); 1615bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1616bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com return false; 1617bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1618bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com 161949f085dddff10473b6ebf832a974288300224e60bsalomon if (bounds) { 1620bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com *bounds = clip.getBounds(); 1621bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1622bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com return true; 1623bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com} 1624bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com 16258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkMatrix& SkCanvas::getTotalMatrix() const { 16261f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fMatrix; 16278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16295c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.orgconst SkRegion& SkCanvas::internal_private_getTotalClip() const { 16301f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.forceGetBW(); 16315c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org} 16325c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org 16339c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.comGrRenderTarget* SkCanvas::internal_private_accessTopLayerRenderTarget() { 16349c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com SkBaseDevice* dev = this->getTopDevice(); 16359c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com return dev ? dev->accessRenderTarget() : NULL; 16369c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 16379c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1638644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.orgGrContext* SkCanvas::getGrContext() { 1639644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#if SK_SUPPORT_GPU 1640644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org SkBaseDevice* device = this->getTopDevice(); 164149f085dddff10473b6ebf832a974288300224e60bsalomon if (device) { 1642644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org GrRenderTarget* renderTarget = device->accessRenderTarget(); 164349f085dddff10473b6ebf832a974288300224e60bsalomon if (renderTarget) { 1644644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org return renderTarget->getContext(); 1645644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org } 1646644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org } 1647644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#endif 1648644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org 1649644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org return NULL; 1650644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org 1651644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org} 1652e97f0856a8044866b12527819d14cdfbcdfd96f2bsalomon@google.com 1653ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.orgvoid SkCanvas::drawDRRect(const SkRRect& outer, const SkRRect& inner, 1654ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkPaint& paint) { 16559881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawDRRect()"); 1656ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (outer.isEmpty()) { 1657ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 1658ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 1659ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (inner.isEmpty()) { 1660ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->drawRRect(outer, paint); 1661ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 1662ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 1663ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 1664ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // We don't have this method (yet), but technically this is what we should 1665ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // be able to assert... 1666ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // SkASSERT(outer.contains(inner)); 1667ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // 1668ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // For now at least check for containment of bounds 1669ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org SkASSERT(outer.getBounds().contains(inner.getBounds())); 1670ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 1671ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->onDrawDRRect(outer, inner, paint); 1672ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org} 1673ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 16748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 16758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// These are the virtual drawing methods 16768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 16778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 167828361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.orgvoid SkCanvas::onDiscard() { 167949f085dddff10473b6ebf832a974288300224e60bsalomon if (fSurfaceBase) { 168028361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org fSurfaceBase->aboutToDraw(SkSurface::kDiscard_ContentChangeMode); 168128361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org } 168228361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org} 168328361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org 16848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPaint(const SkPaint& paint) { 16859881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPaint()"); 1686fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->internalDrawPaint(paint); 1687fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com} 1688fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com 1689fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.comvoid SkCanvas::internalDrawPaint(const SkPaint& paint) { 169078cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPaint_Type, NULL) 16918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 16934e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPaint(iter, looper.paint()); 16948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 16958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16964e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 16978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPoints(PointMode mode, size_t count, const SkPoint pts[], 17008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 17019881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT1("disabled-by-default-skia", "SkCanvas::drawPoints()", "count", static_cast<uint64_t>(count)); 17028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if ((long)count <= 0) { 17038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 17048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 17058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 170678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect r, storage; 170778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 1708a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com if (paint.canComputeFastBounds()) { 1709a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com // special-case 2 points (common for drawing a single line) 1710a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com if (2 == count) { 1711a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com r.set(pts[0], pts[1]); 1712a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } else { 1713a8c7f7702fb4bbedb615031bc653c5cd161a038ecommit-bot@chromium.org r.set(pts, SkToInt(count)); 1714a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } 171578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint.computeFastStrokeBounds(r, &storage); 171678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (this->quickReject(*bounds)) { 1717a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com return; 1718a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } 1719fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 1720a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com 17218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(pts != NULL); 17228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 172378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPoint_Type, bounds) 17244b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 17258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 17264e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPoints(iter, mode, count, pts, looper.paint()); 17278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 17284b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 17294e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 17308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17327ce564cccb246ec56427085872b2e1458fe74bd1bsalomon@google.comvoid SkCanvas::drawRect(const SkRect& r, const SkPaint& paint) { 17339881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRect()"); 173478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 173578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 17368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.canComputeFastBounds()) { 173778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint.computeFastBounds(r, &storage); 173878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (this->quickReject(*bounds)) { 17398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 17408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 17418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 17424b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 174378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kRect_Type, bounds) 17448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 17464e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawRect(iter, r, looper.paint()); 17478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 17488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17494e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 17508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17524ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.comvoid SkCanvas::drawOval(const SkRect& oval, const SkPaint& paint) { 17539881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawOval()"); 175478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 175578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 17564ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (paint.canComputeFastBounds()) { 175778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint.computeFastBounds(oval, &storage); 175878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (this->quickReject(*bounds)) { 17594ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com return; 17604ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 17614ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 1762306ab9d5de38f2a547fd1d69aedbe69b5c6617ccskia.committer@gmail.com 176378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, bounds) 176446d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com 176546d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com while (iter.next()) { 176646d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com iter.fDevice->drawOval(iter, oval, looper.paint()); 176746d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com } 176846d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com 176946d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com LOOPER_END 17704ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 17714ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 17724ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.comvoid SkCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) { 17739881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRRect()"); 177478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 177578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 17764ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (paint.canComputeFastBounds()) { 177778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint.computeFastBounds(rrect.getBounds(), &storage); 177878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (this->quickReject(*bounds)) { 17794ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com return; 17804ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 17814ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 17824ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 17834ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (rrect.isRect()) { 17844ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com // call the non-virtual version 17854ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->SkCanvas::drawRect(rrect.getBounds(), paint); 1786f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org return; 1787f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } else if (rrect.isOval()) { 17884ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com // call the non-virtual version 1789f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org this->SkCanvas::drawOval(rrect.getBounds(), paint); 1790f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org return; 17914ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 1792f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 179378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) 1794f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 1795f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org while (iter.next()) { 1796f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org iter.fDevice->drawRRect(iter, rrect, looper.paint()); 1797f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } 1798f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 1799f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org LOOPER_END 18004ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 18014ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 1802ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.orgvoid SkCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, 1803ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkPaint& paint) { 1804ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org SkRect storage; 1805ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkRect* bounds = NULL; 1806ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (paint.canComputeFastBounds()) { 1807ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org bounds = &paint.computeFastBounds(outer.getBounds(), &storage); 1808ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (this->quickReject(*bounds)) { 1809ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 1810ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 1811ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 181225c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 1813ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) 181425c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 1815ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org while (iter.next()) { 1816ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org iter.fDevice->drawDRRect(iter, outer, inner, looper.paint()); 1817ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 181825c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 1819ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org LOOPER_END 1820ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org} 18214ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 18227ce564cccb246ec56427085872b2e1458fe74bd1bsalomon@google.comvoid SkCanvas::drawPath(const SkPath& path, const SkPaint& paint) { 18239881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPath()"); 18249364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com if (!path.isFinite()) { 18259364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com return; 18269364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com } 18279364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com 182878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 182978cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 1830fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com if (!path.isInverseFillType() && paint.canComputeFastBounds()) { 183178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect& pathBounds = path.getBounds(); 183278cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint.computeFastBounds(pathBounds, &storage); 183378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (this->quickReject(*bounds)) { 18348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 18358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18370b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org 18380b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org const SkRect& r = path.getBounds(); 18390b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org if (r.width() <= 0 && r.height() <= 0) { 18406803c219dd3be4a73e7bb5c4bb8a5b1f803624d0commit-bot@chromium.org if (path.isInverseFillType()) { 1841fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->internalDrawPaint(paint); 1842fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 1843fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com return; 1844fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 18458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 184678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, bounds) 18478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 18494e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPath(iter, path, looper.paint()); 18508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18524e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 18538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1855b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixrvoid SkCanvas::drawImage(const SkImage* image, SkScalar left, SkScalar top, 1856b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr const SkPaint* paint) { 18579881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImage()"); 1858b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr image->draw(this, left, top, paint); 1859b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr} 1860b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 1861b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixrvoid SkCanvas::drawImageRect(const SkImage* image, const SkRect* src, 1862b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr const SkRect& dst, 1863b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr const SkPaint* paint) { 18649881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImageRect()"); 18655ceff913cfd458c653358db7f60e995f505bce84piotaixr image->drawRect(this, src, dst, paint); 1866b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr} 1867b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 18688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y, 18698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* paint) { 18709881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmap()"); 18718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(bitmap.validate();) 18728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18733d60812865bb034851da777a91413ab584929887reed@google.com if (NULL == paint || paint->canComputeFastBounds()) { 18749efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com SkRect bounds = { 18759efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com x, y, 18769efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com x + SkIntToScalar(bitmap.width()), 18779efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com y + SkIntToScalar(bitmap.height()) 18789efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com }; 18799efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com if (paint) { 18809efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com (void)paint->computeFastBounds(bounds, &bounds); 18819efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com } 18823b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(bounds)) { 18838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 18848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18864b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 18878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 18888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.setTranslate(x, y); 18899bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com this->internalDrawBitmap(bitmap, matrix, paint); 18908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18929987ec3791336bad6af5cbe513564786b2df55aareed@google.com// this one is non-virtual, so it can be called safely by other canvas apis 18937112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.comvoid SkCanvas::internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, 1894eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org const SkRect& dst, const SkPaint* paint, 1895eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org DrawBitmapRectFlags flags) { 189650b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org if (bitmap.drawsNothing() || dst.isEmpty()) { 18978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 18988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 189974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 190078cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 190178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = &dst; 19023d60812865bb034851da777a91413ab584929887reed@google.com if (NULL == paint || paint->canComputeFastBounds()) { 19039efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com if (paint) { 19049efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com bounds = &paint->computeFastBounds(dst, &storage); 19059efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com } 19063b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(*bounds)) { 19073d60812865bb034851da777a91413ab584929887reed@google.com return; 19083d60812865bb034851da777a91413ab584929887reed@google.com } 19098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 19103d60812865bb034851da777a91413ab584929887reed@google.com 191133535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com SkLazyPaint lazy; 191233535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com if (NULL == paint) { 191333535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com paint = lazy.init(); 19148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 19157064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 191678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) 19177064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 191833535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com while (iter.next()) { 1919eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org iter.fDevice->drawBitmapRect(iter, bitmap, src, dst, looper.paint(), flags); 1920f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 19217064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 192233535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com LOOPER_END 19238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 19248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19257112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.comvoid SkCanvas::drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src, 1926eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org const SkRect& dst, const SkPaint* paint, 1927eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org DrawBitmapRectFlags flags) { 19289881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmapRectToRect()"); 19299987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkDEBUGCODE(bitmap.validate();) 1930eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org this->internalDrawBitmapRect(bitmap, src, dst, paint, flags); 19319987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 19329987ec3791336bad6af5cbe513564786b2df55aareed@google.com 19339987ec3791336bad6af5cbe513564786b2df55aareed@google.comvoid SkCanvas::internalDrawBitmapNine(const SkBitmap& bitmap, 19349987ec3791336bad6af5cbe513564786b2df55aareed@google.com const SkIRect& center, const SkRect& dst, 19359987ec3791336bad6af5cbe513564786b2df55aareed@google.com const SkPaint* paint) { 193650b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org if (bitmap.drawsNothing()) { 193750b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org return; 193850b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org } 19393d60812865bb034851da777a91413ab584929887reed@google.com if (NULL == paint || paint->canComputeFastBounds()) { 194060abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com SkRect storage; 194160abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com const SkRect* bounds = &dst; 194260abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com if (paint) { 194360abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com bounds = &paint->computeFastBounds(dst, &storage); 194460abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com } 19453b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(*bounds)) { 19463d60812865bb034851da777a91413ab584929887reed@google.com return; 19473d60812865bb034851da777a91413ab584929887reed@google.com } 19483d60812865bb034851da777a91413ab584929887reed@google.com } 19493d60812865bb034851da777a91413ab584929887reed@google.com 19509987ec3791336bad6af5cbe513564786b2df55aareed@google.com const int32_t w = bitmap.width(); 19519987ec3791336bad6af5cbe513564786b2df55aareed@google.com const int32_t h = bitmap.height(); 19529987ec3791336bad6af5cbe513564786b2df55aareed@google.com 19539987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkIRect c = center; 19549987ec3791336bad6af5cbe513564786b2df55aareed@google.com // pin center to the bounds of the bitmap 19559987ec3791336bad6af5cbe513564786b2df55aareed@google.com c.fLeft = SkMax32(0, center.fLeft); 19569987ec3791336bad6af5cbe513564786b2df55aareed@google.com c.fTop = SkMax32(0, center.fTop); 19579987ec3791336bad6af5cbe513564786b2df55aareed@google.com c.fRight = SkPin32(center.fRight, c.fLeft, w); 19589987ec3791336bad6af5cbe513564786b2df55aareed@google.com c.fBottom = SkPin32(center.fBottom, c.fTop, h); 19599987ec3791336bad6af5cbe513564786b2df55aareed@google.com 19607112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com const SkScalar srcX[4] = { 19617d474f8a84a74421bd8d119124daa64ec1710f76rmistry@google.com 0, SkIntToScalar(c.fLeft), SkIntToScalar(c.fRight), SkIntToScalar(w) 19627112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com }; 19637112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com const SkScalar srcY[4] = { 19647d474f8a84a74421bd8d119124daa64ec1710f76rmistry@google.com 0, SkIntToScalar(c.fTop), SkIntToScalar(c.fBottom), SkIntToScalar(h) 19657112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com }; 19669987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkScalar dstX[4] = { 19679987ec3791336bad6af5cbe513564786b2df55aareed@google.com dst.fLeft, dst.fLeft + SkIntToScalar(c.fLeft), 19689987ec3791336bad6af5cbe513564786b2df55aareed@google.com dst.fRight - SkIntToScalar(w - c.fRight), dst.fRight 19699987ec3791336bad6af5cbe513564786b2df55aareed@google.com }; 19709987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkScalar dstY[4] = { 19719987ec3791336bad6af5cbe513564786b2df55aareed@google.com dst.fTop, dst.fTop + SkIntToScalar(c.fTop), 19729987ec3791336bad6af5cbe513564786b2df55aareed@google.com dst.fBottom - SkIntToScalar(h - c.fBottom), dst.fBottom 19739987ec3791336bad6af5cbe513564786b2df55aareed@google.com }; 197474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 19759987ec3791336bad6af5cbe513564786b2df55aareed@google.com if (dstX[1] > dstX[2]) { 19769987ec3791336bad6af5cbe513564786b2df55aareed@google.com dstX[1] = dstX[0] + (dstX[3] - dstX[0]) * c.fLeft / (w - c.width()); 19779987ec3791336bad6af5cbe513564786b2df55aareed@google.com dstX[2] = dstX[1]; 19789987ec3791336bad6af5cbe513564786b2df55aareed@google.com } 197974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 19809987ec3791336bad6af5cbe513564786b2df55aareed@google.com if (dstY[1] > dstY[2]) { 19819987ec3791336bad6af5cbe513564786b2df55aareed@google.com dstY[1] = dstY[0] + (dstY[3] - dstY[0]) * c.fTop / (h - c.height()); 19829987ec3791336bad6af5cbe513564786b2df55aareed@google.com dstY[2] = dstY[1]; 19839987ec3791336bad6af5cbe513564786b2df55aareed@google.com } 198474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 19859987ec3791336bad6af5cbe513564786b2df55aareed@google.com for (int y = 0; y < 3; y++) { 19867112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com SkRect s, d; 19877112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com 19889987ec3791336bad6af5cbe513564786b2df55aareed@google.com s.fTop = srcY[y]; 19899987ec3791336bad6af5cbe513564786b2df55aareed@google.com s.fBottom = srcY[y+1]; 19909987ec3791336bad6af5cbe513564786b2df55aareed@google.com d.fTop = dstY[y]; 19919987ec3791336bad6af5cbe513564786b2df55aareed@google.com d.fBottom = dstY[y+1]; 19929987ec3791336bad6af5cbe513564786b2df55aareed@google.com for (int x = 0; x < 3; x++) { 19939987ec3791336bad6af5cbe513564786b2df55aareed@google.com s.fLeft = srcX[x]; 19949987ec3791336bad6af5cbe513564786b2df55aareed@google.com s.fRight = srcX[x+1]; 19959987ec3791336bad6af5cbe513564786b2df55aareed@google.com d.fLeft = dstX[x]; 19969987ec3791336bad6af5cbe513564786b2df55aareed@google.com d.fRight = dstX[x+1]; 1997eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org this->internalDrawBitmapRect(bitmap, &s, d, paint, 199831acc11977815402e4ef2681350f8559285bec97robertphillips@google.com kNone_DrawBitmapRectFlag); 19999987ec3791336bad6af5cbe513564786b2df55aareed@google.com } 20009987ec3791336bad6af5cbe513564786b2df55aareed@google.com } 20019987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 20029987ec3791336bad6af5cbe513564786b2df55aareed@google.com 20039987ec3791336bad6af5cbe513564786b2df55aareed@google.comvoid SkCanvas::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, 20049987ec3791336bad6af5cbe513564786b2df55aareed@google.com const SkRect& dst, const SkPaint* paint) { 20059881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmapNine()"); 20069987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkDEBUGCODE(bitmap.validate();) 20079987ec3791336bad6af5cbe513564786b2df55aareed@google.com 20089987ec3791336bad6af5cbe513564786b2df55aareed@google.com // Need a device entry-point, so gpu can use a mesh 20099987ec3791336bad6af5cbe513564786b2df55aareed@google.com this->internalDrawBitmapNine(bitmap, center, dst, paint); 20109987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 20119987ec3791336bad6af5cbe513564786b2df55aareed@google.com 2012f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.comclass SkDeviceFilteredPaint { 2013f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.compublic: 20141f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkDeviceFilteredPaint(SkBaseDevice* device, const SkPaint& paint) { 2015112e7e277702e104357f2d44742253ee1b0109acfmalita uint32_t filteredFlags = device->filterTextFlags(paint); 2016112e7e277702e104357f2d44742253ee1b0109acfmalita if (filteredFlags != paint.getFlags()) { 2017a076e9be17654a60310e72c4f70fcd5337f56dbfreed@google.com SkPaint* newPaint = fLazy.set(paint); 2018112e7e277702e104357f2d44742253ee1b0109acfmalita newPaint->setFlags(filteredFlags); 2019f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com fPaint = newPaint; 2020f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } else { 2021f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com fPaint = &paint; 2022f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } 2023f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } 2024f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 2025f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com const SkPaint& paint() const { return *fPaint; } 2026f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 2027f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.comprivate: 20282c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint* fPaint; 20292c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkLazyPaint fLazy; 2030f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com}; 2031f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 203252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.comvoid SkCanvas::DrawRect(const SkDraw& draw, const SkPaint& paint, 203352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com const SkRect& r, SkScalar textSize) { 203417b78946096265d80215a6c946286ecaa35ea7edepoger@google.com if (paint.getStyle() == SkPaint::kFill_Style) { 203552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com draw.fDevice->drawRect(draw, r, paint); 203652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } else { 203752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPaint p(paint); 203817b78946096265d80215a6c946286ecaa35ea7edepoger@google.com p.setStrokeWidth(SkScalarMul(textSize, paint.getStrokeWidth())); 203952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com draw.fDevice->drawRect(draw, r, p); 204052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 204152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com} 204252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 204352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.comvoid SkCanvas::DrawTextDecorations(const SkDraw& draw, const SkPaint& paint, 204452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com const char text[], size_t byteLength, 204552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar x, SkScalar y) { 204652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkASSERT(byteLength == 0 || text != NULL); 204752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 204852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com // nothing to draw 204952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (text == NULL || byteLength == 0 || 205052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com draw.fClip->isEmpty() || 205152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com (paint.getAlpha() == 0 && paint.getXfermode() == NULL)) { 205252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com return; 205352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 205452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 205552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar width = 0; 205652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPoint start; 205752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 205852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.set(0, 0); // to avoid warning 205952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (paint.getFlags() & (SkPaint::kUnderlineText_Flag | 206052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPaint::kStrikeThruText_Flag)) { 206152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com width = paint.measureText(text, byteLength); 206252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 206352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar offsetX = 0; 206452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (paint.getTextAlign() == SkPaint::kCenter_Align) { 206552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com offsetX = SkScalarHalf(width); 206652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } else if (paint.getTextAlign() == SkPaint::kRight_Align) { 206752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com offsetX = width; 206852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 206952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.set(x - offsetX, y); 207052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 207152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 207252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (0 == width) { 207352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com return; 207452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 207552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 207652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com uint32_t flags = paint.getFlags(); 207752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 207852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (flags & (SkPaint::kUnderlineText_Flag | 207952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPaint::kStrikeThruText_Flag)) { 208052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar textSize = paint.getTextSize(); 208152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar height = SkScalarMul(textSize, kStdUnderline_Thickness); 208252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkRect r; 208352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 208452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fLeft = start.fX; 208552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fRight = start.fX + width; 208652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 208752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (flags & SkPaint::kUnderlineText_Flag) { 208852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar offset = SkScalarMulAdd(textSize, kStdUnderline_Offset, 208952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.fY); 209052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fTop = offset; 209152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fBottom = offset + height; 209252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com DrawRect(draw, paint, r, textSize); 209352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 209452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (flags & SkPaint::kStrikeThruText_Flag) { 209552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar offset = SkScalarMulAdd(textSize, kStdStrikeThru_Offset, 209652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.fY); 209752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fTop = offset; 209852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fBottom = offset + height; 209952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com DrawRect(draw, paint, r, textSize); 210052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 210152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 210252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com} 210352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 2104e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 2105e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 210678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL) 21078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 21094e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 2110f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com iter.fDevice->drawText(iter, text, byteLength, x, y, dfp.paint()); 211152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com DrawTextDecorations(iter, dfp.paint(), 211252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com static_cast<const char*>(text), byteLength, x, y); 21138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 21148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21154e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 21168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 21178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2118e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], 2119e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 212005c4a4322e7d4f3417b7df33825bab8603d52051fmalita SkPoint textOffset = SkPoint::Make(0, 0); 212105c4a4322e7d4f3417b7df33825bab8603d52051fmalita 212278cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL) 212387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 21248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 21254e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 212605c4a4322e7d4f3417b7df33825bab8603d52051fmalita iter.fDevice->drawPosText(iter, text, byteLength, &pos->fX, 2, textOffset, 2127f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com dfp.paint()); 21288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2129b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 21304e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 21318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 21328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2133e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], 2134e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com SkScalar constY, const SkPaint& paint) { 213505c4a4322e7d4f3417b7df33825bab8603d52051fmalita 213605c4a4322e7d4f3417b7df33825bab8603d52051fmalita SkPoint textOffset = SkPoint::Make(0, constY); 213705c4a4322e7d4f3417b7df33825bab8603d52051fmalita 213878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL) 213987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 21408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 21414e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 214205c4a4322e7d4f3417b7df33825bab8603d52051fmalita iter.fDevice->drawPosText(iter, text, byteLength, xpos, 1, textOffset, 2143f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com dfp.paint()); 21448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2145b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 21464e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 21478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 21488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2149e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 2150e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkMatrix* matrix, const SkPaint& paint) { 215178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL) 215287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 21538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 21548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawTextOnPath(iter, text, byteLength, path, 21554e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com matrix, looper.paint()); 21568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2157b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 2158945ec3a2bec668ca845071a65df8ec55e8f43819commit-bot@chromium.org LOOPER_END 21594325d114a5679e46f25ae75b0e43547fd7694998commit-bot@chromium.org} 21604325d114a5679e46f25ae75b0e43547fd7694998commit-bot@chromium.org 216100d5c2c6523321d25b32905ff4822f083a4173eefmalitavoid SkCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 216200d5c2c6523321d25b32905ff4822f083a4173eefmalita const SkPaint& paint) { 21637ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita 216419653d1d004610b4ba07ce563a5701164e120e45fmalita if (paint.canComputeFastBounds()) { 21657ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita SkRect storage; 21667ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita 21677ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita if (this->quickReject(paint.computeFastBounds(blob->bounds().makeOffset(x, y), &storage))) { 21687ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita return; 21697ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita } 21707ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita } 21717ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita 2172aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL) 217300d5c2c6523321d25b32905ff4822f083a4173eefmalita 2174aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita while (iter.next()) { 2175aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 2176aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita iter.fDevice->drawTextBlob(iter, blob, x, y, dfp.paint()); 217700d5c2c6523321d25b32905ff4822f083a4173eefmalita } 217800d5c2c6523321d25b32905ff4822f083a4173eefmalita 2179aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita LOOPER_END 218000d5c2c6523321d25b32905ff4822f083a4173eefmalita} 218100d5c2c6523321d25b32905ff4822f083a4173eefmalita 2182e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com// These will become non-virtual, so they always call the (virtual) onDraw... method 2183e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 2184e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 21859881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawText()"); 2186e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawText(text, byteLength, x, y, paint); 2187e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2188e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawPosText(const void* text, size_t byteLength, const SkPoint pos[], 2189e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 21909881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPosText()"); 2191e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawPosText(text, byteLength, pos, paint); 2192e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2193e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], 2194e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com SkScalar constY, const SkPaint& paint) { 21959881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPosTextH()"); 2196e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawPosTextH(text, byteLength, xpos, constY, paint); 2197e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2198e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 2199e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkMatrix* matrix, const SkPaint& paint) { 22009881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextOnPath()"); 2201e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawTextOnPath(text, byteLength, path, matrix, paint); 2202e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 220300d5c2c6523321d25b32905ff4822f083a4173eefmalitavoid SkCanvas::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 220400d5c2c6523321d25b32905ff4822f083a4173eefmalita const SkPaint& paint) { 22059881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextBlob()"); 220649f085dddff10473b6ebf832a974288300224e60bsalomon if (blob) { 220700d5c2c6523321d25b32905ff4822f083a4173eefmalita this->onDrawTextBlob(blob, x, y, paint); 220800d5c2c6523321d25b32905ff4822f083a4173eefmalita } 220900d5c2c6523321d25b32905ff4822f083a4173eefmalita} 2210e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com 22118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawVertices(VertexMode vmode, int vertexCount, 22128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPoint verts[], const SkPoint texs[], 22138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkColor colors[], SkXfermode* xmode, 22148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint16_t indices[], int indexCount, 22158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 22169881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawVertices()"); 221778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, NULL) 22184b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 22198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 22208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawVertices(iter, vmode, vertexCount, verts, texs, 22214e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com colors, xmode, indices, indexCount, 22224e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com looper.paint()); 22238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 22244b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 22254e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 22268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 22278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2228b3c9d1c33caf325aada244204215eb790c228c12dandovvoid SkCanvas::drawPatch(const SkPoint cubics[12], const SkColor colors[4], 2229b3c9d1c33caf325aada244204215eb790c228c12dandov const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint) { 22309881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPatch()"); 2231b3c9d1c33caf325aada244204215eb790c228c12dandov if (NULL == cubics) { 2232b3c9d1c33caf325aada244204215eb790c228c12dandov return; 2233b3c9d1c33caf325aada244204215eb790c228c12dandov } 22346cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2235ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov // Since a patch is always within the convex hull of the control points, we discard it when its 2236ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov // bounding rectangle is completely outside the current clip. 2237ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov SkRect bounds; 2238b3c9d1c33caf325aada244204215eb790c228c12dandov bounds.set(cubics, SkPatchUtils::kNumCtrlPts); 2239ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov if (this->quickReject(bounds)) { 2240ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov return; 2241ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov } 22426cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2243b3c9d1c33caf325aada244204215eb790c228c12dandov this->onDrawPatch(cubics, colors, texCoords, xmode, paint); 2244b3c9d1c33caf325aada244204215eb790c228c12dandov} 2245b3c9d1c33caf325aada244204215eb790c228c12dandov 2246b3c9d1c33caf325aada244204215eb790c228c12dandovvoid SkCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], 2247b3c9d1c33caf325aada244204215eb790c228c12dandov const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint) { 2248b3c9d1c33caf325aada244204215eb790c228c12dandov 2249ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, NULL) 22506cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2251ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov while (iter.next()) { 2252b3c9d1c33caf325aada244204215eb790c228c12dandov iter.fDevice->drawPatch(iter, cubics, colors, texCoords, xmode, paint); 2253ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov } 22546cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2255ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov LOOPER_END 2256ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov} 2257ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov 22586a070dc06af4e9f305f9d08a69e34d18ade473cbreedvoid SkCanvas::EXPERIMENTAL_drawDrawable(SkCanvasDrawable* dr) { 22596be2aa9a251bf6022570a03140f956655b3ef1dareed if (dr && !this->quickReject(dr->getBounds())) { 22606be2aa9a251bf6022570a03140f956655b3ef1dareed this->onDrawDrawable(dr); 22616a070dc06af4e9f305f9d08a69e34d18ade473cbreed } 22626a070dc06af4e9f305f9d08a69e34d18ade473cbreed} 22636a070dc06af4e9f305f9d08a69e34d18ade473cbreed 22646a070dc06af4e9f305f9d08a69e34d18ade473cbreedvoid SkCanvas::onDrawDrawable(SkCanvasDrawable* dr) { 22656a070dc06af4e9f305f9d08a69e34d18ade473cbreed dr->draw(this); 22666a070dc06af4e9f305f9d08a69e34d18ade473cbreed} 22676a070dc06af4e9f305f9d08a69e34d18ade473cbreed 22688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 22698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// These methods are NOT virtual, and therefore must call back into virtual 22708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// methods, rather than actually drawing themselves. 22718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 22728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b, 2274845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com SkXfermode::Mode mode) { 22759881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawARGB()"); 22768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 22778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setARGB(a, r, g, b); 2279845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com if (SkXfermode::kSrcOver_Mode != mode) { 22800baf19375466cfc24c96532df406e7c5b1d1aae8reed@android.com paint.setXfermodeMode(mode); 22818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 22828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPaint(paint); 22838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 22848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2285845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.comvoid SkCanvas::drawColor(SkColor c, SkXfermode::Mode mode) { 22869881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawColor()"); 22878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 22888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setColor(c); 2290845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com if (SkXfermode::kSrcOver_Mode != mode) { 22910baf19375466cfc24c96532df406e7c5b1d1aae8reed@android.com paint.setXfermodeMode(mode); 22928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 22938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPaint(paint); 22948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 22958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPoint(SkScalar x, SkScalar y, const SkPaint& paint) { 22979881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPoint(SkPaint)"); 22988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pt; 22994b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 23008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pt.set(x, y); 23018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kPoints_PointMode, 1, &pt, paint); 23028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPoint(SkScalar x, SkScalar y, SkColor color) { 23059881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPoint(SkColor)"); 23068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pt; 23078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 23084b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 23098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pt.set(x, y); 23108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setColor(color); 23118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kPoints_PointMode, 1, &pt, paint); 23128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, 23158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 23169881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawLine()"); 23178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pts[2]; 23184b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 23198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pts[0].set(x0, y0); 23208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pts[1].set(x1, y1); 23218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kLines_PointMode, 2, pts, paint); 23228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawRectCoords(SkScalar left, SkScalar top, 23258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar right, SkScalar bottom, 23268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 23279881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRectCoords()"); 23288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 23298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.set(left, top, right, bottom); 23318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawRect(r, paint); 23328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, 23358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 23369881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawCircle()"); 23378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (radius < 0) { 23388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com radius = 0; 23398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 23428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.set(cx - radius, cy - radius, cx + radius, cy + radius); 23434ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->drawOval(r, paint); 23448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawRoundRect(const SkRect& r, SkScalar rx, SkScalar ry, 23478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 23489881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRoundRect()"); 23498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (rx > 0 && ry > 0) { 23508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.canComputeFastBounds()) { 23518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect storage; 23523b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(paint.computeFastBounds(r, &storage))) { 23538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 23548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23564ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com SkRRect rrect; 23574ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com rrect.setRectXY(r, rx, ry); 23584ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->drawRRect(rrect, paint); 23598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 23608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawRect(r, paint); 23618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawArc(const SkRect& oval, SkScalar startAngle, 23658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar sweepAngle, bool useCenter, 23668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 23679881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawArc()"); 23688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (SkScalarAbs(sweepAngle) >= SkIntToScalar(360)) { 23698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawOval(oval, paint); 23708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 23718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath path; 23728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (useCenter) { 23738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.moveTo(oval.centerX(), oval.centerY()); 23748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.arcTo(oval, startAngle, sweepAngle, !useCenter); 23768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (useCenter) { 23778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.close(); 23788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPath(path, paint); 23808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawTextOnPathHV(const void* text, size_t byteLength, 23848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPath& path, SkScalar hOffset, 23858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar vOffset, const SkPaint& paint) { 23869881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextOnPathHV()"); 23878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 23884b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 23898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.setTranslate(hOffset, vOffset); 23908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawTextOnPath(text, byteLength, path, &matrix, paint); 23918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2393f76bacff7f66724072c67edb185abf9e3add11a0reed@android.com/////////////////////////////////////////////////////////////////////////////// 23949b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillipsvoid SkCanvas::drawPicture(const SkPicture* picture) { 23959881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPicture()"); 239649f085dddff10473b6ebf832a974288300224e60bsalomon if (picture) { 2397d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed this->onDrawPicture(picture, NULL, NULL); 23989b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips } 23999b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips} 24009b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips 2401d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedvoid SkCanvas::drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint) { 24029881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPicture(SkMatrix, SkPaint)"); 240349f085dddff10473b6ebf832a974288300224e60bsalomon if (picture) { 2404d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed if (matrix && matrix->isIdentity()) { 2405d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed matrix = NULL; 2406d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 2407d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed this->onDrawPicture(picture, matrix, paint); 2408d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 2409d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 24109b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips 2411d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedvoid SkCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix, 2412d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed const SkPaint* paint) { 2413145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org SkBaseDevice* device = this->getTopDevice(); 241449f085dddff10473b6ebf832a974288300224e60bsalomon if (device) { 2415145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org // Canvas has to first give the device the opportunity to render 2416145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org // the picture itself. 2417d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed if (device->EXPERIMENTAL_drawPicture(this, picture, matrix, paint)) { 2418145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org return; // the device has rendered the entire picture 2419145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org } 2420145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org } 2421145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org 2422a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); 2423d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 2424c5ba71d2e5cd426def66fa49dcf003e5b2c98dc7robertphillips picture->playback(this); 24258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 24288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 24298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::LayerIter::LayerIter(SkCanvas* canvas, bool skipEmptyClips) { 2431d642329293cce602ac24df8f585c14a98795da87reed@google.com SK_COMPILE_ASSERT(sizeof(fStorage) >= sizeof(SkDrawIter), fStorage_too_small); 24328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(canvas); 24348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fImpl = new (fStorage) SkDrawIter(canvas, skipEmptyClips); 24368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDone = !fImpl->next(); 24378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::LayerIter::~LayerIter() { 24408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fImpl->~SkDrawIter(); 24418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::LayerIter::next() { 24448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDone = !fImpl->next(); 24458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24471f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::LayerIter::device() const { 24488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fImpl->getDevice(); 24498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkMatrix& SkCanvas::LayerIter::matrix() const { 24528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fImpl->getMatrix(); 24538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkPaint& SkCanvas::LayerIter::paint() const { 24568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* paint = fImpl->getPaint(); 24578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == paint) { 24588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint = &fDefaultPaint; 24598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 24608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return *paint; 24618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkRegion& SkCanvas::LayerIter::clip() const { return fImpl->getClip(); } 24648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::LayerIter::x() const { return fImpl->getX(); } 24658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::LayerIter::y() const { return fImpl->getY(); } 246620a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com 246720a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com/////////////////////////////////////////////////////////////////////////////// 246820a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com 2469c3b589a24eb4d567a906189f882c259ecf5c2f58fmalitaSkCanvasClipVisitor::~SkCanvasClipVisitor() { } 24703107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 24713107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 24723107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 24733107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.orgstatic bool supported_for_raster_canvas(const SkImageInfo& info) { 24743107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org switch (info.alphaType()) { 24753107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kPremul_SkAlphaType: 24763107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kOpaque_SkAlphaType: 24773107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org break; 24783107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org default: 24793107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return false; 24803107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 24813107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 24823107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org switch (info.colorType()) { 24833107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kAlpha_8_SkColorType: 24843107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kRGB_565_SkColorType: 248528fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org case kN32_SkColorType: 24863107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org break; 24873107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org default: 24883107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return false; 24893107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 24903107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 24913107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return true; 24923107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org} 24933107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 249442b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.orgSkCanvas* SkCanvas::NewRasterDirect(const SkImageInfo& info, void* pixels, size_t rowBytes) { 249542b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org if (!supported_for_raster_canvas(info)) { 249642b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org return NULL; 249742b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org } 2498eb849e5fd10cbe00cbc31307ba97fd9efca0b41bskia.committer@gmail.com 249942b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org SkBitmap bitmap; 250042b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org if (!bitmap.installPixels(info, pixels, rowBytes)) { 250142b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org return NULL; 250242b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org } 250342b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org return SkNEW_ARGS(SkCanvas, (bitmap)); 250442b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org} 2505d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 2506d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed/////////////////////////////////////////////////////////////////////////////// 2507d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 2508d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedSkAutoCanvasMatrixPaint::SkAutoCanvasMatrixPaint(SkCanvas* canvas, const SkMatrix* matrix, 2509a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips const SkPaint* paint, const SkRect& bounds) 2510d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed : fCanvas(canvas) 2511d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed , fSaveCount(canvas->getSaveCount()) 2512d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed{ 251349f085dddff10473b6ebf832a974288300224e60bsalomon if (paint) { 2514a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkRect newBounds = bounds; 2515d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed if (matrix) { 2516a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips matrix->mapRect(&newBounds); 2517d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 2518a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips canvas->saveLayer(&newBounds, paint); 251949f085dddff10473b6ebf832a974288300224e60bsalomon } else if (matrix) { 2520d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed canvas->save(); 2521d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 25226cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 252349f085dddff10473b6ebf832a974288300224e60bsalomon if (matrix) { 2524d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed canvas->concat(*matrix); 2525d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 2526d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 2527d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 2528d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedSkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { 2529d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed fCanvas->restoreToCount(fSaveCount); 2530d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 2531