SkCanvas.cpp revision 704cd32e4a92d6c3eae6bfae4adcc20126bf4437
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" 17b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr#include "SkImage.h" 18262a71b7f95ce98ff3dd8dba845afbd724470903reed#include "SkImage_Base.h" 19900c36779610dc65c42a5004ee3693fd70961ba4senorblanco#include "SkImageFilter.h" 20900c36779610dc65c42a5004ee3693fd70961ba4senorblanco#include "SkImageFilterCache.h" 21c573a40ed5024b463e47088d307e3164a486dba5msarett#include "SkLatticeIter.h" 22262a71b7f95ce98ff3dd8dba845afbd724470903reed#include "SkMatrixUtils.h" 2374bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org#include "SkMetaData.h" 24fbfa25802709139c2f14e304319c9541da65ca27msarett#include "SkNx.h" 25c83a29759a5c2966da5ab973e4fd90763e4c962breed#include "SkPaintPriv.h" 26b3c9d1c33caf325aada244204215eb790c228c12dandov#include "SkPatchUtils.h" 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPicture.h" 28b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack#include "SkRadialShadowMapShader.h" 290017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com#include "SkRasterClip.h" 3096472deea70169396b8e1f576e470138f55fdb1freed#include "SkReadPixelsRec.h" 314ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com#include "SkRRect.h" 32904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack#include "SkShadowPaintFilterCanvas.h" 33904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack#include "SkShadowShader.h" 3479fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org#include "SkSmallAllocator.h" 354418dbac3386f26c8da62ab242be9c178961eb18robertphillips#include "SkSpecialImage.h" 3697af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com#include "SkSurface_Base.h" 377ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita#include "SkTextBlob.h" 3852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com#include "SkTextFormatParams.h" 39a076e9be17654a60310e72c4f70fcd5337f56dbfreed@google.com#include "SkTLazy.h" 408f757f540a8378c7b1354aab3d4650eaa920b17adanakj#include "SkTraceEvent.h" 41d3ebb48320cf1b7e969974673e4bd7743816985ebungeman#include <new> 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 43644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#if SK_SUPPORT_GPU 447354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips#include "GrContext.h" 45644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#include "GrRenderTarget.h" 46614d8f9a3c44e22d77fa909e82119e8a6746e1b1bsalomon#include "SkGrPriv.h" 47e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack 48644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#endif 49644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org 50e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed#define RETURN_ON_NULL(ptr) do { if (nullptr == (ptr)) return; } while (0) 51e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed 52c83a29759a5c2966da5ab973e4fd90763e4c962breed/* 53c83a29759a5c2966da5ab973e4fd90763e4c962breed * Return true if the drawing this rect would hit every pixels in the canvas. 54c83a29759a5c2966da5ab973e4fd90763e4c962breed * 55c83a29759a5c2966da5ab973e4fd90763e4c962breed * Returns false if 56c83a29759a5c2966da5ab973e4fd90763e4c962breed * - rect does not contain the canvas' bounds 57c83a29759a5c2966da5ab973e4fd90763e4c962breed * - paint is not fill 58c83a29759a5c2966da5ab973e4fd90763e4c962breed * - paint would blur or otherwise change the coverage of the rect 59c83a29759a5c2966da5ab973e4fd90763e4c962breed */ 60c83a29759a5c2966da5ab973e4fd90763e4c962breedbool SkCanvas::wouldOverwriteEntireSurface(const SkRect* rect, const SkPaint* paint, 61c83a29759a5c2966da5ab973e4fd90763e4c962breed ShaderOverrideOpacity overrideOpacity) const { 6299fe82260633fcf5d92cca38d12ef0937ecca61cbungeman static_assert((int)SkPaintPriv::kNone_ShaderOverrideOpacity == 6399fe82260633fcf5d92cca38d12ef0937ecca61cbungeman (int)kNone_ShaderOverrideOpacity, 6499fe82260633fcf5d92cca38d12ef0937ecca61cbungeman "need_matching_enums0"); 6599fe82260633fcf5d92cca38d12ef0937ecca61cbungeman static_assert((int)SkPaintPriv::kOpaque_ShaderOverrideOpacity == 6699fe82260633fcf5d92cca38d12ef0937ecca61cbungeman (int)kOpaque_ShaderOverrideOpacity, 6799fe82260633fcf5d92cca38d12ef0937ecca61cbungeman "need_matching_enums1"); 6899fe82260633fcf5d92cca38d12ef0937ecca61cbungeman static_assert((int)SkPaintPriv::kNotOpaque_ShaderOverrideOpacity == 6999fe82260633fcf5d92cca38d12ef0937ecca61cbungeman (int)kNotOpaque_ShaderOverrideOpacity, 7099fe82260633fcf5d92cca38d12ef0937ecca61cbungeman "need_matching_enums2"); 71c83a29759a5c2966da5ab973e4fd90763e4c962breed 72c83a29759a5c2966da5ab973e4fd90763e4c962breed const SkISize size = this->getBaseLayerSize(); 73c83a29759a5c2966da5ab973e4fd90763e4c962breed const SkRect bounds = SkRect::MakeIWH(size.width(), size.height()); 74c83a29759a5c2966da5ab973e4fd90763e4c962breed if (!this->getClipStack()->quickContains(bounds)) { 75c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; 76c83a29759a5c2966da5ab973e4fd90763e4c962breed } 77c83a29759a5c2966da5ab973e4fd90763e4c962breed 78c83a29759a5c2966da5ab973e4fd90763e4c962breed if (rect) { 79c5769b2e49a63516f313f42969983f2b9e4d59e0halcanary if (!this->getTotalMatrix().isScaleTranslate()) { 80c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; // conservative 81c83a29759a5c2966da5ab973e4fd90763e4c962breed } 82c5769b2e49a63516f313f42969983f2b9e4d59e0halcanary 83c5769b2e49a63516f313f42969983f2b9e4d59e0halcanary SkRect devRect; 84c5769b2e49a63516f313f42969983f2b9e4d59e0halcanary this->getTotalMatrix().mapRectScaleTranslate(&devRect, *rect); 85c5769b2e49a63516f313f42969983f2b9e4d59e0halcanary if (!devRect.contains(bounds)) { 86c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; 87c83a29759a5c2966da5ab973e4fd90763e4c962breed } 88c83a29759a5c2966da5ab973e4fd90763e4c962breed } 89c83a29759a5c2966da5ab973e4fd90763e4c962breed 90c83a29759a5c2966da5ab973e4fd90763e4c962breed if (paint) { 91c83a29759a5c2966da5ab973e4fd90763e4c962breed SkPaint::Style paintStyle = paint->getStyle(); 92c83a29759a5c2966da5ab973e4fd90763e4c962breed if (!(paintStyle == SkPaint::kFill_Style || 93c83a29759a5c2966da5ab973e4fd90763e4c962breed paintStyle == SkPaint::kStrokeAndFill_Style)) { 94c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; 95c83a29759a5c2966da5ab973e4fd90763e4c962breed } 96c83a29759a5c2966da5ab973e4fd90763e4c962breed if (paint->getMaskFilter() || paint->getLooper() 97c83a29759a5c2966da5ab973e4fd90763e4c962breed || paint->getPathEffect() || paint->getImageFilter()) { 98c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; // conservative 99c83a29759a5c2966da5ab973e4fd90763e4c962breed } 100c83a29759a5c2966da5ab973e4fd90763e4c962breed } 101c83a29759a5c2966da5ab973e4fd90763e4c962breed return SkPaintPriv::Overwrites(paint, (SkPaintPriv::ShaderOverrideOpacity)overrideOpacity); 102c83a29759a5c2966da5ab973e4fd90763e4c962breed} 103c83a29759a5c2966da5ab973e4fd90763e4c962breed 104c83a29759a5c2966da5ab973e4fd90763e4c962breed/////////////////////////////////////////////////////////////////////////////////////////////////// 105c83a29759a5c2966da5ab973e4fd90763e4c962breed 106d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareedstatic bool gIgnoreSaveLayerBounds; 107d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareedvoid SkCanvas::Internal_Private_SetIgnoreSaveLayerBounds(bool ignore) { 108d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed gIgnoreSaveLayerBounds = ignore; 109d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed} 110d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareedbool SkCanvas::Internal_Private_GetIgnoreSaveLayerBounds() { 111d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed return gIgnoreSaveLayerBounds; 112d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed} 113d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed 1140acf1b4b3645772d220c720313821bac389751b5reedstatic bool gTreatSpriteAsBitmap; 1150acf1b4b3645772d220c720313821bac389751b5reedvoid SkCanvas::Internal_Private_SetTreatSpriteAsBitmap(bool spriteAsBitmap) { 1160acf1b4b3645772d220c720313821bac389751b5reed gTreatSpriteAsBitmap = spriteAsBitmap; 1170acf1b4b3645772d220c720313821bac389751b5reed} 1180acf1b4b3645772d220c720313821bac389751b5reedbool SkCanvas::Internal_Private_GetTreatSpriteAsBitmap() { 1190acf1b4b3645772d220c720313821bac389751b5reed return gTreatSpriteAsBitmap; 1200acf1b4b3645772d220c720313821bac389751b5reed} 1210acf1b4b3645772d220c720313821bac389751b5reed 122da17f758442f16747af39f8fbaed9c097048519creed@google.com// experimental for faster tiled drawing... 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//#define SK_TRACE_SAVERESTORE 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_TRACE_SAVERESTORE 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gLayerCounter; 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_layer() { ++gLayerCounter; printf("----- inc layer %d\n", gLayerCounter); } 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_layer() { --gLayerCounter; printf("----- dec layer %d\n", gLayerCounter); } 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gRecCounter; 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_rec() { ++gRecCounter; printf("----- inc rec %d\n", gRecCounter); } 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_rec() { --gRecCounter; printf("----- dec rec %d\n", gRecCounter); } 1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gCanvasCounter; 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_canvas() { ++gCanvasCounter; printf("----- inc canvas %d\n", gCanvasCounter); } 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_canvas() { --gCanvasCounter; printf("----- dec canvas %d\n", gCanvasCounter); } 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_layer() 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_layer() 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_rec() 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_rec() 1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_canvas() 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_canvas() 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1462c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.orgtypedef SkTLazy<SkPaint> SkLazyPaint; 1472c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org 148c83a29759a5c2966da5ab973e4fd90763e4c962breedvoid SkCanvas::predrawNotify(bool willOverwritesEntireSurface) { 14997af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com if (fSurfaceBase) { 150c83a29759a5c2966da5ab973e4fd90763e4c962breed fSurfaceBase->aboutToDraw(willOverwritesEntireSurface 151c83a29759a5c2966da5ab973e4fd90763e4c962breed ? SkSurface::kDiscard_ContentChangeMode 152c83a29759a5c2966da5ab973e4fd90763e4c962breed : SkSurface::kRetain_ContentChangeMode); 153c83a29759a5c2966da5ab973e4fd90763e4c962breed } 154c83a29759a5c2966da5ab973e4fd90763e4c962breed} 155c83a29759a5c2966da5ab973e4fd90763e4c962breed 156c83a29759a5c2966da5ab973e4fd90763e4c962breedvoid SkCanvas::predrawNotify(const SkRect* rect, const SkPaint* paint, 157c83a29759a5c2966da5ab973e4fd90763e4c962breed ShaderOverrideOpacity overrideOpacity) { 158c83a29759a5c2966da5ab973e4fd90763e4c962breed if (fSurfaceBase) { 159c83a29759a5c2966da5ab973e4fd90763e4c962breed SkSurface::ContentChangeMode mode = SkSurface::kRetain_ContentChangeMode; 160c83a29759a5c2966da5ab973e4fd90763e4c962breed // Since willOverwriteAllPixels() may not be complete free to call, we only do so if 161c83a29759a5c2966da5ab973e4fd90763e4c962breed // there is an outstanding snapshot, since w/o that, there will be no copy-on-write 162c83a29759a5c2966da5ab973e4fd90763e4c962breed // and therefore we don't care which mode we're in. 163c83a29759a5c2966da5ab973e4fd90763e4c962breed // 164c83a29759a5c2966da5ab973e4fd90763e4c962breed if (fSurfaceBase->outstandingImageSnapshot()) { 165c83a29759a5c2966da5ab973e4fd90763e4c962breed if (this->wouldOverwriteEntireSurface(rect, paint, overrideOpacity)) { 166c83a29759a5c2966da5ab973e4fd90763e4c962breed mode = SkSurface::kDiscard_ContentChangeMode; 167c83a29759a5c2966da5ab973e4fd90763e4c962breed } 168c83a29759a5c2966da5ab973e4fd90763e4c962breed } 169c83a29759a5c2966da5ab973e4fd90763e4c962breed fSurfaceBase->aboutToDraw(mode); 17097af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com } 17197af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com} 17297af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com 1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1751f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com/* This is the record we keep for each SkBaseDevice that the user installs. 1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com The clip/matrix/proc are fields that reflect the top of the save/restore 1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stack. Whenever the canvas changes, it marks a dirty flag, and then before 1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com these are used (assuming we're not on a layer) we rebuild these cache 1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com values: they reflect the top of the save stack, but translated and clipped 1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com by the device's XY offset and bitmap-bounds. 1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct DeviceCM { 1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* fNext; 1841f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* fDevice; 185045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com SkRasterClip fClip; 1866f8f292aa768869a9e85c314b124875f57504f2creed@google.com SkPaint* fPaint; // may be null (in the future) 18761f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed const SkMatrix* fMatrix; 18861f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed SkMatrix fMatrixStorage; 1898c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkMatrix fStashedMatrix; // original CTM; used by imagefilter in saveLayer 1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19196e657d0e103b8358a77ecd913f6086929f792b8reed DeviceCM(SkBaseDevice* device, const SkPaint* paint, SkCanvas* canvas, 1927503d60847c4ad22df87458aecd917772b23d293reed bool conservativeRasterClip, const SkMatrix& stashed) 19396fcdcc219d2a0d3579719b84b28bede76efba64halcanary : fNext(nullptr) 194d954498c01ccf0417feacf89e45d0c62a06a813breed , fClip(conservativeRasterClip) 1958c30a8196dd5903d2d23b4d0a5dc888e802bf698reed , fStashedMatrix(stashed) 196d954498c01ccf0417feacf89e45d0c62a06a813breed { 1972c9e20055be772feb3f44986c1af0c0a979eff49reed SkSafeRef(device); 1984b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com fDevice = device; 19996fcdcc219d2a0d3579719b84b28bede76efba64halcanary fPaint = paint ? new SkPaint(*paint) : nullptr; 20088edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20288edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com ~DeviceCM() { 2032c9e20055be772feb3f44986c1af0c0a979eff49reed SkSafeUnref(fDevice); 204385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete fPaint; 20588edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 2064b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 207feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein void reset(const SkIRect& bounds) { 208feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(!fPaint); 209feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(!fNext); 210feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(fDevice); 211feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fClip.setRect(bounds); 212feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein } 213feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 214045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com void updateMC(const SkMatrix& totalMatrix, const SkRasterClip& totalClip, 215de6c531e468197bb7746f1217a8ccb2ab175e0b8reed SkRasterClip* updateClip) { 2166f8f292aa768869a9e85c314b124875f57504f2creed@google.com int x = fDevice->getOrigin().x(); 2176f8f292aa768869a9e85c314b124875f57504f2creed@google.com int y = fDevice->getOrigin().y(); 2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int width = fDevice->width(); 2198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int height = fDevice->height(); 2204b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if ((x | y) == 0) { 2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = &totalMatrix; 2238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fClip = totalClip; 2248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrixStorage = totalMatrix; 2268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrixStorage.postTranslate(SkIntToScalar(-x), 2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIntToScalar(-y)); 2288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = &fMatrixStorage; 2294b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com totalClip.translate(-x, -y, &fClip); 2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 233045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com fClip.op(SkIRect::MakeWH(width, height), SkRegion::kIntersect_Op); 2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // intersect clip, but don't translate it (yet) 2364b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (updateClip) { 238045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com updateClip->op(SkIRect::MakeXYWH(x, y, width, height), 2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRegion::kDifference_Op); 2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2414b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!fClip.isEmpty()) { 2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIRect deviceR; 2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com deviceR.set(0, 0, width, height); 2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(deviceR.contains(fClip.getBounds())); 2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 249f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* This is the record we keep for each save/restore level in the stack. 2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Since a level optionally copies the matrix and/or stack, we have pointers 2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for these fields. If the value is copied for this level, the copy is 2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stored in the ...Storage field, and the pointer points to that. If the 2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value is not copied for this level, we ignore ...Storage, and just point 2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com at the corresponding value in the previous level in the stack. 2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkCanvas::MCRec { 2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 2611f836ee096bb988adef4b9757b2629c7afeda36dreed SkDrawFilter* fFilter; // the current filter (or null) 262d954498c01ccf0417feacf89e45d0c62a06a813breed DeviceCM* fLayer; 2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* If there are any layers in the stack, this points to the top-most 2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com one that is at or below this level in the stack (so we know what 2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bitmap/device to draw into from this level. This value is NOT 2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com reference counted, since the real owner is either our fLayer field, 2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com or a previous one in a lower level.) 2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 2692ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed DeviceCM* fTopLayer; 2702ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkRasterClip fRasterClip; 2712ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkMatrix fMatrix; 2722ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed int fDeferredSaveCount; 2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 274e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack // This is the current cumulative depth (aggregate of all done translateZ calls) 275e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack SkScalar fCurDrawDepth; 276e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack 277d954498c01ccf0417feacf89e45d0c62a06a813breed MCRec(bool conservativeRasterClip) : fRasterClip(conservativeRasterClip) { 27896fcdcc219d2a0d3579719b84b28bede76efba64halcanary fFilter = nullptr; 27996fcdcc219d2a0d3579719b84b28bede76efba64halcanary fLayer = nullptr; 28096fcdcc219d2a0d3579719b84b28bede76efba64halcanary fTopLayer = nullptr; 2812ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fMatrix.reset(); 2822ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fDeferredSaveCount = 0; 283e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack fCurDrawDepth = 0; 284b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 285d954498c01ccf0417feacf89e45d0c62a06a813breed // don't bother initializing fNext 286d954498c01ccf0417feacf89e45d0c62a06a813breed inc_rec(); 287d954498c01ccf0417feacf89e45d0c62a06a813breed } 288e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack MCRec(const MCRec& prev) : fRasterClip(prev.fRasterClip), fMatrix(prev.fMatrix), 289e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack fCurDrawDepth(prev.fCurDrawDepth) { 290d954498c01ccf0417feacf89e45d0c62a06a813breed fFilter = SkSafeRef(prev.fFilter); 29196fcdcc219d2a0d3579719b84b28bede76efba64halcanary fLayer = nullptr; 292d954498c01ccf0417feacf89e45d0c62a06a813breed fTopLayer = prev.fTopLayer; 2932ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fDeferredSaveCount = 0; 294b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 2958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // don't bother initializing fNext 2968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inc_rec(); 2978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ~MCRec() { 29982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fFilter); 300385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete fLayer; 3018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dec_rec(); 3028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 303feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 304feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein void reset(const SkIRect& bounds) { 305feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(fLayer); 306feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(fDeferredSaveCount == 0); 307feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 308feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fMatrix.reset(); 309feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fRasterClip.setRect(bounds); 310feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fLayer->reset(bounds); 311feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein } 3128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 31402f9ed74ead11fcb01a24faa7d93f853e869f1abreedstatic SkIRect compute_device_bounds(SkBaseDevice* device) { 31502f9ed74ead11fcb01a24faa7d93f853e869f1abreed return SkIRect::MakeXYWH(device->getOrigin().x(), device->getOrigin().y(), 31602f9ed74ead11fcb01a24faa7d93f853e869f1abreed device->width(), device->height()); 31702f9ed74ead11fcb01a24faa7d93f853e869f1abreed} 31802f9ed74ead11fcb01a24faa7d93f853e869f1abreed 3198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkDrawIter : public SkDraw { 3208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 3213aafe111b6cc388400092851cc53bbbdfcb8a81creed SkDrawIter(SkCanvas* canvas) { 3228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com canvas->updateDeviceCMCache(); 3238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3246bd5284415bd983b0628c4941dff5def40018f5abungeman fClipStack = canvas->getClipStack(); 3258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = canvas->fMCRec->fTopLayer; 32602f9ed74ead11fcb01a24faa7d93f853e869f1abreed 32702f9ed74ead11fcb01a24faa7d93f853e869f1abreed fMultiDeviceCS = nullptr; 32802f9ed74ead11fcb01a24faa7d93f853e869f1abreed if (fCurrLayer->fNext) { 3296bd5284415bd983b0628c4941dff5def40018f5abungeman fMultiDeviceCS = canvas->fClipStack.get(); 33002f9ed74ead11fcb01a24faa7d93f853e869f1abreed fMultiDeviceCS->save(); 33102f9ed74ead11fcb01a24faa7d93f853e869f1abreed } 33202f9ed74ead11fcb01a24faa7d93f853e869f1abreed } 33302f9ed74ead11fcb01a24faa7d93f853e869f1abreed 33402f9ed74ead11fcb01a24faa7d93f853e869f1abreed ~SkDrawIter() { 33502f9ed74ead11fcb01a24faa7d93f853e869f1abreed if (fMultiDeviceCS) { 33602f9ed74ead11fcb01a24faa7d93f853e869f1abreed fMultiDeviceCS->restore(); 33702f9ed74ead11fcb01a24faa7d93f853e869f1abreed } 3388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3394b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 3408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool next() { 34102f9ed74ead11fcb01a24faa7d93f853e869f1abreed if (fMultiDeviceCS && fDevice) { 34202f9ed74ead11fcb01a24faa7d93f853e869f1abreed // remove the previous device's bounds 34373603f3c52ffd89fe9d035be827b566a0e7d3b79reed fMultiDeviceCS->clipDevRect(compute_device_bounds(fDevice), SkCanvas::kDifference_Op); 34402f9ed74ead11fcb01a24faa7d93f853e869f1abreed } 34502f9ed74ead11fcb01a24faa7d93f853e869f1abreed 3468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // skip over recs with empty clips 3473aafe111b6cc388400092851cc53bbbdfcb8a81creed while (fCurrLayer && fCurrLayer->fClip.isEmpty()) { 3483aafe111b6cc388400092851cc53bbbdfcb8a81creed fCurrLayer = fCurrLayer->fNext; 3498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 351f68c5e2f9f05b3af2bae0979ace2684b6041b6e3reed@google.com const DeviceCM* rec = fCurrLayer; 352f68c5e2f9f05b3af2bae0979ace2684b6041b6e3reed@google.com if (rec && rec->fDevice) { 3538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = rec->fMatrix; 355045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com fRC = &rec->fClip; 3568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDevice = rec->fDevice; 35741e010cb901c0da9066c4df562030808c9ccd7f8reed if (!fDevice->accessPixels(&fDst)) { 35896fcdcc219d2a0d3579719b84b28bede76efba64halcanary fDst.reset(fDevice->imageInfo(), nullptr, 0); 35941e010cb901c0da9066c4df562030808c9ccd7f8reed } 3608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint = rec->fPaint; 361f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com SkDEBUGCODE(this->validate();) 3628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = rec->fNext; 36496fcdcc219d2a0d3579719b84b28bede76efba64halcanary // fCurrLayer may be nullptr now 365199f108f14a5f60a9c2205ffa79b26102a206ad0reed@android.com 3668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 3678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 3698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3704b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 3711f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* getDevice() const { return fDevice; } 3721e7f5e708e5daeb0c18ae49001c9e3cd5e3b13cbreed const SkRasterClip& getClip() const { return *fRC; } 3736f8f292aa768869a9e85c314b124875f57504f2creed@google.com int getX() const { return fDevice->getOrigin().x(); } 3746f8f292aa768869a9e85c314b124875f57504f2creed@google.com int getY() const { return fDevice->getOrigin().y(); } 3758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& getMatrix() const { return *fMatrix; } 3768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* getPaint() const { return fPaint; } 3776f8f292aa768869a9e85c314b124875f57504f2creed@google.com 3788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 3798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const DeviceCM* fCurrLayer; 3808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* fPaint; // May be null. 38102f9ed74ead11fcb01a24faa7d93f853e869f1abreed SkClipStack* fMultiDeviceCS; 3828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef SkDraw INHERITED; 3848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////// 3878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 388dbc3cefb0b624808ddb86d444e6103f216e12fa5reedstatic SkPaint* set_if_needed(SkLazyPaint* lazy, const SkPaint& orig) { 389dbc3cefb0b624808ddb86d444e6103f216e12fa5reed return lazy->isValid() ? lazy->get() : lazy->set(orig); 390dbc3cefb0b624808ddb86d444e6103f216e12fa5reed} 391dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 392dbc3cefb0b624808ddb86d444e6103f216e12fa5reed/** 393dbc3cefb0b624808ddb86d444e6103f216e12fa5reed * If the paint has an imagefilter, but it can be simplified to just a colorfilter, return that 39496fcdcc219d2a0d3579719b84b28bede76efba64halcanary * colorfilter, else return nullptr. 395dbc3cefb0b624808ddb86d444e6103f216e12fa5reed */ 396d053ce9c54d4e5937a142278359e5a4cde18095ereedstatic sk_sp<SkColorFilter> image_to_color_filter(const SkPaint& paint) { 397dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkImageFilter* imgf = paint.getImageFilter(); 398dbc3cefb0b624808ddb86d444e6103f216e12fa5reed if (!imgf) { 39996fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 400dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 401dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 402d053ce9c54d4e5937a142278359e5a4cde18095ereed SkColorFilter* imgCFPtr; 403d053ce9c54d4e5937a142278359e5a4cde18095ereed if (!imgf->asAColorFilter(&imgCFPtr)) { 40496fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 405dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 406d053ce9c54d4e5937a142278359e5a4cde18095ereed sk_sp<SkColorFilter> imgCF(imgCFPtr); 407dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 408dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkColorFilter* paintCF = paint.getColorFilter(); 40996fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paintCF) { 410dbc3cefb0b624808ddb86d444e6103f216e12fa5reed // there is no existing paint colorfilter, so we can just return the imagefilter's 411dbc3cefb0b624808ddb86d444e6103f216e12fa5reed return imgCF; 412dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 413dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 414dbc3cefb0b624808ddb86d444e6103f216e12fa5reed // The paint has both a colorfilter(paintCF) and an imagefilter-which-is-a-colorfilter(imgCF) 415dbc3cefb0b624808ddb86d444e6103f216e12fa5reed // and we need to combine them into a single colorfilter. 416d053ce9c54d4e5937a142278359e5a4cde18095ereed return SkColorFilter::MakeComposeFilter(std::move(imgCF), sk_ref_sp(paintCF)); 417dbc3cefb0b624808ddb86d444e6103f216e12fa5reed} 418dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 41987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco/** 42087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * There are many bounds in skia. A circle's bounds is just its center extended by its radius. 42187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * However, if we stroke a circle, then the "bounds" of that is larger, since it will now draw 42287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * outside of its raw-bounds by 1/2 the stroke width. SkPaint has lots of optional 42387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * effects/attributes that can modify the effective bounds of a given primitive -- maskfilters, 42487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * patheffects, stroking, etc. This function takes a raw bounds and a paint, and returns the 42587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * conservative "effective" bounds based on the settings in the paint... with one exception. This 42687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * function does *not* look at the imagefilter, which can also modify the effective bounds. It is 42787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * deliberately ignored. 42887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco */ 42987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblancostatic const SkRect& apply_paint_to_bounds_sans_imagefilter(const SkPaint& paint, 43087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco const SkRect& rawBounds, 43187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect* storage) { 43287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkPaint tmpUnfiltered(paint); 43387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco tmpUnfiltered.setImageFilter(nullptr); 43487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (tmpUnfiltered.canComputeFastBounds()) { 43587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return tmpUnfiltered.computeFastBounds(rawBounds, storage); 43687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } else { 43787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return rawBounds; 43887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 43987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco} 44087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco 4418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass AutoDrawLooper { 4428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 44387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco // "rawBounds" is the original bounds of the primitive about to be drawn, unmodified by the 44487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco // paint. It's used to determine the size of the offscreen layer for filters. 44587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco // If null, the clip will be used instead. 4463aafe111b6cc388400092851cc53bbbdfcb8a81creed AutoDrawLooper(SkCanvas* canvas, const SkPaint& paint, 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; 4845e25717ab6313b011ec54eac0109c414aa8ffc17Mike Reed tmp.setImageFilter(sk_ref_sp(fPaint->getImageFilter())); 485374772bd61951f01bf84fe17bf53d8867681c9aereed tmp.setBlendMode(fPaint->getBlendMode()); 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 } 5078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 50874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 5094e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com ~AutoDrawLooper() { 5105c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed if (fTempLayerForImageFilter) { 5118926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com fCanvas->internalRestore(); 5128926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 5134e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkASSERT(fCanvas->getSaveCount() == fSaveCount); 5148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 51574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 5164e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com const SkPaint& paint() const { 5174e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkASSERT(fPaint); 5184e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return *fPaint; 5194e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 52074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 521129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool next(SkDrawFilter::Type drawType) { 522129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com if (fDone) { 523129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return false; 524129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else if (fIsSimple) { 525129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fDone = true; 526129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return !fPaint->nothingToDraw(); 527129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else { 528129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return this->doNext(drawType); 529129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 530fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 53174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 5328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 533dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkLazyPaint fLazyPaintInit; // base paint storage in case we need to modify it 534dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkLazyPaint fLazyPaintPerLooper; // per-draw-looper storage, so the looper can modify it 5352c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkCanvas* fCanvas; 5362c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint& fOrigPaint; 5372c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkDrawFilter* fFilter; 5382c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint* fPaint; 5392c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org int fSaveCount; 5405c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed bool fTempLayerForImageFilter; 5412c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org bool fDone; 542129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool fIsSimple; 54379fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkDrawLooper::Context* fLooperContext; 54479fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkSmallAllocator<1, 32> fLooperContextAllocator; 545129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com 546129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool doNext(SkDrawFilter::Type drawType); 5478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 5488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 549129ec22cb054592261e001294c430c9dd4e90ff4reed@google.combool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) { 55096fcdcc219d2a0d3579719b84b28bede76efba64halcanary fPaint = nullptr; 551129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com SkASSERT(!fIsSimple); 5525c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed SkASSERT(fLooperContext || fFilter || fTempLayerForImageFilter); 553632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com 554dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkPaint* paint = fLazyPaintPerLooper.set(fLazyPaintInit.isValid() ? 555dbc3cefb0b624808ddb86d444e6103f216e12fa5reed *fLazyPaintInit.get() : fOrigPaint); 5568926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 5575c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed if (fTempLayerForImageFilter) { 55896fcdcc219d2a0d3579719b84b28bede76efba64halcanary paint->setImageFilter(nullptr); 559374772bd61951f01bf84fe17bf53d8867681c9aereed paint->setBlendMode(SkBlendMode::kSrcOver); 560129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 5618926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 56279fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (fLooperContext && !fLooperContext->next(fCanvas, paint)) { 563129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fDone = true; 564129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return false; 565129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 566129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com if (fFilter) { 567971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com if (!fFilter->filter(paint, drawType)) { 568971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com fDone = true; 569971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com return false; 570971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com } 57196fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == fLooperContext) { 572129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // no looper means we only draw once 573632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com fDone = true; 574632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com } 575129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 576129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fPaint = paint; 5778926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 578129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // if we only came in here for the imagefilter, mark us as done 57979fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (!fLooperContext && !fFilter) { 5804e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fDone = true; 5814e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 5824e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com 583632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com // call this after any possible paint modifiers 584632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com if (fPaint->nothingToDraw()) { 58596fcdcc219d2a0d3579719b84b28bede76efba64halcanary fPaint = nullptr; 5864e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return false; 5874e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 5884e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return true; 5894e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com} 5904e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com 5918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////// macros to place around the internal draw calls ////////////////// 5928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5933aafe111b6cc388400092851cc53bbbdfcb8a81creed#define LOOPER_BEGIN_DRAWBITMAP(paint, skipLayerForFilter, bounds) \ 5943aafe111b6cc388400092851cc53bbbdfcb8a81creed this->predrawNotify(); \ 5953aafe111b6cc388400092851cc53bbbdfcb8a81creed AutoDrawLooper looper(this, paint, skipLayerForFilter, bounds); \ 5963aafe111b6cc388400092851cc53bbbdfcb8a81creed while (looper.next(SkDrawFilter::kBitmap_Type)) { \ 597262a71b7f95ce98ff3dd8dba845afbd724470903reed SkDrawIter iter(this); 598262a71b7f95ce98ff3dd8dba845afbd724470903reed 599262a71b7f95ce98ff3dd8dba845afbd724470903reed 6008926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com#define LOOPER_BEGIN_DRAWDEVICE(paint, type) \ 60197af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com this->predrawNotify(); \ 6023aafe111b6cc388400092851cc53bbbdfcb8a81creed AutoDrawLooper looper(this, paint, true); \ 6038926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com while (looper.next(type)) { \ 6048926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkDrawIter iter(this); 6058926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 60678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org#define LOOPER_BEGIN(paint, type, bounds) \ 60797af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com this->predrawNotify(); \ 6083aafe111b6cc388400092851cc53bbbdfcb8a81creed AutoDrawLooper looper(this, paint, false, bounds); \ 6094e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com while (looper.next(type)) { \ 6108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDrawIter iter(this); 6114b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 612c83a29759a5c2966da5ab973e4fd90763e4c962breed#define LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, type, bounds, auxOpaque) \ 613c83a29759a5c2966da5ab973e4fd90763e4c962breed this->predrawNotify(bounds, &paint, auxOpaque); \ 6143aafe111b6cc388400092851cc53bbbdfcb8a81creed AutoDrawLooper looper(this, paint, false, bounds); \ 615c83a29759a5c2966da5ab973e4fd90763e4c962breed while (looper.next(type)) { \ 616c83a29759a5c2966da5ab973e4fd90763e4c962breed SkDrawIter iter(this); 617c83a29759a5c2966da5ab973e4fd90763e4c962breed 6184e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com#define LOOPER_END } 6198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////// 6218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 622fbfa25802709139c2f14e304319c9541da65ca27msarettstatic inline SkRect qr_clip_bounds(const SkIRect& bounds) { 623fbfa25802709139c2f14e304319c9541da65ca27msarett if (bounds.isEmpty()) { 624fbfa25802709139c2f14e304319c9541da65ca27msarett return SkRect::MakeEmpty(); 625fbfa25802709139c2f14e304319c9541da65ca27msarett } 626fbfa25802709139c2f14e304319c9541da65ca27msarett 627fbfa25802709139c2f14e304319c9541da65ca27msarett // Expand bounds out by 1 in case we are anti-aliasing. We store the 628fbfa25802709139c2f14e304319c9541da65ca27msarett // bounds as floats to enable a faster quick reject implementation. 629fbfa25802709139c2f14e304319c9541da65ca27msarett SkRect dst; 630fbfa25802709139c2f14e304319c9541da65ca27msarett SkNx_cast<float>(Sk4i::Load(&bounds.fLeft) + Sk4i(-1,-1,1,1)).store(&dst.fLeft); 631fbfa25802709139c2f14e304319c9541da65ca27msarett return dst; 632fbfa25802709139c2f14e304319c9541da65ca27msarett} 633fbfa25802709139c2f14e304319c9541da65ca27msarett 634feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtkleinvoid SkCanvas::resetForNextPicture(const SkIRect& bounds) { 635feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein this->restoreToCount(1); 636feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fClipStack->reset(); 637feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fMCRec->reset(bounds); 638feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 639feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein // We're peering through a lot of structs here. Only at this scope do we 640feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein // know that the device is an SkBitmapDevice (really an SkNoPixelsBitmapDevice). 641feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein static_cast<SkBitmapDevice*>(fMCRec->fLayer->fDevice)->setNewSize(bounds.size()); 642fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(bounds); 6439637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett fIsScaleTranslate = true; 644feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein} 645feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 646d954498c01ccf0417feacf89e45d0c62a06a813breedSkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) { 64742b73eb00367c8315974b1c374308d20efa78897reed if (device && device->forceConservativeRasterClip()) { 64842b73eb00367c8315974b1c374308d20efa78897reed flags = InitFlags(flags | kConservativeRasterClip_InitFlag); 64942b73eb00367c8315974b1c374308d20efa78897reed } 65042b73eb00367c8315974b1c374308d20efa78897reed // Since init() is only called once by our constructors, it is safe to perform this 65142b73eb00367c8315974b1c374308d20efa78897reed // const-cast. 65242b73eb00367c8315974b1c374308d20efa78897reed *const_cast<bool*>(&fConservativeRasterClip) = SkToBool(flags & kConservativeRasterClip_InitFlag); 65342b73eb00367c8315974b1c374308d20efa78897reed 65445a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com fAllowSimplifyClip = false; 655f92c86642a1875da54d54b447f006cb9dfbbb35creed fDeviceCMDirty = true; 6562ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount = 1; 65796fcdcc219d2a0d3579719b84b28bede76efba64halcanary fMetaData = nullptr; 65895302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack#ifdef SK_EXPERIMENTAL_SHADOWING 65995302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack fLights = nullptr; 66095302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack#endif 6618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 662385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary fClipStack.reset(new SkClipStack); 663687fa1c745febb57f42b0d5f03d7c1f4be2530careed 6648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = (MCRec*)fMCStack.push_back(); 665d954498c01ccf0417feacf89e45d0c62a06a813breed new (fMCRec) MCRec(fConservativeRasterClip); 6669637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett fIsScaleTranslate = true; 6678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 668a499f905e9340e4935447f2562fd92e8853382b1reed SkASSERT(sizeof(DeviceCM) <= sizeof(fDeviceCMStorage)); 669a499f905e9340e4935447f2562fd92e8853382b1reed fMCRec->fLayer = (DeviceCM*)fDeviceCMStorage; 6707503d60847c4ad22df87458aecd917772b23d293reed new (fDeviceCMStorage) DeviceCM(nullptr, nullptr, nullptr, fConservativeRasterClip, 6718c30a8196dd5903d2d23b4d0a5dc888e802bf698reed fMCRec->fMatrix); 672b679ca8926a832274b14fdb512f88f64b61d32eareed 6738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fTopLayer = fMCRec->fLayer; 6748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 67596fcdcc219d2a0d3579719b84b28bede76efba64halcanary fSurfaceBase = nullptr; 676f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 677f92c86642a1875da54d54b447f006cb9dfbbb35creed if (device) { 678efbffedd68636e94d4379e84a2585bce80f6fb8frobertphillips // The root device and the canvas should always have the same pixel geometry 679efbffedd68636e94d4379e84a2585bce80f6fb8frobertphillips SkASSERT(fProps.pixelGeometry() == device->surfaceProps().pixelGeometry()); 680f92c86642a1875da54d54b447f006cb9dfbbb35creed fMCRec->fLayer->fDevice = SkRef(device); 68178e276889795454891cbba48ab11927968114953reed fMCRec->fRasterClip.setRect(device->getGlobalBounds()); 682fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(device->getGlobalBounds()); 683f92c86642a1875da54d54b447f006cb9dfbbb35creed } 684fbfa25802709139c2f14e304319c9541da65ca27msarett 685f92c86642a1875da54d54b447f006cb9dfbbb35creed return device; 6868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 688cde92111d50a96b6d0f3e166fbac7c9bc6eca349reed@google.comSkCanvas::SkCanvas() 689e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 6904a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 69142b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 692e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org{ 6938d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org inc_canvas(); 694ba124485687130183643994f1b4b68d629fbbebaskia.committer@gmail.com 69596fcdcc219d2a0d3579719b84b28bede76efba64halcanary this->init(nullptr, kDefault_InitFlags); 6968d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org} 6978d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org 698d954498c01ccf0417feacf89e45d0c62a06a813breedstatic SkBitmap make_nopixels(int width, int height) { 699d954498c01ccf0417feacf89e45d0c62a06a813breed SkBitmap bitmap; 700d954498c01ccf0417feacf89e45d0c62a06a813breed bitmap.setInfo(SkImageInfo::MakeUnknown(width, height)); 701d954498c01ccf0417feacf89e45d0c62a06a813breed return bitmap; 702d954498c01ccf0417feacf89e45d0c62a06a813breed} 703d954498c01ccf0417feacf89e45d0c62a06a813breed 704d954498c01ccf0417feacf89e45d0c62a06a813breedclass SkNoPixelsBitmapDevice : public SkBitmapDevice { 705d954498c01ccf0417feacf89e45d0c62a06a813breedpublic: 706fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips SkNoPixelsBitmapDevice(const SkIRect& bounds, const SkSurfaceProps& surfaceProps) 707fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips : INHERITED(make_nopixels(bounds.width(), bounds.height()), surfaceProps) 70878e276889795454891cbba48ab11927968114953reed { 70978e276889795454891cbba48ab11927968114953reed this->setOrigin(bounds.x(), bounds.y()); 71078e276889795454891cbba48ab11927968114953reed } 711d954498c01ccf0417feacf89e45d0c62a06a813breed 712d954498c01ccf0417feacf89e45d0c62a06a813breedprivate: 713b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 714d954498c01ccf0417feacf89e45d0c62a06a813breed typedef SkBitmapDevice INHERITED; 715d954498c01ccf0417feacf89e45d0c62a06a813breed}; 716d954498c01ccf0417feacf89e45d0c62a06a813breed 71796a857ef5a40b3d0751ec9ebaaa96d9f20b82b21reedSkCanvas::SkCanvas(int width, int height, const SkSurfaceProps* props) 718e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 71996a857ef5a40b3d0751ec9ebaaa96d9f20b82b21reed , fProps(SkSurfacePropsCopyOrDefault(props)) 72042b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 721e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org{ 722e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org inc_canvas(); 723b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 724385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary this->init(new SkNoPixelsBitmapDevice(SkIRect::MakeWH(width, height), fProps), 725385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary kDefault_InitFlags)->unref(); 726d954498c01ccf0417feacf89e45d0c62a06a813breed} 727e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org 72878e276889795454891cbba48ab11927968114953reedSkCanvas::SkCanvas(const SkIRect& bounds, InitFlags flags) 729d954498c01ccf0417feacf89e45d0c62a06a813breed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7304a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 73142b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 732d954498c01ccf0417feacf89e45d0c62a06a813breed{ 733d954498c01ccf0417feacf89e45d0c62a06a813breed inc_canvas(); 734b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 735385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary this->init(new SkNoPixelsBitmapDevice(bounds, fProps), flags)->unref(); 73627a5e656c3d6ef22f9cb34de18e1b960da3aa241reed} 7378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 738d954498c01ccf0417feacf89e45d0c62a06a813breedSkCanvas::SkCanvas(SkBaseDevice* device) 739d954498c01ccf0417feacf89e45d0c62a06a813breed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7407b05ff11ebc51f3f3abd1c1756337a04f563537erobertphillips , fProps(device->surfaceProps()) 74142b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 742d954498c01ccf0417feacf89e45d0c62a06a813breed{ 743d954498c01ccf0417feacf89e45d0c62a06a813breed inc_canvas(); 744b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 745d954498c01ccf0417feacf89e45d0c62a06a813breed this->init(device, kDefault_InitFlags); 7468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 748fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillipsSkCanvas::SkCanvas(SkBaseDevice* device, InitFlags flags) 749fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7507b05ff11ebc51f3f3abd1c1756337a04f563537erobertphillips , fProps(device->surfaceProps()) 75142b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 752fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips{ 753fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips inc_canvas(); 754fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips 755fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips this->init(device, flags); 756fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips} 757fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips 7584a8126e7f81384526629b1e21bf89b632ea13cd9reedSkCanvas::SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props) 7593716fd067a5621bb94a6cb08d72afec8bf3acedareed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7604a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(props) 76142b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 7623716fd067a5621bb94a6cb08d72afec8bf3acedareed{ 7633716fd067a5621bb94a6cb08d72afec8bf3acedareed inc_canvas(); 764b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 765704cd32e4a92d6c3eae6bfae4adcc20126bf4437Hal Canary sk_sp<SkBaseDevice> device(new SkBitmapDevice(bitmap, fProps)); 766704cd32e4a92d6c3eae6bfae4adcc20126bf4437Hal Canary this->init(device.get(), kDefault_InitFlags); 7674a8126e7f81384526629b1e21bf89b632ea13cd9reed} 76829c857d0f3a1cb837f73406eeb6ba9771879b5e7reed 7694a8126e7f81384526629b1e21bf89b632ea13cd9reedSkCanvas::SkCanvas(const SkBitmap& bitmap) 7704a8126e7f81384526629b1e21bf89b632ea13cd9reed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7714a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 77242b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 7734a8126e7f81384526629b1e21bf89b632ea13cd9reed{ 7744a8126e7f81384526629b1e21bf89b632ea13cd9reed inc_canvas(); 775b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 776704cd32e4a92d6c3eae6bfae4adcc20126bf4437Hal Canary sk_sp<SkBaseDevice> device(new SkBitmapDevice(bitmap, fProps)); 777704cd32e4a92d6c3eae6bfae4adcc20126bf4437Hal Canary this->init(device.get(), kDefault_InitFlags); 7788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::~SkCanvas() { 7818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // free up the contents of our deque 7828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->restoreToCount(1); // restore everything but the last 7837c2029367cea5479fa3b74fb0ca2b0297b42b709reed@google.com 7848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->internalRestore(); // restore the last, since we're going away 7858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 786385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete fMetaData; 787b70ae310bbdaa1b26786773aabce5548c1f48563vandebo@chromium.org 7888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dec_canvas(); 7898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 79153d9f1cfbd5ddbf57c2f22b9e613ce48e5b2896cfmalita#ifdef SK_SUPPORT_LEGACY_DRAWFILTER 7928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDrawFilter* SkCanvas::getDrawFilter() const { 7938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fMCRec->fFilter; 7948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDrawFilter* SkCanvas::setDrawFilter(SkDrawFilter* filter) { 79751985e3f5e608d369e52832b7ce489d85d402422reed this->checkForDeferredSave(); 7988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fMCRec->fFilter, filter); 7998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return filter; 8008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8017765000709dc64eb23be7df47d1f995d1f787115fmalita#endif 8028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 80374bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.orgSkMetaData& SkCanvas::getMetaData() { 80474bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org // metadata users are rare, so we lazily allocate it. If that changes we 80574bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org // can decide to just make it a field in the device (rather than a ptr) 80696fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == fMetaData) { 80774bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org fMetaData = new SkMetaData; 80874bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org } 80974bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org return *fMetaData; 81074bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org} 81174bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org 8128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 8138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 814bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.orgvoid SkCanvas::flush() { 815ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed this->onFlush(); 816ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed} 817ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed 818ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reedvoid SkCanvas::onFlush() { 8191f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* device = this->getDevice(); 820bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org if (device) { 821bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org device->flush(); 822bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org } 823bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org} 824bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org 825afc7cce5d68663934128d76963cd501f771d71desenorblancoSkISize SkCanvas::getBaseLayerSize() const { 826afc7cce5d68663934128d76963cd501f771d71desenorblanco SkBaseDevice* d = this->getDevice(); 8274ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com return d ? SkISize::Make(d->width(), d->height()) : SkISize::Make(0, 0); 8284ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com} 8294ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com 830afc7cce5d68663934128d76963cd501f771d71desenorblancoSkIRect SkCanvas::getTopLayerBounds() const { 8314ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com SkBaseDevice* d = this->getTopDevice(); 832afc7cce5d68663934128d76963cd501f771d71desenorblanco if (!d) { 833afc7cce5d68663934128d76963cd501f771d71desenorblanco return SkIRect::MakeEmpty(); 834afc7cce5d68663934128d76963cd501f771d71desenorblanco } 835afc7cce5d68663934128d76963cd501f771d71desenorblanco return SkIRect::MakeXYWH(d->getOrigin().x(), d->getOrigin().y(), d->width(), d->height()); 836210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com} 837210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com 8381f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::getDevice() const { 8398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // return root device 840c029062a0312fb747fb6c2677983aba51795c580robertphillips@google.com MCRec* rec = (MCRec*) fMCStack.front(); 8418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(rec && rec->fLayer); 8428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return rec->fLayer->fDevice; 8438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8451f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::getTopDevice(bool updateMatrixClip) const { 8460b53d59a24f667350b4282f88470713902409030reed@google.com if (updateMatrixClip) { 8470b53d59a24f667350b4282f88470713902409030reed@google.com const_cast<SkCanvas*>(this)->updateDeviceCMCache(); 8480b53d59a24f667350b4282f88470713902409030reed@google.com } 8499266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com return fMCRec->fTopLayer->fDevice; 8509266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com} 8519266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com 852a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.orgbool SkCanvas::readPixels(SkBitmap* bitmap, int x, int y) { 853c7ec7c9cabf5c8ad08beb617b99831ece25dacddreed if (kUnknown_SkColorType == bitmap->colorType()) { 854a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 855a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 856a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 857a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bool weAllocated = false; 85896fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == bitmap->pixelRef()) { 859848250415eddc54075f7eb8795e8db79e749c6abreed if (!bitmap->tryAllocPixels()) { 860a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 861a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 862a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org weAllocated = true; 863a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 864a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 865cf01e31df6bbda270dca2ee3b4967caf51e465dcreed SkAutoPixmapUnlock unlocker; 866cf01e31df6bbda270dca2ee3b4967caf51e465dcreed if (bitmap->requestLock(&unlocker)) { 867cf01e31df6bbda270dca2ee3b4967caf51e465dcreed const SkPixmap& pm = unlocker.pixmap(); 868cf01e31df6bbda270dca2ee3b4967caf51e465dcreed if (this->readPixels(pm.info(), pm.writable_addr(), pm.rowBytes(), x, y)) { 869cf01e31df6bbda270dca2ee3b4967caf51e465dcreed return true; 870cf01e31df6bbda270dca2ee3b4967caf51e465dcreed } 871a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 872a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 873a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (weAllocated) { 87496fcdcc219d2a0d3579719b84b28bede76efba64halcanary bitmap->setPixelRef(nullptr); 875a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 876a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 877a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org} 87851df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 879c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.combool SkCanvas::readPixels(const SkIRect& srcRect, SkBitmap* bitmap) { 880a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkIRect r = srcRect; 881a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 882a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!r.intersect(0, 0, size.width(), size.height())) { 883a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bitmap->reset(); 884ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com return false; 885ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com } 88674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 887848250415eddc54075f7eb8795e8db79e749c6abreed if (!bitmap->tryAllocN32Pixels(r.width(), r.height())) { 888a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org // bitmap will already be reset. 889a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 890a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 891a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!this->readPixels(bitmap->info(), bitmap->getPixels(), bitmap->rowBytes(), r.x(), r.y())) { 892a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bitmap->reset(); 893daba14b7d4fc96b915c45d82713b22729c0d0f37bsalomon@google.com return false; 894c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } 895a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return true; 896a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org} 897c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 89896472deea70169396b8e1f576e470138f55fdb1freedbool SkCanvas::readPixels(const SkImageInfo& dstInfo, void* dstP, size_t rowBytes, int x, int y) { 899a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkBaseDevice* device = this->getDevice(); 900a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!device) { 901a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 902a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 903a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 904f0f14113431ace669f278fdd97b50950f2cf4c80mtklein 90596472deea70169396b8e1f576e470138f55fdb1freed SkReadPixelsRec rec(dstInfo, dstP, rowBytes, x, y); 90696472deea70169396b8e1f576e470138f55fdb1freed if (!rec.trim(size.width(), size.height())) { 907a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 908a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 909db0c8753775774aa3f67114491e26ac1be32f38eskia.committer@gmail.com 910a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org // The device can assert that the requested area is always contained in its bounds 91196472deea70169396b8e1f576e470138f55fdb1freed return device->readPixels(rec.fInfo, rec.fPixels, rec.fRowBytes, rec.fX, rec.fY); 91251df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com} 91351df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 9144cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgbool SkCanvas::writePixels(const SkBitmap& bitmap, int x, int y) { 915cf01e31df6bbda270dca2ee3b4967caf51e465dcreed SkAutoPixmapUnlock unlocker; 916cf01e31df6bbda270dca2ee3b4967caf51e465dcreed if (bitmap.requestLock(&unlocker)) { 917cf01e31df6bbda270dca2ee3b4967caf51e465dcreed const SkPixmap& pm = unlocker.pixmap(); 918cf01e31df6bbda270dca2ee3b4967caf51e465dcreed return this->writePixels(pm.info(), pm.addr(), pm.rowBytes(), x, y); 9194cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 9204cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 9214cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org} 9224cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 9234cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgbool SkCanvas::writePixels(const SkImageInfo& origInfo, const void* pixels, size_t rowBytes, 9244cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org int x, int y) { 9254cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org switch (origInfo.colorType()) { 9264cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org case kUnknown_SkColorType: 9274cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org case kIndex_8_SkColorType: 9284cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 9294cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org default: 9304cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org break; 9314cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 93296fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == pixels || rowBytes < origInfo.minRowBytes()) { 9334cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 9344cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 9354cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 9364cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 9374cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org SkIRect target = SkIRect::MakeXYWH(x, y, origInfo.width(), origInfo.height()); 9384cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (!target.intersect(0, 0, size.width(), size.height())) { 9394cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 9404cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 9414cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 9424cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org SkBaseDevice* device = this->getDevice(); 9434cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (!device) { 9444cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 9454cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 9464cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 9474cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // the intersect may have shrunk info's logical size 948e5ea500d4714a7d84de2bf913e81be3b65d2de68reed const SkImageInfo info = origInfo.makeWH(target.width(), target.height()); 9494cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 9504cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // if x or y are negative, then we have to adjust pixels 9514cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (x > 0) { 9524cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org x = 0; 9534cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 9544cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (y > 0) { 9554cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org y = 0; 9564cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 9574cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // here x,y are either 0 or negative 9584cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org pixels = ((const char*)pixels - y * rowBytes - x * info.bytesPerPixel()); 9594cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 9604af35f348b2e2f6c428819118eb7a2f2fff53a74reed // Tell our owning surface to bump its generation ID 961c83a29759a5c2966da5ab973e4fd90763e4c962breed const bool completeOverwrite = info.dimensions() == size; 962c83a29759a5c2966da5ab973e4fd90763e4c962breed this->predrawNotify(completeOverwrite); 9634af35f348b2e2f6c428819118eb7a2f2fff53a74reed 9644cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // The device can assert that the requested area is always contained in its bounds 9654ef54f8d72420a521d4aae04ff5cd438810eca7fcommit-bot@chromium.org return device->writePixels(info, pixels, rowBytes, target.x(), target.y()); 9664cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org} 96751df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 9688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 9698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::updateDeviceCMCache() { 9718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fDeviceCMDirty) { 9728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& totalMatrix = this->getTotalMatrix(); 9731f836ee096bb988adef4b9757b2629c7afeda36dreed const SkRasterClip& totalClip = fMCRec->fRasterClip; 9748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* layer = fMCRec->fTopLayer; 9754b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 97696fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == layer->fNext) { // only one layer 977de6c531e468197bb7746f1217a8ccb2ab175e0b8reed layer->updateMC(totalMatrix, totalClip, nullptr); 9788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 979045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com SkRasterClip clip(totalClip); 9808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 981de6c531e468197bb7746f1217a8ccb2ab175e0b8reed layer->updateMC(totalMatrix, clip, &clip); 98296fcdcc219d2a0d3579719b84b28bede76efba64halcanary } while ((layer = layer->fNext) != nullptr); 9838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = false; 9858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 9898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9902ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::checkForDeferredSave() { 9912ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (fMCRec->fDeferredSaveCount > 0) { 9922ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->doSave(); 9932ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 9942ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed} 9952ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed 996f0090cb80ab10a49e511aa5450ae38917fa058d9reedint SkCanvas::getSaveCount() const { 9972ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed#ifdef SK_DEBUG 9982ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed int count = 0; 9992ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkDeque::Iter iter(fMCStack, SkDeque::Iter::kFront_IterStart); 10002ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed for (;;) { 10012ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed const MCRec* rec = (const MCRec*)iter.next(); 10022ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (!rec) { 10032ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed break; 10042ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 10052ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed count += 1 + rec->fDeferredSaveCount; 10062ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 10072ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(count == fSaveCount); 10082ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed#endif 10092ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return fSaveCount; 1010f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 1011f0090cb80ab10a49e511aa5450ae38917fa058d9reed 1012f0090cb80ab10a49e511aa5450ae38917fa058d9reedint SkCanvas::save() { 10132ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount += 1; 10142ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fMCRec->fDeferredSaveCount += 1; 10152ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return this->getSaveCount() - 1; // return our prev value 10162ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed} 10172ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed 10182ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::doSave() { 1019f0090cb80ab10a49e511aa5450ae38917fa058d9reed this->willSave(); 1020a62d32d1e3112c7e5a26c27e5e967d124ef8dd81fmalita 1021a62d32d1e3112c7e5a26c27e5e967d124ef8dd81fmalita SkASSERT(fMCRec->fDeferredSaveCount > 0); 1022a62d32d1e3112c7e5a26c27e5e967d124ef8dd81fmalita fMCRec->fDeferredSaveCount -= 1; 10232ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalSave(); 1024f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 1025f0090cb80ab10a49e511aa5450ae38917fa058d9reed 1026f0090cb80ab10a49e511aa5450ae38917fa058d9reedvoid SkCanvas::restore() { 10272ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (fMCRec->fDeferredSaveCount > 0) { 10282ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(fSaveCount > 1); 10292ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount -= 1; 10302ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fMCRec->fDeferredSaveCount -= 1; 10312ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } else { 10322ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed // check for underflow 10332ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (fMCStack.count() > 1) { 10342ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->willRestore(); 10352ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(fSaveCount > 1); 1036a644116c3375b12c642d1b51ee1e5cf4a22c1f5breed fSaveCount -= 1; 10372ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalRestore(); 10382ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->didRestore(); 10392ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 1040f0090cb80ab10a49e511aa5450ae38917fa058d9reed } 1041f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 1042f0090cb80ab10a49e511aa5450ae38917fa058d9reed 1043f0090cb80ab10a49e511aa5450ae38917fa058d9reedvoid SkCanvas::restoreToCount(int count) { 1044f0090cb80ab10a49e511aa5450ae38917fa058d9reed // sanity check 1045f0090cb80ab10a49e511aa5450ae38917fa058d9reed if (count < 1) { 1046f0090cb80ab10a49e511aa5450ae38917fa058d9reed count = 1; 1047f0090cb80ab10a49e511aa5450ae38917fa058d9reed } 1048f0f14113431ace669f278fdd97b50950f2cf4c80mtklein 1049f0090cb80ab10a49e511aa5450ae38917fa058d9reed int n = this->getSaveCount() - count; 1050f0090cb80ab10a49e511aa5450ae38917fa058d9reed for (int i = 0; i < n; ++i) { 1051f0090cb80ab10a49e511aa5450ae38917fa058d9reed this->restore(); 1052f0090cb80ab10a49e511aa5450ae38917fa058d9reed } 1053f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 1054f0090cb80ab10a49e511aa5450ae38917fa058d9reed 10552ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::internalSave() { 10568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com MCRec* newTop = (MCRec*)fMCStack.push_back(); 1057d954498c01ccf0417feacf89e45d0c62a06a813breed new (newTop) MCRec(*fMCRec); // balanced in restore() 10588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = newTop; 10594b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 1060687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->save(); 10618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10634960eeec4a1f2a772654883d7f3615d47bcd5dc3reedbool SkCanvas::BoundsAffectsClip(SaveLayerFlags saveLayerFlags) { 10644960eeec4a1f2a772654883d7f3615d47bcd5dc3reed return !(saveLayerFlags & SkCanvas::kDontClipToLayer_PrivateSaveLayerFlag); 10658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10674960eeec4a1f2a772654883d7f3615d47bcd5dc3reedbool SkCanvas::clipRectBounds(const SkRect* bounds, SaveLayerFlags saveLayerFlags, 10689b3aa54bc9605257c701cf465813f5fb1d7ba39ereed SkIRect* intersection, const SkImageFilter* imageFilter) { 1069bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect clipBounds; 1070bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (!this->getClipDeviceBounds(&clipBounds)) { 1071a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return false; 1072f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 1073c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org 107496e657d0e103b8358a77ecd913f6086929f792b8reed const SkMatrix& ctm = fMCRec->fMatrix; // this->getTotalMatrix() 107596e657d0e103b8358a77ecd913f6086929f792b8reed 1076c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org if (imageFilter) { 1077e5e79840ef38ab1d3f03abcf1b2df66fb9940018senorblanco clipBounds = imageFilter->filterBounds(clipBounds, ctm); 1078db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco if (bounds && !imageFilter->canComputeFastBounds()) { 1079db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco bounds = nullptr; 1080db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco } 1081c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org } 1082bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect ir; 108349f085dddff10473b6ebf832a974288300224e60bsalomon if (bounds) { 10848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 10854b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 108696e657d0e103b8358a77ecd913f6086929f792b8reed ctm.mapRect(&r, *bounds); 10878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.roundOut(&ir); 10888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // early exit if the layer's bounds are clipped out 10898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!ir.intersect(clipBounds)) { 10904960eeec4a1f2a772654883d7f3615d47bcd5dc3reed if (BoundsAffectsClip(saveLayerFlags)) { 10911f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fRasterClip.setEmpty(); 1092fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds.setEmpty(); 1093bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1094a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return false; 10958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { // no user bounds, so just use the clip 10978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ir = clipBounds; 10988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1099180aec43451dd951fdaae81a92efc710ba093260reed SkASSERT(!ir.isEmpty()); 11008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11014960eeec4a1f2a772654883d7f3615d47bcd5dc3reed if (BoundsAffectsClip(saveLayerFlags)) { 1102180aec43451dd951fdaae81a92efc710ba093260reed // Simplify the current clips since they will be applied properly during restore() 110373603f3c52ffd89fe9d035be827b566a0e7d3b79reed fClipStack->clipDevRect(ir, kReplace_Op); 1104180aec43451dd951fdaae81a92efc710ba093260reed fMCRec->fRasterClip.setRect(ir); 1105fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(ir); 1106a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org } 1107a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 1108a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org if (intersection) { 1109a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org *intersection = ir; 1110a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org } 1111a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return true; 1112a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org} 1113a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 11144960eeec4a1f2a772654883d7f3615d47bcd5dc3reed 11154960eeec4a1f2a772654883d7f3615d47bcd5dc3reedint SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint) { 11164960eeec4a1f2a772654883d7f3615d47bcd5dc3reed return this->saveLayer(SaveLayerRec(bounds, paint, 0)); 1117d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org} 1118d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org 11194960eeec4a1f2a772654883d7f3615d47bcd5dc3reedint SkCanvas::saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPaint* paint) { 11204960eeec4a1f2a772654883d7f3615d47bcd5dc3reed return this->saveLayer(SaveLayerRec(bounds, paint, kPreserveLCDText_SaveLayerFlag)); 11214960eeec4a1f2a772654883d7f3615d47bcd5dc3reed} 11224960eeec4a1f2a772654883d7f3615d47bcd5dc3reed 11234960eeec4a1f2a772654883d7f3615d47bcd5dc3reedint SkCanvas::saveLayer(const SaveLayerRec& origRec) { 11244960eeec4a1f2a772654883d7f3615d47bcd5dc3reed SaveLayerRec rec(origRec); 1125d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed if (gIgnoreSaveLayerBounds) { 11264960eeec4a1f2a772654883d7f3615d47bcd5dc3reed rec.fBounds = nullptr; 1127d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed } 11284960eeec4a1f2a772654883d7f3615d47bcd5dc3reed SaveLayerStrategy strategy = this->getSaveLayerStrategy(rec); 1129a644116c3375b12c642d1b51ee1e5cf4a22c1f5breed fSaveCount += 1; 11304960eeec4a1f2a772654883d7f3615d47bcd5dc3reed this->internalSaveLayer(rec, strategy); 11312ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return this->getSaveCount() - 1; 11328926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com} 11338926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 1134a2217ef965e57fdbbf989989e7ec1f2c04f62d39reedvoid SkCanvas::DrawDeviceWithFilter(SkBaseDevice* src, const SkImageFilter* filter, 1135a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkBaseDevice* dst, const SkMatrix& ctm, 1136a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed const SkClipStack* clipStack) { 1137a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkDraw draw; 1138a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkRasterClip rc; 1139a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed rc.setRect(SkIRect::MakeWH(dst->width(), dst->height())); 1140a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (!dst->accessPixels(&draw.fDst)) { 1141a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed draw.fDst.reset(dst->imageInfo(), nullptr, 0); 1142a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed } 1143a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed draw.fMatrix = &SkMatrix::I(); 1144a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed draw.fRC = &rc; 1145a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed draw.fClipStack = clipStack; 1146a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed draw.fDevice = dst; 11477354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips 11487354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips SkPaint p; 1149372177ee115d46dfb5bfb881a408e6c37ae83678robertphillips p.setImageFilter(filter->makeWithLocalMatrix(ctm)); 1150a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed 1151a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed int x = src->getOrigin().x() - dst->getOrigin().x(); 1152a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed int y = src->getOrigin().y() - dst->getOrigin().y(); 1153a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed auto special = src->snapSpecial(); 1154a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (special) { 1155a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed dst->drawSpecial(draw, special.get(), x, y, p); 1156a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed } 11577354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips} 115870ee31b2fa127eee6c0cea61cf05508e9d3ca7b1reed 1159129ed1cd6d792f3f6cf563aefa9756fc6308289dreedstatic SkImageInfo make_layer_info(const SkImageInfo& prev, int w, int h, bool isOpaque, 1160129ed1cd6d792f3f6cf563aefa9756fc6308289dreed const SkPaint* paint) { 1161129ed1cd6d792f3f6cf563aefa9756fc6308289dreed // need to force L32 for now if we have an image filter. Once filters support other colortypes 1162129ed1cd6d792f3f6cf563aefa9756fc6308289dreed // e.g. sRGB or F16, we can remove this check 116352ede1d905728cdcaa98db1e4a33724f5a85c62dbrianosman // SRGBTODO: Can we remove this check now? 1164129ed1cd6d792f3f6cf563aefa9756fc6308289dreed const bool hasImageFilter = paint && paint->getImageFilter(); 1165129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 1166129ed1cd6d792f3f6cf563aefa9756fc6308289dreed SkAlphaType alphaType = isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType; 1167129ed1cd6d792f3f6cf563aefa9756fc6308289dreed if ((prev.bytesPerPixel() < 4) || hasImageFilter) { 1168129ed1cd6d792f3f6cf563aefa9756fc6308289dreed // force to L32 1169129ed1cd6d792f3f6cf563aefa9756fc6308289dreed return SkImageInfo::MakeN32(w, h, alphaType); 1170129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } else { 1171129ed1cd6d792f3f6cf563aefa9756fc6308289dreed // keep the same characteristics as the prev 117252ede1d905728cdcaa98db1e4a33724f5a85c62dbrianosman return SkImageInfo::Make(w, h, prev.colorType(), alphaType, sk_ref_sp(prev.colorSpace())); 1173129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 1174129ed1cd6d792f3f6cf563aefa9756fc6308289dreed} 1175129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 11764960eeec4a1f2a772654883d7f3615d47bcd5dc3reedvoid SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy strategy) { 11774960eeec4a1f2a772654883d7f3615d47bcd5dc3reed const SkRect* bounds = rec.fBounds; 11784960eeec4a1f2a772654883d7f3615d47bcd5dc3reed const SkPaint* paint = rec.fPaint; 11794960eeec4a1f2a772654883d7f3615d47bcd5dc3reed SaveLayerFlags saveLayerFlags = rec.fSaveLayerFlags; 11804960eeec4a1f2a772654883d7f3615d47bcd5dc3reed 11818c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkLazyPaint lazyP; 11828c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkImageFilter* imageFilter = paint ? paint->getImageFilter() : NULL; 11838c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkMatrix stashedMatrix = fMCRec->fMatrix; 11848c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkMatrix remainder; 11858c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkSize scale; 11868c30a8196dd5903d2d23b4d0a5dc888e802bf698reed /* 11878c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * ImageFilters (so far) do not correctly handle matrices (CTM) that contain rotation/skew/etc. 11888c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * but they do handle scaling. To accommodate this, we do the following: 11898c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 11908c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 1. Stash off the current CTM 11918c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 2. Decompose the CTM into SCALE and REMAINDER 11928c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 3. Wack the CTM to be just SCALE, and wrap the imagefilter with a MatrixImageFilter that 11938c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * contains the REMAINDER 11948c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 4. Proceed as usual, allowing the client to draw into the layer (now with a scale-only CTM) 11958c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 5. During restore, we process the MatrixImageFilter, which applies REMAINDER to the output 11968c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * of the original imagefilter, and draw that (via drawSprite) 11978c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 6. Unwack the CTM to its original state (i.e. stashedMatrix) 11988c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 11998c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * Perhaps in the future we could augment #5 to apply REMAINDER as part of the draw (no longer 12008c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * a sprite operation) to avoid the extra buffer/overhead of MatrixImageFilter. 12018c30a8196dd5903d2d23b4d0a5dc888e802bf698reed */ 120296a04f329926099f0002f97883242793ff04f61creed if (imageFilter && !stashedMatrix.isScaleTranslate() && !imageFilter->canHandleComplexCTM() && 12038c30a8196dd5903d2d23b4d0a5dc888e802bf698reed stashedMatrix.decomposeScale(&scale, &remainder)) 12048c30a8196dd5903d2d23b4d0a5dc888e802bf698reed { 12058c30a8196dd5903d2d23b4d0a5dc888e802bf698reed // We will restore the matrix (which we are overwriting here) in restore via fStashedMatrix 12068c30a8196dd5903d2d23b4d0a5dc888e802bf698reed this->internalSetMatrix(SkMatrix::MakeScale(scale.width(), scale.height())); 12078c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkPaint* p = lazyP.set(*paint); 12088c30a8196dd5903d2d23b4d0a5dc888e802bf698reed p->setImageFilter(SkImageFilter::MakeMatrixFilter(remainder, 12098c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkFilterQuality::kLow_SkFilterQuality, 12108c30a8196dd5903d2d23b4d0a5dc888e802bf698reed sk_ref_sp(imageFilter))); 12118c30a8196dd5903d2d23b4d0a5dc888e802bf698reed imageFilter = p->getImageFilter(); 12128c30a8196dd5903d2d23b4d0a5dc888e802bf698reed paint = p; 12138c30a8196dd5903d2d23b4d0a5dc888e802bf698reed } 12148c30a8196dd5903d2d23b4d0a5dc888e802bf698reed 1215a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org // do this before we create the layer. We don't call the public save() since 1216a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org // that would invoke a possibly overridden virtual 12172ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalSave(); 1218a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 1219a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org fDeviceCMDirty = true; 1220a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 1221a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org SkIRect ir; 12228c30a8196dd5903d2d23b4d0a5dc888e802bf698reed if (!this->clipRectBounds(bounds, saveLayerFlags, &ir, imageFilter)) { 12232ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 12248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1226e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy really care about 1227e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org // the clipRectBounds() call above? 1228e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org if (kNoLayer_SaveLayerStrategy == strategy) { 12292ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 1230e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org } 1231e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org 12324960eeec4a1f2a772654883d7f3615d47bcd5dc3reed bool isOpaque = SkToBool(saveLayerFlags & kIsOpaque_SaveLayerFlag); 12338dc0ccb8d33d1af7dd13228509e61fe915bc7705reed SkPixelGeometry geo = fProps.pixelGeometry(); 12348dc0ccb8d33d1af7dd13228509e61fe915bc7705reed if (paint) { 123576033be81b82c44fd5d4fdf2672eb22e505da1f0reed // TODO: perhaps add a query to filters so we might preserve opaqueness... 1236daa57bfd4204f5a7d304c580bcf5ad99d0121e1freed if (paint->getImageFilter() || paint->getColorFilter()) { 123776033be81b82c44fd5d4fdf2672eb22e505da1f0reed isOpaque = false; 12388dc0ccb8d33d1af7dd13228509e61fe915bc7705reed geo = kUnknown_SkPixelGeometry; 1239b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com } 1240b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com } 12418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12425139e501c5ac3a511e35c78395c907a176113451robertphillips SkBaseDevice* priorDevice = this->getTopDevice(); 1243a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (nullptr == priorDevice) { 1244b2db898573e3cdcc8234eebf51961bfc4977ebbcreed SkDebugf("Unable to find device for layer."); 12452ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 1246b2db898573e3cdcc8234eebf51961bfc4977ebbcreed } 1247b2db898573e3cdcc8234eebf51961bfc4977ebbcreed 12485139e501c5ac3a511e35c78395c907a176113451robertphillips SkImageInfo info = make_layer_info(priorDevice->imageInfo(), ir.width(), ir.height(), isOpaque, 1249129ed1cd6d792f3f6cf563aefa9756fc6308289dreed paint); 1250129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 1251704cd32e4a92d6c3eae6bfae4adcc20126bf4437Hal Canary sk_sp<SkBaseDevice> newDevice; 125261f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed { 125370ee31b2fa127eee6c0cea61cf05508e9d3ca7b1reed const bool preserveLCDText = kOpaque_SkAlphaType == info.alphaType() || 12544960eeec4a1f2a772654883d7f3615d47bcd5dc3reed (saveLayerFlags & kPreserveLCDText_SaveLayerFlag); 1255daa57bfd4204f5a7d304c580bcf5ad99d0121e1freed const SkBaseDevice::TileUsage usage = SkBaseDevice::kNever_TileUsage; 125670ee31b2fa127eee6c0cea61cf05508e9d3ca7b1reed const SkBaseDevice::CreateInfo createInfo = SkBaseDevice::CreateInfo(info, usage, geo, 1257cd4051e1c4770edc03b27663c6c96ec8987122bdreed preserveLCDText); 12585139e501c5ac3a511e35c78395c907a176113451robertphillips newDevice.reset(priorDevice->onCreateDevice(createInfo, paint)); 12595139e501c5ac3a511e35c78395c907a176113451robertphillips if (!newDevice) { 12607503d60847c4ad22df87458aecd917772b23d293reed return; 126161f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed } 1262e25c68402b38ac01dc1ae196ae8a5265b773c5f2bungeman@google.com } 12635139e501c5ac3a511e35c78395c907a176113451robertphillips newDevice->setOrigin(ir.fLeft, ir.fTop); 12647354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips 1265704cd32e4a92d6c3eae6bfae4adcc20126bf4437Hal Canary DeviceCM* layer = 1266704cd32e4a92d6c3eae6bfae4adcc20126bf4437Hal Canary new DeviceCM(newDevice.get(), paint, this, fConservativeRasterClip, stashedMatrix); 12678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com layer->fNext = fMCRec->fTopLayer; 12698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fLayer = layer; 12708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fTopLayer = layer; // this field is NOT an owner of layer 1271a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed 1272a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (rec.fBackdrop) { 1273704cd32e4a92d6c3eae6bfae4adcc20126bf4437Hal Canary DrawDeviceWithFilter(priorDevice, rec.fBackdrop, newDevice.get(), 1274a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed fMCRec->fMatrix, this->getClipStack()); 1275a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed } 12768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1278d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.orgint SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) { 1279bada1885da479d948f065182d6dfa85a1140bda5reed if (0xFF == alpha) { 1280bada1885da479d948f065182d6dfa85a1140bda5reed return this->saveLayer(bounds, nullptr); 1281bada1885da479d948f065182d6dfa85a1140bda5reed } else { 1282bada1885da479d948f065182d6dfa85a1140bda5reed SkPaint tmpPaint; 1283bada1885da479d948f065182d6dfa85a1140bda5reed tmpPaint.setAlpha(alpha); 1284bada1885da479d948f065182d6dfa85a1140bda5reed return this->saveLayer(bounds, &tmpPaint); 1285bada1885da479d948f065182d6dfa85a1140bda5reed } 1286d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org} 1287d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org 12888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::internalRestore() { 12898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fMCStack.count() != 0); 12908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 12928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1293687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->restore(); 12946c157640c27ee2ed6f9a484d21691b7b19dfecdecommit-bot@chromium.org 129588edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com // reserve our layer (if any) 12968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* layer = fMCRec->fLayer; // may be null 12978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now detach it from fMCRec so we can pop(). Gets freed after its drawn 129896fcdcc219d2a0d3579719b84b28bede76efba64halcanary fMCRec->fLayer = nullptr; 12998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now do the normal restore() 13018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->~MCRec(); // balanced in save() 13028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCStack.pop_back(); 13038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = (MCRec*)fMCStack.back(); 13048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* Time to draw the layer's offscreen. We can't call the public drawSprite, 13068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com since if we're being recorded, we don't want to record this (the 13078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com recorder will have already recorded the restore). 13088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 130949f085dddff10473b6ebf832a974288300224e60bsalomon if (layer) { 13108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (layer->fNext) { 13116f8f292aa768869a9e85c314b124875f57504f2creed@google.com const SkIPoint& origin = layer->fDevice->getOrigin(); 13127503d60847c4ad22df87458aecd917772b23d293reed this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(), layer->fPaint); 13138c30a8196dd5903d2d23b4d0a5dc888e802bf698reed // restore what we smashed in internalSaveLayer 13148c30a8196dd5903d2d23b4d0a5dc888e802bf698reed fMCRec->fMatrix = layer->fStashedMatrix; 13158926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com // reset this, since internalDrawDevice will have set it to true 13168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1317385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete layer; 1318b679ca8926a832274b14fdb512f88f64b61d32eareed } else { 1319b679ca8926a832274b14fdb512f88f64b61d32eareed // we're at the root 1320a499f905e9340e4935447f2562fd92e8853382b1reed SkASSERT(layer == (void*)fDeviceCMStorage); 1321b679ca8926a832274b14fdb512f88f64b61d32eareed layer->~DeviceCM(); 13228c30a8196dd5903d2d23b4d0a5dc888e802bf698reed // no need to update fMCRec, 'cause we're killing the canvas 13238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 132488edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 1325fbfa25802709139c2f14e304319c9541da65ca27msarett 1326fbfa25802709139c2f14e304319c9541da65ca27msarett if (fMCRec) { 13279637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett fIsScaleTranslate = fMCRec->fMatrix.isScaleTranslate(); 1328fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 1329fbfa25802709139c2f14e304319c9541da65ca27msarett } 13308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1332e8f3062a36d3682f4019309a32b5b84dc9eddf8creedsk_sp<SkSurface> SkCanvas::makeSurface(const SkImageInfo& info, const SkSurfaceProps* props) { 133396fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == props) { 13344a8126e7f81384526629b1e21bf89b632ea13cd9reed props = &fProps; 13354a8126e7f81384526629b1e21bf89b632ea13cd9reed } 13364a8126e7f81384526629b1e21bf89b632ea13cd9reed return this->onNewSurface(info, *props); 133776f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com} 133876f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com 1339e8f3062a36d3682f4019309a32b5b84dc9eddf8creedsk_sp<SkSurface> SkCanvas::onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props) { 134076f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com SkBaseDevice* dev = this->getDevice(); 1341e8f3062a36d3682f4019309a32b5b84dc9eddf8creed return dev ? dev->makeSurface(info, props) : nullptr; 134276f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com} 134376f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com 1344c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgSkImageInfo SkCanvas::imageInfo() const { 1345ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed return this->onImageInfo(); 1346ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed} 1347ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed 1348ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reedSkImageInfo SkCanvas::onImageInfo() const { 1349c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkBaseDevice* dev = this->getDevice(); 1350c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (dev) { 1351c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return dev->imageInfo(); 1352c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } else { 1353900ecf2f1579d42c9d2959831787af0346320f86reed@google.com return SkImageInfo::MakeUnknown(0, 0); 1354c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1355c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1356c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1357898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosmanbool SkCanvas::getProps(SkSurfaceProps* props) const { 1358ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed return this->onGetProps(props); 1359ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed} 1360ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed 1361ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reedbool SkCanvas::onGetProps(SkSurfaceProps* props) const { 1362898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman SkBaseDevice* dev = this->getDevice(); 1363898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman if (dev) { 1364898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman if (props) { 1365898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman *props = fProps; 1366898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman } 1367898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman return true; 1368898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman } else { 1369898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman return false; 1370898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman } 1371898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman} 1372898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman 13736ceeebd37a43d879c120b6ba100ae1febdd67a18reedbool SkCanvas::peekPixels(SkPixmap* pmap) { 13746ceeebd37a43d879c120b6ba100ae1febdd67a18reed return this->onPeekPixels(pmap); 1375c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1376c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1377884e97cb04db7ed053a866567ee9c6e4c01f993areedbool SkCanvas::onPeekPixels(SkPixmap* pmap) { 1378c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkBaseDevice* dev = this->getDevice(); 1379884e97cb04db7ed053a866567ee9c6e4c01f993areed return dev && dev->peekPixels(pmap); 1380c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1381c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 13826b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.orgvoid* SkCanvas::accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin) { 1383884e97cb04db7ed053a866567ee9c6e4c01f993areed SkPixmap pmap; 1384884e97cb04db7ed053a866567ee9c6e4c01f993areed if (!this->onAccessTopLayerPixels(&pmap)) { 138596fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 1386884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1387884e97cb04db7ed053a866567ee9c6e4c01f993areed if (info) { 1388884e97cb04db7ed053a866567ee9c6e4c01f993areed *info = pmap.info(); 1389884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1390884e97cb04db7ed053a866567ee9c6e4c01f993areed if (rowBytes) { 1391884e97cb04db7ed053a866567ee9c6e4c01f993areed *rowBytes = pmap.rowBytes(); 1392884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1393884e97cb04db7ed053a866567ee9c6e4c01f993areed if (origin) { 13946b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org *origin = this->getTopDevice(false)->getOrigin(); 13956b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org } 1396884e97cb04db7ed053a866567ee9c6e4c01f993areed return pmap.writable_addr(); 13979c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 13989c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1399884e97cb04db7ed053a866567ee9c6e4c01f993areedbool SkCanvas::onAccessTopLayerPixels(SkPixmap* pmap) { 14009c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com SkBaseDevice* dev = this->getTopDevice(); 1401884e97cb04db7ed053a866567ee9c6e4c01f993areed return dev && dev->accessPixels(pmap); 14029c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 14039c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1404520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org///////////////////////////////////////////////////////////////////////////// 14058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14067503d60847c4ad22df87458aecd917772b23d293reedvoid SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, const SkPaint* paint) { 14078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint tmp; 140896fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 14098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint = &tmp; 14108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 14114b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 14128926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com LOOPER_BEGIN_DRAWDEVICE(*paint, SkDrawFilter::kBitmap_Type) 1413a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed 14148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 14151f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* dstDev = iter.fDevice; 141676dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com paint = &looper.paint(); 141776dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkImageFilter* filter = paint->getImageFilter(); 141876dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkIPoint pos = { x - iter.getX(), y - iter.getY() }; 141943513543de102500121afb9222dfdd8f35c50ca7Hal Canary sk_sp<SkSpecialImage> specialImage; 142043513543de102500121afb9222dfdd8f35c50ca7Hal Canary if (filter && (specialImage = srcDev->snapSpecial())) { 142143513543de102500121afb9222dfdd8f35c50ca7Hal Canary dstDev->drawSpecial(iter, specialImage.get(), pos.x(), pos.y(), *paint); 142276dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } else { 1423b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com dstDev->drawDevice(iter, srcDev, pos.x(), pos.y(), *paint); 142476dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } 14258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1426a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed 14274e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 14288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 143032704674f64cb6a14356dfebe060cd3484c06cc7reed///////////////////////////////////////////////////////////////////////////// 1431da420b976e61071cfe5de10556b4b23e519091d6reed 143292362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::translate(SkScalar dx, SkScalar dy) { 1433fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed if (dx || dy) { 1434fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed this->checkForDeferredSave(); 1435fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed fDeviceCMDirty = true; 1436fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed fMCRec->fMatrix.preTranslate(dx,dy); 1437cbdf007bc2eb85056a1a5c75c088202becba2d16mtklein 1438fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed // Translate shouldn't affect the is-scale-translateness of the matrix. 1439fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed SkASSERT(fIsScaleTranslate == fMCRec->fMatrix.isScaleTranslate()); 1440cbdf007bc2eb85056a1a5c75c088202becba2d16mtklein 1441fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed this->didTranslate(dx,dy); 1442fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed } 14438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 144592362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::scale(SkScalar sx, SkScalar sy) { 1446d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1447d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setScale(sx, sy); 1448d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 14498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 145192362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::rotate(SkScalar degrees) { 1452d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1453d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setRotate(degrees); 1454d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 14558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14577438bfc0804d021aa92cdd5ea644994a4248f3dbbungemanvoid SkCanvas::rotate(SkScalar degrees, SkScalar px, SkScalar py) { 14587438bfc0804d021aa92cdd5ea644994a4248f3dbbungeman SkMatrix m; 14597438bfc0804d021aa92cdd5ea644994a4248f3dbbungeman m.setRotate(degrees, px, py); 14607438bfc0804d021aa92cdd5ea644994a4248f3dbbungeman this->concat(m); 14617438bfc0804d021aa92cdd5ea644994a4248f3dbbungeman} 14627438bfc0804d021aa92cdd5ea644994a4248f3dbbungeman 146392362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::skew(SkScalar sx, SkScalar sy) { 1464d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1465d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setSkew(sx, sy); 1466d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 146744c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org} 146844c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 146992362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::concat(const SkMatrix& matrix) { 1470d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org if (matrix.isIdentity()) { 1471d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org return; 1472d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org } 1473d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org 14742ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 14758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 14761f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix.preConcat(matrix); 14779637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett fIsScaleTranslate = fMCRec->fMatrix.isScaleTranslate(); 147844c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org this->didConcat(matrix); 147944c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org} 148044c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 14818c30a8196dd5903d2d23b4d0a5dc888e802bf698reedvoid SkCanvas::internalSetMatrix(const SkMatrix& matrix) { 14828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 14831f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix = matrix; 14849da5a5a198e5dc9148f7f30a6089377590eee55bmsarett fIsScaleTranslate = matrix.isScaleTranslate(); 14858c30a8196dd5903d2d23b4d0a5dc888e802bf698reed} 14868c30a8196dd5903d2d23b4d0a5dc888e802bf698reed 14878c30a8196dd5903d2d23b4d0a5dc888e802bf698reedvoid SkCanvas::setMatrix(const SkMatrix& matrix) { 14888c30a8196dd5903d2d23b4d0a5dc888e802bf698reed this->checkForDeferredSave(); 14898c30a8196dd5903d2d23b4d0a5dc888e802bf698reed this->internalSetMatrix(matrix); 149044c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org this->didSetMatrix(matrix); 14918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::resetMatrix() { 14948c30a8196dd5903d2d23b4d0a5dc888e802bf698reed this->setMatrix(SkMatrix::I()); 14958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 149795302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack#ifdef SK_EXPERIMENTAL_SHADOWING 1498e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblackvoid SkCanvas::translateZ(SkScalar z) { 1499e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack this->checkForDeferredSave(); 1500e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack this->fMCRec->fCurDrawDepth += z; 1501e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack this->didTranslateZ(z); 1502e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack} 1503e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack 1504e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblackSkScalar SkCanvas::getZ() const { 1505e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack return this->fMCRec->fCurDrawDepth; 1506e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack} 1507e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack 150895302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblackvoid SkCanvas::setLights(sk_sp<SkLights> lights) { 150995302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack this->fLights = lights; 151095302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack} 151195302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack 151295302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblacksk_sp<SkLights> SkCanvas::getLights() const { 151395302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack return this->fLights; 151495302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack} 151595302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack#endif 151695302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack 15178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 15188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 151973603f3c52ffd89fe9d035be827b566a0e7d3b79reedvoid SkCanvas::clipRect(const SkRect& rect, ClipOp op, bool doAA) { 15202ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 15218f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 15228f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(rect, op, edgeStyle); 15238f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 15248f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 152573603f3c52ffd89fe9d035be827b566a0e7d3b79reedvoid SkCanvas::onClipRect(const SkRect& rect, ClipOp op, ClipEdgeStyle edgeStyle) { 1526a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon const bool isAA = kSoft_ClipEdgeStyle == edgeStyle; 1527c64eff55049b1192052b791549a32a03be1c43e3reed AutoValidateClip avc(this); 1528a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon fClipStack->clipRect(rect, fMCRec->fMatrix, op, isAA); 1529a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon fMCRec->fRasterClip.op(rect, fMCRec->fMatrix, this->getTopLayerBounds(), (SkRegion::Op)op, 1530a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon isAA); 1531c64eff55049b1192052b791549a32a03be1c43e3reed fDeviceCMDirty = true; 1532fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 15338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 15348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 153573603f3c52ffd89fe9d035be827b566a0e7d3b79reedvoid SkCanvas::clipRRect(const SkRRect& rrect, ClipOp op, bool doAA) { 15362ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 15378f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 15384ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (rrect.isRect()) { 15398f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(rrect.getBounds(), op, edgeStyle); 15408f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } else { 15418f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRRect(rrect, op, edgeStyle); 15424ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 15438f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 154414e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 154573603f3c52ffd89fe9d035be827b566a0e7d3b79reedvoid SkCanvas::onClipRRect(const SkRRect& rrect, ClipOp op, ClipEdgeStyle edgeStyle) { 1546a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon AutoValidateClip avc(this); 154714e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 1548a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon fDeviceCMDirty = true; 154914e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 1550a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon bool isAA = kSoft_ClipEdgeStyle == edgeStyle; 1551a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon fClipStack->clipRRect(rrect, fMCRec->fMatrix, op, isAA); 1552a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon fMCRec->fRasterClip.op(rrect, fMCRec->fMatrix, this->getTopLayerBounds(), (SkRegion::Op)op, 1553a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon isAA); 1554a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 1555a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon return; 15564ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 15574ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 155873603f3c52ffd89fe9d035be827b566a0e7d3b79reedvoid SkCanvas::clipPath(const SkPath& path, ClipOp op, bool doAA) { 15592ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 15608f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 156139f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips 156239f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips if (!path.isInverseFillType() && fMCRec->fMatrix.rectStaysRect()) { 156339f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips SkRect r; 156439f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips if (path.isRect(&r)) { 156539f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips this->onClipRect(r, op, edgeStyle); 156639f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips return; 156739f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips } 156839f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips SkRRect rrect; 156939f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips if (path.isOval(&r)) { 157039f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips rrect.setOval(r); 157139f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips this->onClipRRect(rrect, op, edgeStyle); 157239f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips return; 157339f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips } 157439f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips if (path.isRRect(&rrect)) { 157539f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips this->onClipRRect(rrect, op, edgeStyle); 157639f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips return; 157739f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips } 15788f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 157939f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips 158039f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips this->onClipPath(path, op, edgeStyle); 15818f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 15828f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 158373603f3c52ffd89fe9d035be827b566a0e7d3b79reedvoid SkCanvas::onClipPath(const SkPath& path, ClipOp op, ClipEdgeStyle edgeStyle) { 15845c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com AutoValidateClip avc(this); 15855c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 15868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1587a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon bool isAA = kSoft_ClipEdgeStyle == edgeStyle; 15888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1589a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon fClipStack->clipPath(path, fMCRec->fMatrix, op, isAA); 15905c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 1591a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon const SkPath* rasterClipPath = &path; 1592a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon const SkMatrix* matrix = &fMCRec->fMatrix; 1593a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon SkPath tempPath; 159445a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com if (fAllowSimplifyClip) { 1595a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon isAA = getClipStack()->asPath(&tempPath); 1596a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon rasterClipPath = &tempPath; 1597a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon matrix = &SkMatrix::I(); 159873603f3c52ffd89fe9d035be827b566a0e7d3b79reed op = kReplace_Op; 159945a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com } 1600a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon fMCRec->fRasterClip.op(*rasterClipPath, *matrix, this->getTopLayerBounds(), (SkRegion::Op)op, 1601a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon isAA); 1602fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 16038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 160573603f3c52ffd89fe9d035be827b566a0e7d3b79reedvoid SkCanvas::clipRegion(const SkRegion& rgn, ClipOp op) { 16062ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 16078f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRegion(rgn, op); 16088f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 16098f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 161073603f3c52ffd89fe9d035be827b566a0e7d3b79reedvoid SkCanvas::onClipRegion(const SkRegion& rgn, ClipOp op) { 16115c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com AutoValidateClip avc(this); 16125c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 16138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 16148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16155c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // todo: signal fClipStack that we have a region, and therefore (I guess) 16165c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // we have to ignore it, and use the region directly? 1617687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipDevRect(rgn.getBounds(), op); 16185c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 161973603f3c52ffd89fe9d035be827b566a0e7d3b79reed fMCRec->fRasterClip.op(rgn, (SkRegion::Op)op); 1620fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 16218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1623819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com#ifdef SK_DEBUG 1624819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.comvoid SkCanvas::validateClip() const { 1625819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com // construct clipRgn from the clipstack 16261f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com const SkBaseDevice* device = this->getDevice(); 1627ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com if (!device) { 16285c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org SkASSERT(this->isClipEmpty()); 1629ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com return; 1630ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com } 1631ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com 1632819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com SkIRect ir; 1633819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com ir.set(0, 0, device->width(), device->height()); 1634d954498c01ccf0417feacf89e45d0c62a06a813breed SkRasterClip tmpClip(ir, fConservativeRasterClip); 1635819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 1636687fa1c745febb57f42b0d5f03d7c1f4be2530careed SkClipStack::B2TIter iter(*fClipStack); 16378182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const SkClipStack::Element* element; 163896fcdcc219d2a0d3579719b84b28bede76efba64halcanary while ((element = iter.next()) != nullptr) { 16398182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com switch (element->getType()) { 16408182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kRect_Type: 16418182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com element->getRect().round(&ir); 164273603f3c52ffd89fe9d035be827b566a0e7d3b79reed tmpClip.op(ir, (SkRegion::Op)element->getOp()); 16438182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 16448182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kEmpty_Type: 16458182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com tmpClip.setEmpty(); 16468182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 16479cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org default: { 16489cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org SkPath path; 16499cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org element->asPath(&path); 1650a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon tmpClip.op(path, SkMatrix::I(), this->getTopLayerBounds(), 1651a3b45d4f7db953472df4f11ab1595964b65175f9Brian Salomon (SkRegion::Op)element->getOp(), element->isAA()); 16529cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org break; 16539cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org } 1654819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com } 1655819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com } 1656819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com} 1657819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com#endif 1658819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 165990c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.comvoid SkCanvas::replayClips(ClipVisitor* visitor) const { 1660687fa1c745febb57f42b0d5f03d7c1f4be2530careed SkClipStack::B2TIter iter(*fClipStack); 16618182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const SkClipStack::Element* element; 16628182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com 166396fcdcc219d2a0d3579719b84b28bede76efba64halcanary while ((element = iter.next()) != nullptr) { 1664c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita element->replay(visitor); 166590c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com } 166690c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com} 166790c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com 16685c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com/////////////////////////////////////////////////////////////////////////////// 16695c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 1670754de5f65b466f721d952a379194cc94de376f42reed@google.combool SkCanvas::isClipEmpty() const { 16711f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.isEmpty(); 1672754de5f65b466f721d952a379194cc94de376f42reed@google.com} 1673754de5f65b466f721d952a379194cc94de376f42reed@google.com 16745c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.orgbool SkCanvas::isClipRect() const { 16751f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.isRect(); 16765c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org} 16775c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org 1678fbfa25802709139c2f14e304319c9541da65ca27msarettstatic inline bool is_nan_or_clipped(const Sk4f& devRect, const Sk4f& devClip) { 1679fbfa25802709139c2f14e304319c9541da65ca27msarett#if !defined(SKNX_NO_SIMD) && SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2 1680fbfa25802709139c2f14e304319c9541da65ca27msarett __m128 lLtT = _mm_unpacklo_ps(devRect.fVec, devClip.fVec); 1681fbfa25802709139c2f14e304319c9541da65ca27msarett __m128 RrBb = _mm_unpackhi_ps(devClip.fVec, devRect.fVec); 1682fbfa25802709139c2f14e304319c9541da65ca27msarett __m128 mask = _mm_cmplt_ps(lLtT, RrBb); 1683fbfa25802709139c2f14e304319c9541da65ca27msarett return 0xF != _mm_movemask_ps(mask); 1684fbfa25802709139c2f14e304319c9541da65ca27msarett#elif !defined(SKNX_NO_SIMD) && defined(SK_ARM_HAS_NEON) 1685fbfa25802709139c2f14e304319c9541da65ca27msarett float32x4_t lLtT = vzipq_f32(devRect.fVec, devClip.fVec).val[0]; 1686fbfa25802709139c2f14e304319c9541da65ca27msarett float32x4_t RrBb = vzipq_f32(devClip.fVec, devRect.fVec).val[1]; 1687fbfa25802709139c2f14e304319c9541da65ca27msarett uint32x4_t mask = vcltq_f32(lLtT, RrBb); 1688fbfa25802709139c2f14e304319c9541da65ca27msarett return 0xFFFFFFFFFFFFFFFF != (uint64_t) vmovn_u32(mask); 1689fbfa25802709139c2f14e304319c9541da65ca27msarett#else 1690fbfa25802709139c2f14e304319c9541da65ca27msarett SkRect devRectAsRect; 1691fbfa25802709139c2f14e304319c9541da65ca27msarett SkRect devClipAsRect; 1692fbfa25802709139c2f14e304319c9541da65ca27msarett devRect.store(&devRectAsRect.fLeft); 1693fbfa25802709139c2f14e304319c9541da65ca27msarett devClip.store(&devClipAsRect.fLeft); 1694fbfa25802709139c2f14e304319c9541da65ca27msarett return !devRectAsRect.isFinite() || !devRectAsRect.intersect(devClipAsRect); 1695fbfa25802709139c2f14e304319c9541da65ca27msarett#endif 1696fbfa25802709139c2f14e304319c9541da65ca27msarett} 1697fbfa25802709139c2f14e304319c9541da65ca27msarett 1698fbfa25802709139c2f14e304319c9541da65ca27msarett// It's important for this function to not be inlined. Otherwise the compiler will share code 1699fbfa25802709139c2f14e304319c9541da65ca27msarett// between the fast path and the slow path, resulting in two slow paths. 1700fbfa25802709139c2f14e304319c9541da65ca27msarettstatic SK_NEVER_INLINE bool quick_reject_slow_path(const SkRect& src, const SkRect& deviceClip, 1701fbfa25802709139c2f14e304319c9541da65ca27msarett const SkMatrix& matrix) { 1702fbfa25802709139c2f14e304319c9541da65ca27msarett SkRect deviceRect; 1703fbfa25802709139c2f14e304319c9541da65ca27msarett matrix.mapRect(&deviceRect, src); 1704fbfa25802709139c2f14e304319c9541da65ca27msarett return !deviceRect.isFinite() || !deviceRect.intersect(deviceClip); 1705fbfa25802709139c2f14e304319c9541da65ca27msarett} 1706d22a817ff57986407facd16af36320fc86ce02damsarett 1707fbfa25802709139c2f14e304319c9541da65ca27msarettbool SkCanvas::quickReject(const SkRect& src) const { 1708fbfa25802709139c2f14e304319c9541da65ca27msarett#ifdef SK_DEBUG 1709fbfa25802709139c2f14e304319c9541da65ca27msarett // Verify that fDeviceClipBounds are set properly. 1710fbfa25802709139c2f14e304319c9541da65ca27msarett SkRect tmp = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 17111f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fRasterClip.isEmpty()) { 17120c685ee188a5e500df25a34fa6edfceb4cbb795cmsarett SkASSERT(fDeviceClipBounds.isEmpty()); 1713fbfa25802709139c2f14e304319c9541da65ca27msarett } else { 1714fbfa25802709139c2f14e304319c9541da65ca27msarett SkASSERT(tmp == fDeviceClipBounds); 17158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 17168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17179637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett // Verify that fIsScaleTranslate is set properly. 17189637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett SkASSERT(fIsScaleTranslate == fMCRec->fMatrix.isScaleTranslate()); 1719fbfa25802709139c2f14e304319c9541da65ca27msarett#endif 1720d252db03d9650013b545ef9781fe993c07f8f314reed@android.com 17219637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett if (!fIsScaleTranslate) { 1722fbfa25802709139c2f14e304319c9541da65ca27msarett return quick_reject_slow_path(src, fDeviceClipBounds, fMCRec->fMatrix); 17238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1724fbfa25802709139c2f14e304319c9541da65ca27msarett 1725fbfa25802709139c2f14e304319c9541da65ca27msarett // We inline the implementation of mapScaleTranslate() for the fast path. 1726fbfa25802709139c2f14e304319c9541da65ca27msarett float sx = fMCRec->fMatrix.getScaleX(); 1727fbfa25802709139c2f14e304319c9541da65ca27msarett float sy = fMCRec->fMatrix.getScaleY(); 1728fbfa25802709139c2f14e304319c9541da65ca27msarett float tx = fMCRec->fMatrix.getTranslateX(); 1729fbfa25802709139c2f14e304319c9541da65ca27msarett float ty = fMCRec->fMatrix.getTranslateY(); 1730fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f scale(sx, sy, sx, sy); 1731fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f trans(tx, ty, tx, ty); 1732fbfa25802709139c2f14e304319c9541da65ca27msarett 1733fbfa25802709139c2f14e304319c9541da65ca27msarett // Apply matrix. 1734fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f ltrb = Sk4f::Load(&src.fLeft) * scale + trans; 1735fbfa25802709139c2f14e304319c9541da65ca27msarett 1736fbfa25802709139c2f14e304319c9541da65ca27msarett // Make sure left < right, top < bottom. 1737fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f rblt(ltrb[2], ltrb[3], ltrb[0], ltrb[1]); 1738fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f min = Sk4f::Min(ltrb, rblt); 1739fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f max = Sk4f::Max(ltrb, rblt); 1740fbfa25802709139c2f14e304319c9541da65ca27msarett // We can extract either pair [0,1] or [2,3] from min and max and be correct, but on 1741fbfa25802709139c2f14e304319c9541da65ca27msarett // ARM this sequence generates the fastest (a single instruction). 1742fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f devRect = Sk4f(min[2], min[3], max[0], max[1]); 1743fbfa25802709139c2f14e304319c9541da65ca27msarett 1744fbfa25802709139c2f14e304319c9541da65ca27msarett // Check if the device rect is NaN or outside the clip. 1745fbfa25802709139c2f14e304319c9541da65ca27msarett return is_nan_or_clipped(devRect, Sk4f::Load(&fDeviceClipBounds.fLeft)); 17468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17483b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::quickReject(const SkPath& path) const { 17493b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com return path.isEmpty() || this->quickReject(path.getBounds()); 17508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17523b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::getClipBounds(SkRect* bounds) const { 1753bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect ibounds; 17548f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!this->getClipDeviceBounds(&ibounds)) { 17558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 17568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 17578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1758d9c0f0b57affec7a472879c5919acac6637d926areed@android.com SkMatrix inverse; 1759d9c0f0b57affec7a472879c5919acac6637d926areed@android.com // if we can't invert the CTM, we can't return local clip bounds 17601f836ee096bb988adef4b9757b2629c7afeda36dreed if (!fMCRec->fMatrix.invert(&inverse)) { 176172dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com if (bounds) { 176272dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com bounds->setEmpty(); 176372dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com } 1764d9c0f0b57affec7a472879c5919acac6637d926areed@android.com return false; 1765d9c0f0b57affec7a472879c5919acac6637d926areed@android.com } 1766d9c0f0b57affec7a472879c5919acac6637d926areed@android.com 176749f085dddff10473b6ebf832a974288300224e60bsalomon if (bounds) { 1768bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkRect r; 17693b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com // adjust it outwards in case we are antialiasing 17703b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com const int inset = 1; 1771fa4d5bd09f8f1a4a92b5ae0324800dd672760898reed@google.com 17728f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com r.iset(ibounds.fLeft - inset, ibounds.fTop - inset, 17738f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com ibounds.fRight + inset, ibounds.fBottom + inset); 17748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inverse.mapRect(bounds, r); 17758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 17768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 17778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1779bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.combool SkCanvas::getClipDeviceBounds(SkIRect* bounds) const { 17801f836ee096bb988adef4b9757b2629c7afeda36dreed const SkRasterClip& clip = fMCRec->fRasterClip; 1781bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (clip.isEmpty()) { 1782bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (bounds) { 1783bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com bounds->setEmpty(); 1784bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1785bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com return false; 1786bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1787bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com 178849f085dddff10473b6ebf832a974288300224e60bsalomon if (bounds) { 1789bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com *bounds = clip.getBounds(); 1790bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1791bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com return true; 1792bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com} 1793bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com 17948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkMatrix& SkCanvas::getTotalMatrix() const { 17951f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fMatrix; 17968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17985c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.orgconst SkRegion& SkCanvas::internal_private_getTotalClip() const { 17991f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.forceGetBW(); 18005c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org} 18015c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org 18021105224f9701e57ec5ce0354d6a380b664f5c638Brian OsmanGrRenderTargetContext* SkCanvas::internal_private_accessTopLayerRenderTargetContext() { 18039c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com SkBaseDevice* dev = this->getTopDevice(); 18041105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman return dev ? dev->accessRenderTargetContext() : nullptr; 18059c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 18069c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1807644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.orgGrContext* SkCanvas::getGrContext() { 1808644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org SkBaseDevice* device = this->getTopDevice(); 180986ae3d161412961c27a406465b0ec5749cc2e753reed return device ? device->context() : nullptr; 1810644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org} 1811e97f0856a8044866b12527819d14cdfbcdfd96f2bsalomon@google.com 1812ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.orgvoid SkCanvas::drawDRRect(const SkRRect& outer, const SkRRect& inner, 1813ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkPaint& paint) { 18149881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawDRRect()"); 1815ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (outer.isEmpty()) { 1816ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 1817ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 1818ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (inner.isEmpty()) { 1819ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->drawRRect(outer, paint); 1820ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 1821ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 1822ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 1823ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // We don't have this method (yet), but technically this is what we should 1824ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // be able to assert... 1825ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // SkASSERT(outer.contains(inner)); 1826ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // 1827ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // For now at least check for containment of bounds 1828ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org SkASSERT(outer.getBounds().contains(inner.getBounds())); 1829ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 1830ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->onDrawDRRect(outer, inner, paint); 1831ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org} 1832ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 183341af966ab338e95eee81ab618ab28195075338f7reed// These need to stop being virtual -- clients need to override the onDraw... versions 183441af966ab338e95eee81ab618ab28195075338f7reed 183541af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawPaint(const SkPaint& paint) { 183641af966ab338e95eee81ab618ab28195075338f7reed this->onDrawPaint(paint); 183741af966ab338e95eee81ab618ab28195075338f7reed} 183841af966ab338e95eee81ab618ab28195075338f7reed 183941af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawRect(const SkRect& r, const SkPaint& paint) { 184041af966ab338e95eee81ab618ab28195075338f7reed this->onDrawRect(r, paint); 184141af966ab338e95eee81ab618ab28195075338f7reed} 184241af966ab338e95eee81ab618ab28195075338f7reed 1843dca352e2d42cfe698573947b3d11abc1eaade160msarettvoid SkCanvas::drawRegion(const SkRegion& region, const SkPaint& paint) { 1844dca352e2d42cfe698573947b3d11abc1eaade160msarett if (region.isEmpty()) { 1845dca352e2d42cfe698573947b3d11abc1eaade160msarett return; 1846dca352e2d42cfe698573947b3d11abc1eaade160msarett } 1847dca352e2d42cfe698573947b3d11abc1eaade160msarett 1848dca352e2d42cfe698573947b3d11abc1eaade160msarett if (region.isRect()) { 1849dca352e2d42cfe698573947b3d11abc1eaade160msarett return this->drawIRect(region.getBounds(), paint); 1850dca352e2d42cfe698573947b3d11abc1eaade160msarett } 1851dca352e2d42cfe698573947b3d11abc1eaade160msarett 1852dca352e2d42cfe698573947b3d11abc1eaade160msarett this->onDrawRegion(region, paint); 1853dca352e2d42cfe698573947b3d11abc1eaade160msarett} 1854dca352e2d42cfe698573947b3d11abc1eaade160msarett 185541af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawOval(const SkRect& r, const SkPaint& paint) { 185641af966ab338e95eee81ab618ab28195075338f7reed this->onDrawOval(r, paint); 185741af966ab338e95eee81ab618ab28195075338f7reed} 185841af966ab338e95eee81ab618ab28195075338f7reed 185941af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) { 186041af966ab338e95eee81ab618ab28195075338f7reed this->onDrawRRect(rrect, paint); 186141af966ab338e95eee81ab618ab28195075338f7reed} 186241af966ab338e95eee81ab618ab28195075338f7reed 186341af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint) { 186441af966ab338e95eee81ab618ab28195075338f7reed this->onDrawPoints(mode, count, pts, paint); 186541af966ab338e95eee81ab618ab28195075338f7reed} 186641af966ab338e95eee81ab618ab28195075338f7reed 186741af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawVertices(VertexMode vmode, int vertexCount, const SkPoint vertices[], 18687d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed const SkPoint texs[], const SkColor colors[], SkBlendMode bmode, 186941af966ab338e95eee81ab618ab28195075338f7reed const uint16_t indices[], int indexCount, const SkPaint& paint) { 1870faba3715b8ddfaa0ce4df79bc8006e9bc7694e5bMike Reed this->onDrawVertices(vmode, vertexCount, vertices, texs, colors, bmode, 187141af966ab338e95eee81ab618ab28195075338f7reed indices, indexCount, paint); 187241af966ab338e95eee81ab618ab28195075338f7reed} 187341af966ab338e95eee81ab618ab28195075338f7reed 187441af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawPath(const SkPath& path, const SkPaint& paint) { 187541af966ab338e95eee81ab618ab28195075338f7reed this->onDrawPath(path, paint); 187641af966ab338e95eee81ab618ab28195075338f7reed} 187741af966ab338e95eee81ab618ab28195075338f7reed 1878a85d4d0814818e4ddabb9237da209d61d6cd5854reedvoid SkCanvas::drawImage(const SkImage* image, SkScalar x, SkScalar y, const SkPaint* paint) { 1879e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 1880a85d4d0814818e4ddabb9237da209d61d6cd5854reed this->onDrawImage(image, x, y, paint); 188141af966ab338e95eee81ab618ab28195075338f7reed} 188241af966ab338e95eee81ab618ab28195075338f7reed 1883e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst, 1884e47829b6b1eeb6b0c97ccb3df3016d197046824creed const SkPaint* paint, SrcRectConstraint constraint) { 1885e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 1886e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (dst.isEmpty() || src.isEmpty()) { 1887e47829b6b1eeb6b0c97ccb3df3016d197046824creed return; 1888e47829b6b1eeb6b0c97ccb3df3016d197046824creed } 1889e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->onDrawImageRect(image, &src, dst, paint, constraint); 1890e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 189141af966ab338e95eee81ab618ab28195075338f7reed 189284984efeb64787b88c5f8bd6929cfe2d58a3ba06reedvoid SkCanvas::drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst, 189384984efeb64787b88c5f8bd6929cfe2d58a3ba06reed const SkPaint* paint, SrcRectConstraint constraint) { 1894e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 1895e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, SkRect::Make(isrc), dst, paint, constraint); 189684984efeb64787b88c5f8bd6929cfe2d58a3ba06reed} 189784984efeb64787b88c5f8bd6929cfe2d58a3ba06reed 1898e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint, 1899e47829b6b1eeb6b0c97ccb3df3016d197046824creed SrcRectConstraint constraint) { 1900e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 1901e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, SkRect::MakeIWH(image->width(), image->height()), dst, paint, 1902e47829b6b1eeb6b0c97ccb3df3016d197046824creed constraint); 1903e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 1904e47829b6b1eeb6b0c97ccb3df3016d197046824creed 19054c21dc5ddf3b482293ed34eead876d8d61a662c3reedvoid SkCanvas::drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst, 19064c21dc5ddf3b482293ed34eead876d8d61a662c3reed const SkPaint* paint) { 1907e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 19084c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (dst.isEmpty()) { 19094c21dc5ddf3b482293ed34eead876d8d61a662c3reed return; 19104c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 1911552bca9afadd81d263041d04e2605d8d897940b6msarett if (SkLatticeIter::Valid(image->width(), image->height(), center)) { 1912552bca9afadd81d263041d04e2605d8d897940b6msarett this->onDrawImageNine(image, center, dst, paint); 1913552bca9afadd81d263041d04e2605d8d897940b6msarett } else { 1914e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, dst, paint); 19154c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 19164c21dc5ddf3b482293ed34eead876d8d61a662c3reed} 19174c21dc5ddf3b482293ed34eead876d8d61a662c3reed 1918168820625c35a8c19f66c661efcbce7a5e334837msarettvoid SkCanvas::drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst, 1919168820625c35a8c19f66c661efcbce7a5e334837msarett const SkPaint* paint) { 1920168820625c35a8c19f66c661efcbce7a5e334837msarett RETURN_ON_NULL(image); 1921168820625c35a8c19f66c661efcbce7a5e334837msarett if (dst.isEmpty()) { 1922168820625c35a8c19f66c661efcbce7a5e334837msarett return; 1923168820625c35a8c19f66c661efcbce7a5e334837msarett } 192471df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett 192571df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett SkIRect bounds; 192671df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett Lattice latticePlusBounds = lattice; 192771df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett if (!latticePlusBounds.fBounds) { 192871df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett bounds = SkIRect::MakeWH(image->width(), image->height()); 192971df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett latticePlusBounds.fBounds = &bounds; 193071df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett } 193171df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett 193271df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett if (SkLatticeIter::Valid(image->width(), image->height(), latticePlusBounds)) { 193371df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett this->onDrawImageLattice(image, latticePlusBounds, dst, paint); 1934168820625c35a8c19f66c661efcbce7a5e334837msarett } else { 1935168820625c35a8c19f66c661efcbce7a5e334837msarett this->drawImageRect(image, dst, paint); 1936168820625c35a8c19f66c661efcbce7a5e334837msarett } 1937168820625c35a8c19f66c661efcbce7a5e334837msarett} 1938168820625c35a8c19f66c661efcbce7a5e334837msarett 193941af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar dx, SkScalar dy, const SkPaint* paint) { 19404c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (bitmap.drawsNothing()) { 19412df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson return; 19422df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson } 194341af966ab338e95eee81ab618ab28195075338f7reed this->onDrawBitmap(bitmap, dx, dy, paint); 194441af966ab338e95eee81ab618ab28195075338f7reed} 194541af966ab338e95eee81ab618ab28195075338f7reed 1946e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst, 1947a5517e2b190a8083b38964972b031c13e99f1012reed const SkPaint* paint, SrcRectConstraint constraint) { 1948e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (bitmap.drawsNothing() || dst.isEmpty() || src.isEmpty()) { 1949a5517e2b190a8083b38964972b031c13e99f1012reed return; 1950a5517e2b190a8083b38964972b031c13e99f1012reed } 1951e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->onDrawBitmapRect(bitmap, &src, dst, paint, constraint); 195241af966ab338e95eee81ab618ab28195075338f7reed} 195341af966ab338e95eee81ab618ab28195075338f7reed 195484984efeb64787b88c5f8bd6929cfe2d58a3ba06reedvoid SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst, 195584984efeb64787b88c5f8bd6929cfe2d58a3ba06reed const SkPaint* paint, SrcRectConstraint constraint) { 1956e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, SkRect::Make(isrc), dst, paint, constraint); 1957e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 1958e47829b6b1eeb6b0c97ccb3df3016d197046824creed 1959e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint, 1960e47829b6b1eeb6b0c97ccb3df3016d197046824creed SrcRectConstraint constraint) { 1961e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, SkRect::MakeIWH(bitmap.width(), bitmap.height()), dst, paint, 1962e47829b6b1eeb6b0c97ccb3df3016d197046824creed constraint); 196384984efeb64787b88c5f8bd6929cfe2d58a3ba06reed} 196484984efeb64787b88c5f8bd6929cfe2d58a3ba06reed 196541af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst, 196641af966ab338e95eee81ab618ab28195075338f7reed const SkPaint* paint) { 19674c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (bitmap.drawsNothing() || dst.isEmpty()) { 19682df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson return; 19692df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson } 1970552bca9afadd81d263041d04e2605d8d897940b6msarett if (SkLatticeIter::Valid(bitmap.width(), bitmap.height(), center)) { 1971552bca9afadd81d263041d04e2605d8d897940b6msarett this->onDrawBitmapNine(bitmap, center, dst, paint); 1972552bca9afadd81d263041d04e2605d8d897940b6msarett } else { 1973a5517e2b190a8083b38964972b031c13e99f1012reed this->drawBitmapRect(bitmap, dst, paint); 19744c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 197541af966ab338e95eee81ab618ab28195075338f7reed} 197641af966ab338e95eee81ab618ab28195075338f7reed 1977c573a40ed5024b463e47088d307e3164a486dba5msarettvoid SkCanvas::drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, const SkRect& dst, 1978c573a40ed5024b463e47088d307e3164a486dba5msarett const SkPaint* paint) { 1979168820625c35a8c19f66c661efcbce7a5e334837msarett if (bitmap.drawsNothing() || dst.isEmpty()) { 1980c573a40ed5024b463e47088d307e3164a486dba5msarett return; 1981c573a40ed5024b463e47088d307e3164a486dba5msarett } 198271df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett 198371df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett SkIRect bounds; 198471df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett Lattice latticePlusBounds = lattice; 198571df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett if (!latticePlusBounds.fBounds) { 198671df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett bounds = SkIRect::MakeWH(bitmap.width(), bitmap.height()); 198771df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett latticePlusBounds.fBounds = &bounds; 198871df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett } 198971df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett 199071df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett if (SkLatticeIter::Valid(bitmap.width(), bitmap.height(), latticePlusBounds)) { 199171df2d7bc1bbc83ad4cf005f9027df4cb3b88a9bmsarett this->onDrawBitmapLattice(bitmap, latticePlusBounds, dst, paint); 1992552bca9afadd81d263041d04e2605d8d897940b6msarett } else { 1993168820625c35a8c19f66c661efcbce7a5e334837msarett this->drawBitmapRect(bitmap, dst, paint); 1994c573a40ed5024b463e47088d307e3164a486dba5msarett } 1995c573a40ed5024b463e47088d307e3164a486dba5msarett} 1996c573a40ed5024b463e47088d307e3164a486dba5msarett 199771c3c760a83123ee0b3127b8c65c6394ce541c50reedvoid SkCanvas::drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], 19987d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed const SkColor colors[], int count, SkBlendMode mode, 199971c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkRect* cull, const SkPaint* paint) { 2000e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(atlas); 200171c3c760a83123ee0b3127b8c65c6394ce541c50reed if (count <= 0) { 200271c3c760a83123ee0b3127b8c65c6394ce541c50reed return; 200371c3c760a83123ee0b3127b8c65c6394ce541c50reed } 200471c3c760a83123ee0b3127b8c65c6394ce541c50reed SkASSERT(atlas); 200571c3c760a83123ee0b3127b8c65c6394ce541c50reed SkASSERT(tex); 2006faba3715b8ddfaa0ce4df79bc8006e9bc7694e5bMike Reed this->onDrawAtlas(atlas, xform, tex, colors, count, mode, cull, paint); 200771c3c760a83123ee0b3127b8c65c6394ce541c50reed} 200871c3c760a83123ee0b3127b8c65c6394ce541c50reed 2009f70b531daaf47db1ee95c70da9843f1dd1f418d3reedvoid SkCanvas::drawAnnotation(const SkRect& rect, const char key[], SkData* value) { 2010f70b531daaf47db1ee95c70da9843f1dd1f418d3reed if (key) { 2011f70b531daaf47db1ee95c70da9843f1dd1f418d3reed this->onDrawAnnotation(rect, key, value); 2012f70b531daaf47db1ee95c70da9843f1dd1f418d3reed } 2013f70b531daaf47db1ee95c70da9843f1dd1f418d3reed} 2014f70b531daaf47db1ee95c70da9843f1dd1f418d3reed 2015e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::legacy_drawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, 2016e47829b6b1eeb6b0c97ccb3df3016d197046824creed const SkPaint* paint, SrcRectConstraint constraint) { 2017e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (src) { 2018e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, *src, dst, paint, constraint); 2019e47829b6b1eeb6b0c97ccb3df3016d197046824creed } else { 2020e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, SkRect::MakeIWH(image->width(), image->height()), 2021e47829b6b1eeb6b0c97ccb3df3016d197046824creed dst, paint, constraint); 2022e47829b6b1eeb6b0c97ccb3df3016d197046824creed } 2023e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 2024e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::legacy_drawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, 2025e47829b6b1eeb6b0c97ccb3df3016d197046824creed const SkPaint* paint, SrcRectConstraint constraint) { 2026e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (src) { 2027e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, *src, dst, paint, constraint); 2028e47829b6b1eeb6b0c97ccb3df3016d197046824creed } else { 2029e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, SkRect::MakeIWH(bitmap.width(), bitmap.height()), 2030e47829b6b1eeb6b0c97ccb3df3016d197046824creed dst, paint, constraint); 2031e47829b6b1eeb6b0c97ccb3df3016d197046824creed } 2032e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 2033e47829b6b1eeb6b0c97ccb3df3016d197046824creed 2034cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudsonvoid SkCanvas::temporary_internal_describeTopLayer(SkMatrix* matrix, SkIRect* clip_bounds) { 2035cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson SkIRect layer_bounds = this->getTopLayerBounds(); 2036cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson if (matrix) { 2037cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson *matrix = this->getTotalMatrix(); 2038cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson matrix->preTranslate(-layer_bounds.left(), -layer_bounds.top()); 2039cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson } 2040cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson if (clip_bounds) { 2041cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson this->getClipDeviceBounds(clip_bounds); 2042cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson clip_bounds->offset(-layer_bounds.left(), -layer_bounds.top()); 2043cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson } 2044cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson} 2045cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson 20468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 20478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// These are the virtual drawing methods 20488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 20498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 205028361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.orgvoid SkCanvas::onDiscard() { 205149f085dddff10473b6ebf832a974288300224e60bsalomon if (fSurfaceBase) { 205228361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org fSurfaceBase->aboutToDraw(SkSurface::kDiscard_ContentChangeMode); 205328361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org } 205428361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org} 205528361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org 205641af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawPaint(const SkPaint& paint) { 20579881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPaint()"); 2058fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->internalDrawPaint(paint); 2059fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com} 2060fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com 2061fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.comvoid SkCanvas::internalDrawPaint(const SkPaint& paint) { 206296fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, SkDrawFilter::kPaint_Type, nullptr, false) 20638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 20654e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPaint(iter, looper.paint()); 20668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 20678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20684e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 20698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 20708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 207141af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[], 207241af966ab338e95eee81ab618ab28195075338f7reed const SkPaint& paint) { 20739881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT1("disabled-by-default-skia", "SkCanvas::drawPoints()", "count", static_cast<uint64_t>(count)); 20748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if ((long)count <= 0) { 20758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 20768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 20778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 207878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect r, storage; 207996fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 2080a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com if (paint.canComputeFastBounds()) { 2081a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com // special-case 2 points (common for drawing a single line) 2082a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com if (2 == count) { 2083a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com r.set(pts[0], pts[1]); 2084a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } else { 2085a8c7f7702fb4bbedb615031bc653c5cd161a038ecommit-bot@chromium.org r.set(pts, SkToInt(count)); 2086a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } 208787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastStrokeBounds(r, &storage))) { 208887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 208987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 209087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &r; 2091fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 2092a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com 209396fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkASSERT(pts != nullptr); 20948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 209578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPoint_Type, bounds) 20964b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 20978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 20984e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPoints(iter, mode, count, pts, looper.paint()); 20998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 21004b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 21014e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 21028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 21038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21044a16717bc7aa471fad10ec3157774771a76e5106reedstatic bool needs_autodrawlooper(SkCanvas* canvas, const SkPaint& paint) { 21054a16717bc7aa471fad10ec3157774771a76e5106reed return ((intptr_t)paint.getImageFilter() | 21064a16717bc7aa471fad10ec3157774771a76e5106reed#ifdef SK_SUPPORT_LEGACY_DRAWFILTER 21074a16717bc7aa471fad10ec3157774771a76e5106reed (intptr_t)canvas->getDrawFilter() | 21084a16717bc7aa471fad10ec3157774771a76e5106reed#endif 21094a16717bc7aa471fad10ec3157774771a76e5106reed (intptr_t)paint.getLooper() ) != 0; 21104a16717bc7aa471fad10ec3157774771a76e5106reed} 21114a16717bc7aa471fad10ec3157774771a76e5106reed 211241af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawRect(const SkRect& r, const SkPaint& paint) { 21139881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRect()"); 211478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 211596fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 21168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.canComputeFastBounds()) { 21178432808ad8898ac7137bc7ce1d9df6005e866401reed // Skia will draw an inverted rect, because it explicitly "sorts" it downstream. 21188432808ad8898ac7137bc7ce1d9df6005e866401reed // To prevent accidental rejecting at this stage, we have to sort it before we check. 21198432808ad8898ac7137bc7ce1d9df6005e866401reed SkRect tmp(r); 21208432808ad8898ac7137bc7ce1d9df6005e866401reed tmp.sort(); 21218432808ad8898ac7137bc7ce1d9df6005e866401reed 212287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(tmp, &storage))) { 212387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 212487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 212587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &r; 21268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 21274b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 21284a16717bc7aa471fad10ec3157774771a76e5106reed if (needs_autodrawlooper(this, paint)) { 21294a16717bc7aa471fad10ec3157774771a76e5106reed LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, SkDrawFilter::kRect_Type, bounds, false) 21308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21314a16717bc7aa471fad10ec3157774771a76e5106reed while (iter.next()) { 21324a16717bc7aa471fad10ec3157774771a76e5106reed iter.fDevice->drawRect(iter, r, looper.paint()); 21334a16717bc7aa471fad10ec3157774771a76e5106reed } 21348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21354a16717bc7aa471fad10ec3157774771a76e5106reed LOOPER_END 21364a16717bc7aa471fad10ec3157774771a76e5106reed } else { 21374a16717bc7aa471fad10ec3157774771a76e5106reed this->predrawNotify(bounds, &paint, false); 21384a16717bc7aa471fad10ec3157774771a76e5106reed SkDrawIter iter(this); 21394a16717bc7aa471fad10ec3157774771a76e5106reed while (iter.next()) { 21404a16717bc7aa471fad10ec3157774771a76e5106reed iter.fDevice->drawRect(iter, r, paint); 21414a16717bc7aa471fad10ec3157774771a76e5106reed } 21424a16717bc7aa471fad10ec3157774771a76e5106reed } 21438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 21448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 214544df651ebefc284acc2f66425dff3ea0b0e14b36msarettvoid SkCanvas::onDrawRegion(const SkRegion& region, const SkPaint& paint) { 214644df651ebefc284acc2f66425dff3ea0b0e14b36msarett SkRect storage; 214744df651ebefc284acc2f66425dff3ea0b0e14b36msarett SkRect regionRect = SkRect::Make(region.getBounds()); 214844df651ebefc284acc2f66425dff3ea0b0e14b36msarett const SkRect* bounds = nullptr; 214944df651ebefc284acc2f66425dff3ea0b0e14b36msarett if (paint.canComputeFastBounds()) { 215044df651ebefc284acc2f66425dff3ea0b0e14b36msarett if (this->quickReject(paint.computeFastBounds(regionRect, &storage))) { 215144df651ebefc284acc2f66425dff3ea0b0e14b36msarett return; 215244df651ebefc284acc2f66425dff3ea0b0e14b36msarett } 215344df651ebefc284acc2f66425dff3ea0b0e14b36msarett bounds = ®ionRect; 215444df651ebefc284acc2f66425dff3ea0b0e14b36msarett } 215544df651ebefc284acc2f66425dff3ea0b0e14b36msarett 215644df651ebefc284acc2f66425dff3ea0b0e14b36msarett LOOPER_BEGIN(paint, SkDrawFilter::kRect_Type, bounds) 215744df651ebefc284acc2f66425dff3ea0b0e14b36msarett 215844df651ebefc284acc2f66425dff3ea0b0e14b36msarett while (iter.next()) { 215944df651ebefc284acc2f66425dff3ea0b0e14b36msarett iter.fDevice->drawRegion(iter, region, looper.paint()); 216044df651ebefc284acc2f66425dff3ea0b0e14b36msarett } 216144df651ebefc284acc2f66425dff3ea0b0e14b36msarett 216244df651ebefc284acc2f66425dff3ea0b0e14b36msarett LOOPER_END 216344df651ebefc284acc2f66425dff3ea0b0e14b36msarett} 216444df651ebefc284acc2f66425dff3ea0b0e14b36msarett 216541af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) { 21669881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawOval()"); 216778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 216896fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 21694ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (paint.canComputeFastBounds()) { 217087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(oval, &storage))) { 217187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 217287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 217387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &oval; 21744ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 2175306ab9d5de38f2a547fd1d69aedbe69b5c6617ccskia.committer@gmail.com 217678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, bounds) 217746d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com 217846d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com while (iter.next()) { 217946d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com iter.fDevice->drawOval(iter, oval, looper.paint()); 218046d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com } 218146d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com 218246d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com LOOPER_END 21834ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 21844ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 2185ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomonvoid SkCanvas::onDrawArc(const SkRect& oval, SkScalar startAngle, 2186ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon SkScalar sweepAngle, bool useCenter, 2187ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon const SkPaint& paint) { 2188ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawArc()"); 2189ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon const SkRect* bounds = nullptr; 2190ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon if (paint.canComputeFastBounds()) { 2191ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon SkRect storage; 2192ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon // Note we're using the entire oval as the bounds. 2193ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon if (this->quickReject(paint.computeFastBounds(oval, &storage))) { 2194ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon return; 2195ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon } 2196ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon bounds = &oval; 2197ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon } 2198ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon 2199ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, bounds) 2200ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon 2201ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon while (iter.next()) { 2202ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon iter.fDevice->drawArc(iter, oval, startAngle, sweepAngle, useCenter, looper.paint()); 2203ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon } 2204ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon 2205ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon LOOPER_END 2206ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon} 2207ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon 220841af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) { 22099881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRRect()"); 221078cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 221196fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 22124ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (paint.canComputeFastBounds()) { 221387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(rrect.getBounds(), &storage))) { 221487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 221587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 221687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &rrect.getBounds(); 22174ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 22184ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 22194ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (rrect.isRect()) { 22204ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com // call the non-virtual version 22214ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->SkCanvas::drawRect(rrect.getBounds(), paint); 2222f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org return; 2223f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } else if (rrect.isOval()) { 22244ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com // call the non-virtual version 2225f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org this->SkCanvas::drawOval(rrect.getBounds(), paint); 2226f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org return; 22274ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 2228f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 222978cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) 2230f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 2231f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org while (iter.next()) { 2232f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org iter.fDevice->drawRRect(iter, rrect, looper.paint()); 2233f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } 2234f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 2235f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org LOOPER_END 22364ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 22374ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 2238ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.orgvoid SkCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, 2239ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkPaint& paint) { 2240ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org SkRect storage; 224196fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 2242ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (paint.canComputeFastBounds()) { 224387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(outer.getBounds(), &storage))) { 224487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 224587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 224687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &outer.getBounds(); 2247ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 224825c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 2249ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) 225025c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 2251ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org while (iter.next()) { 2252ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org iter.fDevice->drawDRRect(iter, outer, inner, looper.paint()); 2253ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 225425c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 2255ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org LOOPER_END 2256ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org} 22574ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 225841af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) { 22599881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPath()"); 22609364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com if (!path.isFinite()) { 22619364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com return; 22629364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com } 22639364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com 226478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 226596fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 2266fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com if (!path.isInverseFillType() && paint.canComputeFastBounds()) { 226778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect& pathBounds = path.getBounds(); 226887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(pathBounds, &storage))) { 226987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 227087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 227187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &pathBounds; 22728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 22730b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org 22740b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org const SkRect& r = path.getBounds(); 22750b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org if (r.width() <= 0 && r.height() <= 0) { 22766803c219dd3be4a73e7bb5c4bb8a5b1f803624d0commit-bot@chromium.org if (path.isInverseFillType()) { 2277fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->internalDrawPaint(paint); 22786651a3238dd6affa4276ada42ab613abf1d42d1dcaryclark return; 2279fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 2280fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 22818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 228278cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, bounds) 22838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 22854e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPath(iter, path, looper.paint()); 22868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 22878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22884e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 22898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 22908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2291262a71b7f95ce98ff3dd8dba845afbd724470903reedbool SkCanvas::canDrawBitmapAsSprite(SkScalar x, SkScalar y, int w, int h, const SkPaint& paint) { 2292262a71b7f95ce98ff3dd8dba845afbd724470903reed if (!paint.getImageFilter()) { 2293262a71b7f95ce98ff3dd8dba845afbd724470903reed return false; 2294262a71b7f95ce98ff3dd8dba845afbd724470903reed } 2295262a71b7f95ce98ff3dd8dba845afbd724470903reed 2296262a71b7f95ce98ff3dd8dba845afbd724470903reed const SkMatrix& ctm = this->getTotalMatrix(); 2297c7e211acd0c9201688de7ff0c9a2271c67440adffmalita if (!SkTreatAsSprite(ctm, SkISize::Make(w, h), paint)) { 2298262a71b7f95ce98ff3dd8dba845afbd724470903reed return false; 2299262a71b7f95ce98ff3dd8dba845afbd724470903reed } 2300262a71b7f95ce98ff3dd8dba845afbd724470903reed 2301262a71b7f95ce98ff3dd8dba845afbd724470903reed // Currently we can only use the filterSprite code if we are clipped to the bitmap's bounds. 2302262a71b7f95ce98ff3dd8dba845afbd724470903reed // Once we can filter and the filter will return a result larger than itself, we should be 2303262a71b7f95ce98ff3dd8dba845afbd724470903reed // able to remove this constraint. 2304262a71b7f95ce98ff3dd8dba845afbd724470903reed // skbug.com/4526 2305262a71b7f95ce98ff3dd8dba845afbd724470903reed // 2306262a71b7f95ce98ff3dd8dba845afbd724470903reed SkPoint pt; 2307262a71b7f95ce98ff3dd8dba845afbd724470903reed ctm.mapXY(x, y, &pt); 2308262a71b7f95ce98ff3dd8dba845afbd724470903reed SkIRect ir = SkIRect::MakeXYWH(SkScalarRoundToInt(pt.x()), SkScalarRoundToInt(pt.y()), w, h); 2309262a71b7f95ce98ff3dd8dba845afbd724470903reed return ir.contains(fMCRec->fRasterClip.getBounds()); 2310262a71b7f95ce98ff3dd8dba845afbd724470903reed} 2311262a71b7f95ce98ff3dd8dba845afbd724470903reed 2312a85d4d0814818e4ddabb9237da209d61d6cd5854reedvoid SkCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, const SkPaint* paint) { 23139881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImage()"); 2314a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkRect bounds = SkRect::MakeXYWH(x, y, 2315a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkIntToScalar(image->width()), SkIntToScalar(image->height())); 231696fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 231787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect tmp = bounds; 231887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (paint) { 231987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco paint->computeFastBounds(tmp, &tmp); 232087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 232187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(tmp)) { 232287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 232387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 2324a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 23259d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2326a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkLazyPaint lazy; 232796fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 2328a85d4d0814818e4ddabb9237da209d61d6cd5854reed paint = lazy.init(); 2329a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2330262a71b7f95ce98ff3dd8dba845afbd724470903reed 2331a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed sk_sp<SkSpecialImage> special; 2332129ed1cd6d792f3f6cf563aefa9756fc6308289dreed bool drawAsSprite = this->canDrawBitmapAsSprite(x, y, image->width(), image->height(), 2333129ed1cd6d792f3f6cf563aefa9756fc6308289dreed *paint); 2334129ed1cd6d792f3f6cf563aefa9756fc6308289dreed if (drawAsSprite && paint->getImageFilter()) { 2335a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed special = this->getDevice()->makeSpecial(image); 2336a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (!special) { 2337129ed1cd6d792f3f6cf563aefa9756fc6308289dreed drawAsSprite = false; 2338129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 2339129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 2340129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 2341262a71b7f95ce98ff3dd8dba845afbd724470903reed LOOPER_BEGIN_DRAWBITMAP(*paint, drawAsSprite, &bounds) 2342262a71b7f95ce98ff3dd8dba845afbd724470903reed 2343a85d4d0814818e4ddabb9237da209d61d6cd5854reed while (iter.next()) { 2344262a71b7f95ce98ff3dd8dba845afbd724470903reed const SkPaint& pnt = looper.paint(); 2345a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (special) { 2346a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkPoint pt; 2347a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed iter.fMatrix->mapXY(x, y, &pt); 2348a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed iter.fDevice->drawSpecial(iter, special.get(), 2349a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkScalarRoundToInt(pt.fX), 2350a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkScalarRoundToInt(pt.fY), pnt); 2351262a71b7f95ce98ff3dd8dba845afbd724470903reed } else { 2352262a71b7f95ce98ff3dd8dba845afbd724470903reed iter.fDevice->drawImage(iter, image, x, y, pnt); 2353262a71b7f95ce98ff3dd8dba845afbd724470903reed } 2354a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 23559d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2356a85d4d0814818e4ddabb9237da209d61d6cd5854reed LOOPER_END 2357b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr} 2358b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 235941af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, 2360562fe4767cc73e08a4e039362bc0336aea66ecfbreed const SkPaint* paint, SrcRectConstraint constraint) { 23619881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImageRect()"); 236296fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 2363c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco SkRect storage = dst; 236487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (paint) { 236587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco paint->computeFastBounds(dst, &storage); 236687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 236787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(storage)) { 236887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 236987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 2370a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2371a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkLazyPaint lazy; 237296fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 2373a85d4d0814818e4ddabb9237da209d61d6cd5854reed paint = lazy.init(); 2374a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 23759d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2376c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, SkDrawFilter::kBitmap_Type, &dst, 2377c83a29759a5c2966da5ab973e4fd90763e4c962breed image->isOpaque()) 23789d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2379a85d4d0814818e4ddabb9237da209d61d6cd5854reed while (iter.next()) { 2380a5517e2b190a8083b38964972b031c13e99f1012reed iter.fDevice->drawImageRect(iter, image, src, dst, looper.paint(), constraint); 2381a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 23829d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2383a85d4d0814818e4ddabb9237da209d61d6cd5854reed LOOPER_END 2384b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr} 2385b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 238641af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y, const SkPaint* paint) { 23879881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmap()"); 23888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(bitmap.validate();) 23898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 239033366974d43eae80e22284a2e445225c343859dareed if (bitmap.drawsNothing()) { 239133366974d43eae80e22284a2e445225c343859dareed return; 239233366974d43eae80e22284a2e445225c343859dareed } 239333366974d43eae80e22284a2e445225c343859dareed 239433366974d43eae80e22284a2e445225c343859dareed SkLazyPaint lazy; 239533366974d43eae80e22284a2e445225c343859dareed if (nullptr == paint) { 239633366974d43eae80e22284a2e445225c343859dareed paint = lazy.init(); 239733366974d43eae80e22284a2e445225c343859dareed } 239833366974d43eae80e22284a2e445225c343859dareed 239933366974d43eae80e22284a2e445225c343859dareed const SkMatrix matrix = SkMatrix::MakeTrans(x, y); 240033366974d43eae80e22284a2e445225c343859dareed 240133366974d43eae80e22284a2e445225c343859dareed SkRect storage; 240233366974d43eae80e22284a2e445225c343859dareed const SkRect* bounds = nullptr; 240333366974d43eae80e22284a2e445225c343859dareed if (paint->canComputeFastBounds()) { 240433366974d43eae80e22284a2e445225c343859dareed bitmap.getBounds(&storage); 240533366974d43eae80e22284a2e445225c343859dareed matrix.mapRect(&storage); 240687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect tmp = storage; 240787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint->computeFastBounds(tmp, &tmp))) { 240887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 240987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 241087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &storage; 24118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 24124b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2413a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed sk_sp<SkSpecialImage> special; 2414129ed1cd6d792f3f6cf563aefa9756fc6308289dreed bool drawAsSprite = bounds && this->canDrawBitmapAsSprite(x, y, bitmap.width(), bitmap.height(), 2415129ed1cd6d792f3f6cf563aefa9756fc6308289dreed *paint); 2416129ed1cd6d792f3f6cf563aefa9756fc6308289dreed if (drawAsSprite && paint->getImageFilter()) { 2417a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed special = this->getDevice()->makeSpecial(bitmap); 2418a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (!special) { 2419129ed1cd6d792f3f6cf563aefa9756fc6308289dreed drawAsSprite = false; 2420129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 2421129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 2422129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 2423262a71b7f95ce98ff3dd8dba845afbd724470903reed LOOPER_BEGIN_DRAWBITMAP(*paint, drawAsSprite, bounds) 242433366974d43eae80e22284a2e445225c343859dareed 242533366974d43eae80e22284a2e445225c343859dareed while (iter.next()) { 2426262a71b7f95ce98ff3dd8dba845afbd724470903reed const SkPaint& pnt = looper.paint(); 2427a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (special) { 2428262a71b7f95ce98ff3dd8dba845afbd724470903reed SkPoint pt; 2429262a71b7f95ce98ff3dd8dba845afbd724470903reed iter.fMatrix->mapXY(x, y, &pt); 2430a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed iter.fDevice->drawSpecial(iter, special.get(), 2431a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkScalarRoundToInt(pt.fX), 2432a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkScalarRoundToInt(pt.fY), pnt); 2433262a71b7f95ce98ff3dd8dba845afbd724470903reed } else { 2434262a71b7f95ce98ff3dd8dba845afbd724470903reed iter.fDevice->drawBitmap(iter, bitmap, matrix, looper.paint()); 2435262a71b7f95ce98ff3dd8dba845afbd724470903reed } 243633366974d43eae80e22284a2e445225c343859dareed } 2437fbfa25802709139c2f14e304319c9541da65ca27msarett 243833366974d43eae80e22284a2e445225c343859dareed LOOPER_END 24398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24419987ec3791336bad6af5cbe513564786b2df55aareed@google.com// this one is non-virtual, so it can be called safely by other canvas apis 24427112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.comvoid SkCanvas::internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, 2443eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org const SkRect& dst, const SkPaint* paint, 2444a5517e2b190a8083b38964972b031c13e99f1012reed SrcRectConstraint constraint) { 244550b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org if (bitmap.drawsNothing() || dst.isEmpty()) { 24468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 24478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 244874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 244996fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 2450c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco SkRect storage; 245187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 245287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 245387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 24548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 24553d60812865bb034851da777a91413ab584929887reed@google.com 245633535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com SkLazyPaint lazy; 245796fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 245833535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com paint = lazy.init(); 24598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 24607064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 2461c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, SkDrawFilter::kBitmap_Type, &dst, 2462c83a29759a5c2966da5ab973e4fd90763e4c962breed bitmap.isOpaque()) 24637064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 246433535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com while (iter.next()) { 2465562fe4767cc73e08a4e039362bc0336aea66ecfbreed iter.fDevice->drawBitmapRect(iter, bitmap, src, dst, looper.paint(), constraint); 2466f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 24677064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 246833535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com LOOPER_END 24698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 247141af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, 2472562fe4767cc73e08a4e039362bc0336aea66ecfbreed const SkPaint* paint, SrcRectConstraint constraint) { 24739881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmapRectToRect()"); 24749987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkDEBUGCODE(bitmap.validate();) 2475562fe4767cc73e08a4e039362bc0336aea66ecfbreed this->internalDrawBitmapRect(bitmap, src, dst, paint, constraint); 24769987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 24779987ec3791336bad6af5cbe513564786b2df55aareed@google.com 24784c21dc5ddf3b482293ed34eead876d8d61a662c3reedvoid SkCanvas::onDrawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst, 24794c21dc5ddf3b482293ed34eead876d8d61a662c3reed const SkPaint* paint) { 24804c21dc5ddf3b482293ed34eead876d8d61a662c3reed TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImageNine()"); 24819d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 248296fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 2483c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco SkRect storage; 248487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 248587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 248687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 24873d60812865bb034851da777a91413ab584929887reed@google.com } 24889d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 24894c21dc5ddf3b482293ed34eead876d8d61a662c3reed SkLazyPaint lazy; 249096fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 24914c21dc5ddf3b482293ed34eead876d8d61a662c3reed paint = lazy.init(); 24924c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 24939d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2494c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst) 24959d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 24964c21dc5ddf3b482293ed34eead876d8d61a662c3reed while (iter.next()) { 24974c21dc5ddf3b482293ed34eead876d8d61a662c3reed iter.fDevice->drawImageNine(iter, image, center, dst, looper.paint()); 24989987ec3791336bad6af5cbe513564786b2df55aareed@google.com } 24999d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 25004c21dc5ddf3b482293ed34eead876d8d61a662c3reed LOOPER_END 25019987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 25029987ec3791336bad6af5cbe513564786b2df55aareed@google.com 250341af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst, 250441af966ab338e95eee81ab618ab28195075338f7reed const SkPaint* paint) { 25059881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmapNine()"); 25069987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkDEBUGCODE(bitmap.validate();) 25079987ec3791336bad6af5cbe513564786b2df55aareed@google.com 250896fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 2509c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco SkRect storage; 251087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 251187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 251287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 25134c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 25149d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 25154c21dc5ddf3b482293ed34eead876d8d61a662c3reed SkLazyPaint lazy; 251696fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 25174c21dc5ddf3b482293ed34eead876d8d61a662c3reed paint = lazy.init(); 25184c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 25199d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2520c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst) 25219d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 25224c21dc5ddf3b482293ed34eead876d8d61a662c3reed while (iter.next()) { 25234c21dc5ddf3b482293ed34eead876d8d61a662c3reed iter.fDevice->drawBitmapNine(iter, bitmap, center, dst, looper.paint()); 25244c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 25259d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 25264c21dc5ddf3b482293ed34eead876d8d61a662c3reed LOOPER_END 25279987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 25289987ec3791336bad6af5cbe513564786b2df55aareed@google.com 2529168820625c35a8c19f66c661efcbce7a5e334837msarettvoid SkCanvas::onDrawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst, 2530168820625c35a8c19f66c661efcbce7a5e334837msarett const SkPaint* paint) { 2531168820625c35a8c19f66c661efcbce7a5e334837msarett if (nullptr == paint || paint->canComputeFastBounds()) { 2532168820625c35a8c19f66c661efcbce7a5e334837msarett SkRect storage; 2533168820625c35a8c19f66c661efcbce7a5e334837msarett if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 2534168820625c35a8c19f66c661efcbce7a5e334837msarett return; 2535168820625c35a8c19f66c661efcbce7a5e334837msarett } 2536168820625c35a8c19f66c661efcbce7a5e334837msarett } 2537168820625c35a8c19f66c661efcbce7a5e334837msarett 2538168820625c35a8c19f66c661efcbce7a5e334837msarett SkLazyPaint lazy; 2539168820625c35a8c19f66c661efcbce7a5e334837msarett if (nullptr == paint) { 2540168820625c35a8c19f66c661efcbce7a5e334837msarett paint = lazy.init(); 2541168820625c35a8c19f66c661efcbce7a5e334837msarett } 2542168820625c35a8c19f66c661efcbce7a5e334837msarett 2543168820625c35a8c19f66c661efcbce7a5e334837msarett LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst) 2544168820625c35a8c19f66c661efcbce7a5e334837msarett 2545168820625c35a8c19f66c661efcbce7a5e334837msarett while (iter.next()) { 2546168820625c35a8c19f66c661efcbce7a5e334837msarett iter.fDevice->drawImageLattice(iter, image, lattice, dst, looper.paint()); 2547168820625c35a8c19f66c661efcbce7a5e334837msarett } 2548168820625c35a8c19f66c661efcbce7a5e334837msarett 2549168820625c35a8c19f66c661efcbce7a5e334837msarett LOOPER_END 2550168820625c35a8c19f66c661efcbce7a5e334837msarett} 2551168820625c35a8c19f66c661efcbce7a5e334837msarett 2552168820625c35a8c19f66c661efcbce7a5e334837msarettvoid SkCanvas::onDrawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, 2553168820625c35a8c19f66c661efcbce7a5e334837msarett const SkRect& dst, const SkPaint* paint) { 2554168820625c35a8c19f66c661efcbce7a5e334837msarett if (nullptr == paint || paint->canComputeFastBounds()) { 2555168820625c35a8c19f66c661efcbce7a5e334837msarett SkRect storage; 2556168820625c35a8c19f66c661efcbce7a5e334837msarett if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 2557168820625c35a8c19f66c661efcbce7a5e334837msarett return; 2558168820625c35a8c19f66c661efcbce7a5e334837msarett } 2559168820625c35a8c19f66c661efcbce7a5e334837msarett } 2560168820625c35a8c19f66c661efcbce7a5e334837msarett 2561168820625c35a8c19f66c661efcbce7a5e334837msarett SkLazyPaint lazy; 2562168820625c35a8c19f66c661efcbce7a5e334837msarett if (nullptr == paint) { 2563168820625c35a8c19f66c661efcbce7a5e334837msarett paint = lazy.init(); 2564168820625c35a8c19f66c661efcbce7a5e334837msarett } 2565168820625c35a8c19f66c661efcbce7a5e334837msarett 2566168820625c35a8c19f66c661efcbce7a5e334837msarett LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst) 2567168820625c35a8c19f66c661efcbce7a5e334837msarett 2568168820625c35a8c19f66c661efcbce7a5e334837msarett while (iter.next()) { 2569168820625c35a8c19f66c661efcbce7a5e334837msarett iter.fDevice->drawBitmapLattice(iter, bitmap, lattice, dst, looper.paint()); 2570168820625c35a8c19f66c661efcbce7a5e334837msarett } 2571168820625c35a8c19f66c661efcbce7a5e334837msarett 2572168820625c35a8c19f66c661efcbce7a5e334837msarett LOOPER_END 2573168820625c35a8c19f66c661efcbce7a5e334837msarett} 2574168820625c35a8c19f66c661efcbce7a5e334837msarett 2575f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.comclass SkDeviceFilteredPaint { 2576f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.compublic: 25771f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkDeviceFilteredPaint(SkBaseDevice* device, const SkPaint& paint) { 2578112e7e277702e104357f2d44742253ee1b0109acfmalita uint32_t filteredFlags = device->filterTextFlags(paint); 2579112e7e277702e104357f2d44742253ee1b0109acfmalita if (filteredFlags != paint.getFlags()) { 2580a076e9be17654a60310e72c4f70fcd5337f56dbfreed@google.com SkPaint* newPaint = fLazy.set(paint); 2581112e7e277702e104357f2d44742253ee1b0109acfmalita newPaint->setFlags(filteredFlags); 2582f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com fPaint = newPaint; 2583f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } else { 2584f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com fPaint = &paint; 2585f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } 2586f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } 2587f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 2588f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com const SkPaint& paint() const { return *fPaint; } 2589f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 2590f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.comprivate: 25912c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint* fPaint; 25922c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkLazyPaint fLazy; 2593f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com}; 2594f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 259552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.comvoid SkCanvas::DrawRect(const SkDraw& draw, const SkPaint& paint, 259652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com const SkRect& r, SkScalar textSize) { 259717b78946096265d80215a6c946286ecaa35ea7edepoger@google.com if (paint.getStyle() == SkPaint::kFill_Style) { 259852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com draw.fDevice->drawRect(draw, r, paint); 259952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } else { 260052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPaint p(paint); 260117b78946096265d80215a6c946286ecaa35ea7edepoger@google.com p.setStrokeWidth(SkScalarMul(textSize, paint.getStrokeWidth())); 260252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com draw.fDevice->drawRect(draw, r, p); 260352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 260452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com} 260552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 260652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.comvoid SkCanvas::DrawTextDecorations(const SkDraw& draw, const SkPaint& paint, 260752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com const char text[], size_t byteLength, 260852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar x, SkScalar y) { 260996fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkASSERT(byteLength == 0 || text != nullptr); 261052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 261152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com // nothing to draw 261296fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (text == nullptr || byteLength == 0 || 26131e7f5e708e5daeb0c18ae49001c9e3cd5e3b13cbreed draw.fRC->isEmpty() || 2614374772bd61951f01bf84fe17bf53d8867681c9aereed (paint.getAlpha() == 0 && paint.isSrcOver())) { 261552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com return; 261652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 261752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 261852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar width = 0; 261952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPoint start; 262052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 262152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.set(0, 0); // to avoid warning 262252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (paint.getFlags() & (SkPaint::kUnderlineText_Flag | 262352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPaint::kStrikeThruText_Flag)) { 262452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com width = paint.measureText(text, byteLength); 262552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 262652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar offsetX = 0; 262752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (paint.getTextAlign() == SkPaint::kCenter_Align) { 262852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com offsetX = SkScalarHalf(width); 262952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } else if (paint.getTextAlign() == SkPaint::kRight_Align) { 263052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com offsetX = width; 263152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 263252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.set(x - offsetX, y); 263352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 263452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 263552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (0 == width) { 263652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com return; 263752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 263852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 263952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com uint32_t flags = paint.getFlags(); 264052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 264152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (flags & (SkPaint::kUnderlineText_Flag | 264252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPaint::kStrikeThruText_Flag)) { 264352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar textSize = paint.getTextSize(); 264452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar height = SkScalarMul(textSize, kStdUnderline_Thickness); 264552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkRect r; 264652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 264752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fLeft = start.fX; 264852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fRight = start.fX + width; 264952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 265052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (flags & SkPaint::kUnderlineText_Flag) { 265152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar offset = SkScalarMulAdd(textSize, kStdUnderline_Offset, 265252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.fY); 265352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fTop = offset; 265452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fBottom = offset + height; 2655fb56218292d6c7b509d382f39994c3783b2483a0caryclark DrawRect(draw, paint, r, 1); 265652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 265752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (flags & SkPaint::kStrikeThruText_Flag) { 265852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar offset = SkScalarMulAdd(textSize, kStdStrikeThru_Offset, 265952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.fY); 266052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fTop = offset; 266152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fBottom = offset + height; 2662fb56218292d6c7b509d382f39994c3783b2483a0caryclark DrawRect(draw, paint, r, 1); 266352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 266452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 266552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com} 266652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 2667e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 2668e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 266996fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 26708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 26718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 26724e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 2673f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com iter.fDevice->drawText(iter, text, byteLength, x, y, dfp.paint()); 267452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com DrawTextDecorations(iter, dfp.paint(), 267552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com static_cast<const char*>(text), byteLength, x, y); 26768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 26778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 26784e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 26798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 26808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2681e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], 2682e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 268305c4a4322e7d4f3417b7df33825bab8603d52051fmalita SkPoint textOffset = SkPoint::Make(0, 0); 268405c4a4322e7d4f3417b7df33825bab8603d52051fmalita 268596fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 268687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 26878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 26884e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 268905c4a4322e7d4f3417b7df33825bab8603d52051fmalita iter.fDevice->drawPosText(iter, text, byteLength, &pos->fX, 2, textOffset, 2690f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com dfp.paint()); 26918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2692b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 26934e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 26948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 26958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2696e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], 2697e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com SkScalar constY, const SkPaint& paint) { 269805c4a4322e7d4f3417b7df33825bab8603d52051fmalita 269905c4a4322e7d4f3417b7df33825bab8603d52051fmalita SkPoint textOffset = SkPoint::Make(0, constY); 270005c4a4322e7d4f3417b7df33825bab8603d52051fmalita 270196fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 270287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 27038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 27044e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 270505c4a4322e7d4f3417b7df33825bab8603d52051fmalita iter.fDevice->drawPosText(iter, text, byteLength, xpos, 1, textOffset, 2706f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com dfp.paint()); 27078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2708b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 27094e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 27108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2712e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 2713e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkMatrix* matrix, const SkPaint& paint) { 271496fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 271587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 27168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 27178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawTextOnPath(iter, text, byteLength, path, 27184e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com matrix, looper.paint()); 27198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2720b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 2721945ec3a2bec668ca845071a65df8ec55e8f43819commit-bot@chromium.org LOOPER_END 27224325d114a5679e46f25ae75b0e43547fd7694998commit-bot@chromium.org} 27234325d114a5679e46f25ae75b0e43547fd7694998commit-bot@chromium.org 272445561a0b15fe045ba272c328684c3f7ae290785areedvoid SkCanvas::onDrawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[], 272545561a0b15fe045ba272c328684c3f7ae290785areed const SkRect* cullRect, const SkPaint& paint) { 272645561a0b15fe045ba272c328684c3f7ae290785areed if (cullRect && this->quickReject(*cullRect)) { 272745561a0b15fe045ba272c328684c3f7ae290785areed return; 272845561a0b15fe045ba272c328684c3f7ae290785areed } 272945561a0b15fe045ba272c328684c3f7ae290785areed 273045561a0b15fe045ba272c328684c3f7ae290785areed LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 273145561a0b15fe045ba272c328684c3f7ae290785areed 273245561a0b15fe045ba272c328684c3f7ae290785areed while (iter.next()) { 273345561a0b15fe045ba272c328684c3f7ae290785areed iter.fDevice->drawTextRSXform(iter, text, byteLength, xform, looper.paint()); 273445561a0b15fe045ba272c328684c3f7ae290785areed } 273545561a0b15fe045ba272c328684c3f7ae290785areed 273645561a0b15fe045ba272c328684c3f7ae290785areed LOOPER_END 273745561a0b15fe045ba272c328684c3f7ae290785areed} 273845561a0b15fe045ba272c328684c3f7ae290785areed 273900d5c2c6523321d25b32905ff4822f083a4173eefmalitavoid SkCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 274000d5c2c6523321d25b32905ff4822f083a4173eefmalita const SkPaint& paint) { 27417ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita 274285d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita SkRect storage; 274396fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 274419653d1d004610b4ba07ce563a5701164e120e45fmalita if (paint.canComputeFastBounds()) { 274585d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita storage = blob->bounds().makeOffset(x, y); 274687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect tmp; 274787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(storage, &tmp))) { 274887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 274987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 275087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &storage; 27517ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita } 27527ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita 2753024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita // We cannot filter in the looper as we normally do, because the paint is 2754024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita // incomplete at this point (text-related attributes are embedded within blob run paints). 2755024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita SkDrawFilter* drawFilter = fMCRec->fFilter; 275696fcdcc219d2a0d3579719b84b28bede76efba64halcanary fMCRec->fFilter = nullptr; 2757024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita 275885d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, bounds) 275900d5c2c6523321d25b32905ff4822f083a4173eefmalita 2760aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita while (iter.next()) { 2761aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 2762024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita iter.fDevice->drawTextBlob(iter, blob, x, y, dfp.paint(), drawFilter); 276300d5c2c6523321d25b32905ff4822f083a4173eefmalita } 276400d5c2c6523321d25b32905ff4822f083a4173eefmalita 2765aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita LOOPER_END 2766024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita 2767024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita fMCRec->fFilter = drawFilter; 276800d5c2c6523321d25b32905ff4822f083a4173eefmalita} 276900d5c2c6523321d25b32905ff4822f083a4173eefmalita 2770e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com// These will become non-virtual, so they always call the (virtual) onDraw... method 2771e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 2772e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 27739881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawText()"); 2774ac09554dce518e9d4496771f648f3ae17eca857creed if (byteLength) { 2775ac09554dce518e9d4496771f648f3ae17eca857creed this->onDrawText(text, byteLength, x, y, paint); 2776ac09554dce518e9d4496771f648f3ae17eca857creed } 2777e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2778e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawPosText(const void* text, size_t byteLength, const SkPoint pos[], 2779e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 27809881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPosText()"); 2781ac09554dce518e9d4496771f648f3ae17eca857creed if (byteLength) { 2782ac09554dce518e9d4496771f648f3ae17eca857creed this->onDrawPosText(text, byteLength, pos, paint); 2783ac09554dce518e9d4496771f648f3ae17eca857creed } 2784e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2785e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], 2786e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com SkScalar constY, const SkPaint& paint) { 27879881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPosTextH()"); 2788ac09554dce518e9d4496771f648f3ae17eca857creed if (byteLength) { 2789ac09554dce518e9d4496771f648f3ae17eca857creed this->onDrawPosTextH(text, byteLength, xpos, constY, paint); 2790ac09554dce518e9d4496771f648f3ae17eca857creed } 2791e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2792e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 2793e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkMatrix* matrix, const SkPaint& paint) { 27949881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextOnPath()"); 2795ac09554dce518e9d4496771f648f3ae17eca857creed if (byteLength) { 2796ac09554dce518e9d4496771f648f3ae17eca857creed this->onDrawTextOnPath(text, byteLength, path, matrix, paint); 2797ac09554dce518e9d4496771f648f3ae17eca857creed } 2798e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 279945561a0b15fe045ba272c328684c3f7ae290785areedvoid SkCanvas::drawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[], 280045561a0b15fe045ba272c328684c3f7ae290785areed const SkRect* cullRect, const SkPaint& paint) { 280145561a0b15fe045ba272c328684c3f7ae290785areed TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextRSXform()"); 280245561a0b15fe045ba272c328684c3f7ae290785areed if (byteLength) { 280345561a0b15fe045ba272c328684c3f7ae290785areed this->onDrawTextRSXform(text, byteLength, xform, cullRect, paint); 280445561a0b15fe045ba272c328684c3f7ae290785areed } 280545561a0b15fe045ba272c328684c3f7ae290785areed} 280600d5c2c6523321d25b32905ff4822f083a4173eefmalitavoid SkCanvas::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 280700d5c2c6523321d25b32905ff4822f083a4173eefmalita const SkPaint& paint) { 2808e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(blob); 28099881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextBlob()"); 2810e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawTextBlob(blob, x, y, paint); 281100d5c2c6523321d25b32905ff4822f083a4173eefmalita} 2812e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com 281341af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawVertices(VertexMode vmode, int vertexCount, 281441af966ab338e95eee81ab618ab28195075338f7reed const SkPoint verts[], const SkPoint texs[], 2815faba3715b8ddfaa0ce4df79bc8006e9bc7694e5bMike Reed const SkColor colors[], SkBlendMode bmode, 281641af966ab338e95eee81ab618ab28195075338f7reed const uint16_t indices[], int indexCount, 281741af966ab338e95eee81ab618ab28195075338f7reed const SkPaint& paint) { 28189881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawVertices()"); 281996fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, nullptr) 28204b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 28218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 28228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawVertices(iter, vmode, vertexCount, verts, texs, 2823faba3715b8ddfaa0ce4df79bc8006e9bc7694e5bMike Reed colors, bmode, indices, indexCount, 28244e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com looper.paint()); 28258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 28264b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 28274e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 28288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2830b3c9d1c33caf325aada244204215eb790c228c12dandovvoid SkCanvas::drawPatch(const SkPoint cubics[12], const SkColor colors[4], 28317d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed const SkPoint texCoords[4], SkBlendMode bmode, 28327d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed const SkPaint& paint) { 28339881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPatch()"); 283496fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == cubics) { 2835b3c9d1c33caf325aada244204215eb790c228c12dandov return; 2836b3c9d1c33caf325aada244204215eb790c228c12dandov } 28376cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2838faba3715b8ddfaa0ce4df79bc8006e9bc7694e5bMike Reed this->onDrawPatch(cubics, colors, texCoords, bmode, paint); 28399340c2685c0bb0e1e70008acaaf3d1448f074c38msarett} 28409340c2685c0bb0e1e70008acaaf3d1448f074c38msarett 28419340c2685c0bb0e1e70008acaaf3d1448f074c38msarettvoid SkCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], 2842faba3715b8ddfaa0ce4df79bc8006e9bc7694e5bMike Reed const SkPoint texCoords[4], SkBlendMode bmode, 28437d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed const SkPaint& paint) { 2844ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov // Since a patch is always within the convex hull of the control points, we discard it when its 2845ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov // bounding rectangle is completely outside the current clip. 2846ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov SkRect bounds; 2847b3c9d1c33caf325aada244204215eb790c228c12dandov bounds.set(cubics, SkPatchUtils::kNumCtrlPts); 2848ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov if (this->quickReject(bounds)) { 2849ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov return; 2850ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov } 28516cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 285296fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, nullptr) 28536cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2854ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov while (iter.next()) { 2855faba3715b8ddfaa0ce4df79bc8006e9bc7694e5bMike Reed iter.fDevice->drawPatch(iter, cubics, colors, texCoords, bmode, paint); 2856ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov } 28576cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2858ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov LOOPER_END 2859ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov} 2860ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov 2861a8db72864a43ad1fbba3c2892cf5cd88060a43efreedvoid SkCanvas::drawDrawable(SkDrawable* dr, SkScalar x, SkScalar y) { 2862e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(dr); 2863e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed if (x || y) { 2864e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed SkMatrix matrix = SkMatrix::MakeTrans(x, y); 2865e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawDrawable(dr, &matrix); 2866e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed } else { 2867e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawDrawable(dr, nullptr); 2868a8db72864a43ad1fbba3c2892cf5cd88060a43efreed } 2869a8db72864a43ad1fbba3c2892cf5cd88060a43efreed} 2870a8db72864a43ad1fbba3c2892cf5cd88060a43efreed 2871a8db72864a43ad1fbba3c2892cf5cd88060a43efreedvoid SkCanvas::drawDrawable(SkDrawable* dr, const SkMatrix* matrix) { 2872e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(dr); 2873e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed if (matrix && matrix->isIdentity()) { 2874e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed matrix = nullptr; 28756a070dc06af4e9f305f9d08a69e34d18ade473cbreed } 2876e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawDrawable(dr, matrix); 28776a070dc06af4e9f305f9d08a69e34d18ade473cbreed} 28786a070dc06af4e9f305f9d08a69e34d18ade473cbreed 2879a8db72864a43ad1fbba3c2892cf5cd88060a43efreedvoid SkCanvas::onDrawDrawable(SkDrawable* dr, const SkMatrix* matrix) { 28802a62e853c27cfacafd5c15ac1077cc13140589bareed // drawable bounds are no longer reliable (e.g. android displaylist) 28812a62e853c27cfacafd5c15ac1077cc13140589bareed // so don't use them for quick-reject 2882a8db72864a43ad1fbba3c2892cf5cd88060a43efreed dr->draw(this, matrix); 28836a070dc06af4e9f305f9d08a69e34d18ade473cbreed} 28846a070dc06af4e9f305f9d08a69e34d18ade473cbreed 288571c3c760a83123ee0b3127b8c65c6394ce541c50reedvoid SkCanvas::onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], 2886faba3715b8ddfaa0ce4df79bc8006e9bc7694e5bMike Reed const SkColor colors[], int count, SkBlendMode bmode, 288771c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkRect* cull, const SkPaint* paint) { 288871c3c760a83123ee0b3127b8c65c6394ce541c50reed if (cull && this->quickReject(*cull)) { 288971c3c760a83123ee0b3127b8c65c6394ce541c50reed return; 289071c3c760a83123ee0b3127b8c65c6394ce541c50reed } 289171c3c760a83123ee0b3127b8c65c6394ce541c50reed 289271c3c760a83123ee0b3127b8c65c6394ce541c50reed SkPaint pnt; 289371c3c760a83123ee0b3127b8c65c6394ce541c50reed if (paint) { 289471c3c760a83123ee0b3127b8c65c6394ce541c50reed pnt = *paint; 289571c3c760a83123ee0b3127b8c65c6394ce541c50reed } 28969d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 289796fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(pnt, SkDrawFilter::kPath_Type, nullptr) 289871c3c760a83123ee0b3127b8c65c6394ce541c50reed while (iter.next()) { 2899faba3715b8ddfaa0ce4df79bc8006e9bc7694e5bMike Reed iter.fDevice->drawAtlas(iter, atlas, xform, tex, colors, count, bmode, pnt); 290071c3c760a83123ee0b3127b8c65c6394ce541c50reed } 290171c3c760a83123ee0b3127b8c65c6394ce541c50reed LOOPER_END 290271c3c760a83123ee0b3127b8c65c6394ce541c50reed} 290371c3c760a83123ee0b3127b8c65c6394ce541c50reed 2904f70b531daaf47db1ee95c70da9843f1dd1f418d3reedvoid SkCanvas::onDrawAnnotation(const SkRect& rect, const char key[], SkData* value) { 2905f70b531daaf47db1ee95c70da9843f1dd1f418d3reed SkASSERT(key); 2906f70b531daaf47db1ee95c70da9843f1dd1f418d3reed 2907f70b531daaf47db1ee95c70da9843f1dd1f418d3reed SkPaint paint; 2908f70b531daaf47db1ee95c70da9843f1dd1f418d3reed LOOPER_BEGIN(paint, SkDrawFilter::kRect_Type, nullptr) 2909f70b531daaf47db1ee95c70da9843f1dd1f418d3reed while (iter.next()) { 2910f70b531daaf47db1ee95c70da9843f1dd1f418d3reed iter.fDevice->drawAnnotation(iter, rect, key, value); 2911f70b531daaf47db1ee95c70da9843f1dd1f418d3reed } 2912f70b531daaf47db1ee95c70da9843f1dd1f418d3reed LOOPER_END 2913f70b531daaf47db1ee95c70da9843f1dd1f418d3reed} 2914f70b531daaf47db1ee95c70da9843f1dd1f418d3reed 29158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 29168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// These methods are NOT virtual, and therefore must call back into virtual 29178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// methods, rather than actually drawing themselves. 29188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 29198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2920374772bd61951f01bf84fe17bf53d8867681c9aereedvoid SkCanvas::drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b, SkBlendMode mode) { 29219881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawARGB()"); 29228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 29238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setARGB(a, r, g, b); 2925374772bd61951f01bf84fe17bf53d8867681c9aereed paint.setBlendMode(mode); 29268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPaint(paint); 29278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 29288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2929374772bd61951f01bf84fe17bf53d8867681c9aereedvoid SkCanvas::drawColor(SkColor c, SkBlendMode mode) { 29309881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawColor()"); 29318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 29328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setColor(c); 2934374772bd61951f01bf84fe17bf53d8867681c9aereed paint.setBlendMode(mode); 29358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPaint(paint); 29368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 29378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPoint(SkScalar x, SkScalar y, const SkPaint& paint) { 29399881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPoint(SkPaint)"); 29408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pt; 29414b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 29428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pt.set(x, y); 29438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kPoints_PointMode, 1, &pt, paint); 29448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 29458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPoint(SkScalar x, SkScalar y, SkColor color) { 29479881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPoint(SkColor)"); 29488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pt; 29498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 29504b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 29518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pt.set(x, y); 29528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setColor(color); 29538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kPoints_PointMode, 1, &pt, paint); 29548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 29558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, 29578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 29589881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawLine()"); 29598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pts[2]; 29604b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 29618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pts[0].set(x0, y0); 29628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pts[1].set(x1, y1); 29638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kLines_PointMode, 2, pts, paint); 29648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 29658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawRectCoords(SkScalar left, SkScalar top, 29678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar right, SkScalar bottom, 29688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 29699881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRectCoords()"); 29708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 29718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.set(left, top, right, bottom); 29738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawRect(r, paint); 29748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 29758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, 29778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 29789881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawCircle()"); 29798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (radius < 0) { 29808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com radius = 0; 29818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 29828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 29848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.set(cx - radius, cy - radius, cx + radius, cy + radius); 29854ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->drawOval(r, paint); 29868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 29878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawRoundRect(const SkRect& r, SkScalar rx, SkScalar ry, 29898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 29909881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRoundRect()"); 29918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (rx > 0 && ry > 0) { 29924ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com SkRRect rrect; 29934ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com rrect.setRectXY(r, rx, ry); 29944ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->drawRRect(rrect, paint); 29958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 29968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawRect(r, paint); 29978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 29988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 29998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawArc(const SkRect& oval, SkScalar startAngle, 30018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar sweepAngle, bool useCenter, 30028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 30039881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawArc()"); 300421af9ca1b1f54d9ba1de055aa8475928d5c8ecdfbsalomon if (oval.isEmpty() || !sweepAngle) { 300521af9ca1b1f54d9ba1de055aa8475928d5c8ecdfbsalomon return; 30068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 300721af9ca1b1f54d9ba1de055aa8475928d5c8ecdfbsalomon this->onDrawArc(oval, startAngle, sweepAngle, useCenter, paint); 30088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 30098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawTextOnPathHV(const void* text, size_t byteLength, 30118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPath& path, SkScalar hOffset, 30128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar vOffset, const SkPaint& paint) { 30139881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextOnPathHV()"); 30148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 30154b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 30168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.setTranslate(hOffset, vOffset); 30178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawTextOnPath(text, byteLength, path, &matrix, paint); 30188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 30198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3020f76bacff7f66724072c67edb185abf9e3add11a0reed@android.com/////////////////////////////////////////////////////////////////////////////// 30211c2c441fede0ae9573afc098017011e3439624a9reed 30221c2c441fede0ae9573afc098017011e3439624a9reed/** 30231c2c441fede0ae9573afc098017011e3439624a9reed * This constant is trying to balance the speed of ref'ing a subpicture into a parent picture, 30241c2c441fede0ae9573afc098017011e3439624a9reed * against the playback cost of recursing into the subpicture to get at its actual ops. 30251c2c441fede0ae9573afc098017011e3439624a9reed * 30261c2c441fede0ae9573afc098017011e3439624a9reed * For now we pick a conservatively small value, though measurement (and other heuristics like 30271c2c441fede0ae9573afc098017011e3439624a9reed * the type of ops contained) may justify changing this value. 30281c2c441fede0ae9573afc098017011e3439624a9reed */ 30291c2c441fede0ae9573afc098017011e3439624a9reed#define kMaxPictureOpsToUnrollInsteadOfRef 1 30309b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips 3031d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedvoid SkCanvas::drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint) { 3032e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(picture); 3033e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed 30341c2c441fede0ae9573afc098017011e3439624a9reed TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPicture()"); 3035e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed if (matrix && matrix->isIdentity()) { 3036e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed matrix = nullptr; 3037e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed } 3038e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed if (picture->approximateOpCount() <= kMaxPictureOpsToUnrollInsteadOfRef) { 3039e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); 3040e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed picture->playback(this); 3041e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed } else { 3042e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawPicture(picture, matrix, paint); 3043d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 3044d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 30459b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips 3046d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedvoid SkCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix, 3047d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed const SkPaint* paint) { 3048d028180f0310cf2b23f9744256a41697b0683e67fmalita if (!paint || paint->canComputeFastBounds()) { 3049d028180f0310cf2b23f9744256a41697b0683e67fmalita SkRect bounds = picture->cullRect(); 3050d028180f0310cf2b23f9744256a41697b0683e67fmalita if (paint) { 3051d028180f0310cf2b23f9744256a41697b0683e67fmalita paint->computeFastBounds(bounds, &bounds); 3052d028180f0310cf2b23f9744256a41697b0683e67fmalita } 3053d028180f0310cf2b23f9744256a41697b0683e67fmalita if (matrix) { 3054d028180f0310cf2b23f9744256a41697b0683e67fmalita matrix->mapRect(&bounds); 3055d028180f0310cf2b23f9744256a41697b0683e67fmalita } 3056d028180f0310cf2b23f9744256a41697b0683e67fmalita if (this->quickReject(bounds)) { 3057d028180f0310cf2b23f9744256a41697b0683e67fmalita return; 3058d028180f0310cf2b23f9744256a41697b0683e67fmalita } 3059d028180f0310cf2b23f9744256a41697b0683e67fmalita } 3060d028180f0310cf2b23f9744256a41697b0683e67fmalita 3061a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); 3062c5ba71d2e5cd426def66fa49dcf003e5b2c98dc7robertphillips picture->playback(this); 30638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 30648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 306595302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack#ifdef SK_EXPERIMENTAL_SHADOWING 306695302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblackvoid SkCanvas::drawShadowedPicture(const SkPicture* picture, 306795302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack const SkMatrix* matrix, 3068e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack const SkPaint* paint, 3069e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack const SkShadowParams& params) { 307095302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack RETURN_ON_NULL(picture); 307195302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack 307295302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawShadowedPicture()"); 307395302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack 3074e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack this->onDrawShadowedPicture(picture, matrix, paint, params); 307595302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack} 307695302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack 307795302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblackvoid SkCanvas::onDrawShadowedPicture(const SkPicture* picture, 307895302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack const SkMatrix* matrix, 3079e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack const SkPaint* paint, 3080e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack const SkShadowParams& params) { 3081904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack if (!paint || paint->canComputeFastBounds()) { 3082904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack SkRect bounds = picture->cullRect(); 3083904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack if (paint) { 3084904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack paint->computeFastBounds(bounds, &bounds); 3085904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack } 3086904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack if (matrix) { 3087904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack matrix->mapRect(&bounds); 3088904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack } 3089904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack if (this->quickReject(bounds)) { 3090904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack return; 3091904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack } 3092904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack } 3093904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3094904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); 3095904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3096e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack sk_sp<SkImage> povDepthMap; 3097e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack sk_sp<SkImage> diffuseMap; 3098e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack 3099904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack // povDepthMap 3100904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack { 3101904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack SkLights::Builder builder; 3102772b5ee446d7545eec4ca7d6dc9d75461e2a9c38vjiaoblack builder.add(SkLights::Light::MakeDirectional(SkColor3f::Make(1.0f, 1.0f, 1.0f), 3103772b5ee446d7545eec4ca7d6dc9d75461e2a9c38vjiaoblack SkVector3::Make(0.0f, 0.0f, 1.0f))); 3104904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack sk_sp<SkLights> povLight = builder.finish(); 3105904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3106904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack SkImageInfo info = SkImageInfo::Make(picture->cullRect().width(), 3107904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack picture->cullRect().height(), 3108904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack kBGRA_8888_SkColorType, 3109904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack kOpaque_SkAlphaType); 3110904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3111904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack // Create a new surface (that matches the backend of canvas) 3112904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack // to create the povDepthMap 3113904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack sk_sp<SkSurface> surf(this->makeSurface(info)); 3114904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3115904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack // Wrap another SPFCanvas around the surface 3116904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack sk_sp<SkShadowPaintFilterCanvas> depthMapCanvas = 3117904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack sk_make_sp<SkShadowPaintFilterCanvas>(surf->getCanvas()); 3118904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3119904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack // set the depth map canvas to have the light as the user's POV 3120904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack depthMapCanvas->setLights(std::move(povLight)); 3121904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3122904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack depthMapCanvas->drawPicture(picture); 3123904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack povDepthMap = surf->makeImageSnapshot(); 3124904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack } 3125904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3126904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack // diffuseMap 3127904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack { 3128904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack SkImageInfo info = SkImageInfo::Make(picture->cullRect().width(), 3129904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack picture->cullRect().height(), 3130904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack kBGRA_8888_SkColorType, 3131904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack kOpaque_SkAlphaType); 3132904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3133904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack sk_sp<SkSurface> surf(this->makeSurface(info)); 3134904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack surf->getCanvas()->drawPicture(picture); 3135904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3136904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack diffuseMap = surf->makeImageSnapshot(); 3137904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack } 3138904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3139904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack sk_sp<SkShader> povDepthShader = povDepthMap->makeShader(SkShader::kClamp_TileMode, 3140904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack SkShader::kClamp_TileMode); 3141904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack sk_sp<SkShader> diffuseShader = diffuseMap->makeShader(SkShader::kClamp_TileMode, 3142904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack SkShader::kClamp_TileMode); 3143b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3144b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // TODO: pass the depth to the shader in vertices, or uniforms 3145b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // so we don't have to render depth and color separately 3146b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack for (int i = 0; i < fLights->numLights(); ++i) { 3147b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // skip over ambient lights; they don't cast shadows 3148b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // lights that have shadow maps do not need updating (because lights are immutable) 3149b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack sk_sp<SkImage> depthMap; 3150b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkISize shMapSize; 3151b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3152b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack if (fLights->light(i).getShadowMap() != nullptr) { 3153b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack continue; 3154b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack } 3155b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3156b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack if (fLights->light(i).isRadial()) { 3157b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack shMapSize.fHeight = 1; 3158b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack shMapSize.fWidth = (int) picture->cullRect().width(); 3159b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3160b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkImageInfo info = SkImageInfo::Make(diffuseMap->width(), 1, 3161b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack kBGRA_8888_SkColorType, 3162b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack kOpaque_SkAlphaType); 3163b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3164b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // Create new surface (that matches the backend of canvas) 3165b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // for each shadow map 3166b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack sk_sp<SkSurface> surf(this->makeSurface(info)); 3167b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3168b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // Wrap another SPFCanvas around the surface 3169b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkCanvas* depthMapCanvas = surf->getCanvas(); 3170b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3171b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkLights::Builder builder; 3172b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack builder.add(fLights->light(i)); 3173b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack sk_sp<SkLights> curLight = builder.finish(); 3174b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3175b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack sk_sp<SkShader> shadowMapShader; 3176b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack shadowMapShader = SkRadialShadowMapShader::Make( 3177b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack povDepthShader, curLight, 3178b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack (int) picture->cullRect().width(), 3179b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack (int) picture->cullRect().height()); 3180b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3181b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkPaint shadowMapPaint; 3182b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack shadowMapPaint.setShader(std::move(shadowMapShader)); 3183b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3184b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack depthMapCanvas->setLights(curLight); 3185b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3186b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack depthMapCanvas->drawRect(SkRect::MakeIWH(diffuseMap->width(), 3187b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack diffuseMap->height()), 3188b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack shadowMapPaint); 3189b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3190b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack depthMap = surf->makeImageSnapshot(); 3191b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3192b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack } else { 3193b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // TODO: compute the correct size of the depth map from the light properties 3194b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // TODO: maybe add a kDepth_8_SkColorType 3195b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // TODO: find actual max depth of picture 3196b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack shMapSize = SkShadowPaintFilterCanvas::ComputeDepthMapSize( 3197b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack fLights->light(i), 255, 3198b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack (int) picture->cullRect().width(), 3199b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack (int) picture->cullRect().height()); 3200b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3201b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkImageInfo info = SkImageInfo::Make(shMapSize.fWidth, shMapSize.fHeight, 3202b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack kBGRA_8888_SkColorType, 3203b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack kOpaque_SkAlphaType); 3204b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3205b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // Create a new surface (that matches the backend of canvas) 3206b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // for each shadow map 3207b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack sk_sp<SkSurface> surf(this->makeSurface(info)); 3208b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3209b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // Wrap another SPFCanvas around the surface 3210b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack sk_sp<SkShadowPaintFilterCanvas> depthMapCanvas = 3211b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack sk_make_sp<SkShadowPaintFilterCanvas>(surf->getCanvas()); 3212b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack depthMapCanvas->setShadowParams(params); 3213b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3214b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // set the depth map canvas to have the light we're drawing. 3215b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkLights::Builder builder; 3216b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack builder.add(fLights->light(i)); 3217b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack sk_sp<SkLights> curLight = builder.finish(); 3218b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack depthMapCanvas->setLights(std::move(curLight)); 3219b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3220b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack depthMapCanvas->drawPicture(picture); 3221b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack depthMap = surf->makeImageSnapshot(); 3222b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack } 3223b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3224b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack if (params.fType == SkShadowParams::kNoBlur_ShadowType) { 3225b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack fLights->light(i).setShadowMap(std::move(depthMap)); 3226b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack } else if (params.fType == SkShadowParams::kVariance_ShadowType) { 3227b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // we blur the variance map 3228b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkPaint blurPaint; 3229b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack blurPaint.setImageFilter(SkImageFilter::MakeBlur(params.fShadowRadius, 3230b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack params.fShadowRadius, nullptr)); 3231b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3232b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkImageInfo blurInfo = SkImageInfo::Make(shMapSize.fWidth, shMapSize.fHeight, 3233b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack kBGRA_8888_SkColorType, 3234b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack kOpaque_SkAlphaType); 3235b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3236b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack sk_sp<SkSurface> blurSurf(this->makeSurface(blurInfo)); 3237b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3238b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack blurSurf->getCanvas()->drawImage(std::move(depthMap), 0, 0, &blurPaint); 3239b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3240b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack fLights->light(i).setShadowMap(blurSurf->makeImageSnapshot()); 3241b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack } 3242b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack } 3243b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3244b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkPaint shadowPaint; 3245904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack sk_sp<SkShader> shadowShader = SkShadowShader::Make(std::move(povDepthShader), 3246904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack std::move(diffuseShader), 3247b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack fLights, 3248904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack diffuseMap->width(), 3249e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack diffuseMap->height(), 3250e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack params); 3251904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3252904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack shadowPaint.setShader(shadowShader); 3253904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3254904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack this->drawRect(SkRect::MakeIWH(diffuseMap->width(), diffuseMap->height()), shadowPaint); 325595302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack} 325695302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack#endif 325795302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack 32588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 32598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 32608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 32613aafe111b6cc388400092851cc53bbbdfcb8a81creedSkCanvas::LayerIter::LayerIter(SkCanvas* canvas) { 326299fe82260633fcf5d92cca38d12ef0937ecca61cbungeman static_assert(sizeof(fStorage) >= sizeof(SkDrawIter), "fStorage_too_small"); 32638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 32648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(canvas); 32658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 32663aafe111b6cc388400092851cc53bbbdfcb8a81creed fImpl = new (fStorage) SkDrawIter(canvas); 32678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDone = !fImpl->next(); 32688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 32698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 32708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::LayerIter::~LayerIter() { 32718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fImpl->~SkDrawIter(); 32728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 32738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 32748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::LayerIter::next() { 32758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDone = !fImpl->next(); 32768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 32778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 32781f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::LayerIter::device() const { 32798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fImpl->getDevice(); 32808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 32818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 32828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkMatrix& SkCanvas::LayerIter::matrix() const { 32838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fImpl->getMatrix(); 32848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 32858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 32868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkPaint& SkCanvas::LayerIter::paint() const { 32878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* paint = fImpl->getPaint(); 328896fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 32898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint = &fDefaultPaint; 32908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 32918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return *paint; 32928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 32938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 32941e7f5e708e5daeb0c18ae49001c9e3cd5e3b13cbreedconst SkRasterClip& SkCanvas::LayerIter::clip() const { return fImpl->getClip(); } 32958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::LayerIter::x() const { return fImpl->getX(); } 32968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::LayerIter::y() const { return fImpl->getY(); } 329720a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com 329820a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com/////////////////////////////////////////////////////////////////////////////// 329920a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com 3300c3b589a24eb4d567a906189f882c259ecf5c2f58fmalitaSkCanvasClipVisitor::~SkCanvasClipVisitor() { } 33013107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 33023107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 33033107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 33043107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.orgstatic bool supported_for_raster_canvas(const SkImageInfo& info) { 33053107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org switch (info.alphaType()) { 33063107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kPremul_SkAlphaType: 33073107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kOpaque_SkAlphaType: 33083107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org break; 33093107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org default: 33103107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return false; 33113107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 33123107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 33133107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org switch (info.colorType()) { 33143107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kAlpha_8_SkColorType: 33153107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kRGB_565_SkColorType: 331628fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org case kN32_SkColorType: 33179e3dbdff53f2d9957626a17a279730cda70f17bajunov case kRGBA_F16_SkColorType: 33183107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org break; 33193107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org default: 33203107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return false; 33213107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 33223107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 33233107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return true; 33243107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org} 33253107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 332642b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.orgSkCanvas* SkCanvas::NewRasterDirect(const SkImageInfo& info, void* pixels, size_t rowBytes) { 332742b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org if (!supported_for_raster_canvas(info)) { 332896fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 332942b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org } 3330eb849e5fd10cbe00cbc31307ba97fd9efca0b41bskia.committer@gmail.com 333142b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org SkBitmap bitmap; 333242b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org if (!bitmap.installPixels(info, pixels, rowBytes)) { 333396fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 333442b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org } 3335385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return new SkCanvas(bitmap); 333642b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org} 3337d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 3338d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed/////////////////////////////////////////////////////////////////////////////// 3339d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 3340d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedSkAutoCanvasMatrixPaint::SkAutoCanvasMatrixPaint(SkCanvas* canvas, const SkMatrix* matrix, 3341a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips const SkPaint* paint, const SkRect& bounds) 3342d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed : fCanvas(canvas) 3343d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed , fSaveCount(canvas->getSaveCount()) 3344d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed{ 334549f085dddff10473b6ebf832a974288300224e60bsalomon if (paint) { 3346a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkRect newBounds = bounds; 3347d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed if (matrix) { 3348a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips matrix->mapRect(&newBounds); 3349d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 3350a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips canvas->saveLayer(&newBounds, paint); 335149f085dddff10473b6ebf832a974288300224e60bsalomon } else if (matrix) { 3352d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed canvas->save(); 3353d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 33546cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 335549f085dddff10473b6ebf832a974288300224e60bsalomon if (matrix) { 3356d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed canvas->concat(*matrix); 3357d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 3358d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 3359d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 3360d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedSkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { 3361d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed fCanvas->restoreToCount(fSaveCount); 3362d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 3363e8f3062a36d3682f4019309a32b5b84dc9eddf8creed 336473603f3c52ffd89fe9d035be827b566a0e7d3b79reed///////////////////////////////// 336573603f3c52ffd89fe9d035be827b566a0e7d3b79reed 336673603f3c52ffd89fe9d035be827b566a0e7d3b79reedconst SkCanvas::ClipOp SkCanvas::kDifference_Op; 336773603f3c52ffd89fe9d035be827b566a0e7d3b79reedconst SkCanvas::ClipOp SkCanvas::kIntersect_Op; 336873603f3c52ffd89fe9d035be827b566a0e7d3b79reedconst SkCanvas::ClipOp SkCanvas::kUnion_Op; 336973603f3c52ffd89fe9d035be827b566a0e7d3b79reedconst SkCanvas::ClipOp SkCanvas::kXOR_Op; 337073603f3c52ffd89fe9d035be827b566a0e7d3b79reedconst SkCanvas::ClipOp SkCanvas::kReverseDifference_Op; 337173603f3c52ffd89fe9d035be827b566a0e7d3b79reedconst SkCanvas::ClipOp SkCanvas::kReplace_Op; 337273603f3c52ffd89fe9d035be827b566a0e7d3b79reed 337373603f3c52ffd89fe9d035be827b566a0e7d3b79reedstatic_assert((int)SkRegion::kDifference_Op == (int)kDifference_SkClipOp, ""); 337473603f3c52ffd89fe9d035be827b566a0e7d3b79reedstatic_assert((int)SkRegion::kIntersect_Op == (int)kIntersect_SkClipOp, ""); 337573603f3c52ffd89fe9d035be827b566a0e7d3b79reedstatic_assert((int)SkRegion::kUnion_Op == (int)kUnion_SkClipOp, ""); 337673603f3c52ffd89fe9d035be827b566a0e7d3b79reedstatic_assert((int)SkRegion::kXOR_Op == (int)kXOR_SkClipOp, ""); 337773603f3c52ffd89fe9d035be827b566a0e7d3b79reedstatic_assert((int)SkRegion::kReverseDifference_Op == (int)kReverseDifference_SkClipOp, ""); 337873603f3c52ffd89fe9d035be827b566a0e7d3b79reedstatic_assert((int)SkRegion::kReplace_Op == (int)kReplace_SkClipOp, ""); 3379