SkCanvas.cpp revision 7765000709dc64eb23be7df47d1f995d1f787115
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" 13d3ebb48320cf1b7e969974673e4bd7743816985ebungeman#include "SkDevice.h" 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDraw.h" 153cb3840c9af6f70896cf5565a38d4ee03c02d767reed#include "SkDrawable.h" 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDrawFilter.h" 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDrawLooper.h" 185f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt#include "SkErrorInternals.h" 19b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr#include "SkImage.h" 20262a71b7f95ce98ff3dd8dba845afbd724470903reed#include "SkImage_Base.h" 21262a71b7f95ce98ff3dd8dba845afbd724470903reed#include "SkMatrixUtils.h" 2274bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org#include "SkMetaData.h" 234c21dc5ddf3b482293ed34eead876d8d61a662c3reed#include "SkNinePatchIter.h" 24c83a29759a5c2966da5ab973e4fd90763e4c962breed#include "SkPaintPriv.h" 25b3c9d1c33caf325aada244204215eb790c228c12dandov#include "SkPatchUtils.h" 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPicture.h" 270017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com#include "SkRasterClip.h" 2896472deea70169396b8e1f576e470138f55fdb1freed#include "SkReadPixelsRec.h" 294ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com#include "SkRRect.h" 3079fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org#include "SkSmallAllocator.h" 3197af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com#include "SkSurface_Base.h" 327ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita#include "SkTextBlob.h" 3352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com#include "SkTextFormatParams.h" 34a076e9be17654a60310e72c4f70fcd5337f56dbfreed@google.com#include "SkTLazy.h" 358f757f540a8378c7b1354aab3d4650eaa920b17adanakj#include "SkTraceEvent.h" 36d3ebb48320cf1b7e969974673e4bd7743816985ebungeman 37d3ebb48320cf1b7e969974673e4bd7743816985ebungeman#include <new> 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 39644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#if SK_SUPPORT_GPU 407354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips#include "GrContext.h" 41644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#include "GrRenderTarget.h" 427354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips#include "SkGr.h" 43644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#endif 44644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org 45e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed#define RETURN_ON_NULL(ptr) do { if (nullptr == (ptr)) return; } while (0) 46e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed 47c83a29759a5c2966da5ab973e4fd90763e4c962breed/* 48c83a29759a5c2966da5ab973e4fd90763e4c962breed * Return true if the drawing this rect would hit every pixels in the canvas. 49c83a29759a5c2966da5ab973e4fd90763e4c962breed * 50c83a29759a5c2966da5ab973e4fd90763e4c962breed * Returns false if 51c83a29759a5c2966da5ab973e4fd90763e4c962breed * - rect does not contain the canvas' bounds 52c83a29759a5c2966da5ab973e4fd90763e4c962breed * - paint is not fill 53c83a29759a5c2966da5ab973e4fd90763e4c962breed * - paint would blur or otherwise change the coverage of the rect 54c83a29759a5c2966da5ab973e4fd90763e4c962breed */ 55c83a29759a5c2966da5ab973e4fd90763e4c962breedbool SkCanvas::wouldOverwriteEntireSurface(const SkRect* rect, const SkPaint* paint, 56c83a29759a5c2966da5ab973e4fd90763e4c962breed ShaderOverrideOpacity overrideOpacity) const { 5799fe82260633fcf5d92cca38d12ef0937ecca61cbungeman static_assert((int)SkPaintPriv::kNone_ShaderOverrideOpacity == 5899fe82260633fcf5d92cca38d12ef0937ecca61cbungeman (int)kNone_ShaderOverrideOpacity, 5999fe82260633fcf5d92cca38d12ef0937ecca61cbungeman "need_matching_enums0"); 6099fe82260633fcf5d92cca38d12ef0937ecca61cbungeman static_assert((int)SkPaintPriv::kOpaque_ShaderOverrideOpacity == 6199fe82260633fcf5d92cca38d12ef0937ecca61cbungeman (int)kOpaque_ShaderOverrideOpacity, 6299fe82260633fcf5d92cca38d12ef0937ecca61cbungeman "need_matching_enums1"); 6399fe82260633fcf5d92cca38d12ef0937ecca61cbungeman static_assert((int)SkPaintPriv::kNotOpaque_ShaderOverrideOpacity == 6499fe82260633fcf5d92cca38d12ef0937ecca61cbungeman (int)kNotOpaque_ShaderOverrideOpacity, 6599fe82260633fcf5d92cca38d12ef0937ecca61cbungeman "need_matching_enums2"); 66c83a29759a5c2966da5ab973e4fd90763e4c962breed 67c83a29759a5c2966da5ab973e4fd90763e4c962breed const SkISize size = this->getBaseLayerSize(); 68c83a29759a5c2966da5ab973e4fd90763e4c962breed const SkRect bounds = SkRect::MakeIWH(size.width(), size.height()); 69c83a29759a5c2966da5ab973e4fd90763e4c962breed if (!this->getClipStack()->quickContains(bounds)) { 70c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; 71c83a29759a5c2966da5ab973e4fd90763e4c962breed } 72c83a29759a5c2966da5ab973e4fd90763e4c962breed 73c83a29759a5c2966da5ab973e4fd90763e4c962breed if (rect) { 74c83a29759a5c2966da5ab973e4fd90763e4c962breed if (!this->getTotalMatrix().rectStaysRect()) { 75c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; // conservative 76c83a29759a5c2966da5ab973e4fd90763e4c962breed } 77c83a29759a5c2966da5ab973e4fd90763e4c962breed 78c83a29759a5c2966da5ab973e4fd90763e4c962breed SkRect devRect; 79c83a29759a5c2966da5ab973e4fd90763e4c962breed this->getTotalMatrix().mapRect(&devRect, *rect); 808c0144ccb17220db9d5140ef5ee85d5bc7837513fmalita if (!devRect.contains(bounds)) { 81c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; 82c83a29759a5c2966da5ab973e4fd90763e4c962breed } 83c83a29759a5c2966da5ab973e4fd90763e4c962breed } 84c83a29759a5c2966da5ab973e4fd90763e4c962breed 85c83a29759a5c2966da5ab973e4fd90763e4c962breed if (paint) { 86c83a29759a5c2966da5ab973e4fd90763e4c962breed SkPaint::Style paintStyle = paint->getStyle(); 87c83a29759a5c2966da5ab973e4fd90763e4c962breed if (!(paintStyle == SkPaint::kFill_Style || 88c83a29759a5c2966da5ab973e4fd90763e4c962breed paintStyle == SkPaint::kStrokeAndFill_Style)) { 89c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; 90c83a29759a5c2966da5ab973e4fd90763e4c962breed } 91c83a29759a5c2966da5ab973e4fd90763e4c962breed if (paint->getMaskFilter() || paint->getLooper() 92c83a29759a5c2966da5ab973e4fd90763e4c962breed || paint->getPathEffect() || paint->getImageFilter()) { 93c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; // conservative 94c83a29759a5c2966da5ab973e4fd90763e4c962breed } 95c83a29759a5c2966da5ab973e4fd90763e4c962breed } 96c83a29759a5c2966da5ab973e4fd90763e4c962breed return SkPaintPriv::Overwrites(paint, (SkPaintPriv::ShaderOverrideOpacity)overrideOpacity); 97c83a29759a5c2966da5ab973e4fd90763e4c962breed} 98c83a29759a5c2966da5ab973e4fd90763e4c962breed 99c83a29759a5c2966da5ab973e4fd90763e4c962breed/////////////////////////////////////////////////////////////////////////////////////////////////// 100c83a29759a5c2966da5ab973e4fd90763e4c962breed 101d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareedstatic bool gIgnoreSaveLayerBounds; 102d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareedvoid SkCanvas::Internal_Private_SetIgnoreSaveLayerBounds(bool ignore) { 103d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed gIgnoreSaveLayerBounds = ignore; 104d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed} 105d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareedbool SkCanvas::Internal_Private_GetIgnoreSaveLayerBounds() { 106d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed return gIgnoreSaveLayerBounds; 107d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed} 108d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed 1090acf1b4b3645772d220c720313821bac389751b5reedstatic bool gTreatSpriteAsBitmap; 1100acf1b4b3645772d220c720313821bac389751b5reedvoid SkCanvas::Internal_Private_SetTreatSpriteAsBitmap(bool spriteAsBitmap) { 1110acf1b4b3645772d220c720313821bac389751b5reed gTreatSpriteAsBitmap = spriteAsBitmap; 1120acf1b4b3645772d220c720313821bac389751b5reed} 1130acf1b4b3645772d220c720313821bac389751b5reedbool SkCanvas::Internal_Private_GetTreatSpriteAsBitmap() { 1140acf1b4b3645772d220c720313821bac389751b5reed return gTreatSpriteAsBitmap; 1150acf1b4b3645772d220c720313821bac389751b5reed} 1160acf1b4b3645772d220c720313821bac389751b5reed 117da17f758442f16747af39f8fbaed9c097048519creed@google.com// experimental for faster tiled drawing... 118da17f758442f16747af39f8fbaed9c097048519creed@google.com//#define SK_ENABLE_CLIP_QUICKREJECT 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//#define SK_TRACE_SAVERESTORE 1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_TRACE_SAVERESTORE 1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gLayerCounter; 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_layer() { ++gLayerCounter; printf("----- inc layer %d\n", gLayerCounter); } 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_layer() { --gLayerCounter; printf("----- dec layer %d\n", gLayerCounter); } 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gRecCounter; 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_rec() { ++gRecCounter; printf("----- inc rec %d\n", gRecCounter); } 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_rec() { --gRecCounter; printf("----- dec rec %d\n", gRecCounter); } 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gCanvasCounter; 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_canvas() { ++gCanvasCounter; printf("----- inc canvas %d\n", gCanvasCounter); } 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_canvas() { --gCanvasCounter; printf("----- dec canvas %d\n", gCanvasCounter); } 1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_layer() 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_layer() 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_rec() 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_rec() 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_canvas() 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_canvas() 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1422c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.orgtypedef SkTLazy<SkPaint> SkLazyPaint; 1432c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org 144c83a29759a5c2966da5ab973e4fd90763e4c962breedvoid SkCanvas::predrawNotify(bool willOverwritesEntireSurface) { 14597af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com if (fSurfaceBase) { 146c83a29759a5c2966da5ab973e4fd90763e4c962breed fSurfaceBase->aboutToDraw(willOverwritesEntireSurface 147c83a29759a5c2966da5ab973e4fd90763e4c962breed ? SkSurface::kDiscard_ContentChangeMode 148c83a29759a5c2966da5ab973e4fd90763e4c962breed : SkSurface::kRetain_ContentChangeMode); 149c83a29759a5c2966da5ab973e4fd90763e4c962breed } 150c83a29759a5c2966da5ab973e4fd90763e4c962breed} 151c83a29759a5c2966da5ab973e4fd90763e4c962breed 152c83a29759a5c2966da5ab973e4fd90763e4c962breedvoid SkCanvas::predrawNotify(const SkRect* rect, const SkPaint* paint, 153c83a29759a5c2966da5ab973e4fd90763e4c962breed ShaderOverrideOpacity overrideOpacity) { 154c83a29759a5c2966da5ab973e4fd90763e4c962breed if (fSurfaceBase) { 155c83a29759a5c2966da5ab973e4fd90763e4c962breed SkSurface::ContentChangeMode mode = SkSurface::kRetain_ContentChangeMode; 156c83a29759a5c2966da5ab973e4fd90763e4c962breed // Since willOverwriteAllPixels() may not be complete free to call, we only do so if 157c83a29759a5c2966da5ab973e4fd90763e4c962breed // there is an outstanding snapshot, since w/o that, there will be no copy-on-write 158c83a29759a5c2966da5ab973e4fd90763e4c962breed // and therefore we don't care which mode we're in. 159c83a29759a5c2966da5ab973e4fd90763e4c962breed // 160c83a29759a5c2966da5ab973e4fd90763e4c962breed if (fSurfaceBase->outstandingImageSnapshot()) { 161c83a29759a5c2966da5ab973e4fd90763e4c962breed if (this->wouldOverwriteEntireSurface(rect, paint, overrideOpacity)) { 162c83a29759a5c2966da5ab973e4fd90763e4c962breed mode = SkSurface::kDiscard_ContentChangeMode; 163c83a29759a5c2966da5ab973e4fd90763e4c962breed } 164c83a29759a5c2966da5ab973e4fd90763e4c962breed } 165c83a29759a5c2966da5ab973e4fd90763e4c962breed fSurfaceBase->aboutToDraw(mode); 16697af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com } 16797af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com} 16897af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com 1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1714a8126e7f81384526629b1e21bf89b632ea13cd9reedstatic uint32_t filter_paint_flags(const SkSurfaceProps& props, uint32_t flags) { 1724a8126e7f81384526629b1e21bf89b632ea13cd9reed const uint32_t propFlags = props.flags(); 1734a8126e7f81384526629b1e21bf89b632ea13cd9reed if (propFlags & SkSurfaceProps::kDisallowDither_Flag) { 1744a8126e7f81384526629b1e21bf89b632ea13cd9reed flags &= ~SkPaint::kDither_Flag; 1754a8126e7f81384526629b1e21bf89b632ea13cd9reed } 1764a8126e7f81384526629b1e21bf89b632ea13cd9reed if (propFlags & SkSurfaceProps::kDisallowAntiAlias_Flag) { 1774a8126e7f81384526629b1e21bf89b632ea13cd9reed flags &= ~SkPaint::kAntiAlias_Flag; 1784a8126e7f81384526629b1e21bf89b632ea13cd9reed } 1794a8126e7f81384526629b1e21bf89b632ea13cd9reed return flags; 1804a8126e7f81384526629b1e21bf89b632ea13cd9reed} 1814a8126e7f81384526629b1e21bf89b632ea13cd9reed 1824a8126e7f81384526629b1e21bf89b632ea13cd9reed/////////////////////////////////////////////////////////////////////////////// 1834a8126e7f81384526629b1e21bf89b632ea13cd9reed 1841f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com/* This is the record we keep for each SkBaseDevice that the user installs. 1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com The clip/matrix/proc are fields that reflect the top of the save/restore 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stack. Whenever the canvas changes, it marks a dirty flag, and then before 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com these are used (assuming we're not on a layer) we rebuild these cache 1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com values: they reflect the top of the save stack, but translated and clipped 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com by the device's XY offset and bitmap-bounds. 1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct DeviceCM { 1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* fNext; 1931f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* fDevice; 194045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com SkRasterClip fClip; 1956f8f292aa768869a9e85c314b124875f57504f2creed@google.com SkPaint* fPaint; // may be null (in the future) 19661f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed const SkMatrix* fMatrix; 19761f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed SkMatrix fMatrixStorage; 19861f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed const bool fDeviceIsBitmapDevice; 1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20096e657d0e103b8358a77ecd913f6086929f792b8reed DeviceCM(SkBaseDevice* device, const SkPaint* paint, SkCanvas* canvas, 20186a17e7716c8db858e219a46b9db3817bb770beereed bool conservativeRasterClip, bool deviceIsBitmapDevice) 20296fcdcc219d2a0d3579719b84b28bede76efba64halcanary : fNext(nullptr) 203d954498c01ccf0417feacf89e45d0c62a06a813breed , fClip(conservativeRasterClip) 20461f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed , fDeviceIsBitmapDevice(deviceIsBitmapDevice) 205d954498c01ccf0417feacf89e45d0c62a06a813breed { 20696fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr != device) { 2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device->ref(); 20840a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com device->onAttachToCanvas(canvas); 2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2104b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com fDevice = device; 21196fcdcc219d2a0d3579719b84b28bede76efba64halcanary fPaint = paint ? new SkPaint(*paint) : nullptr; 21288edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21488edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com ~DeviceCM() { 21549f085dddff10473b6ebf832a974288300224e60bsalomon if (fDevice) { 21640a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com fDevice->onDetachFromCanvas(); 2178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDevice->unref(); 2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 219385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete fPaint; 22088edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 2214b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 222feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein void reset(const SkIRect& bounds) { 223feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(!fPaint); 224feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(!fNext); 225feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(fDevice); 226feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fClip.setRect(bounds); 227feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein } 228feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 229045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com void updateMC(const SkMatrix& totalMatrix, const SkRasterClip& totalClip, 230045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com const SkClipStack& clipStack, SkRasterClip* updateClip) { 2316f8f292aa768869a9e85c314b124875f57504f2creed@google.com int x = fDevice->getOrigin().x(); 2326f8f292aa768869a9e85c314b124875f57504f2creed@google.com int y = fDevice->getOrigin().y(); 2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int width = fDevice->width(); 2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int height = fDevice->height(); 2354b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if ((x | y) == 0) { 2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = &totalMatrix; 2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fClip = totalClip; 2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrixStorage = totalMatrix; 2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrixStorage.postTranslate(SkIntToScalar(-x), 2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIntToScalar(-y)); 2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = &fMatrixStorage; 2444b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com totalClip.translate(-x, -y, &fClip); 2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 248045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com fClip.op(SkIRect::MakeWH(width, height), SkRegion::kIntersect_Op); 2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // intersect clip, but don't translate it (yet) 2514b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (updateClip) { 253045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com updateClip->op(SkIRect::MakeXYWH(x, y, width, height), 2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRegion::kDifference_Op); 2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2564b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2573fffb2ee9fa01ae61efb2395973eb7575eda4c96robertphillips@google.com fDevice->setMatrixClip(*fMatrix, fClip.forceGetBW(), clipStack); 2583fffb2ee9fa01ae61efb2395973eb7575eda4c96robertphillips@google.com 2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!fClip.isEmpty()) { 2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIRect deviceR; 2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com deviceR.set(0, 0, width, height); 2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(deviceR.contains(fClip.getBounds())); 2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 266f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* This is the record we keep for each save/restore level in the stack. 2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Since a level optionally copies the matrix and/or stack, we have pointers 2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for these fields. If the value is copied for this level, the copy is 2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stored in the ...Storage field, and the pointer points to that. If the 2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value is not copied for this level, we ignore ...Storage, and just point 2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com at the corresponding value in the previous level in the stack. 2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkCanvas::MCRec { 2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 2781f836ee096bb988adef4b9757b2629c7afeda36dreed SkDrawFilter* fFilter; // the current filter (or null) 279d954498c01ccf0417feacf89e45d0c62a06a813breed DeviceCM* fLayer; 2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* If there are any layers in the stack, this points to the top-most 2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com one that is at or below this level in the stack (so we know what 2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bitmap/device to draw into from this level. This value is NOT 2838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com reference counted, since the real owner is either our fLayer field, 2848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com or a previous one in a lower level.) 2858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 2862ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed DeviceCM* fTopLayer; 2872ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkRasterClip fRasterClip; 2882ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkMatrix fMatrix; 2892ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed int fDeferredSaveCount; 2908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 291d954498c01ccf0417feacf89e45d0c62a06a813breed MCRec(bool conservativeRasterClip) : fRasterClip(conservativeRasterClip) { 29296fcdcc219d2a0d3579719b84b28bede76efba64halcanary fFilter = nullptr; 29396fcdcc219d2a0d3579719b84b28bede76efba64halcanary fLayer = nullptr; 29496fcdcc219d2a0d3579719b84b28bede76efba64halcanary fTopLayer = nullptr; 2952ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fMatrix.reset(); 2962ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fDeferredSaveCount = 0; 297b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 298d954498c01ccf0417feacf89e45d0c62a06a813breed // don't bother initializing fNext 299d954498c01ccf0417feacf89e45d0c62a06a813breed inc_rec(); 300d954498c01ccf0417feacf89e45d0c62a06a813breed } 3012ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed MCRec(const MCRec& prev) : fRasterClip(prev.fRasterClip), fMatrix(prev.fMatrix) { 302d954498c01ccf0417feacf89e45d0c62a06a813breed fFilter = SkSafeRef(prev.fFilter); 30396fcdcc219d2a0d3579719b84b28bede76efba64halcanary fLayer = nullptr; 304d954498c01ccf0417feacf89e45d0c62a06a813breed fTopLayer = prev.fTopLayer; 3052ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fDeferredSaveCount = 0; 306b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 3078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // don't bother initializing fNext 3088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inc_rec(); 3098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ~MCRec() { 31182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fFilter); 312385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete fLayer; 3138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dec_rec(); 3148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 315feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 316feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein void reset(const SkIRect& bounds) { 317feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(fLayer); 318feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(fDeferredSaveCount == 0); 319feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 320feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fMatrix.reset(); 321feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fRasterClip.setRect(bounds); 322feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fLayer->reset(bounds); 323feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein } 3248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkDrawIter : public SkDraw { 3278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 3288a0b0291ae4260ef2a46f4341c18a702c0ce3f8btomhudson@google.com SkDrawIter(SkCanvas* canvas, bool skipEmptyClips = true) { 3294370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com canvas = canvas->canvasForDrawIter(); 3308a0b0291ae4260ef2a46f4341c18a702c0ce3f8btomhudson@google.com fCanvas = canvas; 3318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com canvas->updateDeviceCMCache(); 3328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 333687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack = canvas->fClipStack; 3348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = canvas->fMCRec->fTopLayer; 3358a0b0291ae4260ef2a46f4341c18a702c0ce3f8btomhudson@google.com fSkipEmptyClips = skipEmptyClips; 3368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3374b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 3388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool next() { 3398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // skip over recs with empty clips 3408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fSkipEmptyClips) { 3418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (fCurrLayer && fCurrLayer->fClip.isEmpty()) { 3428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = fCurrLayer->fNext; 3438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 346f68c5e2f9f05b3af2bae0979ace2684b6041b6e3reed@google.com const DeviceCM* rec = fCurrLayer; 347f68c5e2f9f05b3af2bae0979ace2684b6041b6e3reed@google.com if (rec && rec->fDevice) { 3488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = rec->fMatrix; 350045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com fClip = &((SkRasterClip*)&rec->fClip)->forceGetBW(); 351045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com fRC = &rec->fClip; 3528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDevice = rec->fDevice; 35341e010cb901c0da9066c4df562030808c9ccd7f8reed if (!fDevice->accessPixels(&fDst)) { 35496fcdcc219d2a0d3579719b84b28bede76efba64halcanary fDst.reset(fDevice->imageInfo(), nullptr, 0); 35541e010cb901c0da9066c4df562030808c9ccd7f8reed } 3568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint = rec->fPaint; 357f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com SkDEBUGCODE(this->validate();) 3588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = rec->fNext; 36096fcdcc219d2a0d3579719b84b28bede76efba64halcanary // fCurrLayer may be nullptr now 361199f108f14a5f60a9c2205ffa79b26102a206ad0reed@android.com 3628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 3638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 3658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3664b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 3671f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* getDevice() const { return fDevice; } 3686f8f292aa768869a9e85c314b124875f57504f2creed@google.com int getX() const { return fDevice->getOrigin().x(); } 3696f8f292aa768869a9e85c314b124875f57504f2creed@google.com int getY() const { return fDevice->getOrigin().y(); } 3708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& getMatrix() const { return *fMatrix; } 3718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkRegion& getClip() const { return *fClip; } 3728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* getPaint() const { return fPaint; } 3736f8f292aa768869a9e85c314b124875f57504f2creed@google.com 3748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 3758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkCanvas* fCanvas; 3768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const DeviceCM* fCurrLayer; 3778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* fPaint; // May be null. 3788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkBool8 fSkipEmptyClips; 3798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef SkDraw INHERITED; 3818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////// 3848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 385dbc3cefb0b624808ddb86d444e6103f216e12fa5reedstatic SkPaint* set_if_needed(SkLazyPaint* lazy, const SkPaint& orig) { 386dbc3cefb0b624808ddb86d444e6103f216e12fa5reed return lazy->isValid() ? lazy->get() : lazy->set(orig); 387dbc3cefb0b624808ddb86d444e6103f216e12fa5reed} 388dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 389dbc3cefb0b624808ddb86d444e6103f216e12fa5reed/** 390dbc3cefb0b624808ddb86d444e6103f216e12fa5reed * If the paint has an imagefilter, but it can be simplified to just a colorfilter, return that 39196fcdcc219d2a0d3579719b84b28bede76efba64halcanary * colorfilter, else return nullptr. 392dbc3cefb0b624808ddb86d444e6103f216e12fa5reed */ 393dbc3cefb0b624808ddb86d444e6103f216e12fa5reedstatic SkColorFilter* image_to_color_filter(const SkPaint& paint) { 394dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkImageFilter* imgf = paint.getImageFilter(); 395dbc3cefb0b624808ddb86d444e6103f216e12fa5reed if (!imgf) { 39696fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 397dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 398dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 399dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkColorFilter* imgCF; 400dbc3cefb0b624808ddb86d444e6103f216e12fa5reed if (!imgf->asAColorFilter(&imgCF)) { 40196fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 402dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 403dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 404dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkColorFilter* paintCF = paint.getColorFilter(); 40596fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paintCF) { 406dbc3cefb0b624808ddb86d444e6103f216e12fa5reed // there is no existing paint colorfilter, so we can just return the imagefilter's 407dbc3cefb0b624808ddb86d444e6103f216e12fa5reed return imgCF; 408dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 409dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 410dbc3cefb0b624808ddb86d444e6103f216e12fa5reed // The paint has both a colorfilter(paintCF) and an imagefilter-which-is-a-colorfilter(imgCF) 411dbc3cefb0b624808ddb86d444e6103f216e12fa5reed // and we need to combine them into a single colorfilter. 412dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkAutoTUnref<SkColorFilter> autoImgCF(imgCF); 413dbc3cefb0b624808ddb86d444e6103f216e12fa5reed return SkColorFilter::CreateComposeFilter(imgCF, paintCF); 414dbc3cefb0b624808ddb86d444e6103f216e12fa5reed} 415dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 41687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco/** 41787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * There are many bounds in skia. A circle's bounds is just its center extended by its radius. 41887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * However, if we stroke a circle, then the "bounds" of that is larger, since it will now draw 41987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * outside of its raw-bounds by 1/2 the stroke width. SkPaint has lots of optional 42087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * effects/attributes that can modify the effective bounds of a given primitive -- maskfilters, 42187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * patheffects, stroking, etc. This function takes a raw bounds and a paint, and returns the 42287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * conservative "effective" bounds based on the settings in the paint... with one exception. This 42387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * function does *not* look at the imagefilter, which can also modify the effective bounds. It is 42487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * deliberately ignored. 42587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco */ 42687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblancostatic const SkRect& apply_paint_to_bounds_sans_imagefilter(const SkPaint& paint, 42787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco const SkRect& rawBounds, 42887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect* storage) { 42987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkPaint tmpUnfiltered(paint); 43087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco tmpUnfiltered.setImageFilter(nullptr); 43187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (tmpUnfiltered.canComputeFastBounds()) { 43287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return tmpUnfiltered.computeFastBounds(rawBounds, storage); 43387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } else { 43487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return rawBounds; 43587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 43687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco} 43787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco 4388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass AutoDrawLooper { 4398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 44087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco // "rawBounds" is the original bounds of the primitive about to be drawn, unmodified by the 44187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco // paint. It's used to determine the size of the offscreen layer for filters. 44287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco // If null, the clip will be used instead. 4434a8126e7f81384526629b1e21bf89b632ea13cd9reed AutoDrawLooper(SkCanvas* canvas, const SkSurfaceProps& props, const SkPaint& paint, 44478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bool skipLayerForImageFilter = false, 44587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco const SkRect* rawBounds = nullptr) : fOrigPaint(paint) { 4464e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fCanvas = canvas; 4477765000709dc64eb23be7df47d1f995d1f787115fmalita#ifdef SK_SUPPORT_LEGACY_DRAWFLTER 4488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFilter = canvas->getDrawFilter(); 4497765000709dc64eb23be7df47d1f995d1f787115fmalita#else 4507765000709dc64eb23be7df47d1f995d1f787115fmalita fFilter = nullptr; 4517765000709dc64eb23be7df47d1f995d1f787115fmalita#endif 4524a8126e7f81384526629b1e21bf89b632ea13cd9reed fPaint = &fOrigPaint; 4534e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fSaveCount = canvas->getSaveCount(); 4545c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed fTempLayerForImageFilter = false; 4554e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fDone = false; 4568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 457dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkColorFilter* simplifiedCF = image_to_color_filter(fOrigPaint); 458dbc3cefb0b624808ddb86d444e6103f216e12fa5reed if (simplifiedCF) { 459dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkPaint* paint = set_if_needed(&fLazyPaintInit, fOrigPaint); 460dbc3cefb0b624808ddb86d444e6103f216e12fa5reed paint->setColorFilter(simplifiedCF)->unref(); 46196fcdcc219d2a0d3579719b84b28bede76efba64halcanary paint->setImageFilter(nullptr); 462dbc3cefb0b624808ddb86d444e6103f216e12fa5reed fPaint = paint; 463dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 464dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 465dbc3cefb0b624808ddb86d444e6103f216e12fa5reed if (!skipLayerForImageFilter && fPaint->getImageFilter()) { 4665c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed /** 4675c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * We implement ImageFilters for a given draw by creating a layer, then applying the 4685c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * imagefilter to the pixels of that layer (its backing surface/image), and then 4695c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * we call restore() to xfer that layer to the main canvas. 4705c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 4715c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 1. SaveLayer (with a paint containing the current imagefilter and xfermode) 4725c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 2. Generate the src pixels: 4735c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * Remove the imagefilter and the xfermode from the paint that we (AutoDrawLooper) 4745c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * return (fPaint). We then draw the primitive (using srcover) into a cleared 4755c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * buffer/surface. 4765c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 3. Restore the layer created in #1 4775c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * The imagefilter is passed the buffer/surface from the layer (now filled with the 4785c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * src pixels of the primitive). It returns a new "filtered" buffer, which we 4795c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * draw onto the previous layer using the xfermode from the original paint. 4805c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed */ 4818926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkPaint tmp; 482dbc3cefb0b624808ddb86d444e6103f216e12fa5reed tmp.setImageFilter(fPaint->getImageFilter()); 483dbc3cefb0b624808ddb86d444e6103f216e12fa5reed tmp.setXfermode(fPaint->getXfermode()); 48487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect storage; 48587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (rawBounds) { 48687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco // Make rawBounds include all paint outsets except for those due to image filters. 48787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco rawBounds = &apply_paint_to_bounds_sans_imagefilter(*fPaint, *rawBounds, &storage); 48887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 489bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed (void)canvas->internalSaveLayer(SkCanvas::SaveLayerRec(rawBounds, &tmp), 49076033be81b82c44fd5d4fdf2672eb22e505da1f0reed SkCanvas::kFullLayer_SaveLayerStrategy); 4915c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed fTempLayerForImageFilter = true; 4925c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed // we remove the imagefilter/xfermode inside doNext() 4938926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 4948926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 49579fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (SkDrawLooper* looper = paint.getLooper()) { 49679fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org void* buffer = fLooperContextAllocator.reserveT<SkDrawLooper::Context>( 49779fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org looper->contextSize()); 49879fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org fLooperContext = looper->createContext(canvas, buffer); 499129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fIsSimple = false; 500129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else { 50196fcdcc219d2a0d3579719b84b28bede76efba64halcanary fLooperContext = nullptr; 502129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // can we be marked as simple? 5035c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed fIsSimple = !fFilter && !fTempLayerForImageFilter; 5048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 505b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 5064a8126e7f81384526629b1e21bf89b632ea13cd9reed uint32_t oldFlags = paint.getFlags(); 5074a8126e7f81384526629b1e21bf89b632ea13cd9reed fNewPaintFlags = filter_paint_flags(props, oldFlags); 5084a8126e7f81384526629b1e21bf89b632ea13cd9reed if (fIsSimple && (fNewPaintFlags != oldFlags)) { 509dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkPaint* paint = set_if_needed(&fLazyPaintInit, fOrigPaint); 5104a8126e7f81384526629b1e21bf89b632ea13cd9reed paint->setFlags(fNewPaintFlags); 5114a8126e7f81384526629b1e21bf89b632ea13cd9reed fPaint = paint; 5124a8126e7f81384526629b1e21bf89b632ea13cd9reed // if we're not simple, doNext() will take care of calling setFlags() 5134a8126e7f81384526629b1e21bf89b632ea13cd9reed } 5148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 51574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 5164e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com ~AutoDrawLooper() { 5175c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed if (fTempLayerForImageFilter) { 5188926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com fCanvas->internalRestore(); 5198926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 5204e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkASSERT(fCanvas->getSaveCount() == fSaveCount); 5218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 52274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 5234e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com const SkPaint& paint() const { 5244e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkASSERT(fPaint); 5254e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return *fPaint; 5264e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 52774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 528129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool next(SkDrawFilter::Type drawType) { 529129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com if (fDone) { 530129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return false; 531129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else if (fIsSimple) { 532129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fDone = true; 533129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return !fPaint->nothingToDraw(); 534129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else { 535129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return this->doNext(drawType); 536129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 537fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 53874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 5398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 540dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkLazyPaint fLazyPaintInit; // base paint storage in case we need to modify it 541dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkLazyPaint fLazyPaintPerLooper; // per-draw-looper storage, so the looper can modify it 5422c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkCanvas* fCanvas; 5432c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint& fOrigPaint; 5442c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkDrawFilter* fFilter; 5452c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint* fPaint; 5462c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org int fSaveCount; 5474a8126e7f81384526629b1e21bf89b632ea13cd9reed uint32_t fNewPaintFlags; 5485c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed bool fTempLayerForImageFilter; 5492c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org bool fDone; 550129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool fIsSimple; 55179fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkDrawLooper::Context* fLooperContext; 55279fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkSmallAllocator<1, 32> fLooperContextAllocator; 553129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com 554129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool doNext(SkDrawFilter::Type drawType); 5558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 5568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 557129ec22cb054592261e001294c430c9dd4e90ff4reed@google.combool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) { 55896fcdcc219d2a0d3579719b84b28bede76efba64halcanary fPaint = nullptr; 559129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com SkASSERT(!fIsSimple); 5605c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed SkASSERT(fLooperContext || fFilter || fTempLayerForImageFilter); 561632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com 562dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkPaint* paint = fLazyPaintPerLooper.set(fLazyPaintInit.isValid() ? 563dbc3cefb0b624808ddb86d444e6103f216e12fa5reed *fLazyPaintInit.get() : fOrigPaint); 5644a8126e7f81384526629b1e21bf89b632ea13cd9reed paint->setFlags(fNewPaintFlags); 5658926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 5665c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed if (fTempLayerForImageFilter) { 56796fcdcc219d2a0d3579719b84b28bede76efba64halcanary paint->setImageFilter(nullptr); 56896fcdcc219d2a0d3579719b84b28bede76efba64halcanary paint->setXfermode(nullptr); 569129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 5708926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 57179fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (fLooperContext && !fLooperContext->next(fCanvas, paint)) { 572129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fDone = true; 573129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return false; 574129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 575129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com if (fFilter) { 576971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com if (!fFilter->filter(paint, drawType)) { 577971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com fDone = true; 578971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com return false; 579971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com } 58096fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == fLooperContext) { 581129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // no looper means we only draw once 582632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com fDone = true; 583632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com } 584129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 585129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fPaint = paint; 5868926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 587129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // if we only came in here for the imagefilter, mark us as done 58879fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (!fLooperContext && !fFilter) { 5894e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fDone = true; 5904e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 5914e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com 592632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com // call this after any possible paint modifiers 593632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com if (fPaint->nothingToDraw()) { 59496fcdcc219d2a0d3579719b84b28bede76efba64halcanary fPaint = nullptr; 5954e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return false; 5964e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 5974e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return true; 5984e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com} 5994e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com 6008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////// macros to place around the internal draw calls ////////////////// 6018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 602262a71b7f95ce98ff3dd8dba845afbd724470903reed#define LOOPER_BEGIN_DRAWBITMAP(paint, skipLayerForFilter, bounds) \ 603262a71b7f95ce98ff3dd8dba845afbd724470903reed this->predrawNotify(); \ 604262a71b7f95ce98ff3dd8dba845afbd724470903reed AutoDrawLooper looper(this, fProps, paint, skipLayerForFilter, bounds); \ 605262a71b7f95ce98ff3dd8dba845afbd724470903reed while (looper.next(SkDrawFilter::kBitmap_Type)) { \ 606262a71b7f95ce98ff3dd8dba845afbd724470903reed SkDrawIter iter(this); 607262a71b7f95ce98ff3dd8dba845afbd724470903reed 608262a71b7f95ce98ff3dd8dba845afbd724470903reed 6098926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com#define LOOPER_BEGIN_DRAWDEVICE(paint, type) \ 61097af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com this->predrawNotify(); \ 6114a8126e7f81384526629b1e21bf89b632ea13cd9reed AutoDrawLooper looper(this, fProps, paint, true); \ 6128926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com while (looper.next(type)) { \ 6138926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkDrawIter iter(this); 6148926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 61578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org#define LOOPER_BEGIN(paint, type, bounds) \ 61697af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com this->predrawNotify(); \ 6174a8126e7f81384526629b1e21bf89b632ea13cd9reed AutoDrawLooper looper(this, fProps, paint, false, bounds); \ 6184e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com while (looper.next(type)) { \ 6198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDrawIter iter(this); 6204b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 621c83a29759a5c2966da5ab973e4fd90763e4c962breed#define LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, type, bounds, auxOpaque) \ 622c83a29759a5c2966da5ab973e4fd90763e4c962breed this->predrawNotify(bounds, &paint, auxOpaque); \ 623c83a29759a5c2966da5ab973e4fd90763e4c962breed AutoDrawLooper looper(this, fProps, paint, false, bounds); \ 624c83a29759a5c2966da5ab973e4fd90763e4c962breed while (looper.next(type)) { \ 625c83a29759a5c2966da5ab973e4fd90763e4c962breed SkDrawIter iter(this); 626c83a29759a5c2966da5ab973e4fd90763e4c962breed 6274e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com#define LOOPER_END } 6288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////// 6308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 631feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtkleinvoid SkCanvas::resetForNextPicture(const SkIRect& bounds) { 632feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein this->restoreToCount(1); 633feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fCachedLocalClipBounds.setEmpty(); 634feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fCachedLocalClipBoundsDirty = true; 635feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fClipStack->reset(); 636feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fMCRec->reset(bounds); 637feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 638feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein // We're peering through a lot of structs here. Only at this scope do we 639feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein // know that the device is an SkBitmapDevice (really an SkNoPixelsBitmapDevice). 640feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein static_cast<SkBitmapDevice*>(fMCRec->fLayer->fDevice)->setNewSize(bounds.size()); 641feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein} 642feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 643d954498c01ccf0417feacf89e45d0c62a06a813breedSkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) { 64442b73eb00367c8315974b1c374308d20efa78897reed if (device && device->forceConservativeRasterClip()) { 64542b73eb00367c8315974b1c374308d20efa78897reed flags = InitFlags(flags | kConservativeRasterClip_InitFlag); 64642b73eb00367c8315974b1c374308d20efa78897reed } 64742b73eb00367c8315974b1c374308d20efa78897reed // Since init() is only called once by our constructors, it is safe to perform this 64842b73eb00367c8315974b1c374308d20efa78897reed // const-cast. 64942b73eb00367c8315974b1c374308d20efa78897reed *const_cast<bool*>(&fConservativeRasterClip) = SkToBool(flags & kConservativeRasterClip_InitFlag); 65042b73eb00367c8315974b1c374308d20efa78897reed 651c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBounds.setEmpty(); 652c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 6538f0a7b8e7334187a5d7d5ab7fde5a3c3009555f5caryclark@google.com fAllowSoftClip = true; 65445a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com fAllowSimplifyClip = false; 655f92c86642a1875da54d54b447f006cb9dfbbb35creed fDeviceCMDirty = true; 6562ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount = 1; 65796fcdcc219d2a0d3579719b84b28bede76efba64halcanary fMetaData = nullptr; 6588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 659385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary fClipStack.reset(new SkClipStack); 660687fa1c745febb57f42b0d5f03d7c1f4be2530careed 6618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = (MCRec*)fMCStack.push_back(); 662d954498c01ccf0417feacf89e45d0c62a06a813breed new (fMCRec) MCRec(fConservativeRasterClip); 6638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 664a499f905e9340e4935447f2562fd92e8853382b1reed SkASSERT(sizeof(DeviceCM) <= sizeof(fDeviceCMStorage)); 665a499f905e9340e4935447f2562fd92e8853382b1reed fMCRec->fLayer = (DeviceCM*)fDeviceCMStorage; 66696fcdcc219d2a0d3579719b84b28bede76efba64halcanary new (fDeviceCMStorage) DeviceCM(nullptr, nullptr, nullptr, fConservativeRasterClip, false); 667b679ca8926a832274b14fdb512f88f64b61d32eareed 6688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fTopLayer = fMCRec->fLayer; 6698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 67096fcdcc219d2a0d3579719b84b28bede76efba64halcanary fSurfaceBase = nullptr; 671f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 672f92c86642a1875da54d54b447f006cb9dfbbb35creed if (device) { 673efbffedd68636e94d4379e84a2585bce80f6fb8frobertphillips // The root device and the canvas should always have the same pixel geometry 674efbffedd68636e94d4379e84a2585bce80f6fb8frobertphillips SkASSERT(fProps.pixelGeometry() == device->surfaceProps().pixelGeometry()); 675f92c86642a1875da54d54b447f006cb9dfbbb35creed device->onAttachToCanvas(this); 676f92c86642a1875da54d54b447f006cb9dfbbb35creed fMCRec->fLayer->fDevice = SkRef(device); 67778e276889795454891cbba48ab11927968114953reed fMCRec->fRasterClip.setRect(device->getGlobalBounds()); 678f92c86642a1875da54d54b447f006cb9dfbbb35creed } 679f92c86642a1875da54d54b447f006cb9dfbbb35creed return device; 6808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 682cde92111d50a96b6d0f3e166fbac7c9bc6eca349reed@google.comSkCanvas::SkCanvas() 683e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 6844a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 68542b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 686e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org{ 6878d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org inc_canvas(); 688ba124485687130183643994f1b4b68d629fbbebaskia.committer@gmail.com 68996fcdcc219d2a0d3579719b84b28bede76efba64halcanary this->init(nullptr, kDefault_InitFlags); 6908d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org} 6918d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org 692d954498c01ccf0417feacf89e45d0c62a06a813breedstatic SkBitmap make_nopixels(int width, int height) { 693d954498c01ccf0417feacf89e45d0c62a06a813breed SkBitmap bitmap; 694d954498c01ccf0417feacf89e45d0c62a06a813breed bitmap.setInfo(SkImageInfo::MakeUnknown(width, height)); 695d954498c01ccf0417feacf89e45d0c62a06a813breed return bitmap; 696d954498c01ccf0417feacf89e45d0c62a06a813breed} 697d954498c01ccf0417feacf89e45d0c62a06a813breed 698d954498c01ccf0417feacf89e45d0c62a06a813breedclass SkNoPixelsBitmapDevice : public SkBitmapDevice { 699d954498c01ccf0417feacf89e45d0c62a06a813breedpublic: 700fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips SkNoPixelsBitmapDevice(const SkIRect& bounds, const SkSurfaceProps& surfaceProps) 701fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips : INHERITED(make_nopixels(bounds.width(), bounds.height()), surfaceProps) 70278e276889795454891cbba48ab11927968114953reed { 70378e276889795454891cbba48ab11927968114953reed this->setOrigin(bounds.x(), bounds.y()); 70478e276889795454891cbba48ab11927968114953reed } 705d954498c01ccf0417feacf89e45d0c62a06a813breed 706d954498c01ccf0417feacf89e45d0c62a06a813breedprivate: 707b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 708d954498c01ccf0417feacf89e45d0c62a06a813breed typedef SkBitmapDevice INHERITED; 709d954498c01ccf0417feacf89e45d0c62a06a813breed}; 710d954498c01ccf0417feacf89e45d0c62a06a813breed 71196a857ef5a40b3d0751ec9ebaaa96d9f20b82b21reedSkCanvas::SkCanvas(int width, int height, const SkSurfaceProps* props) 712e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 71396a857ef5a40b3d0751ec9ebaaa96d9f20b82b21reed , fProps(SkSurfacePropsCopyOrDefault(props)) 71442b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 715e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org{ 716e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org inc_canvas(); 717b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 718385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary this->init(new SkNoPixelsBitmapDevice(SkIRect::MakeWH(width, height), fProps), 719385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary kDefault_InitFlags)->unref(); 720d954498c01ccf0417feacf89e45d0c62a06a813breed} 721e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org 72278e276889795454891cbba48ab11927968114953reedSkCanvas::SkCanvas(const SkIRect& bounds, InitFlags flags) 723d954498c01ccf0417feacf89e45d0c62a06a813breed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7244a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 72542b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 726d954498c01ccf0417feacf89e45d0c62a06a813breed{ 727d954498c01ccf0417feacf89e45d0c62a06a813breed inc_canvas(); 728b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 729385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary this->init(new SkNoPixelsBitmapDevice(bounds, fProps), flags)->unref(); 73027a5e656c3d6ef22f9cb34de18e1b960da3aa241reed} 7318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 732d954498c01ccf0417feacf89e45d0c62a06a813breedSkCanvas::SkCanvas(SkBaseDevice* device) 733d954498c01ccf0417feacf89e45d0c62a06a813breed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7347b05ff11ebc51f3f3abd1c1756337a04f563537erobertphillips , fProps(device->surfaceProps()) 73542b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 736d954498c01ccf0417feacf89e45d0c62a06a813breed{ 737d954498c01ccf0417feacf89e45d0c62a06a813breed inc_canvas(); 738b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 739d954498c01ccf0417feacf89e45d0c62a06a813breed this->init(device, kDefault_InitFlags); 7408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 742fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillipsSkCanvas::SkCanvas(SkBaseDevice* device, InitFlags flags) 743fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7447b05ff11ebc51f3f3abd1c1756337a04f563537erobertphillips , fProps(device->surfaceProps()) 74542b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 746fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips{ 747fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips inc_canvas(); 748fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips 749fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips this->init(device, flags); 750fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips} 751fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips 7524a8126e7f81384526629b1e21bf89b632ea13cd9reedSkCanvas::SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props) 7533716fd067a5621bb94a6cb08d72afec8bf3acedareed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7544a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(props) 75542b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 7563716fd067a5621bb94a6cb08d72afec8bf3acedareed{ 7573716fd067a5621bb94a6cb08d72afec8bf3acedareed inc_canvas(); 758b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 759385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary SkAutoTUnref<SkBaseDevice> device(new SkBitmapDevice(bitmap, fProps)); 7604a8126e7f81384526629b1e21bf89b632ea13cd9reed this->init(device, kDefault_InitFlags); 7614a8126e7f81384526629b1e21bf89b632ea13cd9reed} 76229c857d0f3a1cb837f73406eeb6ba9771879b5e7reed 7634a8126e7f81384526629b1e21bf89b632ea13cd9reedSkCanvas::SkCanvas(const SkBitmap& bitmap) 7644a8126e7f81384526629b1e21bf89b632ea13cd9reed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7654a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 76642b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 7674a8126e7f81384526629b1e21bf89b632ea13cd9reed{ 7684a8126e7f81384526629b1e21bf89b632ea13cd9reed inc_canvas(); 769b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 770385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary SkAutoTUnref<SkBaseDevice> device(new SkBitmapDevice(bitmap, fProps)); 7714a8126e7f81384526629b1e21bf89b632ea13cd9reed this->init(device, kDefault_InitFlags); 7728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::~SkCanvas() { 7758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // free up the contents of our deque 7768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->restoreToCount(1); // restore everything but the last 7777c2029367cea5479fa3b74fb0ca2b0297b42b709reed@google.com 7788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->internalRestore(); // restore the last, since we're going away 7798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 780385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete fMetaData; 781b70ae310bbdaa1b26786773aabce5548c1f48563vandebo@chromium.org 7828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dec_canvas(); 7838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7857765000709dc64eb23be7df47d1f995d1f787115fmalita#ifdef SK_SUPPORT_LEGACY_DRAWFLTER 7868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDrawFilter* SkCanvas::getDrawFilter() const { 7878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fMCRec->fFilter; 7888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDrawFilter* SkCanvas::setDrawFilter(SkDrawFilter* filter) { 79151985e3f5e608d369e52832b7ce489d85d402422reed this->checkForDeferredSave(); 7928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fMCRec->fFilter, filter); 7938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return filter; 7948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7957765000709dc64eb23be7df47d1f995d1f787115fmalita#endif 7968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 79774bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.orgSkMetaData& SkCanvas::getMetaData() { 79874bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org // metadata users are rare, so we lazily allocate it. If that changes we 79974bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org // can decide to just make it a field in the device (rather than a ptr) 80096fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == fMetaData) { 80174bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org fMetaData = new SkMetaData; 80274bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org } 80374bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org return *fMetaData; 80474bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org} 80574bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org 8068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 8078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 808bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.orgvoid SkCanvas::flush() { 8091f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* device = this->getDevice(); 810bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org if (device) { 811bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org device->flush(); 812bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org } 813bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org} 814bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org 8154ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.comSkISize SkCanvas::getTopLayerSize() const { 8164ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com SkBaseDevice* d = this->getTopDevice(); 8174ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com return d ? SkISize::Make(d->width(), d->height()) : SkISize::Make(0, 0); 8184ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com} 8194ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com 8204ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.comSkIPoint SkCanvas::getTopLayerOrigin() const { 8214ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com SkBaseDevice* d = this->getTopDevice(); 8224ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com return d ? d->getOrigin() : SkIPoint::Make(0, 0); 8234ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com} 8244ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com 8254ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.comSkISize SkCanvas::getBaseLayerSize() const { 8261f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* d = this->getDevice(); 827210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com return d ? SkISize::Make(d->width(), d->height()) : SkISize::Make(0, 0); 828210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com} 829210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com 8301f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::getDevice() const { 8318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // return root device 832c029062a0312fb747fb6c2677983aba51795c580robertphillips@google.com MCRec* rec = (MCRec*) fMCStack.front(); 8338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(rec && rec->fLayer); 8348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return rec->fLayer->fDevice; 8358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8371f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::getTopDevice(bool updateMatrixClip) const { 8380b53d59a24f667350b4282f88470713902409030reed@google.com if (updateMatrixClip) { 8390b53d59a24f667350b4282f88470713902409030reed@google.com const_cast<SkCanvas*>(this)->updateDeviceCMCache(); 8400b53d59a24f667350b4282f88470713902409030reed@google.com } 8419266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com return fMCRec->fTopLayer->fDevice; 8429266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com} 8439266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com 844a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.orgbool SkCanvas::readPixels(SkBitmap* bitmap, int x, int y) { 845a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (kUnknown_SkColorType == bitmap->colorType() || bitmap->getTexture()) { 846a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 847a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 848a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 849a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bool weAllocated = false; 85096fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == bitmap->pixelRef()) { 851848250415eddc54075f7eb8795e8db79e749c6abreed if (!bitmap->tryAllocPixels()) { 852a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 853a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 854a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org weAllocated = true; 855a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 856a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 857cf01e31df6bbda270dca2ee3b4967caf51e465dcreed SkAutoPixmapUnlock unlocker; 858cf01e31df6bbda270dca2ee3b4967caf51e465dcreed if (bitmap->requestLock(&unlocker)) { 859cf01e31df6bbda270dca2ee3b4967caf51e465dcreed const SkPixmap& pm = unlocker.pixmap(); 860cf01e31df6bbda270dca2ee3b4967caf51e465dcreed if (this->readPixels(pm.info(), pm.writable_addr(), pm.rowBytes(), x, y)) { 861cf01e31df6bbda270dca2ee3b4967caf51e465dcreed return true; 862cf01e31df6bbda270dca2ee3b4967caf51e465dcreed } 863a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 864a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 865a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (weAllocated) { 86696fcdcc219d2a0d3579719b84b28bede76efba64halcanary bitmap->setPixelRef(nullptr); 867a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 868a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 869a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org} 87051df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 871c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.combool SkCanvas::readPixels(const SkIRect& srcRect, SkBitmap* bitmap) { 872a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkIRect r = srcRect; 873a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 874a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!r.intersect(0, 0, size.width(), size.height())) { 875a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bitmap->reset(); 876ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com return false; 877ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com } 87874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 879848250415eddc54075f7eb8795e8db79e749c6abreed if (!bitmap->tryAllocN32Pixels(r.width(), r.height())) { 880a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org // bitmap will already be reset. 881a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 882a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 883a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!this->readPixels(bitmap->info(), bitmap->getPixels(), bitmap->rowBytes(), r.x(), r.y())) { 884a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bitmap->reset(); 885daba14b7d4fc96b915c45d82713b22729c0d0f37bsalomon@google.com return false; 886c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } 887a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return true; 888a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org} 889c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 89096472deea70169396b8e1f576e470138f55fdb1freedbool SkCanvas::readPixels(const SkImageInfo& dstInfo, void* dstP, size_t rowBytes, int x, int y) { 891a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkBaseDevice* device = this->getDevice(); 892a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!device) { 893a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 894a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 895a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 896f0f14113431ace669f278fdd97b50950f2cf4c80mtklein 89796472deea70169396b8e1f576e470138f55fdb1freed SkReadPixelsRec rec(dstInfo, dstP, rowBytes, x, y); 89896472deea70169396b8e1f576e470138f55fdb1freed if (!rec.trim(size.width(), size.height())) { 899a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 900a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 901db0c8753775774aa3f67114491e26ac1be32f38eskia.committer@gmail.com 902a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org // The device can assert that the requested area is always contained in its bounds 90396472deea70169396b8e1f576e470138f55fdb1freed return device->readPixels(rec.fInfo, rec.fPixels, rec.fRowBytes, rec.fX, rec.fY); 90451df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com} 90551df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 9064cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgbool SkCanvas::writePixels(const SkBitmap& bitmap, int x, int y) { 9074cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (bitmap.getTexture()) { 9084cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 9094cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 910cf01e31df6bbda270dca2ee3b4967caf51e465dcreed 911cf01e31df6bbda270dca2ee3b4967caf51e465dcreed SkAutoPixmapUnlock unlocker; 912cf01e31df6bbda270dca2ee3b4967caf51e465dcreed if (bitmap.requestLock(&unlocker)) { 913cf01e31df6bbda270dca2ee3b4967caf51e465dcreed const SkPixmap& pm = unlocker.pixmap(); 914cf01e31df6bbda270dca2ee3b4967caf51e465dcreed return this->writePixels(pm.info(), pm.addr(), pm.rowBytes(), x, y); 9154cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 9164cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 9174cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org} 9184cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 9194cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgbool SkCanvas::writePixels(const SkImageInfo& origInfo, const void* pixels, size_t rowBytes, 9204cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org int x, int y) { 9214cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org switch (origInfo.colorType()) { 9224cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org case kUnknown_SkColorType: 9234cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org case kIndex_8_SkColorType: 9244cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 9254cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org default: 9264cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org break; 9274cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 92896fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == pixels || rowBytes < origInfo.minRowBytes()) { 9294cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 9304cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 9314cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 9324cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 9334cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org SkIRect target = SkIRect::MakeXYWH(x, y, origInfo.width(), origInfo.height()); 9344cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (!target.intersect(0, 0, size.width(), size.height())) { 9354cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 9364cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 9374cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 9384cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org SkBaseDevice* device = this->getDevice(); 9394cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (!device) { 9404cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 9414cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 9424cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 9434cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // the intersect may have shrunk info's logical size 944e5ea500d4714a7d84de2bf913e81be3b65d2de68reed const SkImageInfo info = origInfo.makeWH(target.width(), target.height()); 9454cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 9464cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // if x or y are negative, then we have to adjust pixels 9474cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (x > 0) { 9484cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org x = 0; 9494cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 9504cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (y > 0) { 9514cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org y = 0; 9524cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 9534cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // here x,y are either 0 or negative 9544cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org pixels = ((const char*)pixels - y * rowBytes - x * info.bytesPerPixel()); 9554cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 9564af35f348b2e2f6c428819118eb7a2f2fff53a74reed // Tell our owning surface to bump its generation ID 957c83a29759a5c2966da5ab973e4fd90763e4c962breed const bool completeOverwrite = info.dimensions() == size; 958c83a29759a5c2966da5ab973e4fd90763e4c962breed this->predrawNotify(completeOverwrite); 9594af35f348b2e2f6c428819118eb7a2f2fff53a74reed 9604cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // The device can assert that the requested area is always contained in its bounds 9614ef54f8d72420a521d4aae04ff5cd438810eca7fcommit-bot@chromium.org return device->writePixels(info, pixels, rowBytes, target.x(), target.y()); 9624cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org} 96351df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 9644370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comSkCanvas* SkCanvas::canvasForDrawIter() { 9654370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com return this; 9664370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 9674370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 9688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 9698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::updateDeviceCMCache() { 9718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fDeviceCMDirty) { 9728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& totalMatrix = this->getTotalMatrix(); 9731f836ee096bb988adef4b9757b2629c7afeda36dreed const SkRasterClip& totalClip = fMCRec->fRasterClip; 9748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* layer = fMCRec->fTopLayer; 9754b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 97696fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == layer->fNext) { // only one layer 97796fcdcc219d2a0d3579719b84b28bede76efba64halcanary layer->updateMC(totalMatrix, totalClip, *fClipStack, nullptr); 9788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 979045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com SkRasterClip clip(totalClip); 9808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 981687fa1c745febb57f42b0d5f03d7c1f4be2530careed layer->updateMC(totalMatrix, clip, *fClipStack, &clip); 98296fcdcc219d2a0d3579719b84b28bede76efba64halcanary } while ((layer = layer->fNext) != nullptr); 9838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = false; 9858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 9898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9902ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::checkForDeferredSave() { 9912ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (fMCRec->fDeferredSaveCount > 0) { 9922ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->doSave(); 9932ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 9942ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed} 9952ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed 996f0090cb80ab10a49e511aa5450ae38917fa058d9reedint SkCanvas::getSaveCount() const { 9972ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed#ifdef SK_DEBUG 9982ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed int count = 0; 9992ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkDeque::Iter iter(fMCStack, SkDeque::Iter::kFront_IterStart); 10002ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed for (;;) { 10012ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed const MCRec* rec = (const MCRec*)iter.next(); 10022ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (!rec) { 10032ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed break; 10042ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 10052ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed count += 1 + rec->fDeferredSaveCount; 10062ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 10072ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(count == fSaveCount); 10082ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed#endif 10092ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return fSaveCount; 1010f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 1011f0090cb80ab10a49e511aa5450ae38917fa058d9reed 1012f0090cb80ab10a49e511aa5450ae38917fa058d9reedint SkCanvas::save() { 10132ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount += 1; 10142ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fMCRec->fDeferredSaveCount += 1; 10152ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return this->getSaveCount() - 1; // return our prev value 10162ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed} 10172ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed 10182ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::doSave() { 1019f0090cb80ab10a49e511aa5450ae38917fa058d9reed this->willSave(); 1020a62d32d1e3112c7e5a26c27e5e967d124ef8dd81fmalita 1021a62d32d1e3112c7e5a26c27e5e967d124ef8dd81fmalita SkASSERT(fMCRec->fDeferredSaveCount > 0); 1022a62d32d1e3112c7e5a26c27e5e967d124ef8dd81fmalita fMCRec->fDeferredSaveCount -= 1; 10232ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalSave(); 1024f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 1025f0090cb80ab10a49e511aa5450ae38917fa058d9reed 1026f0090cb80ab10a49e511aa5450ae38917fa058d9reedvoid SkCanvas::restore() { 10272ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (fMCRec->fDeferredSaveCount > 0) { 10282ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(fSaveCount > 1); 10292ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount -= 1; 10302ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fMCRec->fDeferredSaveCount -= 1; 10312ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } else { 10322ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed // check for underflow 10332ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (fMCStack.count() > 1) { 10342ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->willRestore(); 10352ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(fSaveCount > 1); 1036a644116c3375b12c642d1b51ee1e5cf4a22c1f5breed fSaveCount -= 1; 10372ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalRestore(); 10382ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->didRestore(); 10392ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 1040f0090cb80ab10a49e511aa5450ae38917fa058d9reed } 1041f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 1042f0090cb80ab10a49e511aa5450ae38917fa058d9reed 1043f0090cb80ab10a49e511aa5450ae38917fa058d9reedvoid SkCanvas::restoreToCount(int count) { 1044f0090cb80ab10a49e511aa5450ae38917fa058d9reed // sanity check 1045f0090cb80ab10a49e511aa5450ae38917fa058d9reed if (count < 1) { 1046f0090cb80ab10a49e511aa5450ae38917fa058d9reed count = 1; 1047f0090cb80ab10a49e511aa5450ae38917fa058d9reed } 1048f0f14113431ace669f278fdd97b50950f2cf4c80mtklein 1049f0090cb80ab10a49e511aa5450ae38917fa058d9reed int n = this->getSaveCount() - count; 1050f0090cb80ab10a49e511aa5450ae38917fa058d9reed for (int i = 0; i < n; ++i) { 1051f0090cb80ab10a49e511aa5450ae38917fa058d9reed this->restore(); 1052f0090cb80ab10a49e511aa5450ae38917fa058d9reed } 1053f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 1054f0090cb80ab10a49e511aa5450ae38917fa058d9reed 10552ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::internalSave() { 10568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com MCRec* newTop = (MCRec*)fMCStack.push_back(); 1057d954498c01ccf0417feacf89e45d0c62a06a813breed new (newTop) MCRec(*fMCRec); // balanced in restore() 10588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = newTop; 10594b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 1060687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->save(); 10618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10634960eeec4a1f2a772654883d7f3615d47bcd5dc3reedbool SkCanvas::BoundsAffectsClip(SaveLayerFlags saveLayerFlags) { 1064b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG 10654960eeec4a1f2a772654883d7f3615d47bcd5dc3reed return !(saveLayerFlags & SkCanvas::kDontClipToLayer_PrivateSaveLayerFlag); 1066b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#else 1067b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com return true; 1068b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#endif 10698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10714960eeec4a1f2a772654883d7f3615d47bcd5dc3reedbool SkCanvas::clipRectBounds(const SkRect* bounds, SaveLayerFlags saveLayerFlags, 10729b3aa54bc9605257c701cf465813f5fb1d7ba39ereed SkIRect* intersection, const SkImageFilter* imageFilter) { 1073bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect clipBounds; 1074bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (!this->getClipDeviceBounds(&clipBounds)) { 1075a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return false; 1076f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 1077c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org 107896e657d0e103b8358a77ecd913f6086929f792b8reed const SkMatrix& ctm = fMCRec->fMatrix; // this->getTotalMatrix() 107996e657d0e103b8358a77ecd913f6086929f792b8reed 1080c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org if (imageFilter) { 108196e657d0e103b8358a77ecd913f6086929f792b8reed imageFilter->filterBounds(clipBounds, ctm, &clipBounds); 1082db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco if (bounds && !imageFilter->canComputeFastBounds()) { 1083db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco bounds = nullptr; 1084db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco } 1085c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org } 1086bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect ir; 108749f085dddff10473b6ebf832a974288300224e60bsalomon if (bounds) { 10888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 10894b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 109096e657d0e103b8358a77ecd913f6086929f792b8reed ctm.mapRect(&r, *bounds); 10918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.roundOut(&ir); 10928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // early exit if the layer's bounds are clipped out 10938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!ir.intersect(clipBounds)) { 10944960eeec4a1f2a772654883d7f3615d47bcd5dc3reed if (BoundsAffectsClip(saveLayerFlags)) { 10959b3aa54bc9605257c701cf465813f5fb1d7ba39ereed fCachedLocalClipBoundsDirty = true; 10961f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fRasterClip.setEmpty(); 1097bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1098a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return false; 10998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { // no user bounds, so just use the clip 11018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ir = clipBounds; 11028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1103180aec43451dd951fdaae81a92efc710ba093260reed SkASSERT(!ir.isEmpty()); 11048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11054960eeec4a1f2a772654883d7f3615d47bcd5dc3reed if (BoundsAffectsClip(saveLayerFlags)) { 1106180aec43451dd951fdaae81a92efc710ba093260reed // Simplify the current clips since they will be applied properly during restore() 11079b3aa54bc9605257c701cf465813f5fb1d7ba39ereed fCachedLocalClipBoundsDirty = true; 1108687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipDevRect(ir, SkRegion::kReplace_Op); 1109180aec43451dd951fdaae81a92efc710ba093260reed fMCRec->fRasterClip.setRect(ir); 1110a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org } 1111a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 1112a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org if (intersection) { 1113a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org *intersection = ir; 1114a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org } 1115a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return true; 1116a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org} 1117a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 1118bada1885da479d948f065182d6dfa85a1140bda5reed#ifdef SK_SUPPORT_LEGACY_SAVEFLAGS 11194960eeec4a1f2a772654883d7f3615d47bcd5dc3reeduint32_t SkCanvas::SaveFlagsToSaveLayerFlags(SaveFlags flags) { 11204960eeec4a1f2a772654883d7f3615d47bcd5dc3reed uint32_t layerFlags = 0; 11214960eeec4a1f2a772654883d7f3615d47bcd5dc3reed 11224960eeec4a1f2a772654883d7f3615d47bcd5dc3reed if (0 == (flags & kClipToLayer_SaveFlag)) { 11234960eeec4a1f2a772654883d7f3615d47bcd5dc3reed layerFlags |= kDontClipToLayer_PrivateSaveLayerFlag; 1124d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed } 11254960eeec4a1f2a772654883d7f3615d47bcd5dc3reed if (0 == (flags & kHasAlphaLayer_SaveFlag)) { 11264960eeec4a1f2a772654883d7f3615d47bcd5dc3reed layerFlags |= kIsOpaque_SaveLayerFlag; 11274960eeec4a1f2a772654883d7f3615d47bcd5dc3reed } 11284960eeec4a1f2a772654883d7f3615d47bcd5dc3reed return layerFlags; 11294960eeec4a1f2a772654883d7f3615d47bcd5dc3reed} 1130ffe031e65cda3f52e057dd7aafbc9407c25cbf8dscroggo 1131ffe031e65cda3f52e057dd7aafbc9407c25cbf8dscroggouint32_t SkCanvas::SaveLayerFlagsToSaveFlags(SaveLayerFlags layerFlags) { 1132ffe031e65cda3f52e057dd7aafbc9407c25cbf8dscroggo uint32_t saveFlags = 0; 1133ffe031e65cda3f52e057dd7aafbc9407c25cbf8dscroggo 1134ffe031e65cda3f52e057dd7aafbc9407c25cbf8dscroggo if (0 == (layerFlags & kDontClipToLayer_PrivateSaveLayerFlag)) { 1135ffe031e65cda3f52e057dd7aafbc9407c25cbf8dscroggo saveFlags |= kClipToLayer_SaveFlag; 1136ffe031e65cda3f52e057dd7aafbc9407c25cbf8dscroggo } 1137ffe031e65cda3f52e057dd7aafbc9407c25cbf8dscroggo if (0 == (layerFlags & kIsOpaque_SaveLayerFlag)) { 1138ffe031e65cda3f52e057dd7aafbc9407c25cbf8dscroggo saveFlags |= kHasAlphaLayer_SaveFlag; 1139ffe031e65cda3f52e057dd7aafbc9407c25cbf8dscroggo } 1140ffe031e65cda3f52e057dd7aafbc9407c25cbf8dscroggo return saveFlags; 1141ffe031e65cda3f52e057dd7aafbc9407c25cbf8dscroggo} 1142bada1885da479d948f065182d6dfa85a1140bda5reed#endif 11434960eeec4a1f2a772654883d7f3615d47bcd5dc3reed 11444960eeec4a1f2a772654883d7f3615d47bcd5dc3reedint SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint) { 11454960eeec4a1f2a772654883d7f3615d47bcd5dc3reed return this->saveLayer(SaveLayerRec(bounds, paint, 0)); 1146d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org} 1147d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org 1148bada1885da479d948f065182d6dfa85a1140bda5reed#ifdef SK_SUPPORT_LEGACY_SAVEFLAGS 11492ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedint SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags) { 11504960eeec4a1f2a772654883d7f3615d47bcd5dc3reed return this->saveLayer(SaveLayerRec(bounds, paint, SaveFlagsToSaveLayerFlags(flags))); 11514960eeec4a1f2a772654883d7f3615d47bcd5dc3reed} 1152bada1885da479d948f065182d6dfa85a1140bda5reed#endif 11534960eeec4a1f2a772654883d7f3615d47bcd5dc3reed 11544960eeec4a1f2a772654883d7f3615d47bcd5dc3reedint SkCanvas::saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPaint* paint) { 11554960eeec4a1f2a772654883d7f3615d47bcd5dc3reed return this->saveLayer(SaveLayerRec(bounds, paint, kPreserveLCDText_SaveLayerFlag)); 11564960eeec4a1f2a772654883d7f3615d47bcd5dc3reed} 11574960eeec4a1f2a772654883d7f3615d47bcd5dc3reed 11584960eeec4a1f2a772654883d7f3615d47bcd5dc3reedint SkCanvas::saveLayer(const SaveLayerRec& origRec) { 11594960eeec4a1f2a772654883d7f3615d47bcd5dc3reed SaveLayerRec rec(origRec); 1160d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed if (gIgnoreSaveLayerBounds) { 11614960eeec4a1f2a772654883d7f3615d47bcd5dc3reed rec.fBounds = nullptr; 1162d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed } 11634960eeec4a1f2a772654883d7f3615d47bcd5dc3reed SaveLayerStrategy strategy = this->getSaveLayerStrategy(rec); 1164a644116c3375b12c642d1b51ee1e5cf4a22c1f5breed fSaveCount += 1; 11654960eeec4a1f2a772654883d7f3615d47bcd5dc3reed this->internalSaveLayer(rec, strategy); 11662ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return this->getSaveCount() - 1; 11678926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com} 11688926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 1169bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areedstatic void draw_filter_into_device(SkBaseDevice* src, const SkImageFilter* filter, 1170bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed SkBaseDevice* dst, const SkMatrix& ctm) { 11717354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips 11727354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips SkBitmap srcBM; 11737354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips 11747354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips#if SK_SUPPORT_GPU 11757354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips GrRenderTarget* srcRT = src->accessRenderTarget(); 11767354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips if (srcRT && !srcRT->asTexture() && dst->accessRenderTarget()) { 11777354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips // When both the src & the dst are on the gpu but the src doesn't have a texture, 11787354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips // we create a temporary texture for the draw. 11797354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips // TODO: we should actually only copy the portion of the source needed to apply the image 11807354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips // filter 11817354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips GrContext* context = srcRT->getContext(); 11827354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips SkAutoTUnref<GrTexture> tex(context->textureProvider()->createTexture(srcRT->desc(), true)); 11837354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips 11847354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips context->copySurface(tex, srcRT); 11857354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips 11867354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips GrWrapTextureInBitmap(tex, src->width(), src->height(), src->isOpaque(), &srcBM); 11877354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips } else 11887354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips#endif 11897354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips { 11907354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips srcBM = src->accessBitmap(false); 11917354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips } 11927354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips 11937354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips SkCanvas c(dst); 11947354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips 1195bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed SkAutoTUnref<SkImageFilter> localF(filter->newWithLocalMatrix(ctm)); 11967354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips SkPaint p; 1197bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed p.setImageFilter(localF); 1198bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed const SkScalar x = SkIntToScalar(src->getOrigin().x()); 1199bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed const SkScalar y = SkIntToScalar(src->getOrigin().y()); 1200bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed c.drawBitmap(srcBM, x, y, &p); 12017354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips} 120270ee31b2fa127eee6c0cea61cf05508e9d3ca7b1reed 12034960eeec4a1f2a772654883d7f3615d47bcd5dc3reedvoid SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy strategy) { 12044960eeec4a1f2a772654883d7f3615d47bcd5dc3reed const SkRect* bounds = rec.fBounds; 12054960eeec4a1f2a772654883d7f3615d47bcd5dc3reed const SkPaint* paint = rec.fPaint; 12064960eeec4a1f2a772654883d7f3615d47bcd5dc3reed SaveLayerFlags saveLayerFlags = rec.fSaveLayerFlags; 12074960eeec4a1f2a772654883d7f3615d47bcd5dc3reed 1208b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG 12094960eeec4a1f2a772654883d7f3615d47bcd5dc3reed saveLayerFlags &= ~kDontClipToLayer_PrivateSaveLayerFlag; 1210b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#endif 1211b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com 1212a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org // do this before we create the layer. We don't call the public save() since 1213a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org // that would invoke a possibly overridden virtual 12142ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalSave(); 1215a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 1216a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org fDeviceCMDirty = true; 1217a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 1218a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org SkIRect ir; 12194960eeec4a1f2a772654883d7f3615d47bcd5dc3reed if (!this->clipRectBounds(bounds, saveLayerFlags, &ir, paint ? paint->getImageFilter() : nullptr)) { 12202ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 12218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1223e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy really care about 1224e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org // the clipRectBounds() call above? 1225e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org if (kNoLayer_SaveLayerStrategy == strategy) { 12262ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 1227e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org } 1228e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org 12294960eeec4a1f2a772654883d7f3615d47bcd5dc3reed bool isOpaque = SkToBool(saveLayerFlags & kIsOpaque_SaveLayerFlag); 12308dc0ccb8d33d1af7dd13228509e61fe915bc7705reed SkPixelGeometry geo = fProps.pixelGeometry(); 12318dc0ccb8d33d1af7dd13228509e61fe915bc7705reed if (paint) { 123276033be81b82c44fd5d4fdf2672eb22e505da1f0reed // TODO: perhaps add a query to filters so we might preserve opaqueness... 1233daa57bfd4204f5a7d304c580bcf5ad99d0121e1freed if (paint->getImageFilter() || paint->getColorFilter()) { 123476033be81b82c44fd5d4fdf2672eb22e505da1f0reed isOpaque = false; 12358dc0ccb8d33d1af7dd13228509e61fe915bc7705reed geo = kUnknown_SkPixelGeometry; 1236b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com } 1237b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com } 123815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org SkImageInfo info = SkImageInfo::MakeN32(ir.width(), ir.height(), 123915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType); 12408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1241b2db898573e3cdcc8234eebf51961bfc4977ebbcreed SkBaseDevice* device = this->getTopDevice(); 124296fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == device) { 1243b2db898573e3cdcc8234eebf51961bfc4977ebbcreed SkDebugf("Unable to find device for layer."); 12442ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 1245b2db898573e3cdcc8234eebf51961bfc4977ebbcreed } 1246b2db898573e3cdcc8234eebf51961bfc4977ebbcreed 124761f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed bool forceSpriteOnRestore = false; 124861f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed { 124970ee31b2fa127eee6c0cea61cf05508e9d3ca7b1reed const bool preserveLCDText = kOpaque_SkAlphaType == info.alphaType() || 12504960eeec4a1f2a772654883d7f3615d47bcd5dc3reed (saveLayerFlags & kPreserveLCDText_SaveLayerFlag); 1251daa57bfd4204f5a7d304c580bcf5ad99d0121e1freed const SkBaseDevice::TileUsage usage = SkBaseDevice::kNever_TileUsage; 125270ee31b2fa127eee6c0cea61cf05508e9d3ca7b1reed const SkBaseDevice::CreateInfo createInfo = SkBaseDevice::CreateInfo(info, usage, geo, 125370ee31b2fa127eee6c0cea61cf05508e9d3ca7b1reed preserveLCDText, false); 125461f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed SkBaseDevice* newDev = device->onCreateDevice(createInfo, paint); 125596fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == newDev) { 125661f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed // If onCreateDevice didn't succeed, try raster (e.g. PDF couldn't handle the paint) 12579a53fd7c41554630124522f4b6eedc16912abbb7robertphillips const SkSurfaceProps surfaceProps(fProps.flags(), createInfo.fPixelGeometry); 12589a53fd7c41554630124522f4b6eedc16912abbb7robertphillips newDev = SkBitmapDevice::Create(createInfo.fInfo, surfaceProps); 125996fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == newDev) { 126061f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed SkErrorInternals::SetError(kInternalError_SkError, 126161f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed "Unable to create device for layer."); 126261f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed return; 126361f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed } 126461f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed forceSpriteOnRestore = true; 126561f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed } 126661f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed device = newDev; 1267e25c68402b38ac01dc1ae196ae8a5265b773c5f2bungeman@google.com } 12686f8f292aa768869a9e85c314b124875f57504f2creed@google.com device->setOrigin(ir.fLeft, ir.fTop); 12697354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips 1270bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed if (rec.fBackdrop) { 1271bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed draw_filter_into_device(fMCRec->fTopLayer->fDevice, rec.fBackdrop, device, fMCRec->fMatrix); 12727354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips } 12737354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips 1274385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary DeviceCM* layer = 1275385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary new DeviceCM(device, paint, this, fConservativeRasterClip, forceSpriteOnRestore); 12768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device->unref(); 12778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com layer->fNext = fMCRec->fTopLayer; 12798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fLayer = layer; 12808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fTopLayer = layer; // this field is NOT an owner of layer 12818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1283d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.orgint SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) { 1284bada1885da479d948f065182d6dfa85a1140bda5reed if (0xFF == alpha) { 1285bada1885da479d948f065182d6dfa85a1140bda5reed return this->saveLayer(bounds, nullptr); 1286bada1885da479d948f065182d6dfa85a1140bda5reed } else { 1287bada1885da479d948f065182d6dfa85a1140bda5reed SkPaint tmpPaint; 1288bada1885da479d948f065182d6dfa85a1140bda5reed tmpPaint.setAlpha(alpha); 1289bada1885da479d948f065182d6dfa85a1140bda5reed return this->saveLayer(bounds, &tmpPaint); 1290bada1885da479d948f065182d6dfa85a1140bda5reed } 1291d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org} 1292d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org 1293bada1885da479d948f065182d6dfa85a1140bda5reed#ifdef SK_SUPPORT_LEGACY_SAVEFLAGS 12948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha, 12958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SaveFlags flags) { 12968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (0xFF == alpha) { 129796fcdcc219d2a0d3579719b84b28bede76efba64halcanary return this->saveLayer(bounds, nullptr, flags); 12988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 12998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint tmpPaint; 13008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com tmpPaint.setAlpha(alpha); 13018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->saveLayer(bounds, &tmpPaint, flags); 13028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1304bada1885da479d948f065182d6dfa85a1140bda5reed#endif 13058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::internalRestore() { 13078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fMCStack.count() != 0); 13088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1310c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 13118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1312687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->restore(); 13136c157640c27ee2ed6f9a484d21691b7b19dfecdecommit-bot@chromium.org 131488edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com // reserve our layer (if any) 13158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* layer = fMCRec->fLayer; // may be null 13168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now detach it from fMCRec so we can pop(). Gets freed after its drawn 131796fcdcc219d2a0d3579719b84b28bede76efba64halcanary fMCRec->fLayer = nullptr; 13188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now do the normal restore() 13208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->~MCRec(); // balanced in save() 13218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCStack.pop_back(); 13228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = (MCRec*)fMCStack.back(); 13238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* Time to draw the layer's offscreen. We can't call the public drawSprite, 13258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com since if we're being recorded, we don't want to record this (the 13268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com recorder will have already recorded the restore). 13278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 132849f085dddff10473b6ebf832a974288300224e60bsalomon if (layer) { 13298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (layer->fNext) { 13306f8f292aa768869a9e85c314b124875f57504f2creed@google.com const SkIPoint& origin = layer->fDevice->getOrigin(); 13318926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(), 133261f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed layer->fPaint, layer->fDeviceIsBitmapDevice); 13338926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com // reset this, since internalDrawDevice will have set it to true 13348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1335385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete layer; 1336b679ca8926a832274b14fdb512f88f64b61d32eareed } else { 1337b679ca8926a832274b14fdb512f88f64b61d32eareed // we're at the root 1338a499f905e9340e4935447f2562fd92e8853382b1reed SkASSERT(layer == (void*)fDeviceCMStorage); 1339b679ca8926a832274b14fdb512f88f64b61d32eareed layer->~DeviceCM(); 13408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 134188edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 13428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13444a8126e7f81384526629b1e21bf89b632ea13cd9reedSkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* props) { 134596fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == props) { 13464a8126e7f81384526629b1e21bf89b632ea13cd9reed props = &fProps; 13474a8126e7f81384526629b1e21bf89b632ea13cd9reed } 13484a8126e7f81384526629b1e21bf89b632ea13cd9reed return this->onNewSurface(info, *props); 134976f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com} 135076f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com 13514a8126e7f81384526629b1e21bf89b632ea13cd9reedSkSurface* SkCanvas::onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props) { 135276f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com SkBaseDevice* dev = this->getDevice(); 135396fcdcc219d2a0d3579719b84b28bede76efba64halcanary return dev ? dev->newSurface(info, props) : nullptr; 135476f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com} 135576f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com 1356c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgSkImageInfo SkCanvas::imageInfo() const { 1357c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkBaseDevice* dev = this->getDevice(); 1358c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (dev) { 1359c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return dev->imageInfo(); 1360c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } else { 1361900ecf2f1579d42c9d2959831787af0346320f86reed@google.com return SkImageInfo::MakeUnknown(0, 0); 1362c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1363c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1364c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1365c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgconst void* SkCanvas::peekPixels(SkImageInfo* info, size_t* rowBytes) { 1366884e97cb04db7ed053a866567ee9c6e4c01f993areed SkPixmap pmap; 1367884e97cb04db7ed053a866567ee9c6e4c01f993areed if (!this->onPeekPixels(&pmap)) { 136896fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 1369884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1370884e97cb04db7ed053a866567ee9c6e4c01f993areed if (info) { 1371884e97cb04db7ed053a866567ee9c6e4c01f993areed *info = pmap.info(); 1372884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1373884e97cb04db7ed053a866567ee9c6e4c01f993areed if (rowBytes) { 1374884e97cb04db7ed053a866567ee9c6e4c01f993areed *rowBytes = pmap.rowBytes(); 1375884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1376884e97cb04db7ed053a866567ee9c6e4c01f993areed return pmap.addr(); 1377c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1378c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1379884e97cb04db7ed053a866567ee9c6e4c01f993areedbool SkCanvas::onPeekPixels(SkPixmap* pmap) { 1380c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkBaseDevice* dev = this->getDevice(); 1381884e97cb04db7ed053a866567ee9c6e4c01f993areed return dev && dev->peekPixels(pmap); 1382c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1383c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 13846b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.orgvoid* SkCanvas::accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin) { 1385884e97cb04db7ed053a866567ee9c6e4c01f993areed SkPixmap pmap; 1386884e97cb04db7ed053a866567ee9c6e4c01f993areed if (!this->onAccessTopLayerPixels(&pmap)) { 138796fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 1388884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1389884e97cb04db7ed053a866567ee9c6e4c01f993areed if (info) { 1390884e97cb04db7ed053a866567ee9c6e4c01f993areed *info = pmap.info(); 1391884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1392884e97cb04db7ed053a866567ee9c6e4c01f993areed if (rowBytes) { 1393884e97cb04db7ed053a866567ee9c6e4c01f993areed *rowBytes = pmap.rowBytes(); 1394884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1395884e97cb04db7ed053a866567ee9c6e4c01f993areed if (origin) { 13966b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org *origin = this->getTopDevice(false)->getOrigin(); 13976b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org } 1398884e97cb04db7ed053a866567ee9c6e4c01f993areed return pmap.writable_addr(); 13999c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 14009c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1401884e97cb04db7ed053a866567ee9c6e4c01f993areedbool SkCanvas::onAccessTopLayerPixels(SkPixmap* pmap) { 14029c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com SkBaseDevice* dev = this->getTopDevice(); 1403884e97cb04db7ed053a866567ee9c6e4c01f993areed return dev && dev->accessPixels(pmap); 14049c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 14059c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1406520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org///////////////////////////////////////////////////////////////////////////// 14078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14081f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comvoid SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, 140961f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed const SkPaint* paint, bool deviceIsBitmapDevice) { 14108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint tmp; 141196fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 14128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint = &tmp; 14138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 14144b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 14158926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com LOOPER_BEGIN_DRAWDEVICE(*paint, SkDrawFilter::kBitmap_Type) 14168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 14171f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* dstDev = iter.fDevice; 141876dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com paint = &looper.paint(); 141976dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkImageFilter* filter = paint->getImageFilter(); 142076dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkIPoint pos = { x - iter.getX(), y - iter.getY() }; 14218926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com if (filter && !dstDev->canHandleImageFilter(filter)) { 142288d064d0e481949184305c7b1d6b282dddffac39reed SkImageFilter::DeviceProxy proxy(dstDev); 142376dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkBitmap dst; 14246776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org SkIPoint offset = SkIPoint::Make(0, 0); 1425b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com const SkBitmap& src = srcDev->accessBitmap(false); 1426fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org SkMatrix matrix = *iter.fMatrix; 1427d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org matrix.postTranslate(SkIntToScalar(-pos.x()), SkIntToScalar(-pos.y())); 1428db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco SkIRect clipBounds = iter.fClip->getBounds().makeOffset(-pos.x(), -pos.y()); 1429be129b26f13d575fd6b396c6ae759838ecc9bd1asenorblanco SkAutoTUnref<SkImageFilter::Cache> cache(dstDev->getImageFilterCache()); 14304e23cdaa6b892afeaa150c6d74099dc6c2065b7ereed SkImageFilter::Context ctx(matrix, clipBounds, cache.get()); 14314cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org if (filter->filterImage(&proxy, src, ctx, &dst, &offset)) { 14325efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com SkPaint tmpUnfiltered(*paint); 143396fcdcc219d2a0d3579719b84b28bede76efba64halcanary tmpUnfiltered.setImageFilter(nullptr); 14346776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org dstDev->drawSprite(iter, dst, pos.x() + offset.x(), pos.y() + offset.y(), 14356776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org tmpUnfiltered); 143676dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } 143761f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed } else if (deviceIsBitmapDevice) { 14389572a10c9a6a868bbb8f71d7806d0a45f183333freed const SkBitmap& src = static_cast<SkBitmapDevice*>(srcDev)->fBitmap; 143961f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed dstDev->drawSprite(iter, src, pos.x(), pos.y(), *paint); 144076dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } else { 1441b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com dstDev->drawDevice(iter, srcDev, pos.x(), pos.y(), *paint); 144276dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } 14438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 14444e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 14458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 144732704674f64cb6a14356dfebe060cd3484c06cc7reed///////////////////////////////////////////////////////////////////////////// 1448da420b976e61071cfe5de10556b4b23e519091d6reed 144992362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::translate(SkScalar dx, SkScalar dy) { 1450d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1451d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setTranslate(dx, dy); 1452d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 14538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 145592362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::scale(SkScalar sx, SkScalar sy) { 1456d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1457d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setScale(sx, sy); 1458d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 14598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 146192362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::rotate(SkScalar degrees) { 1462d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1463d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setRotate(degrees); 1464d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 14658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 146792362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::skew(SkScalar sx, SkScalar sy) { 1468d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1469d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setSkew(sx, sy); 1470d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 147144c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org} 147244c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 147392362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::concat(const SkMatrix& matrix) { 1474d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org if (matrix.isIdentity()) { 1475d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org return; 1476d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org } 1477d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org 14782ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 14798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1480c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 14811f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix.preConcat(matrix); 148244c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 148344c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org this->didConcat(matrix); 148444c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org} 148544c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 148686a17e7716c8db858e219a46b9db3817bb770beereedvoid SkCanvas::setMatrix(const SkMatrix& matrix) { 148786a17e7716c8db858e219a46b9db3817bb770beereed this->checkForDeferredSave(); 14888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1489c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 14901f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix = matrix; 149144c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org this->didSetMatrix(matrix); 14928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::resetMatrix() { 14958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 14964b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 14978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.reset(); 14988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->setMatrix(matrix); 14998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 15008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 15018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 15028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1503759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { 15042ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 15058f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 15068f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(rect, op, edgeStyle); 15078f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 15088f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 15098f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 1510da17f758442f16747af39f8fbaed9c097048519creed@google.com#ifdef SK_ENABLE_CLIP_QUICKREJECT 1511da17f758442f16747af39f8fbaed9c097048519creed@google.com if (SkRegion::kIntersect_Op == op) { 15121f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fRasterClip.isEmpty()) { 1513da17f758442f16747af39f8fbaed9c097048519creed@google.com return false; 1514da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1515da17f758442f16747af39f8fbaed9c097048519creed@google.com 15163b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(rect)) { 1517da17f758442f16747af39f8fbaed9c097048519creed@google.com fDeviceCMDirty = true; 1518c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 1519da17f758442f16747af39f8fbaed9c097048519creed@google.com 1520687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipEmpty(); 15211f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.setEmpty(); 1522da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1523da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1524da17f758442f16747af39f8fbaed9c097048519creed@google.com#endif 1525da17f758442f16747af39f8fbaed9c097048519creed@google.com 1526ac8cabd729c75fdf774c0701b6ea7fd3ea5b9382bsalomon if (!fAllowSoftClip) { 1527ac8cabd729c75fdf774c0701b6ea7fd3ea5b9382bsalomon edgeStyle = kHard_ClipEdgeStyle; 1528ac8cabd729c75fdf774c0701b6ea7fd3ea5b9382bsalomon } 1529ac8cabd729c75fdf774c0701b6ea7fd3ea5b9382bsalomon 1530c64eff55049b1192052b791549a32a03be1c43e3reed const bool rectStaysRect = fMCRec->fMatrix.rectStaysRect(); 1531c64eff55049b1192052b791549a32a03be1c43e3reed SkRect devR; 1532c64eff55049b1192052b791549a32a03be1c43e3reed if (rectStaysRect) { 1533c64eff55049b1192052b791549a32a03be1c43e3reed fMCRec->fMatrix.mapRect(&devR, rect); 1534c64eff55049b1192052b791549a32a03be1c43e3reed } 1535c64eff55049b1192052b791549a32a03be1c43e3reed 1536c64eff55049b1192052b791549a32a03be1c43e3reed // Check if we can quick-accept the clip call (and do nothing) 1537c64eff55049b1192052b791549a32a03be1c43e3reed // 1538c64eff55049b1192052b791549a32a03be1c43e3reed // TODO: investigate if a (conservative) version of this could be done in ::clipRect, 1539c64eff55049b1192052b791549a32a03be1c43e3reed // so that subclasses (like PictureRecording) didn't see unnecessary clips, which in turn 1540c64eff55049b1192052b791549a32a03be1c43e3reed // might allow lazy save/restores to eliminate entire save/restore blocks. 1541c64eff55049b1192052b791549a32a03be1c43e3reed // 1542c64eff55049b1192052b791549a32a03be1c43e3reed if (SkRegion::kIntersect_Op == op && 1543c64eff55049b1192052b791549a32a03be1c43e3reed kHard_ClipEdgeStyle == edgeStyle 1544c64eff55049b1192052b791549a32a03be1c43e3reed && rectStaysRect) 1545c64eff55049b1192052b791549a32a03be1c43e3reed { 1546c64eff55049b1192052b791549a32a03be1c43e3reed if (devR.round().contains(fMCRec->fRasterClip.getBounds())) { 1547c64eff55049b1192052b791549a32a03be1c43e3reed#if 0 1548c64eff55049b1192052b791549a32a03be1c43e3reed SkDebugf("------- ignored clipRect [%g %g %g %g]\n", 1549c64eff55049b1192052b791549a32a03be1c43e3reed rect.left(), rect.top(), rect.right(), rect.bottom()); 1550c64eff55049b1192052b791549a32a03be1c43e3reed#endif 1551c64eff55049b1192052b791549a32a03be1c43e3reed return; 1552c64eff55049b1192052b791549a32a03be1c43e3reed } 1553c64eff55049b1192052b791549a32a03be1c43e3reed } 1554c64eff55049b1192052b791549a32a03be1c43e3reed 1555c64eff55049b1192052b791549a32a03be1c43e3reed AutoValidateClip avc(this); 1556c64eff55049b1192052b791549a32a03be1c43e3reed 1557c64eff55049b1192052b791549a32a03be1c43e3reed fDeviceCMDirty = true; 1558c64eff55049b1192052b791549a32a03be1c43e3reed fCachedLocalClipBoundsDirty = true; 15598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1560c64eff55049b1192052b791549a32a03be1c43e3reed if (rectStaysRect) { 1561c64eff55049b1192052b791549a32a03be1c43e3reed const bool isAA = kSoft_ClipEdgeStyle == edgeStyle; 1562c64eff55049b1192052b791549a32a03be1c43e3reed fClipStack->clipDevRect(devR, op, isAA); 1563c64eff55049b1192052b791549a32a03be1c43e3reed fMCRec->fRasterClip.op(devR, this->getBaseLayerSize(), op, isAA); 15648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 1565123671901abfa595d09ca789b487c4bc7c1f7cbcrobertphillips@google.com // since we're rotated or some such thing, we convert the rect to a path 156698de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // and clip against that, since it can handle any matrix. However, to 156798de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // avoid recursion in the case where we are subclassed (e.g. Pictures) 156898de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // we explicitly call "our" version of clipPath. 15698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath path; 15708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 15718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.addRect(rect); 15728f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->SkCanvas::onClipPath(path, op, edgeStyle); 15738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 15748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 15758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 157673e714eb766617ce06757829a3c0b345c7963faareedstatic void rasterclip_path(SkRasterClip* rc, const SkCanvas* canvas, const SkPath& devPath, 157773e714eb766617ce06757829a3c0b345c7963faareed SkRegion::Op op, bool doAA) { 1578d64c9487135094c83f658319f53ea2005ecc08b2reed rc->op(devPath, canvas->getBaseLayerSize(), op, doAA); 1579819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com} 1580819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 1581759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) { 15822ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 15838f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 15844ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (rrect.isRect()) { 15858f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(rrect.getBounds(), op, edgeStyle); 15868f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } else { 15878f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRRect(rrect, op, edgeStyle); 15884ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 15898f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 159014e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 15918f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 159214e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org SkRRect transformedRRect; 15931f836ee096bb988adef4b9757b2629c7afeda36dreed if (rrect.transform(fMCRec->fMatrix, &transformedRRect)) { 159414e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org AutoValidateClip avc(this); 159514e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 159614e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org fDeviceCMDirty = true; 159714e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org fCachedLocalClipBoundsDirty = true; 15988f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!fAllowSoftClip) { 15998f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com edgeStyle = kHard_ClipEdgeStyle; 16008f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 160114e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 1602687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipDevRRect(transformedRRect, op, kSoft_ClipEdgeStyle == edgeStyle); 160314e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 1604125f19a2964c31a660256132acbce60e8a3e6752robertphillips fMCRec->fRasterClip.op(transformedRRect, this->getBaseLayerSize(), op, 1605125f19a2964c31a660256132acbce60e8a3e6752robertphillips kSoft_ClipEdgeStyle == edgeStyle); 16068f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com return; 160714e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org } 160814e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 160914e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org SkPath path; 161014e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org path.addRRect(rrect); 161114e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org // call the non-virtual version 16128f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->SkCanvas::onClipPath(path, op, edgeStyle); 16134ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 16144ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 1615759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { 16162ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 16178f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 161839f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips 161939f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips if (!path.isInverseFillType() && fMCRec->fMatrix.rectStaysRect()) { 162039f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips SkRect r; 162139f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips if (path.isRect(&r)) { 162239f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips this->onClipRect(r, op, edgeStyle); 162339f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips return; 162439f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips } 162539f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips SkRRect rrect; 162639f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips if (path.isOval(&r)) { 162739f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips rrect.setOval(r); 162839f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips this->onClipRRect(rrect, op, edgeStyle); 162939f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips return; 163039f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips } 163139f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips if (path.isRRect(&rrect)) { 163239f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips this->onClipRRect(rrect, op, edgeStyle); 163339f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips return; 163439f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips } 16358f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 163639f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips 163739f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips this->onClipPath(path, op, edgeStyle); 16388f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 16398f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 16408f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 1641da17f758442f16747af39f8fbaed9c097048519creed@google.com#ifdef SK_ENABLE_CLIP_QUICKREJECT 1642da17f758442f16747af39f8fbaed9c097048519creed@google.com if (SkRegion::kIntersect_Op == op && !path.isInverseFillType()) { 16431f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fRasterClip.isEmpty()) { 1644da17f758442f16747af39f8fbaed9c097048519creed@google.com return false; 1645da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1646fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 16473b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(path.getBounds())) { 1648da17f758442f16747af39f8fbaed9c097048519creed@google.com fDeviceCMDirty = true; 1649c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 1650fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1651687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipEmpty(); 16521f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.setEmpty(); 1653da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1654da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1655da17f758442f16747af39f8fbaed9c097048519creed@google.com#endif 1656da17f758442f16747af39f8fbaed9c097048519creed@google.com 16575c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com AutoValidateClip avc(this); 16585c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 16598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1660c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 16618f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!fAllowSoftClip) { 16628f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com edgeStyle = kHard_ClipEdgeStyle; 16638f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 16648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath devPath; 16661f836ee096bb988adef4b9757b2629c7afeda36dreed path.transform(fMCRec->fMatrix, &devPath); 16678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1668fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // Check if the transfomation, or the original path itself 1669fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // made us empty. Note this can also happen if we contained NaN 1670fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // values. computing the bounds detects this, and will set our 1671fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // bounds to empty if that is the case. (see SkRect::set(pts, count)) 1672fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com if (devPath.getBounds().isEmpty()) { 1673fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // resetting the path will remove any NaN or other wanky values 1674fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // that might upset our scan converter. 1675fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com devPath.reset(); 1676fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com } 1677fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com 16785c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // if we called path.swap() we could avoid a deep copy of this path 1679687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipDevPath(devPath, op, kSoft_ClipEdgeStyle == edgeStyle); 16805c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 168145a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com if (fAllowSimplifyClip) { 16821a481fe4bf632ed4f76cb337691236fabfd4ab03fmalita bool clipIsAA = getClipStack()->asPath(&devPath); 16831a481fe4bf632ed4f76cb337691236fabfd4ab03fmalita if (clipIsAA) { 16841a481fe4bf632ed4f76cb337691236fabfd4ab03fmalita edgeStyle = kSoft_ClipEdgeStyle; 168545a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com } 16861a481fe4bf632ed4f76cb337691236fabfd4ab03fmalita 168745a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com op = SkRegion::kReplace_Op; 168845a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com } 168945a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com 169073e714eb766617ce06757829a3c0b345c7963faareed rasterclip_path(&fMCRec->fRasterClip, this, devPath, op, edgeStyle); 16918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1693759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipRegion(const SkRegion& rgn, SkRegion::Op op) { 16942ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 16958f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRegion(rgn, op); 16968f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 16978f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 16988f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipRegion(const SkRegion& rgn, SkRegion::Op op) { 16995c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com AutoValidateClip avc(this); 17005c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 17018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1702c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 17038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17045c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // todo: signal fClipStack that we have a region, and therefore (I guess) 17055c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // we have to ignore it, and use the region directly? 1706687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipDevRect(rgn.getBounds(), op); 17075c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 17081f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fRasterClip.op(rgn, op); 17098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1711819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com#ifdef SK_DEBUG 1712819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.comvoid SkCanvas::validateClip() const { 1713819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com // construct clipRgn from the clipstack 17141f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com const SkBaseDevice* device = this->getDevice(); 1715ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com if (!device) { 17165c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org SkASSERT(this->isClipEmpty()); 1717ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com return; 1718ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com } 1719ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com 1720819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com SkIRect ir; 1721819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com ir.set(0, 0, device->width(), device->height()); 1722d954498c01ccf0417feacf89e45d0c62a06a813breed SkRasterClip tmpClip(ir, fConservativeRasterClip); 1723819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 1724687fa1c745febb57f42b0d5f03d7c1f4be2530careed SkClipStack::B2TIter iter(*fClipStack); 17258182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const SkClipStack::Element* element; 172696fcdcc219d2a0d3579719b84b28bede76efba64halcanary while ((element = iter.next()) != nullptr) { 17278182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com switch (element->getType()) { 17288182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kRect_Type: 17298182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com element->getRect().round(&ir); 17308182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com tmpClip.op(ir, element->getOp()); 17318182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 17328182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kEmpty_Type: 17338182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com tmpClip.setEmpty(); 17348182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 17359cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org default: { 17369cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org SkPath path; 17379cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org element->asPath(&path); 173873e714eb766617ce06757829a3c0b345c7963faareed rasterclip_path(&tmpClip, this, path, element->getOp(), element->isAA()); 17399cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org break; 17409cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org } 1741819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com } 1742819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com } 1743819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com} 1744819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com#endif 1745819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 174690c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.comvoid SkCanvas::replayClips(ClipVisitor* visitor) const { 1747687fa1c745febb57f42b0d5f03d7c1f4be2530careed SkClipStack::B2TIter iter(*fClipStack); 17488182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const SkClipStack::Element* element; 17498182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com 175096fcdcc219d2a0d3579719b84b28bede76efba64halcanary while ((element = iter.next()) != nullptr) { 1751c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita element->replay(visitor); 175290c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com } 175390c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com} 175490c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com 17555c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com/////////////////////////////////////////////////////////////////////////////// 17565c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 1757754de5f65b466f721d952a379194cc94de376f42reed@google.combool SkCanvas::isClipEmpty() const { 17581f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.isEmpty(); 1759754de5f65b466f721d952a379194cc94de376f42reed@google.com} 1760754de5f65b466f721d952a379194cc94de376f42reed@google.com 17615c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.orgbool SkCanvas::isClipRect() const { 17621f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.isRect(); 17635c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org} 17645c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org 17653b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::quickReject(const SkRect& rect) const { 17661607863b608b7db6c813228768ed5d72997bbc82reed@google.com if (!rect.isFinite()) 1767116b2bcd2c4c4d4670c7b7e2ea597414713c37fbwjmaclean@chromium.org return true; 1768116b2bcd2c4c4d4670c7b7e2ea597414713c37fbwjmaclean@chromium.org 17691f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fRasterClip.isEmpty()) { 17708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 17718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 17728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17731f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fMatrix.hasPerspective()) { 1774a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com SkRect dst; 17751f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix.mapRect(&dst, rect); 1776b07a94f1cba3976596ae1a7f23d8c2043ba353f3reed return !SkIRect::Intersects(dst.roundOut(), fMCRec->fRasterClip.getBounds()); 1777a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com } else { 1778c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com const SkRect& clipR = this->getLocalClipBounds(); 1779d252db03d9650013b545ef9781fe993c07f8f314reed@android.com 1780a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com // for speed, do the most likely reject compares first 1781c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com // TODO: should we use | instead, or compare all 4 at once? 1782c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com if (rect.fTop >= clipR.fBottom || rect.fBottom <= clipR.fTop) { 1783a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com return true; 1784a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com } 1785c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com if (rect.fLeft >= clipR.fRight || rect.fRight <= clipR.fLeft) { 1786a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com return true; 1787a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com } 1788a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com return false; 17898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 17908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17923b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::quickReject(const SkPath& path) const { 17933b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com return path.isEmpty() || this->quickReject(path.getBounds()); 17948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17963b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::getClipBounds(SkRect* bounds) const { 1797bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect ibounds; 17988f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!this->getClipDeviceBounds(&ibounds)) { 17998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 18008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1802d9c0f0b57affec7a472879c5919acac6637d926areed@android.com SkMatrix inverse; 1803d9c0f0b57affec7a472879c5919acac6637d926areed@android.com // if we can't invert the CTM, we can't return local clip bounds 18041f836ee096bb988adef4b9757b2629c7afeda36dreed if (!fMCRec->fMatrix.invert(&inverse)) { 180572dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com if (bounds) { 180672dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com bounds->setEmpty(); 180772dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com } 1808d9c0f0b57affec7a472879c5919acac6637d926areed@android.com return false; 1809d9c0f0b57affec7a472879c5919acac6637d926areed@android.com } 1810d9c0f0b57affec7a472879c5919acac6637d926areed@android.com 181149f085dddff10473b6ebf832a974288300224e60bsalomon if (bounds) { 1812bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkRect r; 18133b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com // adjust it outwards in case we are antialiasing 18143b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com const int inset = 1; 1815fa4d5bd09f8f1a4a92b5ae0324800dd672760898reed@google.com 18168f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com r.iset(ibounds.fLeft - inset, ibounds.fTop - inset, 18178f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com ibounds.fRight + inset, ibounds.fBottom + inset); 18188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inverse.mapRect(bounds, r); 18198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 18218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1823bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.combool SkCanvas::getClipDeviceBounds(SkIRect* bounds) const { 18241f836ee096bb988adef4b9757b2629c7afeda36dreed const SkRasterClip& clip = fMCRec->fRasterClip; 1825bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (clip.isEmpty()) { 1826bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (bounds) { 1827bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com bounds->setEmpty(); 1828bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1829bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com return false; 1830bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1831bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com 183249f085dddff10473b6ebf832a974288300224e60bsalomon if (bounds) { 1833bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com *bounds = clip.getBounds(); 1834bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1835bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com return true; 1836bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com} 1837bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com 18388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkMatrix& SkCanvas::getTotalMatrix() const { 18391f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fMatrix; 18408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18425c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.orgconst SkRegion& SkCanvas::internal_private_getTotalClip() const { 18431f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.forceGetBW(); 18445c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org} 18455c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org 18469c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.comGrRenderTarget* SkCanvas::internal_private_accessTopLayerRenderTarget() { 18479c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com SkBaseDevice* dev = this->getTopDevice(); 184896fcdcc219d2a0d3579719b84b28bede76efba64halcanary return dev ? dev->accessRenderTarget() : nullptr; 18499c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 18509c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1851644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.orgGrContext* SkCanvas::getGrContext() { 1852644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#if SK_SUPPORT_GPU 1853644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org SkBaseDevice* device = this->getTopDevice(); 185449f085dddff10473b6ebf832a974288300224e60bsalomon if (device) { 1855644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org GrRenderTarget* renderTarget = device->accessRenderTarget(); 185649f085dddff10473b6ebf832a974288300224e60bsalomon if (renderTarget) { 1857644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org return renderTarget->getContext(); 1858644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org } 1859644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org } 1860644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#endif 1861644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org 186296fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 1863644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org 1864644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org} 1865e97f0856a8044866b12527819d14cdfbcdfd96f2bsalomon@google.com 1866ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.orgvoid SkCanvas::drawDRRect(const SkRRect& outer, const SkRRect& inner, 1867ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkPaint& paint) { 18689881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawDRRect()"); 1869ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (outer.isEmpty()) { 1870ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 1871ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 1872ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (inner.isEmpty()) { 1873ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->drawRRect(outer, paint); 1874ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 1875ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 1876ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 1877ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // We don't have this method (yet), but technically this is what we should 1878ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // be able to assert... 1879ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // SkASSERT(outer.contains(inner)); 1880ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // 1881ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // For now at least check for containment of bounds 1882ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org SkASSERT(outer.getBounds().contains(inner.getBounds())); 1883ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 1884ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->onDrawDRRect(outer, inner, paint); 1885ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org} 1886ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 188741af966ab338e95eee81ab618ab28195075338f7reed// These need to stop being virtual -- clients need to override the onDraw... versions 188841af966ab338e95eee81ab618ab28195075338f7reed 188941af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawPaint(const SkPaint& paint) { 189041af966ab338e95eee81ab618ab28195075338f7reed this->onDrawPaint(paint); 189141af966ab338e95eee81ab618ab28195075338f7reed} 189241af966ab338e95eee81ab618ab28195075338f7reed 189341af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawRect(const SkRect& r, const SkPaint& paint) { 189441af966ab338e95eee81ab618ab28195075338f7reed this->onDrawRect(r, paint); 189541af966ab338e95eee81ab618ab28195075338f7reed} 189641af966ab338e95eee81ab618ab28195075338f7reed 189741af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawOval(const SkRect& r, const SkPaint& paint) { 189841af966ab338e95eee81ab618ab28195075338f7reed this->onDrawOval(r, paint); 189941af966ab338e95eee81ab618ab28195075338f7reed} 190041af966ab338e95eee81ab618ab28195075338f7reed 190141af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) { 190241af966ab338e95eee81ab618ab28195075338f7reed this->onDrawRRect(rrect, paint); 190341af966ab338e95eee81ab618ab28195075338f7reed} 190441af966ab338e95eee81ab618ab28195075338f7reed 190541af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint) { 190641af966ab338e95eee81ab618ab28195075338f7reed this->onDrawPoints(mode, count, pts, paint); 190741af966ab338e95eee81ab618ab28195075338f7reed} 190841af966ab338e95eee81ab618ab28195075338f7reed 190941af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawVertices(VertexMode vmode, int vertexCount, const SkPoint vertices[], 191041af966ab338e95eee81ab618ab28195075338f7reed const SkPoint texs[], const SkColor colors[], SkXfermode* xmode, 191141af966ab338e95eee81ab618ab28195075338f7reed const uint16_t indices[], int indexCount, const SkPaint& paint) { 191241af966ab338e95eee81ab618ab28195075338f7reed this->onDrawVertices(vmode, vertexCount, vertices, texs, colors, xmode, 191341af966ab338e95eee81ab618ab28195075338f7reed indices, indexCount, paint); 191441af966ab338e95eee81ab618ab28195075338f7reed} 191541af966ab338e95eee81ab618ab28195075338f7reed 191641af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawPath(const SkPath& path, const SkPaint& paint) { 191741af966ab338e95eee81ab618ab28195075338f7reed this->onDrawPath(path, paint); 191841af966ab338e95eee81ab618ab28195075338f7reed} 191941af966ab338e95eee81ab618ab28195075338f7reed 1920a85d4d0814818e4ddabb9237da209d61d6cd5854reedvoid SkCanvas::drawImage(const SkImage* image, SkScalar x, SkScalar y, const SkPaint* paint) { 1921e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 1922a85d4d0814818e4ddabb9237da209d61d6cd5854reed this->onDrawImage(image, x, y, paint); 192341af966ab338e95eee81ab618ab28195075338f7reed} 192441af966ab338e95eee81ab618ab28195075338f7reed 1925e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst, 1926e47829b6b1eeb6b0c97ccb3df3016d197046824creed const SkPaint* paint, SrcRectConstraint constraint) { 1927e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 1928e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (dst.isEmpty() || src.isEmpty()) { 1929e47829b6b1eeb6b0c97ccb3df3016d197046824creed return; 1930e47829b6b1eeb6b0c97ccb3df3016d197046824creed } 1931e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->onDrawImageRect(image, &src, dst, paint, constraint); 1932e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 193341af966ab338e95eee81ab618ab28195075338f7reed 193484984efeb64787b88c5f8bd6929cfe2d58a3ba06reedvoid SkCanvas::drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst, 193584984efeb64787b88c5f8bd6929cfe2d58a3ba06reed const SkPaint* paint, SrcRectConstraint constraint) { 1936e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 1937e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, SkRect::Make(isrc), dst, paint, constraint); 193884984efeb64787b88c5f8bd6929cfe2d58a3ba06reed} 193984984efeb64787b88c5f8bd6929cfe2d58a3ba06reed 1940e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint, 1941e47829b6b1eeb6b0c97ccb3df3016d197046824creed SrcRectConstraint constraint) { 1942e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 1943e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, SkRect::MakeIWH(image->width(), image->height()), dst, paint, 1944e47829b6b1eeb6b0c97ccb3df3016d197046824creed constraint); 1945e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 1946e47829b6b1eeb6b0c97ccb3df3016d197046824creed 19474c21dc5ddf3b482293ed34eead876d8d61a662c3reedvoid SkCanvas::drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst, 19484c21dc5ddf3b482293ed34eead876d8d61a662c3reed const SkPaint* paint) { 1949e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 19504c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (dst.isEmpty()) { 19514c21dc5ddf3b482293ed34eead876d8d61a662c3reed return; 19524c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 19534c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (!SkNinePatchIter::Valid(image->width(), image->height(), center)) { 1954e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, dst, paint); 19554c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 19564c21dc5ddf3b482293ed34eead876d8d61a662c3reed this->onDrawImageNine(image, center, dst, paint); 19574c21dc5ddf3b482293ed34eead876d8d61a662c3reed} 19584c21dc5ddf3b482293ed34eead876d8d61a662c3reed 195941af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar dx, SkScalar dy, const SkPaint* paint) { 19604c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (bitmap.drawsNothing()) { 19612df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson return; 19622df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson } 196341af966ab338e95eee81ab618ab28195075338f7reed this->onDrawBitmap(bitmap, dx, dy, paint); 196441af966ab338e95eee81ab618ab28195075338f7reed} 196541af966ab338e95eee81ab618ab28195075338f7reed 1966e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst, 1967a5517e2b190a8083b38964972b031c13e99f1012reed const SkPaint* paint, SrcRectConstraint constraint) { 1968e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (bitmap.drawsNothing() || dst.isEmpty() || src.isEmpty()) { 1969a5517e2b190a8083b38964972b031c13e99f1012reed return; 1970a5517e2b190a8083b38964972b031c13e99f1012reed } 1971e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->onDrawBitmapRect(bitmap, &src, dst, paint, constraint); 197241af966ab338e95eee81ab618ab28195075338f7reed} 197341af966ab338e95eee81ab618ab28195075338f7reed 197484984efeb64787b88c5f8bd6929cfe2d58a3ba06reedvoid SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst, 197584984efeb64787b88c5f8bd6929cfe2d58a3ba06reed const SkPaint* paint, SrcRectConstraint constraint) { 1976e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, SkRect::Make(isrc), dst, paint, constraint); 1977e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 1978e47829b6b1eeb6b0c97ccb3df3016d197046824creed 1979e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint, 1980e47829b6b1eeb6b0c97ccb3df3016d197046824creed SrcRectConstraint constraint) { 1981e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, SkRect::MakeIWH(bitmap.width(), bitmap.height()), dst, paint, 1982e47829b6b1eeb6b0c97ccb3df3016d197046824creed constraint); 198384984efeb64787b88c5f8bd6929cfe2d58a3ba06reed} 198484984efeb64787b88c5f8bd6929cfe2d58a3ba06reed 198541af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst, 198641af966ab338e95eee81ab618ab28195075338f7reed const SkPaint* paint) { 19874c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (bitmap.drawsNothing() || dst.isEmpty()) { 19882df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson return; 19892df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson } 19904c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (!SkNinePatchIter::Valid(bitmap.width(), bitmap.height(), center)) { 1991a5517e2b190a8083b38964972b031c13e99f1012reed this->drawBitmapRect(bitmap, dst, paint); 19924c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 199341af966ab338e95eee81ab618ab28195075338f7reed this->onDrawBitmapNine(bitmap, center, dst, paint); 199441af966ab338e95eee81ab618ab28195075338f7reed} 199541af966ab338e95eee81ab618ab28195075338f7reed 199671c3c760a83123ee0b3127b8c65c6394ce541c50reedvoid SkCanvas::drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], 199771c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkColor colors[], int count, SkXfermode::Mode mode, 199871c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkRect* cull, const SkPaint* paint) { 1999e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(atlas); 200071c3c760a83123ee0b3127b8c65c6394ce541c50reed if (count <= 0) { 200171c3c760a83123ee0b3127b8c65c6394ce541c50reed return; 200271c3c760a83123ee0b3127b8c65c6394ce541c50reed } 200371c3c760a83123ee0b3127b8c65c6394ce541c50reed SkASSERT(atlas); 200471c3c760a83123ee0b3127b8c65c6394ce541c50reed SkASSERT(xform); 200571c3c760a83123ee0b3127b8c65c6394ce541c50reed SkASSERT(tex); 200671c3c760a83123ee0b3127b8c65c6394ce541c50reed this->onDrawAtlas(atlas, xform, tex, colors, count, mode, cull, paint); 200771c3c760a83123ee0b3127b8c65c6394ce541c50reed} 200871c3c760a83123ee0b3127b8c65c6394ce541c50reed 2009e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::legacy_drawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, 2010e47829b6b1eeb6b0c97ccb3df3016d197046824creed const SkPaint* paint, SrcRectConstraint constraint) { 2011e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (src) { 2012e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, *src, dst, paint, constraint); 2013e47829b6b1eeb6b0c97ccb3df3016d197046824creed } else { 2014e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, SkRect::MakeIWH(image->width(), image->height()), 2015e47829b6b1eeb6b0c97ccb3df3016d197046824creed dst, paint, constraint); 2016e47829b6b1eeb6b0c97ccb3df3016d197046824creed } 2017e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 2018e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::legacy_drawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, 2019e47829b6b1eeb6b0c97ccb3df3016d197046824creed const SkPaint* paint, SrcRectConstraint constraint) { 2020e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (src) { 2021e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, *src, dst, paint, constraint); 2022e47829b6b1eeb6b0c97ccb3df3016d197046824creed } else { 2023e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, SkRect::MakeIWH(bitmap.width(), bitmap.height()), 2024e47829b6b1eeb6b0c97ccb3df3016d197046824creed dst, paint, constraint); 2025e47829b6b1eeb6b0c97ccb3df3016d197046824creed } 2026e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 2027e47829b6b1eeb6b0c97ccb3df3016d197046824creed 20288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 20298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// These are the virtual drawing methods 20308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 20318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 203228361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.orgvoid SkCanvas::onDiscard() { 203349f085dddff10473b6ebf832a974288300224e60bsalomon if (fSurfaceBase) { 203428361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org fSurfaceBase->aboutToDraw(SkSurface::kDiscard_ContentChangeMode); 203528361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org } 203628361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org} 203728361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org 203841af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawPaint(const SkPaint& paint) { 20399881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPaint()"); 2040fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->internalDrawPaint(paint); 2041fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com} 2042fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com 2043fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.comvoid SkCanvas::internalDrawPaint(const SkPaint& paint) { 204496fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, SkDrawFilter::kPaint_Type, nullptr, false) 20458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 20474e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPaint(iter, looper.paint()); 20488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 20498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20504e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 20518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 20528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 205341af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[], 205441af966ab338e95eee81ab618ab28195075338f7reed const SkPaint& paint) { 20559881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT1("disabled-by-default-skia", "SkCanvas::drawPoints()", "count", static_cast<uint64_t>(count)); 20568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if ((long)count <= 0) { 20578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 20588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 20598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 206078cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect r, storage; 206196fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 2062a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com if (paint.canComputeFastBounds()) { 2063a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com // special-case 2 points (common for drawing a single line) 2064a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com if (2 == count) { 2065a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com r.set(pts[0], pts[1]); 2066a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } else { 2067a8c7f7702fb4bbedb615031bc653c5cd161a038ecommit-bot@chromium.org r.set(pts, SkToInt(count)); 2068a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } 206987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastStrokeBounds(r, &storage))) { 207087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 207187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 207287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &r; 2073fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 2074a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com 207596fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkASSERT(pts != nullptr); 20768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 207778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPoint_Type, bounds) 20784b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 20798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 20804e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPoints(iter, mode, count, pts, looper.paint()); 20818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 20824b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 20834e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 20848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 20858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 208641af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawRect(const SkRect& r, const SkPaint& paint) { 20879881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRect()"); 208878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 208996fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 20908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.canComputeFastBounds()) { 20918432808ad8898ac7137bc7ce1d9df6005e866401reed // Skia will draw an inverted rect, because it explicitly "sorts" it downstream. 20928432808ad8898ac7137bc7ce1d9df6005e866401reed // To prevent accidental rejecting at this stage, we have to sort it before we check. 20938432808ad8898ac7137bc7ce1d9df6005e866401reed SkRect tmp(r); 20948432808ad8898ac7137bc7ce1d9df6005e866401reed tmp.sort(); 20958432808ad8898ac7137bc7ce1d9df6005e866401reed 209687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(tmp, &storage))) { 209787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 209887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 209987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &r; 21008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 21014b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2102c83a29759a5c2966da5ab973e4fd90763e4c962breed LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, SkDrawFilter::kRect_Type, bounds, false) 21038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 21054e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawRect(iter, r, looper.paint()); 21068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 21078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21084e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 21098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 21108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 211141af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) { 21129881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawOval()"); 211378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 211496fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 21154ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (paint.canComputeFastBounds()) { 211687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(oval, &storage))) { 211787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 211887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 211987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &oval; 21204ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 2121306ab9d5de38f2a547fd1d69aedbe69b5c6617ccskia.committer@gmail.com 212278cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, bounds) 212346d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com 212446d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com while (iter.next()) { 212546d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com iter.fDevice->drawOval(iter, oval, looper.paint()); 212646d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com } 212746d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com 212846d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com LOOPER_END 21294ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 21304ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 213141af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) { 21329881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRRect()"); 213378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 213496fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 21354ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (paint.canComputeFastBounds()) { 213687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(rrect.getBounds(), &storage))) { 213787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 213887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 213987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &rrect.getBounds(); 21404ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 21414ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 21424ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (rrect.isRect()) { 21434ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com // call the non-virtual version 21444ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->SkCanvas::drawRect(rrect.getBounds(), paint); 2145f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org return; 2146f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } else if (rrect.isOval()) { 21474ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com // call the non-virtual version 2148f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org this->SkCanvas::drawOval(rrect.getBounds(), paint); 2149f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org return; 21504ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 2151f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 215278cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) 2153f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 2154f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org while (iter.next()) { 2155f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org iter.fDevice->drawRRect(iter, rrect, looper.paint()); 2156f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } 2157f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 2158f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org LOOPER_END 21594ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 21604ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 2161ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.orgvoid SkCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, 2162ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkPaint& paint) { 2163ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org SkRect storage; 216496fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 2165ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (paint.canComputeFastBounds()) { 216687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(outer.getBounds(), &storage))) { 216787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 216887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 216987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &outer.getBounds(); 2170ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 217125c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 2172ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) 217325c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 2174ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org while (iter.next()) { 2175ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org iter.fDevice->drawDRRect(iter, outer, inner, looper.paint()); 2176ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 217725c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 2178ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org LOOPER_END 2179ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org} 21804ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 218141af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) { 21829881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPath()"); 21839364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com if (!path.isFinite()) { 21849364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com return; 21859364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com } 21869364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com 218778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 218896fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 2189fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com if (!path.isInverseFillType() && paint.canComputeFastBounds()) { 219078cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect& pathBounds = path.getBounds(); 219187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(pathBounds, &storage))) { 219287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 219387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 219487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &pathBounds; 21958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 21960b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org 21970b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org const SkRect& r = path.getBounds(); 21980b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org if (r.width() <= 0 && r.height() <= 0) { 21996803c219dd3be4a73e7bb5c4bb8a5b1f803624d0commit-bot@chromium.org if (path.isInverseFillType()) { 2200fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->internalDrawPaint(paint); 22016651a3238dd6affa4276ada42ab613abf1d42d1dcaryclark return; 2202fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 2203fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 22048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 220578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, bounds) 22068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 22084e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPath(iter, path, looper.paint()); 22098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 22108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22114e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 22128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 22138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2214262a71b7f95ce98ff3dd8dba845afbd724470903reedbool SkCanvas::canDrawBitmapAsSprite(SkScalar x, SkScalar y, int w, int h, const SkPaint& paint) { 2215262a71b7f95ce98ff3dd8dba845afbd724470903reed if (!paint.getImageFilter()) { 2216262a71b7f95ce98ff3dd8dba845afbd724470903reed return false; 2217262a71b7f95ce98ff3dd8dba845afbd724470903reed } 2218262a71b7f95ce98ff3dd8dba845afbd724470903reed 2219262a71b7f95ce98ff3dd8dba845afbd724470903reed const SkMatrix& ctm = this->getTotalMatrix(); 2220c7e211acd0c9201688de7ff0c9a2271c67440adffmalita if (!SkTreatAsSprite(ctm, SkISize::Make(w, h), paint)) { 2221262a71b7f95ce98ff3dd8dba845afbd724470903reed return false; 2222262a71b7f95ce98ff3dd8dba845afbd724470903reed } 2223262a71b7f95ce98ff3dd8dba845afbd724470903reed 2224262a71b7f95ce98ff3dd8dba845afbd724470903reed // Currently we can only use the filterSprite code if we are clipped to the bitmap's bounds. 2225262a71b7f95ce98ff3dd8dba845afbd724470903reed // Once we can filter and the filter will return a result larger than itself, we should be 2226262a71b7f95ce98ff3dd8dba845afbd724470903reed // able to remove this constraint. 2227262a71b7f95ce98ff3dd8dba845afbd724470903reed // skbug.com/4526 2228262a71b7f95ce98ff3dd8dba845afbd724470903reed // 2229262a71b7f95ce98ff3dd8dba845afbd724470903reed SkPoint pt; 2230262a71b7f95ce98ff3dd8dba845afbd724470903reed ctm.mapXY(x, y, &pt); 2231262a71b7f95ce98ff3dd8dba845afbd724470903reed SkIRect ir = SkIRect::MakeXYWH(SkScalarRoundToInt(pt.x()), SkScalarRoundToInt(pt.y()), w, h); 2232262a71b7f95ce98ff3dd8dba845afbd724470903reed return ir.contains(fMCRec->fRasterClip.getBounds()); 2233262a71b7f95ce98ff3dd8dba845afbd724470903reed} 2234262a71b7f95ce98ff3dd8dba845afbd724470903reed 2235a85d4d0814818e4ddabb9237da209d61d6cd5854reedvoid SkCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, const SkPaint* paint) { 22369881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImage()"); 2237a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkRect bounds = SkRect::MakeXYWH(x, y, 2238a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkIntToScalar(image->width()), SkIntToScalar(image->height())); 223996fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 224087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect tmp = bounds; 224187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (paint) { 224287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco paint->computeFastBounds(tmp, &tmp); 224387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 224487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(tmp)) { 224587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 224687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 2247a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2248a85d4d0814818e4ddabb9237da209d61d6cd5854reed 2249a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkLazyPaint lazy; 225096fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 2251a85d4d0814818e4ddabb9237da209d61d6cd5854reed paint = lazy.init(); 2252a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2253262a71b7f95ce98ff3dd8dba845afbd724470903reed 2254262a71b7f95ce98ff3dd8dba845afbd724470903reed const bool drawAsSprite = this->canDrawBitmapAsSprite(x, y, image->width(), image->height(), 2255262a71b7f95ce98ff3dd8dba845afbd724470903reed *paint); 2256262a71b7f95ce98ff3dd8dba845afbd724470903reed LOOPER_BEGIN_DRAWBITMAP(*paint, drawAsSprite, &bounds) 2257262a71b7f95ce98ff3dd8dba845afbd724470903reed 2258a85d4d0814818e4ddabb9237da209d61d6cd5854reed while (iter.next()) { 2259262a71b7f95ce98ff3dd8dba845afbd724470903reed const SkPaint& pnt = looper.paint(); 2260262a71b7f95ce98ff3dd8dba845afbd724470903reed if (drawAsSprite && pnt.getImageFilter()) { 2261262a71b7f95ce98ff3dd8dba845afbd724470903reed SkBitmap bitmap; 2262262a71b7f95ce98ff3dd8dba845afbd724470903reed if (as_IB(image)->asBitmapForImageFilters(&bitmap)) { 2263262a71b7f95ce98ff3dd8dba845afbd724470903reed SkPoint pt; 2264262a71b7f95ce98ff3dd8dba845afbd724470903reed iter.fMatrix->mapXY(x, y, &pt); 2265262a71b7f95ce98ff3dd8dba845afbd724470903reed iter.fDevice->drawBitmapAsSprite(iter, bitmap, 2266262a71b7f95ce98ff3dd8dba845afbd724470903reed SkScalarRoundToInt(pt.fX), 2267262a71b7f95ce98ff3dd8dba845afbd724470903reed SkScalarRoundToInt(pt.fY), pnt); 2268262a71b7f95ce98ff3dd8dba845afbd724470903reed } 2269262a71b7f95ce98ff3dd8dba845afbd724470903reed } else { 2270262a71b7f95ce98ff3dd8dba845afbd724470903reed iter.fDevice->drawImage(iter, image, x, y, pnt); 2271262a71b7f95ce98ff3dd8dba845afbd724470903reed } 2272a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2273a85d4d0814818e4ddabb9237da209d61d6cd5854reed 2274a85d4d0814818e4ddabb9237da209d61d6cd5854reed LOOPER_END 2275b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr} 2276b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 227741af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, 2278562fe4767cc73e08a4e039362bc0336aea66ecfbreed const SkPaint* paint, SrcRectConstraint constraint) { 22799881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImageRect()"); 228096fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 2281c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco SkRect storage = dst; 228287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (paint) { 228387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco paint->computeFastBounds(dst, &storage); 228487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 228587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(storage)) { 228687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 228787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 2288a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2289a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkLazyPaint lazy; 229096fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 2291a85d4d0814818e4ddabb9237da209d61d6cd5854reed paint = lazy.init(); 2292a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2293a85d4d0814818e4ddabb9237da209d61d6cd5854reed 2294c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, SkDrawFilter::kBitmap_Type, &dst, 2295c83a29759a5c2966da5ab973e4fd90763e4c962breed image->isOpaque()) 2296a85d4d0814818e4ddabb9237da209d61d6cd5854reed 2297a85d4d0814818e4ddabb9237da209d61d6cd5854reed while (iter.next()) { 2298a5517e2b190a8083b38964972b031c13e99f1012reed iter.fDevice->drawImageRect(iter, image, src, dst, looper.paint(), constraint); 2299a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2300a85d4d0814818e4ddabb9237da209d61d6cd5854reed 2301a85d4d0814818e4ddabb9237da209d61d6cd5854reed LOOPER_END 2302b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr} 2303b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 230441af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y, const SkPaint* paint) { 23059881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmap()"); 23068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(bitmap.validate();) 23078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 230833366974d43eae80e22284a2e445225c343859dareed if (bitmap.drawsNothing()) { 230933366974d43eae80e22284a2e445225c343859dareed return; 231033366974d43eae80e22284a2e445225c343859dareed } 231133366974d43eae80e22284a2e445225c343859dareed 231233366974d43eae80e22284a2e445225c343859dareed SkLazyPaint lazy; 231333366974d43eae80e22284a2e445225c343859dareed if (nullptr == paint) { 231433366974d43eae80e22284a2e445225c343859dareed paint = lazy.init(); 231533366974d43eae80e22284a2e445225c343859dareed } 231633366974d43eae80e22284a2e445225c343859dareed 231733366974d43eae80e22284a2e445225c343859dareed const SkMatrix matrix = SkMatrix::MakeTrans(x, y); 231833366974d43eae80e22284a2e445225c343859dareed 231933366974d43eae80e22284a2e445225c343859dareed SkRect storage; 232033366974d43eae80e22284a2e445225c343859dareed const SkRect* bounds = nullptr; 232133366974d43eae80e22284a2e445225c343859dareed if (paint->canComputeFastBounds()) { 232233366974d43eae80e22284a2e445225c343859dareed bitmap.getBounds(&storage); 232333366974d43eae80e22284a2e445225c343859dareed matrix.mapRect(&storage); 232487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect tmp = storage; 232587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint->computeFastBounds(tmp, &tmp))) { 232687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 232787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 232887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &storage; 23298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23304b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2331262a71b7f95ce98ff3dd8dba845afbd724470903reed const bool drawAsSprite = bounds && this->canDrawBitmapAsSprite(x, y, bitmap.width(), 2332262a71b7f95ce98ff3dd8dba845afbd724470903reed bitmap.height(), *paint); 2333262a71b7f95ce98ff3dd8dba845afbd724470903reed LOOPER_BEGIN_DRAWBITMAP(*paint, drawAsSprite, bounds) 233433366974d43eae80e22284a2e445225c343859dareed 233533366974d43eae80e22284a2e445225c343859dareed while (iter.next()) { 2336262a71b7f95ce98ff3dd8dba845afbd724470903reed const SkPaint& pnt = looper.paint(); 2337262a71b7f95ce98ff3dd8dba845afbd724470903reed if (drawAsSprite && pnt.getImageFilter()) { 2338262a71b7f95ce98ff3dd8dba845afbd724470903reed SkPoint pt; 2339262a71b7f95ce98ff3dd8dba845afbd724470903reed iter.fMatrix->mapXY(x, y, &pt); 2340262a71b7f95ce98ff3dd8dba845afbd724470903reed iter.fDevice->drawBitmapAsSprite(iter, bitmap, 2341262a71b7f95ce98ff3dd8dba845afbd724470903reed SkScalarRoundToInt(pt.fX), 2342262a71b7f95ce98ff3dd8dba845afbd724470903reed SkScalarRoundToInt(pt.fY), pnt); 2343262a71b7f95ce98ff3dd8dba845afbd724470903reed } else { 2344262a71b7f95ce98ff3dd8dba845afbd724470903reed iter.fDevice->drawBitmap(iter, bitmap, matrix, looper.paint()); 2345262a71b7f95ce98ff3dd8dba845afbd724470903reed } 234633366974d43eae80e22284a2e445225c343859dareed } 2347262a71b7f95ce98ff3dd8dba845afbd724470903reed 234833366974d43eae80e22284a2e445225c343859dareed LOOPER_END 23498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23519987ec3791336bad6af5cbe513564786b2df55aareed@google.com// this one is non-virtual, so it can be called safely by other canvas apis 23527112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.comvoid SkCanvas::internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, 2353eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org const SkRect& dst, const SkPaint* paint, 2354a5517e2b190a8083b38964972b031c13e99f1012reed SrcRectConstraint constraint) { 235550b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org if (bitmap.drawsNothing() || dst.isEmpty()) { 23568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 23578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 235874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 235996fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 2360c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco SkRect storage; 236187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 236287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 236387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 23648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23653d60812865bb034851da777a91413ab584929887reed@google.com 236633535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com SkLazyPaint lazy; 236796fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 236833535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com paint = lazy.init(); 23698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23707064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 2371c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, SkDrawFilter::kBitmap_Type, &dst, 2372c83a29759a5c2966da5ab973e4fd90763e4c962breed bitmap.isOpaque()) 23737064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 237433535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com while (iter.next()) { 2375562fe4767cc73e08a4e039362bc0336aea66ecfbreed iter.fDevice->drawBitmapRect(iter, bitmap, src, dst, looper.paint(), constraint); 2376f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 23777064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 237833535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com LOOPER_END 23798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 238141af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, 2382562fe4767cc73e08a4e039362bc0336aea66ecfbreed const SkPaint* paint, SrcRectConstraint constraint) { 23839881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmapRectToRect()"); 23849987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkDEBUGCODE(bitmap.validate();) 2385562fe4767cc73e08a4e039362bc0336aea66ecfbreed this->internalDrawBitmapRect(bitmap, src, dst, paint, constraint); 23869987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 23879987ec3791336bad6af5cbe513564786b2df55aareed@google.com 23884c21dc5ddf3b482293ed34eead876d8d61a662c3reedvoid SkCanvas::onDrawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst, 23894c21dc5ddf3b482293ed34eead876d8d61a662c3reed const SkPaint* paint) { 23904c21dc5ddf3b482293ed34eead876d8d61a662c3reed TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImageNine()"); 23914c21dc5ddf3b482293ed34eead876d8d61a662c3reed 239296fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 2393c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco SkRect storage; 239487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 239587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 239687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 23973d60812865bb034851da777a91413ab584929887reed@google.com } 23984c21dc5ddf3b482293ed34eead876d8d61a662c3reed 23994c21dc5ddf3b482293ed34eead876d8d61a662c3reed SkLazyPaint lazy; 240096fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 24014c21dc5ddf3b482293ed34eead876d8d61a662c3reed paint = lazy.init(); 24024c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 24034c21dc5ddf3b482293ed34eead876d8d61a662c3reed 2404c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst) 24054c21dc5ddf3b482293ed34eead876d8d61a662c3reed 24064c21dc5ddf3b482293ed34eead876d8d61a662c3reed while (iter.next()) { 24074c21dc5ddf3b482293ed34eead876d8d61a662c3reed iter.fDevice->drawImageNine(iter, image, center, dst, looper.paint()); 24089987ec3791336bad6af5cbe513564786b2df55aareed@google.com } 24094c21dc5ddf3b482293ed34eead876d8d61a662c3reed 24104c21dc5ddf3b482293ed34eead876d8d61a662c3reed LOOPER_END 24119987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 24129987ec3791336bad6af5cbe513564786b2df55aareed@google.com 241341af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst, 241441af966ab338e95eee81ab618ab28195075338f7reed const SkPaint* paint) { 24159881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmapNine()"); 24169987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkDEBUGCODE(bitmap.validate();) 24179987ec3791336bad6af5cbe513564786b2df55aareed@google.com 241896fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 2419c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco SkRect storage; 242087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 242187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 242287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 24234c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 24244c21dc5ddf3b482293ed34eead876d8d61a662c3reed 24254c21dc5ddf3b482293ed34eead876d8d61a662c3reed SkLazyPaint lazy; 242696fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 24274c21dc5ddf3b482293ed34eead876d8d61a662c3reed paint = lazy.init(); 24284c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 24294c21dc5ddf3b482293ed34eead876d8d61a662c3reed 2430c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst) 24314c21dc5ddf3b482293ed34eead876d8d61a662c3reed 24324c21dc5ddf3b482293ed34eead876d8d61a662c3reed while (iter.next()) { 24334c21dc5ddf3b482293ed34eead876d8d61a662c3reed iter.fDevice->drawBitmapNine(iter, bitmap, center, dst, looper.paint()); 24344c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 24354c21dc5ddf3b482293ed34eead876d8d61a662c3reed 24364c21dc5ddf3b482293ed34eead876d8d61a662c3reed LOOPER_END 24379987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 24389987ec3791336bad6af5cbe513564786b2df55aareed@google.com 2439f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.comclass SkDeviceFilteredPaint { 2440f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.compublic: 24411f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkDeviceFilteredPaint(SkBaseDevice* device, const SkPaint& paint) { 2442112e7e277702e104357f2d44742253ee1b0109acfmalita uint32_t filteredFlags = device->filterTextFlags(paint); 2443112e7e277702e104357f2d44742253ee1b0109acfmalita if (filteredFlags != paint.getFlags()) { 2444a076e9be17654a60310e72c4f70fcd5337f56dbfreed@google.com SkPaint* newPaint = fLazy.set(paint); 2445112e7e277702e104357f2d44742253ee1b0109acfmalita newPaint->setFlags(filteredFlags); 2446f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com fPaint = newPaint; 2447f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } else { 2448f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com fPaint = &paint; 2449f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } 2450f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } 2451f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 2452f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com const SkPaint& paint() const { return *fPaint; } 2453f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 2454f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.comprivate: 24552c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint* fPaint; 24562c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkLazyPaint fLazy; 2457f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com}; 2458f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 245952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.comvoid SkCanvas::DrawRect(const SkDraw& draw, const SkPaint& paint, 246052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com const SkRect& r, SkScalar textSize) { 246117b78946096265d80215a6c946286ecaa35ea7edepoger@google.com if (paint.getStyle() == SkPaint::kFill_Style) { 246252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com draw.fDevice->drawRect(draw, r, paint); 246352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } else { 246452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPaint p(paint); 246517b78946096265d80215a6c946286ecaa35ea7edepoger@google.com p.setStrokeWidth(SkScalarMul(textSize, paint.getStrokeWidth())); 246652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com draw.fDevice->drawRect(draw, r, p); 246752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 246852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com} 246952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 247052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.comvoid SkCanvas::DrawTextDecorations(const SkDraw& draw, const SkPaint& paint, 247152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com const char text[], size_t byteLength, 247252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar x, SkScalar y) { 247396fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkASSERT(byteLength == 0 || text != nullptr); 247452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 247552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com // nothing to draw 247696fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (text == nullptr || byteLength == 0 || 247752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com draw.fClip->isEmpty() || 247896fcdcc219d2a0d3579719b84b28bede76efba64halcanary (paint.getAlpha() == 0 && paint.getXfermode() == nullptr)) { 247952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com return; 248052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 248152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 248252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar width = 0; 248352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPoint start; 248452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 248552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.set(0, 0); // to avoid warning 248652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (paint.getFlags() & (SkPaint::kUnderlineText_Flag | 248752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPaint::kStrikeThruText_Flag)) { 248852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com width = paint.measureText(text, byteLength); 248952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 249052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar offsetX = 0; 249152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (paint.getTextAlign() == SkPaint::kCenter_Align) { 249252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com offsetX = SkScalarHalf(width); 249352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } else if (paint.getTextAlign() == SkPaint::kRight_Align) { 249452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com offsetX = width; 249552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 249652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.set(x - offsetX, y); 249752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 249852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 249952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (0 == width) { 250052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com return; 250152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 250252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 250352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com uint32_t flags = paint.getFlags(); 250452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 250552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (flags & (SkPaint::kUnderlineText_Flag | 250652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPaint::kStrikeThruText_Flag)) { 250752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar textSize = paint.getTextSize(); 250852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar height = SkScalarMul(textSize, kStdUnderline_Thickness); 250952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkRect r; 251052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 251152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fLeft = start.fX; 251252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fRight = start.fX + width; 251352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 251452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (flags & SkPaint::kUnderlineText_Flag) { 251552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar offset = SkScalarMulAdd(textSize, kStdUnderline_Offset, 251652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.fY); 251752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fTop = offset; 251852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fBottom = offset + height; 2519fb56218292d6c7b509d382f39994c3783b2483a0caryclark DrawRect(draw, paint, r, 1); 252052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 252152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (flags & SkPaint::kStrikeThruText_Flag) { 252252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar offset = SkScalarMulAdd(textSize, kStdStrikeThru_Offset, 252352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.fY); 252452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fTop = offset; 252552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fBottom = offset + height; 2526fb56218292d6c7b509d382f39994c3783b2483a0caryclark DrawRect(draw, paint, r, 1); 252752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 252852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 252952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com} 253052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 2531e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 2532e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 253396fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 25348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 25364e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 2537f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com iter.fDevice->drawText(iter, text, byteLength, x, y, dfp.paint()); 253852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com DrawTextDecorations(iter, dfp.paint(), 253952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com static_cast<const char*>(text), byteLength, x, y); 25408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 25418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25424e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 25438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 25448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2545e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], 2546e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 254705c4a4322e7d4f3417b7df33825bab8603d52051fmalita SkPoint textOffset = SkPoint::Make(0, 0); 254805c4a4322e7d4f3417b7df33825bab8603d52051fmalita 254996fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 255087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 25518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 25524e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 255305c4a4322e7d4f3417b7df33825bab8603d52051fmalita iter.fDevice->drawPosText(iter, text, byteLength, &pos->fX, 2, textOffset, 2554f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com dfp.paint()); 25558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2556b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 25574e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 25588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 25598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2560e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], 2561e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com SkScalar constY, const SkPaint& paint) { 256205c4a4322e7d4f3417b7df33825bab8603d52051fmalita 256305c4a4322e7d4f3417b7df33825bab8603d52051fmalita SkPoint textOffset = SkPoint::Make(0, constY); 256405c4a4322e7d4f3417b7df33825bab8603d52051fmalita 256596fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 256687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 25678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 25684e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 256905c4a4322e7d4f3417b7df33825bab8603d52051fmalita iter.fDevice->drawPosText(iter, text, byteLength, xpos, 1, textOffset, 2570f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com dfp.paint()); 25718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2572b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 25734e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 25748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 25758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2576e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 2577e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkMatrix* matrix, const SkPaint& paint) { 257896fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 257987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 25808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 25818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawTextOnPath(iter, text, byteLength, path, 25824e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com matrix, looper.paint()); 25838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2584b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 2585945ec3a2bec668ca845071a65df8ec55e8f43819commit-bot@chromium.org LOOPER_END 25864325d114a5679e46f25ae75b0e43547fd7694998commit-bot@chromium.org} 25874325d114a5679e46f25ae75b0e43547fd7694998commit-bot@chromium.org 258800d5c2c6523321d25b32905ff4822f083a4173eefmalitavoid SkCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 258900d5c2c6523321d25b32905ff4822f083a4173eefmalita const SkPaint& paint) { 25907ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita 259185d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita SkRect storage; 259296fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 259319653d1d004610b4ba07ce563a5701164e120e45fmalita if (paint.canComputeFastBounds()) { 259485d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita storage = blob->bounds().makeOffset(x, y); 259587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect tmp; 259687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(storage, &tmp))) { 259787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 259887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 259987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &storage; 26007ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita } 26017ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita 2602024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita // We cannot filter in the looper as we normally do, because the paint is 2603024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita // incomplete at this point (text-related attributes are embedded within blob run paints). 2604024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita SkDrawFilter* drawFilter = fMCRec->fFilter; 260596fcdcc219d2a0d3579719b84b28bede76efba64halcanary fMCRec->fFilter = nullptr; 2606024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita 260785d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, bounds) 260800d5c2c6523321d25b32905ff4822f083a4173eefmalita 2609aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita while (iter.next()) { 2610aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 2611024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita iter.fDevice->drawTextBlob(iter, blob, x, y, dfp.paint(), drawFilter); 261200d5c2c6523321d25b32905ff4822f083a4173eefmalita } 261300d5c2c6523321d25b32905ff4822f083a4173eefmalita 2614aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita LOOPER_END 2615024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita 2616024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita fMCRec->fFilter = drawFilter; 261700d5c2c6523321d25b32905ff4822f083a4173eefmalita} 261800d5c2c6523321d25b32905ff4822f083a4173eefmalita 2619e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com// These will become non-virtual, so they always call the (virtual) onDraw... method 2620e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 2621e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 26229881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawText()"); 2623e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawText(text, byteLength, x, y, paint); 2624e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2625e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawPosText(const void* text, size_t byteLength, const SkPoint pos[], 2626e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 26279881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPosText()"); 2628e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawPosText(text, byteLength, pos, paint); 2629e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2630e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], 2631e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com SkScalar constY, const SkPaint& paint) { 26329881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPosTextH()"); 2633e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawPosTextH(text, byteLength, xpos, constY, paint); 2634e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2635e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 2636e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkMatrix* matrix, const SkPaint& paint) { 26379881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextOnPath()"); 2638e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawTextOnPath(text, byteLength, path, matrix, paint); 2639e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 264000d5c2c6523321d25b32905ff4822f083a4173eefmalitavoid SkCanvas::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 264100d5c2c6523321d25b32905ff4822f083a4173eefmalita const SkPaint& paint) { 2642e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(blob); 26439881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextBlob()"); 2644e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawTextBlob(blob, x, y, paint); 264500d5c2c6523321d25b32905ff4822f083a4173eefmalita} 2646e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com 264741af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawVertices(VertexMode vmode, int vertexCount, 264841af966ab338e95eee81ab618ab28195075338f7reed const SkPoint verts[], const SkPoint texs[], 264941af966ab338e95eee81ab618ab28195075338f7reed const SkColor colors[], SkXfermode* xmode, 265041af966ab338e95eee81ab618ab28195075338f7reed const uint16_t indices[], int indexCount, 265141af966ab338e95eee81ab618ab28195075338f7reed const SkPaint& paint) { 26529881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawVertices()"); 265396fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, nullptr) 26544b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 26558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 26568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawVertices(iter, vmode, vertexCount, verts, texs, 26574e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com colors, xmode, indices, indexCount, 26584e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com looper.paint()); 26598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 26604b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 26614e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 26628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 26638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2664b3c9d1c33caf325aada244204215eb790c228c12dandovvoid SkCanvas::drawPatch(const SkPoint cubics[12], const SkColor colors[4], 2665b3c9d1c33caf325aada244204215eb790c228c12dandov const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint) { 26669881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPatch()"); 266796fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == cubics) { 2668b3c9d1c33caf325aada244204215eb790c228c12dandov return; 2669b3c9d1c33caf325aada244204215eb790c228c12dandov } 26706cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2671ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov // Since a patch is always within the convex hull of the control points, we discard it when its 2672ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov // bounding rectangle is completely outside the current clip. 2673ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov SkRect bounds; 2674b3c9d1c33caf325aada244204215eb790c228c12dandov bounds.set(cubics, SkPatchUtils::kNumCtrlPts); 2675ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov if (this->quickReject(bounds)) { 2676ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov return; 2677ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov } 26786cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2679b3c9d1c33caf325aada244204215eb790c228c12dandov this->onDrawPatch(cubics, colors, texCoords, xmode, paint); 2680b3c9d1c33caf325aada244204215eb790c228c12dandov} 2681b3c9d1c33caf325aada244204215eb790c228c12dandov 2682b3c9d1c33caf325aada244204215eb790c228c12dandovvoid SkCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], 2683b3c9d1c33caf325aada244204215eb790c228c12dandov const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint) { 2684b3c9d1c33caf325aada244204215eb790c228c12dandov 268596fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, nullptr) 26866cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2687ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov while (iter.next()) { 2688b3c9d1c33caf325aada244204215eb790c228c12dandov iter.fDevice->drawPatch(iter, cubics, colors, texCoords, xmode, paint); 2689ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov } 26906cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2691ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov LOOPER_END 2692ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov} 2693ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov 2694a8db72864a43ad1fbba3c2892cf5cd88060a43efreedvoid SkCanvas::drawDrawable(SkDrawable* dr, SkScalar x, SkScalar y) { 2695e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(dr); 2696e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed if (x || y) { 2697e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed SkMatrix matrix = SkMatrix::MakeTrans(x, y); 2698e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawDrawable(dr, &matrix); 2699e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed } else { 2700e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawDrawable(dr, nullptr); 2701a8db72864a43ad1fbba3c2892cf5cd88060a43efreed } 2702a8db72864a43ad1fbba3c2892cf5cd88060a43efreed} 2703a8db72864a43ad1fbba3c2892cf5cd88060a43efreed 2704a8db72864a43ad1fbba3c2892cf5cd88060a43efreedvoid SkCanvas::drawDrawable(SkDrawable* dr, const SkMatrix* matrix) { 2705e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(dr); 2706e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed if (matrix && matrix->isIdentity()) { 2707e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed matrix = nullptr; 27086a070dc06af4e9f305f9d08a69e34d18ade473cbreed } 2709e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawDrawable(dr, matrix); 27106a070dc06af4e9f305f9d08a69e34d18ade473cbreed} 27116a070dc06af4e9f305f9d08a69e34d18ade473cbreed 2712a8db72864a43ad1fbba3c2892cf5cd88060a43efreedvoid SkCanvas::onDrawDrawable(SkDrawable* dr, const SkMatrix* matrix) { 2713a8db72864a43ad1fbba3c2892cf5cd88060a43efreed SkRect bounds = dr->getBounds(); 2714a8db72864a43ad1fbba3c2892cf5cd88060a43efreed if (matrix) { 2715a8db72864a43ad1fbba3c2892cf5cd88060a43efreed matrix->mapRect(&bounds); 2716a8db72864a43ad1fbba3c2892cf5cd88060a43efreed } 2717a8db72864a43ad1fbba3c2892cf5cd88060a43efreed if (this->quickReject(bounds)) { 2718a8db72864a43ad1fbba3c2892cf5cd88060a43efreed return; 2719a8db72864a43ad1fbba3c2892cf5cd88060a43efreed } 2720a8db72864a43ad1fbba3c2892cf5cd88060a43efreed dr->draw(this, matrix); 27216a070dc06af4e9f305f9d08a69e34d18ade473cbreed} 27226a070dc06af4e9f305f9d08a69e34d18ade473cbreed 272371c3c760a83123ee0b3127b8c65c6394ce541c50reedvoid SkCanvas::onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], 272471c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkColor colors[], int count, SkXfermode::Mode mode, 272571c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkRect* cull, const SkPaint* paint) { 272671c3c760a83123ee0b3127b8c65c6394ce541c50reed if (cull && this->quickReject(*cull)) { 272771c3c760a83123ee0b3127b8c65c6394ce541c50reed return; 272871c3c760a83123ee0b3127b8c65c6394ce541c50reed } 272971c3c760a83123ee0b3127b8c65c6394ce541c50reed 273071c3c760a83123ee0b3127b8c65c6394ce541c50reed SkPaint pnt; 273171c3c760a83123ee0b3127b8c65c6394ce541c50reed if (paint) { 273271c3c760a83123ee0b3127b8c65c6394ce541c50reed pnt = *paint; 273371c3c760a83123ee0b3127b8c65c6394ce541c50reed } 273471c3c760a83123ee0b3127b8c65c6394ce541c50reed 273596fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(pnt, SkDrawFilter::kPath_Type, nullptr) 273671c3c760a83123ee0b3127b8c65c6394ce541c50reed while (iter.next()) { 273771c3c760a83123ee0b3127b8c65c6394ce541c50reed iter.fDevice->drawAtlas(iter, atlas, xform, tex, colors, count, mode, pnt); 273871c3c760a83123ee0b3127b8c65c6394ce541c50reed } 273971c3c760a83123ee0b3127b8c65c6394ce541c50reed LOOPER_END 274071c3c760a83123ee0b3127b8c65c6394ce541c50reed} 274171c3c760a83123ee0b3127b8c65c6394ce541c50reed 27428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 27438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// These methods are NOT virtual, and therefore must call back into virtual 27448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// methods, rather than actually drawing themselves. 27458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 27468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b, 2748845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com SkXfermode::Mode mode) { 27499881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawARGB()"); 27508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 27518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setARGB(a, r, g, b); 2753845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com if (SkXfermode::kSrcOver_Mode != mode) { 27540baf19375466cfc24c96532df406e7c5b1d1aae8reed@android.com paint.setXfermodeMode(mode); 27558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 27568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPaint(paint); 27578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2759845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.comvoid SkCanvas::drawColor(SkColor c, SkXfermode::Mode mode) { 27609881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawColor()"); 27618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 27628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setColor(c); 2764845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com if (SkXfermode::kSrcOver_Mode != mode) { 27650baf19375466cfc24c96532df406e7c5b1d1aae8reed@android.com paint.setXfermodeMode(mode); 27668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 27678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPaint(paint); 27688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPoint(SkScalar x, SkScalar y, const SkPaint& paint) { 27719881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPoint(SkPaint)"); 27728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pt; 27734b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 27748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pt.set(x, y); 27758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kPoints_PointMode, 1, &pt, paint); 27768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPoint(SkScalar x, SkScalar y, SkColor color) { 27799881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPoint(SkColor)"); 27808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pt; 27818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 27824b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 27838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pt.set(x, y); 27848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setColor(color); 27858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kPoints_PointMode, 1, &pt, paint); 27868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, 27898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 27909881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawLine()"); 27918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pts[2]; 27924b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 27938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pts[0].set(x0, y0); 27948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pts[1].set(x1, y1); 27958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kLines_PointMode, 2, pts, paint); 27968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawRectCoords(SkScalar left, SkScalar top, 27998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar right, SkScalar bottom, 28008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 28019881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRectCoords()"); 28028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 28038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.set(left, top, right, bottom); 28058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawRect(r, paint); 28068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, 28098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 28109881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawCircle()"); 28118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (radius < 0) { 28128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com radius = 0; 28138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 28148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 28168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.set(cx - radius, cy - radius, cx + radius, cy + radius); 28174ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->drawOval(r, paint); 28188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawRoundRect(const SkRect& r, SkScalar rx, SkScalar ry, 28218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 28229881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRoundRect()"); 28238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (rx > 0 && ry > 0) { 28248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.canComputeFastBounds()) { 28258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect storage; 28263b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(paint.computeFastBounds(r, &storage))) { 28278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 28288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 28298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 28304ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com SkRRect rrect; 28314ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com rrect.setRectXY(r, rx, ry); 28324ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->drawRRect(rrect, paint); 28338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 28348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawRect(r, paint); 28358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 28368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawArc(const SkRect& oval, SkScalar startAngle, 28398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar sweepAngle, bool useCenter, 28408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 28419881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawArc()"); 28428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (SkScalarAbs(sweepAngle) >= SkIntToScalar(360)) { 28438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawOval(oval, paint); 28448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 28458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath path; 28468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (useCenter) { 28478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.moveTo(oval.centerX(), oval.centerY()); 28488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 28498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.arcTo(oval, startAngle, sweepAngle, !useCenter); 28508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (useCenter) { 28518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.close(); 28528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 28538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPath(path, paint); 28548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 28558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawTextOnPathHV(const void* text, size_t byteLength, 28588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPath& path, SkScalar hOffset, 28598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar vOffset, const SkPaint& paint) { 28609881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextOnPathHV()"); 28618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 28624b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 28638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.setTranslate(hOffset, vOffset); 28648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawTextOnPath(text, byteLength, path, &matrix, paint); 28658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2867f76bacff7f66724072c67edb185abf9e3add11a0reed@android.com/////////////////////////////////////////////////////////////////////////////// 28681c2c441fede0ae9573afc098017011e3439624a9reed 28691c2c441fede0ae9573afc098017011e3439624a9reed/** 28701c2c441fede0ae9573afc098017011e3439624a9reed * This constant is trying to balance the speed of ref'ing a subpicture into a parent picture, 28711c2c441fede0ae9573afc098017011e3439624a9reed * against the playback cost of recursing into the subpicture to get at its actual ops. 28721c2c441fede0ae9573afc098017011e3439624a9reed * 28731c2c441fede0ae9573afc098017011e3439624a9reed * For now we pick a conservatively small value, though measurement (and other heuristics like 28741c2c441fede0ae9573afc098017011e3439624a9reed * the type of ops contained) may justify changing this value. 28751c2c441fede0ae9573afc098017011e3439624a9reed */ 28761c2c441fede0ae9573afc098017011e3439624a9reed#define kMaxPictureOpsToUnrollInsteadOfRef 1 28779b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips 2878d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedvoid SkCanvas::drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint) { 2879e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(picture); 2880e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed 28811c2c441fede0ae9573afc098017011e3439624a9reed TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPicture()"); 2882e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed if (matrix && matrix->isIdentity()) { 2883e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed matrix = nullptr; 2884e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed } 2885e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed if (picture->approximateOpCount() <= kMaxPictureOpsToUnrollInsteadOfRef) { 2886e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); 2887e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed picture->playback(this); 2888e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed } else { 2889e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawPicture(picture, matrix, paint); 2890d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 2891d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 28929b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips 2893d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedvoid SkCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix, 2894d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed const SkPaint* paint) { 2895d028180f0310cf2b23f9744256a41697b0683e67fmalita if (!paint || paint->canComputeFastBounds()) { 2896d028180f0310cf2b23f9744256a41697b0683e67fmalita SkRect bounds = picture->cullRect(); 2897d028180f0310cf2b23f9744256a41697b0683e67fmalita if (paint) { 2898d028180f0310cf2b23f9744256a41697b0683e67fmalita paint->computeFastBounds(bounds, &bounds); 2899d028180f0310cf2b23f9744256a41697b0683e67fmalita } 2900d028180f0310cf2b23f9744256a41697b0683e67fmalita if (matrix) { 2901d028180f0310cf2b23f9744256a41697b0683e67fmalita matrix->mapRect(&bounds); 2902d028180f0310cf2b23f9744256a41697b0683e67fmalita } 2903d028180f0310cf2b23f9744256a41697b0683e67fmalita if (this->quickReject(bounds)) { 2904d028180f0310cf2b23f9744256a41697b0683e67fmalita return; 2905d028180f0310cf2b23f9744256a41697b0683e67fmalita } 2906d028180f0310cf2b23f9744256a41697b0683e67fmalita } 2907d028180f0310cf2b23f9744256a41697b0683e67fmalita 2908145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org SkBaseDevice* device = this->getTopDevice(); 290949f085dddff10473b6ebf832a974288300224e60bsalomon if (device) { 2910145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org // Canvas has to first give the device the opportunity to render 2911145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org // the picture itself. 2912d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed if (device->EXPERIMENTAL_drawPicture(this, picture, matrix, paint)) { 2913145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org return; // the device has rendered the entire picture 2914145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org } 2915145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org } 2916145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org 2917a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); 2918c5ba71d2e5cd426def66fa49dcf003e5b2c98dc7robertphillips picture->playback(this); 29198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 29208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 29228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 29238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::LayerIter::LayerIter(SkCanvas* canvas, bool skipEmptyClips) { 292599fe82260633fcf5d92cca38d12ef0937ecca61cbungeman static_assert(sizeof(fStorage) >= sizeof(SkDrawIter), "fStorage_too_small"); 29268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(canvas); 29288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fImpl = new (fStorage) SkDrawIter(canvas, skipEmptyClips); 29308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDone = !fImpl->next(); 29318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 29328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::LayerIter::~LayerIter() { 29348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fImpl->~SkDrawIter(); 29358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 29368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::LayerIter::next() { 29388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDone = !fImpl->next(); 29398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 29408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29411f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::LayerIter::device() const { 29428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fImpl->getDevice(); 29438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 29448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkMatrix& SkCanvas::LayerIter::matrix() const { 29468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fImpl->getMatrix(); 29478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 29488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkPaint& SkCanvas::LayerIter::paint() const { 29508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* paint = fImpl->getPaint(); 295196fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 29528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint = &fDefaultPaint; 29538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 29548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return *paint; 29558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 29568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkRegion& SkCanvas::LayerIter::clip() const { return fImpl->getClip(); } 29588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::LayerIter::x() const { return fImpl->getX(); } 29598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::LayerIter::y() const { return fImpl->getY(); } 296020a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com 296120a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com/////////////////////////////////////////////////////////////////////////////// 296220a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com 2963c3b589a24eb4d567a906189f882c259ecf5c2f58fmalitaSkCanvasClipVisitor::~SkCanvasClipVisitor() { } 29643107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 29653107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 29663107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 29673107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.orgstatic bool supported_for_raster_canvas(const SkImageInfo& info) { 29683107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org switch (info.alphaType()) { 29693107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kPremul_SkAlphaType: 29703107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kOpaque_SkAlphaType: 29713107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org break; 29723107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org default: 29733107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return false; 29743107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 29753107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 29763107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org switch (info.colorType()) { 29773107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kAlpha_8_SkColorType: 29783107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kRGB_565_SkColorType: 297928fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org case kN32_SkColorType: 29803107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org break; 29813107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org default: 29823107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return false; 29833107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 29843107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 29853107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return true; 29863107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org} 29873107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 298842b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.orgSkCanvas* SkCanvas::NewRasterDirect(const SkImageInfo& info, void* pixels, size_t rowBytes) { 298942b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org if (!supported_for_raster_canvas(info)) { 299096fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 299142b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org } 2992eb849e5fd10cbe00cbc31307ba97fd9efca0b41bskia.committer@gmail.com 299342b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org SkBitmap bitmap; 299442b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org if (!bitmap.installPixels(info, pixels, rowBytes)) { 299596fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 299642b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org } 2997385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return new SkCanvas(bitmap); 299842b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org} 2999d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 3000d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed/////////////////////////////////////////////////////////////////////////////// 3001d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 3002d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedSkAutoCanvasMatrixPaint::SkAutoCanvasMatrixPaint(SkCanvas* canvas, const SkMatrix* matrix, 3003a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips const SkPaint* paint, const SkRect& bounds) 3004d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed : fCanvas(canvas) 3005d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed , fSaveCount(canvas->getSaveCount()) 3006d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed{ 300749f085dddff10473b6ebf832a974288300224e60bsalomon if (paint) { 3008a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkRect newBounds = bounds; 3009d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed if (matrix) { 3010a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips matrix->mapRect(&newBounds); 3011d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 3012a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips canvas->saveLayer(&newBounds, paint); 301349f085dddff10473b6ebf832a974288300224e60bsalomon } else if (matrix) { 3014d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed canvas->save(); 3015d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 30166cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 301749f085dddff10473b6ebf832a974288300224e60bsalomon if (matrix) { 3018d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed canvas->concat(*matrix); 3019d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 3020d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 3021d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 3022d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedSkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { 3023d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed fCanvas->restoreToCount(fSaveCount); 3024d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 3025