SkCanvas.cpp revision 52ede1d905728cdcaa98db1e4a33724f5a85c62d
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 8d3ebb48320cf1b7e969974673e4bd7743816985ebungeman#include "SkBitmapDevice.h" 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h" 10d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed#include "SkCanvasPriv.h" 11d3ebb48320cf1b7e969974673e4bd7743816985ebungeman#include "SkClipStack.h" 12dbc3cefb0b624808ddb86d444e6103f216e12fa5reed#include "SkColorFilter.h" 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDraw.h" 143cb3840c9af6f70896cf5565a38d4ee03c02d767reed#include "SkDrawable.h" 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDrawFilter.h" 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDrawLooper.h" 175f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt#include "SkErrorInternals.h" 18b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr#include "SkImage.h" 19262a71b7f95ce98ff3dd8dba845afbd724470903reed#include "SkImage_Base.h" 20900c36779610dc65c42a5004ee3693fd70961ba4senorblanco#include "SkImageFilter.h" 21900c36779610dc65c42a5004ee3693fd70961ba4senorblanco#include "SkImageFilterCache.h" 22262a71b7f95ce98ff3dd8dba845afbd724470903reed#include "SkMatrixUtils.h" 2374bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org#include "SkMetaData.h" 244c21dc5ddf3b482293ed34eead876d8d61a662c3reed#include "SkNinePatchIter.h" 25c83a29759a5c2966da5ab973e4fd90763e4c962breed#include "SkPaintPriv.h" 26b3c9d1c33caf325aada244204215eb790c228c12dandov#include "SkPatchUtils.h" 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPicture.h" 280017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com#include "SkRasterClip.h" 2996472deea70169396b8e1f576e470138f55fdb1freed#include "SkReadPixelsRec.h" 304ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com#include "SkRRect.h" 3179fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org#include "SkSmallAllocator.h" 324418dbac3386f26c8da62ab242be9c178961eb18robertphillips#include "SkSpecialImage.h" 3397af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com#include "SkSurface_Base.h" 347ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita#include "SkTextBlob.h" 3552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com#include "SkTextFormatParams.h" 36a076e9be17654a60310e72c4f70fcd5337f56dbfreed@google.com#include "SkTLazy.h" 378f757f540a8378c7b1354aab3d4650eaa920b17adanakj#include "SkTraceEvent.h" 38d3ebb48320cf1b7e969974673e4bd7743816985ebungeman 39d3ebb48320cf1b7e969974673e4bd7743816985ebungeman#include <new> 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 41644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#if SK_SUPPORT_GPU 427354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips#include "GrContext.h" 43644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#include "GrRenderTarget.h" 447354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips#include "SkGr.h" 45644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#endif 46644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org 47e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed#define RETURN_ON_NULL(ptr) do { if (nullptr == (ptr)) return; } while (0) 48e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed 49c83a29759a5c2966da5ab973e4fd90763e4c962breed/* 50c83a29759a5c2966da5ab973e4fd90763e4c962breed * Return true if the drawing this rect would hit every pixels in the canvas. 51c83a29759a5c2966da5ab973e4fd90763e4c962breed * 52c83a29759a5c2966da5ab973e4fd90763e4c962breed * Returns false if 53c83a29759a5c2966da5ab973e4fd90763e4c962breed * - rect does not contain the canvas' bounds 54c83a29759a5c2966da5ab973e4fd90763e4c962breed * - paint is not fill 55c83a29759a5c2966da5ab973e4fd90763e4c962breed * - paint would blur or otherwise change the coverage of the rect 56c83a29759a5c2966da5ab973e4fd90763e4c962breed */ 57c83a29759a5c2966da5ab973e4fd90763e4c962breedbool SkCanvas::wouldOverwriteEntireSurface(const SkRect* rect, const SkPaint* paint, 58c83a29759a5c2966da5ab973e4fd90763e4c962breed ShaderOverrideOpacity overrideOpacity) const { 5999fe82260633fcf5d92cca38d12ef0937ecca61cbungeman static_assert((int)SkPaintPriv::kNone_ShaderOverrideOpacity == 6099fe82260633fcf5d92cca38d12ef0937ecca61cbungeman (int)kNone_ShaderOverrideOpacity, 6199fe82260633fcf5d92cca38d12ef0937ecca61cbungeman "need_matching_enums0"); 6299fe82260633fcf5d92cca38d12ef0937ecca61cbungeman static_assert((int)SkPaintPriv::kOpaque_ShaderOverrideOpacity == 6399fe82260633fcf5d92cca38d12ef0937ecca61cbungeman (int)kOpaque_ShaderOverrideOpacity, 6499fe82260633fcf5d92cca38d12ef0937ecca61cbungeman "need_matching_enums1"); 6599fe82260633fcf5d92cca38d12ef0937ecca61cbungeman static_assert((int)SkPaintPriv::kNotOpaque_ShaderOverrideOpacity == 6699fe82260633fcf5d92cca38d12ef0937ecca61cbungeman (int)kNotOpaque_ShaderOverrideOpacity, 6799fe82260633fcf5d92cca38d12ef0937ecca61cbungeman "need_matching_enums2"); 68c83a29759a5c2966da5ab973e4fd90763e4c962breed 69c83a29759a5c2966da5ab973e4fd90763e4c962breed const SkISize size = this->getBaseLayerSize(); 70c83a29759a5c2966da5ab973e4fd90763e4c962breed const SkRect bounds = SkRect::MakeIWH(size.width(), size.height()); 71c83a29759a5c2966da5ab973e4fd90763e4c962breed if (!this->getClipStack()->quickContains(bounds)) { 72c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; 73c83a29759a5c2966da5ab973e4fd90763e4c962breed } 74c83a29759a5c2966da5ab973e4fd90763e4c962breed 75c83a29759a5c2966da5ab973e4fd90763e4c962breed if (rect) { 76c83a29759a5c2966da5ab973e4fd90763e4c962breed if (!this->getTotalMatrix().rectStaysRect()) { 77c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; // conservative 78c83a29759a5c2966da5ab973e4fd90763e4c962breed } 79c83a29759a5c2966da5ab973e4fd90763e4c962breed 80c83a29759a5c2966da5ab973e4fd90763e4c962breed SkRect devRect; 81c83a29759a5c2966da5ab973e4fd90763e4c962breed this->getTotalMatrix().mapRect(&devRect, *rect); 828c0144ccb17220db9d5140ef5ee85d5bc7837513fmalita if (!devRect.contains(bounds)) { 83c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; 84c83a29759a5c2966da5ab973e4fd90763e4c962breed } 85c83a29759a5c2966da5ab973e4fd90763e4c962breed } 86c83a29759a5c2966da5ab973e4fd90763e4c962breed 87c83a29759a5c2966da5ab973e4fd90763e4c962breed if (paint) { 88c83a29759a5c2966da5ab973e4fd90763e4c962breed SkPaint::Style paintStyle = paint->getStyle(); 89c83a29759a5c2966da5ab973e4fd90763e4c962breed if (!(paintStyle == SkPaint::kFill_Style || 90c83a29759a5c2966da5ab973e4fd90763e4c962breed paintStyle == SkPaint::kStrokeAndFill_Style)) { 91c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; 92c83a29759a5c2966da5ab973e4fd90763e4c962breed } 93c83a29759a5c2966da5ab973e4fd90763e4c962breed if (paint->getMaskFilter() || paint->getLooper() 94c83a29759a5c2966da5ab973e4fd90763e4c962breed || paint->getPathEffect() || paint->getImageFilter()) { 95c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; // conservative 96c83a29759a5c2966da5ab973e4fd90763e4c962breed } 97c83a29759a5c2966da5ab973e4fd90763e4c962breed } 98c83a29759a5c2966da5ab973e4fd90763e4c962breed return SkPaintPriv::Overwrites(paint, (SkPaintPriv::ShaderOverrideOpacity)overrideOpacity); 99c83a29759a5c2966da5ab973e4fd90763e4c962breed} 100c83a29759a5c2966da5ab973e4fd90763e4c962breed 101c83a29759a5c2966da5ab973e4fd90763e4c962breed/////////////////////////////////////////////////////////////////////////////////////////////////// 102c83a29759a5c2966da5ab973e4fd90763e4c962breed 103d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareedstatic bool gIgnoreSaveLayerBounds; 104d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareedvoid SkCanvas::Internal_Private_SetIgnoreSaveLayerBounds(bool ignore) { 105d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed gIgnoreSaveLayerBounds = ignore; 106d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed} 107d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareedbool SkCanvas::Internal_Private_GetIgnoreSaveLayerBounds() { 108d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed return gIgnoreSaveLayerBounds; 109d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed} 110d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed 1110acf1b4b3645772d220c720313821bac389751b5reedstatic bool gTreatSpriteAsBitmap; 1120acf1b4b3645772d220c720313821bac389751b5reedvoid SkCanvas::Internal_Private_SetTreatSpriteAsBitmap(bool spriteAsBitmap) { 1130acf1b4b3645772d220c720313821bac389751b5reed gTreatSpriteAsBitmap = spriteAsBitmap; 1140acf1b4b3645772d220c720313821bac389751b5reed} 1150acf1b4b3645772d220c720313821bac389751b5reedbool SkCanvas::Internal_Private_GetTreatSpriteAsBitmap() { 1160acf1b4b3645772d220c720313821bac389751b5reed return gTreatSpriteAsBitmap; 1170acf1b4b3645772d220c720313821bac389751b5reed} 1180acf1b4b3645772d220c720313821bac389751b5reed 119da17f758442f16747af39f8fbaed9c097048519creed@google.com// experimental for faster tiled drawing... 120da17f758442f16747af39f8fbaed9c097048519creed@google.com//#define SK_ENABLE_CLIP_QUICKREJECT 1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//#define SK_TRACE_SAVERESTORE 1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_TRACE_SAVERESTORE 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gLayerCounter; 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_layer() { ++gLayerCounter; printf("----- inc layer %d\n", gLayerCounter); } 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_layer() { --gLayerCounter; printf("----- dec layer %d\n", gLayerCounter); } 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gRecCounter; 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_rec() { ++gRecCounter; printf("----- inc rec %d\n", gRecCounter); } 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_rec() { --gRecCounter; printf("----- dec rec %d\n", gRecCounter); } 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gCanvasCounter; 1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_canvas() { ++gCanvasCounter; printf("----- inc canvas %d\n", gCanvasCounter); } 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_canvas() { --gCanvasCounter; printf("----- dec canvas %d\n", gCanvasCounter); } 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_layer() 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_layer() 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_rec() 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_rec() 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_canvas() 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_canvas() 1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1442c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.orgtypedef SkTLazy<SkPaint> SkLazyPaint; 1452c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org 146c83a29759a5c2966da5ab973e4fd90763e4c962breedvoid SkCanvas::predrawNotify(bool willOverwritesEntireSurface) { 14797af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com if (fSurfaceBase) { 148c83a29759a5c2966da5ab973e4fd90763e4c962breed fSurfaceBase->aboutToDraw(willOverwritesEntireSurface 149c83a29759a5c2966da5ab973e4fd90763e4c962breed ? SkSurface::kDiscard_ContentChangeMode 150c83a29759a5c2966da5ab973e4fd90763e4c962breed : SkSurface::kRetain_ContentChangeMode); 151c83a29759a5c2966da5ab973e4fd90763e4c962breed } 152c83a29759a5c2966da5ab973e4fd90763e4c962breed} 153c83a29759a5c2966da5ab973e4fd90763e4c962breed 154c83a29759a5c2966da5ab973e4fd90763e4c962breedvoid SkCanvas::predrawNotify(const SkRect* rect, const SkPaint* paint, 155c83a29759a5c2966da5ab973e4fd90763e4c962breed ShaderOverrideOpacity overrideOpacity) { 156c83a29759a5c2966da5ab973e4fd90763e4c962breed if (fSurfaceBase) { 157c83a29759a5c2966da5ab973e4fd90763e4c962breed SkSurface::ContentChangeMode mode = SkSurface::kRetain_ContentChangeMode; 158c83a29759a5c2966da5ab973e4fd90763e4c962breed // Since willOverwriteAllPixels() may not be complete free to call, we only do so if 159c83a29759a5c2966da5ab973e4fd90763e4c962breed // there is an outstanding snapshot, since w/o that, there will be no copy-on-write 160c83a29759a5c2966da5ab973e4fd90763e4c962breed // and therefore we don't care which mode we're in. 161c83a29759a5c2966da5ab973e4fd90763e4c962breed // 162c83a29759a5c2966da5ab973e4fd90763e4c962breed if (fSurfaceBase->outstandingImageSnapshot()) { 163c83a29759a5c2966da5ab973e4fd90763e4c962breed if (this->wouldOverwriteEntireSurface(rect, paint, overrideOpacity)) { 164c83a29759a5c2966da5ab973e4fd90763e4c962breed mode = SkSurface::kDiscard_ContentChangeMode; 165c83a29759a5c2966da5ab973e4fd90763e4c962breed } 166c83a29759a5c2966da5ab973e4fd90763e4c962breed } 167c83a29759a5c2966da5ab973e4fd90763e4c962breed fSurfaceBase->aboutToDraw(mode); 16897af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com } 16997af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com} 17097af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com 1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1734a8126e7f81384526629b1e21bf89b632ea13cd9reedstatic uint32_t filter_paint_flags(const SkSurfaceProps& props, uint32_t flags) { 1744a8126e7f81384526629b1e21bf89b632ea13cd9reed const uint32_t propFlags = props.flags(); 1754a8126e7f81384526629b1e21bf89b632ea13cd9reed if (propFlags & SkSurfaceProps::kDisallowDither_Flag) { 1764a8126e7f81384526629b1e21bf89b632ea13cd9reed flags &= ~SkPaint::kDither_Flag; 1774a8126e7f81384526629b1e21bf89b632ea13cd9reed } 1784a8126e7f81384526629b1e21bf89b632ea13cd9reed if (propFlags & SkSurfaceProps::kDisallowAntiAlias_Flag) { 1794a8126e7f81384526629b1e21bf89b632ea13cd9reed flags &= ~SkPaint::kAntiAlias_Flag; 1804a8126e7f81384526629b1e21bf89b632ea13cd9reed } 1814a8126e7f81384526629b1e21bf89b632ea13cd9reed return flags; 1824a8126e7f81384526629b1e21bf89b632ea13cd9reed} 1834a8126e7f81384526629b1e21bf89b632ea13cd9reed 1844a8126e7f81384526629b1e21bf89b632ea13cd9reed/////////////////////////////////////////////////////////////////////////////// 1854a8126e7f81384526629b1e21bf89b632ea13cd9reed 1861f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com/* This is the record we keep for each SkBaseDevice that the user installs. 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com The clip/matrix/proc are fields that reflect the top of the save/restore 1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stack. Whenever the canvas changes, it marks a dirty flag, and then before 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com these are used (assuming we're not on a layer) we rebuild these cache 1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com values: they reflect the top of the save stack, but translated and clipped 1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com by the device's XY offset and bitmap-bounds. 1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct DeviceCM { 1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* fNext; 1951f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* fDevice; 196045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com SkRasterClip fClip; 1976f8f292aa768869a9e85c314b124875f57504f2creed@google.com SkPaint* fPaint; // may be null (in the future) 19861f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed const SkMatrix* fMatrix; 19961f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed SkMatrix fMatrixStorage; 2008c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkMatrix fStashedMatrix; // original CTM; used by imagefilter in saveLayer 20161f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed const bool fDeviceIsBitmapDevice; 2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20396e657d0e103b8358a77ecd913f6086929f792b8reed DeviceCM(SkBaseDevice* device, const SkPaint* paint, SkCanvas* canvas, 2048c30a8196dd5903d2d23b4d0a5dc888e802bf698reed bool conservativeRasterClip, bool deviceIsBitmapDevice, const SkMatrix& stashed) 20596fcdcc219d2a0d3579719b84b28bede76efba64halcanary : fNext(nullptr) 206d954498c01ccf0417feacf89e45d0c62a06a813breed , fClip(conservativeRasterClip) 2078c30a8196dd5903d2d23b4d0a5dc888e802bf698reed , fStashedMatrix(stashed) 20861f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed , fDeviceIsBitmapDevice(deviceIsBitmapDevice) 209d954498c01ccf0417feacf89e45d0c62a06a813breed { 21096fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr != device) { 2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device->ref(); 21240a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com device->onAttachToCanvas(canvas); 2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2144b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com fDevice = device; 21596fcdcc219d2a0d3579719b84b28bede76efba64halcanary fPaint = paint ? new SkPaint(*paint) : nullptr; 21688edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 2178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21888edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com ~DeviceCM() { 21949f085dddff10473b6ebf832a974288300224e60bsalomon if (fDevice) { 22040a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com fDevice->onDetachFromCanvas(); 2218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDevice->unref(); 2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 223385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete fPaint; 22488edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 2254b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 226feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein void reset(const SkIRect& bounds) { 227feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(!fPaint); 228feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(!fNext); 229feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(fDevice); 230feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fClip.setRect(bounds); 231feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein } 232feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 233045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com void updateMC(const SkMatrix& totalMatrix, const SkRasterClip& totalClip, 234045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com const SkClipStack& clipStack, SkRasterClip* updateClip) { 2356f8f292aa768869a9e85c314b124875f57504f2creed@google.com int x = fDevice->getOrigin().x(); 2366f8f292aa768869a9e85c314b124875f57504f2creed@google.com int y = fDevice->getOrigin().y(); 2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int width = fDevice->width(); 2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int height = fDevice->height(); 2394b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if ((x | y) == 0) { 2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = &totalMatrix; 2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fClip = totalClip; 2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrixStorage = totalMatrix; 2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrixStorage.postTranslate(SkIntToScalar(-x), 2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIntToScalar(-y)); 2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = &fMatrixStorage; 2484b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com totalClip.translate(-x, -y, &fClip); 2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 252045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com fClip.op(SkIRect::MakeWH(width, height), SkRegion::kIntersect_Op); 2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // intersect clip, but don't translate it (yet) 2554b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (updateClip) { 257045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com updateClip->op(SkIRect::MakeXYWH(x, y, width, height), 2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRegion::kDifference_Op); 2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2604b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2613fffb2ee9fa01ae61efb2395973eb7575eda4c96robertphillips@google.com fDevice->setMatrixClip(*fMatrix, fClip.forceGetBW(), clipStack); 2623fffb2ee9fa01ae61efb2395973eb7575eda4c96robertphillips@google.com 2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!fClip.isEmpty()) { 2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIRect deviceR; 2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com deviceR.set(0, 0, width, height); 2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(deviceR.contains(fClip.getBounds())); 2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 270f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* This is the record we keep for each save/restore level in the stack. 2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Since a level optionally copies the matrix and/or stack, we have pointers 2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for these fields. If the value is copied for this level, the copy is 2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stored in the ...Storage field, and the pointer points to that. If the 2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value is not copied for this level, we ignore ...Storage, and just point 2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com at the corresponding value in the previous level in the stack. 2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkCanvas::MCRec { 2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 2821f836ee096bb988adef4b9757b2629c7afeda36dreed SkDrawFilter* fFilter; // the current filter (or null) 283d954498c01ccf0417feacf89e45d0c62a06a813breed DeviceCM* fLayer; 2848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* If there are any layers in the stack, this points to the top-most 2858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com one that is at or below this level in the stack (so we know what 2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bitmap/device to draw into from this level. This value is NOT 2878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com reference counted, since the real owner is either our fLayer field, 2888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com or a previous one in a lower level.) 2898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 2902ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed DeviceCM* fTopLayer; 2912ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkRasterClip fRasterClip; 2922ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkMatrix fMatrix; 2932ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed int fDeferredSaveCount; 2948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 295d954498c01ccf0417feacf89e45d0c62a06a813breed MCRec(bool conservativeRasterClip) : fRasterClip(conservativeRasterClip) { 29696fcdcc219d2a0d3579719b84b28bede76efba64halcanary fFilter = nullptr; 29796fcdcc219d2a0d3579719b84b28bede76efba64halcanary fLayer = nullptr; 29896fcdcc219d2a0d3579719b84b28bede76efba64halcanary fTopLayer = nullptr; 2992ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fMatrix.reset(); 3002ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fDeferredSaveCount = 0; 301b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 302d954498c01ccf0417feacf89e45d0c62a06a813breed // don't bother initializing fNext 303d954498c01ccf0417feacf89e45d0c62a06a813breed inc_rec(); 304d954498c01ccf0417feacf89e45d0c62a06a813breed } 3052ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed MCRec(const MCRec& prev) : fRasterClip(prev.fRasterClip), fMatrix(prev.fMatrix) { 306d954498c01ccf0417feacf89e45d0c62a06a813breed fFilter = SkSafeRef(prev.fFilter); 30796fcdcc219d2a0d3579719b84b28bede76efba64halcanary fLayer = nullptr; 308d954498c01ccf0417feacf89e45d0c62a06a813breed fTopLayer = prev.fTopLayer; 3092ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fDeferredSaveCount = 0; 310b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 3118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // don't bother initializing fNext 3128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inc_rec(); 3138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ~MCRec() { 31582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fFilter); 316385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete fLayer; 3178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dec_rec(); 3188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 319feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 320feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein void reset(const SkIRect& bounds) { 321feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(fLayer); 322feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(fDeferredSaveCount == 0); 323feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 324feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fMatrix.reset(); 325feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fRasterClip.setRect(bounds); 326feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fLayer->reset(bounds); 327feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein } 3288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkDrawIter : public SkDraw { 3318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 3328a0b0291ae4260ef2a46f4341c18a702c0ce3f8btomhudson@google.com SkDrawIter(SkCanvas* canvas, bool skipEmptyClips = true) { 3334370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com canvas = canvas->canvasForDrawIter(); 3348a0b0291ae4260ef2a46f4341c18a702c0ce3f8btomhudson@google.com fCanvas = canvas; 3358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com canvas->updateDeviceCMCache(); 3368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 337687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack = canvas->fClipStack; 3388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = canvas->fMCRec->fTopLayer; 3398a0b0291ae4260ef2a46f4341c18a702c0ce3f8btomhudson@google.com fSkipEmptyClips = skipEmptyClips; 3408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3414b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 3428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool next() { 3438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // skip over recs with empty clips 3448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fSkipEmptyClips) { 3458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (fCurrLayer && fCurrLayer->fClip.isEmpty()) { 3468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = fCurrLayer->fNext; 3478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 350f68c5e2f9f05b3af2bae0979ace2684b6041b6e3reed@google.com const DeviceCM* rec = fCurrLayer; 351f68c5e2f9f05b3af2bae0979ace2684b6041b6e3reed@google.com if (rec && rec->fDevice) { 3528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = rec->fMatrix; 354045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com fRC = &rec->fClip; 3558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDevice = rec->fDevice; 35641e010cb901c0da9066c4df562030808c9ccd7f8reed if (!fDevice->accessPixels(&fDst)) { 35796fcdcc219d2a0d3579719b84b28bede76efba64halcanary fDst.reset(fDevice->imageInfo(), nullptr, 0); 35841e010cb901c0da9066c4df562030808c9ccd7f8reed } 3598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint = rec->fPaint; 360f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com SkDEBUGCODE(this->validate();) 3618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = rec->fNext; 36396fcdcc219d2a0d3579719b84b28bede76efba64halcanary // fCurrLayer may be nullptr now 364199f108f14a5f60a9c2205ffa79b26102a206ad0reed@android.com 3658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 3668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 3688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3694b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 3701f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* getDevice() const { return fDevice; } 3711e7f5e708e5daeb0c18ae49001c9e3cd5e3b13cbreed const SkRasterClip& getClip() const { return *fRC; } 3726f8f292aa768869a9e85c314b124875f57504f2creed@google.com int getX() const { return fDevice->getOrigin().x(); } 3736f8f292aa768869a9e85c314b124875f57504f2creed@google.com int getY() const { return fDevice->getOrigin().y(); } 3748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& getMatrix() const { return *fMatrix; } 3758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* getPaint() const { return fPaint; } 3766f8f292aa768869a9e85c314b124875f57504f2creed@google.com 3778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 3788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkCanvas* fCanvas; 3798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const DeviceCM* fCurrLayer; 3808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* fPaint; // May be null. 3818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkBool8 fSkipEmptyClips; 3828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef SkDraw INHERITED; 3848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////// 3878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 388dbc3cefb0b624808ddb86d444e6103f216e12fa5reedstatic SkPaint* set_if_needed(SkLazyPaint* lazy, const SkPaint& orig) { 389dbc3cefb0b624808ddb86d444e6103f216e12fa5reed return lazy->isValid() ? lazy->get() : lazy->set(orig); 390dbc3cefb0b624808ddb86d444e6103f216e12fa5reed} 391dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 392dbc3cefb0b624808ddb86d444e6103f216e12fa5reed/** 393dbc3cefb0b624808ddb86d444e6103f216e12fa5reed * If the paint has an imagefilter, but it can be simplified to just a colorfilter, return that 39496fcdcc219d2a0d3579719b84b28bede76efba64halcanary * colorfilter, else return nullptr. 395dbc3cefb0b624808ddb86d444e6103f216e12fa5reed */ 396d053ce9c54d4e5937a142278359e5a4cde18095ereedstatic sk_sp<SkColorFilter> image_to_color_filter(const SkPaint& paint) { 397dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkImageFilter* imgf = paint.getImageFilter(); 398dbc3cefb0b624808ddb86d444e6103f216e12fa5reed if (!imgf) { 39996fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 400dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 401dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 402d053ce9c54d4e5937a142278359e5a4cde18095ereed SkColorFilter* imgCFPtr; 403d053ce9c54d4e5937a142278359e5a4cde18095ereed if (!imgf->asAColorFilter(&imgCFPtr)) { 40496fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 405dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 406d053ce9c54d4e5937a142278359e5a4cde18095ereed sk_sp<SkColorFilter> imgCF(imgCFPtr); 407dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 408dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkColorFilter* paintCF = paint.getColorFilter(); 40996fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paintCF) { 410dbc3cefb0b624808ddb86d444e6103f216e12fa5reed // there is no existing paint colorfilter, so we can just return the imagefilter's 411dbc3cefb0b624808ddb86d444e6103f216e12fa5reed return imgCF; 412dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 413dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 414dbc3cefb0b624808ddb86d444e6103f216e12fa5reed // The paint has both a colorfilter(paintCF) and an imagefilter-which-is-a-colorfilter(imgCF) 415dbc3cefb0b624808ddb86d444e6103f216e12fa5reed // and we need to combine them into a single colorfilter. 416d053ce9c54d4e5937a142278359e5a4cde18095ereed return SkColorFilter::MakeComposeFilter(std::move(imgCF), sk_ref_sp(paintCF)); 417dbc3cefb0b624808ddb86d444e6103f216e12fa5reed} 418dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 41987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco/** 42087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * There are many bounds in skia. A circle's bounds is just its center extended by its radius. 42187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * However, if we stroke a circle, then the "bounds" of that is larger, since it will now draw 42287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * outside of its raw-bounds by 1/2 the stroke width. SkPaint has lots of optional 42387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * effects/attributes that can modify the effective bounds of a given primitive -- maskfilters, 42487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * patheffects, stroking, etc. This function takes a raw bounds and a paint, and returns the 42587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * conservative "effective" bounds based on the settings in the paint... with one exception. This 42687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * function does *not* look at the imagefilter, which can also modify the effective bounds. It is 42787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * deliberately ignored. 42887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco */ 42987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblancostatic const SkRect& apply_paint_to_bounds_sans_imagefilter(const SkPaint& paint, 43087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco const SkRect& rawBounds, 43187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect* storage) { 43287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkPaint tmpUnfiltered(paint); 43387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco tmpUnfiltered.setImageFilter(nullptr); 43487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (tmpUnfiltered.canComputeFastBounds()) { 43587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return tmpUnfiltered.computeFastBounds(rawBounds, storage); 43687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } else { 43787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return rawBounds; 43887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 43987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco} 44087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco 4418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass AutoDrawLooper { 4428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 44387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco // "rawBounds" is the original bounds of the primitive about to be drawn, unmodified by the 44487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco // paint. It's used to determine the size of the offscreen layer for filters. 44587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco // If null, the clip will be used instead. 4464a8126e7f81384526629b1e21bf89b632ea13cd9reed AutoDrawLooper(SkCanvas* canvas, const SkSurfaceProps& props, const SkPaint& paint, 44778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bool skipLayerForImageFilter = false, 44887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco const SkRect* rawBounds = nullptr) : fOrigPaint(paint) { 4494e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fCanvas = canvas; 45053d9f1cfbd5ddbf57c2f22b9e613ce48e5b2896cfmalita#ifdef SK_SUPPORT_LEGACY_DRAWFILTER 4518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFilter = canvas->getDrawFilter(); 4527765000709dc64eb23be7df47d1f995d1f787115fmalita#else 4537765000709dc64eb23be7df47d1f995d1f787115fmalita fFilter = nullptr; 4547765000709dc64eb23be7df47d1f995d1f787115fmalita#endif 4554a8126e7f81384526629b1e21bf89b632ea13cd9reed fPaint = &fOrigPaint; 4564e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fSaveCount = canvas->getSaveCount(); 4575c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed fTempLayerForImageFilter = false; 4584e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fDone = false; 4598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 460d053ce9c54d4e5937a142278359e5a4cde18095ereed auto simplifiedCF = image_to_color_filter(fOrigPaint); 461dbc3cefb0b624808ddb86d444e6103f216e12fa5reed if (simplifiedCF) { 462dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkPaint* paint = set_if_needed(&fLazyPaintInit, fOrigPaint); 463d053ce9c54d4e5937a142278359e5a4cde18095ereed paint->setColorFilter(std::move(simplifiedCF)); 46496fcdcc219d2a0d3579719b84b28bede76efba64halcanary paint->setImageFilter(nullptr); 465dbc3cefb0b624808ddb86d444e6103f216e12fa5reed fPaint = paint; 466dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 467dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 468dbc3cefb0b624808ddb86d444e6103f216e12fa5reed if (!skipLayerForImageFilter && fPaint->getImageFilter()) { 4695c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed /** 4705c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * We implement ImageFilters for a given draw by creating a layer, then applying the 4715c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * imagefilter to the pixels of that layer (its backing surface/image), and then 4725c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * we call restore() to xfer that layer to the main canvas. 4735c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 4745c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 1. SaveLayer (with a paint containing the current imagefilter and xfermode) 4755c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 2. Generate the src pixels: 4765c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * Remove the imagefilter and the xfermode from the paint that we (AutoDrawLooper) 4775c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * return (fPaint). We then draw the primitive (using srcover) into a cleared 4785c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * buffer/surface. 4795c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 3. Restore the layer created in #1 4805c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * The imagefilter is passed the buffer/surface from the layer (now filled with the 4815c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * src pixels of the primitive). It returns a new "filtered" buffer, which we 4825c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * draw onto the previous layer using the xfermode from the original paint. 4835c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed */ 4848926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkPaint tmp; 485dbc3cefb0b624808ddb86d444e6103f216e12fa5reed tmp.setImageFilter(fPaint->getImageFilter()); 486cfb6bdf767796c950f89985445738d2d8e7f12b0reed tmp.setXfermode(sk_ref_sp(fPaint->getXfermode())); 48787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect storage; 48887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (rawBounds) { 48987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco // Make rawBounds include all paint outsets except for those due to image filters. 49087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco rawBounds = &apply_paint_to_bounds_sans_imagefilter(*fPaint, *rawBounds, &storage); 49187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 492bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed (void)canvas->internalSaveLayer(SkCanvas::SaveLayerRec(rawBounds, &tmp), 49376033be81b82c44fd5d4fdf2672eb22e505da1f0reed SkCanvas::kFullLayer_SaveLayerStrategy); 4945c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed fTempLayerForImageFilter = true; 4955c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed // we remove the imagefilter/xfermode inside doNext() 4968926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 4978926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 49879fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (SkDrawLooper* looper = paint.getLooper()) { 49979fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org void* buffer = fLooperContextAllocator.reserveT<SkDrawLooper::Context>( 50079fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org looper->contextSize()); 50179fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org fLooperContext = looper->createContext(canvas, buffer); 502129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fIsSimple = false; 503129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else { 50496fcdcc219d2a0d3579719b84b28bede76efba64halcanary fLooperContext = nullptr; 505129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // can we be marked as simple? 5065c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed fIsSimple = !fFilter && !fTempLayerForImageFilter; 5078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 508b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 5094a8126e7f81384526629b1e21bf89b632ea13cd9reed uint32_t oldFlags = paint.getFlags(); 5104a8126e7f81384526629b1e21bf89b632ea13cd9reed fNewPaintFlags = filter_paint_flags(props, oldFlags); 5114a8126e7f81384526629b1e21bf89b632ea13cd9reed if (fIsSimple && (fNewPaintFlags != oldFlags)) { 512dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkPaint* paint = set_if_needed(&fLazyPaintInit, fOrigPaint); 5134a8126e7f81384526629b1e21bf89b632ea13cd9reed paint->setFlags(fNewPaintFlags); 5144a8126e7f81384526629b1e21bf89b632ea13cd9reed fPaint = paint; 5154a8126e7f81384526629b1e21bf89b632ea13cd9reed // if we're not simple, doNext() will take care of calling setFlags() 5164a8126e7f81384526629b1e21bf89b632ea13cd9reed } 5178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 51874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 5194e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com ~AutoDrawLooper() { 5205c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed if (fTempLayerForImageFilter) { 5218926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com fCanvas->internalRestore(); 5228926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 5234e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkASSERT(fCanvas->getSaveCount() == fSaveCount); 5248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 52574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 5264e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com const SkPaint& paint() const { 5274e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkASSERT(fPaint); 5284e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return *fPaint; 5294e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 53074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 531129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool next(SkDrawFilter::Type drawType) { 532129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com if (fDone) { 533129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return false; 534129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else if (fIsSimple) { 535129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fDone = true; 536129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return !fPaint->nothingToDraw(); 537129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else { 538129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return this->doNext(drawType); 539129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 540fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 54174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 5428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 543dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkLazyPaint fLazyPaintInit; // base paint storage in case we need to modify it 544dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkLazyPaint fLazyPaintPerLooper; // per-draw-looper storage, so the looper can modify it 5452c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkCanvas* fCanvas; 5462c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint& fOrigPaint; 5472c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkDrawFilter* fFilter; 5482c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint* fPaint; 5492c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org int fSaveCount; 5504a8126e7f81384526629b1e21bf89b632ea13cd9reed uint32_t fNewPaintFlags; 5515c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed bool fTempLayerForImageFilter; 5522c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org bool fDone; 553129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool fIsSimple; 55479fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkDrawLooper::Context* fLooperContext; 55579fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkSmallAllocator<1, 32> fLooperContextAllocator; 556129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com 557129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool doNext(SkDrawFilter::Type drawType); 5588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 5598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 560129ec22cb054592261e001294c430c9dd4e90ff4reed@google.combool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) { 56196fcdcc219d2a0d3579719b84b28bede76efba64halcanary fPaint = nullptr; 562129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com SkASSERT(!fIsSimple); 5635c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed SkASSERT(fLooperContext || fFilter || fTempLayerForImageFilter); 564632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com 565dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkPaint* paint = fLazyPaintPerLooper.set(fLazyPaintInit.isValid() ? 566dbc3cefb0b624808ddb86d444e6103f216e12fa5reed *fLazyPaintInit.get() : fOrigPaint); 5674a8126e7f81384526629b1e21bf89b632ea13cd9reed paint->setFlags(fNewPaintFlags); 5688926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 5695c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed if (fTempLayerForImageFilter) { 57096fcdcc219d2a0d3579719b84b28bede76efba64halcanary paint->setImageFilter(nullptr); 57196fcdcc219d2a0d3579719b84b28bede76efba64halcanary paint->setXfermode(nullptr); 572129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 5738926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 57479fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (fLooperContext && !fLooperContext->next(fCanvas, paint)) { 575129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fDone = true; 576129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return false; 577129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 578129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com if (fFilter) { 579971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com if (!fFilter->filter(paint, drawType)) { 580971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com fDone = true; 581971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com return false; 582971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com } 58396fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == fLooperContext) { 584129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // no looper means we only draw once 585632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com fDone = true; 586632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com } 587129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 588129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fPaint = paint; 5898926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 590129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // if we only came in here for the imagefilter, mark us as done 59179fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (!fLooperContext && !fFilter) { 5924e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fDone = true; 5934e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 5944e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com 595632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com // call this after any possible paint modifiers 596632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com if (fPaint->nothingToDraw()) { 59796fcdcc219d2a0d3579719b84b28bede76efba64halcanary fPaint = nullptr; 5984e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return false; 5994e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 6004e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return true; 6014e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com} 6024e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com 6038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////// macros to place around the internal draw calls ////////////////// 6048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 605262a71b7f95ce98ff3dd8dba845afbd724470903reed#define LOOPER_BEGIN_DRAWBITMAP(paint, skipLayerForFilter, bounds) \ 606262a71b7f95ce98ff3dd8dba845afbd724470903reed this->predrawNotify(); \ 607262a71b7f95ce98ff3dd8dba845afbd724470903reed AutoDrawLooper looper(this, fProps, paint, skipLayerForFilter, bounds); \ 608262a71b7f95ce98ff3dd8dba845afbd724470903reed while (looper.next(SkDrawFilter::kBitmap_Type)) { \ 609262a71b7f95ce98ff3dd8dba845afbd724470903reed SkDrawIter iter(this); 610262a71b7f95ce98ff3dd8dba845afbd724470903reed 611262a71b7f95ce98ff3dd8dba845afbd724470903reed 6128926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com#define LOOPER_BEGIN_DRAWDEVICE(paint, type) \ 61397af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com this->predrawNotify(); \ 6144a8126e7f81384526629b1e21bf89b632ea13cd9reed AutoDrawLooper looper(this, fProps, paint, true); \ 6158926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com while (looper.next(type)) { \ 6168926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkDrawIter iter(this); 6178926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 61878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org#define LOOPER_BEGIN(paint, type, bounds) \ 61997af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com this->predrawNotify(); \ 6204a8126e7f81384526629b1e21bf89b632ea13cd9reed AutoDrawLooper looper(this, fProps, paint, false, bounds); \ 6214e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com while (looper.next(type)) { \ 6228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDrawIter iter(this); 6234b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 624c83a29759a5c2966da5ab973e4fd90763e4c962breed#define LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, type, bounds, auxOpaque) \ 625c83a29759a5c2966da5ab973e4fd90763e4c962breed this->predrawNotify(bounds, &paint, auxOpaque); \ 626c83a29759a5c2966da5ab973e4fd90763e4c962breed AutoDrawLooper looper(this, fProps, paint, false, bounds); \ 627c83a29759a5c2966da5ab973e4fd90763e4c962breed while (looper.next(type)) { \ 628c83a29759a5c2966da5ab973e4fd90763e4c962breed SkDrawIter iter(this); 629c83a29759a5c2966da5ab973e4fd90763e4c962breed 6304e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com#define LOOPER_END } 6318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////// 6338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 634feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtkleinvoid SkCanvas::resetForNextPicture(const SkIRect& bounds) { 635feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein this->restoreToCount(1); 636feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fCachedLocalClipBounds.setEmpty(); 637feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fCachedLocalClipBoundsDirty = true; 638feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fClipStack->reset(); 639feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fMCRec->reset(bounds); 640feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 641feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein // We're peering through a lot of structs here. Only at this scope do we 642feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein // know that the device is an SkBitmapDevice (really an SkNoPixelsBitmapDevice). 643feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein static_cast<SkBitmapDevice*>(fMCRec->fLayer->fDevice)->setNewSize(bounds.size()); 644feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein} 645feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 646d954498c01ccf0417feacf89e45d0c62a06a813breedSkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) { 64742b73eb00367c8315974b1c374308d20efa78897reed if (device && device->forceConservativeRasterClip()) { 64842b73eb00367c8315974b1c374308d20efa78897reed flags = InitFlags(flags | kConservativeRasterClip_InitFlag); 64942b73eb00367c8315974b1c374308d20efa78897reed } 65042b73eb00367c8315974b1c374308d20efa78897reed // Since init() is only called once by our constructors, it is safe to perform this 65142b73eb00367c8315974b1c374308d20efa78897reed // const-cast. 65242b73eb00367c8315974b1c374308d20efa78897reed *const_cast<bool*>(&fConservativeRasterClip) = SkToBool(flags & kConservativeRasterClip_InitFlag); 65342b73eb00367c8315974b1c374308d20efa78897reed 654c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBounds.setEmpty(); 655c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 6568f0a7b8e7334187a5d7d5ab7fde5a3c3009555f5caryclark@google.com fAllowSoftClip = true; 65745a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com fAllowSimplifyClip = false; 658f92c86642a1875da54d54b447f006cb9dfbbb35creed fDeviceCMDirty = true; 6592ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount = 1; 66096fcdcc219d2a0d3579719b84b28bede76efba64halcanary fMetaData = nullptr; 6618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 662385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary fClipStack.reset(new SkClipStack); 663687fa1c745febb57f42b0d5f03d7c1f4be2530careed 6648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = (MCRec*)fMCStack.push_back(); 665d954498c01ccf0417feacf89e45d0c62a06a813breed new (fMCRec) MCRec(fConservativeRasterClip); 6668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 667a499f905e9340e4935447f2562fd92e8853382b1reed SkASSERT(sizeof(DeviceCM) <= sizeof(fDeviceCMStorage)); 668a499f905e9340e4935447f2562fd92e8853382b1reed fMCRec->fLayer = (DeviceCM*)fDeviceCMStorage; 6698c30a8196dd5903d2d23b4d0a5dc888e802bf698reed new (fDeviceCMStorage) DeviceCM(nullptr, nullptr, nullptr, fConservativeRasterClip, false, 6708c30a8196dd5903d2d23b4d0a5dc888e802bf698reed fMCRec->fMatrix); 671b679ca8926a832274b14fdb512f88f64b61d32eareed 6728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fTopLayer = fMCRec->fLayer; 6738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 67496fcdcc219d2a0d3579719b84b28bede76efba64halcanary fSurfaceBase = nullptr; 675f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 676f92c86642a1875da54d54b447f006cb9dfbbb35creed if (device) { 677efbffedd68636e94d4379e84a2585bce80f6fb8frobertphillips // The root device and the canvas should always have the same pixel geometry 678efbffedd68636e94d4379e84a2585bce80f6fb8frobertphillips SkASSERT(fProps.pixelGeometry() == device->surfaceProps().pixelGeometry()); 679f92c86642a1875da54d54b447f006cb9dfbbb35creed device->onAttachToCanvas(this); 680f92c86642a1875da54d54b447f006cb9dfbbb35creed fMCRec->fLayer->fDevice = SkRef(device); 68178e276889795454891cbba48ab11927968114953reed fMCRec->fRasterClip.setRect(device->getGlobalBounds()); 682f92c86642a1875da54d54b447f006cb9dfbbb35creed } 683f92c86642a1875da54d54b447f006cb9dfbbb35creed return device; 6848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 686cde92111d50a96b6d0f3e166fbac7c9bc6eca349reed@google.comSkCanvas::SkCanvas() 687e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 6884a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 68942b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 690e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org{ 6918d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org inc_canvas(); 692ba124485687130183643994f1b4b68d629fbbebaskia.committer@gmail.com 69396fcdcc219d2a0d3579719b84b28bede76efba64halcanary this->init(nullptr, kDefault_InitFlags); 6948d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org} 6958d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org 696d954498c01ccf0417feacf89e45d0c62a06a813breedstatic SkBitmap make_nopixels(int width, int height) { 697d954498c01ccf0417feacf89e45d0c62a06a813breed SkBitmap bitmap; 698d954498c01ccf0417feacf89e45d0c62a06a813breed bitmap.setInfo(SkImageInfo::MakeUnknown(width, height)); 699d954498c01ccf0417feacf89e45d0c62a06a813breed return bitmap; 700d954498c01ccf0417feacf89e45d0c62a06a813breed} 701d954498c01ccf0417feacf89e45d0c62a06a813breed 702d954498c01ccf0417feacf89e45d0c62a06a813breedclass SkNoPixelsBitmapDevice : public SkBitmapDevice { 703d954498c01ccf0417feacf89e45d0c62a06a813breedpublic: 704fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips SkNoPixelsBitmapDevice(const SkIRect& bounds, const SkSurfaceProps& surfaceProps) 705fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips : INHERITED(make_nopixels(bounds.width(), bounds.height()), surfaceProps) 70678e276889795454891cbba48ab11927968114953reed { 70778e276889795454891cbba48ab11927968114953reed this->setOrigin(bounds.x(), bounds.y()); 70878e276889795454891cbba48ab11927968114953reed } 709d954498c01ccf0417feacf89e45d0c62a06a813breed 710d954498c01ccf0417feacf89e45d0c62a06a813breedprivate: 711b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 712d954498c01ccf0417feacf89e45d0c62a06a813breed typedef SkBitmapDevice INHERITED; 713d954498c01ccf0417feacf89e45d0c62a06a813breed}; 714d954498c01ccf0417feacf89e45d0c62a06a813breed 71596a857ef5a40b3d0751ec9ebaaa96d9f20b82b21reedSkCanvas::SkCanvas(int width, int height, const SkSurfaceProps* props) 716e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 71796a857ef5a40b3d0751ec9ebaaa96d9f20b82b21reed , fProps(SkSurfacePropsCopyOrDefault(props)) 71842b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 719e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org{ 720e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org inc_canvas(); 721b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 722385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary this->init(new SkNoPixelsBitmapDevice(SkIRect::MakeWH(width, height), fProps), 723385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary kDefault_InitFlags)->unref(); 724d954498c01ccf0417feacf89e45d0c62a06a813breed} 725e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org 72678e276889795454891cbba48ab11927968114953reedSkCanvas::SkCanvas(const SkIRect& bounds, InitFlags flags) 727d954498c01ccf0417feacf89e45d0c62a06a813breed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7284a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 72942b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 730d954498c01ccf0417feacf89e45d0c62a06a813breed{ 731d954498c01ccf0417feacf89e45d0c62a06a813breed inc_canvas(); 732b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 733385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary this->init(new SkNoPixelsBitmapDevice(bounds, fProps), flags)->unref(); 73427a5e656c3d6ef22f9cb34de18e1b960da3aa241reed} 7358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 736d954498c01ccf0417feacf89e45d0c62a06a813breedSkCanvas::SkCanvas(SkBaseDevice* device) 737d954498c01ccf0417feacf89e45d0c62a06a813breed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7387b05ff11ebc51f3f3abd1c1756337a04f563537erobertphillips , fProps(device->surfaceProps()) 73942b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 740d954498c01ccf0417feacf89e45d0c62a06a813breed{ 741d954498c01ccf0417feacf89e45d0c62a06a813breed inc_canvas(); 742b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 743d954498c01ccf0417feacf89e45d0c62a06a813breed this->init(device, kDefault_InitFlags); 7448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 746fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillipsSkCanvas::SkCanvas(SkBaseDevice* device, InitFlags flags) 747fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7487b05ff11ebc51f3f3abd1c1756337a04f563537erobertphillips , fProps(device->surfaceProps()) 74942b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 750fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips{ 751fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips inc_canvas(); 752fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips 753fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips this->init(device, flags); 754fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips} 755fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips 7564a8126e7f81384526629b1e21bf89b632ea13cd9reedSkCanvas::SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props) 7573716fd067a5621bb94a6cb08d72afec8bf3acedareed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7584a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(props) 75942b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 7603716fd067a5621bb94a6cb08d72afec8bf3acedareed{ 7613716fd067a5621bb94a6cb08d72afec8bf3acedareed inc_canvas(); 762b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 763385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary SkAutoTUnref<SkBaseDevice> device(new SkBitmapDevice(bitmap, fProps)); 7644a8126e7f81384526629b1e21bf89b632ea13cd9reed this->init(device, kDefault_InitFlags); 7654a8126e7f81384526629b1e21bf89b632ea13cd9reed} 76629c857d0f3a1cb837f73406eeb6ba9771879b5e7reed 7674a8126e7f81384526629b1e21bf89b632ea13cd9reedSkCanvas::SkCanvas(const SkBitmap& bitmap) 7684a8126e7f81384526629b1e21bf89b632ea13cd9reed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7694a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 77042b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 7714a8126e7f81384526629b1e21bf89b632ea13cd9reed{ 7724a8126e7f81384526629b1e21bf89b632ea13cd9reed inc_canvas(); 773b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 774385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary SkAutoTUnref<SkBaseDevice> device(new SkBitmapDevice(bitmap, fProps)); 7754a8126e7f81384526629b1e21bf89b632ea13cd9reed this->init(device, kDefault_InitFlags); 7768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::~SkCanvas() { 7798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // free up the contents of our deque 7808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->restoreToCount(1); // restore everything but the last 7817c2029367cea5479fa3b74fb0ca2b0297b42b709reed@google.com 7828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->internalRestore(); // restore the last, since we're going away 7838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 784385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete fMetaData; 785b70ae310bbdaa1b26786773aabce5548c1f48563vandebo@chromium.org 7868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dec_canvas(); 7878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 78953d9f1cfbd5ddbf57c2f22b9e613ce48e5b2896cfmalita#ifdef SK_SUPPORT_LEGACY_DRAWFILTER 7908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDrawFilter* SkCanvas::getDrawFilter() const { 7918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fMCRec->fFilter; 7928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDrawFilter* SkCanvas::setDrawFilter(SkDrawFilter* filter) { 79551985e3f5e608d369e52832b7ce489d85d402422reed this->checkForDeferredSave(); 7968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fMCRec->fFilter, filter); 7978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return filter; 7988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7997765000709dc64eb23be7df47d1f995d1f787115fmalita#endif 8008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 80174bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.orgSkMetaData& SkCanvas::getMetaData() { 80274bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org // metadata users are rare, so we lazily allocate it. If that changes we 80374bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org // can decide to just make it a field in the device (rather than a ptr) 80496fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == fMetaData) { 80574bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org fMetaData = new SkMetaData; 80674bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org } 80774bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org return *fMetaData; 80874bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org} 80974bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org 8108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 8118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 812bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.orgvoid SkCanvas::flush() { 8131f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* device = this->getDevice(); 814bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org if (device) { 815bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org device->flush(); 816bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org } 817bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org} 818bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org 819afc7cce5d68663934128d76963cd501f771d71desenorblancoSkISize SkCanvas::getBaseLayerSize() const { 820afc7cce5d68663934128d76963cd501f771d71desenorblanco SkBaseDevice* d = this->getDevice(); 8214ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com return d ? SkISize::Make(d->width(), d->height()) : SkISize::Make(0, 0); 8224ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com} 8234ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com 824afc7cce5d68663934128d76963cd501f771d71desenorblancoSkIRect SkCanvas::getTopLayerBounds() const { 8254ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com SkBaseDevice* d = this->getTopDevice(); 826afc7cce5d68663934128d76963cd501f771d71desenorblanco if (!d) { 827afc7cce5d68663934128d76963cd501f771d71desenorblanco return SkIRect::MakeEmpty(); 828afc7cce5d68663934128d76963cd501f771d71desenorblanco } 829afc7cce5d68663934128d76963cd501f771d71desenorblanco return SkIRect::MakeXYWH(d->getOrigin().x(), d->getOrigin().y(), d->width(), d->height()); 830210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com} 831210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com 8321f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::getDevice() const { 8338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // return root device 834c029062a0312fb747fb6c2677983aba51795c580robertphillips@google.com MCRec* rec = (MCRec*) fMCStack.front(); 8358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(rec && rec->fLayer); 8368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return rec->fLayer->fDevice; 8378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8391f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::getTopDevice(bool updateMatrixClip) const { 8400b53d59a24f667350b4282f88470713902409030reed@google.com if (updateMatrixClip) { 8410b53d59a24f667350b4282f88470713902409030reed@google.com const_cast<SkCanvas*>(this)->updateDeviceCMCache(); 8420b53d59a24f667350b4282f88470713902409030reed@google.com } 8439266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com return fMCRec->fTopLayer->fDevice; 8449266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com} 8459266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com 846a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.orgbool SkCanvas::readPixels(SkBitmap* bitmap, int x, int y) { 847a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (kUnknown_SkColorType == bitmap->colorType() || bitmap->getTexture()) { 848a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 849a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 850a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 851a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bool weAllocated = false; 85296fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == bitmap->pixelRef()) { 853848250415eddc54075f7eb8795e8db79e749c6abreed if (!bitmap->tryAllocPixels()) { 854a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 855a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 856a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org weAllocated = true; 857a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 858a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 859cf01e31df6bbda270dca2ee3b4967caf51e465dcreed SkAutoPixmapUnlock unlocker; 860cf01e31df6bbda270dca2ee3b4967caf51e465dcreed if (bitmap->requestLock(&unlocker)) { 861cf01e31df6bbda270dca2ee3b4967caf51e465dcreed const SkPixmap& pm = unlocker.pixmap(); 862cf01e31df6bbda270dca2ee3b4967caf51e465dcreed if (this->readPixels(pm.info(), pm.writable_addr(), pm.rowBytes(), x, y)) { 863cf01e31df6bbda270dca2ee3b4967caf51e465dcreed return true; 864cf01e31df6bbda270dca2ee3b4967caf51e465dcreed } 865a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 866a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 867a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (weAllocated) { 86896fcdcc219d2a0d3579719b84b28bede76efba64halcanary bitmap->setPixelRef(nullptr); 869a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 870a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 871a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org} 87251df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 873c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.combool SkCanvas::readPixels(const SkIRect& srcRect, SkBitmap* bitmap) { 874a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkIRect r = srcRect; 875a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 876a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!r.intersect(0, 0, size.width(), size.height())) { 877a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bitmap->reset(); 878ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com return false; 879ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com } 88074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 881848250415eddc54075f7eb8795e8db79e749c6abreed if (!bitmap->tryAllocN32Pixels(r.width(), r.height())) { 882a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org // bitmap will already be reset. 883a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 884a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 885a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!this->readPixels(bitmap->info(), bitmap->getPixels(), bitmap->rowBytes(), r.x(), r.y())) { 886a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bitmap->reset(); 887daba14b7d4fc96b915c45d82713b22729c0d0f37bsalomon@google.com return false; 888c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } 889a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return true; 890a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org} 891c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 89296472deea70169396b8e1f576e470138f55fdb1freedbool SkCanvas::readPixels(const SkImageInfo& dstInfo, void* dstP, size_t rowBytes, int x, int y) { 893a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkBaseDevice* device = this->getDevice(); 894a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!device) { 895a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 896a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 897a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 898f0f14113431ace669f278fdd97b50950f2cf4c80mtklein 89996472deea70169396b8e1f576e470138f55fdb1freed SkReadPixelsRec rec(dstInfo, dstP, rowBytes, x, y); 90096472deea70169396b8e1f576e470138f55fdb1freed if (!rec.trim(size.width(), size.height())) { 901a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 902a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 903db0c8753775774aa3f67114491e26ac1be32f38eskia.committer@gmail.com 904a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org // The device can assert that the requested area is always contained in its bounds 90596472deea70169396b8e1f576e470138f55fdb1freed return device->readPixels(rec.fInfo, rec.fPixels, rec.fRowBytes, rec.fX, rec.fY); 90651df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com} 90751df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 9084cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgbool SkCanvas::writePixels(const SkBitmap& bitmap, int x, int y) { 9094cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (bitmap.getTexture()) { 9104cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 9114cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 912cf01e31df6bbda270dca2ee3b4967caf51e465dcreed 913cf01e31df6bbda270dca2ee3b4967caf51e465dcreed SkAutoPixmapUnlock unlocker; 914cf01e31df6bbda270dca2ee3b4967caf51e465dcreed if (bitmap.requestLock(&unlocker)) { 915cf01e31df6bbda270dca2ee3b4967caf51e465dcreed const SkPixmap& pm = unlocker.pixmap(); 916cf01e31df6bbda270dca2ee3b4967caf51e465dcreed return this->writePixels(pm.info(), pm.addr(), pm.rowBytes(), x, y); 9174cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 9184cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 9194cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org} 9204cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 9214cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgbool SkCanvas::writePixels(const SkImageInfo& origInfo, const void* pixels, size_t rowBytes, 9224cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org int x, int y) { 9234cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org switch (origInfo.colorType()) { 9244cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org case kUnknown_SkColorType: 9254cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org case kIndex_8_SkColorType: 9264cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 9274cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org default: 9284cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org break; 9294cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 93096fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == pixels || rowBytes < origInfo.minRowBytes()) { 9314cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 9324cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 9334cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 9344cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 9354cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org SkIRect target = SkIRect::MakeXYWH(x, y, origInfo.width(), origInfo.height()); 9364cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (!target.intersect(0, 0, size.width(), size.height())) { 9374cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 9384cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 9394cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 9404cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org SkBaseDevice* device = this->getDevice(); 9414cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (!device) { 9424cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 9434cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 9444cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 9454cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // the intersect may have shrunk info's logical size 946e5ea500d4714a7d84de2bf913e81be3b65d2de68reed const SkImageInfo info = origInfo.makeWH(target.width(), target.height()); 9474cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 9484cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // if x or y are negative, then we have to adjust pixels 9494cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (x > 0) { 9504cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org x = 0; 9514cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 9524cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (y > 0) { 9534cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org y = 0; 9544cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 9554cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // here x,y are either 0 or negative 9564cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org pixels = ((const char*)pixels - y * rowBytes - x * info.bytesPerPixel()); 9574cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 9584af35f348b2e2f6c428819118eb7a2f2fff53a74reed // Tell our owning surface to bump its generation ID 959c83a29759a5c2966da5ab973e4fd90763e4c962breed const bool completeOverwrite = info.dimensions() == size; 960c83a29759a5c2966da5ab973e4fd90763e4c962breed this->predrawNotify(completeOverwrite); 9614af35f348b2e2f6c428819118eb7a2f2fff53a74reed 9624cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // The device can assert that the requested area is always contained in its bounds 9634ef54f8d72420a521d4aae04ff5cd438810eca7fcommit-bot@chromium.org return device->writePixels(info, pixels, rowBytes, target.x(), target.y()); 9644cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org} 96551df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 9664370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comSkCanvas* SkCanvas::canvasForDrawIter() { 9674370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com return this; 9684370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 9694370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 9708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 9718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::updateDeviceCMCache() { 9738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fDeviceCMDirty) { 9748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& totalMatrix = this->getTotalMatrix(); 9751f836ee096bb988adef4b9757b2629c7afeda36dreed const SkRasterClip& totalClip = fMCRec->fRasterClip; 9768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* layer = fMCRec->fTopLayer; 9774b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 97896fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == layer->fNext) { // only one layer 97996fcdcc219d2a0d3579719b84b28bede76efba64halcanary layer->updateMC(totalMatrix, totalClip, *fClipStack, nullptr); 9808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 981045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com SkRasterClip clip(totalClip); 9828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 983687fa1c745febb57f42b0d5f03d7c1f4be2530careed layer->updateMC(totalMatrix, clip, *fClipStack, &clip); 98496fcdcc219d2a0d3579719b84b28bede76efba64halcanary } while ((layer = layer->fNext) != nullptr); 9858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = false; 9878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 9918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9922ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::checkForDeferredSave() { 9932ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (fMCRec->fDeferredSaveCount > 0) { 9942ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->doSave(); 9952ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 9962ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed} 9972ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed 998f0090cb80ab10a49e511aa5450ae38917fa058d9reedint SkCanvas::getSaveCount() const { 9992ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed#ifdef SK_DEBUG 10002ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed int count = 0; 10012ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkDeque::Iter iter(fMCStack, SkDeque::Iter::kFront_IterStart); 10022ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed for (;;) { 10032ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed const MCRec* rec = (const MCRec*)iter.next(); 10042ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (!rec) { 10052ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed break; 10062ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 10072ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed count += 1 + rec->fDeferredSaveCount; 10082ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 10092ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(count == fSaveCount); 10102ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed#endif 10112ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return fSaveCount; 1012f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 1013f0090cb80ab10a49e511aa5450ae38917fa058d9reed 1014f0090cb80ab10a49e511aa5450ae38917fa058d9reedint SkCanvas::save() { 10152ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount += 1; 10162ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fMCRec->fDeferredSaveCount += 1; 10172ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return this->getSaveCount() - 1; // return our prev value 10182ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed} 10192ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed 10202ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::doSave() { 1021f0090cb80ab10a49e511aa5450ae38917fa058d9reed this->willSave(); 1022a62d32d1e3112c7e5a26c27e5e967d124ef8dd81fmalita 1023a62d32d1e3112c7e5a26c27e5e967d124ef8dd81fmalita SkASSERT(fMCRec->fDeferredSaveCount > 0); 1024a62d32d1e3112c7e5a26c27e5e967d124ef8dd81fmalita fMCRec->fDeferredSaveCount -= 1; 10252ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalSave(); 1026f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 1027f0090cb80ab10a49e511aa5450ae38917fa058d9reed 1028f0090cb80ab10a49e511aa5450ae38917fa058d9reedvoid SkCanvas::restore() { 10292ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (fMCRec->fDeferredSaveCount > 0) { 10302ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(fSaveCount > 1); 10312ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount -= 1; 10322ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fMCRec->fDeferredSaveCount -= 1; 10332ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } else { 10342ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed // check for underflow 10352ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (fMCStack.count() > 1) { 10362ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->willRestore(); 10372ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(fSaveCount > 1); 1038a644116c3375b12c642d1b51ee1e5cf4a22c1f5breed fSaveCount -= 1; 10392ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalRestore(); 10402ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->didRestore(); 10412ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 1042f0090cb80ab10a49e511aa5450ae38917fa058d9reed } 1043f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 1044f0090cb80ab10a49e511aa5450ae38917fa058d9reed 1045f0090cb80ab10a49e511aa5450ae38917fa058d9reedvoid SkCanvas::restoreToCount(int count) { 1046f0090cb80ab10a49e511aa5450ae38917fa058d9reed // sanity check 1047f0090cb80ab10a49e511aa5450ae38917fa058d9reed if (count < 1) { 1048f0090cb80ab10a49e511aa5450ae38917fa058d9reed count = 1; 1049f0090cb80ab10a49e511aa5450ae38917fa058d9reed } 1050f0f14113431ace669f278fdd97b50950f2cf4c80mtklein 1051f0090cb80ab10a49e511aa5450ae38917fa058d9reed int n = this->getSaveCount() - count; 1052f0090cb80ab10a49e511aa5450ae38917fa058d9reed for (int i = 0; i < n; ++i) { 1053f0090cb80ab10a49e511aa5450ae38917fa058d9reed this->restore(); 1054f0090cb80ab10a49e511aa5450ae38917fa058d9reed } 1055f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 1056f0090cb80ab10a49e511aa5450ae38917fa058d9reed 10572ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::internalSave() { 10588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com MCRec* newTop = (MCRec*)fMCStack.push_back(); 1059d954498c01ccf0417feacf89e45d0c62a06a813breed new (newTop) MCRec(*fMCRec); // balanced in restore() 10608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = newTop; 10614b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 1062687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->save(); 10638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10654960eeec4a1f2a772654883d7f3615d47bcd5dc3reedbool SkCanvas::BoundsAffectsClip(SaveLayerFlags saveLayerFlags) { 1066b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG 10674960eeec4a1f2a772654883d7f3615d47bcd5dc3reed return !(saveLayerFlags & SkCanvas::kDontClipToLayer_PrivateSaveLayerFlag); 1068b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#else 1069b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com return true; 1070b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#endif 10718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10734960eeec4a1f2a772654883d7f3615d47bcd5dc3reedbool SkCanvas::clipRectBounds(const SkRect* bounds, SaveLayerFlags saveLayerFlags, 10749b3aa54bc9605257c701cf465813f5fb1d7ba39ereed SkIRect* intersection, const SkImageFilter* imageFilter) { 1075bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect clipBounds; 1076bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (!this->getClipDeviceBounds(&clipBounds)) { 1077a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return false; 1078f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 1079c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org 108096e657d0e103b8358a77ecd913f6086929f792b8reed const SkMatrix& ctm = fMCRec->fMatrix; // this->getTotalMatrix() 108196e657d0e103b8358a77ecd913f6086929f792b8reed 1082c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org if (imageFilter) { 1083e5e79840ef38ab1d3f03abcf1b2df66fb9940018senorblanco clipBounds = imageFilter->filterBounds(clipBounds, ctm); 1084db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco if (bounds && !imageFilter->canComputeFastBounds()) { 1085db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco bounds = nullptr; 1086db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco } 1087c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org } 1088bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect ir; 108949f085dddff10473b6ebf832a974288300224e60bsalomon if (bounds) { 10908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 10914b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 109296e657d0e103b8358a77ecd913f6086929f792b8reed ctm.mapRect(&r, *bounds); 10938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.roundOut(&ir); 10948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // early exit if the layer's bounds are clipped out 10958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!ir.intersect(clipBounds)) { 10964960eeec4a1f2a772654883d7f3615d47bcd5dc3reed if (BoundsAffectsClip(saveLayerFlags)) { 10979b3aa54bc9605257c701cf465813f5fb1d7ba39ereed fCachedLocalClipBoundsDirty = true; 10981f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fRasterClip.setEmpty(); 1099bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1100a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return false; 11018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { // no user bounds, so just use the clip 11038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ir = clipBounds; 11048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1105180aec43451dd951fdaae81a92efc710ba093260reed SkASSERT(!ir.isEmpty()); 11068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11074960eeec4a1f2a772654883d7f3615d47bcd5dc3reed if (BoundsAffectsClip(saveLayerFlags)) { 1108180aec43451dd951fdaae81a92efc710ba093260reed // Simplify the current clips since they will be applied properly during restore() 11099b3aa54bc9605257c701cf465813f5fb1d7ba39ereed fCachedLocalClipBoundsDirty = true; 1110687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipDevRect(ir, SkRegion::kReplace_Op); 1111180aec43451dd951fdaae81a92efc710ba093260reed fMCRec->fRasterClip.setRect(ir); 1112a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org } 1113a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 1114a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org if (intersection) { 1115a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org *intersection = ir; 1116a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org } 1117a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return true; 1118a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org} 1119a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 11204960eeec4a1f2a772654883d7f3615d47bcd5dc3reed 11214960eeec4a1f2a772654883d7f3615d47bcd5dc3reedint SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint) { 11224960eeec4a1f2a772654883d7f3615d47bcd5dc3reed return this->saveLayer(SaveLayerRec(bounds, paint, 0)); 1123d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org} 1124d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org 11254960eeec4a1f2a772654883d7f3615d47bcd5dc3reedint SkCanvas::saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPaint* paint) { 11264960eeec4a1f2a772654883d7f3615d47bcd5dc3reed return this->saveLayer(SaveLayerRec(bounds, paint, kPreserveLCDText_SaveLayerFlag)); 11274960eeec4a1f2a772654883d7f3615d47bcd5dc3reed} 11284960eeec4a1f2a772654883d7f3615d47bcd5dc3reed 11294960eeec4a1f2a772654883d7f3615d47bcd5dc3reedint SkCanvas::saveLayer(const SaveLayerRec& origRec) { 11304960eeec4a1f2a772654883d7f3615d47bcd5dc3reed SaveLayerRec rec(origRec); 1131d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed if (gIgnoreSaveLayerBounds) { 11324960eeec4a1f2a772654883d7f3615d47bcd5dc3reed rec.fBounds = nullptr; 1133d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed } 11344960eeec4a1f2a772654883d7f3615d47bcd5dc3reed SaveLayerStrategy strategy = this->getSaveLayerStrategy(rec); 1135a644116c3375b12c642d1b51ee1e5cf4a22c1f5breed fSaveCount += 1; 11364960eeec4a1f2a772654883d7f3615d47bcd5dc3reed this->internalSaveLayer(rec, strategy); 11372ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return this->getSaveCount() - 1; 11388926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com} 11398926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 1140bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areedstatic void draw_filter_into_device(SkBaseDevice* src, const SkImageFilter* filter, 1141bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed SkBaseDevice* dst, const SkMatrix& ctm) { 11427354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips 11437354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips SkBitmap srcBM; 11447354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips 11457354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips#if SK_SUPPORT_GPU 1146175dd9b5e3d7d749738dac743d2ac360b5340187robertphillips // TODO: remove this virtual usage of accessRenderTarget! It is preventing 1147175dd9b5e3d7d749738dac743d2ac360b5340187robertphillips // removal of the virtual on SkBaseDevice. 11487354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips GrRenderTarget* srcRT = src->accessRenderTarget(); 11497354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips if (srcRT && !srcRT->asTexture() && dst->accessRenderTarget()) { 11507354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips // When both the src & the dst are on the gpu but the src doesn't have a texture, 11517354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips // we create a temporary texture for the draw. 11527354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips // TODO: we should actually only copy the portion of the source needed to apply the image 11537354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips // filter 11547354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips GrContext* context = srcRT->getContext(); 11555ec26ae9bfca635ccc98283aad5deda11519d826bsalomon SkAutoTUnref<GrTexture> tex(context->textureProvider()->createTexture(srcRT->desc(), 11565ec26ae9bfca635ccc98283aad5deda11519d826bsalomon SkBudgeted::kYes)); 11577354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips 11587354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips context->copySurface(tex, srcRT); 11597354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips 11607354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips GrWrapTextureInBitmap(tex, src->width(), src->height(), src->isOpaque(), &srcBM); 11617354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips } else 11627354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips#endif 11637354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips { 11647354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips srcBM = src->accessBitmap(false); 11657354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips } 11667354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips 11677354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips SkCanvas c(dst); 11687354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips 11697354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips SkPaint p; 1170372177ee115d46dfb5bfb881a408e6c37ae83678robertphillips p.setImageFilter(filter->makeWithLocalMatrix(ctm)); 1171bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed const SkScalar x = SkIntToScalar(src->getOrigin().x()); 1172bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed const SkScalar y = SkIntToScalar(src->getOrigin().y()); 1173bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed c.drawBitmap(srcBM, x, y, &p); 11747354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips} 117570ee31b2fa127eee6c0cea61cf05508e9d3ca7b1reed 1176129ed1cd6d792f3f6cf563aefa9756fc6308289dreedstatic SkImageInfo make_layer_info(const SkImageInfo& prev, int w, int h, bool isOpaque, 1177129ed1cd6d792f3f6cf563aefa9756fc6308289dreed const SkPaint* paint) { 1178129ed1cd6d792f3f6cf563aefa9756fc6308289dreed // need to force L32 for now if we have an image filter. Once filters support other colortypes 1179129ed1cd6d792f3f6cf563aefa9756fc6308289dreed // e.g. sRGB or F16, we can remove this check 118052ede1d905728cdcaa98db1e4a33724f5a85c62dbrianosman // SRGBTODO: Can we remove this check now? 1181129ed1cd6d792f3f6cf563aefa9756fc6308289dreed const bool hasImageFilter = paint && paint->getImageFilter(); 1182129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 1183129ed1cd6d792f3f6cf563aefa9756fc6308289dreed SkAlphaType alphaType = isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType; 1184129ed1cd6d792f3f6cf563aefa9756fc6308289dreed if ((prev.bytesPerPixel() < 4) || hasImageFilter) { 1185129ed1cd6d792f3f6cf563aefa9756fc6308289dreed // force to L32 1186129ed1cd6d792f3f6cf563aefa9756fc6308289dreed return SkImageInfo::MakeN32(w, h, alphaType); 1187129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } else { 1188129ed1cd6d792f3f6cf563aefa9756fc6308289dreed // keep the same characteristics as the prev 118952ede1d905728cdcaa98db1e4a33724f5a85c62dbrianosman return SkImageInfo::Make(w, h, prev.colorType(), alphaType, sk_ref_sp(prev.colorSpace())); 1190129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 1191129ed1cd6d792f3f6cf563aefa9756fc6308289dreed} 1192129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 11934960eeec4a1f2a772654883d7f3615d47bcd5dc3reedvoid SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy strategy) { 11944960eeec4a1f2a772654883d7f3615d47bcd5dc3reed const SkRect* bounds = rec.fBounds; 11954960eeec4a1f2a772654883d7f3615d47bcd5dc3reed const SkPaint* paint = rec.fPaint; 11964960eeec4a1f2a772654883d7f3615d47bcd5dc3reed SaveLayerFlags saveLayerFlags = rec.fSaveLayerFlags; 11974960eeec4a1f2a772654883d7f3615d47bcd5dc3reed 1198b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG 11994960eeec4a1f2a772654883d7f3615d47bcd5dc3reed saveLayerFlags &= ~kDontClipToLayer_PrivateSaveLayerFlag; 1200b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#endif 1201b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com 12028c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkLazyPaint lazyP; 12038c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkImageFilter* imageFilter = paint ? paint->getImageFilter() : NULL; 12048c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkMatrix stashedMatrix = fMCRec->fMatrix; 12058c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkMatrix remainder; 12068c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkSize scale; 12078c30a8196dd5903d2d23b4d0a5dc888e802bf698reed /* 12088c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * ImageFilters (so far) do not correctly handle matrices (CTM) that contain rotation/skew/etc. 12098c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * but they do handle scaling. To accommodate this, we do the following: 12108c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 12118c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 1. Stash off the current CTM 12128c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 2. Decompose the CTM into SCALE and REMAINDER 12138c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 3. Wack the CTM to be just SCALE, and wrap the imagefilter with a MatrixImageFilter that 12148c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * contains the REMAINDER 12158c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 4. Proceed as usual, allowing the client to draw into the layer (now with a scale-only CTM) 12168c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 5. During restore, we process the MatrixImageFilter, which applies REMAINDER to the output 12178c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * of the original imagefilter, and draw that (via drawSprite) 12188c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 6. Unwack the CTM to its original state (i.e. stashedMatrix) 12198c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 12208c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * Perhaps in the future we could augment #5 to apply REMAINDER as part of the draw (no longer 12218c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * a sprite operation) to avoid the extra buffer/overhead of MatrixImageFilter. 12228c30a8196dd5903d2d23b4d0a5dc888e802bf698reed */ 122396a04f329926099f0002f97883242793ff04f61creed if (imageFilter && !stashedMatrix.isScaleTranslate() && !imageFilter->canHandleComplexCTM() && 12248c30a8196dd5903d2d23b4d0a5dc888e802bf698reed stashedMatrix.decomposeScale(&scale, &remainder)) 12258c30a8196dd5903d2d23b4d0a5dc888e802bf698reed { 12268c30a8196dd5903d2d23b4d0a5dc888e802bf698reed // We will restore the matrix (which we are overwriting here) in restore via fStashedMatrix 12278c30a8196dd5903d2d23b4d0a5dc888e802bf698reed this->internalSetMatrix(SkMatrix::MakeScale(scale.width(), scale.height())); 12288c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkPaint* p = lazyP.set(*paint); 12298c30a8196dd5903d2d23b4d0a5dc888e802bf698reed p->setImageFilter(SkImageFilter::MakeMatrixFilter(remainder, 12308c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkFilterQuality::kLow_SkFilterQuality, 12318c30a8196dd5903d2d23b4d0a5dc888e802bf698reed sk_ref_sp(imageFilter))); 12328c30a8196dd5903d2d23b4d0a5dc888e802bf698reed imageFilter = p->getImageFilter(); 12338c30a8196dd5903d2d23b4d0a5dc888e802bf698reed paint = p; 12348c30a8196dd5903d2d23b4d0a5dc888e802bf698reed } 12358c30a8196dd5903d2d23b4d0a5dc888e802bf698reed 1236a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org // do this before we create the layer. We don't call the public save() since 1237a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org // that would invoke a possibly overridden virtual 12382ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalSave(); 1239a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 1240a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org fDeviceCMDirty = true; 1241a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 1242a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org SkIRect ir; 12438c30a8196dd5903d2d23b4d0a5dc888e802bf698reed if (!this->clipRectBounds(bounds, saveLayerFlags, &ir, imageFilter)) { 12442ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 12458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1247e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy really care about 1248e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org // the clipRectBounds() call above? 1249e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org if (kNoLayer_SaveLayerStrategy == strategy) { 12502ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 1251e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org } 1252e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org 12534960eeec4a1f2a772654883d7f3615d47bcd5dc3reed bool isOpaque = SkToBool(saveLayerFlags & kIsOpaque_SaveLayerFlag); 12548dc0ccb8d33d1af7dd13228509e61fe915bc7705reed SkPixelGeometry geo = fProps.pixelGeometry(); 12558dc0ccb8d33d1af7dd13228509e61fe915bc7705reed if (paint) { 125676033be81b82c44fd5d4fdf2672eb22e505da1f0reed // TODO: perhaps add a query to filters so we might preserve opaqueness... 1257daa57bfd4204f5a7d304c580bcf5ad99d0121e1freed if (paint->getImageFilter() || paint->getColorFilter()) { 125876033be81b82c44fd5d4fdf2672eb22e505da1f0reed isOpaque = false; 12598dc0ccb8d33d1af7dd13228509e61fe915bc7705reed geo = kUnknown_SkPixelGeometry; 1260b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com } 1261b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com } 12628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1263b2db898573e3cdcc8234eebf51961bfc4977ebbcreed SkBaseDevice* device = this->getTopDevice(); 126496fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == device) { 1265b2db898573e3cdcc8234eebf51961bfc4977ebbcreed SkDebugf("Unable to find device for layer."); 12662ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 1267b2db898573e3cdcc8234eebf51961bfc4977ebbcreed } 1268b2db898573e3cdcc8234eebf51961bfc4977ebbcreed 1269129ed1cd6d792f3f6cf563aefa9756fc6308289dreed SkImageInfo info = make_layer_info(device->imageInfo(), ir.width(), ir.height(), isOpaque, 1270129ed1cd6d792f3f6cf563aefa9756fc6308289dreed paint); 1271129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 127261f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed bool forceSpriteOnRestore = false; 127361f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed { 127470ee31b2fa127eee6c0cea61cf05508e9d3ca7b1reed const bool preserveLCDText = kOpaque_SkAlphaType == info.alphaType() || 12754960eeec4a1f2a772654883d7f3615d47bcd5dc3reed (saveLayerFlags & kPreserveLCDText_SaveLayerFlag); 1276daa57bfd4204f5a7d304c580bcf5ad99d0121e1freed const SkBaseDevice::TileUsage usage = SkBaseDevice::kNever_TileUsage; 127770ee31b2fa127eee6c0cea61cf05508e9d3ca7b1reed const SkBaseDevice::CreateInfo createInfo = SkBaseDevice::CreateInfo(info, usage, geo, 127870ee31b2fa127eee6c0cea61cf05508e9d3ca7b1reed preserveLCDText, false); 127961f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed SkBaseDevice* newDev = device->onCreateDevice(createInfo, paint); 128096fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == newDev) { 128161f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed // If onCreateDevice didn't succeed, try raster (e.g. PDF couldn't handle the paint) 12829a53fd7c41554630124522f4b6eedc16912abbb7robertphillips const SkSurfaceProps surfaceProps(fProps.flags(), createInfo.fPixelGeometry); 12839a53fd7c41554630124522f4b6eedc16912abbb7robertphillips newDev = SkBitmapDevice::Create(createInfo.fInfo, surfaceProps); 128496fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == newDev) { 128561f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed SkErrorInternals::SetError(kInternalError_SkError, 128661f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed "Unable to create device for layer."); 128761f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed return; 128861f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed } 128961f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed forceSpriteOnRestore = true; 129061f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed } 129161f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed device = newDev; 1292e25c68402b38ac01dc1ae196ae8a5265b773c5f2bungeman@google.com } 12936f8f292aa768869a9e85c314b124875f57504f2creed@google.com device->setOrigin(ir.fLeft, ir.fTop); 12947354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips 1295bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed if (rec.fBackdrop) { 1296bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed draw_filter_into_device(fMCRec->fTopLayer->fDevice, rec.fBackdrop, device, fMCRec->fMatrix); 12977354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips } 12987354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips 12998c30a8196dd5903d2d23b4d0a5dc888e802bf698reed DeviceCM* layer = new DeviceCM(device, paint, this, fConservativeRasterClip, 13008c30a8196dd5903d2d23b4d0a5dc888e802bf698reed forceSpriteOnRestore, stashedMatrix); 13018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device->unref(); 13028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com layer->fNext = fMCRec->fTopLayer; 13048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fLayer = layer; 13058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fTopLayer = layer; // this field is NOT an owner of layer 13068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1308d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.orgint SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) { 1309bada1885da479d948f065182d6dfa85a1140bda5reed if (0xFF == alpha) { 1310bada1885da479d948f065182d6dfa85a1140bda5reed return this->saveLayer(bounds, nullptr); 1311bada1885da479d948f065182d6dfa85a1140bda5reed } else { 1312bada1885da479d948f065182d6dfa85a1140bda5reed SkPaint tmpPaint; 1313bada1885da479d948f065182d6dfa85a1140bda5reed tmpPaint.setAlpha(alpha); 1314bada1885da479d948f065182d6dfa85a1140bda5reed return this->saveLayer(bounds, &tmpPaint); 1315bada1885da479d948f065182d6dfa85a1140bda5reed } 1316d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org} 1317d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org 13188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::internalRestore() { 13198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fMCStack.count() != 0); 13208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1322c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 13238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1324687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->restore(); 13256c157640c27ee2ed6f9a484d21691b7b19dfecdecommit-bot@chromium.org 132688edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com // reserve our layer (if any) 13278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* layer = fMCRec->fLayer; // may be null 13288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now detach it from fMCRec so we can pop(). Gets freed after its drawn 132996fcdcc219d2a0d3579719b84b28bede76efba64halcanary fMCRec->fLayer = nullptr; 13308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now do the normal restore() 13328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->~MCRec(); // balanced in save() 13338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCStack.pop_back(); 13348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = (MCRec*)fMCStack.back(); 13358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* Time to draw the layer's offscreen. We can't call the public drawSprite, 13378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com since if we're being recorded, we don't want to record this (the 13388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com recorder will have already recorded the restore). 13398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 134049f085dddff10473b6ebf832a974288300224e60bsalomon if (layer) { 13418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (layer->fNext) { 13426f8f292aa768869a9e85c314b124875f57504f2creed@google.com const SkIPoint& origin = layer->fDevice->getOrigin(); 13438926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(), 134461f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed layer->fPaint, layer->fDeviceIsBitmapDevice); 13458c30a8196dd5903d2d23b4d0a5dc888e802bf698reed // restore what we smashed in internalSaveLayer 13468c30a8196dd5903d2d23b4d0a5dc888e802bf698reed fMCRec->fMatrix = layer->fStashedMatrix; 13478926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com // reset this, since internalDrawDevice will have set it to true 13488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1349385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete layer; 1350b679ca8926a832274b14fdb512f88f64b61d32eareed } else { 1351b679ca8926a832274b14fdb512f88f64b61d32eareed // we're at the root 1352a499f905e9340e4935447f2562fd92e8853382b1reed SkASSERT(layer == (void*)fDeviceCMStorage); 1353b679ca8926a832274b14fdb512f88f64b61d32eareed layer->~DeviceCM(); 13548c30a8196dd5903d2d23b4d0a5dc888e802bf698reed // no need to update fMCRec, 'cause we're killing the canvas 13558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 135688edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 13578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1359e8f3062a36d3682f4019309a32b5b84dc9eddf8creedsk_sp<SkSurface> SkCanvas::makeSurface(const SkImageInfo& info, const SkSurfaceProps* props) { 136096fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == props) { 13614a8126e7f81384526629b1e21bf89b632ea13cd9reed props = &fProps; 13624a8126e7f81384526629b1e21bf89b632ea13cd9reed } 13634a8126e7f81384526629b1e21bf89b632ea13cd9reed return this->onNewSurface(info, *props); 136476f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com} 136576f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com 1366e8f3062a36d3682f4019309a32b5b84dc9eddf8creedsk_sp<SkSurface> SkCanvas::onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props) { 136776f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com SkBaseDevice* dev = this->getDevice(); 1368e8f3062a36d3682f4019309a32b5b84dc9eddf8creed return dev ? dev->makeSurface(info, props) : nullptr; 136976f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com} 137076f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com 1371c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgSkImageInfo SkCanvas::imageInfo() const { 1372c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkBaseDevice* dev = this->getDevice(); 1373c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (dev) { 1374c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return dev->imageInfo(); 1375c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } else { 1376900ecf2f1579d42c9d2959831787af0346320f86reed@google.com return SkImageInfo::MakeUnknown(0, 0); 1377c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1378c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1379c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1380898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosmanbool SkCanvas::getProps(SkSurfaceProps* props) const { 1381898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman SkBaseDevice* dev = this->getDevice(); 1382898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman if (dev) { 1383898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman if (props) { 1384898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman *props = fProps; 1385898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman } 1386898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman return true; 1387898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman } else { 1388898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman return false; 1389898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman } 1390898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman} 1391898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman 13926ceeebd37a43d879c120b6ba100ae1febdd67a18reed#ifdef SK_SUPPORT_LEGACY_PEEKPIXELS_PARMS 1393c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgconst void* SkCanvas::peekPixels(SkImageInfo* info, size_t* rowBytes) { 1394884e97cb04db7ed053a866567ee9c6e4c01f993areed SkPixmap pmap; 13956ceeebd37a43d879c120b6ba100ae1febdd67a18reed if (this->peekPixels(&pmap)) { 13966ceeebd37a43d879c120b6ba100ae1febdd67a18reed if (info) { 13976ceeebd37a43d879c120b6ba100ae1febdd67a18reed *info = pmap.info(); 13986ceeebd37a43d879c120b6ba100ae1febdd67a18reed } 13996ceeebd37a43d879c120b6ba100ae1febdd67a18reed if (rowBytes) { 14006ceeebd37a43d879c120b6ba100ae1febdd67a18reed *rowBytes = pmap.rowBytes(); 14016ceeebd37a43d879c120b6ba100ae1febdd67a18reed } 14026ceeebd37a43d879c120b6ba100ae1febdd67a18reed return pmap.addr(); 1403884e97cb04db7ed053a866567ee9c6e4c01f993areed } 14046ceeebd37a43d879c120b6ba100ae1febdd67a18reed return nullptr; 14056ceeebd37a43d879c120b6ba100ae1febdd67a18reed} 14066ceeebd37a43d879c120b6ba100ae1febdd67a18reed#endif 14076ceeebd37a43d879c120b6ba100ae1febdd67a18reed 14086ceeebd37a43d879c120b6ba100ae1febdd67a18reedbool SkCanvas::peekPixels(SkPixmap* pmap) { 14096ceeebd37a43d879c120b6ba100ae1febdd67a18reed return this->onPeekPixels(pmap); 1410c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1411c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1412884e97cb04db7ed053a866567ee9c6e4c01f993areedbool SkCanvas::onPeekPixels(SkPixmap* pmap) { 1413c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkBaseDevice* dev = this->getDevice(); 1414884e97cb04db7ed053a866567ee9c6e4c01f993areed return dev && dev->peekPixels(pmap); 1415c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1416c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 14176b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.orgvoid* SkCanvas::accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin) { 1418884e97cb04db7ed053a866567ee9c6e4c01f993areed SkPixmap pmap; 1419884e97cb04db7ed053a866567ee9c6e4c01f993areed if (!this->onAccessTopLayerPixels(&pmap)) { 142096fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 1421884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1422884e97cb04db7ed053a866567ee9c6e4c01f993areed if (info) { 1423884e97cb04db7ed053a866567ee9c6e4c01f993areed *info = pmap.info(); 1424884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1425884e97cb04db7ed053a866567ee9c6e4c01f993areed if (rowBytes) { 1426884e97cb04db7ed053a866567ee9c6e4c01f993areed *rowBytes = pmap.rowBytes(); 1427884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1428884e97cb04db7ed053a866567ee9c6e4c01f993areed if (origin) { 14296b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org *origin = this->getTopDevice(false)->getOrigin(); 14306b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org } 1431884e97cb04db7ed053a866567ee9c6e4c01f993areed return pmap.writable_addr(); 14329c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 14339c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1434884e97cb04db7ed053a866567ee9c6e4c01f993areedbool SkCanvas::onAccessTopLayerPixels(SkPixmap* pmap) { 14359c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com SkBaseDevice* dev = this->getTopDevice(); 1436884e97cb04db7ed053a866567ee9c6e4c01f993areed return dev && dev->accessPixels(pmap); 14379c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 14389c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1439520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org///////////////////////////////////////////////////////////////////////////// 14408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14411f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comvoid SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, 144261f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed const SkPaint* paint, bool deviceIsBitmapDevice) { 14438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint tmp; 144496fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 14458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint = &tmp; 14468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 14474b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 14488926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com LOOPER_BEGIN_DRAWDEVICE(*paint, SkDrawFilter::kBitmap_Type) 14498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 14501f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* dstDev = iter.fDevice; 145176dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com paint = &looper.paint(); 145276dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkImageFilter* filter = paint->getImageFilter(); 145376dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkIPoint pos = { x - iter.getX(), y - iter.getY() }; 1454f35566e8a2497cd7c7bcfeee00c507b3e8ba1587senorblanco if (filter) { 14554418dbac3386f26c8da62ab242be9c178961eb18robertphillips const SkBitmap& srcBM = srcDev->accessBitmap(false); 14561eca11659e217eca138c230525a52deb3d52b2d3reed dstDev->drawSpriteWithFilter(iter, srcBM, pos.x(), pos.y(), *paint); 145761f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed } else if (deviceIsBitmapDevice) { 14589572a10c9a6a868bbb8f71d7806d0a45f183333freed const SkBitmap& src = static_cast<SkBitmapDevice*>(srcDev)->fBitmap; 145961f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed dstDev->drawSprite(iter, src, pos.x(), pos.y(), *paint); 146076dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } else { 1461b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com dstDev->drawDevice(iter, srcDev, pos.x(), pos.y(), *paint); 146276dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } 14638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 14644e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 14658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 146732704674f64cb6a14356dfebe060cd3484c06cc7reed///////////////////////////////////////////////////////////////////////////// 1468da420b976e61071cfe5de10556b4b23e519091d6reed 146992362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::translate(SkScalar dx, SkScalar dy) { 1470d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1471d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setTranslate(dx, dy); 1472d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 14738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 147592362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::scale(SkScalar sx, SkScalar sy) { 1476d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1477d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setScale(sx, sy); 1478d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 14798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 148192362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::rotate(SkScalar degrees) { 1482d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1483d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setRotate(degrees); 1484d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 14858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 148792362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::skew(SkScalar sx, SkScalar sy) { 1488d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1489d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setSkew(sx, sy); 1490d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 149144c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org} 149244c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 149392362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::concat(const SkMatrix& matrix) { 1494d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org if (matrix.isIdentity()) { 1495d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org return; 1496d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org } 1497d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org 14982ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 14998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1500c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 15011f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix.preConcat(matrix); 150244c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 150344c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org this->didConcat(matrix); 150444c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org} 150544c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 15068c30a8196dd5903d2d23b4d0a5dc888e802bf698reedvoid SkCanvas::internalSetMatrix(const SkMatrix& matrix) { 15078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1508c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 15091f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix = matrix; 15108c30a8196dd5903d2d23b4d0a5dc888e802bf698reed} 15118c30a8196dd5903d2d23b4d0a5dc888e802bf698reed 15128c30a8196dd5903d2d23b4d0a5dc888e802bf698reedvoid SkCanvas::setMatrix(const SkMatrix& matrix) { 15138c30a8196dd5903d2d23b4d0a5dc888e802bf698reed this->checkForDeferredSave(); 15148c30a8196dd5903d2d23b4d0a5dc888e802bf698reed this->internalSetMatrix(matrix); 151544c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org this->didSetMatrix(matrix); 15168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 15178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 15188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::resetMatrix() { 15198c30a8196dd5903d2d23b4d0a5dc888e802bf698reed this->setMatrix(SkMatrix::I()); 15208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 15218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 15228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 15238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1524759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { 15252ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 15268f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 15278f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(rect, op, edgeStyle); 15288f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 15298f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 15308f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 1531da17f758442f16747af39f8fbaed9c097048519creed@google.com#ifdef SK_ENABLE_CLIP_QUICKREJECT 1532da17f758442f16747af39f8fbaed9c097048519creed@google.com if (SkRegion::kIntersect_Op == op) { 15331f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fRasterClip.isEmpty()) { 1534da17f758442f16747af39f8fbaed9c097048519creed@google.com return false; 1535da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1536da17f758442f16747af39f8fbaed9c097048519creed@google.com 15373b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(rect)) { 1538da17f758442f16747af39f8fbaed9c097048519creed@google.com fDeviceCMDirty = true; 1539c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 1540da17f758442f16747af39f8fbaed9c097048519creed@google.com 1541687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipEmpty(); 15421f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.setEmpty(); 1543da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1544da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1545da17f758442f16747af39f8fbaed9c097048519creed@google.com#endif 1546da17f758442f16747af39f8fbaed9c097048519creed@google.com 1547ac8cabd729c75fdf774c0701b6ea7fd3ea5b9382bsalomon if (!fAllowSoftClip) { 1548ac8cabd729c75fdf774c0701b6ea7fd3ea5b9382bsalomon edgeStyle = kHard_ClipEdgeStyle; 1549ac8cabd729c75fdf774c0701b6ea7fd3ea5b9382bsalomon } 1550ac8cabd729c75fdf774c0701b6ea7fd3ea5b9382bsalomon 1551c64eff55049b1192052b791549a32a03be1c43e3reed const bool rectStaysRect = fMCRec->fMatrix.rectStaysRect(); 1552c64eff55049b1192052b791549a32a03be1c43e3reed SkRect devR; 1553c64eff55049b1192052b791549a32a03be1c43e3reed if (rectStaysRect) { 1554c64eff55049b1192052b791549a32a03be1c43e3reed fMCRec->fMatrix.mapRect(&devR, rect); 1555c64eff55049b1192052b791549a32a03be1c43e3reed } 1556c64eff55049b1192052b791549a32a03be1c43e3reed 1557c64eff55049b1192052b791549a32a03be1c43e3reed // Check if we can quick-accept the clip call (and do nothing) 1558c64eff55049b1192052b791549a32a03be1c43e3reed // 1559c64eff55049b1192052b791549a32a03be1c43e3reed // TODO: investigate if a (conservative) version of this could be done in ::clipRect, 1560c64eff55049b1192052b791549a32a03be1c43e3reed // so that subclasses (like PictureRecording) didn't see unnecessary clips, which in turn 1561c64eff55049b1192052b791549a32a03be1c43e3reed // might allow lazy save/restores to eliminate entire save/restore blocks. 1562c64eff55049b1192052b791549a32a03be1c43e3reed // 1563c64eff55049b1192052b791549a32a03be1c43e3reed if (SkRegion::kIntersect_Op == op && 1564c64eff55049b1192052b791549a32a03be1c43e3reed kHard_ClipEdgeStyle == edgeStyle 1565c64eff55049b1192052b791549a32a03be1c43e3reed && rectStaysRect) 1566c64eff55049b1192052b791549a32a03be1c43e3reed { 1567c64eff55049b1192052b791549a32a03be1c43e3reed if (devR.round().contains(fMCRec->fRasterClip.getBounds())) { 1568c64eff55049b1192052b791549a32a03be1c43e3reed#if 0 1569c64eff55049b1192052b791549a32a03be1c43e3reed SkDebugf("------- ignored clipRect [%g %g %g %g]\n", 1570c64eff55049b1192052b791549a32a03be1c43e3reed rect.left(), rect.top(), rect.right(), rect.bottom()); 1571c64eff55049b1192052b791549a32a03be1c43e3reed#endif 1572c64eff55049b1192052b791549a32a03be1c43e3reed return; 1573c64eff55049b1192052b791549a32a03be1c43e3reed } 1574c64eff55049b1192052b791549a32a03be1c43e3reed } 1575c64eff55049b1192052b791549a32a03be1c43e3reed 1576c64eff55049b1192052b791549a32a03be1c43e3reed AutoValidateClip avc(this); 1577c64eff55049b1192052b791549a32a03be1c43e3reed 1578c64eff55049b1192052b791549a32a03be1c43e3reed fDeviceCMDirty = true; 1579c64eff55049b1192052b791549a32a03be1c43e3reed fCachedLocalClipBoundsDirty = true; 15808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1581c64eff55049b1192052b791549a32a03be1c43e3reed if (rectStaysRect) { 1582c64eff55049b1192052b791549a32a03be1c43e3reed const bool isAA = kSoft_ClipEdgeStyle == edgeStyle; 1583c64eff55049b1192052b791549a32a03be1c43e3reed fClipStack->clipDevRect(devR, op, isAA); 1584afc7cce5d68663934128d76963cd501f771d71desenorblanco fMCRec->fRasterClip.op(devR, this->getTopLayerBounds(), op, isAA); 15858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 1586123671901abfa595d09ca789b487c4bc7c1f7cbcrobertphillips@google.com // since we're rotated or some such thing, we convert the rect to a path 158798de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // and clip against that, since it can handle any matrix. However, to 158898de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // avoid recursion in the case where we are subclassed (e.g. Pictures) 158998de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // we explicitly call "our" version of clipPath. 15908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath path; 15918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 15928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.addRect(rect); 15938f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->SkCanvas::onClipPath(path, op, edgeStyle); 15948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 15958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 15968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1597759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) { 15982ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 15998f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 16004ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (rrect.isRect()) { 16018f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(rrect.getBounds(), op, edgeStyle); 16028f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } else { 16038f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRRect(rrect, op, edgeStyle); 16044ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 16058f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 160614e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 16078f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 160814e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org SkRRect transformedRRect; 16091f836ee096bb988adef4b9757b2629c7afeda36dreed if (rrect.transform(fMCRec->fMatrix, &transformedRRect)) { 161014e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org AutoValidateClip avc(this); 161114e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 161214e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org fDeviceCMDirty = true; 161314e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org fCachedLocalClipBoundsDirty = true; 16148f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!fAllowSoftClip) { 16158f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com edgeStyle = kHard_ClipEdgeStyle; 16168f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 161714e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 1618687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipDevRRect(transformedRRect, op, kSoft_ClipEdgeStyle == edgeStyle); 161914e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 1620afc7cce5d68663934128d76963cd501f771d71desenorblanco fMCRec->fRasterClip.op(transformedRRect, this->getTopLayerBounds(), op, 1621125f19a2964c31a660256132acbce60e8a3e6752robertphillips kSoft_ClipEdgeStyle == edgeStyle); 16228f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com return; 162314e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org } 162414e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 162514e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org SkPath path; 162614e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org path.addRRect(rrect); 162714e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org // call the non-virtual version 16288f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->SkCanvas::onClipPath(path, op, edgeStyle); 16294ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 16304ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 1631759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { 16322ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 16338f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 163439f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips 163539f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips if (!path.isInverseFillType() && fMCRec->fMatrix.rectStaysRect()) { 163639f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips SkRect r; 163739f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips if (path.isRect(&r)) { 163839f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips this->onClipRect(r, op, edgeStyle); 163939f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips return; 164039f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips } 164139f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips SkRRect rrect; 164239f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips if (path.isOval(&r)) { 164339f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips rrect.setOval(r); 164439f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips this->onClipRRect(rrect, op, edgeStyle); 164539f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips return; 164639f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips } 164739f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips if (path.isRRect(&rrect)) { 164839f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips this->onClipRRect(rrect, op, edgeStyle); 164939f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips return; 165039f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips } 16518f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 165239f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips 165339f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips this->onClipPath(path, op, edgeStyle); 16548f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 16558f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 16568f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 1657da17f758442f16747af39f8fbaed9c097048519creed@google.com#ifdef SK_ENABLE_CLIP_QUICKREJECT 1658da17f758442f16747af39f8fbaed9c097048519creed@google.com if (SkRegion::kIntersect_Op == op && !path.isInverseFillType()) { 16591f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fRasterClip.isEmpty()) { 1660da17f758442f16747af39f8fbaed9c097048519creed@google.com return false; 1661da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1662fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 16633b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(path.getBounds())) { 1664da17f758442f16747af39f8fbaed9c097048519creed@google.com fDeviceCMDirty = true; 1665c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 1666fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1667687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipEmpty(); 16681f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.setEmpty(); 1669da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1670da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1671da17f758442f16747af39f8fbaed9c097048519creed@google.com#endif 1672da17f758442f16747af39f8fbaed9c097048519creed@google.com 16735c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com AutoValidateClip avc(this); 16745c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 16758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1676c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 16778f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!fAllowSoftClip) { 16788f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com edgeStyle = kHard_ClipEdgeStyle; 16798f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 16808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath devPath; 16821f836ee096bb988adef4b9757b2629c7afeda36dreed path.transform(fMCRec->fMatrix, &devPath); 16838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1684fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // Check if the transfomation, or the original path itself 1685fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // made us empty. Note this can also happen if we contained NaN 1686fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // values. computing the bounds detects this, and will set our 1687fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // bounds to empty if that is the case. (see SkRect::set(pts, count)) 1688fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com if (devPath.getBounds().isEmpty()) { 1689fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // resetting the path will remove any NaN or other wanky values 1690fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // that might upset our scan converter. 1691fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com devPath.reset(); 1692fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com } 1693fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com 16945c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // if we called path.swap() we could avoid a deep copy of this path 1695687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipDevPath(devPath, op, kSoft_ClipEdgeStyle == edgeStyle); 16965c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 169745a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com if (fAllowSimplifyClip) { 16981a481fe4bf632ed4f76cb337691236fabfd4ab03fmalita bool clipIsAA = getClipStack()->asPath(&devPath); 16991a481fe4bf632ed4f76cb337691236fabfd4ab03fmalita if (clipIsAA) { 17001a481fe4bf632ed4f76cb337691236fabfd4ab03fmalita edgeStyle = kSoft_ClipEdgeStyle; 170145a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com } 17021a481fe4bf632ed4f76cb337691236fabfd4ab03fmalita 170345a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com op = SkRegion::kReplace_Op; 170445a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com } 170545a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com 1706afc7cce5d68663934128d76963cd501f771d71desenorblanco fMCRec->fRasterClip.op(devPath, this->getTopLayerBounds(), op, edgeStyle); 17078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1709759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipRegion(const SkRegion& rgn, SkRegion::Op op) { 17102ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 17118f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRegion(rgn, op); 17128f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 17138f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 17148f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipRegion(const SkRegion& rgn, SkRegion::Op op) { 17155c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com AutoValidateClip avc(this); 17165c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 17178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1718c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 17198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17205c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // todo: signal fClipStack that we have a region, and therefore (I guess) 17215c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // we have to ignore it, and use the region directly? 1722687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipDevRect(rgn.getBounds(), op); 17235c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 17241f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fRasterClip.op(rgn, op); 17258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1727819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com#ifdef SK_DEBUG 1728819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.comvoid SkCanvas::validateClip() const { 1729819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com // construct clipRgn from the clipstack 17301f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com const SkBaseDevice* device = this->getDevice(); 1731ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com if (!device) { 17325c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org SkASSERT(this->isClipEmpty()); 1733ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com return; 1734ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com } 1735ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com 1736819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com SkIRect ir; 1737819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com ir.set(0, 0, device->width(), device->height()); 1738d954498c01ccf0417feacf89e45d0c62a06a813breed SkRasterClip tmpClip(ir, fConservativeRasterClip); 1739819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 1740687fa1c745febb57f42b0d5f03d7c1f4be2530careed SkClipStack::B2TIter iter(*fClipStack); 17418182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const SkClipStack::Element* element; 174296fcdcc219d2a0d3579719b84b28bede76efba64halcanary while ((element = iter.next()) != nullptr) { 17438182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com switch (element->getType()) { 17448182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kRect_Type: 17458182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com element->getRect().round(&ir); 17468182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com tmpClip.op(ir, element->getOp()); 17478182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 17488182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kEmpty_Type: 17498182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com tmpClip.setEmpty(); 17508182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 17519cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org default: { 17529cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org SkPath path; 17539cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org element->asPath(&path); 1754afc7cce5d68663934128d76963cd501f771d71desenorblanco tmpClip.op(path, this->getTopLayerBounds(), element->getOp(), element->isAA()); 17559cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org break; 17569cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org } 1757819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com } 1758819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com } 1759819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com} 1760819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com#endif 1761819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 176290c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.comvoid SkCanvas::replayClips(ClipVisitor* visitor) const { 1763687fa1c745febb57f42b0d5f03d7c1f4be2530careed SkClipStack::B2TIter iter(*fClipStack); 17648182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const SkClipStack::Element* element; 17658182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com 176696fcdcc219d2a0d3579719b84b28bede76efba64halcanary while ((element = iter.next()) != nullptr) { 1767c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita element->replay(visitor); 176890c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com } 176990c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com} 177090c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com 17715c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com/////////////////////////////////////////////////////////////////////////////// 17725c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 1773754de5f65b466f721d952a379194cc94de376f42reed@google.combool SkCanvas::isClipEmpty() const { 17741f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.isEmpty(); 1775754de5f65b466f721d952a379194cc94de376f42reed@google.com} 1776754de5f65b466f721d952a379194cc94de376f42reed@google.com 17775c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.orgbool SkCanvas::isClipRect() const { 17781f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.isRect(); 17795c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org} 17805c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org 17813b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::quickReject(const SkRect& rect) const { 17821607863b608b7db6c813228768ed5d72997bbc82reed@google.com if (!rect.isFinite()) 1783116b2bcd2c4c4d4670c7b7e2ea597414713c37fbwjmaclean@chromium.org return true; 1784116b2bcd2c4c4d4670c7b7e2ea597414713c37fbwjmaclean@chromium.org 17851f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fRasterClip.isEmpty()) { 17868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 17878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 17888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17891f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fMatrix.hasPerspective()) { 1790a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com SkRect dst; 17911f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix.mapRect(&dst, rect); 1792b07a94f1cba3976596ae1a7f23d8c2043ba353f3reed return !SkIRect::Intersects(dst.roundOut(), fMCRec->fRasterClip.getBounds()); 1793a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com } else { 1794c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com const SkRect& clipR = this->getLocalClipBounds(); 1795d252db03d9650013b545ef9781fe993c07f8f314reed@android.com 1796a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com // for speed, do the most likely reject compares first 1797c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com // TODO: should we use | instead, or compare all 4 at once? 1798c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com if (rect.fTop >= clipR.fBottom || rect.fBottom <= clipR.fTop) { 1799a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com return true; 1800a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com } 1801c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com if (rect.fLeft >= clipR.fRight || rect.fRight <= clipR.fLeft) { 1802a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com return true; 1803a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com } 1804a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com return false; 18058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18083b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::quickReject(const SkPath& path) const { 18093b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com return path.isEmpty() || this->quickReject(path.getBounds()); 18108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18123b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::getClipBounds(SkRect* bounds) const { 1813bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect ibounds; 18148f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!this->getClipDeviceBounds(&ibounds)) { 18158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 18168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1818d9c0f0b57affec7a472879c5919acac6637d926areed@android.com SkMatrix inverse; 1819d9c0f0b57affec7a472879c5919acac6637d926areed@android.com // if we can't invert the CTM, we can't return local clip bounds 18201f836ee096bb988adef4b9757b2629c7afeda36dreed if (!fMCRec->fMatrix.invert(&inverse)) { 182172dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com if (bounds) { 182272dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com bounds->setEmpty(); 182372dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com } 1824d9c0f0b57affec7a472879c5919acac6637d926areed@android.com return false; 1825d9c0f0b57affec7a472879c5919acac6637d926areed@android.com } 1826d9c0f0b57affec7a472879c5919acac6637d926areed@android.com 182749f085dddff10473b6ebf832a974288300224e60bsalomon if (bounds) { 1828bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkRect r; 18293b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com // adjust it outwards in case we are antialiasing 18303b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com const int inset = 1; 1831fa4d5bd09f8f1a4a92b5ae0324800dd672760898reed@google.com 18328f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com r.iset(ibounds.fLeft - inset, ibounds.fTop - inset, 18338f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com ibounds.fRight + inset, ibounds.fBottom + inset); 18348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inverse.mapRect(bounds, r); 18358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 18378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1839bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.combool SkCanvas::getClipDeviceBounds(SkIRect* bounds) const { 18401f836ee096bb988adef4b9757b2629c7afeda36dreed const SkRasterClip& clip = fMCRec->fRasterClip; 1841bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (clip.isEmpty()) { 1842bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (bounds) { 1843bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com bounds->setEmpty(); 1844bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1845bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com return false; 1846bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1847bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com 184849f085dddff10473b6ebf832a974288300224e60bsalomon if (bounds) { 1849bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com *bounds = clip.getBounds(); 1850bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1851bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com return true; 1852bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com} 1853bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com 18548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkMatrix& SkCanvas::getTotalMatrix() const { 18551f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fMatrix; 18568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18585c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.orgconst SkRegion& SkCanvas::internal_private_getTotalClip() const { 18591f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.forceGetBW(); 18605c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org} 18615c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org 1862175dd9b5e3d7d749738dac743d2ac360b5340187robertphillipsGrDrawContext* SkCanvas::internal_private_accessTopLayerDrawContext() { 18639c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com SkBaseDevice* dev = this->getTopDevice(); 1864175dd9b5e3d7d749738dac743d2ac360b5340187robertphillips return dev ? dev->accessDrawContext() : nullptr; 18659c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 18669c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1867644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.orgGrContext* SkCanvas::getGrContext() { 1868644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org SkBaseDevice* device = this->getTopDevice(); 186986ae3d161412961c27a406465b0ec5749cc2e753reed return device ? device->context() : nullptr; 1870644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org} 1871e97f0856a8044866b12527819d14cdfbcdfd96f2bsalomon@google.com 1872ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.orgvoid SkCanvas::drawDRRect(const SkRRect& outer, const SkRRect& inner, 1873ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkPaint& paint) { 18749881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawDRRect()"); 1875ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (outer.isEmpty()) { 1876ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 1877ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 1878ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (inner.isEmpty()) { 1879ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->drawRRect(outer, paint); 1880ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 1881ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 1882ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 1883ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // We don't have this method (yet), but technically this is what we should 1884ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // be able to assert... 1885ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // SkASSERT(outer.contains(inner)); 1886ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // 1887ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // For now at least check for containment of bounds 1888ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org SkASSERT(outer.getBounds().contains(inner.getBounds())); 1889ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 1890ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->onDrawDRRect(outer, inner, paint); 1891ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org} 1892ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 189341af966ab338e95eee81ab618ab28195075338f7reed// These need to stop being virtual -- clients need to override the onDraw... versions 189441af966ab338e95eee81ab618ab28195075338f7reed 189541af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawPaint(const SkPaint& paint) { 189641af966ab338e95eee81ab618ab28195075338f7reed this->onDrawPaint(paint); 189741af966ab338e95eee81ab618ab28195075338f7reed} 189841af966ab338e95eee81ab618ab28195075338f7reed 189941af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawRect(const SkRect& r, const SkPaint& paint) { 190041af966ab338e95eee81ab618ab28195075338f7reed this->onDrawRect(r, paint); 190141af966ab338e95eee81ab618ab28195075338f7reed} 190241af966ab338e95eee81ab618ab28195075338f7reed 190341af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawOval(const SkRect& r, const SkPaint& paint) { 190441af966ab338e95eee81ab618ab28195075338f7reed this->onDrawOval(r, paint); 190541af966ab338e95eee81ab618ab28195075338f7reed} 190641af966ab338e95eee81ab618ab28195075338f7reed 190741af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) { 190841af966ab338e95eee81ab618ab28195075338f7reed this->onDrawRRect(rrect, paint); 190941af966ab338e95eee81ab618ab28195075338f7reed} 191041af966ab338e95eee81ab618ab28195075338f7reed 191141af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint) { 191241af966ab338e95eee81ab618ab28195075338f7reed this->onDrawPoints(mode, count, pts, paint); 191341af966ab338e95eee81ab618ab28195075338f7reed} 191441af966ab338e95eee81ab618ab28195075338f7reed 191541af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawVertices(VertexMode vmode, int vertexCount, const SkPoint vertices[], 191641af966ab338e95eee81ab618ab28195075338f7reed const SkPoint texs[], const SkColor colors[], SkXfermode* xmode, 191741af966ab338e95eee81ab618ab28195075338f7reed const uint16_t indices[], int indexCount, const SkPaint& paint) { 191841af966ab338e95eee81ab618ab28195075338f7reed this->onDrawVertices(vmode, vertexCount, vertices, texs, colors, xmode, 191941af966ab338e95eee81ab618ab28195075338f7reed indices, indexCount, paint); 192041af966ab338e95eee81ab618ab28195075338f7reed} 192141af966ab338e95eee81ab618ab28195075338f7reed 192241af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawPath(const SkPath& path, const SkPaint& paint) { 192341af966ab338e95eee81ab618ab28195075338f7reed this->onDrawPath(path, paint); 192441af966ab338e95eee81ab618ab28195075338f7reed} 192541af966ab338e95eee81ab618ab28195075338f7reed 1926a85d4d0814818e4ddabb9237da209d61d6cd5854reedvoid SkCanvas::drawImage(const SkImage* image, SkScalar x, SkScalar y, const SkPaint* paint) { 1927e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 1928a85d4d0814818e4ddabb9237da209d61d6cd5854reed this->onDrawImage(image, x, y, paint); 192941af966ab338e95eee81ab618ab28195075338f7reed} 193041af966ab338e95eee81ab618ab28195075338f7reed 1931e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst, 1932e47829b6b1eeb6b0c97ccb3df3016d197046824creed const SkPaint* paint, SrcRectConstraint constraint) { 1933e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 1934e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (dst.isEmpty() || src.isEmpty()) { 1935e47829b6b1eeb6b0c97ccb3df3016d197046824creed return; 1936e47829b6b1eeb6b0c97ccb3df3016d197046824creed } 1937e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->onDrawImageRect(image, &src, dst, paint, constraint); 1938e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 193941af966ab338e95eee81ab618ab28195075338f7reed 194084984efeb64787b88c5f8bd6929cfe2d58a3ba06reedvoid SkCanvas::drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst, 194184984efeb64787b88c5f8bd6929cfe2d58a3ba06reed const SkPaint* paint, SrcRectConstraint constraint) { 1942e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 1943e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, SkRect::Make(isrc), dst, paint, constraint); 194484984efeb64787b88c5f8bd6929cfe2d58a3ba06reed} 194584984efeb64787b88c5f8bd6929cfe2d58a3ba06reed 1946e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint, 1947e47829b6b1eeb6b0c97ccb3df3016d197046824creed SrcRectConstraint constraint) { 1948e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 1949e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, SkRect::MakeIWH(image->width(), image->height()), dst, paint, 1950e47829b6b1eeb6b0c97ccb3df3016d197046824creed constraint); 1951e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 1952e47829b6b1eeb6b0c97ccb3df3016d197046824creed 19534c21dc5ddf3b482293ed34eead876d8d61a662c3reedvoid SkCanvas::drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst, 19544c21dc5ddf3b482293ed34eead876d8d61a662c3reed const SkPaint* paint) { 1955e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 19564c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (dst.isEmpty()) { 19574c21dc5ddf3b482293ed34eead876d8d61a662c3reed return; 19584c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 19594c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (!SkNinePatchIter::Valid(image->width(), image->height(), center)) { 1960e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, dst, paint); 19614c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 19624c21dc5ddf3b482293ed34eead876d8d61a662c3reed this->onDrawImageNine(image, center, dst, paint); 19634c21dc5ddf3b482293ed34eead876d8d61a662c3reed} 19644c21dc5ddf3b482293ed34eead876d8d61a662c3reed 196541af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar dx, SkScalar dy, const SkPaint* paint) { 19664c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (bitmap.drawsNothing()) { 19672df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson return; 19682df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson } 196941af966ab338e95eee81ab618ab28195075338f7reed this->onDrawBitmap(bitmap, dx, dy, paint); 197041af966ab338e95eee81ab618ab28195075338f7reed} 197141af966ab338e95eee81ab618ab28195075338f7reed 1972e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst, 1973a5517e2b190a8083b38964972b031c13e99f1012reed const SkPaint* paint, SrcRectConstraint constraint) { 1974e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (bitmap.drawsNothing() || dst.isEmpty() || src.isEmpty()) { 1975a5517e2b190a8083b38964972b031c13e99f1012reed return; 1976a5517e2b190a8083b38964972b031c13e99f1012reed } 1977e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->onDrawBitmapRect(bitmap, &src, dst, paint, constraint); 197841af966ab338e95eee81ab618ab28195075338f7reed} 197941af966ab338e95eee81ab618ab28195075338f7reed 198084984efeb64787b88c5f8bd6929cfe2d58a3ba06reedvoid SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst, 198184984efeb64787b88c5f8bd6929cfe2d58a3ba06reed const SkPaint* paint, SrcRectConstraint constraint) { 1982e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, SkRect::Make(isrc), dst, paint, constraint); 1983e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 1984e47829b6b1eeb6b0c97ccb3df3016d197046824creed 1985e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint, 1986e47829b6b1eeb6b0c97ccb3df3016d197046824creed SrcRectConstraint constraint) { 1987e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, SkRect::MakeIWH(bitmap.width(), bitmap.height()), dst, paint, 1988e47829b6b1eeb6b0c97ccb3df3016d197046824creed constraint); 198984984efeb64787b88c5f8bd6929cfe2d58a3ba06reed} 199084984efeb64787b88c5f8bd6929cfe2d58a3ba06reed 199141af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst, 199241af966ab338e95eee81ab618ab28195075338f7reed const SkPaint* paint) { 19934c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (bitmap.drawsNothing() || dst.isEmpty()) { 19942df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson return; 19952df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson } 19964c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (!SkNinePatchIter::Valid(bitmap.width(), bitmap.height(), center)) { 1997a5517e2b190a8083b38964972b031c13e99f1012reed this->drawBitmapRect(bitmap, dst, paint); 19984c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 199941af966ab338e95eee81ab618ab28195075338f7reed this->onDrawBitmapNine(bitmap, center, dst, paint); 200041af966ab338e95eee81ab618ab28195075338f7reed} 200141af966ab338e95eee81ab618ab28195075338f7reed 200271c3c760a83123ee0b3127b8c65c6394ce541c50reedvoid SkCanvas::drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], 200371c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkColor colors[], int count, SkXfermode::Mode mode, 200471c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkRect* cull, const SkPaint* paint) { 2005e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(atlas); 200671c3c760a83123ee0b3127b8c65c6394ce541c50reed if (count <= 0) { 200771c3c760a83123ee0b3127b8c65c6394ce541c50reed return; 200871c3c760a83123ee0b3127b8c65c6394ce541c50reed } 200971c3c760a83123ee0b3127b8c65c6394ce541c50reed SkASSERT(atlas); 201071c3c760a83123ee0b3127b8c65c6394ce541c50reed SkASSERT(xform); 201171c3c760a83123ee0b3127b8c65c6394ce541c50reed SkASSERT(tex); 201271c3c760a83123ee0b3127b8c65c6394ce541c50reed this->onDrawAtlas(atlas, xform, tex, colors, count, mode, cull, paint); 201371c3c760a83123ee0b3127b8c65c6394ce541c50reed} 201471c3c760a83123ee0b3127b8c65c6394ce541c50reed 2015f70b531daaf47db1ee95c70da9843f1dd1f418d3reedvoid SkCanvas::drawAnnotation(const SkRect& rect, const char key[], SkData* value) { 2016f70b531daaf47db1ee95c70da9843f1dd1f418d3reed if (key) { 2017f70b531daaf47db1ee95c70da9843f1dd1f418d3reed this->onDrawAnnotation(rect, key, value); 2018f70b531daaf47db1ee95c70da9843f1dd1f418d3reed } 2019f70b531daaf47db1ee95c70da9843f1dd1f418d3reed} 2020f70b531daaf47db1ee95c70da9843f1dd1f418d3reed 2021e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::legacy_drawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, 2022e47829b6b1eeb6b0c97ccb3df3016d197046824creed const SkPaint* paint, SrcRectConstraint constraint) { 2023e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (src) { 2024e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, *src, dst, paint, constraint); 2025e47829b6b1eeb6b0c97ccb3df3016d197046824creed } else { 2026e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, SkRect::MakeIWH(image->width(), image->height()), 2027e47829b6b1eeb6b0c97ccb3df3016d197046824creed dst, paint, constraint); 2028e47829b6b1eeb6b0c97ccb3df3016d197046824creed } 2029e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 2030e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::legacy_drawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, 2031e47829b6b1eeb6b0c97ccb3df3016d197046824creed const SkPaint* paint, SrcRectConstraint constraint) { 2032e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (src) { 2033e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, *src, dst, paint, constraint); 2034e47829b6b1eeb6b0c97ccb3df3016d197046824creed } else { 2035e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, SkRect::MakeIWH(bitmap.width(), bitmap.height()), 2036e47829b6b1eeb6b0c97ccb3df3016d197046824creed dst, paint, constraint); 2037e47829b6b1eeb6b0c97ccb3df3016d197046824creed } 2038e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 2039e47829b6b1eeb6b0c97ccb3df3016d197046824creed 2040cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudsonvoid SkCanvas::temporary_internal_describeTopLayer(SkMatrix* matrix, SkIRect* clip_bounds) { 2041cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson SkIRect layer_bounds = this->getTopLayerBounds(); 2042cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson if (matrix) { 2043cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson *matrix = this->getTotalMatrix(); 2044cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson matrix->preTranslate(-layer_bounds.left(), -layer_bounds.top()); 2045cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson } 2046cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson if (clip_bounds) { 2047cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson this->getClipDeviceBounds(clip_bounds); 2048cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson clip_bounds->offset(-layer_bounds.left(), -layer_bounds.top()); 2049cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson } 2050cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson} 2051cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson 20528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 20538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// These are the virtual drawing methods 20548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 20558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 205628361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.orgvoid SkCanvas::onDiscard() { 205749f085dddff10473b6ebf832a974288300224e60bsalomon if (fSurfaceBase) { 205828361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org fSurfaceBase->aboutToDraw(SkSurface::kDiscard_ContentChangeMode); 205928361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org } 206028361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org} 206128361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org 206241af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawPaint(const SkPaint& paint) { 20639881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPaint()"); 2064fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->internalDrawPaint(paint); 2065fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com} 2066fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com 2067fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.comvoid SkCanvas::internalDrawPaint(const SkPaint& paint) { 206896fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, SkDrawFilter::kPaint_Type, nullptr, false) 20698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 20714e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPaint(iter, looper.paint()); 20728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 20738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20744e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 20758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 20768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 207741af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[], 207841af966ab338e95eee81ab618ab28195075338f7reed const SkPaint& paint) { 20799881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT1("disabled-by-default-skia", "SkCanvas::drawPoints()", "count", static_cast<uint64_t>(count)); 20808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if ((long)count <= 0) { 20818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 20828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 20838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 208478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect r, storage; 208596fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 2086a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com if (paint.canComputeFastBounds()) { 2087a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com // special-case 2 points (common for drawing a single line) 2088a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com if (2 == count) { 2089a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com r.set(pts[0], pts[1]); 2090a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } else { 2091a8c7f7702fb4bbedb615031bc653c5cd161a038ecommit-bot@chromium.org r.set(pts, SkToInt(count)); 2092a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } 209387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastStrokeBounds(r, &storage))) { 209487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 209587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 209687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &r; 2097fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 2098a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com 209996fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkASSERT(pts != nullptr); 21008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 210178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPoint_Type, bounds) 21024b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 21038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 21044e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPoints(iter, mode, count, pts, looper.paint()); 21058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 21064b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 21074e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 21088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 21098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 211041af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawRect(const SkRect& r, const SkPaint& paint) { 21119881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRect()"); 211278cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 211396fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 21148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.canComputeFastBounds()) { 21158432808ad8898ac7137bc7ce1d9df6005e866401reed // Skia will draw an inverted rect, because it explicitly "sorts" it downstream. 21168432808ad8898ac7137bc7ce1d9df6005e866401reed // To prevent accidental rejecting at this stage, we have to sort it before we check. 21178432808ad8898ac7137bc7ce1d9df6005e866401reed SkRect tmp(r); 21188432808ad8898ac7137bc7ce1d9df6005e866401reed tmp.sort(); 21198432808ad8898ac7137bc7ce1d9df6005e866401reed 212087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(tmp, &storage))) { 212187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 212287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 212387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &r; 21248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 21254b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2126c83a29759a5c2966da5ab973e4fd90763e4c962breed LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, SkDrawFilter::kRect_Type, bounds, false) 21278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 21294e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawRect(iter, r, looper.paint()); 21308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 21318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21324e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 21338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 21348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 213541af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) { 21369881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawOval()"); 213778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 213896fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 21394ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (paint.canComputeFastBounds()) { 214087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(oval, &storage))) { 214187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 214287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 214387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &oval; 21444ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 2145306ab9d5de38f2a547fd1d69aedbe69b5c6617ccskia.committer@gmail.com 214678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, bounds) 214746d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com 214846d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com while (iter.next()) { 214946d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com iter.fDevice->drawOval(iter, oval, looper.paint()); 215046d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com } 215146d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com 215246d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com LOOPER_END 21534ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 21544ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 215541af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) { 21569881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRRect()"); 215778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 215896fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 21594ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (paint.canComputeFastBounds()) { 216087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(rrect.getBounds(), &storage))) { 216187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 216287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 216387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &rrect.getBounds(); 21644ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 21654ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 21664ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (rrect.isRect()) { 21674ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com // call the non-virtual version 21684ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->SkCanvas::drawRect(rrect.getBounds(), paint); 2169f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org return; 2170f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } else if (rrect.isOval()) { 21714ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com // call the non-virtual version 2172f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org this->SkCanvas::drawOval(rrect.getBounds(), paint); 2173f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org return; 21744ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 2175f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 217678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) 2177f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 2178f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org while (iter.next()) { 2179f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org iter.fDevice->drawRRect(iter, rrect, looper.paint()); 2180f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } 2181f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 2182f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org LOOPER_END 21834ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 21844ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 2185ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.orgvoid SkCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, 2186ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkPaint& paint) { 2187ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org SkRect storage; 218896fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 2189ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (paint.canComputeFastBounds()) { 219087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(outer.getBounds(), &storage))) { 219187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 219287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 219387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &outer.getBounds(); 2194ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 219525c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 2196ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) 219725c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 2198ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org while (iter.next()) { 2199ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org iter.fDevice->drawDRRect(iter, outer, inner, looper.paint()); 2200ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 220125c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 2202ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org LOOPER_END 2203ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org} 22044ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 220541af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) { 22069881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPath()"); 22079364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com if (!path.isFinite()) { 22089364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com return; 22099364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com } 22109364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com 221178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 221296fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 2213fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com if (!path.isInverseFillType() && paint.canComputeFastBounds()) { 221478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect& pathBounds = path.getBounds(); 221587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(pathBounds, &storage))) { 221687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 221787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 221887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &pathBounds; 22198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 22200b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org 22210b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org const SkRect& r = path.getBounds(); 22220b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org if (r.width() <= 0 && r.height() <= 0) { 22236803c219dd3be4a73e7bb5c4bb8a5b1f803624d0commit-bot@chromium.org if (path.isInverseFillType()) { 2224fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->internalDrawPaint(paint); 22256651a3238dd6affa4276ada42ab613abf1d42d1dcaryclark return; 2226fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 2227fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 22288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 222978cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, bounds) 22308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 22324e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPath(iter, path, looper.paint()); 22338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 22348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22354e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 22368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 22378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2238262a71b7f95ce98ff3dd8dba845afbd724470903reedbool SkCanvas::canDrawBitmapAsSprite(SkScalar x, SkScalar y, int w, int h, const SkPaint& paint) { 2239262a71b7f95ce98ff3dd8dba845afbd724470903reed if (!paint.getImageFilter()) { 2240262a71b7f95ce98ff3dd8dba845afbd724470903reed return false; 2241262a71b7f95ce98ff3dd8dba845afbd724470903reed } 2242262a71b7f95ce98ff3dd8dba845afbd724470903reed 2243262a71b7f95ce98ff3dd8dba845afbd724470903reed const SkMatrix& ctm = this->getTotalMatrix(); 2244c7e211acd0c9201688de7ff0c9a2271c67440adffmalita if (!SkTreatAsSprite(ctm, SkISize::Make(w, h), paint)) { 2245262a71b7f95ce98ff3dd8dba845afbd724470903reed return false; 2246262a71b7f95ce98ff3dd8dba845afbd724470903reed } 2247262a71b7f95ce98ff3dd8dba845afbd724470903reed 2248262a71b7f95ce98ff3dd8dba845afbd724470903reed // Currently we can only use the filterSprite code if we are clipped to the bitmap's bounds. 2249262a71b7f95ce98ff3dd8dba845afbd724470903reed // Once we can filter and the filter will return a result larger than itself, we should be 2250262a71b7f95ce98ff3dd8dba845afbd724470903reed // able to remove this constraint. 2251262a71b7f95ce98ff3dd8dba845afbd724470903reed // skbug.com/4526 2252262a71b7f95ce98ff3dd8dba845afbd724470903reed // 2253262a71b7f95ce98ff3dd8dba845afbd724470903reed SkPoint pt; 2254262a71b7f95ce98ff3dd8dba845afbd724470903reed ctm.mapXY(x, y, &pt); 2255262a71b7f95ce98ff3dd8dba845afbd724470903reed SkIRect ir = SkIRect::MakeXYWH(SkScalarRoundToInt(pt.x()), SkScalarRoundToInt(pt.y()), w, h); 2256262a71b7f95ce98ff3dd8dba845afbd724470903reed return ir.contains(fMCRec->fRasterClip.getBounds()); 2257262a71b7f95ce98ff3dd8dba845afbd724470903reed} 2258262a71b7f95ce98ff3dd8dba845afbd724470903reed 2259a85d4d0814818e4ddabb9237da209d61d6cd5854reedvoid SkCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, const SkPaint* paint) { 22609881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImage()"); 2261a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkRect bounds = SkRect::MakeXYWH(x, y, 2262a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkIntToScalar(image->width()), SkIntToScalar(image->height())); 226396fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 226487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect tmp = bounds; 226587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (paint) { 226687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco paint->computeFastBounds(tmp, &tmp); 226787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 226887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(tmp)) { 226987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 227087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 2271a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 22729d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2273a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkLazyPaint lazy; 227496fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 2275a85d4d0814818e4ddabb9237da209d61d6cd5854reed paint = lazy.init(); 2276a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2277262a71b7f95ce98ff3dd8dba845afbd724470903reed 2278129ed1cd6d792f3f6cf563aefa9756fc6308289dreed bool drawAsSprite = this->canDrawBitmapAsSprite(x, y, image->width(), image->height(), 2279129ed1cd6d792f3f6cf563aefa9756fc6308289dreed *paint); 2280129ed1cd6d792f3f6cf563aefa9756fc6308289dreed if (drawAsSprite && paint->getImageFilter()) { 2281129ed1cd6d792f3f6cf563aefa9756fc6308289dreed SkBitmap bitmap; 2282129ed1cd6d792f3f6cf563aefa9756fc6308289dreed if (!as_IB(image)->asBitmapForImageFilters(&bitmap)) { 2283129ed1cd6d792f3f6cf563aefa9756fc6308289dreed drawAsSprite = false; 2284129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } else{ 2285129ed1cd6d792f3f6cf563aefa9756fc6308289dreed // Until imagefilters are updated, they cannot handle any src type but N32... 2286129ed1cd6d792f3f6cf563aefa9756fc6308289dreed if (bitmap.info().colorType() != kN32_SkColorType || bitmap.info().isSRGB()) { 2287129ed1cd6d792f3f6cf563aefa9756fc6308289dreed drawAsSprite = false; 2288129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 2289129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 2290129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 2291129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 2292262a71b7f95ce98ff3dd8dba845afbd724470903reed LOOPER_BEGIN_DRAWBITMAP(*paint, drawAsSprite, &bounds) 2293262a71b7f95ce98ff3dd8dba845afbd724470903reed 2294a85d4d0814818e4ddabb9237da209d61d6cd5854reed while (iter.next()) { 2295262a71b7f95ce98ff3dd8dba845afbd724470903reed const SkPaint& pnt = looper.paint(); 2296262a71b7f95ce98ff3dd8dba845afbd724470903reed if (drawAsSprite && pnt.getImageFilter()) { 2297262a71b7f95ce98ff3dd8dba845afbd724470903reed SkBitmap bitmap; 2298262a71b7f95ce98ff3dd8dba845afbd724470903reed if (as_IB(image)->asBitmapForImageFilters(&bitmap)) { 2299262a71b7f95ce98ff3dd8dba845afbd724470903reed SkPoint pt; 2300262a71b7f95ce98ff3dd8dba845afbd724470903reed iter.fMatrix->mapXY(x, y, &pt); 23012302de920e5434809bd0e85b871a6e002856dfdbrobertphillips iter.fDevice->drawSpriteWithFilter(iter, bitmap, 23022302de920e5434809bd0e85b871a6e002856dfdbrobertphillips SkScalarRoundToInt(pt.fX), 23032302de920e5434809bd0e85b871a6e002856dfdbrobertphillips SkScalarRoundToInt(pt.fY), pnt); 2304262a71b7f95ce98ff3dd8dba845afbd724470903reed } 2305262a71b7f95ce98ff3dd8dba845afbd724470903reed } else { 2306262a71b7f95ce98ff3dd8dba845afbd724470903reed iter.fDevice->drawImage(iter, image, x, y, pnt); 2307262a71b7f95ce98ff3dd8dba845afbd724470903reed } 2308a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 23099d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2310a85d4d0814818e4ddabb9237da209d61d6cd5854reed LOOPER_END 2311b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr} 2312b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 231341af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, 2314562fe4767cc73e08a4e039362bc0336aea66ecfbreed const SkPaint* paint, SrcRectConstraint constraint) { 23159881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImageRect()"); 231696fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 2317c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco SkRect storage = dst; 231887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (paint) { 231987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco paint->computeFastBounds(dst, &storage); 232087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 232187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(storage)) { 232287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 232387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 2324a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2325a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkLazyPaint lazy; 232696fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 2327a85d4d0814818e4ddabb9237da209d61d6cd5854reed paint = lazy.init(); 2328a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 23299d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2330c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, SkDrawFilter::kBitmap_Type, &dst, 2331c83a29759a5c2966da5ab973e4fd90763e4c962breed image->isOpaque()) 23329d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2333a85d4d0814818e4ddabb9237da209d61d6cd5854reed while (iter.next()) { 2334a5517e2b190a8083b38964972b031c13e99f1012reed iter.fDevice->drawImageRect(iter, image, src, dst, looper.paint(), constraint); 2335a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 23369d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2337a85d4d0814818e4ddabb9237da209d61d6cd5854reed LOOPER_END 2338b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr} 2339b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 234041af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y, const SkPaint* paint) { 23419881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmap()"); 23428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(bitmap.validate();) 23438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 234433366974d43eae80e22284a2e445225c343859dareed if (bitmap.drawsNothing()) { 234533366974d43eae80e22284a2e445225c343859dareed return; 234633366974d43eae80e22284a2e445225c343859dareed } 234733366974d43eae80e22284a2e445225c343859dareed 234833366974d43eae80e22284a2e445225c343859dareed SkLazyPaint lazy; 234933366974d43eae80e22284a2e445225c343859dareed if (nullptr == paint) { 235033366974d43eae80e22284a2e445225c343859dareed paint = lazy.init(); 235133366974d43eae80e22284a2e445225c343859dareed } 235233366974d43eae80e22284a2e445225c343859dareed 235333366974d43eae80e22284a2e445225c343859dareed const SkMatrix matrix = SkMatrix::MakeTrans(x, y); 235433366974d43eae80e22284a2e445225c343859dareed 235533366974d43eae80e22284a2e445225c343859dareed SkRect storage; 235633366974d43eae80e22284a2e445225c343859dareed const SkRect* bounds = nullptr; 235733366974d43eae80e22284a2e445225c343859dareed if (paint->canComputeFastBounds()) { 235833366974d43eae80e22284a2e445225c343859dareed bitmap.getBounds(&storage); 235933366974d43eae80e22284a2e445225c343859dareed matrix.mapRect(&storage); 236087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect tmp = storage; 236187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint->computeFastBounds(tmp, &tmp))) { 236287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 236387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 236487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &storage; 23658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23664b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2367129ed1cd6d792f3f6cf563aefa9756fc6308289dreed bool drawAsSprite = bounds && this->canDrawBitmapAsSprite(x, y, bitmap.width(), bitmap.height(), 2368129ed1cd6d792f3f6cf563aefa9756fc6308289dreed *paint); 2369129ed1cd6d792f3f6cf563aefa9756fc6308289dreed if (drawAsSprite && paint->getImageFilter()) { 2370129ed1cd6d792f3f6cf563aefa9756fc6308289dreed // Until imagefilters are updated, they cannot handle any src type but N32... 2371129ed1cd6d792f3f6cf563aefa9756fc6308289dreed if (bitmap.info().colorType() != kN32_SkColorType || bitmap.info().isSRGB()) { 2372129ed1cd6d792f3f6cf563aefa9756fc6308289dreed drawAsSprite = false; 2373129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 2374129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 2375129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 2376262a71b7f95ce98ff3dd8dba845afbd724470903reed LOOPER_BEGIN_DRAWBITMAP(*paint, drawAsSprite, bounds) 237733366974d43eae80e22284a2e445225c343859dareed 237833366974d43eae80e22284a2e445225c343859dareed while (iter.next()) { 2379262a71b7f95ce98ff3dd8dba845afbd724470903reed const SkPaint& pnt = looper.paint(); 2380262a71b7f95ce98ff3dd8dba845afbd724470903reed if (drawAsSprite && pnt.getImageFilter()) { 2381262a71b7f95ce98ff3dd8dba845afbd724470903reed SkPoint pt; 2382262a71b7f95ce98ff3dd8dba845afbd724470903reed iter.fMatrix->mapXY(x, y, &pt); 23832302de920e5434809bd0e85b871a6e002856dfdbrobertphillips iter.fDevice->drawSpriteWithFilter(iter, bitmap, 23842302de920e5434809bd0e85b871a6e002856dfdbrobertphillips SkScalarRoundToInt(pt.fX), 23852302de920e5434809bd0e85b871a6e002856dfdbrobertphillips SkScalarRoundToInt(pt.fY), pnt); 2386262a71b7f95ce98ff3dd8dba845afbd724470903reed } else { 2387262a71b7f95ce98ff3dd8dba845afbd724470903reed iter.fDevice->drawBitmap(iter, bitmap, matrix, looper.paint()); 2388262a71b7f95ce98ff3dd8dba845afbd724470903reed } 238933366974d43eae80e22284a2e445225c343859dareed } 2390262a71b7f95ce98ff3dd8dba845afbd724470903reed 239133366974d43eae80e22284a2e445225c343859dareed LOOPER_END 23928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23949987ec3791336bad6af5cbe513564786b2df55aareed@google.com// this one is non-virtual, so it can be called safely by other canvas apis 23957112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.comvoid SkCanvas::internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, 2396eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org const SkRect& dst, const SkPaint* paint, 2397a5517e2b190a8083b38964972b031c13e99f1012reed SrcRectConstraint constraint) { 239850b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org if (bitmap.drawsNothing() || dst.isEmpty()) { 23998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 24008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 240174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 240296fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 2403c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco SkRect storage; 240487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 240587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 240687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 24078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 24083d60812865bb034851da777a91413ab584929887reed@google.com 240933535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com SkLazyPaint lazy; 241096fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 241133535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com paint = lazy.init(); 24128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 24137064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 2414c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, SkDrawFilter::kBitmap_Type, &dst, 2415c83a29759a5c2966da5ab973e4fd90763e4c962breed bitmap.isOpaque()) 24167064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 241733535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com while (iter.next()) { 2418562fe4767cc73e08a4e039362bc0336aea66ecfbreed iter.fDevice->drawBitmapRect(iter, bitmap, src, dst, looper.paint(), constraint); 2419f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 24207064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 242133535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com LOOPER_END 24228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 242441af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, 2425562fe4767cc73e08a4e039362bc0336aea66ecfbreed const SkPaint* paint, SrcRectConstraint constraint) { 24269881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmapRectToRect()"); 24279987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkDEBUGCODE(bitmap.validate();) 2428562fe4767cc73e08a4e039362bc0336aea66ecfbreed this->internalDrawBitmapRect(bitmap, src, dst, paint, constraint); 24299987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 24309987ec3791336bad6af5cbe513564786b2df55aareed@google.com 24314c21dc5ddf3b482293ed34eead876d8d61a662c3reedvoid SkCanvas::onDrawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst, 24324c21dc5ddf3b482293ed34eead876d8d61a662c3reed const SkPaint* paint) { 24334c21dc5ddf3b482293ed34eead876d8d61a662c3reed TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImageNine()"); 24349d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 243596fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 2436c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco SkRect storage; 243787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 243887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 243987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 24403d60812865bb034851da777a91413ab584929887reed@google.com } 24419d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 24424c21dc5ddf3b482293ed34eead876d8d61a662c3reed SkLazyPaint lazy; 244396fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 24444c21dc5ddf3b482293ed34eead876d8d61a662c3reed paint = lazy.init(); 24454c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 24469d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2447c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst) 24489d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 24494c21dc5ddf3b482293ed34eead876d8d61a662c3reed while (iter.next()) { 24504c21dc5ddf3b482293ed34eead876d8d61a662c3reed iter.fDevice->drawImageNine(iter, image, center, dst, looper.paint()); 24519987ec3791336bad6af5cbe513564786b2df55aareed@google.com } 24529d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 24534c21dc5ddf3b482293ed34eead876d8d61a662c3reed LOOPER_END 24549987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 24559987ec3791336bad6af5cbe513564786b2df55aareed@google.com 245641af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst, 245741af966ab338e95eee81ab618ab28195075338f7reed const SkPaint* paint) { 24589881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmapNine()"); 24599987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkDEBUGCODE(bitmap.validate();) 24609987ec3791336bad6af5cbe513564786b2df55aareed@google.com 246196fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 2462c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco SkRect storage; 246387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 246487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 246587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 24664c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 24679d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 24684c21dc5ddf3b482293ed34eead876d8d61a662c3reed SkLazyPaint lazy; 246996fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 24704c21dc5ddf3b482293ed34eead876d8d61a662c3reed paint = lazy.init(); 24714c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 24729d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2473c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst) 24749d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 24754c21dc5ddf3b482293ed34eead876d8d61a662c3reed while (iter.next()) { 24764c21dc5ddf3b482293ed34eead876d8d61a662c3reed iter.fDevice->drawBitmapNine(iter, bitmap, center, dst, looper.paint()); 24774c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 24789d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 24794c21dc5ddf3b482293ed34eead876d8d61a662c3reed LOOPER_END 24809987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 24819987ec3791336bad6af5cbe513564786b2df55aareed@google.com 2482f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.comclass SkDeviceFilteredPaint { 2483f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.compublic: 24841f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkDeviceFilteredPaint(SkBaseDevice* device, const SkPaint& paint) { 2485112e7e277702e104357f2d44742253ee1b0109acfmalita uint32_t filteredFlags = device->filterTextFlags(paint); 2486112e7e277702e104357f2d44742253ee1b0109acfmalita if (filteredFlags != paint.getFlags()) { 2487a076e9be17654a60310e72c4f70fcd5337f56dbfreed@google.com SkPaint* newPaint = fLazy.set(paint); 2488112e7e277702e104357f2d44742253ee1b0109acfmalita newPaint->setFlags(filteredFlags); 2489f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com fPaint = newPaint; 2490f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } else { 2491f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com fPaint = &paint; 2492f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } 2493f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } 2494f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 2495f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com const SkPaint& paint() const { return *fPaint; } 2496f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 2497f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.comprivate: 24982c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint* fPaint; 24992c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkLazyPaint fLazy; 2500f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com}; 2501f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 250252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.comvoid SkCanvas::DrawRect(const SkDraw& draw, const SkPaint& paint, 250352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com const SkRect& r, SkScalar textSize) { 250417b78946096265d80215a6c946286ecaa35ea7edepoger@google.com if (paint.getStyle() == SkPaint::kFill_Style) { 250552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com draw.fDevice->drawRect(draw, r, paint); 250652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } else { 250752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPaint p(paint); 250817b78946096265d80215a6c946286ecaa35ea7edepoger@google.com p.setStrokeWidth(SkScalarMul(textSize, paint.getStrokeWidth())); 250952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com draw.fDevice->drawRect(draw, r, p); 251052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 251152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com} 251252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 251352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.comvoid SkCanvas::DrawTextDecorations(const SkDraw& draw, const SkPaint& paint, 251452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com const char text[], size_t byteLength, 251552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar x, SkScalar y) { 251696fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkASSERT(byteLength == 0 || text != nullptr); 251752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 251852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com // nothing to draw 251996fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (text == nullptr || byteLength == 0 || 25201e7f5e708e5daeb0c18ae49001c9e3cd5e3b13cbreed draw.fRC->isEmpty() || 252196fcdcc219d2a0d3579719b84b28bede76efba64halcanary (paint.getAlpha() == 0 && paint.getXfermode() == nullptr)) { 252252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com return; 252352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 252452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 252552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar width = 0; 252652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPoint start; 252752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 252852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.set(0, 0); // to avoid warning 252952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (paint.getFlags() & (SkPaint::kUnderlineText_Flag | 253052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPaint::kStrikeThruText_Flag)) { 253152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com width = paint.measureText(text, byteLength); 253252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 253352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar offsetX = 0; 253452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (paint.getTextAlign() == SkPaint::kCenter_Align) { 253552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com offsetX = SkScalarHalf(width); 253652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } else if (paint.getTextAlign() == SkPaint::kRight_Align) { 253752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com offsetX = width; 253852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 253952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.set(x - offsetX, y); 254052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 254152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 254252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (0 == width) { 254352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com return; 254452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 254552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 254652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com uint32_t flags = paint.getFlags(); 254752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 254852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (flags & (SkPaint::kUnderlineText_Flag | 254952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPaint::kStrikeThruText_Flag)) { 255052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar textSize = paint.getTextSize(); 255152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar height = SkScalarMul(textSize, kStdUnderline_Thickness); 255252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkRect r; 255352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 255452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fLeft = start.fX; 255552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fRight = start.fX + width; 255652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 255752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (flags & SkPaint::kUnderlineText_Flag) { 255852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar offset = SkScalarMulAdd(textSize, kStdUnderline_Offset, 255952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.fY); 256052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fTop = offset; 256152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fBottom = offset + height; 2562fb56218292d6c7b509d382f39994c3783b2483a0caryclark DrawRect(draw, paint, r, 1); 256352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 256452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (flags & SkPaint::kStrikeThruText_Flag) { 256552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar offset = SkScalarMulAdd(textSize, kStdStrikeThru_Offset, 256652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.fY); 256752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fTop = offset; 256852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fBottom = offset + height; 2569fb56218292d6c7b509d382f39994c3783b2483a0caryclark DrawRect(draw, paint, r, 1); 257052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 257152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 257252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com} 257352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 2574e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 2575e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 257696fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 25778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 25794e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 2580f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com iter.fDevice->drawText(iter, text, byteLength, x, y, dfp.paint()); 258152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com DrawTextDecorations(iter, dfp.paint(), 258252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com static_cast<const char*>(text), byteLength, x, y); 25838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 25848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25854e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 25868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 25878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2588e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], 2589e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 259005c4a4322e7d4f3417b7df33825bab8603d52051fmalita SkPoint textOffset = SkPoint::Make(0, 0); 259105c4a4322e7d4f3417b7df33825bab8603d52051fmalita 259296fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 259387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 25948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 25954e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 259605c4a4322e7d4f3417b7df33825bab8603d52051fmalita iter.fDevice->drawPosText(iter, text, byteLength, &pos->fX, 2, textOffset, 2597f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com dfp.paint()); 25988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2599b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 26004e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 26018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 26028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2603e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], 2604e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com SkScalar constY, const SkPaint& paint) { 260505c4a4322e7d4f3417b7df33825bab8603d52051fmalita 260605c4a4322e7d4f3417b7df33825bab8603d52051fmalita SkPoint textOffset = SkPoint::Make(0, constY); 260705c4a4322e7d4f3417b7df33825bab8603d52051fmalita 260896fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 260987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 26108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 26114e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 261205c4a4322e7d4f3417b7df33825bab8603d52051fmalita iter.fDevice->drawPosText(iter, text, byteLength, xpos, 1, textOffset, 2613f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com dfp.paint()); 26148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2615b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 26164e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 26178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 26188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2619e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 2620e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkMatrix* matrix, const SkPaint& paint) { 262196fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 262287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 26238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 26248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawTextOnPath(iter, text, byteLength, path, 26254e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com matrix, looper.paint()); 26268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2627b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 2628945ec3a2bec668ca845071a65df8ec55e8f43819commit-bot@chromium.org LOOPER_END 26294325d114a5679e46f25ae75b0e43547fd7694998commit-bot@chromium.org} 26304325d114a5679e46f25ae75b0e43547fd7694998commit-bot@chromium.org 263100d5c2c6523321d25b32905ff4822f083a4173eefmalitavoid SkCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 263200d5c2c6523321d25b32905ff4822f083a4173eefmalita const SkPaint& paint) { 26337ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita 263485d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita SkRect storage; 263596fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 263619653d1d004610b4ba07ce563a5701164e120e45fmalita if (paint.canComputeFastBounds()) { 263785d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita storage = blob->bounds().makeOffset(x, y); 263887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect tmp; 263987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(storage, &tmp))) { 264087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 264187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 264287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &storage; 26437ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita } 26447ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita 2645024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita // We cannot filter in the looper as we normally do, because the paint is 2646024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita // incomplete at this point (text-related attributes are embedded within blob run paints). 2647024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita SkDrawFilter* drawFilter = fMCRec->fFilter; 264896fcdcc219d2a0d3579719b84b28bede76efba64halcanary fMCRec->fFilter = nullptr; 2649024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita 265085d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, bounds) 265100d5c2c6523321d25b32905ff4822f083a4173eefmalita 2652aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita while (iter.next()) { 2653aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 2654024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita iter.fDevice->drawTextBlob(iter, blob, x, y, dfp.paint(), drawFilter); 265500d5c2c6523321d25b32905ff4822f083a4173eefmalita } 265600d5c2c6523321d25b32905ff4822f083a4173eefmalita 2657aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita LOOPER_END 2658024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita 2659024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita fMCRec->fFilter = drawFilter; 266000d5c2c6523321d25b32905ff4822f083a4173eefmalita} 266100d5c2c6523321d25b32905ff4822f083a4173eefmalita 2662e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com// These will become non-virtual, so they always call the (virtual) onDraw... method 2663e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 2664e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 26659881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawText()"); 2666e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawText(text, byteLength, x, y, paint); 2667e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2668e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawPosText(const void* text, size_t byteLength, const SkPoint pos[], 2669e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 26709881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPosText()"); 2671e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawPosText(text, byteLength, pos, paint); 2672e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2673e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], 2674e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com SkScalar constY, const SkPaint& paint) { 26759881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPosTextH()"); 2676e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawPosTextH(text, byteLength, xpos, constY, paint); 2677e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2678e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 2679e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkMatrix* matrix, const SkPaint& paint) { 26809881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextOnPath()"); 2681e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawTextOnPath(text, byteLength, path, matrix, paint); 2682e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 268300d5c2c6523321d25b32905ff4822f083a4173eefmalitavoid SkCanvas::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 268400d5c2c6523321d25b32905ff4822f083a4173eefmalita const SkPaint& paint) { 2685e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(blob); 26869881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextBlob()"); 2687e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawTextBlob(blob, x, y, paint); 268800d5c2c6523321d25b32905ff4822f083a4173eefmalita} 2689e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com 269041af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawVertices(VertexMode vmode, int vertexCount, 269141af966ab338e95eee81ab618ab28195075338f7reed const SkPoint verts[], const SkPoint texs[], 269241af966ab338e95eee81ab618ab28195075338f7reed const SkColor colors[], SkXfermode* xmode, 269341af966ab338e95eee81ab618ab28195075338f7reed const uint16_t indices[], int indexCount, 269441af966ab338e95eee81ab618ab28195075338f7reed const SkPaint& paint) { 26959881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawVertices()"); 269696fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, nullptr) 26974b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 26988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 26998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawVertices(iter, vmode, vertexCount, verts, texs, 27004e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com colors, xmode, indices, indexCount, 27014e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com looper.paint()); 27028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 27034b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 27044e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 27058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2707b3c9d1c33caf325aada244204215eb790c228c12dandovvoid SkCanvas::drawPatch(const SkPoint cubics[12], const SkColor colors[4], 2708b3c9d1c33caf325aada244204215eb790c228c12dandov const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint) { 27099881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPatch()"); 271096fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == cubics) { 2711b3c9d1c33caf325aada244204215eb790c228c12dandov return; 2712b3c9d1c33caf325aada244204215eb790c228c12dandov } 27136cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2714ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov // Since a patch is always within the convex hull of the control points, we discard it when its 2715ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov // bounding rectangle is completely outside the current clip. 2716ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov SkRect bounds; 2717b3c9d1c33caf325aada244204215eb790c228c12dandov bounds.set(cubics, SkPatchUtils::kNumCtrlPts); 2718ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov if (this->quickReject(bounds)) { 2719ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov return; 2720ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov } 27216cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2722b3c9d1c33caf325aada244204215eb790c228c12dandov this->onDrawPatch(cubics, colors, texCoords, xmode, paint); 2723b3c9d1c33caf325aada244204215eb790c228c12dandov} 2724b3c9d1c33caf325aada244204215eb790c228c12dandov 2725b3c9d1c33caf325aada244204215eb790c228c12dandovvoid SkCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], 2726b3c9d1c33caf325aada244204215eb790c228c12dandov const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint) { 2727b3c9d1c33caf325aada244204215eb790c228c12dandov 272896fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, nullptr) 27296cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2730ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov while (iter.next()) { 2731b3c9d1c33caf325aada244204215eb790c228c12dandov iter.fDevice->drawPatch(iter, cubics, colors, texCoords, xmode, paint); 2732ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov } 27336cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2734ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov LOOPER_END 2735ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov} 2736ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov 2737a8db72864a43ad1fbba3c2892cf5cd88060a43efreedvoid SkCanvas::drawDrawable(SkDrawable* dr, SkScalar x, SkScalar y) { 2738e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(dr); 2739e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed if (x || y) { 2740e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed SkMatrix matrix = SkMatrix::MakeTrans(x, y); 2741e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawDrawable(dr, &matrix); 2742e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed } else { 2743e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawDrawable(dr, nullptr); 2744a8db72864a43ad1fbba3c2892cf5cd88060a43efreed } 2745a8db72864a43ad1fbba3c2892cf5cd88060a43efreed} 2746a8db72864a43ad1fbba3c2892cf5cd88060a43efreed 2747a8db72864a43ad1fbba3c2892cf5cd88060a43efreedvoid SkCanvas::drawDrawable(SkDrawable* dr, const SkMatrix* matrix) { 2748e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(dr); 2749e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed if (matrix && matrix->isIdentity()) { 2750e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed matrix = nullptr; 27516a070dc06af4e9f305f9d08a69e34d18ade473cbreed } 2752e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawDrawable(dr, matrix); 27536a070dc06af4e9f305f9d08a69e34d18ade473cbreed} 27546a070dc06af4e9f305f9d08a69e34d18ade473cbreed 2755a8db72864a43ad1fbba3c2892cf5cd88060a43efreedvoid SkCanvas::onDrawDrawable(SkDrawable* dr, const SkMatrix* matrix) { 2756a8db72864a43ad1fbba3c2892cf5cd88060a43efreed SkRect bounds = dr->getBounds(); 2757a8db72864a43ad1fbba3c2892cf5cd88060a43efreed if (matrix) { 2758a8db72864a43ad1fbba3c2892cf5cd88060a43efreed matrix->mapRect(&bounds); 2759a8db72864a43ad1fbba3c2892cf5cd88060a43efreed } 2760a8db72864a43ad1fbba3c2892cf5cd88060a43efreed if (this->quickReject(bounds)) { 2761a8db72864a43ad1fbba3c2892cf5cd88060a43efreed return; 2762a8db72864a43ad1fbba3c2892cf5cd88060a43efreed } 2763a8db72864a43ad1fbba3c2892cf5cd88060a43efreed dr->draw(this, matrix); 27646a070dc06af4e9f305f9d08a69e34d18ade473cbreed} 27656a070dc06af4e9f305f9d08a69e34d18ade473cbreed 276671c3c760a83123ee0b3127b8c65c6394ce541c50reedvoid SkCanvas::onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], 276771c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkColor colors[], int count, SkXfermode::Mode mode, 276871c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkRect* cull, const SkPaint* paint) { 276971c3c760a83123ee0b3127b8c65c6394ce541c50reed if (cull && this->quickReject(*cull)) { 277071c3c760a83123ee0b3127b8c65c6394ce541c50reed return; 277171c3c760a83123ee0b3127b8c65c6394ce541c50reed } 277271c3c760a83123ee0b3127b8c65c6394ce541c50reed 277371c3c760a83123ee0b3127b8c65c6394ce541c50reed SkPaint pnt; 277471c3c760a83123ee0b3127b8c65c6394ce541c50reed if (paint) { 277571c3c760a83123ee0b3127b8c65c6394ce541c50reed pnt = *paint; 277671c3c760a83123ee0b3127b8c65c6394ce541c50reed } 27779d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 277896fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(pnt, SkDrawFilter::kPath_Type, nullptr) 277971c3c760a83123ee0b3127b8c65c6394ce541c50reed while (iter.next()) { 278071c3c760a83123ee0b3127b8c65c6394ce541c50reed iter.fDevice->drawAtlas(iter, atlas, xform, tex, colors, count, mode, pnt); 278171c3c760a83123ee0b3127b8c65c6394ce541c50reed } 278271c3c760a83123ee0b3127b8c65c6394ce541c50reed LOOPER_END 278371c3c760a83123ee0b3127b8c65c6394ce541c50reed} 278471c3c760a83123ee0b3127b8c65c6394ce541c50reed 2785f70b531daaf47db1ee95c70da9843f1dd1f418d3reedvoid SkCanvas::onDrawAnnotation(const SkRect& rect, const char key[], SkData* value) { 2786f70b531daaf47db1ee95c70da9843f1dd1f418d3reed SkASSERT(key); 2787f70b531daaf47db1ee95c70da9843f1dd1f418d3reed 2788f70b531daaf47db1ee95c70da9843f1dd1f418d3reed SkPaint paint; 2789f70b531daaf47db1ee95c70da9843f1dd1f418d3reed LOOPER_BEGIN(paint, SkDrawFilter::kRect_Type, nullptr) 2790f70b531daaf47db1ee95c70da9843f1dd1f418d3reed while (iter.next()) { 2791f70b531daaf47db1ee95c70da9843f1dd1f418d3reed iter.fDevice->drawAnnotation(iter, rect, key, value); 2792f70b531daaf47db1ee95c70da9843f1dd1f418d3reed } 2793f70b531daaf47db1ee95c70da9843f1dd1f418d3reed LOOPER_END 2794f70b531daaf47db1ee95c70da9843f1dd1f418d3reed} 2795f70b531daaf47db1ee95c70da9843f1dd1f418d3reed 27968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 27978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// These methods are NOT virtual, and therefore must call back into virtual 27988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// methods, rather than actually drawing themselves. 27998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 28008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b, 2802845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com SkXfermode::Mode mode) { 28039881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawARGB()"); 28048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 28058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setARGB(a, r, g, b); 2807845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com if (SkXfermode::kSrcOver_Mode != mode) { 28080baf19375466cfc24c96532df406e7c5b1d1aae8reed@android.com paint.setXfermodeMode(mode); 28098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 28108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPaint(paint); 28118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2813845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.comvoid SkCanvas::drawColor(SkColor c, SkXfermode::Mode mode) { 28149881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawColor()"); 28158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 28168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setColor(c); 2818845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com if (SkXfermode::kSrcOver_Mode != mode) { 28190baf19375466cfc24c96532df406e7c5b1d1aae8reed@android.com paint.setXfermodeMode(mode); 28208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 28218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPaint(paint); 28228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPoint(SkScalar x, SkScalar y, const SkPaint& paint) { 28259881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPoint(SkPaint)"); 28268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pt; 28274b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 28288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pt.set(x, y); 28298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kPoints_PointMode, 1, &pt, paint); 28308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPoint(SkScalar x, SkScalar y, SkColor color) { 28339881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPoint(SkColor)"); 28348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pt; 28358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 28364b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 28378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pt.set(x, y); 28388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setColor(color); 28398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kPoints_PointMode, 1, &pt, paint); 28408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, 28438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 28449881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawLine()"); 28458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pts[2]; 28464b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 28478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pts[0].set(x0, y0); 28488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pts[1].set(x1, y1); 28498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kLines_PointMode, 2, pts, paint); 28508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawRectCoords(SkScalar left, SkScalar top, 28538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar right, SkScalar bottom, 28548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 28559881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRectCoords()"); 28568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 28578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.set(left, top, right, bottom); 28598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawRect(r, paint); 28608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, 28638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 28649881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawCircle()"); 28658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (radius < 0) { 28668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com radius = 0; 28678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 28688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 28708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.set(cx - radius, cy - radius, cx + radius, cy + radius); 28714ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->drawOval(r, paint); 28728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawRoundRect(const SkRect& r, SkScalar rx, SkScalar ry, 28758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 28769881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRoundRect()"); 28778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (rx > 0 && ry > 0) { 28788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.canComputeFastBounds()) { 28798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect storage; 28803b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(paint.computeFastBounds(r, &storage))) { 28818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 28828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 28838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 28844ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com SkRRect rrect; 28854ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com rrect.setRectXY(r, rx, ry); 28864ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->drawRRect(rrect, paint); 28878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 28888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawRect(r, paint); 28898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 28908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawArc(const SkRect& oval, SkScalar startAngle, 28938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar sweepAngle, bool useCenter, 28948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 28959881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawArc()"); 28968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (SkScalarAbs(sweepAngle) >= SkIntToScalar(360)) { 28978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawOval(oval, paint); 28988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 28998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath path; 29008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (useCenter) { 29018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.moveTo(oval.centerX(), oval.centerY()); 29028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 29038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.arcTo(oval, startAngle, sweepAngle, !useCenter); 29048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (useCenter) { 29058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.close(); 29068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 29078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPath(path, paint); 29088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 29098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 29108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawTextOnPathHV(const void* text, size_t byteLength, 29128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPath& path, SkScalar hOffset, 29138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar vOffset, const SkPaint& paint) { 29149881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextOnPathHV()"); 29158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 29164b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 29178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.setTranslate(hOffset, vOffset); 29188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawTextOnPath(text, byteLength, path, &matrix, paint); 29198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 29208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2921f76bacff7f66724072c67edb185abf9e3add11a0reed@android.com/////////////////////////////////////////////////////////////////////////////// 29221c2c441fede0ae9573afc098017011e3439624a9reed 29231c2c441fede0ae9573afc098017011e3439624a9reed/** 29241c2c441fede0ae9573afc098017011e3439624a9reed * This constant is trying to balance the speed of ref'ing a subpicture into a parent picture, 29251c2c441fede0ae9573afc098017011e3439624a9reed * against the playback cost of recursing into the subpicture to get at its actual ops. 29261c2c441fede0ae9573afc098017011e3439624a9reed * 29271c2c441fede0ae9573afc098017011e3439624a9reed * For now we pick a conservatively small value, though measurement (and other heuristics like 29281c2c441fede0ae9573afc098017011e3439624a9reed * the type of ops contained) may justify changing this value. 29291c2c441fede0ae9573afc098017011e3439624a9reed */ 29301c2c441fede0ae9573afc098017011e3439624a9reed#define kMaxPictureOpsToUnrollInsteadOfRef 1 29319b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips 2932d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedvoid SkCanvas::drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint) { 2933e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(picture); 2934e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed 29351c2c441fede0ae9573afc098017011e3439624a9reed TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPicture()"); 2936e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed if (matrix && matrix->isIdentity()) { 2937e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed matrix = nullptr; 2938e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed } 2939e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed if (picture->approximateOpCount() <= kMaxPictureOpsToUnrollInsteadOfRef) { 2940e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); 2941e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed picture->playback(this); 2942e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed } else { 2943e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawPicture(picture, matrix, paint); 2944d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 2945d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 29469b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips 2947d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedvoid SkCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix, 2948d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed const SkPaint* paint) { 2949d028180f0310cf2b23f9744256a41697b0683e67fmalita if (!paint || paint->canComputeFastBounds()) { 2950d028180f0310cf2b23f9744256a41697b0683e67fmalita SkRect bounds = picture->cullRect(); 2951d028180f0310cf2b23f9744256a41697b0683e67fmalita if (paint) { 2952d028180f0310cf2b23f9744256a41697b0683e67fmalita paint->computeFastBounds(bounds, &bounds); 2953d028180f0310cf2b23f9744256a41697b0683e67fmalita } 2954d028180f0310cf2b23f9744256a41697b0683e67fmalita if (matrix) { 2955d028180f0310cf2b23f9744256a41697b0683e67fmalita matrix->mapRect(&bounds); 2956d028180f0310cf2b23f9744256a41697b0683e67fmalita } 2957d028180f0310cf2b23f9744256a41697b0683e67fmalita if (this->quickReject(bounds)) { 2958d028180f0310cf2b23f9744256a41697b0683e67fmalita return; 2959d028180f0310cf2b23f9744256a41697b0683e67fmalita } 2960d028180f0310cf2b23f9744256a41697b0683e67fmalita } 2961d028180f0310cf2b23f9744256a41697b0683e67fmalita 2962145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org SkBaseDevice* device = this->getTopDevice(); 296349f085dddff10473b6ebf832a974288300224e60bsalomon if (device) { 2964145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org // Canvas has to first give the device the opportunity to render 2965145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org // the picture itself. 2966d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed if (device->EXPERIMENTAL_drawPicture(this, picture, matrix, paint)) { 2967145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org return; // the device has rendered the entire picture 2968145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org } 2969145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org } 2970145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org 2971a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); 2972c5ba71d2e5cd426def66fa49dcf003e5b2c98dc7robertphillips picture->playback(this); 29738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 29748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 29768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 29778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::LayerIter::LayerIter(SkCanvas* canvas, bool skipEmptyClips) { 297999fe82260633fcf5d92cca38d12ef0937ecca61cbungeman static_assert(sizeof(fStorage) >= sizeof(SkDrawIter), "fStorage_too_small"); 29808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(canvas); 29828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fImpl = new (fStorage) SkDrawIter(canvas, skipEmptyClips); 29848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDone = !fImpl->next(); 29858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 29868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::LayerIter::~LayerIter() { 29888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fImpl->~SkDrawIter(); 29898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 29908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::LayerIter::next() { 29928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDone = !fImpl->next(); 29938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 29948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29951f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::LayerIter::device() const { 29968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fImpl->getDevice(); 29978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 29988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkMatrix& SkCanvas::LayerIter::matrix() const { 30008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fImpl->getMatrix(); 30018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 30028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkPaint& SkCanvas::LayerIter::paint() const { 30048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* paint = fImpl->getPaint(); 300596fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 30068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint = &fDefaultPaint; 30078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 30088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return *paint; 30098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 30108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30111e7f5e708e5daeb0c18ae49001c9e3cd5e3b13cbreedconst SkRasterClip& SkCanvas::LayerIter::clip() const { return fImpl->getClip(); } 30128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::LayerIter::x() const { return fImpl->getX(); } 30138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::LayerIter::y() const { return fImpl->getY(); } 301420a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com 301520a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com/////////////////////////////////////////////////////////////////////////////// 301620a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com 3017c3b589a24eb4d567a906189f882c259ecf5c2f58fmalitaSkCanvasClipVisitor::~SkCanvasClipVisitor() { } 30183107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 30193107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 30203107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 30213107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.orgstatic bool supported_for_raster_canvas(const SkImageInfo& info) { 30223107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org switch (info.alphaType()) { 30233107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kPremul_SkAlphaType: 30243107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kOpaque_SkAlphaType: 30253107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org break; 30263107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org default: 30273107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return false; 30283107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 30293107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 30303107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org switch (info.colorType()) { 30313107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kAlpha_8_SkColorType: 30323107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kRGB_565_SkColorType: 303328fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org case kN32_SkColorType: 30343107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org break; 30353107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org default: 30363107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return false; 30373107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 30383107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 30393107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return true; 30403107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org} 30413107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 304242b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.orgSkCanvas* SkCanvas::NewRasterDirect(const SkImageInfo& info, void* pixels, size_t rowBytes) { 304342b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org if (!supported_for_raster_canvas(info)) { 304496fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 304542b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org } 3046eb849e5fd10cbe00cbc31307ba97fd9efca0b41bskia.committer@gmail.com 304742b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org SkBitmap bitmap; 304842b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org if (!bitmap.installPixels(info, pixels, rowBytes)) { 304996fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 305042b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org } 3051385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return new SkCanvas(bitmap); 305242b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org} 3053d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 3054d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed/////////////////////////////////////////////////////////////////////////////// 3055d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 3056d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedSkAutoCanvasMatrixPaint::SkAutoCanvasMatrixPaint(SkCanvas* canvas, const SkMatrix* matrix, 3057a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips const SkPaint* paint, const SkRect& bounds) 3058d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed : fCanvas(canvas) 3059d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed , fSaveCount(canvas->getSaveCount()) 3060d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed{ 306149f085dddff10473b6ebf832a974288300224e60bsalomon if (paint) { 3062a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkRect newBounds = bounds; 3063d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed if (matrix) { 3064a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips matrix->mapRect(&newBounds); 3065d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 3066a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips canvas->saveLayer(&newBounds, paint); 306749f085dddff10473b6ebf832a974288300224e60bsalomon } else if (matrix) { 3068d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed canvas->save(); 3069d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 30706cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 307149f085dddff10473b6ebf832a974288300224e60bsalomon if (matrix) { 3072d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed canvas->concat(*matrix); 3073d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 3074d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 3075d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 3076d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedSkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { 3077d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed fCanvas->restoreToCount(fSaveCount); 3078d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 3079e8f3062a36d3682f4019309a32b5b84dc9eddf8creed 3080e8f3062a36d3682f4019309a32b5b84dc9eddf8creed#ifdef SK_SUPPORT_LEGACY_NEW_SURFACE_API 3081e8f3062a36d3682f4019309a32b5b84dc9eddf8creedSkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* props) { 3082e8f3062a36d3682f4019309a32b5b84dc9eddf8creed return this->makeSurface(info, props).release(); 3083e8f3062a36d3682f4019309a32b5b84dc9eddf8creed} 3084e8f3062a36d3682f4019309a32b5b84dc9eddf8creed#endif 3085