SkCanvas.cpp revision 96a04f329926099f0002f97883242793ff04f61c
18a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2008 The Android Open Source Project 38a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 68a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8d3ebb48320cf1b7e969974673e4bd7743816985ebungeman#include "SkBitmapDevice.h" 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h" 10d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed#include "SkCanvasPriv.h" 11d3ebb48320cf1b7e969974673e4bd7743816985ebungeman#include "SkClipStack.h" 12dbc3cefb0b624808ddb86d444e6103f216e12fa5reed#include "SkColorFilter.h" 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDraw.h" 143cb3840c9af6f70896cf5565a38d4ee03c02d767reed#include "SkDrawable.h" 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDrawFilter.h" 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDrawLooper.h" 175f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt#include "SkErrorInternals.h" 18b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr#include "SkImage.h" 19262a71b7f95ce98ff3dd8dba845afbd724470903reed#include "SkImage_Base.h" 20262a71b7f95ce98ff3dd8dba845afbd724470903reed#include "SkMatrixUtils.h" 2174bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org#include "SkMetaData.h" 224c21dc5ddf3b482293ed34eead876d8d61a662c3reed#include "SkNinePatchIter.h" 23c83a29759a5c2966da5ab973e4fd90763e4c962breed#include "SkPaintPriv.h" 24b3c9d1c33caf325aada244204215eb790c228c12dandov#include "SkPatchUtils.h" 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPicture.h" 260017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com#include "SkRasterClip.h" 2796472deea70169396b8e1f576e470138f55fdb1freed#include "SkReadPixelsRec.h" 284ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com#include "SkRRect.h" 2979fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org#include "SkSmallAllocator.h" 304418dbac3386f26c8da62ab242be9c178961eb18robertphillips#include "SkSpecialImage.h" 3197af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com#include "SkSurface_Base.h" 327ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita#include "SkTextBlob.h" 3352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com#include "SkTextFormatParams.h" 34a076e9be17654a60310e72c4f70fcd5337f56dbfreed@google.com#include "SkTLazy.h" 358f757f540a8378c7b1354aab3d4650eaa920b17adanakj#include "SkTraceEvent.h" 36d3ebb48320cf1b7e969974673e4bd7743816985ebungeman 37d3ebb48320cf1b7e969974673e4bd7743816985ebungeman#include <new> 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 39644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#if SK_SUPPORT_GPU 407354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips#include "GrContext.h" 41644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#include "GrRenderTarget.h" 427354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips#include "SkGr.h" 43644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#endif 44644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org 45e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed#define RETURN_ON_NULL(ptr) do { if (nullptr == (ptr)) return; } while (0) 46e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed 47c83a29759a5c2966da5ab973e4fd90763e4c962breed/* 48c83a29759a5c2966da5ab973e4fd90763e4c962breed * Return true if the drawing this rect would hit every pixels in the canvas. 49c83a29759a5c2966da5ab973e4fd90763e4c962breed * 50c83a29759a5c2966da5ab973e4fd90763e4c962breed * Returns false if 51c83a29759a5c2966da5ab973e4fd90763e4c962breed * - rect does not contain the canvas' bounds 52c83a29759a5c2966da5ab973e4fd90763e4c962breed * - paint is not fill 53c83a29759a5c2966da5ab973e4fd90763e4c962breed * - paint would blur or otherwise change the coverage of the rect 54c83a29759a5c2966da5ab973e4fd90763e4c962breed */ 55c83a29759a5c2966da5ab973e4fd90763e4c962breedbool SkCanvas::wouldOverwriteEntireSurface(const SkRect* rect, const SkPaint* paint, 56c83a29759a5c2966da5ab973e4fd90763e4c962breed ShaderOverrideOpacity overrideOpacity) const { 5799fe82260633fcf5d92cca38d12ef0937ecca61cbungeman static_assert((int)SkPaintPriv::kNone_ShaderOverrideOpacity == 5899fe82260633fcf5d92cca38d12ef0937ecca61cbungeman (int)kNone_ShaderOverrideOpacity, 5999fe82260633fcf5d92cca38d12ef0937ecca61cbungeman "need_matching_enums0"); 6099fe82260633fcf5d92cca38d12ef0937ecca61cbungeman static_assert((int)SkPaintPriv::kOpaque_ShaderOverrideOpacity == 6199fe82260633fcf5d92cca38d12ef0937ecca61cbungeman (int)kOpaque_ShaderOverrideOpacity, 6299fe82260633fcf5d92cca38d12ef0937ecca61cbungeman "need_matching_enums1"); 6399fe82260633fcf5d92cca38d12ef0937ecca61cbungeman static_assert((int)SkPaintPriv::kNotOpaque_ShaderOverrideOpacity == 6499fe82260633fcf5d92cca38d12ef0937ecca61cbungeman (int)kNotOpaque_ShaderOverrideOpacity, 6599fe82260633fcf5d92cca38d12ef0937ecca61cbungeman "need_matching_enums2"); 66c83a29759a5c2966da5ab973e4fd90763e4c962breed 67c83a29759a5c2966da5ab973e4fd90763e4c962breed const SkISize size = this->getBaseLayerSize(); 68c83a29759a5c2966da5ab973e4fd90763e4c962breed const SkRect bounds = SkRect::MakeIWH(size.width(), size.height()); 69c83a29759a5c2966da5ab973e4fd90763e4c962breed if (!this->getClipStack()->quickContains(bounds)) { 70c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; 71c83a29759a5c2966da5ab973e4fd90763e4c962breed } 72c83a29759a5c2966da5ab973e4fd90763e4c962breed 73c83a29759a5c2966da5ab973e4fd90763e4c962breed if (rect) { 74c83a29759a5c2966da5ab973e4fd90763e4c962breed if (!this->getTotalMatrix().rectStaysRect()) { 75c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; // conservative 76c83a29759a5c2966da5ab973e4fd90763e4c962breed } 77c83a29759a5c2966da5ab973e4fd90763e4c962breed 78c83a29759a5c2966da5ab973e4fd90763e4c962breed SkRect devRect; 79c83a29759a5c2966da5ab973e4fd90763e4c962breed this->getTotalMatrix().mapRect(&devRect, *rect); 808c0144ccb17220db9d5140ef5ee85d5bc7837513fmalita if (!devRect.contains(bounds)) { 81c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; 82c83a29759a5c2966da5ab973e4fd90763e4c962breed } 83c83a29759a5c2966da5ab973e4fd90763e4c962breed } 84c83a29759a5c2966da5ab973e4fd90763e4c962breed 85c83a29759a5c2966da5ab973e4fd90763e4c962breed if (paint) { 86c83a29759a5c2966da5ab973e4fd90763e4c962breed SkPaint::Style paintStyle = paint->getStyle(); 87c83a29759a5c2966da5ab973e4fd90763e4c962breed if (!(paintStyle == SkPaint::kFill_Style || 88c83a29759a5c2966da5ab973e4fd90763e4c962breed paintStyle == SkPaint::kStrokeAndFill_Style)) { 89c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; 90c83a29759a5c2966da5ab973e4fd90763e4c962breed } 91c83a29759a5c2966da5ab973e4fd90763e4c962breed if (paint->getMaskFilter() || paint->getLooper() 92c83a29759a5c2966da5ab973e4fd90763e4c962breed || paint->getPathEffect() || paint->getImageFilter()) { 93c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; // conservative 94c83a29759a5c2966da5ab973e4fd90763e4c962breed } 95c83a29759a5c2966da5ab973e4fd90763e4c962breed } 96c83a29759a5c2966da5ab973e4fd90763e4c962breed return SkPaintPriv::Overwrites(paint, (SkPaintPriv::ShaderOverrideOpacity)overrideOpacity); 97c83a29759a5c2966da5ab973e4fd90763e4c962breed} 98c83a29759a5c2966da5ab973e4fd90763e4c962breed 99c83a29759a5c2966da5ab973e4fd90763e4c962breed/////////////////////////////////////////////////////////////////////////////////////////////////// 100c83a29759a5c2966da5ab973e4fd90763e4c962breed 101d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareedstatic bool gIgnoreSaveLayerBounds; 102d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareedvoid SkCanvas::Internal_Private_SetIgnoreSaveLayerBounds(bool ignore) { 103d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed gIgnoreSaveLayerBounds = ignore; 104d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed} 105d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareedbool SkCanvas::Internal_Private_GetIgnoreSaveLayerBounds() { 106d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed return gIgnoreSaveLayerBounds; 107d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed} 108d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed 1090acf1b4b3645772d220c720313821bac389751b5reedstatic bool gTreatSpriteAsBitmap; 1100acf1b4b3645772d220c720313821bac389751b5reedvoid SkCanvas::Internal_Private_SetTreatSpriteAsBitmap(bool spriteAsBitmap) { 1110acf1b4b3645772d220c720313821bac389751b5reed gTreatSpriteAsBitmap = spriteAsBitmap; 1120acf1b4b3645772d220c720313821bac389751b5reed} 1130acf1b4b3645772d220c720313821bac389751b5reedbool SkCanvas::Internal_Private_GetTreatSpriteAsBitmap() { 1140acf1b4b3645772d220c720313821bac389751b5reed return gTreatSpriteAsBitmap; 1150acf1b4b3645772d220c720313821bac389751b5reed} 1160acf1b4b3645772d220c720313821bac389751b5reed 117da17f758442f16747af39f8fbaed9c097048519creed@google.com// experimental for faster tiled drawing... 118da17f758442f16747af39f8fbaed9c097048519creed@google.com//#define SK_ENABLE_CLIP_QUICKREJECT 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//#define SK_TRACE_SAVERESTORE 1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_TRACE_SAVERESTORE 1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gLayerCounter; 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_layer() { ++gLayerCounter; printf("----- inc layer %d\n", gLayerCounter); } 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_layer() { --gLayerCounter; printf("----- dec layer %d\n", gLayerCounter); } 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gRecCounter; 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_rec() { ++gRecCounter; printf("----- inc rec %d\n", gRecCounter); } 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_rec() { --gRecCounter; printf("----- dec rec %d\n", gRecCounter); } 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gCanvasCounter; 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_canvas() { ++gCanvasCounter; printf("----- inc canvas %d\n", gCanvasCounter); } 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_canvas() { --gCanvasCounter; printf("----- dec canvas %d\n", gCanvasCounter); } 1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_layer() 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_layer() 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_rec() 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_rec() 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_canvas() 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_canvas() 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1422c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.orgtypedef SkTLazy<SkPaint> SkLazyPaint; 1432c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org 144c83a29759a5c2966da5ab973e4fd90763e4c962breedvoid SkCanvas::predrawNotify(bool willOverwritesEntireSurface) { 14597af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com if (fSurfaceBase) { 146c83a29759a5c2966da5ab973e4fd90763e4c962breed fSurfaceBase->aboutToDraw(willOverwritesEntireSurface 147c83a29759a5c2966da5ab973e4fd90763e4c962breed ? SkSurface::kDiscard_ContentChangeMode 148c83a29759a5c2966da5ab973e4fd90763e4c962breed : SkSurface::kRetain_ContentChangeMode); 149c83a29759a5c2966da5ab973e4fd90763e4c962breed } 150c83a29759a5c2966da5ab973e4fd90763e4c962breed} 151c83a29759a5c2966da5ab973e4fd90763e4c962breed 152c83a29759a5c2966da5ab973e4fd90763e4c962breedvoid SkCanvas::predrawNotify(const SkRect* rect, const SkPaint* paint, 153c83a29759a5c2966da5ab973e4fd90763e4c962breed ShaderOverrideOpacity overrideOpacity) { 154c83a29759a5c2966da5ab973e4fd90763e4c962breed if (fSurfaceBase) { 155c83a29759a5c2966da5ab973e4fd90763e4c962breed SkSurface::ContentChangeMode mode = SkSurface::kRetain_ContentChangeMode; 156c83a29759a5c2966da5ab973e4fd90763e4c962breed // Since willOverwriteAllPixels() may not be complete free to call, we only do so if 157c83a29759a5c2966da5ab973e4fd90763e4c962breed // there is an outstanding snapshot, since w/o that, there will be no copy-on-write 158c83a29759a5c2966da5ab973e4fd90763e4c962breed // and therefore we don't care which mode we're in. 159c83a29759a5c2966da5ab973e4fd90763e4c962breed // 160c83a29759a5c2966da5ab973e4fd90763e4c962breed if (fSurfaceBase->outstandingImageSnapshot()) { 161c83a29759a5c2966da5ab973e4fd90763e4c962breed if (this->wouldOverwriteEntireSurface(rect, paint, overrideOpacity)) { 162c83a29759a5c2966da5ab973e4fd90763e4c962breed mode = SkSurface::kDiscard_ContentChangeMode; 163c83a29759a5c2966da5ab973e4fd90763e4c962breed } 164c83a29759a5c2966da5ab973e4fd90763e4c962breed } 165c83a29759a5c2966da5ab973e4fd90763e4c962breed fSurfaceBase->aboutToDraw(mode); 16697af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com } 16797af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com} 16897af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com 1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1714a8126e7f81384526629b1e21bf89b632ea13cd9reedstatic uint32_t filter_paint_flags(const SkSurfaceProps& props, uint32_t flags) { 1724a8126e7f81384526629b1e21bf89b632ea13cd9reed const uint32_t propFlags = props.flags(); 1734a8126e7f81384526629b1e21bf89b632ea13cd9reed if (propFlags & SkSurfaceProps::kDisallowDither_Flag) { 1744a8126e7f81384526629b1e21bf89b632ea13cd9reed flags &= ~SkPaint::kDither_Flag; 1754a8126e7f81384526629b1e21bf89b632ea13cd9reed } 1764a8126e7f81384526629b1e21bf89b632ea13cd9reed if (propFlags & SkSurfaceProps::kDisallowAntiAlias_Flag) { 1774a8126e7f81384526629b1e21bf89b632ea13cd9reed flags &= ~SkPaint::kAntiAlias_Flag; 1784a8126e7f81384526629b1e21bf89b632ea13cd9reed } 1794a8126e7f81384526629b1e21bf89b632ea13cd9reed return flags; 1804a8126e7f81384526629b1e21bf89b632ea13cd9reed} 1814a8126e7f81384526629b1e21bf89b632ea13cd9reed 1824a8126e7f81384526629b1e21bf89b632ea13cd9reed/////////////////////////////////////////////////////////////////////////////// 1834a8126e7f81384526629b1e21bf89b632ea13cd9reed 1841f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com/* This is the record we keep for each SkBaseDevice that the user installs. 1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com The clip/matrix/proc are fields that reflect the top of the save/restore 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stack. Whenever the canvas changes, it marks a dirty flag, and then before 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com these are used (assuming we're not on a layer) we rebuild these cache 1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com values: they reflect the top of the save stack, but translated and clipped 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com by the device's XY offset and bitmap-bounds. 1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct DeviceCM { 1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* fNext; 1931f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* fDevice; 194045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com SkRasterClip fClip; 1956f8f292aa768869a9e85c314b124875f57504f2creed@google.com SkPaint* fPaint; // may be null (in the future) 19661f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed const SkMatrix* fMatrix; 19761f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed SkMatrix fMatrixStorage; 1988c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkMatrix fStashedMatrix; // original CTM; used by imagefilter in saveLayer 19961f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed const bool fDeviceIsBitmapDevice; 2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20196e657d0e103b8358a77ecd913f6086929f792b8reed DeviceCM(SkBaseDevice* device, const SkPaint* paint, SkCanvas* canvas, 2028c30a8196dd5903d2d23b4d0a5dc888e802bf698reed bool conservativeRasterClip, bool deviceIsBitmapDevice, const SkMatrix& stashed) 20396fcdcc219d2a0d3579719b84b28bede76efba64halcanary : fNext(nullptr) 204d954498c01ccf0417feacf89e45d0c62a06a813breed , fClip(conservativeRasterClip) 2058c30a8196dd5903d2d23b4d0a5dc888e802bf698reed , fStashedMatrix(stashed) 20661f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed , fDeviceIsBitmapDevice(deviceIsBitmapDevice) 207d954498c01ccf0417feacf89e45d0c62a06a813breed { 20896fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr != device) { 2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device->ref(); 21040a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com device->onAttachToCanvas(canvas); 2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2124b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com fDevice = device; 21396fcdcc219d2a0d3579719b84b28bede76efba64halcanary fPaint = paint ? new SkPaint(*paint) : nullptr; 21488edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21688edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com ~DeviceCM() { 21749f085dddff10473b6ebf832a974288300224e60bsalomon if (fDevice) { 21840a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com fDevice->onDetachFromCanvas(); 2198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDevice->unref(); 2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 221385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete fPaint; 22288edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 2234b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 224feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein void reset(const SkIRect& bounds) { 225feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(!fPaint); 226feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(!fNext); 227feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(fDevice); 228feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fClip.setRect(bounds); 229feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein } 230feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 231045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com void updateMC(const SkMatrix& totalMatrix, const SkRasterClip& totalClip, 232045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com const SkClipStack& clipStack, SkRasterClip* updateClip) { 2336f8f292aa768869a9e85c314b124875f57504f2creed@google.com int x = fDevice->getOrigin().x(); 2346f8f292aa768869a9e85c314b124875f57504f2creed@google.com int y = fDevice->getOrigin().y(); 2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int width = fDevice->width(); 2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int height = fDevice->height(); 2374b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if ((x | y) == 0) { 2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = &totalMatrix; 2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fClip = totalClip; 2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrixStorage = totalMatrix; 2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrixStorage.postTranslate(SkIntToScalar(-x), 2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIntToScalar(-y)); 2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = &fMatrixStorage; 2464b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com totalClip.translate(-x, -y, &fClip); 2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 250045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com fClip.op(SkIRect::MakeWH(width, height), SkRegion::kIntersect_Op); 2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // intersect clip, but don't translate it (yet) 2534b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (updateClip) { 255045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com updateClip->op(SkIRect::MakeXYWH(x, y, width, height), 2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRegion::kDifference_Op); 2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2584b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2593fffb2ee9fa01ae61efb2395973eb7575eda4c96robertphillips@google.com fDevice->setMatrixClip(*fMatrix, fClip.forceGetBW(), clipStack); 2603fffb2ee9fa01ae61efb2395973eb7575eda4c96robertphillips@google.com 2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!fClip.isEmpty()) { 2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIRect deviceR; 2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com deviceR.set(0, 0, width, height); 2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(deviceR.contains(fClip.getBounds())); 2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 268f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* This is the record we keep for each save/restore level in the stack. 2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Since a level optionally copies the matrix and/or stack, we have pointers 2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for these fields. If the value is copied for this level, the copy is 2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stored in the ...Storage field, and the pointer points to that. If the 2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value is not copied for this level, we ignore ...Storage, and just point 2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com at the corresponding value in the previous level in the stack. 2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkCanvas::MCRec { 2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 2801f836ee096bb988adef4b9757b2629c7afeda36dreed SkDrawFilter* fFilter; // the current filter (or null) 281d954498c01ccf0417feacf89e45d0c62a06a813breed DeviceCM* fLayer; 2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* If there are any layers in the stack, this points to the top-most 2838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com one that is at or below this level in the stack (so we know what 2848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bitmap/device to draw into from this level. This value is NOT 2858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com reference counted, since the real owner is either our fLayer field, 2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com or a previous one in a lower level.) 2878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 2882ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed DeviceCM* fTopLayer; 2892ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkRasterClip fRasterClip; 2902ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkMatrix fMatrix; 2912ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed int fDeferredSaveCount; 2928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 293d954498c01ccf0417feacf89e45d0c62a06a813breed MCRec(bool conservativeRasterClip) : fRasterClip(conservativeRasterClip) { 29496fcdcc219d2a0d3579719b84b28bede76efba64halcanary fFilter = nullptr; 29596fcdcc219d2a0d3579719b84b28bede76efba64halcanary fLayer = nullptr; 29696fcdcc219d2a0d3579719b84b28bede76efba64halcanary fTopLayer = nullptr; 2972ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fMatrix.reset(); 2982ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fDeferredSaveCount = 0; 299b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 300d954498c01ccf0417feacf89e45d0c62a06a813breed // don't bother initializing fNext 301d954498c01ccf0417feacf89e45d0c62a06a813breed inc_rec(); 302d954498c01ccf0417feacf89e45d0c62a06a813breed } 3032ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed MCRec(const MCRec& prev) : fRasterClip(prev.fRasterClip), fMatrix(prev.fMatrix) { 304d954498c01ccf0417feacf89e45d0c62a06a813breed fFilter = SkSafeRef(prev.fFilter); 30596fcdcc219d2a0d3579719b84b28bede76efba64halcanary fLayer = nullptr; 306d954498c01ccf0417feacf89e45d0c62a06a813breed fTopLayer = prev.fTopLayer; 3072ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fDeferredSaveCount = 0; 308b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 3098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // don't bother initializing fNext 3108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inc_rec(); 3118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ~MCRec() { 31382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fFilter); 314385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete fLayer; 3158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dec_rec(); 3168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 317feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 318feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein void reset(const SkIRect& bounds) { 319feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(fLayer); 320feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(fDeferredSaveCount == 0); 321feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 322feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fMatrix.reset(); 323feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fRasterClip.setRect(bounds); 324feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fLayer->reset(bounds); 325feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein } 3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkDrawIter : public SkDraw { 3298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 3308a0b0291ae4260ef2a46f4341c18a702c0ce3f8btomhudson@google.com SkDrawIter(SkCanvas* canvas, bool skipEmptyClips = true) { 3314370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com canvas = canvas->canvasForDrawIter(); 3328a0b0291ae4260ef2a46f4341c18a702c0ce3f8btomhudson@google.com fCanvas = canvas; 3338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com canvas->updateDeviceCMCache(); 3348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 335687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack = canvas->fClipStack; 3368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = canvas->fMCRec->fTopLayer; 3378a0b0291ae4260ef2a46f4341c18a702c0ce3f8btomhudson@google.com fSkipEmptyClips = skipEmptyClips; 3388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3394b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 3408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool next() { 3418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // skip over recs with empty clips 3428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fSkipEmptyClips) { 3438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (fCurrLayer && fCurrLayer->fClip.isEmpty()) { 3448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = fCurrLayer->fNext; 3458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 348f68c5e2f9f05b3af2bae0979ace2684b6041b6e3reed@google.com const DeviceCM* rec = fCurrLayer; 349f68c5e2f9f05b3af2bae0979ace2684b6041b6e3reed@google.com if (rec && rec->fDevice) { 3508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = rec->fMatrix; 352045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com fClip = &((SkRasterClip*)&rec->fClip)->forceGetBW(); 353045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com fRC = &rec->fClip; 3548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDevice = rec->fDevice; 35541e010cb901c0da9066c4df562030808c9ccd7f8reed if (!fDevice->accessPixels(&fDst)) { 35696fcdcc219d2a0d3579719b84b28bede76efba64halcanary fDst.reset(fDevice->imageInfo(), nullptr, 0); 35741e010cb901c0da9066c4df562030808c9ccd7f8reed } 3588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint = rec->fPaint; 359f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com SkDEBUGCODE(this->validate();) 3608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = rec->fNext; 36296fcdcc219d2a0d3579719b84b28bede76efba64halcanary // fCurrLayer may be nullptr now 363199f108f14a5f60a9c2205ffa79b26102a206ad0reed@android.com 3648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 3658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 3678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3684b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 3691f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* getDevice() const { return fDevice; } 3706f8f292aa768869a9e85c314b124875f57504f2creed@google.com int getX() const { return fDevice->getOrigin().x(); } 3716f8f292aa768869a9e85c314b124875f57504f2creed@google.com int getY() const { return fDevice->getOrigin().y(); } 3728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& getMatrix() const { return *fMatrix; } 3738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkRegion& getClip() const { return *fClip; } 3748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* getPaint() const { return fPaint; } 3756f8f292aa768869a9e85c314b124875f57504f2creed@google.com 3768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 3778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkCanvas* fCanvas; 3788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const DeviceCM* fCurrLayer; 3798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* fPaint; // May be null. 3808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkBool8 fSkipEmptyClips; 3818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef SkDraw INHERITED; 3838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////// 3868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 387dbc3cefb0b624808ddb86d444e6103f216e12fa5reedstatic SkPaint* set_if_needed(SkLazyPaint* lazy, const SkPaint& orig) { 388dbc3cefb0b624808ddb86d444e6103f216e12fa5reed return lazy->isValid() ? lazy->get() : lazy->set(orig); 389dbc3cefb0b624808ddb86d444e6103f216e12fa5reed} 390dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 391dbc3cefb0b624808ddb86d444e6103f216e12fa5reed/** 392dbc3cefb0b624808ddb86d444e6103f216e12fa5reed * If the paint has an imagefilter, but it can be simplified to just a colorfilter, return that 39396fcdcc219d2a0d3579719b84b28bede76efba64halcanary * colorfilter, else return nullptr. 394dbc3cefb0b624808ddb86d444e6103f216e12fa5reed */ 395d053ce9c54d4e5937a142278359e5a4cde18095ereedstatic sk_sp<SkColorFilter> image_to_color_filter(const SkPaint& paint) { 396dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkImageFilter* imgf = paint.getImageFilter(); 397dbc3cefb0b624808ddb86d444e6103f216e12fa5reed if (!imgf) { 39896fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 399dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 400dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 401d053ce9c54d4e5937a142278359e5a4cde18095ereed SkColorFilter* imgCFPtr; 402d053ce9c54d4e5937a142278359e5a4cde18095ereed if (!imgf->asAColorFilter(&imgCFPtr)) { 40396fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 404dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 405d053ce9c54d4e5937a142278359e5a4cde18095ereed sk_sp<SkColorFilter> imgCF(imgCFPtr); 406dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 407dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkColorFilter* paintCF = paint.getColorFilter(); 40896fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paintCF) { 409dbc3cefb0b624808ddb86d444e6103f216e12fa5reed // there is no existing paint colorfilter, so we can just return the imagefilter's 410dbc3cefb0b624808ddb86d444e6103f216e12fa5reed return imgCF; 411dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 412dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 413dbc3cefb0b624808ddb86d444e6103f216e12fa5reed // The paint has both a colorfilter(paintCF) and an imagefilter-which-is-a-colorfilter(imgCF) 414dbc3cefb0b624808ddb86d444e6103f216e12fa5reed // and we need to combine them into a single colorfilter. 415d053ce9c54d4e5937a142278359e5a4cde18095ereed return SkColorFilter::MakeComposeFilter(std::move(imgCF), sk_ref_sp(paintCF)); 416dbc3cefb0b624808ddb86d444e6103f216e12fa5reed} 417dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 41887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco/** 41987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * There are many bounds in skia. A circle's bounds is just its center extended by its radius. 42087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * However, if we stroke a circle, then the "bounds" of that is larger, since it will now draw 42187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * outside of its raw-bounds by 1/2 the stroke width. SkPaint has lots of optional 42287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * effects/attributes that can modify the effective bounds of a given primitive -- maskfilters, 42387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * patheffects, stroking, etc. This function takes a raw bounds and a paint, and returns the 42487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * conservative "effective" bounds based on the settings in the paint... with one exception. This 42587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * function does *not* look at the imagefilter, which can also modify the effective bounds. It is 42687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * deliberately ignored. 42787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco */ 42887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblancostatic const SkRect& apply_paint_to_bounds_sans_imagefilter(const SkPaint& paint, 42987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco const SkRect& rawBounds, 43087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect* storage) { 43187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkPaint tmpUnfiltered(paint); 43287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco tmpUnfiltered.setImageFilter(nullptr); 43387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (tmpUnfiltered.canComputeFastBounds()) { 43487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return tmpUnfiltered.computeFastBounds(rawBounds, storage); 43587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } else { 43687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return rawBounds; 43787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 43887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco} 43987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco 4408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass AutoDrawLooper { 4418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 44287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco // "rawBounds" is the original bounds of the primitive about to be drawn, unmodified by the 44387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco // paint. It's used to determine the size of the offscreen layer for filters. 44487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco // If null, the clip will be used instead. 4454a8126e7f81384526629b1e21bf89b632ea13cd9reed AutoDrawLooper(SkCanvas* canvas, const SkSurfaceProps& props, const SkPaint& paint, 44678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bool skipLayerForImageFilter = false, 44787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco const SkRect* rawBounds = nullptr) : fOrigPaint(paint) { 4484e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fCanvas = canvas; 44953d9f1cfbd5ddbf57c2f22b9e613ce48e5b2896cfmalita#ifdef SK_SUPPORT_LEGACY_DRAWFILTER 4508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFilter = canvas->getDrawFilter(); 4517765000709dc64eb23be7df47d1f995d1f787115fmalita#else 4527765000709dc64eb23be7df47d1f995d1f787115fmalita fFilter = nullptr; 4537765000709dc64eb23be7df47d1f995d1f787115fmalita#endif 4544a8126e7f81384526629b1e21bf89b632ea13cd9reed fPaint = &fOrigPaint; 4554e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fSaveCount = canvas->getSaveCount(); 4565c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed fTempLayerForImageFilter = false; 4574e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fDone = false; 4588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 459d053ce9c54d4e5937a142278359e5a4cde18095ereed auto simplifiedCF = image_to_color_filter(fOrigPaint); 460dbc3cefb0b624808ddb86d444e6103f216e12fa5reed if (simplifiedCF) { 461dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkPaint* paint = set_if_needed(&fLazyPaintInit, fOrigPaint); 462d053ce9c54d4e5937a142278359e5a4cde18095ereed paint->setColorFilter(std::move(simplifiedCF)); 46396fcdcc219d2a0d3579719b84b28bede76efba64halcanary paint->setImageFilter(nullptr); 464dbc3cefb0b624808ddb86d444e6103f216e12fa5reed fPaint = paint; 465dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 466dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 467dbc3cefb0b624808ddb86d444e6103f216e12fa5reed if (!skipLayerForImageFilter && fPaint->getImageFilter()) { 4685c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed /** 4695c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * We implement ImageFilters for a given draw by creating a layer, then applying the 4705c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * imagefilter to the pixels of that layer (its backing surface/image), and then 4715c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * we call restore() to xfer that layer to the main canvas. 4725c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 4735c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 1. SaveLayer (with a paint containing the current imagefilter and xfermode) 4745c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 2. Generate the src pixels: 4755c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * Remove the imagefilter and the xfermode from the paint that we (AutoDrawLooper) 4765c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * return (fPaint). We then draw the primitive (using srcover) into a cleared 4775c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * buffer/surface. 4785c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 3. Restore the layer created in #1 4795c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * The imagefilter is passed the buffer/surface from the layer (now filled with the 4805c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * src pixels of the primitive). It returns a new "filtered" buffer, which we 4815c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * draw onto the previous layer using the xfermode from the original paint. 4825c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed */ 4838926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkPaint tmp; 484dbc3cefb0b624808ddb86d444e6103f216e12fa5reed tmp.setImageFilter(fPaint->getImageFilter()); 485cfb6bdf767796c950f89985445738d2d8e7f12b0reed tmp.setXfermode(sk_ref_sp(fPaint->getXfermode())); 48687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect storage; 48787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (rawBounds) { 48887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco // Make rawBounds include all paint outsets except for those due to image filters. 48987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco rawBounds = &apply_paint_to_bounds_sans_imagefilter(*fPaint, *rawBounds, &storage); 49087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 491bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed (void)canvas->internalSaveLayer(SkCanvas::SaveLayerRec(rawBounds, &tmp), 49276033be81b82c44fd5d4fdf2672eb22e505da1f0reed SkCanvas::kFullLayer_SaveLayerStrategy); 4935c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed fTempLayerForImageFilter = true; 4945c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed // we remove the imagefilter/xfermode inside doNext() 4958926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 4968926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 49779fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (SkDrawLooper* looper = paint.getLooper()) { 49879fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org void* buffer = fLooperContextAllocator.reserveT<SkDrawLooper::Context>( 49979fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org looper->contextSize()); 50079fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org fLooperContext = looper->createContext(canvas, buffer); 501129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fIsSimple = false; 502129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else { 50396fcdcc219d2a0d3579719b84b28bede76efba64halcanary fLooperContext = nullptr; 504129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // can we be marked as simple? 5055c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed fIsSimple = !fFilter && !fTempLayerForImageFilter; 5068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 507b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 5084a8126e7f81384526629b1e21bf89b632ea13cd9reed uint32_t oldFlags = paint.getFlags(); 5094a8126e7f81384526629b1e21bf89b632ea13cd9reed fNewPaintFlags = filter_paint_flags(props, oldFlags); 5104a8126e7f81384526629b1e21bf89b632ea13cd9reed if (fIsSimple && (fNewPaintFlags != oldFlags)) { 511dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkPaint* paint = set_if_needed(&fLazyPaintInit, fOrigPaint); 5124a8126e7f81384526629b1e21bf89b632ea13cd9reed paint->setFlags(fNewPaintFlags); 5134a8126e7f81384526629b1e21bf89b632ea13cd9reed fPaint = paint; 5144a8126e7f81384526629b1e21bf89b632ea13cd9reed // if we're not simple, doNext() will take care of calling setFlags() 5154a8126e7f81384526629b1e21bf89b632ea13cd9reed } 5168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 51774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 5184e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com ~AutoDrawLooper() { 5195c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed if (fTempLayerForImageFilter) { 5208926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com fCanvas->internalRestore(); 5218926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 5224e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkASSERT(fCanvas->getSaveCount() == fSaveCount); 5238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 52474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 5254e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com const SkPaint& paint() const { 5264e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkASSERT(fPaint); 5274e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return *fPaint; 5284e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 52974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 530129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool next(SkDrawFilter::Type drawType) { 531129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com if (fDone) { 532129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return false; 533129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else if (fIsSimple) { 534129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fDone = true; 535129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return !fPaint->nothingToDraw(); 536129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else { 537129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return this->doNext(drawType); 538129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 539fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 54074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 5418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 542dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkLazyPaint fLazyPaintInit; // base paint storage in case we need to modify it 543dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkLazyPaint fLazyPaintPerLooper; // per-draw-looper storage, so the looper can modify it 5442c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkCanvas* fCanvas; 5452c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint& fOrigPaint; 5462c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkDrawFilter* fFilter; 5472c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint* fPaint; 5482c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org int fSaveCount; 5494a8126e7f81384526629b1e21bf89b632ea13cd9reed uint32_t fNewPaintFlags; 5505c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed bool fTempLayerForImageFilter; 5512c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org bool fDone; 552129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool fIsSimple; 55379fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkDrawLooper::Context* fLooperContext; 55479fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkSmallAllocator<1, 32> fLooperContextAllocator; 555129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com 556129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool doNext(SkDrawFilter::Type drawType); 5578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 5588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 559129ec22cb054592261e001294c430c9dd4e90ff4reed@google.combool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) { 56096fcdcc219d2a0d3579719b84b28bede76efba64halcanary fPaint = nullptr; 561129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com SkASSERT(!fIsSimple); 5625c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed SkASSERT(fLooperContext || fFilter || fTempLayerForImageFilter); 563632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com 564dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkPaint* paint = fLazyPaintPerLooper.set(fLazyPaintInit.isValid() ? 565dbc3cefb0b624808ddb86d444e6103f216e12fa5reed *fLazyPaintInit.get() : fOrigPaint); 5664a8126e7f81384526629b1e21bf89b632ea13cd9reed paint->setFlags(fNewPaintFlags); 5678926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 5685c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed if (fTempLayerForImageFilter) { 56996fcdcc219d2a0d3579719b84b28bede76efba64halcanary paint->setImageFilter(nullptr); 57096fcdcc219d2a0d3579719b84b28bede76efba64halcanary paint->setXfermode(nullptr); 571129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 5728926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 57379fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (fLooperContext && !fLooperContext->next(fCanvas, paint)) { 574129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fDone = true; 575129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return false; 576129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 577129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com if (fFilter) { 578971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com if (!fFilter->filter(paint, drawType)) { 579971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com fDone = true; 580971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com return false; 581971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com } 58296fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == fLooperContext) { 583129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // no looper means we only draw once 584632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com fDone = true; 585632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com } 586129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 587129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fPaint = paint; 5888926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 589129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // if we only came in here for the imagefilter, mark us as done 59079fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (!fLooperContext && !fFilter) { 5914e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fDone = true; 5924e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 5934e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com 594632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com // call this after any possible paint modifiers 595632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com if (fPaint->nothingToDraw()) { 59696fcdcc219d2a0d3579719b84b28bede76efba64halcanary fPaint = nullptr; 5974e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return false; 5984e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 5994e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return true; 6004e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com} 6014e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com 6028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////// macros to place around the internal draw calls ////////////////// 6038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 604262a71b7f95ce98ff3dd8dba845afbd724470903reed#define LOOPER_BEGIN_DRAWBITMAP(paint, skipLayerForFilter, bounds) \ 605262a71b7f95ce98ff3dd8dba845afbd724470903reed this->predrawNotify(); \ 606262a71b7f95ce98ff3dd8dba845afbd724470903reed AutoDrawLooper looper(this, fProps, paint, skipLayerForFilter, bounds); \ 607262a71b7f95ce98ff3dd8dba845afbd724470903reed while (looper.next(SkDrawFilter::kBitmap_Type)) { \ 608262a71b7f95ce98ff3dd8dba845afbd724470903reed SkDrawIter iter(this); 609262a71b7f95ce98ff3dd8dba845afbd724470903reed 610262a71b7f95ce98ff3dd8dba845afbd724470903reed 6118926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com#define LOOPER_BEGIN_DRAWDEVICE(paint, type) \ 61297af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com this->predrawNotify(); \ 6134a8126e7f81384526629b1e21bf89b632ea13cd9reed AutoDrawLooper looper(this, fProps, paint, true); \ 6148926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com while (looper.next(type)) { \ 6158926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkDrawIter iter(this); 6168926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 61778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org#define LOOPER_BEGIN(paint, type, bounds) \ 61897af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com this->predrawNotify(); \ 6194a8126e7f81384526629b1e21bf89b632ea13cd9reed AutoDrawLooper looper(this, fProps, paint, false, bounds); \ 6204e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com while (looper.next(type)) { \ 6218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDrawIter iter(this); 6224b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 623c83a29759a5c2966da5ab973e4fd90763e4c962breed#define LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, type, bounds, auxOpaque) \ 624c83a29759a5c2966da5ab973e4fd90763e4c962breed this->predrawNotify(bounds, &paint, auxOpaque); \ 625c83a29759a5c2966da5ab973e4fd90763e4c962breed AutoDrawLooper looper(this, fProps, paint, false, bounds); \ 626c83a29759a5c2966da5ab973e4fd90763e4c962breed while (looper.next(type)) { \ 627c83a29759a5c2966da5ab973e4fd90763e4c962breed SkDrawIter iter(this); 628c83a29759a5c2966da5ab973e4fd90763e4c962breed 6294e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com#define LOOPER_END } 6308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////// 6328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 633feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtkleinvoid SkCanvas::resetForNextPicture(const SkIRect& bounds) { 634feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein this->restoreToCount(1); 635feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fCachedLocalClipBounds.setEmpty(); 636feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fCachedLocalClipBoundsDirty = true; 637feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fClipStack->reset(); 638feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fMCRec->reset(bounds); 639feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 640feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein // We're peering through a lot of structs here. Only at this scope do we 641feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein // know that the device is an SkBitmapDevice (really an SkNoPixelsBitmapDevice). 642feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein static_cast<SkBitmapDevice*>(fMCRec->fLayer->fDevice)->setNewSize(bounds.size()); 643feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein} 644feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 645d954498c01ccf0417feacf89e45d0c62a06a813breedSkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) { 64642b73eb00367c8315974b1c374308d20efa78897reed if (device && device->forceConservativeRasterClip()) { 64742b73eb00367c8315974b1c374308d20efa78897reed flags = InitFlags(flags | kConservativeRasterClip_InitFlag); 64842b73eb00367c8315974b1c374308d20efa78897reed } 64942b73eb00367c8315974b1c374308d20efa78897reed // Since init() is only called once by our constructors, it is safe to perform this 65042b73eb00367c8315974b1c374308d20efa78897reed // const-cast. 65142b73eb00367c8315974b1c374308d20efa78897reed *const_cast<bool*>(&fConservativeRasterClip) = SkToBool(flags & kConservativeRasterClip_InitFlag); 65242b73eb00367c8315974b1c374308d20efa78897reed 653c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBounds.setEmpty(); 654c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 6558f0a7b8e7334187a5d7d5ab7fde5a3c3009555f5caryclark@google.com fAllowSoftClip = true; 65645a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com fAllowSimplifyClip = false; 657f92c86642a1875da54d54b447f006cb9dfbbb35creed fDeviceCMDirty = true; 6582ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount = 1; 65996fcdcc219d2a0d3579719b84b28bede76efba64halcanary fMetaData = nullptr; 6608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 661385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary fClipStack.reset(new SkClipStack); 662687fa1c745febb57f42b0d5f03d7c1f4be2530careed 6638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = (MCRec*)fMCStack.push_back(); 664d954498c01ccf0417feacf89e45d0c62a06a813breed new (fMCRec) MCRec(fConservativeRasterClip); 6658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 666a499f905e9340e4935447f2562fd92e8853382b1reed SkASSERT(sizeof(DeviceCM) <= sizeof(fDeviceCMStorage)); 667a499f905e9340e4935447f2562fd92e8853382b1reed fMCRec->fLayer = (DeviceCM*)fDeviceCMStorage; 6688c30a8196dd5903d2d23b4d0a5dc888e802bf698reed new (fDeviceCMStorage) DeviceCM(nullptr, nullptr, nullptr, fConservativeRasterClip, false, 6698c30a8196dd5903d2d23b4d0a5dc888e802bf698reed fMCRec->fMatrix); 670b679ca8926a832274b14fdb512f88f64b61d32eareed 6718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fTopLayer = fMCRec->fLayer; 6728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 67396fcdcc219d2a0d3579719b84b28bede76efba64halcanary fSurfaceBase = nullptr; 674f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 675f92c86642a1875da54d54b447f006cb9dfbbb35creed if (device) { 676efbffedd68636e94d4379e84a2585bce80f6fb8frobertphillips // The root device and the canvas should always have the same pixel geometry 677efbffedd68636e94d4379e84a2585bce80f6fb8frobertphillips SkASSERT(fProps.pixelGeometry() == device->surfaceProps().pixelGeometry()); 678f92c86642a1875da54d54b447f006cb9dfbbb35creed device->onAttachToCanvas(this); 679f92c86642a1875da54d54b447f006cb9dfbbb35creed fMCRec->fLayer->fDevice = SkRef(device); 68078e276889795454891cbba48ab11927968114953reed fMCRec->fRasterClip.setRect(device->getGlobalBounds()); 681f92c86642a1875da54d54b447f006cb9dfbbb35creed } 682f92c86642a1875da54d54b447f006cb9dfbbb35creed return device; 6838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 685cde92111d50a96b6d0f3e166fbac7c9bc6eca349reed@google.comSkCanvas::SkCanvas() 686e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 6874a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 68842b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 689e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org{ 6908d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org inc_canvas(); 691ba124485687130183643994f1b4b68d629fbbebaskia.committer@gmail.com 69296fcdcc219d2a0d3579719b84b28bede76efba64halcanary this->init(nullptr, kDefault_InitFlags); 6938d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org} 6948d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org 695d954498c01ccf0417feacf89e45d0c62a06a813breedstatic SkBitmap make_nopixels(int width, int height) { 696d954498c01ccf0417feacf89e45d0c62a06a813breed SkBitmap bitmap; 697d954498c01ccf0417feacf89e45d0c62a06a813breed bitmap.setInfo(SkImageInfo::MakeUnknown(width, height)); 698d954498c01ccf0417feacf89e45d0c62a06a813breed return bitmap; 699d954498c01ccf0417feacf89e45d0c62a06a813breed} 700d954498c01ccf0417feacf89e45d0c62a06a813breed 701d954498c01ccf0417feacf89e45d0c62a06a813breedclass SkNoPixelsBitmapDevice : public SkBitmapDevice { 702d954498c01ccf0417feacf89e45d0c62a06a813breedpublic: 703fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips SkNoPixelsBitmapDevice(const SkIRect& bounds, const SkSurfaceProps& surfaceProps) 704fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips : INHERITED(make_nopixels(bounds.width(), bounds.height()), surfaceProps) 70578e276889795454891cbba48ab11927968114953reed { 70678e276889795454891cbba48ab11927968114953reed this->setOrigin(bounds.x(), bounds.y()); 70778e276889795454891cbba48ab11927968114953reed } 708d954498c01ccf0417feacf89e45d0c62a06a813breed 709d954498c01ccf0417feacf89e45d0c62a06a813breedprivate: 710b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 711d954498c01ccf0417feacf89e45d0c62a06a813breed typedef SkBitmapDevice INHERITED; 712d954498c01ccf0417feacf89e45d0c62a06a813breed}; 713d954498c01ccf0417feacf89e45d0c62a06a813breed 71496a857ef5a40b3d0751ec9ebaaa96d9f20b82b21reedSkCanvas::SkCanvas(int width, int height, const SkSurfaceProps* props) 715e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 71696a857ef5a40b3d0751ec9ebaaa96d9f20b82b21reed , fProps(SkSurfacePropsCopyOrDefault(props)) 71742b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 718e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org{ 719e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org inc_canvas(); 720b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 721385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary this->init(new SkNoPixelsBitmapDevice(SkIRect::MakeWH(width, height), fProps), 722385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary kDefault_InitFlags)->unref(); 723d954498c01ccf0417feacf89e45d0c62a06a813breed} 724e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org 72578e276889795454891cbba48ab11927968114953reedSkCanvas::SkCanvas(const SkIRect& bounds, InitFlags flags) 726d954498c01ccf0417feacf89e45d0c62a06a813breed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7274a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 72842b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 729d954498c01ccf0417feacf89e45d0c62a06a813breed{ 730d954498c01ccf0417feacf89e45d0c62a06a813breed inc_canvas(); 731b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 732385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary this->init(new SkNoPixelsBitmapDevice(bounds, fProps), flags)->unref(); 73327a5e656c3d6ef22f9cb34de18e1b960da3aa241reed} 7348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 735d954498c01ccf0417feacf89e45d0c62a06a813breedSkCanvas::SkCanvas(SkBaseDevice* device) 736d954498c01ccf0417feacf89e45d0c62a06a813breed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7377b05ff11ebc51f3f3abd1c1756337a04f563537erobertphillips , fProps(device->surfaceProps()) 73842b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 739d954498c01ccf0417feacf89e45d0c62a06a813breed{ 740d954498c01ccf0417feacf89e45d0c62a06a813breed inc_canvas(); 741b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 742d954498c01ccf0417feacf89e45d0c62a06a813breed this->init(device, kDefault_InitFlags); 7438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 745fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillipsSkCanvas::SkCanvas(SkBaseDevice* device, InitFlags flags) 746fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7477b05ff11ebc51f3f3abd1c1756337a04f563537erobertphillips , fProps(device->surfaceProps()) 74842b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 749fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips{ 750fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips inc_canvas(); 751fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips 752fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips this->init(device, flags); 753fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips} 754fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips 7554a8126e7f81384526629b1e21bf89b632ea13cd9reedSkCanvas::SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props) 7563716fd067a5621bb94a6cb08d72afec8bf3acedareed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7574a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(props) 75842b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 7593716fd067a5621bb94a6cb08d72afec8bf3acedareed{ 7603716fd067a5621bb94a6cb08d72afec8bf3acedareed inc_canvas(); 761b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 762385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary SkAutoTUnref<SkBaseDevice> device(new SkBitmapDevice(bitmap, fProps)); 7634a8126e7f81384526629b1e21bf89b632ea13cd9reed this->init(device, kDefault_InitFlags); 7644a8126e7f81384526629b1e21bf89b632ea13cd9reed} 76529c857d0f3a1cb837f73406eeb6ba9771879b5e7reed 7664a8126e7f81384526629b1e21bf89b632ea13cd9reedSkCanvas::SkCanvas(const SkBitmap& bitmap) 7674a8126e7f81384526629b1e21bf89b632ea13cd9reed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7684a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 76942b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 7704a8126e7f81384526629b1e21bf89b632ea13cd9reed{ 7714a8126e7f81384526629b1e21bf89b632ea13cd9reed inc_canvas(); 772b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 773385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary SkAutoTUnref<SkBaseDevice> device(new SkBitmapDevice(bitmap, fProps)); 7744a8126e7f81384526629b1e21bf89b632ea13cd9reed this->init(device, kDefault_InitFlags); 7758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::~SkCanvas() { 7788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // free up the contents of our deque 7798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->restoreToCount(1); // restore everything but the last 7807c2029367cea5479fa3b74fb0ca2b0297b42b709reed@google.com 7818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->internalRestore(); // restore the last, since we're going away 7828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 783385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete fMetaData; 784b70ae310bbdaa1b26786773aabce5548c1f48563vandebo@chromium.org 7858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dec_canvas(); 7868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 78853d9f1cfbd5ddbf57c2f22b9e613ce48e5b2896cfmalita#ifdef SK_SUPPORT_LEGACY_DRAWFILTER 7898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDrawFilter* SkCanvas::getDrawFilter() const { 7908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fMCRec->fFilter; 7918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDrawFilter* SkCanvas::setDrawFilter(SkDrawFilter* filter) { 79451985e3f5e608d369e52832b7ce489d85d402422reed this->checkForDeferredSave(); 7958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fMCRec->fFilter, filter); 7968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return filter; 7978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7987765000709dc64eb23be7df47d1f995d1f787115fmalita#endif 7998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 80074bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.orgSkMetaData& SkCanvas::getMetaData() { 80174bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org // metadata users are rare, so we lazily allocate it. If that changes we 80274bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org // can decide to just make it a field in the device (rather than a ptr) 80396fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == fMetaData) { 80474bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org fMetaData = new SkMetaData; 80574bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org } 80674bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org return *fMetaData; 80774bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org} 80874bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org 8098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 8108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 811bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.orgvoid SkCanvas::flush() { 8121f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* device = this->getDevice(); 813bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org if (device) { 814bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org device->flush(); 815bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org } 816bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org} 817bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org 818afc7cce5d68663934128d76963cd501f771d71desenorblancoSkISize SkCanvas::getBaseLayerSize() const { 819afc7cce5d68663934128d76963cd501f771d71desenorblanco SkBaseDevice* d = this->getDevice(); 8204ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com return d ? SkISize::Make(d->width(), d->height()) : SkISize::Make(0, 0); 8214ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com} 8224ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com 823afc7cce5d68663934128d76963cd501f771d71desenorblancoSkIRect SkCanvas::getTopLayerBounds() const { 8244ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com SkBaseDevice* d = this->getTopDevice(); 825afc7cce5d68663934128d76963cd501f771d71desenorblanco if (!d) { 826afc7cce5d68663934128d76963cd501f771d71desenorblanco return SkIRect::MakeEmpty(); 827afc7cce5d68663934128d76963cd501f771d71desenorblanco } 828afc7cce5d68663934128d76963cd501f771d71desenorblanco return SkIRect::MakeXYWH(d->getOrigin().x(), d->getOrigin().y(), d->width(), d->height()); 829210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com} 830210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com 8311f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::getDevice() const { 8328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // return root device 833c029062a0312fb747fb6c2677983aba51795c580robertphillips@google.com MCRec* rec = (MCRec*) fMCStack.front(); 8348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(rec && rec->fLayer); 8358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return rec->fLayer->fDevice; 8368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8381f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::getTopDevice(bool updateMatrixClip) const { 8390b53d59a24f667350b4282f88470713902409030reed@google.com if (updateMatrixClip) { 8400b53d59a24f667350b4282f88470713902409030reed@google.com const_cast<SkCanvas*>(this)->updateDeviceCMCache(); 8410b53d59a24f667350b4282f88470713902409030reed@google.com } 8429266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com return fMCRec->fTopLayer->fDevice; 8439266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com} 8449266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com 845a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.orgbool SkCanvas::readPixels(SkBitmap* bitmap, int x, int y) { 846a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (kUnknown_SkColorType == bitmap->colorType() || bitmap->getTexture()) { 847a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 848a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 849a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 850a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bool weAllocated = false; 85196fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == bitmap->pixelRef()) { 852848250415eddc54075f7eb8795e8db79e749c6abreed if (!bitmap->tryAllocPixels()) { 853a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 854a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 855a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org weAllocated = true; 856a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 857a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 858cf01e31df6bbda270dca2ee3b4967caf51e465dcreed SkAutoPixmapUnlock unlocker; 859cf01e31df6bbda270dca2ee3b4967caf51e465dcreed if (bitmap->requestLock(&unlocker)) { 860cf01e31df6bbda270dca2ee3b4967caf51e465dcreed const SkPixmap& pm = unlocker.pixmap(); 861cf01e31df6bbda270dca2ee3b4967caf51e465dcreed if (this->readPixels(pm.info(), pm.writable_addr(), pm.rowBytes(), x, y)) { 862cf01e31df6bbda270dca2ee3b4967caf51e465dcreed return true; 863cf01e31df6bbda270dca2ee3b4967caf51e465dcreed } 864a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 865a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 866a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (weAllocated) { 86796fcdcc219d2a0d3579719b84b28bede76efba64halcanary bitmap->setPixelRef(nullptr); 868a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 869a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 870a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org} 87151df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 872c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.combool SkCanvas::readPixels(const SkIRect& srcRect, SkBitmap* bitmap) { 873a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkIRect r = srcRect; 874a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 875a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!r.intersect(0, 0, size.width(), size.height())) { 876a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bitmap->reset(); 877ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com return false; 878ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com } 87974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 880848250415eddc54075f7eb8795e8db79e749c6abreed if (!bitmap->tryAllocN32Pixels(r.width(), r.height())) { 881a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org // bitmap will already be reset. 882a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 883a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 884a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!this->readPixels(bitmap->info(), bitmap->getPixels(), bitmap->rowBytes(), r.x(), r.y())) { 885a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bitmap->reset(); 886daba14b7d4fc96b915c45d82713b22729c0d0f37bsalomon@google.com return false; 887c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } 888a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return true; 889a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org} 890c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 89196472deea70169396b8e1f576e470138f55fdb1freedbool SkCanvas::readPixels(const SkImageInfo& dstInfo, void* dstP, size_t rowBytes, int x, int y) { 892a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkBaseDevice* device = this->getDevice(); 893a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!device) { 894a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 895a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 896a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 897f0f14113431ace669f278fdd97b50950f2cf4c80mtklein 89896472deea70169396b8e1f576e470138f55fdb1freed SkReadPixelsRec rec(dstInfo, dstP, rowBytes, x, y); 89996472deea70169396b8e1f576e470138f55fdb1freed if (!rec.trim(size.width(), size.height())) { 900a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 901a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 902db0c8753775774aa3f67114491e26ac1be32f38eskia.committer@gmail.com 903a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org // The device can assert that the requested area is always contained in its bounds 90496472deea70169396b8e1f576e470138f55fdb1freed return device->readPixels(rec.fInfo, rec.fPixels, rec.fRowBytes, rec.fX, rec.fY); 90551df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com} 90651df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 9074cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgbool SkCanvas::writePixels(const SkBitmap& bitmap, int x, int y) { 9084cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (bitmap.getTexture()) { 9094cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 9104cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 911cf01e31df6bbda270dca2ee3b4967caf51e465dcreed 912cf01e31df6bbda270dca2ee3b4967caf51e465dcreed SkAutoPixmapUnlock unlocker; 913cf01e31df6bbda270dca2ee3b4967caf51e465dcreed if (bitmap.requestLock(&unlocker)) { 914cf01e31df6bbda270dca2ee3b4967caf51e465dcreed const SkPixmap& pm = unlocker.pixmap(); 915cf01e31df6bbda270dca2ee3b4967caf51e465dcreed return this->writePixels(pm.info(), pm.addr(), pm.rowBytes(), x, y); 9164cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 9174cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 9184cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org} 9194cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 9204cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgbool SkCanvas::writePixels(const SkImageInfo& origInfo, const void* pixels, size_t rowBytes, 9214cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org int x, int y) { 9224cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org switch (origInfo.colorType()) { 9234cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org case kUnknown_SkColorType: 9244cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org case kIndex_8_SkColorType: 9254cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 9264cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org default: 9274cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org break; 9284cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 92996fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == pixels || rowBytes < origInfo.minRowBytes()) { 9304cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 9314cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 9324cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 9334cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 9344cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org SkIRect target = SkIRect::MakeXYWH(x, y, origInfo.width(), origInfo.height()); 9354cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (!target.intersect(0, 0, size.width(), size.height())) { 9364cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 9374cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 9384cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 9394cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org SkBaseDevice* device = this->getDevice(); 9404cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (!device) { 9414cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 9424cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 9434cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 9444cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // the intersect may have shrunk info's logical size 945e5ea500d4714a7d84de2bf913e81be3b65d2de68reed const SkImageInfo info = origInfo.makeWH(target.width(), target.height()); 9464cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 9474cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // if x or y are negative, then we have to adjust pixels 9484cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (x > 0) { 9494cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org x = 0; 9504cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 9514cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (y > 0) { 9524cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org y = 0; 9534cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 9544cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // here x,y are either 0 or negative 9554cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org pixels = ((const char*)pixels - y * rowBytes - x * info.bytesPerPixel()); 9564cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 9574af35f348b2e2f6c428819118eb7a2f2fff53a74reed // Tell our owning surface to bump its generation ID 958c83a29759a5c2966da5ab973e4fd90763e4c962breed const bool completeOverwrite = info.dimensions() == size; 959c83a29759a5c2966da5ab973e4fd90763e4c962breed this->predrawNotify(completeOverwrite); 9604af35f348b2e2f6c428819118eb7a2f2fff53a74reed 9614cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // The device can assert that the requested area is always contained in its bounds 9624ef54f8d72420a521d4aae04ff5cd438810eca7fcommit-bot@chromium.org return device->writePixels(info, pixels, rowBytes, target.x(), target.y()); 9634cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org} 96451df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 9654370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comSkCanvas* SkCanvas::canvasForDrawIter() { 9664370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com return this; 9674370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 9684370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 9698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 9708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::updateDeviceCMCache() { 9728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fDeviceCMDirty) { 9738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& totalMatrix = this->getTotalMatrix(); 9741f836ee096bb988adef4b9757b2629c7afeda36dreed const SkRasterClip& totalClip = fMCRec->fRasterClip; 9758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* layer = fMCRec->fTopLayer; 9764b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 97796fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == layer->fNext) { // only one layer 97896fcdcc219d2a0d3579719b84b28bede76efba64halcanary layer->updateMC(totalMatrix, totalClip, *fClipStack, nullptr); 9798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 980045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com SkRasterClip clip(totalClip); 9818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 982687fa1c745febb57f42b0d5f03d7c1f4be2530careed layer->updateMC(totalMatrix, clip, *fClipStack, &clip); 98396fcdcc219d2a0d3579719b84b28bede76efba64halcanary } while ((layer = layer->fNext) != nullptr); 9848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = false; 9868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 9908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9912ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::checkForDeferredSave() { 9922ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (fMCRec->fDeferredSaveCount > 0) { 9932ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->doSave(); 9942ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 9952ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed} 9962ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed 997f0090cb80ab10a49e511aa5450ae38917fa058d9reedint SkCanvas::getSaveCount() const { 9982ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed#ifdef SK_DEBUG 9992ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed int count = 0; 10002ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkDeque::Iter iter(fMCStack, SkDeque::Iter::kFront_IterStart); 10012ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed for (;;) { 10022ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed const MCRec* rec = (const MCRec*)iter.next(); 10032ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (!rec) { 10042ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed break; 10052ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 10062ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed count += 1 + rec->fDeferredSaveCount; 10072ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 10082ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(count == fSaveCount); 10092ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed#endif 10102ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return fSaveCount; 1011f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 1012f0090cb80ab10a49e511aa5450ae38917fa058d9reed 1013f0090cb80ab10a49e511aa5450ae38917fa058d9reedint SkCanvas::save() { 10142ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount += 1; 10152ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fMCRec->fDeferredSaveCount += 1; 10162ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return this->getSaveCount() - 1; // return our prev value 10172ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed} 10182ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed 10192ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::doSave() { 1020f0090cb80ab10a49e511aa5450ae38917fa058d9reed this->willSave(); 1021a62d32d1e3112c7e5a26c27e5e967d124ef8dd81fmalita 1022a62d32d1e3112c7e5a26c27e5e967d124ef8dd81fmalita SkASSERT(fMCRec->fDeferredSaveCount > 0); 1023a62d32d1e3112c7e5a26c27e5e967d124ef8dd81fmalita fMCRec->fDeferredSaveCount -= 1; 10242ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalSave(); 1025f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 1026f0090cb80ab10a49e511aa5450ae38917fa058d9reed 1027f0090cb80ab10a49e511aa5450ae38917fa058d9reedvoid SkCanvas::restore() { 10282ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (fMCRec->fDeferredSaveCount > 0) { 10292ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(fSaveCount > 1); 10302ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount -= 1; 10312ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fMCRec->fDeferredSaveCount -= 1; 10322ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } else { 10332ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed // check for underflow 10342ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (fMCStack.count() > 1) { 10352ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->willRestore(); 10362ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(fSaveCount > 1); 1037a644116c3375b12c642d1b51ee1e5cf4a22c1f5breed fSaveCount -= 1; 10382ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalRestore(); 10392ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->didRestore(); 10402ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 1041f0090cb80ab10a49e511aa5450ae38917fa058d9reed } 1042f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 1043f0090cb80ab10a49e511aa5450ae38917fa058d9reed 1044f0090cb80ab10a49e511aa5450ae38917fa058d9reedvoid SkCanvas::restoreToCount(int count) { 1045f0090cb80ab10a49e511aa5450ae38917fa058d9reed // sanity check 1046f0090cb80ab10a49e511aa5450ae38917fa058d9reed if (count < 1) { 1047f0090cb80ab10a49e511aa5450ae38917fa058d9reed count = 1; 1048f0090cb80ab10a49e511aa5450ae38917fa058d9reed } 1049f0f14113431ace669f278fdd97b50950f2cf4c80mtklein 1050f0090cb80ab10a49e511aa5450ae38917fa058d9reed int n = this->getSaveCount() - count; 1051f0090cb80ab10a49e511aa5450ae38917fa058d9reed for (int i = 0; i < n; ++i) { 1052f0090cb80ab10a49e511aa5450ae38917fa058d9reed this->restore(); 1053f0090cb80ab10a49e511aa5450ae38917fa058d9reed } 1054f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 1055f0090cb80ab10a49e511aa5450ae38917fa058d9reed 10562ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::internalSave() { 10578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com MCRec* newTop = (MCRec*)fMCStack.push_back(); 1058d954498c01ccf0417feacf89e45d0c62a06a813breed new (newTop) MCRec(*fMCRec); // balanced in restore() 10598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = newTop; 10604b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 1061687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->save(); 10628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10644960eeec4a1f2a772654883d7f3615d47bcd5dc3reedbool SkCanvas::BoundsAffectsClip(SaveLayerFlags saveLayerFlags) { 1065b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG 10664960eeec4a1f2a772654883d7f3615d47bcd5dc3reed return !(saveLayerFlags & SkCanvas::kDontClipToLayer_PrivateSaveLayerFlag); 1067b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#else 1068b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com return true; 1069b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#endif 10708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10724960eeec4a1f2a772654883d7f3615d47bcd5dc3reedbool SkCanvas::clipRectBounds(const SkRect* bounds, SaveLayerFlags saveLayerFlags, 10739b3aa54bc9605257c701cf465813f5fb1d7ba39ereed SkIRect* intersection, const SkImageFilter* imageFilter) { 1074bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect clipBounds; 1075bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (!this->getClipDeviceBounds(&clipBounds)) { 1076a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return false; 1077f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 1078c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org 107996e657d0e103b8358a77ecd913f6086929f792b8reed const SkMatrix& ctm = fMCRec->fMatrix; // this->getTotalMatrix() 108096e657d0e103b8358a77ecd913f6086929f792b8reed 1081c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org if (imageFilter) { 1082e5e79840ef38ab1d3f03abcf1b2df66fb9940018senorblanco clipBounds = imageFilter->filterBounds(clipBounds, ctm); 1083db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco if (bounds && !imageFilter->canComputeFastBounds()) { 1084db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco bounds = nullptr; 1085db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco } 1086c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org } 1087bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect ir; 108849f085dddff10473b6ebf832a974288300224e60bsalomon if (bounds) { 10898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 10904b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 109196e657d0e103b8358a77ecd913f6086929f792b8reed ctm.mapRect(&r, *bounds); 10928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.roundOut(&ir); 10938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // early exit if the layer's bounds are clipped out 10948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!ir.intersect(clipBounds)) { 10954960eeec4a1f2a772654883d7f3615d47bcd5dc3reed if (BoundsAffectsClip(saveLayerFlags)) { 10969b3aa54bc9605257c701cf465813f5fb1d7ba39ereed fCachedLocalClipBoundsDirty = true; 10971f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fRasterClip.setEmpty(); 1098bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1099a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return false; 11008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { // no user bounds, so just use the clip 11028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ir = clipBounds; 11038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1104180aec43451dd951fdaae81a92efc710ba093260reed SkASSERT(!ir.isEmpty()); 11058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11064960eeec4a1f2a772654883d7f3615d47bcd5dc3reed if (BoundsAffectsClip(saveLayerFlags)) { 1107180aec43451dd951fdaae81a92efc710ba093260reed // Simplify the current clips since they will be applied properly during restore() 11089b3aa54bc9605257c701cf465813f5fb1d7ba39ereed fCachedLocalClipBoundsDirty = true; 1109687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipDevRect(ir, SkRegion::kReplace_Op); 1110180aec43451dd951fdaae81a92efc710ba093260reed fMCRec->fRasterClip.setRect(ir); 1111a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org } 1112a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 1113a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org if (intersection) { 1114a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org *intersection = ir; 1115a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org } 1116a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return true; 1117a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org} 1118a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 11194960eeec4a1f2a772654883d7f3615d47bcd5dc3reed 11204960eeec4a1f2a772654883d7f3615d47bcd5dc3reedint SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint) { 11214960eeec4a1f2a772654883d7f3615d47bcd5dc3reed return this->saveLayer(SaveLayerRec(bounds, paint, 0)); 1122d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org} 1123d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org 11244960eeec4a1f2a772654883d7f3615d47bcd5dc3reedint SkCanvas::saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPaint* paint) { 11254960eeec4a1f2a772654883d7f3615d47bcd5dc3reed return this->saveLayer(SaveLayerRec(bounds, paint, kPreserveLCDText_SaveLayerFlag)); 11264960eeec4a1f2a772654883d7f3615d47bcd5dc3reed} 11274960eeec4a1f2a772654883d7f3615d47bcd5dc3reed 11284960eeec4a1f2a772654883d7f3615d47bcd5dc3reedint SkCanvas::saveLayer(const SaveLayerRec& origRec) { 11294960eeec4a1f2a772654883d7f3615d47bcd5dc3reed SaveLayerRec rec(origRec); 1130d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed if (gIgnoreSaveLayerBounds) { 11314960eeec4a1f2a772654883d7f3615d47bcd5dc3reed rec.fBounds = nullptr; 1132d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed } 11334960eeec4a1f2a772654883d7f3615d47bcd5dc3reed SaveLayerStrategy strategy = this->getSaveLayerStrategy(rec); 1134a644116c3375b12c642d1b51ee1e5cf4a22c1f5breed fSaveCount += 1; 11354960eeec4a1f2a772654883d7f3615d47bcd5dc3reed this->internalSaveLayer(rec, strategy); 11362ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return this->getSaveCount() - 1; 11378926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com} 11388926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 1139bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areedstatic void draw_filter_into_device(SkBaseDevice* src, const SkImageFilter* filter, 1140bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed SkBaseDevice* dst, const SkMatrix& ctm) { 11417354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips 11427354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips SkBitmap srcBM; 11437354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips 11447354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips#if SK_SUPPORT_GPU 11457354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips GrRenderTarget* srcRT = src->accessRenderTarget(); 11467354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips if (srcRT && !srcRT->asTexture() && dst->accessRenderTarget()) { 11477354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips // When both the src & the dst are on the gpu but the src doesn't have a texture, 11487354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips // we create a temporary texture for the draw. 11497354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips // TODO: we should actually only copy the portion of the source needed to apply the image 11507354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips // filter 11517354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips GrContext* context = srcRT->getContext(); 11525ec26ae9bfca635ccc98283aad5deda11519d826bsalomon SkAutoTUnref<GrTexture> tex(context->textureProvider()->createTexture(srcRT->desc(), 11535ec26ae9bfca635ccc98283aad5deda11519d826bsalomon SkBudgeted::kYes)); 11547354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips 11557354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips context->copySurface(tex, srcRT); 11567354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips 11577354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips GrWrapTextureInBitmap(tex, src->width(), src->height(), src->isOpaque(), &srcBM); 11587354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips } else 11597354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips#endif 11607354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips { 11617354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips srcBM = src->accessBitmap(false); 11627354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips } 11637354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips 11647354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips SkCanvas c(dst); 11657354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips 11667354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips SkPaint p; 1167372177ee115d46dfb5bfb881a408e6c37ae83678robertphillips p.setImageFilter(filter->makeWithLocalMatrix(ctm)); 1168bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed const SkScalar x = SkIntToScalar(src->getOrigin().x()); 1169bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed const SkScalar y = SkIntToScalar(src->getOrigin().y()); 1170bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed c.drawBitmap(srcBM, x, y, &p); 11717354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips} 117270ee31b2fa127eee6c0cea61cf05508e9d3ca7b1reed 1173129ed1cd6d792f3f6cf563aefa9756fc6308289dreedstatic SkImageInfo make_layer_info(const SkImageInfo& prev, int w, int h, bool isOpaque, 1174129ed1cd6d792f3f6cf563aefa9756fc6308289dreed const SkPaint* paint) { 1175129ed1cd6d792f3f6cf563aefa9756fc6308289dreed // need to force L32 for now if we have an image filter. Once filters support other colortypes 1176129ed1cd6d792f3f6cf563aefa9756fc6308289dreed // e.g. sRGB or F16, we can remove this check 1177129ed1cd6d792f3f6cf563aefa9756fc6308289dreed const bool hasImageFilter = paint && paint->getImageFilter(); 1178129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 1179129ed1cd6d792f3f6cf563aefa9756fc6308289dreed SkAlphaType alphaType = isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType; 1180129ed1cd6d792f3f6cf563aefa9756fc6308289dreed if ((prev.bytesPerPixel() < 4) || hasImageFilter) { 1181129ed1cd6d792f3f6cf563aefa9756fc6308289dreed // force to L32 1182129ed1cd6d792f3f6cf563aefa9756fc6308289dreed return SkImageInfo::MakeN32(w, h, alphaType); 1183129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } else { 1184129ed1cd6d792f3f6cf563aefa9756fc6308289dreed // keep the same characteristics as the prev 1185129ed1cd6d792f3f6cf563aefa9756fc6308289dreed return SkImageInfo::Make(w, h, prev.colorType(), alphaType, prev.profileType()); 1186129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 1187129ed1cd6d792f3f6cf563aefa9756fc6308289dreed} 1188129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 11894960eeec4a1f2a772654883d7f3615d47bcd5dc3reedvoid SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy strategy) { 11904960eeec4a1f2a772654883d7f3615d47bcd5dc3reed const SkRect* bounds = rec.fBounds; 11914960eeec4a1f2a772654883d7f3615d47bcd5dc3reed const SkPaint* paint = rec.fPaint; 11924960eeec4a1f2a772654883d7f3615d47bcd5dc3reed SaveLayerFlags saveLayerFlags = rec.fSaveLayerFlags; 11934960eeec4a1f2a772654883d7f3615d47bcd5dc3reed 1194b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG 11954960eeec4a1f2a772654883d7f3615d47bcd5dc3reed saveLayerFlags &= ~kDontClipToLayer_PrivateSaveLayerFlag; 1196b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#endif 1197b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com 11988c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkLazyPaint lazyP; 11998c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkImageFilter* imageFilter = paint ? paint->getImageFilter() : NULL; 12008c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkMatrix stashedMatrix = fMCRec->fMatrix; 12018c30a8196dd5903d2d23b4d0a5dc888e802bf698reed#ifndef SK_SUPPORT_LEGACY_IMAGEFILTER_CTM 12028c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkMatrix remainder; 12038c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkSize scale; 12048c30a8196dd5903d2d23b4d0a5dc888e802bf698reed /* 12058c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * ImageFilters (so far) do not correctly handle matrices (CTM) that contain rotation/skew/etc. 12068c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * but they do handle scaling. To accommodate this, we do the following: 12078c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 12088c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 1. Stash off the current CTM 12098c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 2. Decompose the CTM into SCALE and REMAINDER 12108c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 3. Wack the CTM to be just SCALE, and wrap the imagefilter with a MatrixImageFilter that 12118c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * contains the REMAINDER 12128c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 4. Proceed as usual, allowing the client to draw into the layer (now with a scale-only CTM) 12138c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 5. During restore, we process the MatrixImageFilter, which applies REMAINDER to the output 12148c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * of the original imagefilter, and draw that (via drawSprite) 12158c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 6. Unwack the CTM to its original state (i.e. stashedMatrix) 12168c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 12178c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * Perhaps in the future we could augment #5 to apply REMAINDER as part of the draw (no longer 12188c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * a sprite operation) to avoid the extra buffer/overhead of MatrixImageFilter. 12198c30a8196dd5903d2d23b4d0a5dc888e802bf698reed */ 122096a04f329926099f0002f97883242793ff04f61creed if (imageFilter && !stashedMatrix.isScaleTranslate() && !imageFilter->canHandleComplexCTM() && 12218c30a8196dd5903d2d23b4d0a5dc888e802bf698reed stashedMatrix.decomposeScale(&scale, &remainder)) 12228c30a8196dd5903d2d23b4d0a5dc888e802bf698reed { 12238c30a8196dd5903d2d23b4d0a5dc888e802bf698reed // We will restore the matrix (which we are overwriting here) in restore via fStashedMatrix 12248c30a8196dd5903d2d23b4d0a5dc888e802bf698reed this->internalSetMatrix(SkMatrix::MakeScale(scale.width(), scale.height())); 12258c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkPaint* p = lazyP.set(*paint); 12268c30a8196dd5903d2d23b4d0a5dc888e802bf698reed p->setImageFilter(SkImageFilter::MakeMatrixFilter(remainder, 12278c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkFilterQuality::kLow_SkFilterQuality, 12288c30a8196dd5903d2d23b4d0a5dc888e802bf698reed sk_ref_sp(imageFilter))); 12298c30a8196dd5903d2d23b4d0a5dc888e802bf698reed imageFilter = p->getImageFilter(); 12308c30a8196dd5903d2d23b4d0a5dc888e802bf698reed paint = p; 12318c30a8196dd5903d2d23b4d0a5dc888e802bf698reed } 12328c30a8196dd5903d2d23b4d0a5dc888e802bf698reed#endif 12338c30a8196dd5903d2d23b4d0a5dc888e802bf698reed 1234a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org // do this before we create the layer. We don't call the public save() since 1235a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org // that would invoke a possibly overridden virtual 12362ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalSave(); 1237a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 1238a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org fDeviceCMDirty = true; 1239a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 1240a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org SkIRect ir; 12418c30a8196dd5903d2d23b4d0a5dc888e802bf698reed if (!this->clipRectBounds(bounds, saveLayerFlags, &ir, imageFilter)) { 12422ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 12438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1245e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy really care about 1246e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org // the clipRectBounds() call above? 1247e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org if (kNoLayer_SaveLayerStrategy == strategy) { 12482ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 1249e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org } 1250e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org 12514960eeec4a1f2a772654883d7f3615d47bcd5dc3reed bool isOpaque = SkToBool(saveLayerFlags & kIsOpaque_SaveLayerFlag); 12528dc0ccb8d33d1af7dd13228509e61fe915bc7705reed SkPixelGeometry geo = fProps.pixelGeometry(); 12538dc0ccb8d33d1af7dd13228509e61fe915bc7705reed if (paint) { 125476033be81b82c44fd5d4fdf2672eb22e505da1f0reed // TODO: perhaps add a query to filters so we might preserve opaqueness... 1255daa57bfd4204f5a7d304c580bcf5ad99d0121e1freed if (paint->getImageFilter() || paint->getColorFilter()) { 125676033be81b82c44fd5d4fdf2672eb22e505da1f0reed isOpaque = false; 12578dc0ccb8d33d1af7dd13228509e61fe915bc7705reed geo = kUnknown_SkPixelGeometry; 1258b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com } 1259b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com } 12608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1261b2db898573e3cdcc8234eebf51961bfc4977ebbcreed SkBaseDevice* device = this->getTopDevice(); 126296fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == device) { 1263b2db898573e3cdcc8234eebf51961bfc4977ebbcreed SkDebugf("Unable to find device for layer."); 12642ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 1265b2db898573e3cdcc8234eebf51961bfc4977ebbcreed } 1266b2db898573e3cdcc8234eebf51961bfc4977ebbcreed 1267129ed1cd6d792f3f6cf563aefa9756fc6308289dreed SkImageInfo info = make_layer_info(device->imageInfo(), ir.width(), ir.height(), isOpaque, 1268129ed1cd6d792f3f6cf563aefa9756fc6308289dreed paint); 1269129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 127061f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed bool forceSpriteOnRestore = false; 127161f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed { 127270ee31b2fa127eee6c0cea61cf05508e9d3ca7b1reed const bool preserveLCDText = kOpaque_SkAlphaType == info.alphaType() || 12734960eeec4a1f2a772654883d7f3615d47bcd5dc3reed (saveLayerFlags & kPreserveLCDText_SaveLayerFlag); 1274daa57bfd4204f5a7d304c580bcf5ad99d0121e1freed const SkBaseDevice::TileUsage usage = SkBaseDevice::kNever_TileUsage; 127570ee31b2fa127eee6c0cea61cf05508e9d3ca7b1reed const SkBaseDevice::CreateInfo createInfo = SkBaseDevice::CreateInfo(info, usage, geo, 127670ee31b2fa127eee6c0cea61cf05508e9d3ca7b1reed preserveLCDText, false); 127761f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed SkBaseDevice* newDev = device->onCreateDevice(createInfo, paint); 127896fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == newDev) { 127961f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed // If onCreateDevice didn't succeed, try raster (e.g. PDF couldn't handle the paint) 12809a53fd7c41554630124522f4b6eedc16912abbb7robertphillips const SkSurfaceProps surfaceProps(fProps.flags(), createInfo.fPixelGeometry); 12819a53fd7c41554630124522f4b6eedc16912abbb7robertphillips newDev = SkBitmapDevice::Create(createInfo.fInfo, surfaceProps); 128296fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == newDev) { 128361f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed SkErrorInternals::SetError(kInternalError_SkError, 128461f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed "Unable to create device for layer."); 128561f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed return; 128661f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed } 128761f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed forceSpriteOnRestore = true; 128861f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed } 128961f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed device = newDev; 1290e25c68402b38ac01dc1ae196ae8a5265b773c5f2bungeman@google.com } 12916f8f292aa768869a9e85c314b124875f57504f2creed@google.com device->setOrigin(ir.fLeft, ir.fTop); 12927354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips 1293bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed if (rec.fBackdrop) { 1294bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed draw_filter_into_device(fMCRec->fTopLayer->fDevice, rec.fBackdrop, device, fMCRec->fMatrix); 12957354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips } 12967354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips 12978c30a8196dd5903d2d23b4d0a5dc888e802bf698reed DeviceCM* layer = new DeviceCM(device, paint, this, fConservativeRasterClip, 12988c30a8196dd5903d2d23b4d0a5dc888e802bf698reed forceSpriteOnRestore, stashedMatrix); 12998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device->unref(); 13008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com layer->fNext = fMCRec->fTopLayer; 13028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fLayer = layer; 13038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fTopLayer = layer; // this field is NOT an owner of layer 13048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1306d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.orgint SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) { 1307bada1885da479d948f065182d6dfa85a1140bda5reed if (0xFF == alpha) { 1308bada1885da479d948f065182d6dfa85a1140bda5reed return this->saveLayer(bounds, nullptr); 1309bada1885da479d948f065182d6dfa85a1140bda5reed } else { 1310bada1885da479d948f065182d6dfa85a1140bda5reed SkPaint tmpPaint; 1311bada1885da479d948f065182d6dfa85a1140bda5reed tmpPaint.setAlpha(alpha); 1312bada1885da479d948f065182d6dfa85a1140bda5reed return this->saveLayer(bounds, &tmpPaint); 1313bada1885da479d948f065182d6dfa85a1140bda5reed } 1314d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org} 1315d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org 13168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::internalRestore() { 13178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fMCStack.count() != 0); 13188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1320c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 13218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1322687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->restore(); 13236c157640c27ee2ed6f9a484d21691b7b19dfecdecommit-bot@chromium.org 132488edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com // reserve our layer (if any) 13258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* layer = fMCRec->fLayer; // may be null 13268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now detach it from fMCRec so we can pop(). Gets freed after its drawn 132796fcdcc219d2a0d3579719b84b28bede76efba64halcanary fMCRec->fLayer = nullptr; 13288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now do the normal restore() 13308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->~MCRec(); // balanced in save() 13318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCStack.pop_back(); 13328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = (MCRec*)fMCStack.back(); 13338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* Time to draw the layer's offscreen. We can't call the public drawSprite, 13358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com since if we're being recorded, we don't want to record this (the 13368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com recorder will have already recorded the restore). 13378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 133849f085dddff10473b6ebf832a974288300224e60bsalomon if (layer) { 13398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (layer->fNext) { 13406f8f292aa768869a9e85c314b124875f57504f2creed@google.com const SkIPoint& origin = layer->fDevice->getOrigin(); 13418926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(), 134261f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed layer->fPaint, layer->fDeviceIsBitmapDevice); 13438c30a8196dd5903d2d23b4d0a5dc888e802bf698reed // restore what we smashed in internalSaveLayer 13448c30a8196dd5903d2d23b4d0a5dc888e802bf698reed fMCRec->fMatrix = layer->fStashedMatrix; 13458926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com // reset this, since internalDrawDevice will have set it to true 13468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1347385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete layer; 1348b679ca8926a832274b14fdb512f88f64b61d32eareed } else { 1349b679ca8926a832274b14fdb512f88f64b61d32eareed // we're at the root 1350a499f905e9340e4935447f2562fd92e8853382b1reed SkASSERT(layer == (void*)fDeviceCMStorage); 1351b679ca8926a832274b14fdb512f88f64b61d32eareed layer->~DeviceCM(); 13528c30a8196dd5903d2d23b4d0a5dc888e802bf698reed // no need to update fMCRec, 'cause we're killing the canvas 13538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 135488edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 13558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1357e8f3062a36d3682f4019309a32b5b84dc9eddf8creedsk_sp<SkSurface> SkCanvas::makeSurface(const SkImageInfo& info, const SkSurfaceProps* props) { 135896fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == props) { 13594a8126e7f81384526629b1e21bf89b632ea13cd9reed props = &fProps; 13604a8126e7f81384526629b1e21bf89b632ea13cd9reed } 13614a8126e7f81384526629b1e21bf89b632ea13cd9reed return this->onNewSurface(info, *props); 136276f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com} 136376f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com 1364e8f3062a36d3682f4019309a32b5b84dc9eddf8creedsk_sp<SkSurface> SkCanvas::onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props) { 136576f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com SkBaseDevice* dev = this->getDevice(); 1366e8f3062a36d3682f4019309a32b5b84dc9eddf8creed return dev ? dev->makeSurface(info, props) : nullptr; 136776f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com} 136876f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com 1369c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgSkImageInfo SkCanvas::imageInfo() const { 1370c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkBaseDevice* dev = this->getDevice(); 1371c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (dev) { 1372c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return dev->imageInfo(); 1373c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } else { 1374900ecf2f1579d42c9d2959831787af0346320f86reed@google.com return SkImageInfo::MakeUnknown(0, 0); 1375c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1376c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1377c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1378898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosmanbool SkCanvas::getProps(SkSurfaceProps* props) const { 1379898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman SkBaseDevice* dev = this->getDevice(); 1380898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman if (dev) { 1381898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman if (props) { 1382898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman *props = fProps; 1383898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman } 1384898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman return true; 1385898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman } else { 1386898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman return false; 1387898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman } 1388898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman} 1389898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman 13906ceeebd37a43d879c120b6ba100ae1febdd67a18reed#ifdef SK_SUPPORT_LEGACY_PEEKPIXELS_PARMS 1391c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgconst void* SkCanvas::peekPixels(SkImageInfo* info, size_t* rowBytes) { 1392884e97cb04db7ed053a866567ee9c6e4c01f993areed SkPixmap pmap; 13936ceeebd37a43d879c120b6ba100ae1febdd67a18reed if (this->peekPixels(&pmap)) { 13946ceeebd37a43d879c120b6ba100ae1febdd67a18reed if (info) { 13956ceeebd37a43d879c120b6ba100ae1febdd67a18reed *info = pmap.info(); 13966ceeebd37a43d879c120b6ba100ae1febdd67a18reed } 13976ceeebd37a43d879c120b6ba100ae1febdd67a18reed if (rowBytes) { 13986ceeebd37a43d879c120b6ba100ae1febdd67a18reed *rowBytes = pmap.rowBytes(); 13996ceeebd37a43d879c120b6ba100ae1febdd67a18reed } 14006ceeebd37a43d879c120b6ba100ae1febdd67a18reed return pmap.addr(); 1401884e97cb04db7ed053a866567ee9c6e4c01f993areed } 14026ceeebd37a43d879c120b6ba100ae1febdd67a18reed return nullptr; 14036ceeebd37a43d879c120b6ba100ae1febdd67a18reed} 14046ceeebd37a43d879c120b6ba100ae1febdd67a18reed#endif 14056ceeebd37a43d879c120b6ba100ae1febdd67a18reed 14066ceeebd37a43d879c120b6ba100ae1febdd67a18reedbool SkCanvas::peekPixels(SkPixmap* pmap) { 14076ceeebd37a43d879c120b6ba100ae1febdd67a18reed return this->onPeekPixels(pmap); 1408c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1409c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1410884e97cb04db7ed053a866567ee9c6e4c01f993areedbool SkCanvas::onPeekPixels(SkPixmap* pmap) { 1411c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkBaseDevice* dev = this->getDevice(); 1412884e97cb04db7ed053a866567ee9c6e4c01f993areed return dev && dev->peekPixels(pmap); 1413c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1414c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 14156b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.orgvoid* SkCanvas::accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin) { 1416884e97cb04db7ed053a866567ee9c6e4c01f993areed SkPixmap pmap; 1417884e97cb04db7ed053a866567ee9c6e4c01f993areed if (!this->onAccessTopLayerPixels(&pmap)) { 141896fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 1419884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1420884e97cb04db7ed053a866567ee9c6e4c01f993areed if (info) { 1421884e97cb04db7ed053a866567ee9c6e4c01f993areed *info = pmap.info(); 1422884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1423884e97cb04db7ed053a866567ee9c6e4c01f993areed if (rowBytes) { 1424884e97cb04db7ed053a866567ee9c6e4c01f993areed *rowBytes = pmap.rowBytes(); 1425884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1426884e97cb04db7ed053a866567ee9c6e4c01f993areed if (origin) { 14276b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org *origin = this->getTopDevice(false)->getOrigin(); 14286b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org } 1429884e97cb04db7ed053a866567ee9c6e4c01f993areed return pmap.writable_addr(); 14309c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 14319c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1432884e97cb04db7ed053a866567ee9c6e4c01f993areedbool SkCanvas::onAccessTopLayerPixels(SkPixmap* pmap) { 14339c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com SkBaseDevice* dev = this->getTopDevice(); 1434884e97cb04db7ed053a866567ee9c6e4c01f993areed return dev && dev->accessPixels(pmap); 14359c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 14369c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1437520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org///////////////////////////////////////////////////////////////////////////// 14388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14391f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comvoid SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, 144061f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed const SkPaint* paint, bool deviceIsBitmapDevice) { 14418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint tmp; 144296fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 14438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint = &tmp; 14448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 14454b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 14468926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com LOOPER_BEGIN_DRAWDEVICE(*paint, SkDrawFilter::kBitmap_Type) 14478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 14481f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* dstDev = iter.fDevice; 144976dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com paint = &looper.paint(); 145076dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkImageFilter* filter = paint->getImageFilter(); 145176dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkIPoint pos = { x - iter.getX(), y - iter.getY() }; 1452f35566e8a2497cd7c7bcfeee00c507b3e8ba1587senorblanco if (filter) { 14536776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org SkIPoint offset = SkIPoint::Make(0, 0); 14544418dbac3386f26c8da62ab242be9c178961eb18robertphillips const SkBitmap& srcBM = srcDev->accessBitmap(false); 1455fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org SkMatrix matrix = *iter.fMatrix; 1456d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org matrix.postTranslate(SkIntToScalar(-pos.x()), SkIntToScalar(-pos.y())); 14574418dbac3386f26c8da62ab242be9c178961eb18robertphillips const SkIRect clipBounds = iter.fClip->getBounds().makeOffset(-pos.x(), -pos.y()); 1458be129b26f13d575fd6b396c6ae759838ecc9bd1asenorblanco SkAutoTUnref<SkImageFilter::Cache> cache(dstDev->getImageFilterCache()); 14594e23cdaa6b892afeaa150c6d74099dc6c2065b7ereed SkImageFilter::Context ctx(matrix, clipBounds, cache.get()); 14604418dbac3386f26c8da62ab242be9c178961eb18robertphillips 14613e302275b324172c845627cbd00cee8a06571bafrobertphillips sk_sp<SkSpecialImage> srcImg(SkSpecialImage::internal_fromBM(srcBM, 1462898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman &dstDev->surfaceProps())); 14634418dbac3386f26c8da62ab242be9c178961eb18robertphillips if (!srcImg) { 14644418dbac3386f26c8da62ab242be9c178961eb18robertphillips continue; // something disastrous happened 14654418dbac3386f26c8da62ab242be9c178961eb18robertphillips } 14664418dbac3386f26c8da62ab242be9c178961eb18robertphillips 14672302de920e5434809bd0e85b871a6e002856dfdbrobertphillips sk_sp<SkSpecialImage> resultImg(filter->filterImage(srcImg.get(), ctx, &offset)); 14684418dbac3386f26c8da62ab242be9c178961eb18robertphillips if (resultImg) { 14695efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com SkPaint tmpUnfiltered(*paint); 147096fcdcc219d2a0d3579719b84b28bede76efba64halcanary tmpUnfiltered.setImageFilter(nullptr); 14714418dbac3386f26c8da62ab242be9c178961eb18robertphillips SkBitmap resultBM; 14724418dbac3386f26c8da62ab242be9c178961eb18robertphillips if (resultImg->internal_getBM(&resultBM)) { 14734418dbac3386f26c8da62ab242be9c178961eb18robertphillips // TODO: add drawSprite(SkSpecialImage) to SkDevice? (see skbug.com/5073) 14744418dbac3386f26c8da62ab242be9c178961eb18robertphillips dstDev->drawSprite(iter, resultBM, pos.x() + offset.x(), pos.y() + offset.y(), 14754418dbac3386f26c8da62ab242be9c178961eb18robertphillips tmpUnfiltered); 14764418dbac3386f26c8da62ab242be9c178961eb18robertphillips } 147776dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } 147861f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed } else if (deviceIsBitmapDevice) { 14799572a10c9a6a868bbb8f71d7806d0a45f183333freed const SkBitmap& src = static_cast<SkBitmapDevice*>(srcDev)->fBitmap; 148061f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed dstDev->drawSprite(iter, src, pos.x(), pos.y(), *paint); 148176dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } else { 1482b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com dstDev->drawDevice(iter, srcDev, pos.x(), pos.y(), *paint); 148376dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } 14848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 14854e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 14868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 148832704674f64cb6a14356dfebe060cd3484c06cc7reed///////////////////////////////////////////////////////////////////////////// 1489da420b976e61071cfe5de10556b4b23e519091d6reed 149092362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::translate(SkScalar dx, SkScalar dy) { 1491d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1492d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setTranslate(dx, dy); 1493d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 14948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 149692362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::scale(SkScalar sx, SkScalar sy) { 1497d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1498d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setScale(sx, sy); 1499d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 15008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 15018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 150292362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::rotate(SkScalar degrees) { 1503d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1504d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setRotate(degrees); 1505d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 15068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 15078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 150892362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::skew(SkScalar sx, SkScalar sy) { 1509d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1510d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setSkew(sx, sy); 1511d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 151244c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org} 151344c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 151492362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::concat(const SkMatrix& matrix) { 1515d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org if (matrix.isIdentity()) { 1516d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org return; 1517d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org } 1518d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org 15192ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 15208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1521c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 15221f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix.preConcat(matrix); 152344c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 152444c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org this->didConcat(matrix); 152544c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org} 152644c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 15278c30a8196dd5903d2d23b4d0a5dc888e802bf698reedvoid SkCanvas::internalSetMatrix(const SkMatrix& matrix) { 15288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1529c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 15301f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix = matrix; 15318c30a8196dd5903d2d23b4d0a5dc888e802bf698reed} 15328c30a8196dd5903d2d23b4d0a5dc888e802bf698reed 15338c30a8196dd5903d2d23b4d0a5dc888e802bf698reedvoid SkCanvas::setMatrix(const SkMatrix& matrix) { 15348c30a8196dd5903d2d23b4d0a5dc888e802bf698reed this->checkForDeferredSave(); 15358c30a8196dd5903d2d23b4d0a5dc888e802bf698reed this->internalSetMatrix(matrix); 153644c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org this->didSetMatrix(matrix); 15378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 15388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 15398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::resetMatrix() { 15408c30a8196dd5903d2d23b4d0a5dc888e802bf698reed this->setMatrix(SkMatrix::I()); 15418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 15428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 15438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 15448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1545759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { 15462ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 15478f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 15488f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(rect, op, edgeStyle); 15498f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 15508f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 15518f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 1552da17f758442f16747af39f8fbaed9c097048519creed@google.com#ifdef SK_ENABLE_CLIP_QUICKREJECT 1553da17f758442f16747af39f8fbaed9c097048519creed@google.com if (SkRegion::kIntersect_Op == op) { 15541f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fRasterClip.isEmpty()) { 1555da17f758442f16747af39f8fbaed9c097048519creed@google.com return false; 1556da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1557da17f758442f16747af39f8fbaed9c097048519creed@google.com 15583b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(rect)) { 1559da17f758442f16747af39f8fbaed9c097048519creed@google.com fDeviceCMDirty = true; 1560c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 1561da17f758442f16747af39f8fbaed9c097048519creed@google.com 1562687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipEmpty(); 15631f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.setEmpty(); 1564da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1565da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1566da17f758442f16747af39f8fbaed9c097048519creed@google.com#endif 1567da17f758442f16747af39f8fbaed9c097048519creed@google.com 1568ac8cabd729c75fdf774c0701b6ea7fd3ea5b9382bsalomon if (!fAllowSoftClip) { 1569ac8cabd729c75fdf774c0701b6ea7fd3ea5b9382bsalomon edgeStyle = kHard_ClipEdgeStyle; 1570ac8cabd729c75fdf774c0701b6ea7fd3ea5b9382bsalomon } 1571ac8cabd729c75fdf774c0701b6ea7fd3ea5b9382bsalomon 1572c64eff55049b1192052b791549a32a03be1c43e3reed const bool rectStaysRect = fMCRec->fMatrix.rectStaysRect(); 1573c64eff55049b1192052b791549a32a03be1c43e3reed SkRect devR; 1574c64eff55049b1192052b791549a32a03be1c43e3reed if (rectStaysRect) { 1575c64eff55049b1192052b791549a32a03be1c43e3reed fMCRec->fMatrix.mapRect(&devR, rect); 1576c64eff55049b1192052b791549a32a03be1c43e3reed } 1577c64eff55049b1192052b791549a32a03be1c43e3reed 1578c64eff55049b1192052b791549a32a03be1c43e3reed // Check if we can quick-accept the clip call (and do nothing) 1579c64eff55049b1192052b791549a32a03be1c43e3reed // 1580c64eff55049b1192052b791549a32a03be1c43e3reed // TODO: investigate if a (conservative) version of this could be done in ::clipRect, 1581c64eff55049b1192052b791549a32a03be1c43e3reed // so that subclasses (like PictureRecording) didn't see unnecessary clips, which in turn 1582c64eff55049b1192052b791549a32a03be1c43e3reed // might allow lazy save/restores to eliminate entire save/restore blocks. 1583c64eff55049b1192052b791549a32a03be1c43e3reed // 1584c64eff55049b1192052b791549a32a03be1c43e3reed if (SkRegion::kIntersect_Op == op && 1585c64eff55049b1192052b791549a32a03be1c43e3reed kHard_ClipEdgeStyle == edgeStyle 1586c64eff55049b1192052b791549a32a03be1c43e3reed && rectStaysRect) 1587c64eff55049b1192052b791549a32a03be1c43e3reed { 1588c64eff55049b1192052b791549a32a03be1c43e3reed if (devR.round().contains(fMCRec->fRasterClip.getBounds())) { 1589c64eff55049b1192052b791549a32a03be1c43e3reed#if 0 1590c64eff55049b1192052b791549a32a03be1c43e3reed SkDebugf("------- ignored clipRect [%g %g %g %g]\n", 1591c64eff55049b1192052b791549a32a03be1c43e3reed rect.left(), rect.top(), rect.right(), rect.bottom()); 1592c64eff55049b1192052b791549a32a03be1c43e3reed#endif 1593c64eff55049b1192052b791549a32a03be1c43e3reed return; 1594c64eff55049b1192052b791549a32a03be1c43e3reed } 1595c64eff55049b1192052b791549a32a03be1c43e3reed } 1596c64eff55049b1192052b791549a32a03be1c43e3reed 1597c64eff55049b1192052b791549a32a03be1c43e3reed AutoValidateClip avc(this); 1598c64eff55049b1192052b791549a32a03be1c43e3reed 1599c64eff55049b1192052b791549a32a03be1c43e3reed fDeviceCMDirty = true; 1600c64eff55049b1192052b791549a32a03be1c43e3reed fCachedLocalClipBoundsDirty = true; 16018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1602c64eff55049b1192052b791549a32a03be1c43e3reed if (rectStaysRect) { 1603c64eff55049b1192052b791549a32a03be1c43e3reed const bool isAA = kSoft_ClipEdgeStyle == edgeStyle; 1604c64eff55049b1192052b791549a32a03be1c43e3reed fClipStack->clipDevRect(devR, op, isAA); 1605afc7cce5d68663934128d76963cd501f771d71desenorblanco fMCRec->fRasterClip.op(devR, this->getTopLayerBounds(), op, isAA); 16068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 1607123671901abfa595d09ca789b487c4bc7c1f7cbcrobertphillips@google.com // since we're rotated or some such thing, we convert the rect to a path 160898de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // and clip against that, since it can handle any matrix. However, to 160998de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // avoid recursion in the case where we are subclassed (e.g. Pictures) 161098de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // we explicitly call "our" version of clipPath. 16118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath path; 16128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.addRect(rect); 16148f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->SkCanvas::onClipPath(path, op, edgeStyle); 16158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 16168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1618759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) { 16192ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 16208f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 16214ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (rrect.isRect()) { 16228f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(rrect.getBounds(), op, edgeStyle); 16238f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } else { 16248f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRRect(rrect, op, edgeStyle); 16254ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 16268f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 162714e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 16288f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 162914e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org SkRRect transformedRRect; 16301f836ee096bb988adef4b9757b2629c7afeda36dreed if (rrect.transform(fMCRec->fMatrix, &transformedRRect)) { 163114e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org AutoValidateClip avc(this); 163214e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 163314e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org fDeviceCMDirty = true; 163414e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org fCachedLocalClipBoundsDirty = true; 16358f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!fAllowSoftClip) { 16368f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com edgeStyle = kHard_ClipEdgeStyle; 16378f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 163814e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 1639687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipDevRRect(transformedRRect, op, kSoft_ClipEdgeStyle == edgeStyle); 164014e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 1641afc7cce5d68663934128d76963cd501f771d71desenorblanco fMCRec->fRasterClip.op(transformedRRect, this->getTopLayerBounds(), op, 1642125f19a2964c31a660256132acbce60e8a3e6752robertphillips kSoft_ClipEdgeStyle == edgeStyle); 16438f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com return; 164414e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org } 164514e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 164614e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org SkPath path; 164714e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org path.addRRect(rrect); 164814e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org // call the non-virtual version 16498f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->SkCanvas::onClipPath(path, op, edgeStyle); 16504ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 16514ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 1652759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { 16532ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 16548f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 165539f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips 165639f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips if (!path.isInverseFillType() && fMCRec->fMatrix.rectStaysRect()) { 165739f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips SkRect r; 165839f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips if (path.isRect(&r)) { 165939f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips this->onClipRect(r, op, edgeStyle); 166039f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips return; 166139f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips } 166239f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips SkRRect rrect; 166339f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips if (path.isOval(&r)) { 166439f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips rrect.setOval(r); 166539f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips this->onClipRRect(rrect, op, edgeStyle); 166639f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips return; 166739f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips } 166839f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips if (path.isRRect(&rrect)) { 166939f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips this->onClipRRect(rrect, op, edgeStyle); 167039f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips return; 167139f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips } 16728f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 167339f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips 167439f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips this->onClipPath(path, op, edgeStyle); 16758f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 16768f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 16778f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 1678da17f758442f16747af39f8fbaed9c097048519creed@google.com#ifdef SK_ENABLE_CLIP_QUICKREJECT 1679da17f758442f16747af39f8fbaed9c097048519creed@google.com if (SkRegion::kIntersect_Op == op && !path.isInverseFillType()) { 16801f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fRasterClip.isEmpty()) { 1681da17f758442f16747af39f8fbaed9c097048519creed@google.com return false; 1682da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1683fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 16843b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(path.getBounds())) { 1685da17f758442f16747af39f8fbaed9c097048519creed@google.com fDeviceCMDirty = true; 1686c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 1687fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1688687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipEmpty(); 16891f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.setEmpty(); 1690da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1691da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1692da17f758442f16747af39f8fbaed9c097048519creed@google.com#endif 1693da17f758442f16747af39f8fbaed9c097048519creed@google.com 16945c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com AutoValidateClip avc(this); 16955c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 16968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1697c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 16988f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!fAllowSoftClip) { 16998f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com edgeStyle = kHard_ClipEdgeStyle; 17008f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 17018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath devPath; 17031f836ee096bb988adef4b9757b2629c7afeda36dreed path.transform(fMCRec->fMatrix, &devPath); 17048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1705fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // Check if the transfomation, or the original path itself 1706fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // made us empty. Note this can also happen if we contained NaN 1707fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // values. computing the bounds detects this, and will set our 1708fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // bounds to empty if that is the case. (see SkRect::set(pts, count)) 1709fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com if (devPath.getBounds().isEmpty()) { 1710fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // resetting the path will remove any NaN or other wanky values 1711fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // that might upset our scan converter. 1712fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com devPath.reset(); 1713fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com } 1714fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com 17155c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // if we called path.swap() we could avoid a deep copy of this path 1716687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipDevPath(devPath, op, kSoft_ClipEdgeStyle == edgeStyle); 17175c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 171845a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com if (fAllowSimplifyClip) { 17191a481fe4bf632ed4f76cb337691236fabfd4ab03fmalita bool clipIsAA = getClipStack()->asPath(&devPath); 17201a481fe4bf632ed4f76cb337691236fabfd4ab03fmalita if (clipIsAA) { 17211a481fe4bf632ed4f76cb337691236fabfd4ab03fmalita edgeStyle = kSoft_ClipEdgeStyle; 172245a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com } 17231a481fe4bf632ed4f76cb337691236fabfd4ab03fmalita 172445a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com op = SkRegion::kReplace_Op; 172545a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com } 172645a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com 1727afc7cce5d68663934128d76963cd501f771d71desenorblanco fMCRec->fRasterClip.op(devPath, this->getTopLayerBounds(), op, edgeStyle); 17288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1730759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipRegion(const SkRegion& rgn, SkRegion::Op op) { 17312ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 17328f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRegion(rgn, op); 17338f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 17348f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 17358f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipRegion(const SkRegion& rgn, SkRegion::Op op) { 17365c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com AutoValidateClip avc(this); 17375c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 17388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1739c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 17408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17415c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // todo: signal fClipStack that we have a region, and therefore (I guess) 17425c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // we have to ignore it, and use the region directly? 1743687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipDevRect(rgn.getBounds(), op); 17445c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 17451f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fRasterClip.op(rgn, op); 17468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1748819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com#ifdef SK_DEBUG 1749819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.comvoid SkCanvas::validateClip() const { 1750819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com // construct clipRgn from the clipstack 17511f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com const SkBaseDevice* device = this->getDevice(); 1752ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com if (!device) { 17535c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org SkASSERT(this->isClipEmpty()); 1754ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com return; 1755ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com } 1756ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com 1757819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com SkIRect ir; 1758819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com ir.set(0, 0, device->width(), device->height()); 1759d954498c01ccf0417feacf89e45d0c62a06a813breed SkRasterClip tmpClip(ir, fConservativeRasterClip); 1760819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 1761687fa1c745febb57f42b0d5f03d7c1f4be2530careed SkClipStack::B2TIter iter(*fClipStack); 17628182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const SkClipStack::Element* element; 176396fcdcc219d2a0d3579719b84b28bede76efba64halcanary while ((element = iter.next()) != nullptr) { 17648182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com switch (element->getType()) { 17658182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kRect_Type: 17668182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com element->getRect().round(&ir); 17678182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com tmpClip.op(ir, element->getOp()); 17688182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 17698182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kEmpty_Type: 17708182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com tmpClip.setEmpty(); 17718182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 17729cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org default: { 17739cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org SkPath path; 17749cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org element->asPath(&path); 1775afc7cce5d68663934128d76963cd501f771d71desenorblanco tmpClip.op(path, this->getTopLayerBounds(), element->getOp(), element->isAA()); 17769cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org break; 17779cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org } 1778819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com } 1779819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com } 1780819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com} 1781819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com#endif 1782819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 178390c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.comvoid SkCanvas::replayClips(ClipVisitor* visitor) const { 1784687fa1c745febb57f42b0d5f03d7c1f4be2530careed SkClipStack::B2TIter iter(*fClipStack); 17858182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const SkClipStack::Element* element; 17868182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com 178796fcdcc219d2a0d3579719b84b28bede76efba64halcanary while ((element = iter.next()) != nullptr) { 1788c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita element->replay(visitor); 178990c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com } 179090c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com} 179190c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com 17925c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com/////////////////////////////////////////////////////////////////////////////// 17935c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 1794754de5f65b466f721d952a379194cc94de376f42reed@google.combool SkCanvas::isClipEmpty() const { 17951f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.isEmpty(); 1796754de5f65b466f721d952a379194cc94de376f42reed@google.com} 1797754de5f65b466f721d952a379194cc94de376f42reed@google.com 17985c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.orgbool SkCanvas::isClipRect() const { 17991f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.isRect(); 18005c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org} 18015c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org 18023b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::quickReject(const SkRect& rect) const { 18031607863b608b7db6c813228768ed5d72997bbc82reed@google.com if (!rect.isFinite()) 1804116b2bcd2c4c4d4670c7b7e2ea597414713c37fbwjmaclean@chromium.org return true; 1805116b2bcd2c4c4d4670c7b7e2ea597414713c37fbwjmaclean@chromium.org 18061f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fRasterClip.isEmpty()) { 18078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 18088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18101f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fMatrix.hasPerspective()) { 1811a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com SkRect dst; 18121f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix.mapRect(&dst, rect); 1813b07a94f1cba3976596ae1a7f23d8c2043ba353f3reed return !SkIRect::Intersects(dst.roundOut(), fMCRec->fRasterClip.getBounds()); 1814a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com } else { 1815c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com const SkRect& clipR = this->getLocalClipBounds(); 1816d252db03d9650013b545ef9781fe993c07f8f314reed@android.com 1817a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com // for speed, do the most likely reject compares first 1818c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com // TODO: should we use | instead, or compare all 4 at once? 1819c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com if (rect.fTop >= clipR.fBottom || rect.fBottom <= clipR.fTop) { 1820a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com return true; 1821a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com } 1822c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com if (rect.fLeft >= clipR.fRight || rect.fRight <= clipR.fLeft) { 1823a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com return true; 1824a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com } 1825a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com return false; 18268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18293b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::quickReject(const SkPath& path) const { 18303b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com return path.isEmpty() || this->quickReject(path.getBounds()); 18318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18333b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::getClipBounds(SkRect* bounds) const { 1834bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect ibounds; 18358f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!this->getClipDeviceBounds(&ibounds)) { 18368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 18378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1839d9c0f0b57affec7a472879c5919acac6637d926areed@android.com SkMatrix inverse; 1840d9c0f0b57affec7a472879c5919acac6637d926areed@android.com // if we can't invert the CTM, we can't return local clip bounds 18411f836ee096bb988adef4b9757b2629c7afeda36dreed if (!fMCRec->fMatrix.invert(&inverse)) { 184272dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com if (bounds) { 184372dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com bounds->setEmpty(); 184472dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com } 1845d9c0f0b57affec7a472879c5919acac6637d926areed@android.com return false; 1846d9c0f0b57affec7a472879c5919acac6637d926areed@android.com } 1847d9c0f0b57affec7a472879c5919acac6637d926areed@android.com 184849f085dddff10473b6ebf832a974288300224e60bsalomon if (bounds) { 1849bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkRect r; 18503b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com // adjust it outwards in case we are antialiasing 18513b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com const int inset = 1; 1852fa4d5bd09f8f1a4a92b5ae0324800dd672760898reed@google.com 18538f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com r.iset(ibounds.fLeft - inset, ibounds.fTop - inset, 18548f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com ibounds.fRight + inset, ibounds.fBottom + inset); 18558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inverse.mapRect(bounds, r); 18568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 18588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1860bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.combool SkCanvas::getClipDeviceBounds(SkIRect* bounds) const { 18611f836ee096bb988adef4b9757b2629c7afeda36dreed const SkRasterClip& clip = fMCRec->fRasterClip; 1862bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (clip.isEmpty()) { 1863bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (bounds) { 1864bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com bounds->setEmpty(); 1865bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1866bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com return false; 1867bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1868bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com 186949f085dddff10473b6ebf832a974288300224e60bsalomon if (bounds) { 1870bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com *bounds = clip.getBounds(); 1871bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1872bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com return true; 1873bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com} 1874bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com 18758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkMatrix& SkCanvas::getTotalMatrix() const { 18761f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fMatrix; 18778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18795c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.orgconst SkRegion& SkCanvas::internal_private_getTotalClip() const { 18801f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.forceGetBW(); 18815c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org} 18825c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org 18839c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.comGrRenderTarget* SkCanvas::internal_private_accessTopLayerRenderTarget() { 18849c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com SkBaseDevice* dev = this->getTopDevice(); 188596fcdcc219d2a0d3579719b84b28bede76efba64halcanary return dev ? dev->accessRenderTarget() : nullptr; 18869c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 18879c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1888644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.orgGrContext* SkCanvas::getGrContext() { 1889644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#if SK_SUPPORT_GPU 1890644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org SkBaseDevice* device = this->getTopDevice(); 189149f085dddff10473b6ebf832a974288300224e60bsalomon if (device) { 1892644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org GrRenderTarget* renderTarget = device->accessRenderTarget(); 189349f085dddff10473b6ebf832a974288300224e60bsalomon if (renderTarget) { 1894644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org return renderTarget->getContext(); 1895644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org } 1896644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org } 1897644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#endif 1898644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org 189996fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 1900644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org 1901644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org} 1902e97f0856a8044866b12527819d14cdfbcdfd96f2bsalomon@google.com 1903ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.orgvoid SkCanvas::drawDRRect(const SkRRect& outer, const SkRRect& inner, 1904ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkPaint& paint) { 19059881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawDRRect()"); 1906ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (outer.isEmpty()) { 1907ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 1908ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 1909ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (inner.isEmpty()) { 1910ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->drawRRect(outer, paint); 1911ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 1912ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 1913ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 1914ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // We don't have this method (yet), but technically this is what we should 1915ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // be able to assert... 1916ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // SkASSERT(outer.contains(inner)); 1917ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // 1918ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // For now at least check for containment of bounds 1919ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org SkASSERT(outer.getBounds().contains(inner.getBounds())); 1920ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 1921ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->onDrawDRRect(outer, inner, paint); 1922ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org} 1923ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 192441af966ab338e95eee81ab618ab28195075338f7reed// These need to stop being virtual -- clients need to override the onDraw... versions 192541af966ab338e95eee81ab618ab28195075338f7reed 192641af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawPaint(const SkPaint& paint) { 192741af966ab338e95eee81ab618ab28195075338f7reed this->onDrawPaint(paint); 192841af966ab338e95eee81ab618ab28195075338f7reed} 192941af966ab338e95eee81ab618ab28195075338f7reed 193041af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawRect(const SkRect& r, const SkPaint& paint) { 193141af966ab338e95eee81ab618ab28195075338f7reed this->onDrawRect(r, paint); 193241af966ab338e95eee81ab618ab28195075338f7reed} 193341af966ab338e95eee81ab618ab28195075338f7reed 193441af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawOval(const SkRect& r, const SkPaint& paint) { 193541af966ab338e95eee81ab618ab28195075338f7reed this->onDrawOval(r, paint); 193641af966ab338e95eee81ab618ab28195075338f7reed} 193741af966ab338e95eee81ab618ab28195075338f7reed 193841af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) { 193941af966ab338e95eee81ab618ab28195075338f7reed this->onDrawRRect(rrect, paint); 194041af966ab338e95eee81ab618ab28195075338f7reed} 194141af966ab338e95eee81ab618ab28195075338f7reed 194241af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint) { 194341af966ab338e95eee81ab618ab28195075338f7reed this->onDrawPoints(mode, count, pts, paint); 194441af966ab338e95eee81ab618ab28195075338f7reed} 194541af966ab338e95eee81ab618ab28195075338f7reed 194641af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawVertices(VertexMode vmode, int vertexCount, const SkPoint vertices[], 194741af966ab338e95eee81ab618ab28195075338f7reed const SkPoint texs[], const SkColor colors[], SkXfermode* xmode, 194841af966ab338e95eee81ab618ab28195075338f7reed const uint16_t indices[], int indexCount, const SkPaint& paint) { 194941af966ab338e95eee81ab618ab28195075338f7reed this->onDrawVertices(vmode, vertexCount, vertices, texs, colors, xmode, 195041af966ab338e95eee81ab618ab28195075338f7reed indices, indexCount, paint); 195141af966ab338e95eee81ab618ab28195075338f7reed} 195241af966ab338e95eee81ab618ab28195075338f7reed 195341af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawPath(const SkPath& path, const SkPaint& paint) { 195441af966ab338e95eee81ab618ab28195075338f7reed this->onDrawPath(path, paint); 195541af966ab338e95eee81ab618ab28195075338f7reed} 195641af966ab338e95eee81ab618ab28195075338f7reed 1957a85d4d0814818e4ddabb9237da209d61d6cd5854reedvoid SkCanvas::drawImage(const SkImage* image, SkScalar x, SkScalar y, const SkPaint* paint) { 1958e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 1959a85d4d0814818e4ddabb9237da209d61d6cd5854reed this->onDrawImage(image, x, y, paint); 196041af966ab338e95eee81ab618ab28195075338f7reed} 196141af966ab338e95eee81ab618ab28195075338f7reed 1962e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst, 1963e47829b6b1eeb6b0c97ccb3df3016d197046824creed const SkPaint* paint, SrcRectConstraint constraint) { 1964e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 1965e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (dst.isEmpty() || src.isEmpty()) { 1966e47829b6b1eeb6b0c97ccb3df3016d197046824creed return; 1967e47829b6b1eeb6b0c97ccb3df3016d197046824creed } 1968e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->onDrawImageRect(image, &src, dst, paint, constraint); 1969e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 197041af966ab338e95eee81ab618ab28195075338f7reed 197184984efeb64787b88c5f8bd6929cfe2d58a3ba06reedvoid SkCanvas::drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst, 197284984efeb64787b88c5f8bd6929cfe2d58a3ba06reed const SkPaint* paint, SrcRectConstraint constraint) { 1973e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 1974e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, SkRect::Make(isrc), dst, paint, constraint); 197584984efeb64787b88c5f8bd6929cfe2d58a3ba06reed} 197684984efeb64787b88c5f8bd6929cfe2d58a3ba06reed 1977e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint, 1978e47829b6b1eeb6b0c97ccb3df3016d197046824creed SrcRectConstraint constraint) { 1979e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 1980e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, SkRect::MakeIWH(image->width(), image->height()), dst, paint, 1981e47829b6b1eeb6b0c97ccb3df3016d197046824creed constraint); 1982e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 1983e47829b6b1eeb6b0c97ccb3df3016d197046824creed 19844c21dc5ddf3b482293ed34eead876d8d61a662c3reedvoid SkCanvas::drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst, 19854c21dc5ddf3b482293ed34eead876d8d61a662c3reed const SkPaint* paint) { 1986e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 19874c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (dst.isEmpty()) { 19884c21dc5ddf3b482293ed34eead876d8d61a662c3reed return; 19894c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 19904c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (!SkNinePatchIter::Valid(image->width(), image->height(), center)) { 1991e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, dst, paint); 19924c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 19934c21dc5ddf3b482293ed34eead876d8d61a662c3reed this->onDrawImageNine(image, center, dst, paint); 19944c21dc5ddf3b482293ed34eead876d8d61a662c3reed} 19954c21dc5ddf3b482293ed34eead876d8d61a662c3reed 199641af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar dx, SkScalar dy, const SkPaint* paint) { 19974c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (bitmap.drawsNothing()) { 19982df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson return; 19992df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson } 200041af966ab338e95eee81ab618ab28195075338f7reed this->onDrawBitmap(bitmap, dx, dy, paint); 200141af966ab338e95eee81ab618ab28195075338f7reed} 200241af966ab338e95eee81ab618ab28195075338f7reed 2003e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst, 2004a5517e2b190a8083b38964972b031c13e99f1012reed const SkPaint* paint, SrcRectConstraint constraint) { 2005e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (bitmap.drawsNothing() || dst.isEmpty() || src.isEmpty()) { 2006a5517e2b190a8083b38964972b031c13e99f1012reed return; 2007a5517e2b190a8083b38964972b031c13e99f1012reed } 2008e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->onDrawBitmapRect(bitmap, &src, dst, paint, constraint); 200941af966ab338e95eee81ab618ab28195075338f7reed} 201041af966ab338e95eee81ab618ab28195075338f7reed 201184984efeb64787b88c5f8bd6929cfe2d58a3ba06reedvoid SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst, 201284984efeb64787b88c5f8bd6929cfe2d58a3ba06reed const SkPaint* paint, SrcRectConstraint constraint) { 2013e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, SkRect::Make(isrc), dst, paint, constraint); 2014e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 2015e47829b6b1eeb6b0c97ccb3df3016d197046824creed 2016e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint, 2017e47829b6b1eeb6b0c97ccb3df3016d197046824creed SrcRectConstraint constraint) { 2018e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, SkRect::MakeIWH(bitmap.width(), bitmap.height()), dst, paint, 2019e47829b6b1eeb6b0c97ccb3df3016d197046824creed constraint); 202084984efeb64787b88c5f8bd6929cfe2d58a3ba06reed} 202184984efeb64787b88c5f8bd6929cfe2d58a3ba06reed 202241af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst, 202341af966ab338e95eee81ab618ab28195075338f7reed const SkPaint* paint) { 20244c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (bitmap.drawsNothing() || dst.isEmpty()) { 20252df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson return; 20262df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson } 20274c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (!SkNinePatchIter::Valid(bitmap.width(), bitmap.height(), center)) { 2028a5517e2b190a8083b38964972b031c13e99f1012reed this->drawBitmapRect(bitmap, dst, paint); 20294c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 203041af966ab338e95eee81ab618ab28195075338f7reed this->onDrawBitmapNine(bitmap, center, dst, paint); 203141af966ab338e95eee81ab618ab28195075338f7reed} 203241af966ab338e95eee81ab618ab28195075338f7reed 203371c3c760a83123ee0b3127b8c65c6394ce541c50reedvoid SkCanvas::drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], 203471c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkColor colors[], int count, SkXfermode::Mode mode, 203571c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkRect* cull, const SkPaint* paint) { 2036e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(atlas); 203771c3c760a83123ee0b3127b8c65c6394ce541c50reed if (count <= 0) { 203871c3c760a83123ee0b3127b8c65c6394ce541c50reed return; 203971c3c760a83123ee0b3127b8c65c6394ce541c50reed } 204071c3c760a83123ee0b3127b8c65c6394ce541c50reed SkASSERT(atlas); 204171c3c760a83123ee0b3127b8c65c6394ce541c50reed SkASSERT(xform); 204271c3c760a83123ee0b3127b8c65c6394ce541c50reed SkASSERT(tex); 204371c3c760a83123ee0b3127b8c65c6394ce541c50reed this->onDrawAtlas(atlas, xform, tex, colors, count, mode, cull, paint); 204471c3c760a83123ee0b3127b8c65c6394ce541c50reed} 204571c3c760a83123ee0b3127b8c65c6394ce541c50reed 2046f70b531daaf47db1ee95c70da9843f1dd1f418d3reedvoid SkCanvas::drawAnnotation(const SkRect& rect, const char key[], SkData* value) { 2047f70b531daaf47db1ee95c70da9843f1dd1f418d3reed if (key) { 2048f70b531daaf47db1ee95c70da9843f1dd1f418d3reed this->onDrawAnnotation(rect, key, value); 2049f70b531daaf47db1ee95c70da9843f1dd1f418d3reed } 2050f70b531daaf47db1ee95c70da9843f1dd1f418d3reed} 2051f70b531daaf47db1ee95c70da9843f1dd1f418d3reed 2052e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::legacy_drawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, 2053e47829b6b1eeb6b0c97ccb3df3016d197046824creed const SkPaint* paint, SrcRectConstraint constraint) { 2054e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (src) { 2055e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, *src, dst, paint, constraint); 2056e47829b6b1eeb6b0c97ccb3df3016d197046824creed } else { 2057e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, SkRect::MakeIWH(image->width(), image->height()), 2058e47829b6b1eeb6b0c97ccb3df3016d197046824creed dst, paint, constraint); 2059e47829b6b1eeb6b0c97ccb3df3016d197046824creed } 2060e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 2061e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::legacy_drawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, 2062e47829b6b1eeb6b0c97ccb3df3016d197046824creed const SkPaint* paint, SrcRectConstraint constraint) { 2063e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (src) { 2064e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, *src, dst, paint, constraint); 2065e47829b6b1eeb6b0c97ccb3df3016d197046824creed } else { 2066e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, SkRect::MakeIWH(bitmap.width(), bitmap.height()), 2067e47829b6b1eeb6b0c97ccb3df3016d197046824creed dst, paint, constraint); 2068e47829b6b1eeb6b0c97ccb3df3016d197046824creed } 2069e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 2070e47829b6b1eeb6b0c97ccb3df3016d197046824creed 20718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 20728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// These are the virtual drawing methods 20738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 20748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 207528361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.orgvoid SkCanvas::onDiscard() { 207649f085dddff10473b6ebf832a974288300224e60bsalomon if (fSurfaceBase) { 207728361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org fSurfaceBase->aboutToDraw(SkSurface::kDiscard_ContentChangeMode); 207828361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org } 207928361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org} 208028361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org 208141af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawPaint(const SkPaint& paint) { 20829881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPaint()"); 2083fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->internalDrawPaint(paint); 2084fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com} 2085fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com 2086fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.comvoid SkCanvas::internalDrawPaint(const SkPaint& paint) { 208796fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, SkDrawFilter::kPaint_Type, nullptr, false) 20888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 20904e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPaint(iter, looper.paint()); 20918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 20928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20934e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 20948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 20958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 209641af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[], 209741af966ab338e95eee81ab618ab28195075338f7reed const SkPaint& paint) { 20989881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT1("disabled-by-default-skia", "SkCanvas::drawPoints()", "count", static_cast<uint64_t>(count)); 20998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if ((long)count <= 0) { 21008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 21018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 21028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 210378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect r, storage; 210496fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 2105a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com if (paint.canComputeFastBounds()) { 2106a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com // special-case 2 points (common for drawing a single line) 2107a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com if (2 == count) { 2108a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com r.set(pts[0], pts[1]); 2109a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } else { 2110a8c7f7702fb4bbedb615031bc653c5cd161a038ecommit-bot@chromium.org r.set(pts, SkToInt(count)); 2111a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } 211287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastStrokeBounds(r, &storage))) { 211387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 211487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 211587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &r; 2116fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 2117a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com 211896fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkASSERT(pts != nullptr); 21198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 212078cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPoint_Type, bounds) 21214b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 21228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 21234e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPoints(iter, mode, count, pts, looper.paint()); 21248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 21254b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 21264e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 21278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 21288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 212941af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawRect(const SkRect& r, const SkPaint& paint) { 21309881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRect()"); 213178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 213296fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 21338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.canComputeFastBounds()) { 21348432808ad8898ac7137bc7ce1d9df6005e866401reed // Skia will draw an inverted rect, because it explicitly "sorts" it downstream. 21358432808ad8898ac7137bc7ce1d9df6005e866401reed // To prevent accidental rejecting at this stage, we have to sort it before we check. 21368432808ad8898ac7137bc7ce1d9df6005e866401reed SkRect tmp(r); 21378432808ad8898ac7137bc7ce1d9df6005e866401reed tmp.sort(); 21388432808ad8898ac7137bc7ce1d9df6005e866401reed 213987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(tmp, &storage))) { 214087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 214187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 214287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &r; 21438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 21444b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2145c83a29759a5c2966da5ab973e4fd90763e4c962breed LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, SkDrawFilter::kRect_Type, bounds, false) 21468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 21484e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawRect(iter, r, looper.paint()); 21498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 21508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21514e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 21528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 21538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 215441af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) { 21559881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawOval()"); 215678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 215796fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 21584ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (paint.canComputeFastBounds()) { 215987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(oval, &storage))) { 216087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 216187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 216287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &oval; 21634ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 2164306ab9d5de38f2a547fd1d69aedbe69b5c6617ccskia.committer@gmail.com 216578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, bounds) 216646d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com 216746d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com while (iter.next()) { 216846d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com iter.fDevice->drawOval(iter, oval, looper.paint()); 216946d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com } 217046d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com 217146d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com LOOPER_END 21724ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 21734ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 217441af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) { 21759881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRRect()"); 217678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 217796fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 21784ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (paint.canComputeFastBounds()) { 217987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(rrect.getBounds(), &storage))) { 218087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 218187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 218287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &rrect.getBounds(); 21834ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 21844ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 21854ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (rrect.isRect()) { 21864ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com // call the non-virtual version 21874ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->SkCanvas::drawRect(rrect.getBounds(), paint); 2188f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org return; 2189f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } else if (rrect.isOval()) { 21904ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com // call the non-virtual version 2191f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org this->SkCanvas::drawOval(rrect.getBounds(), paint); 2192f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org return; 21934ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 2194f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 219578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) 2196f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 2197f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org while (iter.next()) { 2198f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org iter.fDevice->drawRRect(iter, rrect, looper.paint()); 2199f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } 2200f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 2201f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org LOOPER_END 22024ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 22034ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 2204ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.orgvoid SkCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, 2205ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkPaint& paint) { 2206ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org SkRect storage; 220796fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 2208ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (paint.canComputeFastBounds()) { 220987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(outer.getBounds(), &storage))) { 221087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 221187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 221287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &outer.getBounds(); 2213ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 221425c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 2215ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) 221625c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 2217ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org while (iter.next()) { 2218ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org iter.fDevice->drawDRRect(iter, outer, inner, looper.paint()); 2219ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 222025c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 2221ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org LOOPER_END 2222ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org} 22234ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 222441af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) { 22259881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPath()"); 22269364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com if (!path.isFinite()) { 22279364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com return; 22289364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com } 22299364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com 223078cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 223196fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 2232fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com if (!path.isInverseFillType() && paint.canComputeFastBounds()) { 223378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect& pathBounds = path.getBounds(); 223487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(pathBounds, &storage))) { 223587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 223687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 223787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &pathBounds; 22388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 22390b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org 22400b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org const SkRect& r = path.getBounds(); 22410b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org if (r.width() <= 0 && r.height() <= 0) { 22426803c219dd3be4a73e7bb5c4bb8a5b1f803624d0commit-bot@chromium.org if (path.isInverseFillType()) { 2243fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->internalDrawPaint(paint); 22446651a3238dd6affa4276ada42ab613abf1d42d1dcaryclark return; 2245fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 2246fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 22478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 224878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, bounds) 22498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 22514e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPath(iter, path, looper.paint()); 22528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 22538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22544e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 22558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 22568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2257262a71b7f95ce98ff3dd8dba845afbd724470903reedbool SkCanvas::canDrawBitmapAsSprite(SkScalar x, SkScalar y, int w, int h, const SkPaint& paint) { 2258262a71b7f95ce98ff3dd8dba845afbd724470903reed if (!paint.getImageFilter()) { 2259262a71b7f95ce98ff3dd8dba845afbd724470903reed return false; 2260262a71b7f95ce98ff3dd8dba845afbd724470903reed } 2261262a71b7f95ce98ff3dd8dba845afbd724470903reed 2262262a71b7f95ce98ff3dd8dba845afbd724470903reed const SkMatrix& ctm = this->getTotalMatrix(); 2263c7e211acd0c9201688de7ff0c9a2271c67440adffmalita if (!SkTreatAsSprite(ctm, SkISize::Make(w, h), paint)) { 2264262a71b7f95ce98ff3dd8dba845afbd724470903reed return false; 2265262a71b7f95ce98ff3dd8dba845afbd724470903reed } 2266262a71b7f95ce98ff3dd8dba845afbd724470903reed 2267262a71b7f95ce98ff3dd8dba845afbd724470903reed // Currently we can only use the filterSprite code if we are clipped to the bitmap's bounds. 2268262a71b7f95ce98ff3dd8dba845afbd724470903reed // Once we can filter and the filter will return a result larger than itself, we should be 2269262a71b7f95ce98ff3dd8dba845afbd724470903reed // able to remove this constraint. 2270262a71b7f95ce98ff3dd8dba845afbd724470903reed // skbug.com/4526 2271262a71b7f95ce98ff3dd8dba845afbd724470903reed // 2272262a71b7f95ce98ff3dd8dba845afbd724470903reed SkPoint pt; 2273262a71b7f95ce98ff3dd8dba845afbd724470903reed ctm.mapXY(x, y, &pt); 2274262a71b7f95ce98ff3dd8dba845afbd724470903reed SkIRect ir = SkIRect::MakeXYWH(SkScalarRoundToInt(pt.x()), SkScalarRoundToInt(pt.y()), w, h); 2275262a71b7f95ce98ff3dd8dba845afbd724470903reed return ir.contains(fMCRec->fRasterClip.getBounds()); 2276262a71b7f95ce98ff3dd8dba845afbd724470903reed} 2277262a71b7f95ce98ff3dd8dba845afbd724470903reed 2278a85d4d0814818e4ddabb9237da209d61d6cd5854reedvoid SkCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, const SkPaint* paint) { 22799881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImage()"); 2280a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkRect bounds = SkRect::MakeXYWH(x, y, 2281a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkIntToScalar(image->width()), SkIntToScalar(image->height())); 228296fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 228387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect tmp = bounds; 228487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (paint) { 228587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco paint->computeFastBounds(tmp, &tmp); 228687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 228787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(tmp)) { 228887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 228987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 2290a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 22919d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2292a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkLazyPaint lazy; 229396fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 2294a85d4d0814818e4ddabb9237da209d61d6cd5854reed paint = lazy.init(); 2295a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2296262a71b7f95ce98ff3dd8dba845afbd724470903reed 2297129ed1cd6d792f3f6cf563aefa9756fc6308289dreed bool drawAsSprite = this->canDrawBitmapAsSprite(x, y, image->width(), image->height(), 2298129ed1cd6d792f3f6cf563aefa9756fc6308289dreed *paint); 2299129ed1cd6d792f3f6cf563aefa9756fc6308289dreed if (drawAsSprite && paint->getImageFilter()) { 2300129ed1cd6d792f3f6cf563aefa9756fc6308289dreed SkBitmap bitmap; 2301129ed1cd6d792f3f6cf563aefa9756fc6308289dreed if (!as_IB(image)->asBitmapForImageFilters(&bitmap)) { 2302129ed1cd6d792f3f6cf563aefa9756fc6308289dreed drawAsSprite = false; 2303129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } else{ 2304129ed1cd6d792f3f6cf563aefa9756fc6308289dreed // Until imagefilters are updated, they cannot handle any src type but N32... 2305129ed1cd6d792f3f6cf563aefa9756fc6308289dreed if (bitmap.info().colorType() != kN32_SkColorType || bitmap.info().isSRGB()) { 2306129ed1cd6d792f3f6cf563aefa9756fc6308289dreed drawAsSprite = false; 2307129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 2308129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 2309129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 2310129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 2311262a71b7f95ce98ff3dd8dba845afbd724470903reed LOOPER_BEGIN_DRAWBITMAP(*paint, drawAsSprite, &bounds) 2312262a71b7f95ce98ff3dd8dba845afbd724470903reed 2313a85d4d0814818e4ddabb9237da209d61d6cd5854reed while (iter.next()) { 2314262a71b7f95ce98ff3dd8dba845afbd724470903reed const SkPaint& pnt = looper.paint(); 2315262a71b7f95ce98ff3dd8dba845afbd724470903reed if (drawAsSprite && pnt.getImageFilter()) { 2316262a71b7f95ce98ff3dd8dba845afbd724470903reed SkBitmap bitmap; 2317262a71b7f95ce98ff3dd8dba845afbd724470903reed if (as_IB(image)->asBitmapForImageFilters(&bitmap)) { 2318262a71b7f95ce98ff3dd8dba845afbd724470903reed SkPoint pt; 2319262a71b7f95ce98ff3dd8dba845afbd724470903reed iter.fMatrix->mapXY(x, y, &pt); 23202302de920e5434809bd0e85b871a6e002856dfdbrobertphillips iter.fDevice->drawSpriteWithFilter(iter, bitmap, 23212302de920e5434809bd0e85b871a6e002856dfdbrobertphillips SkScalarRoundToInt(pt.fX), 23222302de920e5434809bd0e85b871a6e002856dfdbrobertphillips SkScalarRoundToInt(pt.fY), pnt); 2323262a71b7f95ce98ff3dd8dba845afbd724470903reed } 2324262a71b7f95ce98ff3dd8dba845afbd724470903reed } else { 2325262a71b7f95ce98ff3dd8dba845afbd724470903reed iter.fDevice->drawImage(iter, image, x, y, pnt); 2326262a71b7f95ce98ff3dd8dba845afbd724470903reed } 2327a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 23289d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2329a85d4d0814818e4ddabb9237da209d61d6cd5854reed LOOPER_END 2330b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr} 2331b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 233241af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, 2333562fe4767cc73e08a4e039362bc0336aea66ecfbreed const SkPaint* paint, SrcRectConstraint constraint) { 23349881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImageRect()"); 233596fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 2336c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco SkRect storage = dst; 233787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (paint) { 233887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco paint->computeFastBounds(dst, &storage); 233987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 234087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(storage)) { 234187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 234287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 2343a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2344a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkLazyPaint lazy; 234596fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 2346a85d4d0814818e4ddabb9237da209d61d6cd5854reed paint = lazy.init(); 2347a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 23489d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2349c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, SkDrawFilter::kBitmap_Type, &dst, 2350c83a29759a5c2966da5ab973e4fd90763e4c962breed image->isOpaque()) 23519d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2352a85d4d0814818e4ddabb9237da209d61d6cd5854reed while (iter.next()) { 2353a5517e2b190a8083b38964972b031c13e99f1012reed iter.fDevice->drawImageRect(iter, image, src, dst, looper.paint(), constraint); 2354a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 23559d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2356a85d4d0814818e4ddabb9237da209d61d6cd5854reed LOOPER_END 2357b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr} 2358b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 235941af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y, const SkPaint* paint) { 23609881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmap()"); 23618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(bitmap.validate();) 23628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 236333366974d43eae80e22284a2e445225c343859dareed if (bitmap.drawsNothing()) { 236433366974d43eae80e22284a2e445225c343859dareed return; 236533366974d43eae80e22284a2e445225c343859dareed } 236633366974d43eae80e22284a2e445225c343859dareed 236733366974d43eae80e22284a2e445225c343859dareed SkLazyPaint lazy; 236833366974d43eae80e22284a2e445225c343859dareed if (nullptr == paint) { 236933366974d43eae80e22284a2e445225c343859dareed paint = lazy.init(); 237033366974d43eae80e22284a2e445225c343859dareed } 237133366974d43eae80e22284a2e445225c343859dareed 237233366974d43eae80e22284a2e445225c343859dareed const SkMatrix matrix = SkMatrix::MakeTrans(x, y); 237333366974d43eae80e22284a2e445225c343859dareed 237433366974d43eae80e22284a2e445225c343859dareed SkRect storage; 237533366974d43eae80e22284a2e445225c343859dareed const SkRect* bounds = nullptr; 237633366974d43eae80e22284a2e445225c343859dareed if (paint->canComputeFastBounds()) { 237733366974d43eae80e22284a2e445225c343859dareed bitmap.getBounds(&storage); 237833366974d43eae80e22284a2e445225c343859dareed matrix.mapRect(&storage); 237987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect tmp = storage; 238087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint->computeFastBounds(tmp, &tmp))) { 238187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 238287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 238387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &storage; 23848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23854b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2386129ed1cd6d792f3f6cf563aefa9756fc6308289dreed bool drawAsSprite = bounds && this->canDrawBitmapAsSprite(x, y, bitmap.width(), bitmap.height(), 2387129ed1cd6d792f3f6cf563aefa9756fc6308289dreed *paint); 2388129ed1cd6d792f3f6cf563aefa9756fc6308289dreed if (drawAsSprite && paint->getImageFilter()) { 2389129ed1cd6d792f3f6cf563aefa9756fc6308289dreed // Until imagefilters are updated, they cannot handle any src type but N32... 2390129ed1cd6d792f3f6cf563aefa9756fc6308289dreed if (bitmap.info().colorType() != kN32_SkColorType || bitmap.info().isSRGB()) { 2391129ed1cd6d792f3f6cf563aefa9756fc6308289dreed drawAsSprite = false; 2392129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 2393129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 2394129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 2395262a71b7f95ce98ff3dd8dba845afbd724470903reed LOOPER_BEGIN_DRAWBITMAP(*paint, drawAsSprite, bounds) 239633366974d43eae80e22284a2e445225c343859dareed 239733366974d43eae80e22284a2e445225c343859dareed while (iter.next()) { 2398262a71b7f95ce98ff3dd8dba845afbd724470903reed const SkPaint& pnt = looper.paint(); 2399262a71b7f95ce98ff3dd8dba845afbd724470903reed if (drawAsSprite && pnt.getImageFilter()) { 2400262a71b7f95ce98ff3dd8dba845afbd724470903reed SkPoint pt; 2401262a71b7f95ce98ff3dd8dba845afbd724470903reed iter.fMatrix->mapXY(x, y, &pt); 24022302de920e5434809bd0e85b871a6e002856dfdbrobertphillips iter.fDevice->drawSpriteWithFilter(iter, bitmap, 24032302de920e5434809bd0e85b871a6e002856dfdbrobertphillips SkScalarRoundToInt(pt.fX), 24042302de920e5434809bd0e85b871a6e002856dfdbrobertphillips SkScalarRoundToInt(pt.fY), pnt); 2405262a71b7f95ce98ff3dd8dba845afbd724470903reed } else { 2406262a71b7f95ce98ff3dd8dba845afbd724470903reed iter.fDevice->drawBitmap(iter, bitmap, matrix, looper.paint()); 2407262a71b7f95ce98ff3dd8dba845afbd724470903reed } 240833366974d43eae80e22284a2e445225c343859dareed } 2409262a71b7f95ce98ff3dd8dba845afbd724470903reed 241033366974d43eae80e22284a2e445225c343859dareed LOOPER_END 24118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24139987ec3791336bad6af5cbe513564786b2df55aareed@google.com// this one is non-virtual, so it can be called safely by other canvas apis 24147112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.comvoid SkCanvas::internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, 2415eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org const SkRect& dst, const SkPaint* paint, 2416a5517e2b190a8083b38964972b031c13e99f1012reed SrcRectConstraint constraint) { 241750b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org if (bitmap.drawsNothing() || dst.isEmpty()) { 24188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 24198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 242074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 242196fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 2422c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco SkRect storage; 242387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 242487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 242587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 24268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 24273d60812865bb034851da777a91413ab584929887reed@google.com 242833535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com SkLazyPaint lazy; 242996fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 243033535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com paint = lazy.init(); 24318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 24327064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 2433c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, SkDrawFilter::kBitmap_Type, &dst, 2434c83a29759a5c2966da5ab973e4fd90763e4c962breed bitmap.isOpaque()) 24357064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 243633535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com while (iter.next()) { 2437562fe4767cc73e08a4e039362bc0336aea66ecfbreed iter.fDevice->drawBitmapRect(iter, bitmap, src, dst, looper.paint(), constraint); 2438f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 24397064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 244033535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com LOOPER_END 24418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 244341af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, 2444562fe4767cc73e08a4e039362bc0336aea66ecfbreed const SkPaint* paint, SrcRectConstraint constraint) { 24459881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmapRectToRect()"); 24469987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkDEBUGCODE(bitmap.validate();) 2447562fe4767cc73e08a4e039362bc0336aea66ecfbreed this->internalDrawBitmapRect(bitmap, src, dst, paint, constraint); 24489987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 24499987ec3791336bad6af5cbe513564786b2df55aareed@google.com 24504c21dc5ddf3b482293ed34eead876d8d61a662c3reedvoid SkCanvas::onDrawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst, 24514c21dc5ddf3b482293ed34eead876d8d61a662c3reed const SkPaint* paint) { 24524c21dc5ddf3b482293ed34eead876d8d61a662c3reed TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImageNine()"); 24539d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 245496fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 2455c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco SkRect storage; 245687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 245787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 245887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 24593d60812865bb034851da777a91413ab584929887reed@google.com } 24609d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 24614c21dc5ddf3b482293ed34eead876d8d61a662c3reed SkLazyPaint lazy; 246296fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 24634c21dc5ddf3b482293ed34eead876d8d61a662c3reed paint = lazy.init(); 24644c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 24659d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2466c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst) 24679d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 24684c21dc5ddf3b482293ed34eead876d8d61a662c3reed while (iter.next()) { 24694c21dc5ddf3b482293ed34eead876d8d61a662c3reed iter.fDevice->drawImageNine(iter, image, center, dst, looper.paint()); 24709987ec3791336bad6af5cbe513564786b2df55aareed@google.com } 24719d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 24724c21dc5ddf3b482293ed34eead876d8d61a662c3reed LOOPER_END 24739987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 24749987ec3791336bad6af5cbe513564786b2df55aareed@google.com 247541af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst, 247641af966ab338e95eee81ab618ab28195075338f7reed const SkPaint* paint) { 24779881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmapNine()"); 24789987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkDEBUGCODE(bitmap.validate();) 24799987ec3791336bad6af5cbe513564786b2df55aareed@google.com 248096fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 2481c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco SkRect storage; 248287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 248387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 248487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 24854c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 24869d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 24874c21dc5ddf3b482293ed34eead876d8d61a662c3reed SkLazyPaint lazy; 248896fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 24894c21dc5ddf3b482293ed34eead876d8d61a662c3reed paint = lazy.init(); 24904c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 24919d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2492c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst) 24939d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 24944c21dc5ddf3b482293ed34eead876d8d61a662c3reed while (iter.next()) { 24954c21dc5ddf3b482293ed34eead876d8d61a662c3reed iter.fDevice->drawBitmapNine(iter, bitmap, center, dst, looper.paint()); 24964c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 24979d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 24984c21dc5ddf3b482293ed34eead876d8d61a662c3reed LOOPER_END 24999987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 25009987ec3791336bad6af5cbe513564786b2df55aareed@google.com 2501f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.comclass SkDeviceFilteredPaint { 2502f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.compublic: 25031f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkDeviceFilteredPaint(SkBaseDevice* device, const SkPaint& paint) { 2504112e7e277702e104357f2d44742253ee1b0109acfmalita uint32_t filteredFlags = device->filterTextFlags(paint); 2505112e7e277702e104357f2d44742253ee1b0109acfmalita if (filteredFlags != paint.getFlags()) { 2506a076e9be17654a60310e72c4f70fcd5337f56dbfreed@google.com SkPaint* newPaint = fLazy.set(paint); 2507112e7e277702e104357f2d44742253ee1b0109acfmalita newPaint->setFlags(filteredFlags); 2508f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com fPaint = newPaint; 2509f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } else { 2510f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com fPaint = &paint; 2511f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } 2512f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } 2513f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 2514f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com const SkPaint& paint() const { return *fPaint; } 2515f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 2516f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.comprivate: 25172c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint* fPaint; 25182c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkLazyPaint fLazy; 2519f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com}; 2520f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 252152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.comvoid SkCanvas::DrawRect(const SkDraw& draw, const SkPaint& paint, 252252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com const SkRect& r, SkScalar textSize) { 252317b78946096265d80215a6c946286ecaa35ea7edepoger@google.com if (paint.getStyle() == SkPaint::kFill_Style) { 252452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com draw.fDevice->drawRect(draw, r, paint); 252552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } else { 252652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPaint p(paint); 252717b78946096265d80215a6c946286ecaa35ea7edepoger@google.com p.setStrokeWidth(SkScalarMul(textSize, paint.getStrokeWidth())); 252852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com draw.fDevice->drawRect(draw, r, p); 252952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 253052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com} 253152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 253252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.comvoid SkCanvas::DrawTextDecorations(const SkDraw& draw, const SkPaint& paint, 253352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com const char text[], size_t byteLength, 253452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar x, SkScalar y) { 253596fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkASSERT(byteLength == 0 || text != nullptr); 253652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 253752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com // nothing to draw 253896fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (text == nullptr || byteLength == 0 || 253952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com draw.fClip->isEmpty() || 254096fcdcc219d2a0d3579719b84b28bede76efba64halcanary (paint.getAlpha() == 0 && paint.getXfermode() == nullptr)) { 254152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com return; 254252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 254352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 254452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar width = 0; 254552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPoint start; 254652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 254752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.set(0, 0); // to avoid warning 254852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (paint.getFlags() & (SkPaint::kUnderlineText_Flag | 254952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPaint::kStrikeThruText_Flag)) { 255052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com width = paint.measureText(text, byteLength); 255152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 255252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar offsetX = 0; 255352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (paint.getTextAlign() == SkPaint::kCenter_Align) { 255452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com offsetX = SkScalarHalf(width); 255552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } else if (paint.getTextAlign() == SkPaint::kRight_Align) { 255652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com offsetX = width; 255752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 255852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.set(x - offsetX, y); 255952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 256052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 256152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (0 == width) { 256252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com return; 256352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 256452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 256552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com uint32_t flags = paint.getFlags(); 256652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 256752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (flags & (SkPaint::kUnderlineText_Flag | 256852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPaint::kStrikeThruText_Flag)) { 256952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar textSize = paint.getTextSize(); 257052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar height = SkScalarMul(textSize, kStdUnderline_Thickness); 257152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkRect r; 257252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 257352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fLeft = start.fX; 257452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fRight = start.fX + width; 257552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 257652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (flags & SkPaint::kUnderlineText_Flag) { 257752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar offset = SkScalarMulAdd(textSize, kStdUnderline_Offset, 257852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.fY); 257952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fTop = offset; 258052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fBottom = offset + height; 2581fb56218292d6c7b509d382f39994c3783b2483a0caryclark DrawRect(draw, paint, r, 1); 258252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 258352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (flags & SkPaint::kStrikeThruText_Flag) { 258452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar offset = SkScalarMulAdd(textSize, kStdStrikeThru_Offset, 258552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.fY); 258652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fTop = offset; 258752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fBottom = offset + height; 2588fb56218292d6c7b509d382f39994c3783b2483a0caryclark DrawRect(draw, paint, r, 1); 258952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 259052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 259152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com} 259252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 2593e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 2594e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 259596fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 25968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 25984e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 2599f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com iter.fDevice->drawText(iter, text, byteLength, x, y, dfp.paint()); 260052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com DrawTextDecorations(iter, dfp.paint(), 260152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com static_cast<const char*>(text), byteLength, x, y); 26028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 26038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 26044e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 26058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 26068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2607e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], 2608e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 260905c4a4322e7d4f3417b7df33825bab8603d52051fmalita SkPoint textOffset = SkPoint::Make(0, 0); 261005c4a4322e7d4f3417b7df33825bab8603d52051fmalita 261196fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 261287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 26138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 26144e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 261505c4a4322e7d4f3417b7df33825bab8603d52051fmalita iter.fDevice->drawPosText(iter, text, byteLength, &pos->fX, 2, textOffset, 2616f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com dfp.paint()); 26178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2618b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 26194e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 26208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 26218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2622e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], 2623e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com SkScalar constY, const SkPaint& paint) { 262405c4a4322e7d4f3417b7df33825bab8603d52051fmalita 262505c4a4322e7d4f3417b7df33825bab8603d52051fmalita SkPoint textOffset = SkPoint::Make(0, constY); 262605c4a4322e7d4f3417b7df33825bab8603d52051fmalita 262796fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 262887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 26298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 26304e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 263105c4a4322e7d4f3417b7df33825bab8603d52051fmalita iter.fDevice->drawPosText(iter, text, byteLength, xpos, 1, textOffset, 2632f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com dfp.paint()); 26338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2634b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 26354e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 26368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 26378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2638e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 2639e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkMatrix* matrix, const SkPaint& paint) { 264096fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 264187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 26428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 26438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawTextOnPath(iter, text, byteLength, path, 26444e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com matrix, looper.paint()); 26458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2646b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 2647945ec3a2bec668ca845071a65df8ec55e8f43819commit-bot@chromium.org LOOPER_END 26484325d114a5679e46f25ae75b0e43547fd7694998commit-bot@chromium.org} 26494325d114a5679e46f25ae75b0e43547fd7694998commit-bot@chromium.org 265000d5c2c6523321d25b32905ff4822f083a4173eefmalitavoid SkCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 265100d5c2c6523321d25b32905ff4822f083a4173eefmalita const SkPaint& paint) { 26527ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita 265385d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita SkRect storage; 265496fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 265519653d1d004610b4ba07ce563a5701164e120e45fmalita if (paint.canComputeFastBounds()) { 265685d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita storage = blob->bounds().makeOffset(x, y); 265787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect tmp; 265887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(storage, &tmp))) { 265987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 266087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 266187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &storage; 26627ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita } 26637ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita 2664024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita // We cannot filter in the looper as we normally do, because the paint is 2665024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita // incomplete at this point (text-related attributes are embedded within blob run paints). 2666024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita SkDrawFilter* drawFilter = fMCRec->fFilter; 266796fcdcc219d2a0d3579719b84b28bede76efba64halcanary fMCRec->fFilter = nullptr; 2668024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita 266985d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, bounds) 267000d5c2c6523321d25b32905ff4822f083a4173eefmalita 2671aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita while (iter.next()) { 2672aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 2673024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita iter.fDevice->drawTextBlob(iter, blob, x, y, dfp.paint(), drawFilter); 267400d5c2c6523321d25b32905ff4822f083a4173eefmalita } 267500d5c2c6523321d25b32905ff4822f083a4173eefmalita 2676aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita LOOPER_END 2677024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita 2678024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita fMCRec->fFilter = drawFilter; 267900d5c2c6523321d25b32905ff4822f083a4173eefmalita} 268000d5c2c6523321d25b32905ff4822f083a4173eefmalita 2681e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com// These will become non-virtual, so they always call the (virtual) onDraw... method 2682e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 2683e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 26849881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawText()"); 2685e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawText(text, byteLength, x, y, paint); 2686e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2687e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawPosText(const void* text, size_t byteLength, const SkPoint pos[], 2688e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 26899881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPosText()"); 2690e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawPosText(text, byteLength, pos, paint); 2691e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2692e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], 2693e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com SkScalar constY, const SkPaint& paint) { 26949881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPosTextH()"); 2695e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawPosTextH(text, byteLength, xpos, constY, paint); 2696e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2697e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 2698e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkMatrix* matrix, const SkPaint& paint) { 26999881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextOnPath()"); 2700e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawTextOnPath(text, byteLength, path, matrix, paint); 2701e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 270200d5c2c6523321d25b32905ff4822f083a4173eefmalitavoid SkCanvas::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 270300d5c2c6523321d25b32905ff4822f083a4173eefmalita const SkPaint& paint) { 2704e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(blob); 27059881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextBlob()"); 2706e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawTextBlob(blob, x, y, paint); 270700d5c2c6523321d25b32905ff4822f083a4173eefmalita} 2708e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com 270941af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawVertices(VertexMode vmode, int vertexCount, 271041af966ab338e95eee81ab618ab28195075338f7reed const SkPoint verts[], const SkPoint texs[], 271141af966ab338e95eee81ab618ab28195075338f7reed const SkColor colors[], SkXfermode* xmode, 271241af966ab338e95eee81ab618ab28195075338f7reed const uint16_t indices[], int indexCount, 271341af966ab338e95eee81ab618ab28195075338f7reed const SkPaint& paint) { 27149881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawVertices()"); 271596fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, nullptr) 27164b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 27178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 27188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawVertices(iter, vmode, vertexCount, verts, texs, 27194e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com colors, xmode, indices, indexCount, 27204e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com looper.paint()); 27218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 27224b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 27234e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 27248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2726b3c9d1c33caf325aada244204215eb790c228c12dandovvoid SkCanvas::drawPatch(const SkPoint cubics[12], const SkColor colors[4], 2727b3c9d1c33caf325aada244204215eb790c228c12dandov const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint) { 27289881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPatch()"); 272996fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == cubics) { 2730b3c9d1c33caf325aada244204215eb790c228c12dandov return; 2731b3c9d1c33caf325aada244204215eb790c228c12dandov } 27326cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2733ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov // Since a patch is always within the convex hull of the control points, we discard it when its 2734ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov // bounding rectangle is completely outside the current clip. 2735ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov SkRect bounds; 2736b3c9d1c33caf325aada244204215eb790c228c12dandov bounds.set(cubics, SkPatchUtils::kNumCtrlPts); 2737ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov if (this->quickReject(bounds)) { 2738ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov return; 2739ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov } 27406cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2741b3c9d1c33caf325aada244204215eb790c228c12dandov this->onDrawPatch(cubics, colors, texCoords, xmode, paint); 2742b3c9d1c33caf325aada244204215eb790c228c12dandov} 2743b3c9d1c33caf325aada244204215eb790c228c12dandov 2744b3c9d1c33caf325aada244204215eb790c228c12dandovvoid SkCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], 2745b3c9d1c33caf325aada244204215eb790c228c12dandov const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint) { 2746b3c9d1c33caf325aada244204215eb790c228c12dandov 274796fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, nullptr) 27486cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2749ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov while (iter.next()) { 2750b3c9d1c33caf325aada244204215eb790c228c12dandov iter.fDevice->drawPatch(iter, cubics, colors, texCoords, xmode, paint); 2751ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov } 27526cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2753ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov LOOPER_END 2754ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov} 2755ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov 2756a8db72864a43ad1fbba3c2892cf5cd88060a43efreedvoid SkCanvas::drawDrawable(SkDrawable* dr, SkScalar x, SkScalar y) { 2757e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(dr); 2758e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed if (x || y) { 2759e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed SkMatrix matrix = SkMatrix::MakeTrans(x, y); 2760e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawDrawable(dr, &matrix); 2761e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed } else { 2762e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawDrawable(dr, nullptr); 2763a8db72864a43ad1fbba3c2892cf5cd88060a43efreed } 2764a8db72864a43ad1fbba3c2892cf5cd88060a43efreed} 2765a8db72864a43ad1fbba3c2892cf5cd88060a43efreed 2766a8db72864a43ad1fbba3c2892cf5cd88060a43efreedvoid SkCanvas::drawDrawable(SkDrawable* dr, const SkMatrix* matrix) { 2767e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(dr); 2768e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed if (matrix && matrix->isIdentity()) { 2769e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed matrix = nullptr; 27706a070dc06af4e9f305f9d08a69e34d18ade473cbreed } 2771e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawDrawable(dr, matrix); 27726a070dc06af4e9f305f9d08a69e34d18ade473cbreed} 27736a070dc06af4e9f305f9d08a69e34d18ade473cbreed 2774a8db72864a43ad1fbba3c2892cf5cd88060a43efreedvoid SkCanvas::onDrawDrawable(SkDrawable* dr, const SkMatrix* matrix) { 2775a8db72864a43ad1fbba3c2892cf5cd88060a43efreed SkRect bounds = dr->getBounds(); 2776a8db72864a43ad1fbba3c2892cf5cd88060a43efreed if (matrix) { 2777a8db72864a43ad1fbba3c2892cf5cd88060a43efreed matrix->mapRect(&bounds); 2778a8db72864a43ad1fbba3c2892cf5cd88060a43efreed } 2779a8db72864a43ad1fbba3c2892cf5cd88060a43efreed if (this->quickReject(bounds)) { 2780a8db72864a43ad1fbba3c2892cf5cd88060a43efreed return; 2781a8db72864a43ad1fbba3c2892cf5cd88060a43efreed } 2782a8db72864a43ad1fbba3c2892cf5cd88060a43efreed dr->draw(this, matrix); 27836a070dc06af4e9f305f9d08a69e34d18ade473cbreed} 27846a070dc06af4e9f305f9d08a69e34d18ade473cbreed 278571c3c760a83123ee0b3127b8c65c6394ce541c50reedvoid SkCanvas::onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], 278671c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkColor colors[], int count, SkXfermode::Mode mode, 278771c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkRect* cull, const SkPaint* paint) { 278871c3c760a83123ee0b3127b8c65c6394ce541c50reed if (cull && this->quickReject(*cull)) { 278971c3c760a83123ee0b3127b8c65c6394ce541c50reed return; 279071c3c760a83123ee0b3127b8c65c6394ce541c50reed } 279171c3c760a83123ee0b3127b8c65c6394ce541c50reed 279271c3c760a83123ee0b3127b8c65c6394ce541c50reed SkPaint pnt; 279371c3c760a83123ee0b3127b8c65c6394ce541c50reed if (paint) { 279471c3c760a83123ee0b3127b8c65c6394ce541c50reed pnt = *paint; 279571c3c760a83123ee0b3127b8c65c6394ce541c50reed } 27969d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 279796fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(pnt, SkDrawFilter::kPath_Type, nullptr) 279871c3c760a83123ee0b3127b8c65c6394ce541c50reed while (iter.next()) { 279971c3c760a83123ee0b3127b8c65c6394ce541c50reed iter.fDevice->drawAtlas(iter, atlas, xform, tex, colors, count, mode, pnt); 280071c3c760a83123ee0b3127b8c65c6394ce541c50reed } 280171c3c760a83123ee0b3127b8c65c6394ce541c50reed LOOPER_END 280271c3c760a83123ee0b3127b8c65c6394ce541c50reed} 280371c3c760a83123ee0b3127b8c65c6394ce541c50reed 2804f70b531daaf47db1ee95c70da9843f1dd1f418d3reedvoid SkCanvas::onDrawAnnotation(const SkRect& rect, const char key[], SkData* value) { 2805f70b531daaf47db1ee95c70da9843f1dd1f418d3reed SkASSERT(key); 2806f70b531daaf47db1ee95c70da9843f1dd1f418d3reed 2807f70b531daaf47db1ee95c70da9843f1dd1f418d3reed SkPaint paint; 2808f70b531daaf47db1ee95c70da9843f1dd1f418d3reed LOOPER_BEGIN(paint, SkDrawFilter::kRect_Type, nullptr) 2809f70b531daaf47db1ee95c70da9843f1dd1f418d3reed while (iter.next()) { 2810f70b531daaf47db1ee95c70da9843f1dd1f418d3reed iter.fDevice->drawAnnotation(iter, rect, key, value); 2811f70b531daaf47db1ee95c70da9843f1dd1f418d3reed } 2812f70b531daaf47db1ee95c70da9843f1dd1f418d3reed LOOPER_END 2813f70b531daaf47db1ee95c70da9843f1dd1f418d3reed} 2814f70b531daaf47db1ee95c70da9843f1dd1f418d3reed 28158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 28168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// These methods are NOT virtual, and therefore must call back into virtual 28178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// methods, rather than actually drawing themselves. 28188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 28198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b, 2821845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com SkXfermode::Mode mode) { 28229881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawARGB()"); 28238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 28248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setARGB(a, r, g, b); 2826845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com if (SkXfermode::kSrcOver_Mode != mode) { 28270baf19375466cfc24c96532df406e7c5b1d1aae8reed@android.com paint.setXfermodeMode(mode); 28288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 28298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPaint(paint); 28308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2832845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.comvoid SkCanvas::drawColor(SkColor c, SkXfermode::Mode mode) { 28339881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawColor()"); 28348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 28358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setColor(c); 2837845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com if (SkXfermode::kSrcOver_Mode != mode) { 28380baf19375466cfc24c96532df406e7c5b1d1aae8reed@android.com paint.setXfermodeMode(mode); 28398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 28408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPaint(paint); 28418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPoint(SkScalar x, SkScalar y, const SkPaint& paint) { 28449881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPoint(SkPaint)"); 28458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pt; 28464b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 28478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pt.set(x, y); 28488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kPoints_PointMode, 1, &pt, paint); 28498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPoint(SkScalar x, SkScalar y, SkColor color) { 28529881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPoint(SkColor)"); 28538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pt; 28548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 28554b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 28568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pt.set(x, y); 28578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setColor(color); 28588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kPoints_PointMode, 1, &pt, paint); 28598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, 28628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 28639881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawLine()"); 28648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pts[2]; 28654b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 28668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pts[0].set(x0, y0); 28678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pts[1].set(x1, y1); 28688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kLines_PointMode, 2, pts, paint); 28698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawRectCoords(SkScalar left, SkScalar top, 28728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar right, SkScalar bottom, 28738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 28749881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRectCoords()"); 28758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 28768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.set(left, top, right, bottom); 28788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawRect(r, paint); 28798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, 28828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 28839881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawCircle()"); 28848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (radius < 0) { 28858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com radius = 0; 28868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 28878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 28898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.set(cx - radius, cy - radius, cx + radius, cy + radius); 28904ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->drawOval(r, paint); 28918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawRoundRect(const SkRect& r, SkScalar rx, SkScalar ry, 28948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 28959881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRoundRect()"); 28968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (rx > 0 && ry > 0) { 28978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.canComputeFastBounds()) { 28988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect storage; 28993b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(paint.computeFastBounds(r, &storage))) { 29008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 29018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 29028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 29034ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com SkRRect rrect; 29044ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com rrect.setRectXY(r, rx, ry); 29054ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->drawRRect(rrect, paint); 29068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 29078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawRect(r, paint); 29088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 29098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 29108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawArc(const SkRect& oval, SkScalar startAngle, 29128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar sweepAngle, bool useCenter, 29138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 29149881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawArc()"); 29158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (SkScalarAbs(sweepAngle) >= SkIntToScalar(360)) { 29168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawOval(oval, paint); 29178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 29188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath path; 29198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (useCenter) { 29208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.moveTo(oval.centerX(), oval.centerY()); 29218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 29228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.arcTo(oval, startAngle, sweepAngle, !useCenter); 29238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (useCenter) { 29248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.close(); 29258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 29268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPath(path, paint); 29278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 29288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 29298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawTextOnPathHV(const void* text, size_t byteLength, 29318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPath& path, SkScalar hOffset, 29328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar vOffset, const SkPaint& paint) { 29339881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextOnPathHV()"); 29348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 29354b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 29368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.setTranslate(hOffset, vOffset); 29378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawTextOnPath(text, byteLength, path, &matrix, paint); 29388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 29398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2940f76bacff7f66724072c67edb185abf9e3add11a0reed@android.com/////////////////////////////////////////////////////////////////////////////// 29411c2c441fede0ae9573afc098017011e3439624a9reed 29421c2c441fede0ae9573afc098017011e3439624a9reed/** 29431c2c441fede0ae9573afc098017011e3439624a9reed * This constant is trying to balance the speed of ref'ing a subpicture into a parent picture, 29441c2c441fede0ae9573afc098017011e3439624a9reed * against the playback cost of recursing into the subpicture to get at its actual ops. 29451c2c441fede0ae9573afc098017011e3439624a9reed * 29461c2c441fede0ae9573afc098017011e3439624a9reed * For now we pick a conservatively small value, though measurement (and other heuristics like 29471c2c441fede0ae9573afc098017011e3439624a9reed * the type of ops contained) may justify changing this value. 29481c2c441fede0ae9573afc098017011e3439624a9reed */ 29491c2c441fede0ae9573afc098017011e3439624a9reed#define kMaxPictureOpsToUnrollInsteadOfRef 1 29509b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips 2951d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedvoid SkCanvas::drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint) { 2952e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(picture); 2953e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed 29541c2c441fede0ae9573afc098017011e3439624a9reed TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPicture()"); 2955e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed if (matrix && matrix->isIdentity()) { 2956e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed matrix = nullptr; 2957e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed } 2958e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed if (picture->approximateOpCount() <= kMaxPictureOpsToUnrollInsteadOfRef) { 2959e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); 2960e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed picture->playback(this); 2961e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed } else { 2962e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawPicture(picture, matrix, paint); 2963d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 2964d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 29659b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips 2966d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedvoid SkCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix, 2967d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed const SkPaint* paint) { 2968d028180f0310cf2b23f9744256a41697b0683e67fmalita if (!paint || paint->canComputeFastBounds()) { 2969d028180f0310cf2b23f9744256a41697b0683e67fmalita SkRect bounds = picture->cullRect(); 2970d028180f0310cf2b23f9744256a41697b0683e67fmalita if (paint) { 2971d028180f0310cf2b23f9744256a41697b0683e67fmalita paint->computeFastBounds(bounds, &bounds); 2972d028180f0310cf2b23f9744256a41697b0683e67fmalita } 2973d028180f0310cf2b23f9744256a41697b0683e67fmalita if (matrix) { 2974d028180f0310cf2b23f9744256a41697b0683e67fmalita matrix->mapRect(&bounds); 2975d028180f0310cf2b23f9744256a41697b0683e67fmalita } 2976d028180f0310cf2b23f9744256a41697b0683e67fmalita if (this->quickReject(bounds)) { 2977d028180f0310cf2b23f9744256a41697b0683e67fmalita return; 2978d028180f0310cf2b23f9744256a41697b0683e67fmalita } 2979d028180f0310cf2b23f9744256a41697b0683e67fmalita } 2980d028180f0310cf2b23f9744256a41697b0683e67fmalita 2981145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org SkBaseDevice* device = this->getTopDevice(); 298249f085dddff10473b6ebf832a974288300224e60bsalomon if (device) { 2983145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org // Canvas has to first give the device the opportunity to render 2984145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org // the picture itself. 2985d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed if (device->EXPERIMENTAL_drawPicture(this, picture, matrix, paint)) { 2986145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org return; // the device has rendered the entire picture 2987145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org } 2988145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org } 2989145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org 2990a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); 2991c5ba71d2e5cd426def66fa49dcf003e5b2c98dc7robertphillips picture->playback(this); 29928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 29938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 29958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 29968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::LayerIter::LayerIter(SkCanvas* canvas, bool skipEmptyClips) { 299899fe82260633fcf5d92cca38d12ef0937ecca61cbungeman static_assert(sizeof(fStorage) >= sizeof(SkDrawIter), "fStorage_too_small"); 29998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(canvas); 30018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fImpl = new (fStorage) SkDrawIter(canvas, skipEmptyClips); 30038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDone = !fImpl->next(); 30048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 30058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::LayerIter::~LayerIter() { 30078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fImpl->~SkDrawIter(); 30088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 30098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::LayerIter::next() { 30118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDone = !fImpl->next(); 30128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 30138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30141f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::LayerIter::device() const { 30158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fImpl->getDevice(); 30168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 30178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkMatrix& SkCanvas::LayerIter::matrix() const { 30198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fImpl->getMatrix(); 30208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 30218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkPaint& SkCanvas::LayerIter::paint() const { 30238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* paint = fImpl->getPaint(); 302496fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 30258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint = &fDefaultPaint; 30268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 30278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return *paint; 30288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 30298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkRegion& SkCanvas::LayerIter::clip() const { return fImpl->getClip(); } 30318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::LayerIter::x() const { return fImpl->getX(); } 30328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::LayerIter::y() const { return fImpl->getY(); } 303320a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com 303420a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com/////////////////////////////////////////////////////////////////////////////// 303520a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com 3036c3b589a24eb4d567a906189f882c259ecf5c2f58fmalitaSkCanvasClipVisitor::~SkCanvasClipVisitor() { } 30373107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 30383107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 30393107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 30403107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.orgstatic bool supported_for_raster_canvas(const SkImageInfo& info) { 30413107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org switch (info.alphaType()) { 30423107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kPremul_SkAlphaType: 30433107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kOpaque_SkAlphaType: 30443107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org break; 30453107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org default: 30463107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return false; 30473107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 30483107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 30493107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org switch (info.colorType()) { 30503107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kAlpha_8_SkColorType: 30513107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kRGB_565_SkColorType: 305228fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org case kN32_SkColorType: 30533107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org break; 30543107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org default: 30553107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return false; 30563107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 30573107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 30583107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return true; 30593107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org} 30603107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 306142b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.orgSkCanvas* SkCanvas::NewRasterDirect(const SkImageInfo& info, void* pixels, size_t rowBytes) { 306242b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org if (!supported_for_raster_canvas(info)) { 306396fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 306442b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org } 3065eb849e5fd10cbe00cbc31307ba97fd9efca0b41bskia.committer@gmail.com 306642b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org SkBitmap bitmap; 306742b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org if (!bitmap.installPixels(info, pixels, rowBytes)) { 306896fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 306942b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org } 3070385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return new SkCanvas(bitmap); 307142b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org} 3072d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 3073d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed/////////////////////////////////////////////////////////////////////////////// 3074d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 3075d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedSkAutoCanvasMatrixPaint::SkAutoCanvasMatrixPaint(SkCanvas* canvas, const SkMatrix* matrix, 3076a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips const SkPaint* paint, const SkRect& bounds) 3077d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed : fCanvas(canvas) 3078d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed , fSaveCount(canvas->getSaveCount()) 3079d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed{ 308049f085dddff10473b6ebf832a974288300224e60bsalomon if (paint) { 3081a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkRect newBounds = bounds; 3082d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed if (matrix) { 3083a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips matrix->mapRect(&newBounds); 3084d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 3085a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips canvas->saveLayer(&newBounds, paint); 308649f085dddff10473b6ebf832a974288300224e60bsalomon } else if (matrix) { 3087d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed canvas->save(); 3088d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 30896cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 309049f085dddff10473b6ebf832a974288300224e60bsalomon if (matrix) { 3091d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed canvas->concat(*matrix); 3092d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 3093d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 3094d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 3095d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedSkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { 3096d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed fCanvas->restoreToCount(fSaveCount); 3097d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 3098e8f3062a36d3682f4019309a32b5b84dc9eddf8creed 3099e8f3062a36d3682f4019309a32b5b84dc9eddf8creed#ifdef SK_SUPPORT_LEGACY_NEW_SURFACE_API 3100e8f3062a36d3682f4019309a32b5b84dc9eddf8creedSkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* props) { 3101e8f3062a36d3682f4019309a32b5b84dc9eddf8creed return this->makeSurface(info, props).release(); 3102e8f3062a36d3682f4019309a32b5b84dc9eddf8creed} 3103e8f3062a36d3682f4019309a32b5b84dc9eddf8creed#endif 3104