SkCanvas.cpp revision 42b73eb00367c8315974b1c374308d20efa78897
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" 2074bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org#include "SkMetaData.h" 214c21dc5ddf3b482293ed34eead876d8d61a662c3reed#include "SkNinePatchIter.h" 22c83a29759a5c2966da5ab973e4fd90763e4c962breed#include "SkPaintPriv.h" 23b3c9d1c33caf325aada244204215eb790c228c12dandov#include "SkPatchUtils.h" 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPicture.h" 250017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com#include "SkRasterClip.h" 2696472deea70169396b8e1f576e470138f55fdb1freed#include "SkReadPixelsRec.h" 274ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com#include "SkRRect.h" 2879fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org#include "SkSmallAllocator.h" 2997af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com#include "SkSurface_Base.h" 307ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita#include "SkTextBlob.h" 3152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com#include "SkTextFormatParams.h" 32a076e9be17654a60310e72c4f70fcd5337f56dbfreed@google.com#include "SkTLazy.h" 338f757f540a8378c7b1354aab3d4650eaa920b17adanakj#include "SkTraceEvent.h" 34d3ebb48320cf1b7e969974673e4bd7743816985ebungeman 35d3ebb48320cf1b7e969974673e4bd7743816985ebungeman#include <new> 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 37644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#if SK_SUPPORT_GPU 38644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#include "GrRenderTarget.h" 39644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#endif 40644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org 4187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco#define SK_SUPPORT_SRC_BOUNDS_BLOAT_FOR_IMAGEFILTERS 4287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco 43c83a29759a5c2966da5ab973e4fd90763e4c962breed/* 44c83a29759a5c2966da5ab973e4fd90763e4c962breed * Return true if the drawing this rect would hit every pixels in the canvas. 45c83a29759a5c2966da5ab973e4fd90763e4c962breed * 46c83a29759a5c2966da5ab973e4fd90763e4c962breed * Returns false if 47c83a29759a5c2966da5ab973e4fd90763e4c962breed * - rect does not contain the canvas' bounds 48c83a29759a5c2966da5ab973e4fd90763e4c962breed * - paint is not fill 49c83a29759a5c2966da5ab973e4fd90763e4c962breed * - paint would blur or otherwise change the coverage of the rect 50c83a29759a5c2966da5ab973e4fd90763e4c962breed */ 51c83a29759a5c2966da5ab973e4fd90763e4c962breedbool SkCanvas::wouldOverwriteEntireSurface(const SkRect* rect, const SkPaint* paint, 52c83a29759a5c2966da5ab973e4fd90763e4c962breed ShaderOverrideOpacity overrideOpacity) const { 5399fe82260633fcf5d92cca38d12ef0937ecca61cbungeman static_assert((int)SkPaintPriv::kNone_ShaderOverrideOpacity == 5499fe82260633fcf5d92cca38d12ef0937ecca61cbungeman (int)kNone_ShaderOverrideOpacity, 5599fe82260633fcf5d92cca38d12ef0937ecca61cbungeman "need_matching_enums0"); 5699fe82260633fcf5d92cca38d12ef0937ecca61cbungeman static_assert((int)SkPaintPriv::kOpaque_ShaderOverrideOpacity == 5799fe82260633fcf5d92cca38d12ef0937ecca61cbungeman (int)kOpaque_ShaderOverrideOpacity, 5899fe82260633fcf5d92cca38d12ef0937ecca61cbungeman "need_matching_enums1"); 5999fe82260633fcf5d92cca38d12ef0937ecca61cbungeman static_assert((int)SkPaintPriv::kNotOpaque_ShaderOverrideOpacity == 6099fe82260633fcf5d92cca38d12ef0937ecca61cbungeman (int)kNotOpaque_ShaderOverrideOpacity, 6199fe82260633fcf5d92cca38d12ef0937ecca61cbungeman "need_matching_enums2"); 62c83a29759a5c2966da5ab973e4fd90763e4c962breed 63c83a29759a5c2966da5ab973e4fd90763e4c962breed const SkISize size = this->getBaseLayerSize(); 64c83a29759a5c2966da5ab973e4fd90763e4c962breed const SkRect bounds = SkRect::MakeIWH(size.width(), size.height()); 65c83a29759a5c2966da5ab973e4fd90763e4c962breed if (!this->getClipStack()->quickContains(bounds)) { 66c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; 67c83a29759a5c2966da5ab973e4fd90763e4c962breed } 68c83a29759a5c2966da5ab973e4fd90763e4c962breed 69c83a29759a5c2966da5ab973e4fd90763e4c962breed if (rect) { 70c83a29759a5c2966da5ab973e4fd90763e4c962breed if (!this->getTotalMatrix().rectStaysRect()) { 71c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; // conservative 72c83a29759a5c2966da5ab973e4fd90763e4c962breed } 73c83a29759a5c2966da5ab973e4fd90763e4c962breed 74c83a29759a5c2966da5ab973e4fd90763e4c962breed SkRect devRect; 75c83a29759a5c2966da5ab973e4fd90763e4c962breed this->getTotalMatrix().mapRect(&devRect, *rect); 768c0144ccb17220db9d5140ef5ee85d5bc7837513fmalita if (!devRect.contains(bounds)) { 77c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; 78c83a29759a5c2966da5ab973e4fd90763e4c962breed } 79c83a29759a5c2966da5ab973e4fd90763e4c962breed } 80c83a29759a5c2966da5ab973e4fd90763e4c962breed 81c83a29759a5c2966da5ab973e4fd90763e4c962breed if (paint) { 82c83a29759a5c2966da5ab973e4fd90763e4c962breed SkPaint::Style paintStyle = paint->getStyle(); 83c83a29759a5c2966da5ab973e4fd90763e4c962breed if (!(paintStyle == SkPaint::kFill_Style || 84c83a29759a5c2966da5ab973e4fd90763e4c962breed paintStyle == SkPaint::kStrokeAndFill_Style)) { 85c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; 86c83a29759a5c2966da5ab973e4fd90763e4c962breed } 87c83a29759a5c2966da5ab973e4fd90763e4c962breed if (paint->getMaskFilter() || paint->getLooper() 88c83a29759a5c2966da5ab973e4fd90763e4c962breed || paint->getPathEffect() || paint->getImageFilter()) { 89c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; // conservative 90c83a29759a5c2966da5ab973e4fd90763e4c962breed } 91c83a29759a5c2966da5ab973e4fd90763e4c962breed } 92c83a29759a5c2966da5ab973e4fd90763e4c962breed return SkPaintPriv::Overwrites(paint, (SkPaintPriv::ShaderOverrideOpacity)overrideOpacity); 93c83a29759a5c2966da5ab973e4fd90763e4c962breed} 94c83a29759a5c2966da5ab973e4fd90763e4c962breed 95c83a29759a5c2966da5ab973e4fd90763e4c962breed/////////////////////////////////////////////////////////////////////////////////////////////////// 96c83a29759a5c2966da5ab973e4fd90763e4c962breed 97d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareedstatic bool gIgnoreSaveLayerBounds; 98d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareedvoid SkCanvas::Internal_Private_SetIgnoreSaveLayerBounds(bool ignore) { 99d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed gIgnoreSaveLayerBounds = ignore; 100d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed} 101d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareedbool SkCanvas::Internal_Private_GetIgnoreSaveLayerBounds() { 102d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed return gIgnoreSaveLayerBounds; 103d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed} 104d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed 1050acf1b4b3645772d220c720313821bac389751b5reedstatic bool gTreatSpriteAsBitmap; 1060acf1b4b3645772d220c720313821bac389751b5reedvoid SkCanvas::Internal_Private_SetTreatSpriteAsBitmap(bool spriteAsBitmap) { 1070acf1b4b3645772d220c720313821bac389751b5reed gTreatSpriteAsBitmap = spriteAsBitmap; 1080acf1b4b3645772d220c720313821bac389751b5reed} 1090acf1b4b3645772d220c720313821bac389751b5reedbool SkCanvas::Internal_Private_GetTreatSpriteAsBitmap() { 1100acf1b4b3645772d220c720313821bac389751b5reed return gTreatSpriteAsBitmap; 1110acf1b4b3645772d220c720313821bac389751b5reed} 1120acf1b4b3645772d220c720313821bac389751b5reed 113da17f758442f16747af39f8fbaed9c097048519creed@google.com// experimental for faster tiled drawing... 114da17f758442f16747af39f8fbaed9c097048519creed@google.com//#define SK_ENABLE_CLIP_QUICKREJECT 11515e9d3e66e161ce23df30bc13f8a0c87d196b463robertphillips@google.com 1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//#define SK_TRACE_SAVERESTORE 1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_TRACE_SAVERESTORE 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gLayerCounter; 1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_layer() { ++gLayerCounter; printf("----- inc layer %d\n", gLayerCounter); } 1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_layer() { --gLayerCounter; printf("----- dec layer %d\n", gLayerCounter); } 1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gRecCounter; 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_rec() { ++gRecCounter; printf("----- inc rec %d\n", gRecCounter); } 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_rec() { --gRecCounter; printf("----- dec rec %d\n", gRecCounter); } 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gCanvasCounter; 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_canvas() { ++gCanvasCounter; printf("----- inc canvas %d\n", gCanvasCounter); } 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_canvas() { --gCanvasCounter; printf("----- dec canvas %d\n", gCanvasCounter); } 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_layer() 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_layer() 1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_rec() 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_rec() 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_canvas() 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_canvas() 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1392c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.orgtypedef SkTLazy<SkPaint> SkLazyPaint; 1402c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org 141c83a29759a5c2966da5ab973e4fd90763e4c962breedvoid SkCanvas::predrawNotify(bool willOverwritesEntireSurface) { 14297af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com if (fSurfaceBase) { 143c83a29759a5c2966da5ab973e4fd90763e4c962breed fSurfaceBase->aboutToDraw(willOverwritesEntireSurface 144c83a29759a5c2966da5ab973e4fd90763e4c962breed ? SkSurface::kDiscard_ContentChangeMode 145c83a29759a5c2966da5ab973e4fd90763e4c962breed : SkSurface::kRetain_ContentChangeMode); 146c83a29759a5c2966da5ab973e4fd90763e4c962breed } 147c83a29759a5c2966da5ab973e4fd90763e4c962breed} 148c83a29759a5c2966da5ab973e4fd90763e4c962breed 149c83a29759a5c2966da5ab973e4fd90763e4c962breedvoid SkCanvas::predrawNotify(const SkRect* rect, const SkPaint* paint, 150c83a29759a5c2966da5ab973e4fd90763e4c962breed ShaderOverrideOpacity overrideOpacity) { 151c83a29759a5c2966da5ab973e4fd90763e4c962breed if (fSurfaceBase) { 152c83a29759a5c2966da5ab973e4fd90763e4c962breed SkSurface::ContentChangeMode mode = SkSurface::kRetain_ContentChangeMode; 153c83a29759a5c2966da5ab973e4fd90763e4c962breed // Since willOverwriteAllPixels() may not be complete free to call, we only do so if 154c83a29759a5c2966da5ab973e4fd90763e4c962breed // there is an outstanding snapshot, since w/o that, there will be no copy-on-write 155c83a29759a5c2966da5ab973e4fd90763e4c962breed // and therefore we don't care which mode we're in. 156c83a29759a5c2966da5ab973e4fd90763e4c962breed // 157c83a29759a5c2966da5ab973e4fd90763e4c962breed if (fSurfaceBase->outstandingImageSnapshot()) { 158c83a29759a5c2966da5ab973e4fd90763e4c962breed if (this->wouldOverwriteEntireSurface(rect, paint, overrideOpacity)) { 159c83a29759a5c2966da5ab973e4fd90763e4c962breed mode = SkSurface::kDiscard_ContentChangeMode; 160c83a29759a5c2966da5ab973e4fd90763e4c962breed } 161c83a29759a5c2966da5ab973e4fd90763e4c962breed } 162c83a29759a5c2966da5ab973e4fd90763e4c962breed fSurfaceBase->aboutToDraw(mode); 16397af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com } 16497af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com} 16597af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com 1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1684a8126e7f81384526629b1e21bf89b632ea13cd9reedstatic uint32_t filter_paint_flags(const SkSurfaceProps& props, uint32_t flags) { 1694a8126e7f81384526629b1e21bf89b632ea13cd9reed const uint32_t propFlags = props.flags(); 1704a8126e7f81384526629b1e21bf89b632ea13cd9reed if (propFlags & SkSurfaceProps::kDisallowDither_Flag) { 1714a8126e7f81384526629b1e21bf89b632ea13cd9reed flags &= ~SkPaint::kDither_Flag; 1724a8126e7f81384526629b1e21bf89b632ea13cd9reed } 1734a8126e7f81384526629b1e21bf89b632ea13cd9reed if (propFlags & SkSurfaceProps::kDisallowAntiAlias_Flag) { 1744a8126e7f81384526629b1e21bf89b632ea13cd9reed flags &= ~SkPaint::kAntiAlias_Flag; 1754a8126e7f81384526629b1e21bf89b632ea13cd9reed } 1764a8126e7f81384526629b1e21bf89b632ea13cd9reed return flags; 1774a8126e7f81384526629b1e21bf89b632ea13cd9reed} 1784a8126e7f81384526629b1e21bf89b632ea13cd9reed 1794a8126e7f81384526629b1e21bf89b632ea13cd9reed/////////////////////////////////////////////////////////////////////////////// 1804a8126e7f81384526629b1e21bf89b632ea13cd9reed 1811f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com/* This is the record we keep for each SkBaseDevice that the user installs. 1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com The clip/matrix/proc are fields that reflect the top of the save/restore 1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stack. Whenever the canvas changes, it marks a dirty flag, and then before 1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com these are used (assuming we're not on a layer) we rebuild these cache 1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com values: they reflect the top of the save stack, but translated and clipped 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com by the device's XY offset and bitmap-bounds. 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct DeviceCM { 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* fNext; 1901f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* fDevice; 191045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com SkRasterClip fClip; 1926f8f292aa768869a9e85c314b124875f57504f2creed@google.com SkPaint* fPaint; // may be null (in the future) 19361f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed const SkMatrix* fMatrix; 19461f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed SkMatrix fMatrixStorage; 19561f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed const bool fDeviceIsBitmapDevice; 1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19796e657d0e103b8358a77ecd913f6086929f792b8reed DeviceCM(SkBaseDevice* device, const SkPaint* paint, SkCanvas* canvas, 19886a17e7716c8db858e219a46b9db3817bb770beereed bool conservativeRasterClip, bool deviceIsBitmapDevice) 19996fcdcc219d2a0d3579719b84b28bede76efba64halcanary : fNext(nullptr) 200d954498c01ccf0417feacf89e45d0c62a06a813breed , fClip(conservativeRasterClip) 20161f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed , fDeviceIsBitmapDevice(deviceIsBitmapDevice) 202d954498c01ccf0417feacf89e45d0c62a06a813breed { 20396fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr != device) { 2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device->ref(); 20540a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com device->onAttachToCanvas(canvas); 2068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2074b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com fDevice = device; 20896fcdcc219d2a0d3579719b84b28bede76efba64halcanary fPaint = paint ? new SkPaint(*paint) : nullptr; 20988edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21188edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com ~DeviceCM() { 21249f085dddff10473b6ebf832a974288300224e60bsalomon if (fDevice) { 21340a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com fDevice->onDetachFromCanvas(); 2148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDevice->unref(); 2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 216385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete fPaint; 21788edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 2184b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 219feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein void reset(const SkIRect& bounds) { 220feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(!fPaint); 221feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(!fNext); 222feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(fDevice); 223feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fClip.setRect(bounds); 224feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein } 225feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 226045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com void updateMC(const SkMatrix& totalMatrix, const SkRasterClip& totalClip, 227045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com const SkClipStack& clipStack, SkRasterClip* updateClip) { 2286f8f292aa768869a9e85c314b124875f57504f2creed@google.com int x = fDevice->getOrigin().x(); 2296f8f292aa768869a9e85c314b124875f57504f2creed@google.com int y = fDevice->getOrigin().y(); 2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int width = fDevice->width(); 2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int height = fDevice->height(); 2324b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if ((x | y) == 0) { 2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = &totalMatrix; 2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fClip = totalClip; 2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrixStorage = totalMatrix; 2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrixStorage.postTranslate(SkIntToScalar(-x), 2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIntToScalar(-y)); 2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = &fMatrixStorage; 2414b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com totalClip.translate(-x, -y, &fClip); 2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 245045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com fClip.op(SkIRect::MakeWH(width, height), SkRegion::kIntersect_Op); 2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // intersect clip, but don't translate it (yet) 2484b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (updateClip) { 250045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com updateClip->op(SkIRect::MakeXYWH(x, y, width, height), 2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRegion::kDifference_Op); 2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2534b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2543fffb2ee9fa01ae61efb2395973eb7575eda4c96robertphillips@google.com fDevice->setMatrixClip(*fMatrix, fClip.forceGetBW(), clipStack); 2553fffb2ee9fa01ae61efb2395973eb7575eda4c96robertphillips@google.com 2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!fClip.isEmpty()) { 2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIRect deviceR; 2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com deviceR.set(0, 0, width, height); 2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(deviceR.contains(fClip.getBounds())); 2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 263f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* This is the record we keep for each save/restore level in the stack. 2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Since a level optionally copies the matrix and/or stack, we have pointers 2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for these fields. If the value is copied for this level, the copy is 2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stored in the ...Storage field, and the pointer points to that. If the 2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value is not copied for this level, we ignore ...Storage, and just point 2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com at the corresponding value in the previous level in the stack. 2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkCanvas::MCRec { 2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 2751f836ee096bb988adef4b9757b2629c7afeda36dreed SkDrawFilter* fFilter; // the current filter (or null) 276d954498c01ccf0417feacf89e45d0c62a06a813breed DeviceCM* fLayer; 2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* If there are any layers in the stack, this points to the top-most 2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com one that is at or below this level in the stack (so we know what 2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bitmap/device to draw into from this level. This value is NOT 2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com reference counted, since the real owner is either our fLayer field, 2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com or a previous one in a lower level.) 2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 2832ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed DeviceCM* fTopLayer; 2842ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkRasterClip fRasterClip; 2852ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkMatrix fMatrix; 2862ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed int fDeferredSaveCount; 2878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 288d954498c01ccf0417feacf89e45d0c62a06a813breed MCRec(bool conservativeRasterClip) : fRasterClip(conservativeRasterClip) { 28996fcdcc219d2a0d3579719b84b28bede76efba64halcanary fFilter = nullptr; 29096fcdcc219d2a0d3579719b84b28bede76efba64halcanary fLayer = nullptr; 29196fcdcc219d2a0d3579719b84b28bede76efba64halcanary fTopLayer = nullptr; 2922ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fMatrix.reset(); 2932ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fDeferredSaveCount = 0; 294b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 295d954498c01ccf0417feacf89e45d0c62a06a813breed // don't bother initializing fNext 296d954498c01ccf0417feacf89e45d0c62a06a813breed inc_rec(); 297d954498c01ccf0417feacf89e45d0c62a06a813breed } 2982ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed MCRec(const MCRec& prev) : fRasterClip(prev.fRasterClip), fMatrix(prev.fMatrix) { 299d954498c01ccf0417feacf89e45d0c62a06a813breed fFilter = SkSafeRef(prev.fFilter); 30096fcdcc219d2a0d3579719b84b28bede76efba64halcanary fLayer = nullptr; 301d954498c01ccf0417feacf89e45d0c62a06a813breed fTopLayer = prev.fTopLayer; 3022ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fDeferredSaveCount = 0; 303b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 3048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // don't bother initializing fNext 3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inc_rec(); 3068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ~MCRec() { 30882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fFilter); 309385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete fLayer; 3108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dec_rec(); 3118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 312feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 313feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein void reset(const SkIRect& bounds) { 314feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(fLayer); 315feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(fDeferredSaveCount == 0); 316feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 317feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fMatrix.reset(); 318feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fRasterClip.setRect(bounds); 319feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fLayer->reset(bounds); 320feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein } 3218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkDrawIter : public SkDraw { 3248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 3258a0b0291ae4260ef2a46f4341c18a702c0ce3f8btomhudson@google.com SkDrawIter(SkCanvas* canvas, bool skipEmptyClips = true) { 3264370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com canvas = canvas->canvasForDrawIter(); 3278a0b0291ae4260ef2a46f4341c18a702c0ce3f8btomhudson@google.com fCanvas = canvas; 3288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com canvas->updateDeviceCMCache(); 3298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 330687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack = canvas->fClipStack; 3318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = canvas->fMCRec->fTopLayer; 3328a0b0291ae4260ef2a46f4341c18a702c0ce3f8btomhudson@google.com fSkipEmptyClips = skipEmptyClips; 3338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3344b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 3358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool next() { 3368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // skip over recs with empty clips 3378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fSkipEmptyClips) { 3388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (fCurrLayer && fCurrLayer->fClip.isEmpty()) { 3398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = fCurrLayer->fNext; 3408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 343f68c5e2f9f05b3af2bae0979ace2684b6041b6e3reed@google.com const DeviceCM* rec = fCurrLayer; 344f68c5e2f9f05b3af2bae0979ace2684b6041b6e3reed@google.com if (rec && rec->fDevice) { 3458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = rec->fMatrix; 347045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com fClip = &((SkRasterClip*)&rec->fClip)->forceGetBW(); 348045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com fRC = &rec->fClip; 3498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDevice = rec->fDevice; 35041e010cb901c0da9066c4df562030808c9ccd7f8reed if (!fDevice->accessPixels(&fDst)) { 35196fcdcc219d2a0d3579719b84b28bede76efba64halcanary fDst.reset(fDevice->imageInfo(), nullptr, 0); 35241e010cb901c0da9066c4df562030808c9ccd7f8reed } 3538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint = rec->fPaint; 354f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com SkDEBUGCODE(this->validate();) 3558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = rec->fNext; 35796fcdcc219d2a0d3579719b84b28bede76efba64halcanary // fCurrLayer may be nullptr now 358199f108f14a5f60a9c2205ffa79b26102a206ad0reed@android.com 3598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 3608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 3628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3634b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 3641f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* getDevice() const { return fDevice; } 3656f8f292aa768869a9e85c314b124875f57504f2creed@google.com int getX() const { return fDevice->getOrigin().x(); } 3666f8f292aa768869a9e85c314b124875f57504f2creed@google.com int getY() const { return fDevice->getOrigin().y(); } 3678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& getMatrix() const { return *fMatrix; } 3688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkRegion& getClip() const { return *fClip; } 3698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* getPaint() const { return fPaint; } 3706f8f292aa768869a9e85c314b124875f57504f2creed@google.com 3718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 3728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkCanvas* fCanvas; 3738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const DeviceCM* fCurrLayer; 3748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* fPaint; // May be null. 3758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkBool8 fSkipEmptyClips; 3768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef SkDraw INHERITED; 3788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////// 3818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 382dbc3cefb0b624808ddb86d444e6103f216e12fa5reedstatic SkPaint* set_if_needed(SkLazyPaint* lazy, const SkPaint& orig) { 383dbc3cefb0b624808ddb86d444e6103f216e12fa5reed return lazy->isValid() ? lazy->get() : lazy->set(orig); 384dbc3cefb0b624808ddb86d444e6103f216e12fa5reed} 385dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 386dbc3cefb0b624808ddb86d444e6103f216e12fa5reed/** 387dbc3cefb0b624808ddb86d444e6103f216e12fa5reed * If the paint has an imagefilter, but it can be simplified to just a colorfilter, return that 38896fcdcc219d2a0d3579719b84b28bede76efba64halcanary * colorfilter, else return nullptr. 389dbc3cefb0b624808ddb86d444e6103f216e12fa5reed */ 390dbc3cefb0b624808ddb86d444e6103f216e12fa5reedstatic SkColorFilter* image_to_color_filter(const SkPaint& paint) { 391dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkImageFilter* imgf = paint.getImageFilter(); 392dbc3cefb0b624808ddb86d444e6103f216e12fa5reed if (!imgf) { 39396fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 394dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 395dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 396dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkColorFilter* imgCF; 397dbc3cefb0b624808ddb86d444e6103f216e12fa5reed if (!imgf->asAColorFilter(&imgCF)) { 39896fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 399dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 400dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 401dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkColorFilter* paintCF = paint.getColorFilter(); 40296fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paintCF) { 403dbc3cefb0b624808ddb86d444e6103f216e12fa5reed // there is no existing paint colorfilter, so we can just return the imagefilter's 404dbc3cefb0b624808ddb86d444e6103f216e12fa5reed return imgCF; 405dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 406dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 407dbc3cefb0b624808ddb86d444e6103f216e12fa5reed // The paint has both a colorfilter(paintCF) and an imagefilter-which-is-a-colorfilter(imgCF) 408dbc3cefb0b624808ddb86d444e6103f216e12fa5reed // and we need to combine them into a single colorfilter. 409dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkAutoTUnref<SkColorFilter> autoImgCF(imgCF); 410dbc3cefb0b624808ddb86d444e6103f216e12fa5reed return SkColorFilter::CreateComposeFilter(imgCF, paintCF); 411dbc3cefb0b624808ddb86d444e6103f216e12fa5reed} 412dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 41387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco/** 41487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * There are many bounds in skia. A circle's bounds is just its center extended by its radius. 41587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * However, if we stroke a circle, then the "bounds" of that is larger, since it will now draw 41687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * outside of its raw-bounds by 1/2 the stroke width. SkPaint has lots of optional 41787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * effects/attributes that can modify the effective bounds of a given primitive -- maskfilters, 41887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * patheffects, stroking, etc. This function takes a raw bounds and a paint, and returns the 41987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * conservative "effective" bounds based on the settings in the paint... with one exception. This 42087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * function does *not* look at the imagefilter, which can also modify the effective bounds. It is 42187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * deliberately ignored. 42287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco */ 42387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblancostatic const SkRect& apply_paint_to_bounds_sans_imagefilter(const SkPaint& paint, 42487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco const SkRect& rawBounds, 42587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect* storage) { 42687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkPaint tmpUnfiltered(paint); 42787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco tmpUnfiltered.setImageFilter(nullptr); 42887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (tmpUnfiltered.canComputeFastBounds()) { 42987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return tmpUnfiltered.computeFastBounds(rawBounds, storage); 43087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } else { 43187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return rawBounds; 43287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 43387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco} 43487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco 4358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass AutoDrawLooper { 4368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 43787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco // "rawBounds" is the original bounds of the primitive about to be drawn, unmodified by the 43887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco // paint. It's used to determine the size of the offscreen layer for filters. 43987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco // If null, the clip will be used instead. 4404a8126e7f81384526629b1e21bf89b632ea13cd9reed AutoDrawLooper(SkCanvas* canvas, const SkSurfaceProps& props, const SkPaint& paint, 44178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bool skipLayerForImageFilter = false, 44287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco const SkRect* rawBounds = nullptr) : fOrigPaint(paint) { 4434e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fCanvas = canvas; 4448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFilter = canvas->getDrawFilter(); 4454a8126e7f81384526629b1e21bf89b632ea13cd9reed fPaint = &fOrigPaint; 4464e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fSaveCount = canvas->getSaveCount(); 4475c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed fTempLayerForImageFilter = false; 4484e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fDone = false; 4498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 450dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkColorFilter* simplifiedCF = image_to_color_filter(fOrigPaint); 451dbc3cefb0b624808ddb86d444e6103f216e12fa5reed if (simplifiedCF) { 452dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkPaint* paint = set_if_needed(&fLazyPaintInit, fOrigPaint); 453dbc3cefb0b624808ddb86d444e6103f216e12fa5reed paint->setColorFilter(simplifiedCF)->unref(); 45496fcdcc219d2a0d3579719b84b28bede76efba64halcanary paint->setImageFilter(nullptr); 455dbc3cefb0b624808ddb86d444e6103f216e12fa5reed fPaint = paint; 456dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 457dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 458dbc3cefb0b624808ddb86d444e6103f216e12fa5reed if (!skipLayerForImageFilter && fPaint->getImageFilter()) { 4595c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed /** 4605c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * We implement ImageFilters for a given draw by creating a layer, then applying the 4615c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * imagefilter to the pixels of that layer (its backing surface/image), and then 4625c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * we call restore() to xfer that layer to the main canvas. 4635c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 4645c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 1. SaveLayer (with a paint containing the current imagefilter and xfermode) 4655c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 2. Generate the src pixels: 4665c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * Remove the imagefilter and the xfermode from the paint that we (AutoDrawLooper) 4675c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * return (fPaint). We then draw the primitive (using srcover) into a cleared 4685c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * buffer/surface. 4695c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 3. Restore the layer created in #1 4705c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * The imagefilter is passed the buffer/surface from the layer (now filled with the 4715c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * src pixels of the primitive). It returns a new "filtered" buffer, which we 4725c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * draw onto the previous layer using the xfermode from the original paint. 4735c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed */ 4748926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkPaint tmp; 475dbc3cefb0b624808ddb86d444e6103f216e12fa5reed tmp.setImageFilter(fPaint->getImageFilter()); 476dbc3cefb0b624808ddb86d444e6103f216e12fa5reed tmp.setXfermode(fPaint->getXfermode()); 47787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect storage; 47887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (rawBounds) { 47987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco // Make rawBounds include all paint outsets except for those due to image filters. 48087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco rawBounds = &apply_paint_to_bounds_sans_imagefilter(*fPaint, *rawBounds, &storage); 48187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 48287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco (void)canvas->internalSaveLayer(rawBounds, &tmp, SkCanvas::kARGB_ClipLayer_SaveFlag, 48376033be81b82c44fd5d4fdf2672eb22e505da1f0reed SkCanvas::kFullLayer_SaveLayerStrategy); 4845c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed fTempLayerForImageFilter = true; 4855c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed // we remove the imagefilter/xfermode inside doNext() 4868926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 4878926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 48879fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (SkDrawLooper* looper = paint.getLooper()) { 48979fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org void* buffer = fLooperContextAllocator.reserveT<SkDrawLooper::Context>( 49079fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org looper->contextSize()); 49179fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org fLooperContext = looper->createContext(canvas, buffer); 492129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fIsSimple = false; 493129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else { 49496fcdcc219d2a0d3579719b84b28bede76efba64halcanary fLooperContext = nullptr; 495129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // can we be marked as simple? 4965c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed fIsSimple = !fFilter && !fTempLayerForImageFilter; 4978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 498b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 4994a8126e7f81384526629b1e21bf89b632ea13cd9reed uint32_t oldFlags = paint.getFlags(); 5004a8126e7f81384526629b1e21bf89b632ea13cd9reed fNewPaintFlags = filter_paint_flags(props, oldFlags); 5014a8126e7f81384526629b1e21bf89b632ea13cd9reed if (fIsSimple && (fNewPaintFlags != oldFlags)) { 502dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkPaint* paint = set_if_needed(&fLazyPaintInit, fOrigPaint); 5034a8126e7f81384526629b1e21bf89b632ea13cd9reed paint->setFlags(fNewPaintFlags); 5044a8126e7f81384526629b1e21bf89b632ea13cd9reed fPaint = paint; 5054a8126e7f81384526629b1e21bf89b632ea13cd9reed // if we're not simple, doNext() will take care of calling setFlags() 5064a8126e7f81384526629b1e21bf89b632ea13cd9reed } 5078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 50874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 5094e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com ~AutoDrawLooper() { 5105c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed if (fTempLayerForImageFilter) { 5118926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com fCanvas->internalRestore(); 5128926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 5134e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkASSERT(fCanvas->getSaveCount() == fSaveCount); 5148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 51574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 5164e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com const SkPaint& paint() const { 5174e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkASSERT(fPaint); 5184e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return *fPaint; 5194e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 52074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 521129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool next(SkDrawFilter::Type drawType) { 522129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com if (fDone) { 523129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return false; 524129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else if (fIsSimple) { 525129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fDone = true; 526129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return !fPaint->nothingToDraw(); 527129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else { 528129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return this->doNext(drawType); 529129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 530fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 53174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 5328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 533dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkLazyPaint fLazyPaintInit; // base paint storage in case we need to modify it 534dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkLazyPaint fLazyPaintPerLooper; // per-draw-looper storage, so the looper can modify it 5352c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkCanvas* fCanvas; 5362c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint& fOrigPaint; 5372c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkDrawFilter* fFilter; 5382c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint* fPaint; 5392c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org int fSaveCount; 5404a8126e7f81384526629b1e21bf89b632ea13cd9reed uint32_t fNewPaintFlags; 5415c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed bool fTempLayerForImageFilter; 5422c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org bool fDone; 543129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool fIsSimple; 54479fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkDrawLooper::Context* fLooperContext; 54579fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkSmallAllocator<1, 32> fLooperContextAllocator; 546129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com 547129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool doNext(SkDrawFilter::Type drawType); 5488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 5498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 550129ec22cb054592261e001294c430c9dd4e90ff4reed@google.combool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) { 55196fcdcc219d2a0d3579719b84b28bede76efba64halcanary fPaint = nullptr; 552129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com SkASSERT(!fIsSimple); 5535c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed SkASSERT(fLooperContext || fFilter || fTempLayerForImageFilter); 554632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com 555dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkPaint* paint = fLazyPaintPerLooper.set(fLazyPaintInit.isValid() ? 556dbc3cefb0b624808ddb86d444e6103f216e12fa5reed *fLazyPaintInit.get() : fOrigPaint); 5574a8126e7f81384526629b1e21bf89b632ea13cd9reed paint->setFlags(fNewPaintFlags); 5588926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 5595c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed if (fTempLayerForImageFilter) { 56096fcdcc219d2a0d3579719b84b28bede76efba64halcanary paint->setImageFilter(nullptr); 56196fcdcc219d2a0d3579719b84b28bede76efba64halcanary paint->setXfermode(nullptr); 562129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 5638926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 56479fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (fLooperContext && !fLooperContext->next(fCanvas, paint)) { 565129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fDone = true; 566129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return false; 567129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 568129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com if (fFilter) { 569971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com if (!fFilter->filter(paint, drawType)) { 570971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com fDone = true; 571971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com return false; 572971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com } 57396fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == fLooperContext) { 574129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // no looper means we only draw once 575632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com fDone = true; 576632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com } 577129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 578129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fPaint = paint; 5798926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 580129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // if we only came in here for the imagefilter, mark us as done 58179fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (!fLooperContext && !fFilter) { 5824e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fDone = true; 5834e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 5844e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com 585632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com // call this after any possible paint modifiers 586632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com if (fPaint->nothingToDraw()) { 58796fcdcc219d2a0d3579719b84b28bede76efba64halcanary fPaint = nullptr; 5884e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return false; 5894e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 5904e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return true; 5914e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com} 5924e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com 5938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////// macros to place around the internal draw calls ////////////////// 5948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5958926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com#define LOOPER_BEGIN_DRAWDEVICE(paint, type) \ 59697af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com this->predrawNotify(); \ 5974a8126e7f81384526629b1e21bf89b632ea13cd9reed AutoDrawLooper looper(this, fProps, paint, true); \ 5988926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com while (looper.next(type)) { \ 5998926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkDrawIter iter(this); 6008926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 60178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org#define LOOPER_BEGIN(paint, type, bounds) \ 60297af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com this->predrawNotify(); \ 6034a8126e7f81384526629b1e21bf89b632ea13cd9reed AutoDrawLooper looper(this, fProps, paint, false, bounds); \ 6044e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com while (looper.next(type)) { \ 6058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDrawIter iter(this); 6064b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 607c83a29759a5c2966da5ab973e4fd90763e4c962breed#define LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, type, bounds, auxOpaque) \ 608c83a29759a5c2966da5ab973e4fd90763e4c962breed this->predrawNotify(bounds, &paint, auxOpaque); \ 609c83a29759a5c2966da5ab973e4fd90763e4c962breed AutoDrawLooper looper(this, fProps, paint, false, bounds); \ 610c83a29759a5c2966da5ab973e4fd90763e4c962breed while (looper.next(type)) { \ 611c83a29759a5c2966da5ab973e4fd90763e4c962breed SkDrawIter iter(this); 612c83a29759a5c2966da5ab973e4fd90763e4c962breed 6134e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com#define LOOPER_END } 6148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////// 6168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 617feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtkleinvoid SkCanvas::resetForNextPicture(const SkIRect& bounds) { 618feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein this->restoreToCount(1); 619feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fCachedLocalClipBounds.setEmpty(); 620feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fCachedLocalClipBoundsDirty = true; 621feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fClipStack->reset(); 622feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fMCRec->reset(bounds); 623feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 624feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein // We're peering through a lot of structs here. Only at this scope do we 625feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein // know that the device is an SkBitmapDevice (really an SkNoPixelsBitmapDevice). 626feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein static_cast<SkBitmapDevice*>(fMCRec->fLayer->fDevice)->setNewSize(bounds.size()); 627feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein} 628feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 629d954498c01ccf0417feacf89e45d0c62a06a813breedSkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) { 63042b73eb00367c8315974b1c374308d20efa78897reed if (device && device->forceConservativeRasterClip()) { 63142b73eb00367c8315974b1c374308d20efa78897reed flags = InitFlags(flags | kConservativeRasterClip_InitFlag); 63242b73eb00367c8315974b1c374308d20efa78897reed } 63342b73eb00367c8315974b1c374308d20efa78897reed // Since init() is only called once by our constructors, it is safe to perform this 63442b73eb00367c8315974b1c374308d20efa78897reed // const-cast. 63542b73eb00367c8315974b1c374308d20efa78897reed *const_cast<bool*>(&fConservativeRasterClip) = SkToBool(flags & kConservativeRasterClip_InitFlag); 63642b73eb00367c8315974b1c374308d20efa78897reed 637c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBounds.setEmpty(); 638c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 6398f0a7b8e7334187a5d7d5ab7fde5a3c3009555f5caryclark@google.com fAllowSoftClip = true; 64045a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com fAllowSimplifyClip = false; 641f92c86642a1875da54d54b447f006cb9dfbbb35creed fDeviceCMDirty = true; 6422ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount = 1; 64396fcdcc219d2a0d3579719b84b28bede76efba64halcanary fMetaData = nullptr; 6448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 645385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary fClipStack.reset(new SkClipStack); 646687fa1c745febb57f42b0d5f03d7c1f4be2530careed 6478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = (MCRec*)fMCStack.push_back(); 648d954498c01ccf0417feacf89e45d0c62a06a813breed new (fMCRec) MCRec(fConservativeRasterClip); 6498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 650a499f905e9340e4935447f2562fd92e8853382b1reed SkASSERT(sizeof(DeviceCM) <= sizeof(fDeviceCMStorage)); 651a499f905e9340e4935447f2562fd92e8853382b1reed fMCRec->fLayer = (DeviceCM*)fDeviceCMStorage; 65296fcdcc219d2a0d3579719b84b28bede76efba64halcanary new (fDeviceCMStorage) DeviceCM(nullptr, nullptr, nullptr, fConservativeRasterClip, false); 653b679ca8926a832274b14fdb512f88f64b61d32eareed 6548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fTopLayer = fMCRec->fLayer; 6558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 65696fcdcc219d2a0d3579719b84b28bede76efba64halcanary fSurfaceBase = nullptr; 657f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 658f92c86642a1875da54d54b447f006cb9dfbbb35creed if (device) { 659efbffedd68636e94d4379e84a2585bce80f6fb8frobertphillips // The root device and the canvas should always have the same pixel geometry 660efbffedd68636e94d4379e84a2585bce80f6fb8frobertphillips SkASSERT(fProps.pixelGeometry() == device->surfaceProps().pixelGeometry()); 661f92c86642a1875da54d54b447f006cb9dfbbb35creed device->onAttachToCanvas(this); 662f92c86642a1875da54d54b447f006cb9dfbbb35creed fMCRec->fLayer->fDevice = SkRef(device); 66378e276889795454891cbba48ab11927968114953reed fMCRec->fRasterClip.setRect(device->getGlobalBounds()); 664f92c86642a1875da54d54b447f006cb9dfbbb35creed } 665f92c86642a1875da54d54b447f006cb9dfbbb35creed return device; 6668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 668cde92111d50a96b6d0f3e166fbac7c9bc6eca349reed@google.comSkCanvas::SkCanvas() 669e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 6704a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 67142b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 672e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org{ 6738d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org inc_canvas(); 674ba124485687130183643994f1b4b68d629fbbebaskia.committer@gmail.com 67596fcdcc219d2a0d3579719b84b28bede76efba64halcanary this->init(nullptr, kDefault_InitFlags); 6768d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org} 6778d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org 678d954498c01ccf0417feacf89e45d0c62a06a813breedstatic SkBitmap make_nopixels(int width, int height) { 679d954498c01ccf0417feacf89e45d0c62a06a813breed SkBitmap bitmap; 680d954498c01ccf0417feacf89e45d0c62a06a813breed bitmap.setInfo(SkImageInfo::MakeUnknown(width, height)); 681d954498c01ccf0417feacf89e45d0c62a06a813breed return bitmap; 682d954498c01ccf0417feacf89e45d0c62a06a813breed} 683d954498c01ccf0417feacf89e45d0c62a06a813breed 684d954498c01ccf0417feacf89e45d0c62a06a813breedclass SkNoPixelsBitmapDevice : public SkBitmapDevice { 685d954498c01ccf0417feacf89e45d0c62a06a813breedpublic: 686fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips SkNoPixelsBitmapDevice(const SkIRect& bounds, const SkSurfaceProps& surfaceProps) 687fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips : INHERITED(make_nopixels(bounds.width(), bounds.height()), surfaceProps) 68878e276889795454891cbba48ab11927968114953reed { 68978e276889795454891cbba48ab11927968114953reed this->setOrigin(bounds.x(), bounds.y()); 69078e276889795454891cbba48ab11927968114953reed } 691d954498c01ccf0417feacf89e45d0c62a06a813breed 692d954498c01ccf0417feacf89e45d0c62a06a813breedprivate: 693b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 694d954498c01ccf0417feacf89e45d0c62a06a813breed typedef SkBitmapDevice INHERITED; 695d954498c01ccf0417feacf89e45d0c62a06a813breed}; 696d954498c01ccf0417feacf89e45d0c62a06a813breed 69796a857ef5a40b3d0751ec9ebaaa96d9f20b82b21reedSkCanvas::SkCanvas(int width, int height, const SkSurfaceProps* props) 698e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 69996a857ef5a40b3d0751ec9ebaaa96d9f20b82b21reed , fProps(SkSurfacePropsCopyOrDefault(props)) 70042b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 701e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org{ 702e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org inc_canvas(); 703b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 704385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary this->init(new SkNoPixelsBitmapDevice(SkIRect::MakeWH(width, height), fProps), 705385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary kDefault_InitFlags)->unref(); 706d954498c01ccf0417feacf89e45d0c62a06a813breed} 707e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org 70878e276889795454891cbba48ab11927968114953reedSkCanvas::SkCanvas(const SkIRect& bounds, InitFlags flags) 709d954498c01ccf0417feacf89e45d0c62a06a813breed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7104a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 71142b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 712d954498c01ccf0417feacf89e45d0c62a06a813breed{ 713d954498c01ccf0417feacf89e45d0c62a06a813breed inc_canvas(); 714b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 715385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary this->init(new SkNoPixelsBitmapDevice(bounds, fProps), flags)->unref(); 71627a5e656c3d6ef22f9cb34de18e1b960da3aa241reed} 7178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 718d954498c01ccf0417feacf89e45d0c62a06a813breedSkCanvas::SkCanvas(SkBaseDevice* device) 719d954498c01ccf0417feacf89e45d0c62a06a813breed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7207b05ff11ebc51f3f3abd1c1756337a04f563537erobertphillips , fProps(device->surfaceProps()) 72142b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 722d954498c01ccf0417feacf89e45d0c62a06a813breed{ 723d954498c01ccf0417feacf89e45d0c62a06a813breed inc_canvas(); 724b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 725d954498c01ccf0417feacf89e45d0c62a06a813breed this->init(device, kDefault_InitFlags); 7268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 728fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillipsSkCanvas::SkCanvas(SkBaseDevice* device, InitFlags flags) 729fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7307b05ff11ebc51f3f3abd1c1756337a04f563537erobertphillips , fProps(device->surfaceProps()) 73142b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 732fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips{ 733fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips inc_canvas(); 734fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips 735fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips this->init(device, flags); 736fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips} 737fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips 7384a8126e7f81384526629b1e21bf89b632ea13cd9reedSkCanvas::SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props) 7393716fd067a5621bb94a6cb08d72afec8bf3acedareed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7404a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(props) 74142b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 7423716fd067a5621bb94a6cb08d72afec8bf3acedareed{ 7433716fd067a5621bb94a6cb08d72afec8bf3acedareed inc_canvas(); 744b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 745385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary SkAutoTUnref<SkBaseDevice> device(new SkBitmapDevice(bitmap, fProps)); 7464a8126e7f81384526629b1e21bf89b632ea13cd9reed this->init(device, kDefault_InitFlags); 7474a8126e7f81384526629b1e21bf89b632ea13cd9reed} 74829c857d0f3a1cb837f73406eeb6ba9771879b5e7reed 7494a8126e7f81384526629b1e21bf89b632ea13cd9reedSkCanvas::SkCanvas(const SkBitmap& bitmap) 7504a8126e7f81384526629b1e21bf89b632ea13cd9reed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7514a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 75242b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 7534a8126e7f81384526629b1e21bf89b632ea13cd9reed{ 7544a8126e7f81384526629b1e21bf89b632ea13cd9reed inc_canvas(); 755b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 756385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary SkAutoTUnref<SkBaseDevice> device(new SkBitmapDevice(bitmap, fProps)); 7574a8126e7f81384526629b1e21bf89b632ea13cd9reed this->init(device, kDefault_InitFlags); 7588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::~SkCanvas() { 7618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // free up the contents of our deque 7628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->restoreToCount(1); // restore everything but the last 7637c2029367cea5479fa3b74fb0ca2b0297b42b709reed@google.com 7648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->internalRestore(); // restore the last, since we're going away 7658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 766385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete fMetaData; 767b70ae310bbdaa1b26786773aabce5548c1f48563vandebo@chromium.org 7688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dec_canvas(); 7698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDrawFilter* SkCanvas::getDrawFilter() const { 7728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fMCRec->fFilter; 7738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDrawFilter* SkCanvas::setDrawFilter(SkDrawFilter* filter) { 77651985e3f5e608d369e52832b7ce489d85d402422reed this->checkForDeferredSave(); 7778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fMCRec->fFilter, filter); 7788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return filter; 7798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 78174bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.orgSkMetaData& SkCanvas::getMetaData() { 78274bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org // metadata users are rare, so we lazily allocate it. If that changes we 78374bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org // can decide to just make it a field in the device (rather than a ptr) 78496fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == fMetaData) { 78574bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org fMetaData = new SkMetaData; 78674bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org } 78774bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org return *fMetaData; 78874bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org} 78974bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org 7908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 7918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 792bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.orgvoid SkCanvas::flush() { 7931f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* device = this->getDevice(); 794bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org if (device) { 795bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org device->flush(); 796bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org } 797bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org} 798bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org 7994ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.comSkISize SkCanvas::getTopLayerSize() const { 8004ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com SkBaseDevice* d = this->getTopDevice(); 8014ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com return d ? SkISize::Make(d->width(), d->height()) : SkISize::Make(0, 0); 8024ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com} 8034ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com 8044ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.comSkIPoint SkCanvas::getTopLayerOrigin() const { 8054ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com SkBaseDevice* d = this->getTopDevice(); 8064ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com return d ? d->getOrigin() : SkIPoint::Make(0, 0); 8074ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com} 8084ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com 8094ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.comSkISize SkCanvas::getBaseLayerSize() const { 8101f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* d = this->getDevice(); 811210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com return d ? SkISize::Make(d->width(), d->height()) : SkISize::Make(0, 0); 812210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com} 813210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com 8141f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::getDevice() const { 8158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // return root device 816c029062a0312fb747fb6c2677983aba51795c580robertphillips@google.com MCRec* rec = (MCRec*) fMCStack.front(); 8178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(rec && rec->fLayer); 8188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return rec->fLayer->fDevice; 8198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8211f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::getTopDevice(bool updateMatrixClip) const { 8220b53d59a24f667350b4282f88470713902409030reed@google.com if (updateMatrixClip) { 8230b53d59a24f667350b4282f88470713902409030reed@google.com const_cast<SkCanvas*>(this)->updateDeviceCMCache(); 8240b53d59a24f667350b4282f88470713902409030reed@google.com } 8259266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com return fMCRec->fTopLayer->fDevice; 8269266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com} 8279266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com 828a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.orgbool SkCanvas::readPixels(SkBitmap* bitmap, int x, int y) { 829a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (kUnknown_SkColorType == bitmap->colorType() || bitmap->getTexture()) { 830a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 831a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 832a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 833a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bool weAllocated = false; 83496fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == bitmap->pixelRef()) { 835848250415eddc54075f7eb8795e8db79e749c6abreed if (!bitmap->tryAllocPixels()) { 836a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 837a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 838a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org weAllocated = true; 839a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 840a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 841cf01e31df6bbda270dca2ee3b4967caf51e465dcreed SkAutoPixmapUnlock unlocker; 842cf01e31df6bbda270dca2ee3b4967caf51e465dcreed if (bitmap->requestLock(&unlocker)) { 843cf01e31df6bbda270dca2ee3b4967caf51e465dcreed const SkPixmap& pm = unlocker.pixmap(); 844cf01e31df6bbda270dca2ee3b4967caf51e465dcreed if (this->readPixels(pm.info(), pm.writable_addr(), pm.rowBytes(), x, y)) { 845cf01e31df6bbda270dca2ee3b4967caf51e465dcreed return true; 846cf01e31df6bbda270dca2ee3b4967caf51e465dcreed } 847a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 848a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 849a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (weAllocated) { 85096fcdcc219d2a0d3579719b84b28bede76efba64halcanary bitmap->setPixelRef(nullptr); 851a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 852a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 853a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org} 85451df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 855c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.combool SkCanvas::readPixels(const SkIRect& srcRect, SkBitmap* bitmap) { 856a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkIRect r = srcRect; 857a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 858a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!r.intersect(0, 0, size.width(), size.height())) { 859a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bitmap->reset(); 860ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com return false; 861ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com } 86274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 863848250415eddc54075f7eb8795e8db79e749c6abreed if (!bitmap->tryAllocN32Pixels(r.width(), r.height())) { 864a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org // bitmap will already be reset. 865a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 866a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 867a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!this->readPixels(bitmap->info(), bitmap->getPixels(), bitmap->rowBytes(), r.x(), r.y())) { 868a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bitmap->reset(); 869daba14b7d4fc96b915c45d82713b22729c0d0f37bsalomon@google.com return false; 870c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } 871a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return true; 872a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org} 873c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 87496472deea70169396b8e1f576e470138f55fdb1freedbool SkCanvas::readPixels(const SkImageInfo& dstInfo, void* dstP, size_t rowBytes, int x, int y) { 875a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkBaseDevice* device = this->getDevice(); 876a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!device) { 877a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 878a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 879a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 880f0f14113431ace669f278fdd97b50950f2cf4c80mtklein 88196472deea70169396b8e1f576e470138f55fdb1freed SkReadPixelsRec rec(dstInfo, dstP, rowBytes, x, y); 88296472deea70169396b8e1f576e470138f55fdb1freed if (!rec.trim(size.width(), size.height())) { 883a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 884a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 885db0c8753775774aa3f67114491e26ac1be32f38eskia.committer@gmail.com 886a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org // The device can assert that the requested area is always contained in its bounds 88796472deea70169396b8e1f576e470138f55fdb1freed return device->readPixels(rec.fInfo, rec.fPixels, rec.fRowBytes, rec.fX, rec.fY); 88851df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com} 88951df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 8904cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgbool SkCanvas::writePixels(const SkBitmap& bitmap, int x, int y) { 8914cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (bitmap.getTexture()) { 8924cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 8934cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 894cf01e31df6bbda270dca2ee3b4967caf51e465dcreed 895cf01e31df6bbda270dca2ee3b4967caf51e465dcreed SkAutoPixmapUnlock unlocker; 896cf01e31df6bbda270dca2ee3b4967caf51e465dcreed if (bitmap.requestLock(&unlocker)) { 897cf01e31df6bbda270dca2ee3b4967caf51e465dcreed const SkPixmap& pm = unlocker.pixmap(); 898cf01e31df6bbda270dca2ee3b4967caf51e465dcreed return this->writePixels(pm.info(), pm.addr(), pm.rowBytes(), x, y); 8994cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 9004cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 9014cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org} 9024cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 9034cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgbool SkCanvas::writePixels(const SkImageInfo& origInfo, const void* pixels, size_t rowBytes, 9044cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org int x, int y) { 9054cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org switch (origInfo.colorType()) { 9064cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org case kUnknown_SkColorType: 9074cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org case kIndex_8_SkColorType: 9084cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 9094cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org default: 9104cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org break; 9114cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 91296fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == pixels || rowBytes < origInfo.minRowBytes()) { 9134cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 9144cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 9154cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 9164cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 9174cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org SkIRect target = SkIRect::MakeXYWH(x, y, origInfo.width(), origInfo.height()); 9184cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (!target.intersect(0, 0, size.width(), size.height())) { 9194cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 9204cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 9214cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 9224cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org SkBaseDevice* device = this->getDevice(); 9234cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (!device) { 9244cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 9254cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 9264cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 9274cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // the intersect may have shrunk info's logical size 928e5ea500d4714a7d84de2bf913e81be3b65d2de68reed const SkImageInfo info = origInfo.makeWH(target.width(), target.height()); 9294cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 9304cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // if x or y are negative, then we have to adjust pixels 9314cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (x > 0) { 9324cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org x = 0; 9334cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 9344cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (y > 0) { 9354cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org y = 0; 9364cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 9374cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // here x,y are either 0 or negative 9384cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org pixels = ((const char*)pixels - y * rowBytes - x * info.bytesPerPixel()); 9394cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 9404af35f348b2e2f6c428819118eb7a2f2fff53a74reed // Tell our owning surface to bump its generation ID 941c83a29759a5c2966da5ab973e4fd90763e4c962breed const bool completeOverwrite = info.dimensions() == size; 942c83a29759a5c2966da5ab973e4fd90763e4c962breed this->predrawNotify(completeOverwrite); 9434af35f348b2e2f6c428819118eb7a2f2fff53a74reed 9444cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // The device can assert that the requested area is always contained in its bounds 9454ef54f8d72420a521d4aae04ff5cd438810eca7fcommit-bot@chromium.org return device->writePixels(info, pixels, rowBytes, target.x(), target.y()); 9464cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org} 94751df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 9484370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comSkCanvas* SkCanvas::canvasForDrawIter() { 9494370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com return this; 9504370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 9514370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 9528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 9538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::updateDeviceCMCache() { 9558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fDeviceCMDirty) { 9568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& totalMatrix = this->getTotalMatrix(); 9571f836ee096bb988adef4b9757b2629c7afeda36dreed const SkRasterClip& totalClip = fMCRec->fRasterClip; 9588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* layer = fMCRec->fTopLayer; 9594b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 96096fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == layer->fNext) { // only one layer 96196fcdcc219d2a0d3579719b84b28bede76efba64halcanary layer->updateMC(totalMatrix, totalClip, *fClipStack, nullptr); 9628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 963045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com SkRasterClip clip(totalClip); 9648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 965687fa1c745febb57f42b0d5f03d7c1f4be2530careed layer->updateMC(totalMatrix, clip, *fClipStack, &clip); 96696fcdcc219d2a0d3579719b84b28bede76efba64halcanary } while ((layer = layer->fNext) != nullptr); 9678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = false; 9698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 9738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9742ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::checkForDeferredSave() { 9752ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (fMCRec->fDeferredSaveCount > 0) { 9762ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->doSave(); 9772ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 9782ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed} 9792ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed 980f0090cb80ab10a49e511aa5450ae38917fa058d9reedint SkCanvas::getSaveCount() const { 9812ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed#ifdef SK_DEBUG 9822ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed int count = 0; 9832ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkDeque::Iter iter(fMCStack, SkDeque::Iter::kFront_IterStart); 9842ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed for (;;) { 9852ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed const MCRec* rec = (const MCRec*)iter.next(); 9862ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (!rec) { 9872ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed break; 9882ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 9892ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed count += 1 + rec->fDeferredSaveCount; 9902ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 9912ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(count == fSaveCount); 9922ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed#endif 9932ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return fSaveCount; 994f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 995f0090cb80ab10a49e511aa5450ae38917fa058d9reed 996f0090cb80ab10a49e511aa5450ae38917fa058d9reedint SkCanvas::save() { 9972ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount += 1; 9982ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fMCRec->fDeferredSaveCount += 1; 9992ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return this->getSaveCount() - 1; // return our prev value 10002ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed} 10012ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed 10022ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::doSave() { 1003f0090cb80ab10a49e511aa5450ae38917fa058d9reed this->willSave(); 1004a62d32d1e3112c7e5a26c27e5e967d124ef8dd81fmalita 1005a62d32d1e3112c7e5a26c27e5e967d124ef8dd81fmalita SkASSERT(fMCRec->fDeferredSaveCount > 0); 1006a62d32d1e3112c7e5a26c27e5e967d124ef8dd81fmalita fMCRec->fDeferredSaveCount -= 1; 10072ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalSave(); 1008f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 1009f0090cb80ab10a49e511aa5450ae38917fa058d9reed 1010f0090cb80ab10a49e511aa5450ae38917fa058d9reedvoid SkCanvas::restore() { 10112ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (fMCRec->fDeferredSaveCount > 0) { 10122ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(fSaveCount > 1); 10132ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount -= 1; 10142ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fMCRec->fDeferredSaveCount -= 1; 10152ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } else { 10162ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed // check for underflow 10172ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (fMCStack.count() > 1) { 10182ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->willRestore(); 10192ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(fSaveCount > 1); 1020a644116c3375b12c642d1b51ee1e5cf4a22c1f5breed fSaveCount -= 1; 10212ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalRestore(); 10222ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->didRestore(); 10232ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 1024f0090cb80ab10a49e511aa5450ae38917fa058d9reed } 1025f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 1026f0090cb80ab10a49e511aa5450ae38917fa058d9reed 1027f0090cb80ab10a49e511aa5450ae38917fa058d9reedvoid SkCanvas::restoreToCount(int count) { 1028f0090cb80ab10a49e511aa5450ae38917fa058d9reed // sanity check 1029f0090cb80ab10a49e511aa5450ae38917fa058d9reed if (count < 1) { 1030f0090cb80ab10a49e511aa5450ae38917fa058d9reed count = 1; 1031f0090cb80ab10a49e511aa5450ae38917fa058d9reed } 1032f0f14113431ace669f278fdd97b50950f2cf4c80mtklein 1033f0090cb80ab10a49e511aa5450ae38917fa058d9reed int n = this->getSaveCount() - count; 1034f0090cb80ab10a49e511aa5450ae38917fa058d9reed for (int i = 0; i < n; ++i) { 1035f0090cb80ab10a49e511aa5450ae38917fa058d9reed this->restore(); 1036f0090cb80ab10a49e511aa5450ae38917fa058d9reed } 1037f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 1038f0090cb80ab10a49e511aa5450ae38917fa058d9reed 10392ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::internalSave() { 10408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com MCRec* newTop = (MCRec*)fMCStack.push_back(); 1041d954498c01ccf0417feacf89e45d0c62a06a813breed new (newTop) MCRec(*fMCRec); // balanced in restore() 10428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = newTop; 10434b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 1044687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->save(); 10458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic bool bounds_affects_clip(SkCanvas::SaveFlags flags) { 1048b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG 10498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (flags & SkCanvas::kClipToLayer_SaveFlag) != 0; 1050b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#else 1051b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com return true; 1052b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#endif 10538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1055a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.orgbool SkCanvas::clipRectBounds(const SkRect* bounds, SaveFlags flags, 10569b3aa54bc9605257c701cf465813f5fb1d7ba39ereed SkIRect* intersection, const SkImageFilter* imageFilter) { 1057bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect clipBounds; 1058bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (!this->getClipDeviceBounds(&clipBounds)) { 1059a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return false; 1060f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 1061c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org 106296e657d0e103b8358a77ecd913f6086929f792b8reed const SkMatrix& ctm = fMCRec->fMatrix; // this->getTotalMatrix() 106396e657d0e103b8358a77ecd913f6086929f792b8reed 106487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco// This is a temporary hack, until individual filters can do their own 106587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco// bloating, when this will be removed. 106687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco#ifdef SK_SUPPORT_SRC_BOUNDS_BLOAT_FOR_IMAGEFILTERS 106787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect storage; 106887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco#endif 1069c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org if (imageFilter) { 107096e657d0e103b8358a77ecd913f6086929f792b8reed imageFilter->filterBounds(clipBounds, ctm, &clipBounds); 107187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco#ifdef SK_SUPPORT_SRC_BOUNDS_BLOAT_FOR_IMAGEFILTERS 107287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (bounds && imageFilter->canComputeFastBounds()) { 107387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco imageFilter->computeFastBounds(*bounds, &storage); 107487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &storage; 107587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } else { 107687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = nullptr; 107787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 107887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco#endif 1079c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org } 1080bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect ir; 108149f085dddff10473b6ebf832a974288300224e60bsalomon if (bounds) { 10828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 10834b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 108496e657d0e103b8358a77ecd913f6086929f792b8reed ctm.mapRect(&r, *bounds); 10858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.roundOut(&ir); 10868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // early exit if the layer's bounds are clipped out 10878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!ir.intersect(clipBounds)) { 1088bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (bounds_affects_clip(flags)) { 10899b3aa54bc9605257c701cf465813f5fb1d7ba39ereed fCachedLocalClipBoundsDirty = true; 10901f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fRasterClip.setEmpty(); 1091bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1092a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return false; 10938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { // no user bounds, so just use the clip 10958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ir = clipBounds; 10968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1097180aec43451dd951fdaae81a92efc710ba093260reed SkASSERT(!ir.isEmpty()); 10988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 109989f077ced4918ded7e911bc5052b61c90ad57a9asenorblanco@chromium.org if (bounds_affects_clip(flags)) { 1100180aec43451dd951fdaae81a92efc710ba093260reed // Simplify the current clips since they will be applied properly during restore() 11019b3aa54bc9605257c701cf465813f5fb1d7ba39ereed fCachedLocalClipBoundsDirty = true; 1102687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipDevRect(ir, SkRegion::kReplace_Op); 1103180aec43451dd951fdaae81a92efc710ba093260reed fMCRec->fRasterClip.setRect(ir); 1104a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org } 1105a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 1106a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org if (intersection) { 1107a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org *intersection = ir; 1108a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org } 1109a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return true; 1110a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org} 1111a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 1112d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.orgint SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint) { 1113d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed if (gIgnoreSaveLayerBounds) { 111496fcdcc219d2a0d3579719b84b28bede76efba64halcanary bounds = nullptr; 1115d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed } 1116d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org SaveLayerStrategy strategy = this->willSaveLayer(bounds, paint, kARGB_ClipLayer_SaveFlag); 1117a644116c3375b12c642d1b51ee1e5cf4a22c1f5breed fSaveCount += 1; 111876033be81b82c44fd5d4fdf2672eb22e505da1f0reed this->internalSaveLayer(bounds, paint, kARGB_ClipLayer_SaveFlag, strategy); 11192ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return this->getSaveCount() - 1; 1120d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org} 1121d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org 11222ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedint SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags) { 1123d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed if (gIgnoreSaveLayerBounds) { 112496fcdcc219d2a0d3579719b84b28bede76efba64halcanary bounds = nullptr; 1125d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed } 1126e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org SaveLayerStrategy strategy = this->willSaveLayer(bounds, paint, flags); 1127a644116c3375b12c642d1b51ee1e5cf4a22c1f5breed fSaveCount += 1; 112876033be81b82c44fd5d4fdf2672eb22e505da1f0reed this->internalSaveLayer(bounds, paint, flags, strategy); 11292ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return this->getSaveCount() - 1; 11308926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com} 11318926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 11322ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags, 113376033be81b82c44fd5d4fdf2672eb22e505da1f0reed SaveLayerStrategy strategy) { 1134b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG 11352a5cd60bfff32c92cf44a8cfc3e8c017b9aee456commit-bot@chromium.org flags |= kClipToLayer_SaveFlag; 1136b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#endif 1137b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com 1138a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org // do this before we create the layer. We don't call the public save() since 1139a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org // that would invoke a possibly overridden virtual 11402ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalSave(); 1141a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 1142a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org fDeviceCMDirty = true; 1143a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 1144a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org SkIRect ir; 114596fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (!this->clipRectBounds(bounds, flags, &ir, paint ? paint->getImageFilter() : nullptr)) { 11462ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 11478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1149e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy really care about 1150e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org // the clipRectBounds() call above? 1151e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org if (kNoLayer_SaveLayerStrategy == strategy) { 11522ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 1153e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org } 1154e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org 115576033be81b82c44fd5d4fdf2672eb22e505da1f0reed bool isOpaque = !SkToBool(flags & kHasAlphaLayer_SaveFlag); 11568dc0ccb8d33d1af7dd13228509e61fe915bc7705reed SkPixelGeometry geo = fProps.pixelGeometry(); 11578dc0ccb8d33d1af7dd13228509e61fe915bc7705reed if (paint) { 115876033be81b82c44fd5d4fdf2672eb22e505da1f0reed // TODO: perhaps add a query to filters so we might preserve opaqueness... 1159daa57bfd4204f5a7d304c580bcf5ad99d0121e1freed if (paint->getImageFilter() || paint->getColorFilter()) { 116076033be81b82c44fd5d4fdf2672eb22e505da1f0reed isOpaque = false; 11618dc0ccb8d33d1af7dd13228509e61fe915bc7705reed geo = kUnknown_SkPixelGeometry; 1162b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com } 1163b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com } 116415a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org SkImageInfo info = SkImageInfo::MakeN32(ir.width(), ir.height(), 116515a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType); 11668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1167b2db898573e3cdcc8234eebf51961bfc4977ebbcreed SkBaseDevice* device = this->getTopDevice(); 116896fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == device) { 1169b2db898573e3cdcc8234eebf51961bfc4977ebbcreed SkDebugf("Unable to find device for layer."); 11702ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 1171b2db898573e3cdcc8234eebf51961bfc4977ebbcreed } 1172b2db898573e3cdcc8234eebf51961bfc4977ebbcreed 117361f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed bool forceSpriteOnRestore = false; 117461f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed { 1175daa57bfd4204f5a7d304c580bcf5ad99d0121e1freed const SkBaseDevice::TileUsage usage = SkBaseDevice::kNever_TileUsage; 117661f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed const SkBaseDevice::CreateInfo createInfo = SkBaseDevice::CreateInfo(info, usage, geo); 117761f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed SkBaseDevice* newDev = device->onCreateDevice(createInfo, paint); 117896fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == newDev) { 117961f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed // If onCreateDevice didn't succeed, try raster (e.g. PDF couldn't handle the paint) 11809a53fd7c41554630124522f4b6eedc16912abbb7robertphillips const SkSurfaceProps surfaceProps(fProps.flags(), createInfo.fPixelGeometry); 11819a53fd7c41554630124522f4b6eedc16912abbb7robertphillips newDev = SkBitmapDevice::Create(createInfo.fInfo, surfaceProps); 118296fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == newDev) { 118361f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed SkErrorInternals::SetError(kInternalError_SkError, 118461f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed "Unable to create device for layer."); 118561f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed return; 118661f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed } 118761f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed forceSpriteOnRestore = true; 118861f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed } 118961f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed device = newDev; 1190e25c68402b38ac01dc1ae196ae8a5265b773c5f2bungeman@google.com } 1191e97f0856a8044866b12527819d14cdfbcdfd96f2bsalomon@google.com 11926f8f292aa768869a9e85c314b124875f57504f2creed@google.com device->setOrigin(ir.fLeft, ir.fTop); 1193385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary DeviceCM* layer = 1194385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary new DeviceCM(device, paint, this, fConservativeRasterClip, forceSpriteOnRestore); 11958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device->unref(); 11968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com layer->fNext = fMCRec->fTopLayer; 11988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fLayer = layer; 11998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fTopLayer = layer; // this field is NOT an owner of layer 12008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1202d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.orgint SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) { 1203d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org return this->saveLayerAlpha(bounds, alpha, kARGB_ClipLayer_SaveFlag); 1204d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org} 1205d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org 12068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha, 12078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SaveFlags flags) { 12088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (0xFF == alpha) { 120996fcdcc219d2a0d3579719b84b28bede76efba64halcanary return this->saveLayer(bounds, nullptr, flags); 12108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 12118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint tmpPaint; 12128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com tmpPaint.setAlpha(alpha); 12138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->saveLayer(bounds, &tmpPaint, flags); 12148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::internalRestore() { 12188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fMCStack.count() != 0); 12198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1221c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 12228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1223687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->restore(); 12246c157640c27ee2ed6f9a484d21691b7b19dfecdecommit-bot@chromium.org 122588edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com // reserve our layer (if any) 12268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* layer = fMCRec->fLayer; // may be null 12278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now detach it from fMCRec so we can pop(). Gets freed after its drawn 122896fcdcc219d2a0d3579719b84b28bede76efba64halcanary fMCRec->fLayer = nullptr; 12298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now do the normal restore() 12318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->~MCRec(); // balanced in save() 12328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCStack.pop_back(); 12338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = (MCRec*)fMCStack.back(); 12348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* Time to draw the layer's offscreen. We can't call the public drawSprite, 12368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com since if we're being recorded, we don't want to record this (the 12378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com recorder will have already recorded the restore). 12388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 123949f085dddff10473b6ebf832a974288300224e60bsalomon if (layer) { 12408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (layer->fNext) { 12416f8f292aa768869a9e85c314b124875f57504f2creed@google.com const SkIPoint& origin = layer->fDevice->getOrigin(); 12428926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(), 124361f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed layer->fPaint, layer->fDeviceIsBitmapDevice); 12448926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com // reset this, since internalDrawDevice will have set it to true 12458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1246385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete layer; 1247b679ca8926a832274b14fdb512f88f64b61d32eareed } else { 1248b679ca8926a832274b14fdb512f88f64b61d32eareed // we're at the root 1249a499f905e9340e4935447f2562fd92e8853382b1reed SkASSERT(layer == (void*)fDeviceCMStorage); 1250b679ca8926a832274b14fdb512f88f64b61d32eareed layer->~DeviceCM(); 12518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 125288edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 12538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12554a8126e7f81384526629b1e21bf89b632ea13cd9reedSkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* props) { 125696fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == props) { 12574a8126e7f81384526629b1e21bf89b632ea13cd9reed props = &fProps; 12584a8126e7f81384526629b1e21bf89b632ea13cd9reed } 12594a8126e7f81384526629b1e21bf89b632ea13cd9reed return this->onNewSurface(info, *props); 126076f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com} 126176f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com 12624a8126e7f81384526629b1e21bf89b632ea13cd9reedSkSurface* SkCanvas::onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props) { 126376f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com SkBaseDevice* dev = this->getDevice(); 126496fcdcc219d2a0d3579719b84b28bede76efba64halcanary return dev ? dev->newSurface(info, props) : nullptr; 126576f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com} 126676f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com 1267c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgSkImageInfo SkCanvas::imageInfo() const { 1268c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkBaseDevice* dev = this->getDevice(); 1269c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (dev) { 1270c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return dev->imageInfo(); 1271c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } else { 1272900ecf2f1579d42c9d2959831787af0346320f86reed@google.com return SkImageInfo::MakeUnknown(0, 0); 1273c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1274c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1275c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1276c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgconst void* SkCanvas::peekPixels(SkImageInfo* info, size_t* rowBytes) { 1277884e97cb04db7ed053a866567ee9c6e4c01f993areed SkPixmap pmap; 1278884e97cb04db7ed053a866567ee9c6e4c01f993areed if (!this->onPeekPixels(&pmap)) { 127996fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 1280884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1281884e97cb04db7ed053a866567ee9c6e4c01f993areed if (info) { 1282884e97cb04db7ed053a866567ee9c6e4c01f993areed *info = pmap.info(); 1283884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1284884e97cb04db7ed053a866567ee9c6e4c01f993areed if (rowBytes) { 1285884e97cb04db7ed053a866567ee9c6e4c01f993areed *rowBytes = pmap.rowBytes(); 1286884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1287884e97cb04db7ed053a866567ee9c6e4c01f993areed return pmap.addr(); 1288c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1289c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1290884e97cb04db7ed053a866567ee9c6e4c01f993areedbool SkCanvas::onPeekPixels(SkPixmap* pmap) { 1291c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkBaseDevice* dev = this->getDevice(); 1292884e97cb04db7ed053a866567ee9c6e4c01f993areed return dev && dev->peekPixels(pmap); 1293c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1294c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 12956b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.orgvoid* SkCanvas::accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin) { 1296884e97cb04db7ed053a866567ee9c6e4c01f993areed SkPixmap pmap; 1297884e97cb04db7ed053a866567ee9c6e4c01f993areed if (!this->onAccessTopLayerPixels(&pmap)) { 129896fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 1299884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1300884e97cb04db7ed053a866567ee9c6e4c01f993areed if (info) { 1301884e97cb04db7ed053a866567ee9c6e4c01f993areed *info = pmap.info(); 1302884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1303884e97cb04db7ed053a866567ee9c6e4c01f993areed if (rowBytes) { 1304884e97cb04db7ed053a866567ee9c6e4c01f993areed *rowBytes = pmap.rowBytes(); 1305884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1306884e97cb04db7ed053a866567ee9c6e4c01f993areed if (origin) { 13076b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org *origin = this->getTopDevice(false)->getOrigin(); 13086b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org } 1309884e97cb04db7ed053a866567ee9c6e4c01f993areed return pmap.writable_addr(); 13109c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 13119c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1312884e97cb04db7ed053a866567ee9c6e4c01f993areedbool SkCanvas::onAccessTopLayerPixels(SkPixmap* pmap) { 13139c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com SkBaseDevice* dev = this->getTopDevice(); 1314884e97cb04db7ed053a866567ee9c6e4c01f993areed return dev && dev->accessPixels(pmap); 13159c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 13169c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1317c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgSkAutoROCanvasPixels::SkAutoROCanvasPixels(SkCanvas* canvas) { 1318c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org fAddr = canvas->peekPixels(&fInfo, &fRowBytes); 131996fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == fAddr) { 1320c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org fInfo = canvas->imageInfo(); 1321848250415eddc54075f7eb8795e8db79e749c6abreed if (kUnknown_SkColorType == fInfo.colorType() || !fBitmap.tryAllocPixels(fInfo)) { 132296fcdcc219d2a0d3579719b84b28bede76efba64halcanary return; // failure, fAddr is nullptr 1323c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1324c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (!canvas->readPixels(&fBitmap, 0, 0)) { 132596fcdcc219d2a0d3579719b84b28bede76efba64halcanary return; // failure, fAddr is nullptr 1326c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1327c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org fAddr = fBitmap.getPixels(); 1328c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org fRowBytes = fBitmap.rowBytes(); 1329c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1330c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkASSERT(fAddr); // success 1331c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1332c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1333c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgbool SkAutoROCanvasPixels::asROBitmap(SkBitmap* bitmap) const { 1334c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (fAddr) { 133500f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org return bitmap->installPixels(fInfo, const_cast<void*>(fAddr), fRowBytes); 1336c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } else { 1337c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org bitmap->reset(); 1338c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return false; 1339c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1340c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1341c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1342520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org///////////////////////////////////////////////////////////////////////////// 13438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13441f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comvoid SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, 134561f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed const SkPaint* paint, bool deviceIsBitmapDevice) { 13468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint tmp; 134796fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 13488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint = &tmp; 13498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13504b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 13518926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com LOOPER_BEGIN_DRAWDEVICE(*paint, SkDrawFilter::kBitmap_Type) 13528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 13531f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* dstDev = iter.fDevice; 135476dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com paint = &looper.paint(); 135576dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkImageFilter* filter = paint->getImageFilter(); 135676dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkIPoint pos = { x - iter.getX(), y - iter.getY() }; 13578926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com if (filter && !dstDev->canHandleImageFilter(filter)) { 135888d064d0e481949184305c7b1d6b282dddffac39reed SkImageFilter::DeviceProxy proxy(dstDev); 135976dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkBitmap dst; 13606776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org SkIPoint offset = SkIPoint::Make(0, 0); 1361b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com const SkBitmap& src = srcDev->accessBitmap(false); 1362fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org SkMatrix matrix = *iter.fMatrix; 1363d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org matrix.postTranslate(SkIntToScalar(-pos.x()), SkIntToScalar(-pos.y())); 13644cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org SkIRect clipBounds = SkIRect::MakeWH(srcDev->width(), srcDev->height()); 1365be129b26f13d575fd6b396c6ae759838ecc9bd1asenorblanco SkAutoTUnref<SkImageFilter::Cache> cache(dstDev->getImageFilterCache()); 1366c9b5f8b1522e72449d704d30ed6aee4fc6211ee8reed SkImageFilter::Context ctx(matrix, clipBounds, cache.get(), 1367c9b5f8b1522e72449d704d30ed6aee4fc6211ee8reed SkImageFilter::kApprox_SizeConstraint); 13684cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org if (filter->filterImage(&proxy, src, ctx, &dst, &offset)) { 13695efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com SkPaint tmpUnfiltered(*paint); 137096fcdcc219d2a0d3579719b84b28bede76efba64halcanary tmpUnfiltered.setImageFilter(nullptr); 13716776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org dstDev->drawSprite(iter, dst, pos.x() + offset.x(), pos.y() + offset.y(), 13726776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org tmpUnfiltered); 137376dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } 137461f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed } else if (deviceIsBitmapDevice) { 13759572a10c9a6a868bbb8f71d7806d0a45f183333freed const SkBitmap& src = static_cast<SkBitmapDevice*>(srcDev)->fBitmap; 137661f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed dstDev->drawSprite(iter, src, pos.x(), pos.y(), *paint); 137776dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } else { 1378b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com dstDev->drawDevice(iter, srcDev, pos.x(), pos.y(), *paint); 137976dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } 13808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13814e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 13828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 138441af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawSprite(const SkBitmap& bitmap, int x, int y, const SkPaint* paint) { 13850acf1b4b3645772d220c720313821bac389751b5reed if (gTreatSpriteAsBitmap) { 13860acf1b4b3645772d220c720313821bac389751b5reed this->save(); 13870acf1b4b3645772d220c720313821bac389751b5reed this->resetMatrix(); 13880acf1b4b3645772d220c720313821bac389751b5reed this->drawBitmap(bitmap, SkIntToScalar(x), SkIntToScalar(y), paint); 13890acf1b4b3645772d220c720313821bac389751b5reed this->restore(); 13900acf1b4b3645772d220c720313821bac389751b5reed return; 13910acf1b4b3645772d220c720313821bac389751b5reed } 13920acf1b4b3645772d220c720313821bac389751b5reed 13939881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawSprite()"); 139450b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org if (bitmap.drawsNothing()) { 13958926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com return; 13968926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 139750b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org SkDEBUGCODE(bitmap.validate();) 1398fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 13998926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkPaint tmp; 140096fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 14018926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com paint = &tmp; 14028926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 1403fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 14048926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com LOOPER_BEGIN_DRAWDEVICE(*paint, SkDrawFilter::kBitmap_Type) 1405fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 14068926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com while (iter.next()) { 14078926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com paint = &looper.paint(); 14088926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkImageFilter* filter = paint->getImageFilter(); 14098926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkIPoint pos = { x - iter.getX(), y - iter.getY() }; 14108926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com if (filter && !iter.fDevice->canHandleImageFilter(filter)) { 141188d064d0e481949184305c7b1d6b282dddffac39reed SkImageFilter::DeviceProxy proxy(iter.fDevice); 14128926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkBitmap dst; 14136776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org SkIPoint offset = SkIPoint::Make(0, 0); 1414fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org SkMatrix matrix = *iter.fMatrix; 1415d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org matrix.postTranslate(SkIntToScalar(-pos.x()), SkIntToScalar(-pos.y())); 1416f622a6c8fd176acf9944de8df00d7f0bb56b67d3halcanary const SkIRect clipBounds = bitmap.bounds(); 1417be129b26f13d575fd6b396c6ae759838ecc9bd1asenorblanco SkAutoTUnref<SkImageFilter::Cache> cache(iter.fDevice->getImageFilterCache()); 1418c9b5f8b1522e72449d704d30ed6aee4fc6211ee8reed SkImageFilter::Context ctx(matrix, clipBounds, cache.get(), 1419c9b5f8b1522e72449d704d30ed6aee4fc6211ee8reed SkImageFilter::kApprox_SizeConstraint); 14204cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org if (filter->filterImage(&proxy, bitmap, ctx, &dst, &offset)) { 14215efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com SkPaint tmpUnfiltered(*paint); 142296fcdcc219d2a0d3579719b84b28bede76efba64halcanary tmpUnfiltered.setImageFilter(nullptr); 14236776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org iter.fDevice->drawSprite(iter, dst, pos.x() + offset.x(), pos.y() + offset.y(), 14245efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com tmpUnfiltered); 14258926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 14268926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } else { 14278926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com iter.fDevice->drawSprite(iter, bitmap, pos.x(), pos.y(), *paint); 14288926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 14298926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 14308926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com LOOPER_END 14318926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com} 14328926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 14338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////// 143492362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::translate(SkScalar dx, SkScalar dy) { 1435d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1436d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setTranslate(dx, dy); 1437d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 14388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 144092362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::scale(SkScalar sx, SkScalar sy) { 1441d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1442d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setScale(sx, sy); 1443d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 14448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 144692362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::rotate(SkScalar degrees) { 1447d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1448d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setRotate(degrees); 1449d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 14508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 145292362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::skew(SkScalar sx, SkScalar sy) { 1453d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1454d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setSkew(sx, sy); 1455d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 145644c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org} 145744c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 145892362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::concat(const SkMatrix& matrix) { 1459d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org if (matrix.isIdentity()) { 1460d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org return; 1461d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org } 1462d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org 14632ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 14648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1465c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 14661f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix.preConcat(matrix); 146744c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 146844c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org this->didConcat(matrix); 146944c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org} 147044c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 147186a17e7716c8db858e219a46b9db3817bb770beereedvoid SkCanvas::setMatrix(const SkMatrix& matrix) { 147286a17e7716c8db858e219a46b9db3817bb770beereed this->checkForDeferredSave(); 14738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1474c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 14751f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix = matrix; 147644c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org this->didSetMatrix(matrix); 14778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::resetMatrix() { 14808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 14814b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 14828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.reset(); 14838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->setMatrix(matrix); 14848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 14878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1488759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { 14892ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 14908f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 14918f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(rect, op, edgeStyle); 14928f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 14938f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 14948f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 1495da17f758442f16747af39f8fbaed9c097048519creed@google.com#ifdef SK_ENABLE_CLIP_QUICKREJECT 1496da17f758442f16747af39f8fbaed9c097048519creed@google.com if (SkRegion::kIntersect_Op == op) { 14971f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fRasterClip.isEmpty()) { 1498da17f758442f16747af39f8fbaed9c097048519creed@google.com return false; 1499da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1500da17f758442f16747af39f8fbaed9c097048519creed@google.com 15013b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(rect)) { 1502da17f758442f16747af39f8fbaed9c097048519creed@google.com fDeviceCMDirty = true; 1503c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 1504da17f758442f16747af39f8fbaed9c097048519creed@google.com 1505687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipEmpty(); 15061f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.setEmpty(); 1507da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1508da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1509da17f758442f16747af39f8fbaed9c097048519creed@google.com#endif 1510da17f758442f16747af39f8fbaed9c097048519creed@google.com 15115c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com AutoValidateClip avc(this); 15125c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 15138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1514c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 15158f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!fAllowSoftClip) { 15168f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com edgeStyle = kHard_ClipEdgeStyle; 15178f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 15188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 15191f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fMatrix.rectStaysRect()) { 1520123671901abfa595d09ca789b487c4bc7c1f7cbcrobertphillips@google.com // for these simpler matrices, we can stay a rect even after applying 152198de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // the matrix. This means we don't have to a) make a path, and b) tell 152298de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // the region code to scan-convert the path, only to discover that it 152398de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // is really just a rect. 15248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 15258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 15261f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix.mapRect(&r, rect); 1527687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipDevRect(r, op, kSoft_ClipEdgeStyle == edgeStyle); 1528d954498c01ccf0417feacf89e45d0c62a06a813breed fMCRec->fRasterClip.op(r, this->getBaseLayerSize(), op, kSoft_ClipEdgeStyle == edgeStyle); 15298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 1530123671901abfa595d09ca789b487c4bc7c1f7cbcrobertphillips@google.com // since we're rotated or some such thing, we convert the rect to a path 153198de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // and clip against that, since it can handle any matrix. However, to 153298de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // avoid recursion in the case where we are subclassed (e.g. Pictures) 153398de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // we explicitly call "our" version of clipPath. 15348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath path; 15358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 15368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.addRect(rect); 15378f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->SkCanvas::onClipPath(path, op, edgeStyle); 15388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 15398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 15408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 154173e714eb766617ce06757829a3c0b345c7963faareedstatic void rasterclip_path(SkRasterClip* rc, const SkCanvas* canvas, const SkPath& devPath, 154273e714eb766617ce06757829a3c0b345c7963faareed SkRegion::Op op, bool doAA) { 1543d64c9487135094c83f658319f53ea2005ecc08b2reed rc->op(devPath, canvas->getBaseLayerSize(), op, doAA); 1544819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com} 1545819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 1546759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) { 15472ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 15488f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 15494ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (rrect.isRect()) { 15508f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(rrect.getBounds(), op, edgeStyle); 15518f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } else { 15528f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRRect(rrect, op, edgeStyle); 15534ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 15548f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 155514e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 15568f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 155714e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org SkRRect transformedRRect; 15581f836ee096bb988adef4b9757b2629c7afeda36dreed if (rrect.transform(fMCRec->fMatrix, &transformedRRect)) { 155914e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org AutoValidateClip avc(this); 156014e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 156114e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org fDeviceCMDirty = true; 156214e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org fCachedLocalClipBoundsDirty = true; 15638f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!fAllowSoftClip) { 15648f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com edgeStyle = kHard_ClipEdgeStyle; 15658f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 156614e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 1567687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipDevRRect(transformedRRect, op, kSoft_ClipEdgeStyle == edgeStyle); 156814e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 156914e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org SkPath devPath; 157014e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org devPath.addRRect(transformedRRect); 157114e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 157273e714eb766617ce06757829a3c0b345c7963faareed rasterclip_path(&fMCRec->fRasterClip, this, devPath, op, kSoft_ClipEdgeStyle == edgeStyle); 15738f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com return; 157414e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org } 157514e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 157614e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org SkPath path; 157714e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org path.addRRect(rrect); 157814e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org // call the non-virtual version 15798f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->SkCanvas::onClipPath(path, op, edgeStyle); 15804ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 15814ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 1582759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { 15832ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 15848f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 15858f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com SkRect r; 15868f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!path.isInverseFillType() && path.isRect(&r)) { 15878f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(r, op, edgeStyle); 15888f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } else { 15898f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipPath(path, op, edgeStyle); 15908f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 15918f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 15928f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 15938f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 1594da17f758442f16747af39f8fbaed9c097048519creed@google.com#ifdef SK_ENABLE_CLIP_QUICKREJECT 1595da17f758442f16747af39f8fbaed9c097048519creed@google.com if (SkRegion::kIntersect_Op == op && !path.isInverseFillType()) { 15961f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fRasterClip.isEmpty()) { 1597da17f758442f16747af39f8fbaed9c097048519creed@google.com return false; 1598da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1599fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 16003b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(path.getBounds())) { 1601da17f758442f16747af39f8fbaed9c097048519creed@google.com fDeviceCMDirty = true; 1602c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 1603fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1604687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipEmpty(); 16051f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.setEmpty(); 1606da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1607da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1608da17f758442f16747af39f8fbaed9c097048519creed@google.com#endif 1609da17f758442f16747af39f8fbaed9c097048519creed@google.com 16105c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com AutoValidateClip avc(this); 16115c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 16128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1613c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 16148f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!fAllowSoftClip) { 16158f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com edgeStyle = kHard_ClipEdgeStyle; 16168f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 16178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath devPath; 16191f836ee096bb988adef4b9757b2629c7afeda36dreed path.transform(fMCRec->fMatrix, &devPath); 16208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1621fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // Check if the transfomation, or the original path itself 1622fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // made us empty. Note this can also happen if we contained NaN 1623fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // values. computing the bounds detects this, and will set our 1624fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // bounds to empty if that is the case. (see SkRect::set(pts, count)) 1625fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com if (devPath.getBounds().isEmpty()) { 1626fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // resetting the path will remove any NaN or other wanky values 1627fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // that might upset our scan converter. 1628fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com devPath.reset(); 1629fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com } 1630fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com 16315c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // if we called path.swap() we could avoid a deep copy of this path 1632687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipDevPath(devPath, op, kSoft_ClipEdgeStyle == edgeStyle); 16335c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 163445a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com if (fAllowSimplifyClip) { 16351a481fe4bf632ed4f76cb337691236fabfd4ab03fmalita bool clipIsAA = getClipStack()->asPath(&devPath); 16361a481fe4bf632ed4f76cb337691236fabfd4ab03fmalita if (clipIsAA) { 16371a481fe4bf632ed4f76cb337691236fabfd4ab03fmalita edgeStyle = kSoft_ClipEdgeStyle; 163845a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com } 16391a481fe4bf632ed4f76cb337691236fabfd4ab03fmalita 164045a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com op = SkRegion::kReplace_Op; 164145a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com } 164245a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com 164373e714eb766617ce06757829a3c0b345c7963faareed rasterclip_path(&fMCRec->fRasterClip, this, devPath, op, edgeStyle); 16448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1646759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipRegion(const SkRegion& rgn, SkRegion::Op op) { 16472ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 16488f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRegion(rgn, op); 16498f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 16508f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 16518f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipRegion(const SkRegion& rgn, SkRegion::Op op) { 16525c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com AutoValidateClip avc(this); 16535c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 16548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1655c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 16568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16575c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // todo: signal fClipStack that we have a region, and therefore (I guess) 16585c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // we have to ignore it, and use the region directly? 1659687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipDevRect(rgn.getBounds(), op); 16605c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 16611f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fRasterClip.op(rgn, op); 16628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1664819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com#ifdef SK_DEBUG 1665819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.comvoid SkCanvas::validateClip() const { 1666819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com // construct clipRgn from the clipstack 16671f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com const SkBaseDevice* device = this->getDevice(); 1668ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com if (!device) { 16695c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org SkASSERT(this->isClipEmpty()); 1670ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com return; 1671ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com } 1672ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com 1673819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com SkIRect ir; 1674819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com ir.set(0, 0, device->width(), device->height()); 1675d954498c01ccf0417feacf89e45d0c62a06a813breed SkRasterClip tmpClip(ir, fConservativeRasterClip); 1676819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 1677687fa1c745febb57f42b0d5f03d7c1f4be2530careed SkClipStack::B2TIter iter(*fClipStack); 16788182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const SkClipStack::Element* element; 167996fcdcc219d2a0d3579719b84b28bede76efba64halcanary while ((element = iter.next()) != nullptr) { 16808182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com switch (element->getType()) { 16818182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kRect_Type: 16828182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com element->getRect().round(&ir); 16838182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com tmpClip.op(ir, element->getOp()); 16848182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 16858182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kEmpty_Type: 16868182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com tmpClip.setEmpty(); 16878182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 16889cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org default: { 16899cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org SkPath path; 16909cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org element->asPath(&path); 169173e714eb766617ce06757829a3c0b345c7963faareed rasterclip_path(&tmpClip, this, path, element->getOp(), element->isAA()); 16929cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org break; 16939cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org } 1694819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com } 1695819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com } 1696819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com} 1697819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com#endif 1698819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 169990c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.comvoid SkCanvas::replayClips(ClipVisitor* visitor) const { 1700687fa1c745febb57f42b0d5f03d7c1f4be2530careed SkClipStack::B2TIter iter(*fClipStack); 17018182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const SkClipStack::Element* element; 17028182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com 170396fcdcc219d2a0d3579719b84b28bede76efba64halcanary while ((element = iter.next()) != nullptr) { 1704c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita element->replay(visitor); 170590c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com } 170690c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com} 170790c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com 17085c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com/////////////////////////////////////////////////////////////////////////////// 17095c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 1710754de5f65b466f721d952a379194cc94de376f42reed@google.combool SkCanvas::isClipEmpty() const { 17111f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.isEmpty(); 1712754de5f65b466f721d952a379194cc94de376f42reed@google.com} 1713754de5f65b466f721d952a379194cc94de376f42reed@google.com 17145c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.orgbool SkCanvas::isClipRect() const { 17151f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.isRect(); 17165c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org} 17175c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org 17183b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::quickReject(const SkRect& rect) const { 17191607863b608b7db6c813228768ed5d72997bbc82reed@google.com if (!rect.isFinite()) 1720116b2bcd2c4c4d4670c7b7e2ea597414713c37fbwjmaclean@chromium.org return true; 1721116b2bcd2c4c4d4670c7b7e2ea597414713c37fbwjmaclean@chromium.org 17221f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fRasterClip.isEmpty()) { 17238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 17248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 17258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17261f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fMatrix.hasPerspective()) { 1727a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com SkRect dst; 17281f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix.mapRect(&dst, rect); 1729b07a94f1cba3976596ae1a7f23d8c2043ba353f3reed return !SkIRect::Intersects(dst.roundOut(), fMCRec->fRasterClip.getBounds()); 1730a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com } else { 1731c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com const SkRect& clipR = this->getLocalClipBounds(); 1732d252db03d9650013b545ef9781fe993c07f8f314reed@android.com 1733a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com // for speed, do the most likely reject compares first 1734c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com // TODO: should we use | instead, or compare all 4 at once? 1735c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com if (rect.fTop >= clipR.fBottom || rect.fBottom <= clipR.fTop) { 1736a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com return true; 1737a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com } 1738c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com if (rect.fLeft >= clipR.fRight || rect.fRight <= clipR.fLeft) { 1739a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com return true; 1740a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com } 1741a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com return false; 17428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 17438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17453b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::quickReject(const SkPath& path) const { 17463b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com return path.isEmpty() || this->quickReject(path.getBounds()); 17478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17493b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::getClipBounds(SkRect* bounds) const { 1750bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect ibounds; 17518f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!this->getClipDeviceBounds(&ibounds)) { 17528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 17538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 17548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1755d9c0f0b57affec7a472879c5919acac6637d926areed@android.com SkMatrix inverse; 1756d9c0f0b57affec7a472879c5919acac6637d926areed@android.com // if we can't invert the CTM, we can't return local clip bounds 17571f836ee096bb988adef4b9757b2629c7afeda36dreed if (!fMCRec->fMatrix.invert(&inverse)) { 175872dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com if (bounds) { 175972dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com bounds->setEmpty(); 176072dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com } 1761d9c0f0b57affec7a472879c5919acac6637d926areed@android.com return false; 1762d9c0f0b57affec7a472879c5919acac6637d926areed@android.com } 1763d9c0f0b57affec7a472879c5919acac6637d926areed@android.com 176449f085dddff10473b6ebf832a974288300224e60bsalomon if (bounds) { 1765bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkRect r; 17663b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com // adjust it outwards in case we are antialiasing 17673b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com const int inset = 1; 1768fa4d5bd09f8f1a4a92b5ae0324800dd672760898reed@google.com 17698f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com r.iset(ibounds.fLeft - inset, ibounds.fTop - inset, 17708f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com ibounds.fRight + inset, ibounds.fBottom + inset); 17718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inverse.mapRect(bounds, r); 17728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 17738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 17748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1776bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.combool SkCanvas::getClipDeviceBounds(SkIRect* bounds) const { 17771f836ee096bb988adef4b9757b2629c7afeda36dreed const SkRasterClip& clip = fMCRec->fRasterClip; 1778bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (clip.isEmpty()) { 1779bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (bounds) { 1780bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com bounds->setEmpty(); 1781bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1782bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com return false; 1783bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1784bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com 178549f085dddff10473b6ebf832a974288300224e60bsalomon if (bounds) { 1786bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com *bounds = clip.getBounds(); 1787bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1788bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com return true; 1789bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com} 1790bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com 17918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkMatrix& SkCanvas::getTotalMatrix() const { 17921f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fMatrix; 17938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17955c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.orgconst SkRegion& SkCanvas::internal_private_getTotalClip() const { 17961f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.forceGetBW(); 17975c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org} 17985c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org 17999c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.comGrRenderTarget* SkCanvas::internal_private_accessTopLayerRenderTarget() { 18009c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com SkBaseDevice* dev = this->getTopDevice(); 180196fcdcc219d2a0d3579719b84b28bede76efba64halcanary return dev ? dev->accessRenderTarget() : nullptr; 18029c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 18039c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1804644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.orgGrContext* SkCanvas::getGrContext() { 1805644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#if SK_SUPPORT_GPU 1806644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org SkBaseDevice* device = this->getTopDevice(); 180749f085dddff10473b6ebf832a974288300224e60bsalomon if (device) { 1808644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org GrRenderTarget* renderTarget = device->accessRenderTarget(); 180949f085dddff10473b6ebf832a974288300224e60bsalomon if (renderTarget) { 1810644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org return renderTarget->getContext(); 1811644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org } 1812644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org } 1813644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#endif 1814644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org 181596fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 1816644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org 1817644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org} 1818e97f0856a8044866b12527819d14cdfbcdfd96f2bsalomon@google.com 1819ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.orgvoid SkCanvas::drawDRRect(const SkRRect& outer, const SkRRect& inner, 1820ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkPaint& paint) { 18219881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawDRRect()"); 1822ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (outer.isEmpty()) { 1823ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 1824ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 1825ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (inner.isEmpty()) { 1826ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->drawRRect(outer, paint); 1827ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 1828ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 1829ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 1830ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // We don't have this method (yet), but technically this is what we should 1831ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // be able to assert... 1832ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // SkASSERT(outer.contains(inner)); 1833ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // 1834ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // For now at least check for containment of bounds 1835ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org SkASSERT(outer.getBounds().contains(inner.getBounds())); 1836ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 1837ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->onDrawDRRect(outer, inner, paint); 1838ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org} 1839ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 184041af966ab338e95eee81ab618ab28195075338f7reed// These need to stop being virtual -- clients need to override the onDraw... versions 184141af966ab338e95eee81ab618ab28195075338f7reed 184241af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawPaint(const SkPaint& paint) { 184341af966ab338e95eee81ab618ab28195075338f7reed this->onDrawPaint(paint); 184441af966ab338e95eee81ab618ab28195075338f7reed} 184541af966ab338e95eee81ab618ab28195075338f7reed 184641af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawRect(const SkRect& r, const SkPaint& paint) { 184741af966ab338e95eee81ab618ab28195075338f7reed this->onDrawRect(r, paint); 184841af966ab338e95eee81ab618ab28195075338f7reed} 184941af966ab338e95eee81ab618ab28195075338f7reed 185041af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawOval(const SkRect& r, const SkPaint& paint) { 185141af966ab338e95eee81ab618ab28195075338f7reed this->onDrawOval(r, paint); 185241af966ab338e95eee81ab618ab28195075338f7reed} 185341af966ab338e95eee81ab618ab28195075338f7reed 185441af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) { 185541af966ab338e95eee81ab618ab28195075338f7reed this->onDrawRRect(rrect, paint); 185641af966ab338e95eee81ab618ab28195075338f7reed} 185741af966ab338e95eee81ab618ab28195075338f7reed 185841af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint) { 185941af966ab338e95eee81ab618ab28195075338f7reed this->onDrawPoints(mode, count, pts, paint); 186041af966ab338e95eee81ab618ab28195075338f7reed} 186141af966ab338e95eee81ab618ab28195075338f7reed 186241af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawVertices(VertexMode vmode, int vertexCount, const SkPoint vertices[], 186341af966ab338e95eee81ab618ab28195075338f7reed const SkPoint texs[], const SkColor colors[], SkXfermode* xmode, 186441af966ab338e95eee81ab618ab28195075338f7reed const uint16_t indices[], int indexCount, const SkPaint& paint) { 186541af966ab338e95eee81ab618ab28195075338f7reed this->onDrawVertices(vmode, vertexCount, vertices, texs, colors, xmode, 186641af966ab338e95eee81ab618ab28195075338f7reed indices, indexCount, paint); 186741af966ab338e95eee81ab618ab28195075338f7reed} 186841af966ab338e95eee81ab618ab28195075338f7reed 186941af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawPath(const SkPath& path, const SkPaint& paint) { 187041af966ab338e95eee81ab618ab28195075338f7reed this->onDrawPath(path, paint); 187141af966ab338e95eee81ab618ab28195075338f7reed} 187241af966ab338e95eee81ab618ab28195075338f7reed 1873a85d4d0814818e4ddabb9237da209d61d6cd5854reedvoid SkCanvas::drawImage(const SkImage* image, SkScalar x, SkScalar y, const SkPaint* paint) { 1874a85d4d0814818e4ddabb9237da209d61d6cd5854reed this->onDrawImage(image, x, y, paint); 187541af966ab338e95eee81ab618ab28195075338f7reed} 187641af966ab338e95eee81ab618ab28195075338f7reed 1877e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst, 1878e47829b6b1eeb6b0c97ccb3df3016d197046824creed const SkPaint* paint, SrcRectConstraint constraint) { 1879e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (dst.isEmpty() || src.isEmpty()) { 1880e47829b6b1eeb6b0c97ccb3df3016d197046824creed return; 1881e47829b6b1eeb6b0c97ccb3df3016d197046824creed } 1882e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->onDrawImageRect(image, &src, dst, paint, constraint); 1883e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 188441af966ab338e95eee81ab618ab28195075338f7reed 188584984efeb64787b88c5f8bd6929cfe2d58a3ba06reedvoid SkCanvas::drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst, 188684984efeb64787b88c5f8bd6929cfe2d58a3ba06reed const SkPaint* paint, SrcRectConstraint constraint) { 1887e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, SkRect::Make(isrc), dst, paint, constraint); 188884984efeb64787b88c5f8bd6929cfe2d58a3ba06reed} 188984984efeb64787b88c5f8bd6929cfe2d58a3ba06reed 1890e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint, 1891e47829b6b1eeb6b0c97ccb3df3016d197046824creed SrcRectConstraint constraint) { 1892e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, SkRect::MakeIWH(image->width(), image->height()), dst, paint, 1893e47829b6b1eeb6b0c97ccb3df3016d197046824creed constraint); 1894e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 1895e47829b6b1eeb6b0c97ccb3df3016d197046824creed 18964c21dc5ddf3b482293ed34eead876d8d61a662c3reedvoid SkCanvas::drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst, 18974c21dc5ddf3b482293ed34eead876d8d61a662c3reed const SkPaint* paint) { 18984c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (dst.isEmpty()) { 18994c21dc5ddf3b482293ed34eead876d8d61a662c3reed return; 19004c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 19014c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (!SkNinePatchIter::Valid(image->width(), image->height(), center)) { 1902e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, dst, paint); 19034c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 19044c21dc5ddf3b482293ed34eead876d8d61a662c3reed this->onDrawImageNine(image, center, dst, paint); 19054c21dc5ddf3b482293ed34eead876d8d61a662c3reed} 19064c21dc5ddf3b482293ed34eead876d8d61a662c3reed 190741af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar dx, SkScalar dy, const SkPaint* paint) { 19084c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (bitmap.drawsNothing()) { 19092df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson return; 19102df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson } 191141af966ab338e95eee81ab618ab28195075338f7reed this->onDrawBitmap(bitmap, dx, dy, paint); 191241af966ab338e95eee81ab618ab28195075338f7reed} 191341af966ab338e95eee81ab618ab28195075338f7reed 1914e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst, 1915a5517e2b190a8083b38964972b031c13e99f1012reed const SkPaint* paint, SrcRectConstraint constraint) { 1916e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (bitmap.drawsNothing() || dst.isEmpty() || src.isEmpty()) { 1917a5517e2b190a8083b38964972b031c13e99f1012reed return; 1918a5517e2b190a8083b38964972b031c13e99f1012reed } 1919e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->onDrawBitmapRect(bitmap, &src, dst, paint, constraint); 192041af966ab338e95eee81ab618ab28195075338f7reed} 192141af966ab338e95eee81ab618ab28195075338f7reed 192284984efeb64787b88c5f8bd6929cfe2d58a3ba06reedvoid SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst, 192384984efeb64787b88c5f8bd6929cfe2d58a3ba06reed const SkPaint* paint, SrcRectConstraint constraint) { 1924e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, SkRect::Make(isrc), dst, paint, constraint); 1925e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 1926e47829b6b1eeb6b0c97ccb3df3016d197046824creed 1927e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint, 1928e47829b6b1eeb6b0c97ccb3df3016d197046824creed SrcRectConstraint constraint) { 1929e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, SkRect::MakeIWH(bitmap.width(), bitmap.height()), dst, paint, 1930e47829b6b1eeb6b0c97ccb3df3016d197046824creed constraint); 193184984efeb64787b88c5f8bd6929cfe2d58a3ba06reed} 193284984efeb64787b88c5f8bd6929cfe2d58a3ba06reed 193341af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst, 193441af966ab338e95eee81ab618ab28195075338f7reed const SkPaint* paint) { 19354c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (bitmap.drawsNothing() || dst.isEmpty()) { 19362df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson return; 19372df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson } 19384c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (!SkNinePatchIter::Valid(bitmap.width(), bitmap.height(), center)) { 1939a5517e2b190a8083b38964972b031c13e99f1012reed this->drawBitmapRect(bitmap, dst, paint); 19404c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 194141af966ab338e95eee81ab618ab28195075338f7reed this->onDrawBitmapNine(bitmap, center, dst, paint); 194241af966ab338e95eee81ab618ab28195075338f7reed} 194341af966ab338e95eee81ab618ab28195075338f7reed 194441af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawSprite(const SkBitmap& bitmap, int left, int top, const SkPaint* paint) { 19454c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (bitmap.drawsNothing()) { 19462df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson return; 19472df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson } 194841af966ab338e95eee81ab618ab28195075338f7reed this->onDrawSprite(bitmap, left, top, paint); 194941af966ab338e95eee81ab618ab28195075338f7reed} 195041af966ab338e95eee81ab618ab28195075338f7reed 195171c3c760a83123ee0b3127b8c65c6394ce541c50reedvoid SkCanvas::drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], 195271c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkColor colors[], int count, SkXfermode::Mode mode, 195371c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkRect* cull, const SkPaint* paint) { 195471c3c760a83123ee0b3127b8c65c6394ce541c50reed if (count <= 0) { 195571c3c760a83123ee0b3127b8c65c6394ce541c50reed return; 195671c3c760a83123ee0b3127b8c65c6394ce541c50reed } 195771c3c760a83123ee0b3127b8c65c6394ce541c50reed SkASSERT(atlas); 195871c3c760a83123ee0b3127b8c65c6394ce541c50reed SkASSERT(xform); 195971c3c760a83123ee0b3127b8c65c6394ce541c50reed SkASSERT(tex); 196071c3c760a83123ee0b3127b8c65c6394ce541c50reed this->onDrawAtlas(atlas, xform, tex, colors, count, mode, cull, paint); 196171c3c760a83123ee0b3127b8c65c6394ce541c50reed} 196271c3c760a83123ee0b3127b8c65c6394ce541c50reed 1963e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::legacy_drawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, 1964e47829b6b1eeb6b0c97ccb3df3016d197046824creed const SkPaint* paint, SrcRectConstraint constraint) { 1965e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (src) { 1966e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, *src, dst, paint, constraint); 1967e47829b6b1eeb6b0c97ccb3df3016d197046824creed } else { 1968e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, SkRect::MakeIWH(image->width(), image->height()), 1969e47829b6b1eeb6b0c97ccb3df3016d197046824creed dst, paint, constraint); 1970e47829b6b1eeb6b0c97ccb3df3016d197046824creed } 1971e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 1972e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::legacy_drawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, 1973e47829b6b1eeb6b0c97ccb3df3016d197046824creed const SkPaint* paint, SrcRectConstraint constraint) { 1974e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (src) { 1975e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, *src, dst, paint, constraint); 1976e47829b6b1eeb6b0c97ccb3df3016d197046824creed } else { 1977e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, SkRect::MakeIWH(bitmap.width(), bitmap.height()), 1978e47829b6b1eeb6b0c97ccb3df3016d197046824creed dst, paint, constraint); 1979e47829b6b1eeb6b0c97ccb3df3016d197046824creed } 1980e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 1981e47829b6b1eeb6b0c97ccb3df3016d197046824creed 19828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 19838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// These are the virtual drawing methods 19848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 19858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 198628361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.orgvoid SkCanvas::onDiscard() { 198749f085dddff10473b6ebf832a974288300224e60bsalomon if (fSurfaceBase) { 198828361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org fSurfaceBase->aboutToDraw(SkSurface::kDiscard_ContentChangeMode); 198928361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org } 199028361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org} 199128361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org 199241af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawPaint(const SkPaint& paint) { 19939881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPaint()"); 1994fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->internalDrawPaint(paint); 1995fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com} 1996fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com 1997fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.comvoid SkCanvas::internalDrawPaint(const SkPaint& paint) { 199896fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, SkDrawFilter::kPaint_Type, nullptr, false) 19998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 20014e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPaint(iter, looper.paint()); 20028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 20038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20044e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 20058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 20068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 200741af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[], 200841af966ab338e95eee81ab618ab28195075338f7reed const SkPaint& paint) { 20099881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT1("disabled-by-default-skia", "SkCanvas::drawPoints()", "count", static_cast<uint64_t>(count)); 20108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if ((long)count <= 0) { 20118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 20128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 20138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 201478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect r, storage; 201596fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 2016a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com if (paint.canComputeFastBounds()) { 2017a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com // special-case 2 points (common for drawing a single line) 2018a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com if (2 == count) { 2019a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com r.set(pts[0], pts[1]); 2020a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } else { 2021a8c7f7702fb4bbedb615031bc653c5cd161a038ecommit-bot@chromium.org r.set(pts, SkToInt(count)); 2022a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } 202387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastStrokeBounds(r, &storage))) { 202487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 202587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 202687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &r; 2027fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 2028a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com 202996fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkASSERT(pts != nullptr); 20308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 203178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPoint_Type, bounds) 20324b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 20338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 20344e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPoints(iter, mode, count, pts, looper.paint()); 20358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 20364b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 20374e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 20388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 20398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 204041af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawRect(const SkRect& r, const SkPaint& paint) { 20419881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRect()"); 204278cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 204396fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 20448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.canComputeFastBounds()) { 20458432808ad8898ac7137bc7ce1d9df6005e866401reed // Skia will draw an inverted rect, because it explicitly "sorts" it downstream. 20468432808ad8898ac7137bc7ce1d9df6005e866401reed // To prevent accidental rejecting at this stage, we have to sort it before we check. 20478432808ad8898ac7137bc7ce1d9df6005e866401reed SkRect tmp(r); 20488432808ad8898ac7137bc7ce1d9df6005e866401reed tmp.sort(); 20498432808ad8898ac7137bc7ce1d9df6005e866401reed 205087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(tmp, &storage))) { 205187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 205287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 205387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &r; 20548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 20554b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2056c83a29759a5c2966da5ab973e4fd90763e4c962breed LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, SkDrawFilter::kRect_Type, bounds, false) 20578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 20594e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawRect(iter, r, looper.paint()); 20608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 20618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20624e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 20638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 20648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 206541af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) { 20669881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawOval()"); 206778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 206896fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 20694ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (paint.canComputeFastBounds()) { 207087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(oval, &storage))) { 207187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 207287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 207387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &oval; 20744ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 2075306ab9d5de38f2a547fd1d69aedbe69b5c6617ccskia.committer@gmail.com 207678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, bounds) 207746d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com 207846d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com while (iter.next()) { 207946d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com iter.fDevice->drawOval(iter, oval, looper.paint()); 208046d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com } 208146d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com 208246d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com LOOPER_END 20834ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 20844ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 208541af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) { 20869881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRRect()"); 208778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 208896fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 20894ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (paint.canComputeFastBounds()) { 209087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(rrect.getBounds(), &storage))) { 209187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 209287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 209387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &rrect.getBounds(); 20944ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 20954ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 20964ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (rrect.isRect()) { 20974ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com // call the non-virtual version 20984ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->SkCanvas::drawRect(rrect.getBounds(), paint); 2099f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org return; 2100f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } else if (rrect.isOval()) { 21014ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com // call the non-virtual version 2102f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org this->SkCanvas::drawOval(rrect.getBounds(), paint); 2103f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org return; 21044ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 2105f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 210678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) 2107f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 2108f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org while (iter.next()) { 2109f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org iter.fDevice->drawRRect(iter, rrect, looper.paint()); 2110f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } 2111f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 2112f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org LOOPER_END 21134ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 21144ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 2115ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.orgvoid SkCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, 2116ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkPaint& paint) { 2117ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org SkRect storage; 211896fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 2119ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (paint.canComputeFastBounds()) { 212087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(outer.getBounds(), &storage))) { 212187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 212287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 212387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &outer.getBounds(); 2124ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 212525c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 2126ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) 212725c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 2128ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org while (iter.next()) { 2129ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org iter.fDevice->drawDRRect(iter, outer, inner, looper.paint()); 2130ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 213125c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 2132ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org LOOPER_END 2133ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org} 21344ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 213541af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) { 21369881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPath()"); 21379364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com if (!path.isFinite()) { 21389364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com return; 21399364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com } 21409364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com 214178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 214296fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 2143fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com if (!path.isInverseFillType() && paint.canComputeFastBounds()) { 214478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect& pathBounds = path.getBounds(); 214587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(pathBounds, &storage))) { 214687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 214787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 214887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &pathBounds; 21498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 21500b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org 21510b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org const SkRect& r = path.getBounds(); 21520b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org if (r.width() <= 0 && r.height() <= 0) { 21536803c219dd3be4a73e7bb5c4bb8a5b1f803624d0commit-bot@chromium.org if (path.isInverseFillType()) { 2154fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->internalDrawPaint(paint); 21556651a3238dd6affa4276ada42ab613abf1d42d1dcaryclark return; 2156fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 2157fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 21588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 215978cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, bounds) 21608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 21624e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPath(iter, path, looper.paint()); 21638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 21648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21654e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 21668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 21678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2168a85d4d0814818e4ddabb9237da209d61d6cd5854reedvoid SkCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, const SkPaint* paint) { 21699881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImage()"); 2170a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkRect bounds = SkRect::MakeXYWH(x, y, 2171a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkIntToScalar(image->width()), SkIntToScalar(image->height())); 217296fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 217387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect tmp = bounds; 217487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (paint) { 217587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco paint->computeFastBounds(tmp, &tmp); 217687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 217787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(tmp)) { 217887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 217987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 2180a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2181a85d4d0814818e4ddabb9237da209d61d6cd5854reed 2182a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkLazyPaint lazy; 218396fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 2184a85d4d0814818e4ddabb9237da209d61d6cd5854reed paint = lazy.init(); 2185a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2186a85d4d0814818e4ddabb9237da209d61d6cd5854reed 2187a85d4d0814818e4ddabb9237da209d61d6cd5854reed LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &bounds) 2188a85d4d0814818e4ddabb9237da209d61d6cd5854reed 2189a85d4d0814818e4ddabb9237da209d61d6cd5854reed while (iter.next()) { 2190a85d4d0814818e4ddabb9237da209d61d6cd5854reed iter.fDevice->drawImage(iter, image, x, y, looper.paint()); 2191a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2192a85d4d0814818e4ddabb9237da209d61d6cd5854reed 2193a85d4d0814818e4ddabb9237da209d61d6cd5854reed LOOPER_END 2194b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr} 2195b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 219641af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, 2197562fe4767cc73e08a4e039362bc0336aea66ecfbreed const SkPaint* paint, SrcRectConstraint constraint) { 21989881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImageRect()"); 2199a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkRect storage; 2200a85d4d0814818e4ddabb9237da209d61d6cd5854reed const SkRect* bounds = &dst; 220196fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 220287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco storage = dst; 220387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (paint) { 220487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco paint->computeFastBounds(dst, &storage); 220587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 220687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(storage)) { 220787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 220887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 2209a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2210a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkLazyPaint lazy; 221196fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 2212a85d4d0814818e4ddabb9237da209d61d6cd5854reed paint = lazy.init(); 2213a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2214a85d4d0814818e4ddabb9237da209d61d6cd5854reed 2215c83a29759a5c2966da5ab973e4fd90763e4c962breed LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, SkDrawFilter::kBitmap_Type, bounds, 2216c83a29759a5c2966da5ab973e4fd90763e4c962breed image->isOpaque()) 2217a85d4d0814818e4ddabb9237da209d61d6cd5854reed 2218a85d4d0814818e4ddabb9237da209d61d6cd5854reed while (iter.next()) { 2219a5517e2b190a8083b38964972b031c13e99f1012reed iter.fDevice->drawImageRect(iter, image, src, dst, looper.paint(), constraint); 2220a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2221a85d4d0814818e4ddabb9237da209d61d6cd5854reed 2222a85d4d0814818e4ddabb9237da209d61d6cd5854reed LOOPER_END 2223b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr} 2224b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 222541af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y, const SkPaint* paint) { 22269881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmap()"); 22278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(bitmap.validate();) 22288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 222933366974d43eae80e22284a2e445225c343859dareed if (bitmap.drawsNothing()) { 223033366974d43eae80e22284a2e445225c343859dareed return; 223133366974d43eae80e22284a2e445225c343859dareed } 223233366974d43eae80e22284a2e445225c343859dareed 223333366974d43eae80e22284a2e445225c343859dareed SkLazyPaint lazy; 223433366974d43eae80e22284a2e445225c343859dareed if (nullptr == paint) { 223533366974d43eae80e22284a2e445225c343859dareed paint = lazy.init(); 223633366974d43eae80e22284a2e445225c343859dareed } 223733366974d43eae80e22284a2e445225c343859dareed 223833366974d43eae80e22284a2e445225c343859dareed const SkMatrix matrix = SkMatrix::MakeTrans(x, y); 223933366974d43eae80e22284a2e445225c343859dareed 224033366974d43eae80e22284a2e445225c343859dareed SkRect storage; 224133366974d43eae80e22284a2e445225c343859dareed const SkRect* bounds = nullptr; 224233366974d43eae80e22284a2e445225c343859dareed if (paint->canComputeFastBounds()) { 224333366974d43eae80e22284a2e445225c343859dareed bitmap.getBounds(&storage); 224433366974d43eae80e22284a2e445225c343859dareed matrix.mapRect(&storage); 224587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect tmp = storage; 224687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint->computeFastBounds(tmp, &tmp))) { 224787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 224887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 224987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &storage; 22508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 22514b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 225233366974d43eae80e22284a2e445225c343859dareed LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) 225333366974d43eae80e22284a2e445225c343859dareed 225433366974d43eae80e22284a2e445225c343859dareed while (iter.next()) { 225533366974d43eae80e22284a2e445225c343859dareed iter.fDevice->drawBitmap(iter, bitmap, matrix, looper.paint()); 225633366974d43eae80e22284a2e445225c343859dareed } 225733366974d43eae80e22284a2e445225c343859dareed 225833366974d43eae80e22284a2e445225c343859dareed LOOPER_END 22598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 22608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22619987ec3791336bad6af5cbe513564786b2df55aareed@google.com// this one is non-virtual, so it can be called safely by other canvas apis 22627112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.comvoid SkCanvas::internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, 2263eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org const SkRect& dst, const SkPaint* paint, 2264a5517e2b190a8083b38964972b031c13e99f1012reed SrcRectConstraint constraint) { 226550b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org if (bitmap.drawsNothing() || dst.isEmpty()) { 22668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 22678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 226874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 226978cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 227078cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = &dst; 227196fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 227287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 227387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 227487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 22758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 22763d60812865bb034851da777a91413ab584929887reed@google.com 227733535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com SkLazyPaint lazy; 227896fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 227933535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com paint = lazy.init(); 22808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 22817064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 2282c83a29759a5c2966da5ab973e4fd90763e4c962breed LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, SkDrawFilter::kBitmap_Type, bounds, 2283c83a29759a5c2966da5ab973e4fd90763e4c962breed bitmap.isOpaque()) 22847064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 228533535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com while (iter.next()) { 2286562fe4767cc73e08a4e039362bc0336aea66ecfbreed iter.fDevice->drawBitmapRect(iter, bitmap, src, dst, looper.paint(), constraint); 2287f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 22887064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 228933535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com LOOPER_END 22908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 22918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 229241af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, 2293562fe4767cc73e08a4e039362bc0336aea66ecfbreed const SkPaint* paint, SrcRectConstraint constraint) { 22949881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmapRectToRect()"); 22959987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkDEBUGCODE(bitmap.validate();) 2296562fe4767cc73e08a4e039362bc0336aea66ecfbreed this->internalDrawBitmapRect(bitmap, src, dst, paint, constraint); 22979987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 22989987ec3791336bad6af5cbe513564786b2df55aareed@google.com 22994c21dc5ddf3b482293ed34eead876d8d61a662c3reedvoid SkCanvas::onDrawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst, 23004c21dc5ddf3b482293ed34eead876d8d61a662c3reed const SkPaint* paint) { 23014c21dc5ddf3b482293ed34eead876d8d61a662c3reed TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImageNine()"); 23024c21dc5ddf3b482293ed34eead876d8d61a662c3reed 23034c21dc5ddf3b482293ed34eead876d8d61a662c3reed SkRect storage; 23044c21dc5ddf3b482293ed34eead876d8d61a662c3reed const SkRect* bounds = &dst; 230596fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 230687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 230787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 230887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 23093d60812865bb034851da777a91413ab584929887reed@google.com } 23104c21dc5ddf3b482293ed34eead876d8d61a662c3reed 23114c21dc5ddf3b482293ed34eead876d8d61a662c3reed SkLazyPaint lazy; 231296fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 23134c21dc5ddf3b482293ed34eead876d8d61a662c3reed paint = lazy.init(); 23144c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 23154c21dc5ddf3b482293ed34eead876d8d61a662c3reed 23164c21dc5ddf3b482293ed34eead876d8d61a662c3reed LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) 23174c21dc5ddf3b482293ed34eead876d8d61a662c3reed 23184c21dc5ddf3b482293ed34eead876d8d61a662c3reed while (iter.next()) { 23194c21dc5ddf3b482293ed34eead876d8d61a662c3reed iter.fDevice->drawImageNine(iter, image, center, dst, looper.paint()); 23209987ec3791336bad6af5cbe513564786b2df55aareed@google.com } 23214c21dc5ddf3b482293ed34eead876d8d61a662c3reed 23224c21dc5ddf3b482293ed34eead876d8d61a662c3reed LOOPER_END 23239987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 23249987ec3791336bad6af5cbe513564786b2df55aareed@google.com 232541af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst, 232641af966ab338e95eee81ab618ab28195075338f7reed const SkPaint* paint) { 23279881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmapNine()"); 23289987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkDEBUGCODE(bitmap.validate();) 23299987ec3791336bad6af5cbe513564786b2df55aareed@google.com 23304c21dc5ddf3b482293ed34eead876d8d61a662c3reed SkRect storage; 23314c21dc5ddf3b482293ed34eead876d8d61a662c3reed const SkRect* bounds = &dst; 233296fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 233387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 233487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 233587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 23364c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 23374c21dc5ddf3b482293ed34eead876d8d61a662c3reed 23384c21dc5ddf3b482293ed34eead876d8d61a662c3reed SkLazyPaint lazy; 233996fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 23404c21dc5ddf3b482293ed34eead876d8d61a662c3reed paint = lazy.init(); 23414c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 23424c21dc5ddf3b482293ed34eead876d8d61a662c3reed 23434c21dc5ddf3b482293ed34eead876d8d61a662c3reed LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) 23444c21dc5ddf3b482293ed34eead876d8d61a662c3reed 23454c21dc5ddf3b482293ed34eead876d8d61a662c3reed while (iter.next()) { 23464c21dc5ddf3b482293ed34eead876d8d61a662c3reed iter.fDevice->drawBitmapNine(iter, bitmap, center, dst, looper.paint()); 23474c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 23484c21dc5ddf3b482293ed34eead876d8d61a662c3reed 23494c21dc5ddf3b482293ed34eead876d8d61a662c3reed LOOPER_END 23509987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 23519987ec3791336bad6af5cbe513564786b2df55aareed@google.com 2352f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.comclass SkDeviceFilteredPaint { 2353f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.compublic: 23541f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkDeviceFilteredPaint(SkBaseDevice* device, const SkPaint& paint) { 2355112e7e277702e104357f2d44742253ee1b0109acfmalita uint32_t filteredFlags = device->filterTextFlags(paint); 2356112e7e277702e104357f2d44742253ee1b0109acfmalita if (filteredFlags != paint.getFlags()) { 2357a076e9be17654a60310e72c4f70fcd5337f56dbfreed@google.com SkPaint* newPaint = fLazy.set(paint); 2358112e7e277702e104357f2d44742253ee1b0109acfmalita newPaint->setFlags(filteredFlags); 2359f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com fPaint = newPaint; 2360f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } else { 2361f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com fPaint = &paint; 2362f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } 2363f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } 2364f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 2365f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com const SkPaint& paint() const { return *fPaint; } 2366f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 2367f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.comprivate: 23682c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint* fPaint; 23692c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkLazyPaint fLazy; 2370f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com}; 2371f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 237252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.comvoid SkCanvas::DrawRect(const SkDraw& draw, const SkPaint& paint, 237352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com const SkRect& r, SkScalar textSize) { 237417b78946096265d80215a6c946286ecaa35ea7edepoger@google.com if (paint.getStyle() == SkPaint::kFill_Style) { 237552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com draw.fDevice->drawRect(draw, r, paint); 237652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } else { 237752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPaint p(paint); 237817b78946096265d80215a6c946286ecaa35ea7edepoger@google.com p.setStrokeWidth(SkScalarMul(textSize, paint.getStrokeWidth())); 237952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com draw.fDevice->drawRect(draw, r, p); 238052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 238152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com} 238252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 238352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.comvoid SkCanvas::DrawTextDecorations(const SkDraw& draw, const SkPaint& paint, 238452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com const char text[], size_t byteLength, 238552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar x, SkScalar y) { 238696fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkASSERT(byteLength == 0 || text != nullptr); 238752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 238852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com // nothing to draw 238996fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (text == nullptr || byteLength == 0 || 239052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com draw.fClip->isEmpty() || 239196fcdcc219d2a0d3579719b84b28bede76efba64halcanary (paint.getAlpha() == 0 && paint.getXfermode() == nullptr)) { 239252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com return; 239352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 239452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 239552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar width = 0; 239652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPoint start; 239752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 239852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.set(0, 0); // to avoid warning 239952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (paint.getFlags() & (SkPaint::kUnderlineText_Flag | 240052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPaint::kStrikeThruText_Flag)) { 240152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com width = paint.measureText(text, byteLength); 240252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 240352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar offsetX = 0; 240452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (paint.getTextAlign() == SkPaint::kCenter_Align) { 240552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com offsetX = SkScalarHalf(width); 240652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } else if (paint.getTextAlign() == SkPaint::kRight_Align) { 240752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com offsetX = width; 240852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 240952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.set(x - offsetX, y); 241052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 241152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 241252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (0 == width) { 241352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com return; 241452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 241552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 241652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com uint32_t flags = paint.getFlags(); 241752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 241852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (flags & (SkPaint::kUnderlineText_Flag | 241952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPaint::kStrikeThruText_Flag)) { 242052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar textSize = paint.getTextSize(); 242152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar height = SkScalarMul(textSize, kStdUnderline_Thickness); 242252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkRect r; 242352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 242452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fLeft = start.fX; 242552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fRight = start.fX + width; 242652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 242752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (flags & SkPaint::kUnderlineText_Flag) { 242852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar offset = SkScalarMulAdd(textSize, kStdUnderline_Offset, 242952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.fY); 243052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fTop = offset; 243152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fBottom = offset + height; 243252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com DrawRect(draw, paint, r, textSize); 243352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 243452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (flags & SkPaint::kStrikeThruText_Flag) { 243552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar offset = SkScalarMulAdd(textSize, kStdStrikeThru_Offset, 243652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.fY); 243752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fTop = offset; 243852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fBottom = offset + height; 243952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com DrawRect(draw, paint, r, textSize); 244052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 244152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 244252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com} 244352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 2444e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 2445e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 244696fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 24478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 24494e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 2450f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com iter.fDevice->drawText(iter, text, byteLength, x, y, dfp.paint()); 245152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com DrawTextDecorations(iter, dfp.paint(), 245252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com static_cast<const char*>(text), byteLength, x, y); 24538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 24548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24554e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 24568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2458e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], 2459e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 246005c4a4322e7d4f3417b7df33825bab8603d52051fmalita SkPoint textOffset = SkPoint::Make(0, 0); 246105c4a4322e7d4f3417b7df33825bab8603d52051fmalita 246296fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 246387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 24648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 24654e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 246605c4a4322e7d4f3417b7df33825bab8603d52051fmalita iter.fDevice->drawPosText(iter, text, byteLength, &pos->fX, 2, textOffset, 2467f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com dfp.paint()); 24688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2469b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 24704e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 24718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2473e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], 2474e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com SkScalar constY, const SkPaint& paint) { 247505c4a4322e7d4f3417b7df33825bab8603d52051fmalita 247605c4a4322e7d4f3417b7df33825bab8603d52051fmalita SkPoint textOffset = SkPoint::Make(0, constY); 247705c4a4322e7d4f3417b7df33825bab8603d52051fmalita 247896fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 247987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 24808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 24814e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 248205c4a4322e7d4f3417b7df33825bab8603d52051fmalita iter.fDevice->drawPosText(iter, text, byteLength, xpos, 1, textOffset, 2483f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com dfp.paint()); 24848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2485b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 24864e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 24878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2489e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 2490e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkMatrix* matrix, const SkPaint& paint) { 249196fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 249287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 24938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 24948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawTextOnPath(iter, text, byteLength, path, 24954e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com matrix, looper.paint()); 24968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2497b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 2498945ec3a2bec668ca845071a65df8ec55e8f43819commit-bot@chromium.org LOOPER_END 24994325d114a5679e46f25ae75b0e43547fd7694998commit-bot@chromium.org} 25004325d114a5679e46f25ae75b0e43547fd7694998commit-bot@chromium.org 250100d5c2c6523321d25b32905ff4822f083a4173eefmalitavoid SkCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 250200d5c2c6523321d25b32905ff4822f083a4173eefmalita const SkPaint& paint) { 25037ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita 250485d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita SkRect storage; 250596fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 250619653d1d004610b4ba07ce563a5701164e120e45fmalita if (paint.canComputeFastBounds()) { 250785d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita storage = blob->bounds().makeOffset(x, y); 250887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect tmp; 250987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(storage, &tmp))) { 251087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 251187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 251287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &storage; 25137ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita } 25147ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita 2515024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita // We cannot filter in the looper as we normally do, because the paint is 2516024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita // incomplete at this point (text-related attributes are embedded within blob run paints). 2517024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita SkDrawFilter* drawFilter = fMCRec->fFilter; 251896fcdcc219d2a0d3579719b84b28bede76efba64halcanary fMCRec->fFilter = nullptr; 2519024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita 252085d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, bounds) 252100d5c2c6523321d25b32905ff4822f083a4173eefmalita 2522aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita while (iter.next()) { 2523aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 2524024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita iter.fDevice->drawTextBlob(iter, blob, x, y, dfp.paint(), drawFilter); 252500d5c2c6523321d25b32905ff4822f083a4173eefmalita } 252600d5c2c6523321d25b32905ff4822f083a4173eefmalita 2527aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita LOOPER_END 2528024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita 2529024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita fMCRec->fFilter = drawFilter; 253000d5c2c6523321d25b32905ff4822f083a4173eefmalita} 253100d5c2c6523321d25b32905ff4822f083a4173eefmalita 2532e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com// These will become non-virtual, so they always call the (virtual) onDraw... method 2533e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 2534e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 25359881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawText()"); 2536e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawText(text, byteLength, x, y, paint); 2537e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2538e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawPosText(const void* text, size_t byteLength, const SkPoint pos[], 2539e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 25409881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPosText()"); 2541e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawPosText(text, byteLength, pos, paint); 2542e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2543e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], 2544e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com SkScalar constY, const SkPaint& paint) { 25459881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPosTextH()"); 2546e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawPosTextH(text, byteLength, xpos, constY, paint); 2547e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2548e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 2549e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkMatrix* matrix, const SkPaint& paint) { 25509881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextOnPath()"); 2551e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawTextOnPath(text, byteLength, path, matrix, paint); 2552e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 255300d5c2c6523321d25b32905ff4822f083a4173eefmalitavoid SkCanvas::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 255400d5c2c6523321d25b32905ff4822f083a4173eefmalita const SkPaint& paint) { 25559881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextBlob()"); 255649f085dddff10473b6ebf832a974288300224e60bsalomon if (blob) { 255700d5c2c6523321d25b32905ff4822f083a4173eefmalita this->onDrawTextBlob(blob, x, y, paint); 255800d5c2c6523321d25b32905ff4822f083a4173eefmalita } 255900d5c2c6523321d25b32905ff4822f083a4173eefmalita} 2560e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com 256141af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawVertices(VertexMode vmode, int vertexCount, 256241af966ab338e95eee81ab618ab28195075338f7reed const SkPoint verts[], const SkPoint texs[], 256341af966ab338e95eee81ab618ab28195075338f7reed const SkColor colors[], SkXfermode* xmode, 256441af966ab338e95eee81ab618ab28195075338f7reed const uint16_t indices[], int indexCount, 256541af966ab338e95eee81ab618ab28195075338f7reed const SkPaint& paint) { 25669881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawVertices()"); 256796fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, nullptr) 25684b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 25698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 25708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawVertices(iter, vmode, vertexCount, verts, texs, 25714e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com colors, xmode, indices, indexCount, 25724e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com looper.paint()); 25738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 25744b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 25754e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 25768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 25778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2578b3c9d1c33caf325aada244204215eb790c228c12dandovvoid SkCanvas::drawPatch(const SkPoint cubics[12], const SkColor colors[4], 2579b3c9d1c33caf325aada244204215eb790c228c12dandov const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint) { 25809881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPatch()"); 258196fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == cubics) { 2582b3c9d1c33caf325aada244204215eb790c228c12dandov return; 2583b3c9d1c33caf325aada244204215eb790c228c12dandov } 25846cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2585ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov // Since a patch is always within the convex hull of the control points, we discard it when its 2586ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov // bounding rectangle is completely outside the current clip. 2587ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov SkRect bounds; 2588b3c9d1c33caf325aada244204215eb790c228c12dandov bounds.set(cubics, SkPatchUtils::kNumCtrlPts); 2589ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov if (this->quickReject(bounds)) { 2590ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov return; 2591ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov } 25926cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2593b3c9d1c33caf325aada244204215eb790c228c12dandov this->onDrawPatch(cubics, colors, texCoords, xmode, paint); 2594b3c9d1c33caf325aada244204215eb790c228c12dandov} 2595b3c9d1c33caf325aada244204215eb790c228c12dandov 2596b3c9d1c33caf325aada244204215eb790c228c12dandovvoid SkCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], 2597b3c9d1c33caf325aada244204215eb790c228c12dandov const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint) { 2598b3c9d1c33caf325aada244204215eb790c228c12dandov 259996fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, nullptr) 26006cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2601ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov while (iter.next()) { 2602b3c9d1c33caf325aada244204215eb790c228c12dandov iter.fDevice->drawPatch(iter, cubics, colors, texCoords, xmode, paint); 2603ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov } 26046cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2605ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov LOOPER_END 2606ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov} 2607ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov 2608a8db72864a43ad1fbba3c2892cf5cd88060a43efreedvoid SkCanvas::drawDrawable(SkDrawable* dr, SkScalar x, SkScalar y) { 2609a8db72864a43ad1fbba3c2892cf5cd88060a43efreed if (dr) { 2610a8db72864a43ad1fbba3c2892cf5cd88060a43efreed if (x || y) { 2611a8db72864a43ad1fbba3c2892cf5cd88060a43efreed SkMatrix matrix = SkMatrix::MakeTrans(x, y); 2612a8db72864a43ad1fbba3c2892cf5cd88060a43efreed this->onDrawDrawable(dr, &matrix); 2613a8db72864a43ad1fbba3c2892cf5cd88060a43efreed } else { 261496fcdcc219d2a0d3579719b84b28bede76efba64halcanary this->onDrawDrawable(dr, nullptr); 2615a8db72864a43ad1fbba3c2892cf5cd88060a43efreed } 2616a8db72864a43ad1fbba3c2892cf5cd88060a43efreed } 2617a8db72864a43ad1fbba3c2892cf5cd88060a43efreed} 2618a8db72864a43ad1fbba3c2892cf5cd88060a43efreed 2619a8db72864a43ad1fbba3c2892cf5cd88060a43efreedvoid SkCanvas::drawDrawable(SkDrawable* dr, const SkMatrix* matrix) { 2620a8db72864a43ad1fbba3c2892cf5cd88060a43efreed if (dr) { 2621a8db72864a43ad1fbba3c2892cf5cd88060a43efreed if (matrix && matrix->isIdentity()) { 262296fcdcc219d2a0d3579719b84b28bede76efba64halcanary matrix = nullptr; 2623a8db72864a43ad1fbba3c2892cf5cd88060a43efreed } 2624a8db72864a43ad1fbba3c2892cf5cd88060a43efreed this->onDrawDrawable(dr, matrix); 26256a070dc06af4e9f305f9d08a69e34d18ade473cbreed } 26266a070dc06af4e9f305f9d08a69e34d18ade473cbreed} 26276a070dc06af4e9f305f9d08a69e34d18ade473cbreed 2628a8db72864a43ad1fbba3c2892cf5cd88060a43efreedvoid SkCanvas::onDrawDrawable(SkDrawable* dr, const SkMatrix* matrix) { 2629a8db72864a43ad1fbba3c2892cf5cd88060a43efreed SkRect bounds = dr->getBounds(); 2630a8db72864a43ad1fbba3c2892cf5cd88060a43efreed if (matrix) { 2631a8db72864a43ad1fbba3c2892cf5cd88060a43efreed matrix->mapRect(&bounds); 2632a8db72864a43ad1fbba3c2892cf5cd88060a43efreed } 2633a8db72864a43ad1fbba3c2892cf5cd88060a43efreed if (this->quickReject(bounds)) { 2634a8db72864a43ad1fbba3c2892cf5cd88060a43efreed return; 2635a8db72864a43ad1fbba3c2892cf5cd88060a43efreed } 2636a8db72864a43ad1fbba3c2892cf5cd88060a43efreed dr->draw(this, matrix); 26376a070dc06af4e9f305f9d08a69e34d18ade473cbreed} 26386a070dc06af4e9f305f9d08a69e34d18ade473cbreed 263971c3c760a83123ee0b3127b8c65c6394ce541c50reedvoid SkCanvas::onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], 264071c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkColor colors[], int count, SkXfermode::Mode mode, 264171c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkRect* cull, const SkPaint* paint) { 264271c3c760a83123ee0b3127b8c65c6394ce541c50reed if (cull && this->quickReject(*cull)) { 264371c3c760a83123ee0b3127b8c65c6394ce541c50reed return; 264471c3c760a83123ee0b3127b8c65c6394ce541c50reed } 264571c3c760a83123ee0b3127b8c65c6394ce541c50reed 264671c3c760a83123ee0b3127b8c65c6394ce541c50reed SkPaint pnt; 264771c3c760a83123ee0b3127b8c65c6394ce541c50reed if (paint) { 264871c3c760a83123ee0b3127b8c65c6394ce541c50reed pnt = *paint; 264971c3c760a83123ee0b3127b8c65c6394ce541c50reed } 265071c3c760a83123ee0b3127b8c65c6394ce541c50reed 265196fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(pnt, SkDrawFilter::kPath_Type, nullptr) 265271c3c760a83123ee0b3127b8c65c6394ce541c50reed while (iter.next()) { 265371c3c760a83123ee0b3127b8c65c6394ce541c50reed iter.fDevice->drawAtlas(iter, atlas, xform, tex, colors, count, mode, pnt); 265471c3c760a83123ee0b3127b8c65c6394ce541c50reed } 265571c3c760a83123ee0b3127b8c65c6394ce541c50reed LOOPER_END 265671c3c760a83123ee0b3127b8c65c6394ce541c50reed} 265771c3c760a83123ee0b3127b8c65c6394ce541c50reed 26588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 26598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// These methods are NOT virtual, and therefore must call back into virtual 26608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// methods, rather than actually drawing themselves. 26618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 26628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 26638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b, 2664845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com SkXfermode::Mode mode) { 26659881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawARGB()"); 26668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 26678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 26688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setARGB(a, r, g, b); 2669845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com if (SkXfermode::kSrcOver_Mode != mode) { 26700baf19375466cfc24c96532df406e7c5b1d1aae8reed@android.com paint.setXfermodeMode(mode); 26718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 26728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPaint(paint); 26738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 26748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2675845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.comvoid SkCanvas::drawColor(SkColor c, SkXfermode::Mode mode) { 26769881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawColor()"); 26778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 26788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 26798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setColor(c); 2680845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com if (SkXfermode::kSrcOver_Mode != mode) { 26810baf19375466cfc24c96532df406e7c5b1d1aae8reed@android.com paint.setXfermodeMode(mode); 26828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 26838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPaint(paint); 26848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 26858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 26868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPoint(SkScalar x, SkScalar y, const SkPaint& paint) { 26879881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPoint(SkPaint)"); 26888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pt; 26894b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 26908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pt.set(x, y); 26918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kPoints_PointMode, 1, &pt, paint); 26928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 26938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 26948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPoint(SkScalar x, SkScalar y, SkColor color) { 26959881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPoint(SkColor)"); 26968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pt; 26978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 26984b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 26998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pt.set(x, y); 27008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setColor(color); 27018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kPoints_PointMode, 1, &pt, paint); 27028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, 27058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 27069881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawLine()"); 27078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pts[2]; 27084b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 27098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pts[0].set(x0, y0); 27108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pts[1].set(x1, y1); 27118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kLines_PointMode, 2, pts, paint); 27128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawRectCoords(SkScalar left, SkScalar top, 27158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar right, SkScalar bottom, 27168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 27179881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRectCoords()"); 27188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 27198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.set(left, top, right, bottom); 27218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawRect(r, paint); 27228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, 27258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 27269881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawCircle()"); 27278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (radius < 0) { 27288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com radius = 0; 27298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 27308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 27328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.set(cx - radius, cy - radius, cx + radius, cy + radius); 27334ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->drawOval(r, paint); 27348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawRoundRect(const SkRect& r, SkScalar rx, SkScalar ry, 27378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 27389881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRoundRect()"); 27398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (rx > 0 && ry > 0) { 27408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.canComputeFastBounds()) { 27418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect storage; 27423b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(paint.computeFastBounds(r, &storage))) { 27438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 27448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 27458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 27464ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com SkRRect rrect; 27474ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com rrect.setRectXY(r, rx, ry); 27484ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->drawRRect(rrect, paint); 27498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 27508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawRect(r, paint); 27518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 27528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawArc(const SkRect& oval, SkScalar startAngle, 27558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar sweepAngle, bool useCenter, 27568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 27579881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawArc()"); 27588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (SkScalarAbs(sweepAngle) >= SkIntToScalar(360)) { 27598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawOval(oval, paint); 27608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 27618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath path; 27628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (useCenter) { 27638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.moveTo(oval.centerX(), oval.centerY()); 27648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 27658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.arcTo(oval, startAngle, sweepAngle, !useCenter); 27668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (useCenter) { 27678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.close(); 27688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 27698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPath(path, paint); 27708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 27718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawTextOnPathHV(const void* text, size_t byteLength, 27748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPath& path, SkScalar hOffset, 27758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar vOffset, const SkPaint& paint) { 27769881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextOnPathHV()"); 27778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 27784b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 27798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.setTranslate(hOffset, vOffset); 27808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawTextOnPath(text, byteLength, path, &matrix, paint); 27818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2783f76bacff7f66724072c67edb185abf9e3add11a0reed@android.com/////////////////////////////////////////////////////////////////////////////// 27841c2c441fede0ae9573afc098017011e3439624a9reed 27851c2c441fede0ae9573afc098017011e3439624a9reed/** 27861c2c441fede0ae9573afc098017011e3439624a9reed * This constant is trying to balance the speed of ref'ing a subpicture into a parent picture, 27871c2c441fede0ae9573afc098017011e3439624a9reed * against the playback cost of recursing into the subpicture to get at its actual ops. 27881c2c441fede0ae9573afc098017011e3439624a9reed * 27891c2c441fede0ae9573afc098017011e3439624a9reed * For now we pick a conservatively small value, though measurement (and other heuristics like 27901c2c441fede0ae9573afc098017011e3439624a9reed * the type of ops contained) may justify changing this value. 27911c2c441fede0ae9573afc098017011e3439624a9reed */ 27921c2c441fede0ae9573afc098017011e3439624a9reed#define kMaxPictureOpsToUnrollInsteadOfRef 1 27939b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips 2794d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedvoid SkCanvas::drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint) { 27951c2c441fede0ae9573afc098017011e3439624a9reed TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPicture()"); 279649f085dddff10473b6ebf832a974288300224e60bsalomon if (picture) { 2797d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed if (matrix && matrix->isIdentity()) { 279896fcdcc219d2a0d3579719b84b28bede76efba64halcanary matrix = nullptr; 2799d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 28001c2c441fede0ae9573afc098017011e3439624a9reed if (picture->approximateOpCount() <= kMaxPictureOpsToUnrollInsteadOfRef) { 28011c2c441fede0ae9573afc098017011e3439624a9reed SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); 28021c2c441fede0ae9573afc098017011e3439624a9reed picture->playback(this); 28031c2c441fede0ae9573afc098017011e3439624a9reed } else { 28041c2c441fede0ae9573afc098017011e3439624a9reed this->onDrawPicture(picture, matrix, paint); 28051c2c441fede0ae9573afc098017011e3439624a9reed } 2806d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 2807d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 28089b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips 2809d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedvoid SkCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix, 2810d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed const SkPaint* paint) { 2811d028180f0310cf2b23f9744256a41697b0683e67fmalita if (!paint || paint->canComputeFastBounds()) { 2812d028180f0310cf2b23f9744256a41697b0683e67fmalita SkRect bounds = picture->cullRect(); 2813d028180f0310cf2b23f9744256a41697b0683e67fmalita if (paint) { 2814d028180f0310cf2b23f9744256a41697b0683e67fmalita paint->computeFastBounds(bounds, &bounds); 2815d028180f0310cf2b23f9744256a41697b0683e67fmalita } 2816d028180f0310cf2b23f9744256a41697b0683e67fmalita if (matrix) { 2817d028180f0310cf2b23f9744256a41697b0683e67fmalita matrix->mapRect(&bounds); 2818d028180f0310cf2b23f9744256a41697b0683e67fmalita } 2819d028180f0310cf2b23f9744256a41697b0683e67fmalita if (this->quickReject(bounds)) { 2820d028180f0310cf2b23f9744256a41697b0683e67fmalita return; 2821d028180f0310cf2b23f9744256a41697b0683e67fmalita } 2822d028180f0310cf2b23f9744256a41697b0683e67fmalita } 2823d028180f0310cf2b23f9744256a41697b0683e67fmalita 2824145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org SkBaseDevice* device = this->getTopDevice(); 282549f085dddff10473b6ebf832a974288300224e60bsalomon if (device) { 2826145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org // Canvas has to first give the device the opportunity to render 2827145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org // the picture itself. 2828d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed if (device->EXPERIMENTAL_drawPicture(this, picture, matrix, paint)) { 2829145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org return; // the device has rendered the entire picture 2830145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org } 2831145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org } 2832145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org 2833a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); 2834c5ba71d2e5cd426def66fa49dcf003e5b2c98dc7robertphillips picture->playback(this); 28358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 28388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 28398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::LayerIter::LayerIter(SkCanvas* canvas, bool skipEmptyClips) { 284199fe82260633fcf5d92cca38d12ef0937ecca61cbungeman static_assert(sizeof(fStorage) >= sizeof(SkDrawIter), "fStorage_too_small"); 28428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(canvas); 28448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fImpl = new (fStorage) SkDrawIter(canvas, skipEmptyClips); 28468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDone = !fImpl->next(); 28478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::LayerIter::~LayerIter() { 28508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fImpl->~SkDrawIter(); 28518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::LayerIter::next() { 28548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDone = !fImpl->next(); 28558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28571f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::LayerIter::device() const { 28588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fImpl->getDevice(); 28598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkMatrix& SkCanvas::LayerIter::matrix() const { 28628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fImpl->getMatrix(); 28638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkPaint& SkCanvas::LayerIter::paint() const { 28668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* paint = fImpl->getPaint(); 286796fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 28688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint = &fDefaultPaint; 28698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 28708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return *paint; 28718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkRegion& SkCanvas::LayerIter::clip() const { return fImpl->getClip(); } 28748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::LayerIter::x() const { return fImpl->getX(); } 28758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::LayerIter::y() const { return fImpl->getY(); } 287620a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com 287720a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com/////////////////////////////////////////////////////////////////////////////// 287820a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com 2879c3b589a24eb4d567a906189f882c259ecf5c2f58fmalitaSkCanvasClipVisitor::~SkCanvasClipVisitor() { } 28803107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 28813107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 28823107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 28833107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.orgstatic bool supported_for_raster_canvas(const SkImageInfo& info) { 28843107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org switch (info.alphaType()) { 28853107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kPremul_SkAlphaType: 28863107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kOpaque_SkAlphaType: 28873107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org break; 28883107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org default: 28893107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return false; 28903107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 28913107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 28923107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org switch (info.colorType()) { 28933107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kAlpha_8_SkColorType: 28943107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kRGB_565_SkColorType: 289528fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org case kN32_SkColorType: 28963107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org break; 28973107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org default: 28983107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return false; 28993107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 29003107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 29013107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return true; 29023107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org} 29033107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 290442b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.orgSkCanvas* SkCanvas::NewRasterDirect(const SkImageInfo& info, void* pixels, size_t rowBytes) { 290542b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org if (!supported_for_raster_canvas(info)) { 290696fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 290742b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org } 2908eb849e5fd10cbe00cbc31307ba97fd9efca0b41bskia.committer@gmail.com 290942b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org SkBitmap bitmap; 291042b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org if (!bitmap.installPixels(info, pixels, rowBytes)) { 291196fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 291242b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org } 2913385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return new SkCanvas(bitmap); 291442b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org} 2915d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 2916d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed/////////////////////////////////////////////////////////////////////////////// 2917d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 2918d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedSkAutoCanvasMatrixPaint::SkAutoCanvasMatrixPaint(SkCanvas* canvas, const SkMatrix* matrix, 2919a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips const SkPaint* paint, const SkRect& bounds) 2920d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed : fCanvas(canvas) 2921d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed , fSaveCount(canvas->getSaveCount()) 2922d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed{ 292349f085dddff10473b6ebf832a974288300224e60bsalomon if (paint) { 2924a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkRect newBounds = bounds; 2925d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed if (matrix) { 2926a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips matrix->mapRect(&newBounds); 2927d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 2928a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips canvas->saveLayer(&newBounds, paint); 292949f085dddff10473b6ebf832a974288300224e60bsalomon } else if (matrix) { 2930d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed canvas->save(); 2931d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 29326cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 293349f085dddff10473b6ebf832a974288300224e60bsalomon if (matrix) { 2934d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed canvas->concat(*matrix); 2935d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 2936d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 2937d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 2938d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedSkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { 2939d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed fCanvas->restoreToCount(fSaveCount); 2940d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 2941