SkCanvas.cpp revision fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2c
18a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2008 The Android Open Source Project 38a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 68a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8d3ebb48320cf1b7e969974673e4bd7743816985ebungeman#include "SkBitmapDevice.h" 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h" 10d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed#include "SkCanvasPriv.h" 11d3ebb48320cf1b7e969974673e4bd7743816985ebungeman#include "SkClipStack.h" 12dbc3cefb0b624808ddb86d444e6103f216e12fa5reed#include "SkColorFilter.h" 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDraw.h" 143cb3840c9af6f70896cf5565a38d4ee03c02d767reed#include "SkDrawable.h" 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDrawFilter.h" 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDrawLooper.h" 175f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt#include "SkErrorInternals.h" 18b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr#include "SkImage.h" 19262a71b7f95ce98ff3dd8dba845afbd724470903reed#include "SkImage_Base.h" 20900c36779610dc65c42a5004ee3693fd70961ba4senorblanco#include "SkImageFilter.h" 21900c36779610dc65c42a5004ee3693fd70961ba4senorblanco#include "SkImageFilterCache.h" 22c573a40ed5024b463e47088d307e3164a486dba5msarett#include "SkLatticeIter.h" 23262a71b7f95ce98ff3dd8dba845afbd724470903reed#include "SkMatrixUtils.h" 2474bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org#include "SkMetaData.h" 25fbfa25802709139c2f14e304319c9541da65ca27msarett#include "SkNx.h" 26c83a29759a5c2966da5ab973e4fd90763e4c962breed#include "SkPaintPriv.h" 27b3c9d1c33caf325aada244204215eb790c228c12dandov#include "SkPatchUtils.h" 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPicture.h" 29b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack#include "SkRadialShadowMapShader.h" 300017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com#include "SkRasterClip.h" 3196472deea70169396b8e1f576e470138f55fdb1freed#include "SkReadPixelsRec.h" 324ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com#include "SkRRect.h" 33904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack#include "SkShadowPaintFilterCanvas.h" 34904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack#include "SkShadowShader.h" 3579fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org#include "SkSmallAllocator.h" 364418dbac3386f26c8da62ab242be9c178961eb18robertphillips#include "SkSpecialImage.h" 3797af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com#include "SkSurface_Base.h" 387ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita#include "SkTextBlob.h" 3952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com#include "SkTextFormatParams.h" 40a076e9be17654a60310e72c4f70fcd5337f56dbfreed@google.com#include "SkTLazy.h" 418f757f540a8378c7b1354aab3d4650eaa920b17adanakj#include "SkTraceEvent.h" 42d3ebb48320cf1b7e969974673e4bd7743816985ebungeman#include <new> 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 44644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#if SK_SUPPORT_GPU 457354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips#include "GrContext.h" 46644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#include "GrRenderTarget.h" 47614d8f9a3c44e22d77fa909e82119e8a6746e1b1bsalomon#include "SkGrPriv.h" 48e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack 49644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#endif 50644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org 51e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed#define RETURN_ON_NULL(ptr) do { if (nullptr == (ptr)) return; } while (0) 52e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed 532d1afab8ef2db8b4f0bdab387b0e42ccee1db64freed//#define SK_SUPPORT_PRECHECK_CLIPRECT 542d1afab8ef2db8b4f0bdab387b0e42ccee1db64freed 55c83a29759a5c2966da5ab973e4fd90763e4c962breed/* 56c83a29759a5c2966da5ab973e4fd90763e4c962breed * Return true if the drawing this rect would hit every pixels in the canvas. 57c83a29759a5c2966da5ab973e4fd90763e4c962breed * 58c83a29759a5c2966da5ab973e4fd90763e4c962breed * Returns false if 59c83a29759a5c2966da5ab973e4fd90763e4c962breed * - rect does not contain the canvas' bounds 60c83a29759a5c2966da5ab973e4fd90763e4c962breed * - paint is not fill 61c83a29759a5c2966da5ab973e4fd90763e4c962breed * - paint would blur or otherwise change the coverage of the rect 62c83a29759a5c2966da5ab973e4fd90763e4c962breed */ 63c83a29759a5c2966da5ab973e4fd90763e4c962breedbool SkCanvas::wouldOverwriteEntireSurface(const SkRect* rect, const SkPaint* paint, 64c83a29759a5c2966da5ab973e4fd90763e4c962breed ShaderOverrideOpacity overrideOpacity) const { 6599fe82260633fcf5d92cca38d12ef0937ecca61cbungeman static_assert((int)SkPaintPriv::kNone_ShaderOverrideOpacity == 6699fe82260633fcf5d92cca38d12ef0937ecca61cbungeman (int)kNone_ShaderOverrideOpacity, 6799fe82260633fcf5d92cca38d12ef0937ecca61cbungeman "need_matching_enums0"); 6899fe82260633fcf5d92cca38d12ef0937ecca61cbungeman static_assert((int)SkPaintPriv::kOpaque_ShaderOverrideOpacity == 6999fe82260633fcf5d92cca38d12ef0937ecca61cbungeman (int)kOpaque_ShaderOverrideOpacity, 7099fe82260633fcf5d92cca38d12ef0937ecca61cbungeman "need_matching_enums1"); 7199fe82260633fcf5d92cca38d12ef0937ecca61cbungeman static_assert((int)SkPaintPriv::kNotOpaque_ShaderOverrideOpacity == 7299fe82260633fcf5d92cca38d12ef0937ecca61cbungeman (int)kNotOpaque_ShaderOverrideOpacity, 7399fe82260633fcf5d92cca38d12ef0937ecca61cbungeman "need_matching_enums2"); 74c83a29759a5c2966da5ab973e4fd90763e4c962breed 75c83a29759a5c2966da5ab973e4fd90763e4c962breed const SkISize size = this->getBaseLayerSize(); 76c83a29759a5c2966da5ab973e4fd90763e4c962breed const SkRect bounds = SkRect::MakeIWH(size.width(), size.height()); 77c83a29759a5c2966da5ab973e4fd90763e4c962breed if (!this->getClipStack()->quickContains(bounds)) { 78c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; 79c83a29759a5c2966da5ab973e4fd90763e4c962breed } 80c83a29759a5c2966da5ab973e4fd90763e4c962breed 81c83a29759a5c2966da5ab973e4fd90763e4c962breed if (rect) { 82c5769b2e49a63516f313f42969983f2b9e4d59e0halcanary if (!this->getTotalMatrix().isScaleTranslate()) { 83c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; // conservative 84c83a29759a5c2966da5ab973e4fd90763e4c962breed } 85c5769b2e49a63516f313f42969983f2b9e4d59e0halcanary 86c5769b2e49a63516f313f42969983f2b9e4d59e0halcanary SkRect devRect; 87c5769b2e49a63516f313f42969983f2b9e4d59e0halcanary this->getTotalMatrix().mapRectScaleTranslate(&devRect, *rect); 88c5769b2e49a63516f313f42969983f2b9e4d59e0halcanary if (!devRect.contains(bounds)) { 89c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; 90c83a29759a5c2966da5ab973e4fd90763e4c962breed } 91c83a29759a5c2966da5ab973e4fd90763e4c962breed } 92c83a29759a5c2966da5ab973e4fd90763e4c962breed 93c83a29759a5c2966da5ab973e4fd90763e4c962breed if (paint) { 94c83a29759a5c2966da5ab973e4fd90763e4c962breed SkPaint::Style paintStyle = paint->getStyle(); 95c83a29759a5c2966da5ab973e4fd90763e4c962breed if (!(paintStyle == SkPaint::kFill_Style || 96c83a29759a5c2966da5ab973e4fd90763e4c962breed paintStyle == SkPaint::kStrokeAndFill_Style)) { 97c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; 98c83a29759a5c2966da5ab973e4fd90763e4c962breed } 99c83a29759a5c2966da5ab973e4fd90763e4c962breed if (paint->getMaskFilter() || paint->getLooper() 100c83a29759a5c2966da5ab973e4fd90763e4c962breed || paint->getPathEffect() || paint->getImageFilter()) { 101c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; // conservative 102c83a29759a5c2966da5ab973e4fd90763e4c962breed } 103c83a29759a5c2966da5ab973e4fd90763e4c962breed } 104c83a29759a5c2966da5ab973e4fd90763e4c962breed return SkPaintPriv::Overwrites(paint, (SkPaintPriv::ShaderOverrideOpacity)overrideOpacity); 105c83a29759a5c2966da5ab973e4fd90763e4c962breed} 106c83a29759a5c2966da5ab973e4fd90763e4c962breed 107c83a29759a5c2966da5ab973e4fd90763e4c962breed/////////////////////////////////////////////////////////////////////////////////////////////////// 108c83a29759a5c2966da5ab973e4fd90763e4c962breed 109d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareedstatic bool gIgnoreSaveLayerBounds; 110d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareedvoid SkCanvas::Internal_Private_SetIgnoreSaveLayerBounds(bool ignore) { 111d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed gIgnoreSaveLayerBounds = ignore; 112d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed} 113d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareedbool SkCanvas::Internal_Private_GetIgnoreSaveLayerBounds() { 114d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed return gIgnoreSaveLayerBounds; 115d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed} 116d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed 1170acf1b4b3645772d220c720313821bac389751b5reedstatic bool gTreatSpriteAsBitmap; 1180acf1b4b3645772d220c720313821bac389751b5reedvoid SkCanvas::Internal_Private_SetTreatSpriteAsBitmap(bool spriteAsBitmap) { 1190acf1b4b3645772d220c720313821bac389751b5reed gTreatSpriteAsBitmap = spriteAsBitmap; 1200acf1b4b3645772d220c720313821bac389751b5reed} 1210acf1b4b3645772d220c720313821bac389751b5reedbool SkCanvas::Internal_Private_GetTreatSpriteAsBitmap() { 1220acf1b4b3645772d220c720313821bac389751b5reed return gTreatSpriteAsBitmap; 1230acf1b4b3645772d220c720313821bac389751b5reed} 1240acf1b4b3645772d220c720313821bac389751b5reed 125da17f758442f16747af39f8fbaed9c097048519creed@google.com// experimental for faster tiled drawing... 126da17f758442f16747af39f8fbaed9c097048519creed@google.com//#define SK_ENABLE_CLIP_QUICKREJECT 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//#define SK_TRACE_SAVERESTORE 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_TRACE_SAVERESTORE 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gLayerCounter; 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_layer() { ++gLayerCounter; printf("----- inc layer %d\n", gLayerCounter); } 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_layer() { --gLayerCounter; printf("----- dec layer %d\n", gLayerCounter); } 1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gRecCounter; 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_rec() { ++gRecCounter; printf("----- inc rec %d\n", gRecCounter); } 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_rec() { --gRecCounter; printf("----- dec rec %d\n", gRecCounter); } 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gCanvasCounter; 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_canvas() { ++gCanvasCounter; printf("----- inc canvas %d\n", gCanvasCounter); } 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_canvas() { --gCanvasCounter; printf("----- dec canvas %d\n", gCanvasCounter); } 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else 1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_layer() 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_layer() 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_rec() 1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_rec() 1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_canvas() 1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_canvas() 1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1502c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.orgtypedef SkTLazy<SkPaint> SkLazyPaint; 1512c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org 152c83a29759a5c2966da5ab973e4fd90763e4c962breedvoid SkCanvas::predrawNotify(bool willOverwritesEntireSurface) { 15397af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com if (fSurfaceBase) { 154c83a29759a5c2966da5ab973e4fd90763e4c962breed fSurfaceBase->aboutToDraw(willOverwritesEntireSurface 155c83a29759a5c2966da5ab973e4fd90763e4c962breed ? SkSurface::kDiscard_ContentChangeMode 156c83a29759a5c2966da5ab973e4fd90763e4c962breed : SkSurface::kRetain_ContentChangeMode); 157c83a29759a5c2966da5ab973e4fd90763e4c962breed } 158c83a29759a5c2966da5ab973e4fd90763e4c962breed} 159c83a29759a5c2966da5ab973e4fd90763e4c962breed 160c83a29759a5c2966da5ab973e4fd90763e4c962breedvoid SkCanvas::predrawNotify(const SkRect* rect, const SkPaint* paint, 161c83a29759a5c2966da5ab973e4fd90763e4c962breed ShaderOverrideOpacity overrideOpacity) { 162c83a29759a5c2966da5ab973e4fd90763e4c962breed if (fSurfaceBase) { 163c83a29759a5c2966da5ab973e4fd90763e4c962breed SkSurface::ContentChangeMode mode = SkSurface::kRetain_ContentChangeMode; 164c83a29759a5c2966da5ab973e4fd90763e4c962breed // Since willOverwriteAllPixels() may not be complete free to call, we only do so if 165c83a29759a5c2966da5ab973e4fd90763e4c962breed // there is an outstanding snapshot, since w/o that, there will be no copy-on-write 166c83a29759a5c2966da5ab973e4fd90763e4c962breed // and therefore we don't care which mode we're in. 167c83a29759a5c2966da5ab973e4fd90763e4c962breed // 168c83a29759a5c2966da5ab973e4fd90763e4c962breed if (fSurfaceBase->outstandingImageSnapshot()) { 169c83a29759a5c2966da5ab973e4fd90763e4c962breed if (this->wouldOverwriteEntireSurface(rect, paint, overrideOpacity)) { 170c83a29759a5c2966da5ab973e4fd90763e4c962breed mode = SkSurface::kDiscard_ContentChangeMode; 171c83a29759a5c2966da5ab973e4fd90763e4c962breed } 172c83a29759a5c2966da5ab973e4fd90763e4c962breed } 173c83a29759a5c2966da5ab973e4fd90763e4c962breed fSurfaceBase->aboutToDraw(mode); 17497af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com } 17597af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com} 17697af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com 1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1791f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com/* This is the record we keep for each SkBaseDevice that the user installs. 1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com The clip/matrix/proc are fields that reflect the top of the save/restore 1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stack. Whenever the canvas changes, it marks a dirty flag, and then before 1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com these are used (assuming we're not on a layer) we rebuild these cache 1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com values: they reflect the top of the save stack, but translated and clipped 1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com by the device's XY offset and bitmap-bounds. 1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct DeviceCM { 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* fNext; 1881f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* fDevice; 189045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com SkRasterClip fClip; 1906f8f292aa768869a9e85c314b124875f57504f2creed@google.com SkPaint* fPaint; // may be null (in the future) 19161f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed const SkMatrix* fMatrix; 19261f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed SkMatrix fMatrixStorage; 1938c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkMatrix fStashedMatrix; // original CTM; used by imagefilter in saveLayer 1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19596e657d0e103b8358a77ecd913f6086929f792b8reed DeviceCM(SkBaseDevice* device, const SkPaint* paint, SkCanvas* canvas, 1967503d60847c4ad22df87458aecd917772b23d293reed bool conservativeRasterClip, const SkMatrix& stashed) 19796fcdcc219d2a0d3579719b84b28bede76efba64halcanary : fNext(nullptr) 198d954498c01ccf0417feacf89e45d0c62a06a813breed , fClip(conservativeRasterClip) 1998c30a8196dd5903d2d23b4d0a5dc888e802bf698reed , fStashedMatrix(stashed) 200d954498c01ccf0417feacf89e45d0c62a06a813breed { 2012c9e20055be772feb3f44986c1af0c0a979eff49reed SkSafeRef(device); 2024b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com fDevice = device; 20396fcdcc219d2a0d3579719b84b28bede76efba64halcanary fPaint = paint ? new SkPaint(*paint) : nullptr; 20488edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20688edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com ~DeviceCM() { 2072c9e20055be772feb3f44986c1af0c0a979eff49reed SkSafeUnref(fDevice); 208385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete fPaint; 20988edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 2104b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 211feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein void reset(const SkIRect& bounds) { 212feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(!fPaint); 213feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(!fNext); 214feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(fDevice); 215feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fClip.setRect(bounds); 216feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein } 217feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 218045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com void updateMC(const SkMatrix& totalMatrix, const SkRasterClip& totalClip, 219de6c531e468197bb7746f1217a8ccb2ab175e0b8reed SkRasterClip* updateClip) { 2206f8f292aa768869a9e85c314b124875f57504f2creed@google.com int x = fDevice->getOrigin().x(); 2216f8f292aa768869a9e85c314b124875f57504f2creed@google.com int y = fDevice->getOrigin().y(); 2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int width = fDevice->width(); 2238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int height = fDevice->height(); 2244b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if ((x | y) == 0) { 2268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = &totalMatrix; 2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fClip = totalClip; 2288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrixStorage = totalMatrix; 2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrixStorage.postTranslate(SkIntToScalar(-x), 2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIntToScalar(-y)); 2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = &fMatrixStorage; 2334b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com totalClip.translate(-x, -y, &fClip); 2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 237045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com fClip.op(SkIRect::MakeWH(width, height), SkRegion::kIntersect_Op); 2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // intersect clip, but don't translate it (yet) 2404b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (updateClip) { 242045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com updateClip->op(SkIRect::MakeXYWH(x, y, width, height), 2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRegion::kDifference_Op); 2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2454b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!fClip.isEmpty()) { 2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIRect deviceR; 2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com deviceR.set(0, 0, width, height); 2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(deviceR.contains(fClip.getBounds())); 2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 253f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* This is the record we keep for each save/restore level in the stack. 2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Since a level optionally copies the matrix and/or stack, we have pointers 2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for these fields. If the value is copied for this level, the copy is 2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stored in the ...Storage field, and the pointer points to that. If the 2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value is not copied for this level, we ignore ...Storage, and just point 2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com at the corresponding value in the previous level in the stack. 2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkCanvas::MCRec { 2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 2651f836ee096bb988adef4b9757b2629c7afeda36dreed SkDrawFilter* fFilter; // the current filter (or null) 266d954498c01ccf0417feacf89e45d0c62a06a813breed DeviceCM* fLayer; 2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* If there are any layers in the stack, this points to the top-most 2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com one that is at or below this level in the stack (so we know what 2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bitmap/device to draw into from this level. This value is NOT 2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com reference counted, since the real owner is either our fLayer field, 2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com or a previous one in a lower level.) 2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 2732ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed DeviceCM* fTopLayer; 2742ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkRasterClip fRasterClip; 2752ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkMatrix fMatrix; 2762ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed int fDeferredSaveCount; 2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 278e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack // This is the current cumulative depth (aggregate of all done translateZ calls) 279e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack SkScalar fCurDrawDepth; 280e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack 281d954498c01ccf0417feacf89e45d0c62a06a813breed MCRec(bool conservativeRasterClip) : fRasterClip(conservativeRasterClip) { 28296fcdcc219d2a0d3579719b84b28bede76efba64halcanary fFilter = nullptr; 28396fcdcc219d2a0d3579719b84b28bede76efba64halcanary fLayer = nullptr; 28496fcdcc219d2a0d3579719b84b28bede76efba64halcanary fTopLayer = nullptr; 2852ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fMatrix.reset(); 2862ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fDeferredSaveCount = 0; 287e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack fCurDrawDepth = 0; 288b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 289d954498c01ccf0417feacf89e45d0c62a06a813breed // don't bother initializing fNext 290d954498c01ccf0417feacf89e45d0c62a06a813breed inc_rec(); 291d954498c01ccf0417feacf89e45d0c62a06a813breed } 292e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack MCRec(const MCRec& prev) : fRasterClip(prev.fRasterClip), fMatrix(prev.fMatrix), 293e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack fCurDrawDepth(prev.fCurDrawDepth) { 294d954498c01ccf0417feacf89e45d0c62a06a813breed fFilter = SkSafeRef(prev.fFilter); 29596fcdcc219d2a0d3579719b84b28bede76efba64halcanary fLayer = nullptr; 296d954498c01ccf0417feacf89e45d0c62a06a813breed fTopLayer = prev.fTopLayer; 2972ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fDeferredSaveCount = 0; 298b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 2998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // don't bother initializing fNext 3008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inc_rec(); 3018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ~MCRec() { 30382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fFilter); 304385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete fLayer; 3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dec_rec(); 3068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 307feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 308feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein void reset(const SkIRect& bounds) { 309feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(fLayer); 310feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(fDeferredSaveCount == 0); 311feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 312feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fMatrix.reset(); 313feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fRasterClip.setRect(bounds); 314feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fLayer->reset(bounds); 315feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein } 3168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 31802f9ed74ead11fcb01a24faa7d93f853e869f1abreedstatic SkIRect compute_device_bounds(SkBaseDevice* device) { 31902f9ed74ead11fcb01a24faa7d93f853e869f1abreed return SkIRect::MakeXYWH(device->getOrigin().x(), device->getOrigin().y(), 32002f9ed74ead11fcb01a24faa7d93f853e869f1abreed device->width(), device->height()); 32102f9ed74ead11fcb01a24faa7d93f853e869f1abreed} 32202f9ed74ead11fcb01a24faa7d93f853e869f1abreed 3238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkDrawIter : public SkDraw { 3248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 3253aafe111b6cc388400092851cc53bbbdfcb8a81creed SkDrawIter(SkCanvas* canvas) { 3264370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com canvas = canvas->canvasForDrawIter(); 3278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com canvas->updateDeviceCMCache(); 3288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 329687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack = canvas->fClipStack; 3308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = canvas->fMCRec->fTopLayer; 33102f9ed74ead11fcb01a24faa7d93f853e869f1abreed 33202f9ed74ead11fcb01a24faa7d93f853e869f1abreed fMultiDeviceCS = nullptr; 33302f9ed74ead11fcb01a24faa7d93f853e869f1abreed if (fCurrLayer->fNext) { 33402f9ed74ead11fcb01a24faa7d93f853e869f1abreed fMultiDeviceCS = canvas->fClipStack; 33502f9ed74ead11fcb01a24faa7d93f853e869f1abreed fMultiDeviceCS->save(); 33602f9ed74ead11fcb01a24faa7d93f853e869f1abreed } 33702f9ed74ead11fcb01a24faa7d93f853e869f1abreed } 33802f9ed74ead11fcb01a24faa7d93f853e869f1abreed 33902f9ed74ead11fcb01a24faa7d93f853e869f1abreed ~SkDrawIter() { 34002f9ed74ead11fcb01a24faa7d93f853e869f1abreed if (fMultiDeviceCS) { 34102f9ed74ead11fcb01a24faa7d93f853e869f1abreed fMultiDeviceCS->restore(); 34202f9ed74ead11fcb01a24faa7d93f853e869f1abreed } 3438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3444b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 3458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool next() { 34602f9ed74ead11fcb01a24faa7d93f853e869f1abreed if (fMultiDeviceCS && fDevice) { 34702f9ed74ead11fcb01a24faa7d93f853e869f1abreed // remove the previous device's bounds 34802f9ed74ead11fcb01a24faa7d93f853e869f1abreed fMultiDeviceCS->clipDevRect(compute_device_bounds(fDevice), 34902f9ed74ead11fcb01a24faa7d93f853e869f1abreed SkRegion::kDifference_Op); 35002f9ed74ead11fcb01a24faa7d93f853e869f1abreed } 35102f9ed74ead11fcb01a24faa7d93f853e869f1abreed 3528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // skip over recs with empty clips 3533aafe111b6cc388400092851cc53bbbdfcb8a81creed while (fCurrLayer && fCurrLayer->fClip.isEmpty()) { 3543aafe111b6cc388400092851cc53bbbdfcb8a81creed fCurrLayer = fCurrLayer->fNext; 3558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 357f68c5e2f9f05b3af2bae0979ace2684b6041b6e3reed@google.com const DeviceCM* rec = fCurrLayer; 358f68c5e2f9f05b3af2bae0979ace2684b6041b6e3reed@google.com if (rec && rec->fDevice) { 3598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = rec->fMatrix; 361045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com fRC = &rec->fClip; 3628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDevice = rec->fDevice; 36341e010cb901c0da9066c4df562030808c9ccd7f8reed if (!fDevice->accessPixels(&fDst)) { 36496fcdcc219d2a0d3579719b84b28bede76efba64halcanary fDst.reset(fDevice->imageInfo(), nullptr, 0); 36541e010cb901c0da9066c4df562030808c9ccd7f8reed } 3668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint = rec->fPaint; 367f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com SkDEBUGCODE(this->validate();) 3688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = rec->fNext; 37096fcdcc219d2a0d3579719b84b28bede76efba64halcanary // fCurrLayer may be nullptr now 371199f108f14a5f60a9c2205ffa79b26102a206ad0reed@android.com 3728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 3738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 3758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3764b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 3771f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* getDevice() const { return fDevice; } 3781e7f5e708e5daeb0c18ae49001c9e3cd5e3b13cbreed const SkRasterClip& getClip() const { return *fRC; } 3796f8f292aa768869a9e85c314b124875f57504f2creed@google.com int getX() const { return fDevice->getOrigin().x(); } 3806f8f292aa768869a9e85c314b124875f57504f2creed@google.com int getY() const { return fDevice->getOrigin().y(); } 3818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& getMatrix() const { return *fMatrix; } 3828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* getPaint() const { return fPaint; } 3836f8f292aa768869a9e85c314b124875f57504f2creed@google.com 3848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 3858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const DeviceCM* fCurrLayer; 3868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* fPaint; // May be null. 38702f9ed74ead11fcb01a24faa7d93f853e869f1abreed SkClipStack* fMultiDeviceCS; 3888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef SkDraw INHERITED; 3908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////// 3938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 394dbc3cefb0b624808ddb86d444e6103f216e12fa5reedstatic SkPaint* set_if_needed(SkLazyPaint* lazy, const SkPaint& orig) { 395dbc3cefb0b624808ddb86d444e6103f216e12fa5reed return lazy->isValid() ? lazy->get() : lazy->set(orig); 396dbc3cefb0b624808ddb86d444e6103f216e12fa5reed} 397dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 398dbc3cefb0b624808ddb86d444e6103f216e12fa5reed/** 399dbc3cefb0b624808ddb86d444e6103f216e12fa5reed * If the paint has an imagefilter, but it can be simplified to just a colorfilter, return that 40096fcdcc219d2a0d3579719b84b28bede76efba64halcanary * colorfilter, else return nullptr. 401dbc3cefb0b624808ddb86d444e6103f216e12fa5reed */ 402d053ce9c54d4e5937a142278359e5a4cde18095ereedstatic sk_sp<SkColorFilter> image_to_color_filter(const SkPaint& paint) { 403dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkImageFilter* imgf = paint.getImageFilter(); 404dbc3cefb0b624808ddb86d444e6103f216e12fa5reed if (!imgf) { 40596fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 406dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 407dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 408d053ce9c54d4e5937a142278359e5a4cde18095ereed SkColorFilter* imgCFPtr; 409d053ce9c54d4e5937a142278359e5a4cde18095ereed if (!imgf->asAColorFilter(&imgCFPtr)) { 41096fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 411dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 412d053ce9c54d4e5937a142278359e5a4cde18095ereed sk_sp<SkColorFilter> imgCF(imgCFPtr); 413dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 414dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkColorFilter* paintCF = paint.getColorFilter(); 41596fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paintCF) { 416dbc3cefb0b624808ddb86d444e6103f216e12fa5reed // there is no existing paint colorfilter, so we can just return the imagefilter's 417dbc3cefb0b624808ddb86d444e6103f216e12fa5reed return imgCF; 418dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 419dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 420dbc3cefb0b624808ddb86d444e6103f216e12fa5reed // The paint has both a colorfilter(paintCF) and an imagefilter-which-is-a-colorfilter(imgCF) 421dbc3cefb0b624808ddb86d444e6103f216e12fa5reed // and we need to combine them into a single colorfilter. 422d053ce9c54d4e5937a142278359e5a4cde18095ereed return SkColorFilter::MakeComposeFilter(std::move(imgCF), sk_ref_sp(paintCF)); 423dbc3cefb0b624808ddb86d444e6103f216e12fa5reed} 424dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 42587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco/** 42687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * There are many bounds in skia. A circle's bounds is just its center extended by its radius. 42787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * However, if we stroke a circle, then the "bounds" of that is larger, since it will now draw 42887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * outside of its raw-bounds by 1/2 the stroke width. SkPaint has lots of optional 42987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * effects/attributes that can modify the effective bounds of a given primitive -- maskfilters, 43087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * patheffects, stroking, etc. This function takes a raw bounds and a paint, and returns the 43187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * conservative "effective" bounds based on the settings in the paint... with one exception. This 43287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * function does *not* look at the imagefilter, which can also modify the effective bounds. It is 43387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco * deliberately ignored. 43487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco */ 43587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblancostatic const SkRect& apply_paint_to_bounds_sans_imagefilter(const SkPaint& paint, 43687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco const SkRect& rawBounds, 43787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect* storage) { 43887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkPaint tmpUnfiltered(paint); 43987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco tmpUnfiltered.setImageFilter(nullptr); 44087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (tmpUnfiltered.canComputeFastBounds()) { 44187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return tmpUnfiltered.computeFastBounds(rawBounds, storage); 44287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } else { 44387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return rawBounds; 44487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 44587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco} 44687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco 4478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass AutoDrawLooper { 4488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 44987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco // "rawBounds" is the original bounds of the primitive about to be drawn, unmodified by the 45087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco // paint. It's used to determine the size of the offscreen layer for filters. 45187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco // If null, the clip will be used instead. 4523aafe111b6cc388400092851cc53bbbdfcb8a81creed AutoDrawLooper(SkCanvas* canvas, const SkPaint& paint, bool skipLayerForImageFilter = false, 45387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco const SkRect* rawBounds = nullptr) : fOrigPaint(paint) { 4544e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fCanvas = canvas; 45553d9f1cfbd5ddbf57c2f22b9e613ce48e5b2896cfmalita#ifdef SK_SUPPORT_LEGACY_DRAWFILTER 4568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFilter = canvas->getDrawFilter(); 4577765000709dc64eb23be7df47d1f995d1f787115fmalita#else 4587765000709dc64eb23be7df47d1f995d1f787115fmalita fFilter = nullptr; 4597765000709dc64eb23be7df47d1f995d1f787115fmalita#endif 4604a8126e7f81384526629b1e21bf89b632ea13cd9reed fPaint = &fOrigPaint; 4614e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fSaveCount = canvas->getSaveCount(); 4625c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed fTempLayerForImageFilter = false; 4634e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fDone = false; 4648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 465d053ce9c54d4e5937a142278359e5a4cde18095ereed auto simplifiedCF = image_to_color_filter(fOrigPaint); 466dbc3cefb0b624808ddb86d444e6103f216e12fa5reed if (simplifiedCF) { 467dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkPaint* paint = set_if_needed(&fLazyPaintInit, fOrigPaint); 468d053ce9c54d4e5937a142278359e5a4cde18095ereed paint->setColorFilter(std::move(simplifiedCF)); 46996fcdcc219d2a0d3579719b84b28bede76efba64halcanary paint->setImageFilter(nullptr); 470dbc3cefb0b624808ddb86d444e6103f216e12fa5reed fPaint = paint; 471dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 472dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 473dbc3cefb0b624808ddb86d444e6103f216e12fa5reed if (!skipLayerForImageFilter && fPaint->getImageFilter()) { 4745c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed /** 4755c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * We implement ImageFilters for a given draw by creating a layer, then applying the 4765c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * imagefilter to the pixels of that layer (its backing surface/image), and then 4775c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * we call restore() to xfer that layer to the main canvas. 4785c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 4795c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 1. SaveLayer (with a paint containing the current imagefilter and xfermode) 4805c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 2. Generate the src pixels: 4815c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * Remove the imagefilter and the xfermode from the paint that we (AutoDrawLooper) 4825c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * return (fPaint). We then draw the primitive (using srcover) into a cleared 4835c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * buffer/surface. 4845c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 3. Restore the layer created in #1 4855c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * The imagefilter is passed the buffer/surface from the layer (now filled with the 4865c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * src pixels of the primitive). It returns a new "filtered" buffer, which we 4875c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * draw onto the previous layer using the xfermode from the original paint. 4885c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed */ 4898926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkPaint tmp; 490dbc3cefb0b624808ddb86d444e6103f216e12fa5reed tmp.setImageFilter(fPaint->getImageFilter()); 491cfb6bdf767796c950f89985445738d2d8e7f12b0reed tmp.setXfermode(sk_ref_sp(fPaint->getXfermode())); 49287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect storage; 49387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (rawBounds) { 49487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco // Make rawBounds include all paint outsets except for those due to image filters. 49587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco rawBounds = &apply_paint_to_bounds_sans_imagefilter(*fPaint, *rawBounds, &storage); 49687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 497bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed (void)canvas->internalSaveLayer(SkCanvas::SaveLayerRec(rawBounds, &tmp), 49876033be81b82c44fd5d4fdf2672eb22e505da1f0reed SkCanvas::kFullLayer_SaveLayerStrategy); 4995c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed fTempLayerForImageFilter = true; 5005c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed // we remove the imagefilter/xfermode inside doNext() 5018926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 5028926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 50379fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (SkDrawLooper* looper = paint.getLooper()) { 50479fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org void* buffer = fLooperContextAllocator.reserveT<SkDrawLooper::Context>( 50579fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org looper->contextSize()); 50679fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org fLooperContext = looper->createContext(canvas, buffer); 507129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fIsSimple = false; 508129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else { 50996fcdcc219d2a0d3579719b84b28bede76efba64halcanary fLooperContext = nullptr; 510129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // can we be marked as simple? 5115c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed fIsSimple = !fFilter && !fTempLayerForImageFilter; 5128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 51474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 5154e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com ~AutoDrawLooper() { 5165c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed if (fTempLayerForImageFilter) { 5178926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com fCanvas->internalRestore(); 5188926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 5194e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkASSERT(fCanvas->getSaveCount() == fSaveCount); 5208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 52174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 5224e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com const SkPaint& paint() const { 5234e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkASSERT(fPaint); 5244e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return *fPaint; 5254e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 52674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 527129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool next(SkDrawFilter::Type drawType) { 528129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com if (fDone) { 529129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return false; 530129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else if (fIsSimple) { 531129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fDone = true; 532129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return !fPaint->nothingToDraw(); 533129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else { 534129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return this->doNext(drawType); 535129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 536fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 53774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 5388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 539dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkLazyPaint fLazyPaintInit; // base paint storage in case we need to modify it 540dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkLazyPaint fLazyPaintPerLooper; // per-draw-looper storage, so the looper can modify it 5412c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkCanvas* fCanvas; 5422c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint& fOrigPaint; 5432c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkDrawFilter* fFilter; 5442c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint* fPaint; 5452c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org int fSaveCount; 5465c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed bool fTempLayerForImageFilter; 5472c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org bool fDone; 548129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool fIsSimple; 54979fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkDrawLooper::Context* fLooperContext; 55079fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkSmallAllocator<1, 32> fLooperContextAllocator; 551129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com 552129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool doNext(SkDrawFilter::Type drawType); 5538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 5548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 555129ec22cb054592261e001294c430c9dd4e90ff4reed@google.combool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) { 55696fcdcc219d2a0d3579719b84b28bede76efba64halcanary fPaint = nullptr; 557129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com SkASSERT(!fIsSimple); 5585c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed SkASSERT(fLooperContext || fFilter || fTempLayerForImageFilter); 559632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com 560dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkPaint* paint = fLazyPaintPerLooper.set(fLazyPaintInit.isValid() ? 561dbc3cefb0b624808ddb86d444e6103f216e12fa5reed *fLazyPaintInit.get() : fOrigPaint); 5628926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 5635c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed if (fTempLayerForImageFilter) { 56496fcdcc219d2a0d3579719b84b28bede76efba64halcanary paint->setImageFilter(nullptr); 56596fcdcc219d2a0d3579719b84b28bede76efba64halcanary paint->setXfermode(nullptr); 566129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 5678926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 56879fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (fLooperContext && !fLooperContext->next(fCanvas, paint)) { 569129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fDone = true; 570129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return false; 571129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 572129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com if (fFilter) { 573971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com if (!fFilter->filter(paint, drawType)) { 574971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com fDone = true; 575971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com return false; 576971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com } 57796fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == fLooperContext) { 578129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // no looper means we only draw once 579632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com fDone = true; 580632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com } 581129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 582129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fPaint = paint; 5838926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 584129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // if we only came in here for the imagefilter, mark us as done 58579fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (!fLooperContext && !fFilter) { 5864e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fDone = true; 5874e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 5884e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com 589632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com // call this after any possible paint modifiers 590632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com if (fPaint->nothingToDraw()) { 59196fcdcc219d2a0d3579719b84b28bede76efba64halcanary fPaint = nullptr; 5924e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return false; 5934e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 5944e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return true; 5954e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com} 5964e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com 5978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////// macros to place around the internal draw calls ////////////////// 5988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5993aafe111b6cc388400092851cc53bbbdfcb8a81creed#define LOOPER_BEGIN_DRAWBITMAP(paint, skipLayerForFilter, bounds) \ 6003aafe111b6cc388400092851cc53bbbdfcb8a81creed this->predrawNotify(); \ 6013aafe111b6cc388400092851cc53bbbdfcb8a81creed AutoDrawLooper looper(this, paint, skipLayerForFilter, bounds); \ 6023aafe111b6cc388400092851cc53bbbdfcb8a81creed while (looper.next(SkDrawFilter::kBitmap_Type)) { \ 603262a71b7f95ce98ff3dd8dba845afbd724470903reed SkDrawIter iter(this); 604262a71b7f95ce98ff3dd8dba845afbd724470903reed 605262a71b7f95ce98ff3dd8dba845afbd724470903reed 6068926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com#define LOOPER_BEGIN_DRAWDEVICE(paint, type) \ 60797af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com this->predrawNotify(); \ 6083aafe111b6cc388400092851cc53bbbdfcb8a81creed AutoDrawLooper looper(this, paint, true); \ 6098926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com while (looper.next(type)) { \ 6108926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkDrawIter iter(this); 6118926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 61278cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org#define LOOPER_BEGIN(paint, type, bounds) \ 61397af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com this->predrawNotify(); \ 6143aafe111b6cc388400092851cc53bbbdfcb8a81creed AutoDrawLooper looper(this, paint, false, bounds); \ 6154e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com while (looper.next(type)) { \ 6168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDrawIter iter(this); 6174b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 618c83a29759a5c2966da5ab973e4fd90763e4c962breed#define LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, type, bounds, auxOpaque) \ 619c83a29759a5c2966da5ab973e4fd90763e4c962breed this->predrawNotify(bounds, &paint, auxOpaque); \ 6203aafe111b6cc388400092851cc53bbbdfcb8a81creed AutoDrawLooper looper(this, paint, false, bounds); \ 621c83a29759a5c2966da5ab973e4fd90763e4c962breed while (looper.next(type)) { \ 622c83a29759a5c2966da5ab973e4fd90763e4c962breed SkDrawIter iter(this); 623c83a29759a5c2966da5ab973e4fd90763e4c962breed 6244e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com#define LOOPER_END } 6258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////// 6278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 628fbfa25802709139c2f14e304319c9541da65ca27msarettstatic inline SkRect qr_clip_bounds(const SkIRect& bounds) { 629fbfa25802709139c2f14e304319c9541da65ca27msarett if (bounds.isEmpty()) { 630fbfa25802709139c2f14e304319c9541da65ca27msarett return SkRect::MakeEmpty(); 631fbfa25802709139c2f14e304319c9541da65ca27msarett } 632fbfa25802709139c2f14e304319c9541da65ca27msarett 633fbfa25802709139c2f14e304319c9541da65ca27msarett // Expand bounds out by 1 in case we are anti-aliasing. We store the 634fbfa25802709139c2f14e304319c9541da65ca27msarett // bounds as floats to enable a faster quick reject implementation. 635fbfa25802709139c2f14e304319c9541da65ca27msarett SkRect dst; 636fbfa25802709139c2f14e304319c9541da65ca27msarett SkNx_cast<float>(Sk4i::Load(&bounds.fLeft) + Sk4i(-1,-1,1,1)).store(&dst.fLeft); 637fbfa25802709139c2f14e304319c9541da65ca27msarett return dst; 638fbfa25802709139c2f14e304319c9541da65ca27msarett} 639fbfa25802709139c2f14e304319c9541da65ca27msarett 640feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtkleinvoid SkCanvas::resetForNextPicture(const SkIRect& bounds) { 641feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein this->restoreToCount(1); 642feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fClipStack->reset(); 643feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fMCRec->reset(bounds); 644feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 645feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein // We're peering through a lot of structs here. Only at this scope do we 646feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein // know that the device is an SkBitmapDevice (really an SkNoPixelsBitmapDevice). 647feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein static_cast<SkBitmapDevice*>(fMCRec->fLayer->fDevice)->setNewSize(bounds.size()); 648fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(bounds); 6499637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett fIsScaleTranslate = true; 650feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein} 651feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 652d954498c01ccf0417feacf89e45d0c62a06a813breedSkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) { 65342b73eb00367c8315974b1c374308d20efa78897reed if (device && device->forceConservativeRasterClip()) { 65442b73eb00367c8315974b1c374308d20efa78897reed flags = InitFlags(flags | kConservativeRasterClip_InitFlag); 65542b73eb00367c8315974b1c374308d20efa78897reed } 65642b73eb00367c8315974b1c374308d20efa78897reed // Since init() is only called once by our constructors, it is safe to perform this 65742b73eb00367c8315974b1c374308d20efa78897reed // const-cast. 65842b73eb00367c8315974b1c374308d20efa78897reed *const_cast<bool*>(&fConservativeRasterClip) = SkToBool(flags & kConservativeRasterClip_InitFlag); 65942b73eb00367c8315974b1c374308d20efa78897reed 6608f0a7b8e7334187a5d7d5ab7fde5a3c3009555f5caryclark@google.com fAllowSoftClip = true; 66145a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com fAllowSimplifyClip = false; 662f92c86642a1875da54d54b447f006cb9dfbbb35creed fDeviceCMDirty = true; 6632ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount = 1; 66496fcdcc219d2a0d3579719b84b28bede76efba64halcanary fMetaData = nullptr; 66595302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack#ifdef SK_EXPERIMENTAL_SHADOWING 66695302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack fLights = nullptr; 66795302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack#endif 6688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 669385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary fClipStack.reset(new SkClipStack); 670687fa1c745febb57f42b0d5f03d7c1f4be2530careed 6718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = (MCRec*)fMCStack.push_back(); 672d954498c01ccf0417feacf89e45d0c62a06a813breed new (fMCRec) MCRec(fConservativeRasterClip); 6739637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett fIsScaleTranslate = true; 6748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 675a499f905e9340e4935447f2562fd92e8853382b1reed SkASSERT(sizeof(DeviceCM) <= sizeof(fDeviceCMStorage)); 676a499f905e9340e4935447f2562fd92e8853382b1reed fMCRec->fLayer = (DeviceCM*)fDeviceCMStorage; 6777503d60847c4ad22df87458aecd917772b23d293reed new (fDeviceCMStorage) DeviceCM(nullptr, nullptr, nullptr, fConservativeRasterClip, 6788c30a8196dd5903d2d23b4d0a5dc888e802bf698reed fMCRec->fMatrix); 679b679ca8926a832274b14fdb512f88f64b61d32eareed 6808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fTopLayer = fMCRec->fLayer; 6818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 68296fcdcc219d2a0d3579719b84b28bede76efba64halcanary fSurfaceBase = nullptr; 683f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 684f92c86642a1875da54d54b447f006cb9dfbbb35creed if (device) { 685efbffedd68636e94d4379e84a2585bce80f6fb8frobertphillips // The root device and the canvas should always have the same pixel geometry 686efbffedd68636e94d4379e84a2585bce80f6fb8frobertphillips SkASSERT(fProps.pixelGeometry() == device->surfaceProps().pixelGeometry()); 687f92c86642a1875da54d54b447f006cb9dfbbb35creed fMCRec->fLayer->fDevice = SkRef(device); 68878e276889795454891cbba48ab11927968114953reed fMCRec->fRasterClip.setRect(device->getGlobalBounds()); 689fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(device->getGlobalBounds()); 690f92c86642a1875da54d54b447f006cb9dfbbb35creed } 691fbfa25802709139c2f14e304319c9541da65ca27msarett 692f92c86642a1875da54d54b447f006cb9dfbbb35creed return device; 6938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 695cde92111d50a96b6d0f3e166fbac7c9bc6eca349reed@google.comSkCanvas::SkCanvas() 696e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 6974a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 69842b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 699e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org{ 7008d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org inc_canvas(); 701ba124485687130183643994f1b4b68d629fbbebaskia.committer@gmail.com 70296fcdcc219d2a0d3579719b84b28bede76efba64halcanary this->init(nullptr, kDefault_InitFlags); 7038d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org} 7048d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org 705d954498c01ccf0417feacf89e45d0c62a06a813breedstatic SkBitmap make_nopixels(int width, int height) { 706d954498c01ccf0417feacf89e45d0c62a06a813breed SkBitmap bitmap; 707d954498c01ccf0417feacf89e45d0c62a06a813breed bitmap.setInfo(SkImageInfo::MakeUnknown(width, height)); 708d954498c01ccf0417feacf89e45d0c62a06a813breed return bitmap; 709d954498c01ccf0417feacf89e45d0c62a06a813breed} 710d954498c01ccf0417feacf89e45d0c62a06a813breed 711d954498c01ccf0417feacf89e45d0c62a06a813breedclass SkNoPixelsBitmapDevice : public SkBitmapDevice { 712d954498c01ccf0417feacf89e45d0c62a06a813breedpublic: 713fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips SkNoPixelsBitmapDevice(const SkIRect& bounds, const SkSurfaceProps& surfaceProps) 714fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips : INHERITED(make_nopixels(bounds.width(), bounds.height()), surfaceProps) 71578e276889795454891cbba48ab11927968114953reed { 71678e276889795454891cbba48ab11927968114953reed this->setOrigin(bounds.x(), bounds.y()); 71778e276889795454891cbba48ab11927968114953reed } 718d954498c01ccf0417feacf89e45d0c62a06a813breed 719d954498c01ccf0417feacf89e45d0c62a06a813breedprivate: 720b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 721d954498c01ccf0417feacf89e45d0c62a06a813breed typedef SkBitmapDevice INHERITED; 722d954498c01ccf0417feacf89e45d0c62a06a813breed}; 723d954498c01ccf0417feacf89e45d0c62a06a813breed 72496a857ef5a40b3d0751ec9ebaaa96d9f20b82b21reedSkCanvas::SkCanvas(int width, int height, const SkSurfaceProps* props) 725e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 72696a857ef5a40b3d0751ec9ebaaa96d9f20b82b21reed , fProps(SkSurfacePropsCopyOrDefault(props)) 72742b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 728e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org{ 729e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org inc_canvas(); 730b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 731385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary this->init(new SkNoPixelsBitmapDevice(SkIRect::MakeWH(width, height), fProps), 732385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary kDefault_InitFlags)->unref(); 733d954498c01ccf0417feacf89e45d0c62a06a813breed} 734e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org 73578e276889795454891cbba48ab11927968114953reedSkCanvas::SkCanvas(const SkIRect& bounds, InitFlags flags) 736d954498c01ccf0417feacf89e45d0c62a06a813breed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7374a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 73842b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 739d954498c01ccf0417feacf89e45d0c62a06a813breed{ 740d954498c01ccf0417feacf89e45d0c62a06a813breed inc_canvas(); 741b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 742385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary this->init(new SkNoPixelsBitmapDevice(bounds, fProps), flags)->unref(); 74327a5e656c3d6ef22f9cb34de18e1b960da3aa241reed} 7448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 745d954498c01ccf0417feacf89e45d0c62a06a813breedSkCanvas::SkCanvas(SkBaseDevice* device) 746d954498c01ccf0417feacf89e45d0c62a06a813breed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7477b05ff11ebc51f3f3abd1c1756337a04f563537erobertphillips , fProps(device->surfaceProps()) 74842b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 749d954498c01ccf0417feacf89e45d0c62a06a813breed{ 750d954498c01ccf0417feacf89e45d0c62a06a813breed inc_canvas(); 751b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 752d954498c01ccf0417feacf89e45d0c62a06a813breed this->init(device, kDefault_InitFlags); 7538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 755fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillipsSkCanvas::SkCanvas(SkBaseDevice* device, InitFlags flags) 756fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7577b05ff11ebc51f3f3abd1c1756337a04f563537erobertphillips , fProps(device->surfaceProps()) 75842b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 759fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips{ 760fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips inc_canvas(); 761fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips 762fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips this->init(device, flags); 763fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips} 764fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips 7654a8126e7f81384526629b1e21bf89b632ea13cd9reedSkCanvas::SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props) 7663716fd067a5621bb94a6cb08d72afec8bf3acedareed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7674a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(props) 76842b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 7693716fd067a5621bb94a6cb08d72afec8bf3acedareed{ 7703716fd067a5621bb94a6cb08d72afec8bf3acedareed inc_canvas(); 771b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 772385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary SkAutoTUnref<SkBaseDevice> device(new SkBitmapDevice(bitmap, fProps)); 7734a8126e7f81384526629b1e21bf89b632ea13cd9reed this->init(device, kDefault_InitFlags); 7744a8126e7f81384526629b1e21bf89b632ea13cd9reed} 77529c857d0f3a1cb837f73406eeb6ba9771879b5e7reed 7764a8126e7f81384526629b1e21bf89b632ea13cd9reedSkCanvas::SkCanvas(const SkBitmap& bitmap) 7774a8126e7f81384526629b1e21bf89b632ea13cd9reed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7784a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 77942b73eb00367c8315974b1c374308d20efa78897reed , fConservativeRasterClip(false) 7804a8126e7f81384526629b1e21bf89b632ea13cd9reed{ 7814a8126e7f81384526629b1e21bf89b632ea13cd9reed inc_canvas(); 782b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 783385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary SkAutoTUnref<SkBaseDevice> device(new SkBitmapDevice(bitmap, fProps)); 7844a8126e7f81384526629b1e21bf89b632ea13cd9reed this->init(device, kDefault_InitFlags); 7858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::~SkCanvas() { 7888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // free up the contents of our deque 7898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->restoreToCount(1); // restore everything but the last 7907c2029367cea5479fa3b74fb0ca2b0297b42b709reed@google.com 7918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->internalRestore(); // restore the last, since we're going away 7928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 793385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete fMetaData; 794b70ae310bbdaa1b26786773aabce5548c1f48563vandebo@chromium.org 7958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dec_canvas(); 7968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 79853d9f1cfbd5ddbf57c2f22b9e613ce48e5b2896cfmalita#ifdef SK_SUPPORT_LEGACY_DRAWFILTER 7998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDrawFilter* SkCanvas::getDrawFilter() const { 8008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fMCRec->fFilter; 8018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDrawFilter* SkCanvas::setDrawFilter(SkDrawFilter* filter) { 80451985e3f5e608d369e52832b7ce489d85d402422reed this->checkForDeferredSave(); 8058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fMCRec->fFilter, filter); 8068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return filter; 8078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8087765000709dc64eb23be7df47d1f995d1f787115fmalita#endif 8098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 81074bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.orgSkMetaData& SkCanvas::getMetaData() { 81174bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org // metadata users are rare, so we lazily allocate it. If that changes we 81274bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org // can decide to just make it a field in the device (rather than a ptr) 81396fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == fMetaData) { 81474bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org fMetaData = new SkMetaData; 81574bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org } 81674bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org return *fMetaData; 81774bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org} 81874bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org 8198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 8208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 821bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.orgvoid SkCanvas::flush() { 822ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed this->onFlush(); 823ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed} 824ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed 825ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reedvoid SkCanvas::onFlush() { 8261f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* device = this->getDevice(); 827bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org if (device) { 828bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org device->flush(); 829bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org } 830bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org} 831bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org 832afc7cce5d68663934128d76963cd501f771d71desenorblancoSkISize SkCanvas::getBaseLayerSize() const { 833afc7cce5d68663934128d76963cd501f771d71desenorblanco SkBaseDevice* d = this->getDevice(); 8344ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com return d ? SkISize::Make(d->width(), d->height()) : SkISize::Make(0, 0); 8354ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com} 8364ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com 837afc7cce5d68663934128d76963cd501f771d71desenorblancoSkIRect SkCanvas::getTopLayerBounds() const { 8384ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com SkBaseDevice* d = this->getTopDevice(); 839afc7cce5d68663934128d76963cd501f771d71desenorblanco if (!d) { 840afc7cce5d68663934128d76963cd501f771d71desenorblanco return SkIRect::MakeEmpty(); 841afc7cce5d68663934128d76963cd501f771d71desenorblanco } 842afc7cce5d68663934128d76963cd501f771d71desenorblanco return SkIRect::MakeXYWH(d->getOrigin().x(), d->getOrigin().y(), d->width(), d->height()); 843210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com} 844210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com 8451f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::getDevice() const { 8468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // return root device 847c029062a0312fb747fb6c2677983aba51795c580robertphillips@google.com MCRec* rec = (MCRec*) fMCStack.front(); 8488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(rec && rec->fLayer); 8498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return rec->fLayer->fDevice; 8508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8521f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::getTopDevice(bool updateMatrixClip) const { 8530b53d59a24f667350b4282f88470713902409030reed@google.com if (updateMatrixClip) { 8540b53d59a24f667350b4282f88470713902409030reed@google.com const_cast<SkCanvas*>(this)->updateDeviceCMCache(); 8550b53d59a24f667350b4282f88470713902409030reed@google.com } 8569266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com return fMCRec->fTopLayer->fDevice; 8579266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com} 8589266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com 859a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.orgbool SkCanvas::readPixels(SkBitmap* bitmap, int x, int y) { 860c7ec7c9cabf5c8ad08beb617b99831ece25dacddreed if (kUnknown_SkColorType == bitmap->colorType()) { 861a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 862a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 863a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 864a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bool weAllocated = false; 86596fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == bitmap->pixelRef()) { 866848250415eddc54075f7eb8795e8db79e749c6abreed if (!bitmap->tryAllocPixels()) { 867a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 868a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 869a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org weAllocated = true; 870a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 871a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 872cf01e31df6bbda270dca2ee3b4967caf51e465dcreed SkAutoPixmapUnlock unlocker; 873cf01e31df6bbda270dca2ee3b4967caf51e465dcreed if (bitmap->requestLock(&unlocker)) { 874cf01e31df6bbda270dca2ee3b4967caf51e465dcreed const SkPixmap& pm = unlocker.pixmap(); 875cf01e31df6bbda270dca2ee3b4967caf51e465dcreed if (this->readPixels(pm.info(), pm.writable_addr(), pm.rowBytes(), x, y)) { 876cf01e31df6bbda270dca2ee3b4967caf51e465dcreed return true; 877cf01e31df6bbda270dca2ee3b4967caf51e465dcreed } 878a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 879a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 880a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (weAllocated) { 88196fcdcc219d2a0d3579719b84b28bede76efba64halcanary bitmap->setPixelRef(nullptr); 882a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 883a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 884a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org} 88551df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 886c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.combool SkCanvas::readPixels(const SkIRect& srcRect, SkBitmap* bitmap) { 887a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkIRect r = srcRect; 888a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 889a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!r.intersect(0, 0, size.width(), size.height())) { 890a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bitmap->reset(); 891ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com return false; 892ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com } 89374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 894848250415eddc54075f7eb8795e8db79e749c6abreed if (!bitmap->tryAllocN32Pixels(r.width(), r.height())) { 895a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org // bitmap will already be reset. 896a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 897a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 898a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!this->readPixels(bitmap->info(), bitmap->getPixels(), bitmap->rowBytes(), r.x(), r.y())) { 899a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bitmap->reset(); 900daba14b7d4fc96b915c45d82713b22729c0d0f37bsalomon@google.com return false; 901c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } 902a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return true; 903a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org} 904c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 90596472deea70169396b8e1f576e470138f55fdb1freedbool SkCanvas::readPixels(const SkImageInfo& dstInfo, void* dstP, size_t rowBytes, int x, int y) { 906a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkBaseDevice* device = this->getDevice(); 907a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!device) { 908a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 909a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 910a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 911f0f14113431ace669f278fdd97b50950f2cf4c80mtklein 91296472deea70169396b8e1f576e470138f55fdb1freed SkReadPixelsRec rec(dstInfo, dstP, rowBytes, x, y); 91396472deea70169396b8e1f576e470138f55fdb1freed if (!rec.trim(size.width(), size.height())) { 914a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 915a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 916db0c8753775774aa3f67114491e26ac1be32f38eskia.committer@gmail.com 917a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org // The device can assert that the requested area is always contained in its bounds 91896472deea70169396b8e1f576e470138f55fdb1freed return device->readPixels(rec.fInfo, rec.fPixels, rec.fRowBytes, rec.fX, rec.fY); 91951df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com} 92051df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 9214cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgbool SkCanvas::writePixels(const SkBitmap& bitmap, int x, int y) { 922cf01e31df6bbda270dca2ee3b4967caf51e465dcreed SkAutoPixmapUnlock unlocker; 923cf01e31df6bbda270dca2ee3b4967caf51e465dcreed if (bitmap.requestLock(&unlocker)) { 924cf01e31df6bbda270dca2ee3b4967caf51e465dcreed const SkPixmap& pm = unlocker.pixmap(); 925cf01e31df6bbda270dca2ee3b4967caf51e465dcreed return this->writePixels(pm.info(), pm.addr(), pm.rowBytes(), x, y); 9264cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 9274cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 9284cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org} 9294cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 9304cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgbool SkCanvas::writePixels(const SkImageInfo& origInfo, const void* pixels, size_t rowBytes, 9314cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org int x, int y) { 9324cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org switch (origInfo.colorType()) { 9334cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org case kUnknown_SkColorType: 9344cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org case kIndex_8_SkColorType: 9354cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 9364cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org default: 9374cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org break; 9384cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 93996fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == pixels || rowBytes < origInfo.minRowBytes()) { 9404cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 9414cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 9424cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 9434cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 9444cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org SkIRect target = SkIRect::MakeXYWH(x, y, origInfo.width(), origInfo.height()); 9454cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (!target.intersect(0, 0, size.width(), size.height())) { 9464cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 9474cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 9484cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 9494cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org SkBaseDevice* device = this->getDevice(); 9504cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (!device) { 9514cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 9524cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 9534cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 9544cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // the intersect may have shrunk info's logical size 955e5ea500d4714a7d84de2bf913e81be3b65d2de68reed const SkImageInfo info = origInfo.makeWH(target.width(), target.height()); 9564cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 9574cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // if x or y are negative, then we have to adjust pixels 9584cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (x > 0) { 9594cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org x = 0; 9604cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 9614cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (y > 0) { 9624cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org y = 0; 9634cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 9644cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // here x,y are either 0 or negative 9654cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org pixels = ((const char*)pixels - y * rowBytes - x * info.bytesPerPixel()); 9664cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 9674af35f348b2e2f6c428819118eb7a2f2fff53a74reed // Tell our owning surface to bump its generation ID 968c83a29759a5c2966da5ab973e4fd90763e4c962breed const bool completeOverwrite = info.dimensions() == size; 969c83a29759a5c2966da5ab973e4fd90763e4c962breed this->predrawNotify(completeOverwrite); 9704af35f348b2e2f6c428819118eb7a2f2fff53a74reed 9714cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // The device can assert that the requested area is always contained in its bounds 9724ef54f8d72420a521d4aae04ff5cd438810eca7fcommit-bot@chromium.org return device->writePixels(info, pixels, rowBytes, target.x(), target.y()); 9734cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org} 97451df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 9754370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comSkCanvas* SkCanvas::canvasForDrawIter() { 9764370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com return this; 9774370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 9784370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 9798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 9808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::updateDeviceCMCache() { 9828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fDeviceCMDirty) { 9838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& totalMatrix = this->getTotalMatrix(); 9841f836ee096bb988adef4b9757b2629c7afeda36dreed const SkRasterClip& totalClip = fMCRec->fRasterClip; 9858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* layer = fMCRec->fTopLayer; 9864b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 98796fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == layer->fNext) { // only one layer 988de6c531e468197bb7746f1217a8ccb2ab175e0b8reed layer->updateMC(totalMatrix, totalClip, nullptr); 9898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 990045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com SkRasterClip clip(totalClip); 9918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 992de6c531e468197bb7746f1217a8ccb2ab175e0b8reed layer->updateMC(totalMatrix, clip, &clip); 99396fcdcc219d2a0d3579719b84b28bede76efba64halcanary } while ((layer = layer->fNext) != nullptr); 9948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = false; 9968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 10008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10012ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::checkForDeferredSave() { 10022ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (fMCRec->fDeferredSaveCount > 0) { 10032ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->doSave(); 10042ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 10052ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed} 10062ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed 1007f0090cb80ab10a49e511aa5450ae38917fa058d9reedint SkCanvas::getSaveCount() const { 10082ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed#ifdef SK_DEBUG 10092ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed int count = 0; 10102ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkDeque::Iter iter(fMCStack, SkDeque::Iter::kFront_IterStart); 10112ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed for (;;) { 10122ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed const MCRec* rec = (const MCRec*)iter.next(); 10132ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (!rec) { 10142ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed break; 10152ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 10162ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed count += 1 + rec->fDeferredSaveCount; 10172ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 10182ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(count == fSaveCount); 10192ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed#endif 10202ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return fSaveCount; 1021f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 1022f0090cb80ab10a49e511aa5450ae38917fa058d9reed 1023f0090cb80ab10a49e511aa5450ae38917fa058d9reedint SkCanvas::save() { 10242ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount += 1; 10252ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fMCRec->fDeferredSaveCount += 1; 10262ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return this->getSaveCount() - 1; // return our prev value 10272ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed} 10282ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed 10292ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::doSave() { 1030f0090cb80ab10a49e511aa5450ae38917fa058d9reed this->willSave(); 1031a62d32d1e3112c7e5a26c27e5e967d124ef8dd81fmalita 1032a62d32d1e3112c7e5a26c27e5e967d124ef8dd81fmalita SkASSERT(fMCRec->fDeferredSaveCount > 0); 1033a62d32d1e3112c7e5a26c27e5e967d124ef8dd81fmalita fMCRec->fDeferredSaveCount -= 1; 10342ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalSave(); 1035f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 1036f0090cb80ab10a49e511aa5450ae38917fa058d9reed 1037f0090cb80ab10a49e511aa5450ae38917fa058d9reedvoid SkCanvas::restore() { 10382ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (fMCRec->fDeferredSaveCount > 0) { 10392ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(fSaveCount > 1); 10402ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount -= 1; 10412ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fMCRec->fDeferredSaveCount -= 1; 10422ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } else { 10432ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed // check for underflow 10442ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (fMCStack.count() > 1) { 10452ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->willRestore(); 10462ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(fSaveCount > 1); 1047a644116c3375b12c642d1b51ee1e5cf4a22c1f5breed fSaveCount -= 1; 10482ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalRestore(); 10492ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->didRestore(); 10502ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 1051f0090cb80ab10a49e511aa5450ae38917fa058d9reed } 1052f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 1053f0090cb80ab10a49e511aa5450ae38917fa058d9reed 1054f0090cb80ab10a49e511aa5450ae38917fa058d9reedvoid SkCanvas::restoreToCount(int count) { 1055f0090cb80ab10a49e511aa5450ae38917fa058d9reed // sanity check 1056f0090cb80ab10a49e511aa5450ae38917fa058d9reed if (count < 1) { 1057f0090cb80ab10a49e511aa5450ae38917fa058d9reed count = 1; 1058f0090cb80ab10a49e511aa5450ae38917fa058d9reed } 1059f0f14113431ace669f278fdd97b50950f2cf4c80mtklein 1060f0090cb80ab10a49e511aa5450ae38917fa058d9reed int n = this->getSaveCount() - count; 1061f0090cb80ab10a49e511aa5450ae38917fa058d9reed for (int i = 0; i < n; ++i) { 1062f0090cb80ab10a49e511aa5450ae38917fa058d9reed this->restore(); 1063f0090cb80ab10a49e511aa5450ae38917fa058d9reed } 1064f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 1065f0090cb80ab10a49e511aa5450ae38917fa058d9reed 10662ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::internalSave() { 10678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com MCRec* newTop = (MCRec*)fMCStack.push_back(); 1068d954498c01ccf0417feacf89e45d0c62a06a813breed new (newTop) MCRec(*fMCRec); // balanced in restore() 10698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = newTop; 10704b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 1071687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->save(); 10728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10744960eeec4a1f2a772654883d7f3615d47bcd5dc3reedbool SkCanvas::BoundsAffectsClip(SaveLayerFlags saveLayerFlags) { 10754960eeec4a1f2a772654883d7f3615d47bcd5dc3reed return !(saveLayerFlags & SkCanvas::kDontClipToLayer_PrivateSaveLayerFlag); 10768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10784960eeec4a1f2a772654883d7f3615d47bcd5dc3reedbool SkCanvas::clipRectBounds(const SkRect* bounds, SaveLayerFlags saveLayerFlags, 10799b3aa54bc9605257c701cf465813f5fb1d7ba39ereed SkIRect* intersection, const SkImageFilter* imageFilter) { 1080bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect clipBounds; 1081bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (!this->getClipDeviceBounds(&clipBounds)) { 1082a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return false; 1083f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 1084c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org 108596e657d0e103b8358a77ecd913f6086929f792b8reed const SkMatrix& ctm = fMCRec->fMatrix; // this->getTotalMatrix() 108696e657d0e103b8358a77ecd913f6086929f792b8reed 1087c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org if (imageFilter) { 1088e5e79840ef38ab1d3f03abcf1b2df66fb9940018senorblanco clipBounds = imageFilter->filterBounds(clipBounds, ctm); 1089db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco if (bounds && !imageFilter->canComputeFastBounds()) { 1090db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco bounds = nullptr; 1091db64af3b178a19ecb47d2b9a373113687d8921fdsenorblanco } 1092c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org } 1093bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect ir; 109449f085dddff10473b6ebf832a974288300224e60bsalomon if (bounds) { 10958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 10964b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 109796e657d0e103b8358a77ecd913f6086929f792b8reed ctm.mapRect(&r, *bounds); 10988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.roundOut(&ir); 10998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // early exit if the layer's bounds are clipped out 11008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!ir.intersect(clipBounds)) { 11014960eeec4a1f2a772654883d7f3615d47bcd5dc3reed if (BoundsAffectsClip(saveLayerFlags)) { 11021f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fRasterClip.setEmpty(); 1103fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds.setEmpty(); 1104bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1105a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return false; 11068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { // no user bounds, so just use the clip 11088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ir = clipBounds; 11098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1110180aec43451dd951fdaae81a92efc710ba093260reed SkASSERT(!ir.isEmpty()); 11118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11124960eeec4a1f2a772654883d7f3615d47bcd5dc3reed if (BoundsAffectsClip(saveLayerFlags)) { 1113180aec43451dd951fdaae81a92efc710ba093260reed // Simplify the current clips since they will be applied properly during restore() 1114687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipDevRect(ir, SkRegion::kReplace_Op); 1115180aec43451dd951fdaae81a92efc710ba093260reed fMCRec->fRasterClip.setRect(ir); 1116fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(ir); 1117a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org } 1118a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 1119a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org if (intersection) { 1120a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org *intersection = ir; 1121a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org } 1122a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return true; 1123a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org} 1124a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 11254960eeec4a1f2a772654883d7f3615d47bcd5dc3reed 11264960eeec4a1f2a772654883d7f3615d47bcd5dc3reedint SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint) { 11274960eeec4a1f2a772654883d7f3615d47bcd5dc3reed return this->saveLayer(SaveLayerRec(bounds, paint, 0)); 1128d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org} 1129d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org 11304960eeec4a1f2a772654883d7f3615d47bcd5dc3reedint SkCanvas::saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPaint* paint) { 11314960eeec4a1f2a772654883d7f3615d47bcd5dc3reed return this->saveLayer(SaveLayerRec(bounds, paint, kPreserveLCDText_SaveLayerFlag)); 11324960eeec4a1f2a772654883d7f3615d47bcd5dc3reed} 11334960eeec4a1f2a772654883d7f3615d47bcd5dc3reed 11344960eeec4a1f2a772654883d7f3615d47bcd5dc3reedint SkCanvas::saveLayer(const SaveLayerRec& origRec) { 11354960eeec4a1f2a772654883d7f3615d47bcd5dc3reed SaveLayerRec rec(origRec); 1136d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed if (gIgnoreSaveLayerBounds) { 11374960eeec4a1f2a772654883d7f3615d47bcd5dc3reed rec.fBounds = nullptr; 1138d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed } 11394960eeec4a1f2a772654883d7f3615d47bcd5dc3reed SaveLayerStrategy strategy = this->getSaveLayerStrategy(rec); 1140a644116c3375b12c642d1b51ee1e5cf4a22c1f5breed fSaveCount += 1; 11414960eeec4a1f2a772654883d7f3615d47bcd5dc3reed this->internalSaveLayer(rec, strategy); 11422ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return this->getSaveCount() - 1; 11438926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com} 11448926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 1145a2217ef965e57fdbbf989989e7ec1f2c04f62d39reedvoid SkCanvas::DrawDeviceWithFilter(SkBaseDevice* src, const SkImageFilter* filter, 1146a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkBaseDevice* dst, const SkMatrix& ctm, 1147a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed const SkClipStack* clipStack) { 1148a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkDraw draw; 1149a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkRasterClip rc; 1150a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed rc.setRect(SkIRect::MakeWH(dst->width(), dst->height())); 1151a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (!dst->accessPixels(&draw.fDst)) { 1152a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed draw.fDst.reset(dst->imageInfo(), nullptr, 0); 1153a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed } 1154a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed draw.fMatrix = &SkMatrix::I(); 1155a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed draw.fRC = &rc; 1156a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed draw.fClipStack = clipStack; 1157a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed draw.fDevice = dst; 11587354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips 11597354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips SkPaint p; 1160372177ee115d46dfb5bfb881a408e6c37ae83678robertphillips p.setImageFilter(filter->makeWithLocalMatrix(ctm)); 1161a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed 1162a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed int x = src->getOrigin().x() - dst->getOrigin().x(); 1163a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed int y = src->getOrigin().y() - dst->getOrigin().y(); 1164a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed auto special = src->snapSpecial(); 1165a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (special) { 1166a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed dst->drawSpecial(draw, special.get(), x, y, p); 1167a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed } 11687354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips} 116970ee31b2fa127eee6c0cea61cf05508e9d3ca7b1reed 1170129ed1cd6d792f3f6cf563aefa9756fc6308289dreedstatic SkImageInfo make_layer_info(const SkImageInfo& prev, int w, int h, bool isOpaque, 1171129ed1cd6d792f3f6cf563aefa9756fc6308289dreed const SkPaint* paint) { 1172129ed1cd6d792f3f6cf563aefa9756fc6308289dreed // need to force L32 for now if we have an image filter. Once filters support other colortypes 1173129ed1cd6d792f3f6cf563aefa9756fc6308289dreed // e.g. sRGB or F16, we can remove this check 117452ede1d905728cdcaa98db1e4a33724f5a85c62dbrianosman // SRGBTODO: Can we remove this check now? 1175129ed1cd6d792f3f6cf563aefa9756fc6308289dreed const bool hasImageFilter = paint && paint->getImageFilter(); 1176129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 1177129ed1cd6d792f3f6cf563aefa9756fc6308289dreed SkAlphaType alphaType = isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType; 1178129ed1cd6d792f3f6cf563aefa9756fc6308289dreed if ((prev.bytesPerPixel() < 4) || hasImageFilter) { 1179129ed1cd6d792f3f6cf563aefa9756fc6308289dreed // force to L32 1180129ed1cd6d792f3f6cf563aefa9756fc6308289dreed return SkImageInfo::MakeN32(w, h, alphaType); 1181129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } else { 1182129ed1cd6d792f3f6cf563aefa9756fc6308289dreed // keep the same characteristics as the prev 118352ede1d905728cdcaa98db1e4a33724f5a85c62dbrianosman return SkImageInfo::Make(w, h, prev.colorType(), alphaType, sk_ref_sp(prev.colorSpace())); 1184129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 1185129ed1cd6d792f3f6cf563aefa9756fc6308289dreed} 1186129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 11874960eeec4a1f2a772654883d7f3615d47bcd5dc3reedvoid SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy strategy) { 11884960eeec4a1f2a772654883d7f3615d47bcd5dc3reed const SkRect* bounds = rec.fBounds; 11894960eeec4a1f2a772654883d7f3615d47bcd5dc3reed const SkPaint* paint = rec.fPaint; 11904960eeec4a1f2a772654883d7f3615d47bcd5dc3reed SaveLayerFlags saveLayerFlags = rec.fSaveLayerFlags; 11914960eeec4a1f2a772654883d7f3615d47bcd5dc3reed 11928c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkLazyPaint lazyP; 11938c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkImageFilter* imageFilter = paint ? paint->getImageFilter() : NULL; 11948c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkMatrix stashedMatrix = fMCRec->fMatrix; 11958c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkMatrix remainder; 11968c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkSize scale; 11978c30a8196dd5903d2d23b4d0a5dc888e802bf698reed /* 11988c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * ImageFilters (so far) do not correctly handle matrices (CTM) that contain rotation/skew/etc. 11998c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * but they do handle scaling. To accommodate this, we do the following: 12008c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 12018c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 1. Stash off the current CTM 12028c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 2. Decompose the CTM into SCALE and REMAINDER 12038c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 3. Wack the CTM to be just SCALE, and wrap the imagefilter with a MatrixImageFilter that 12048c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * contains the REMAINDER 12058c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 4. Proceed as usual, allowing the client to draw into the layer (now with a scale-only CTM) 12068c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 5. During restore, we process the MatrixImageFilter, which applies REMAINDER to the output 12078c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * of the original imagefilter, and draw that (via drawSprite) 12088c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 6. Unwack the CTM to its original state (i.e. stashedMatrix) 12098c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * 12108c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * Perhaps in the future we could augment #5 to apply REMAINDER as part of the draw (no longer 12118c30a8196dd5903d2d23b4d0a5dc888e802bf698reed * a sprite operation) to avoid the extra buffer/overhead of MatrixImageFilter. 12128c30a8196dd5903d2d23b4d0a5dc888e802bf698reed */ 121396a04f329926099f0002f97883242793ff04f61creed if (imageFilter && !stashedMatrix.isScaleTranslate() && !imageFilter->canHandleComplexCTM() && 12148c30a8196dd5903d2d23b4d0a5dc888e802bf698reed stashedMatrix.decomposeScale(&scale, &remainder)) 12158c30a8196dd5903d2d23b4d0a5dc888e802bf698reed { 12168c30a8196dd5903d2d23b4d0a5dc888e802bf698reed // We will restore the matrix (which we are overwriting here) in restore via fStashedMatrix 12178c30a8196dd5903d2d23b4d0a5dc888e802bf698reed this->internalSetMatrix(SkMatrix::MakeScale(scale.width(), scale.height())); 12188c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkPaint* p = lazyP.set(*paint); 12198c30a8196dd5903d2d23b4d0a5dc888e802bf698reed p->setImageFilter(SkImageFilter::MakeMatrixFilter(remainder, 12208c30a8196dd5903d2d23b4d0a5dc888e802bf698reed SkFilterQuality::kLow_SkFilterQuality, 12218c30a8196dd5903d2d23b4d0a5dc888e802bf698reed sk_ref_sp(imageFilter))); 12228c30a8196dd5903d2d23b4d0a5dc888e802bf698reed imageFilter = p->getImageFilter(); 12238c30a8196dd5903d2d23b4d0a5dc888e802bf698reed paint = p; 12248c30a8196dd5903d2d23b4d0a5dc888e802bf698reed } 12258c30a8196dd5903d2d23b4d0a5dc888e802bf698reed 1226a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org // do this before we create the layer. We don't call the public save() since 1227a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org // that would invoke a possibly overridden virtual 12282ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalSave(); 1229a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 1230a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org fDeviceCMDirty = true; 1231a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 1232a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org SkIRect ir; 12338c30a8196dd5903d2d23b4d0a5dc888e802bf698reed if (!this->clipRectBounds(bounds, saveLayerFlags, &ir, imageFilter)) { 12342ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 12358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1237e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy really care about 1238e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org // the clipRectBounds() call above? 1239e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org if (kNoLayer_SaveLayerStrategy == strategy) { 12402ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 1241e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org } 1242e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org 12434960eeec4a1f2a772654883d7f3615d47bcd5dc3reed bool isOpaque = SkToBool(saveLayerFlags & kIsOpaque_SaveLayerFlag); 12448dc0ccb8d33d1af7dd13228509e61fe915bc7705reed SkPixelGeometry geo = fProps.pixelGeometry(); 12458dc0ccb8d33d1af7dd13228509e61fe915bc7705reed if (paint) { 124676033be81b82c44fd5d4fdf2672eb22e505da1f0reed // TODO: perhaps add a query to filters so we might preserve opaqueness... 1247daa57bfd4204f5a7d304c580bcf5ad99d0121e1freed if (paint->getImageFilter() || paint->getColorFilter()) { 124876033be81b82c44fd5d4fdf2672eb22e505da1f0reed isOpaque = false; 12498dc0ccb8d33d1af7dd13228509e61fe915bc7705reed geo = kUnknown_SkPixelGeometry; 1250b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com } 1251b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com } 12528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12535139e501c5ac3a511e35c78395c907a176113451robertphillips SkBaseDevice* priorDevice = this->getTopDevice(); 1254a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (nullptr == priorDevice) { 1255b2db898573e3cdcc8234eebf51961bfc4977ebbcreed SkDebugf("Unable to find device for layer."); 12562ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 1257b2db898573e3cdcc8234eebf51961bfc4977ebbcreed } 1258b2db898573e3cdcc8234eebf51961bfc4977ebbcreed 12595139e501c5ac3a511e35c78395c907a176113451robertphillips SkImageInfo info = make_layer_info(priorDevice->imageInfo(), ir.width(), ir.height(), isOpaque, 1260129ed1cd6d792f3f6cf563aefa9756fc6308289dreed paint); 1261129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 12625139e501c5ac3a511e35c78395c907a176113451robertphillips SkAutoTUnref<SkBaseDevice> newDevice; 126361f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed { 126470ee31b2fa127eee6c0cea61cf05508e9d3ca7b1reed const bool preserveLCDText = kOpaque_SkAlphaType == info.alphaType() || 12654960eeec4a1f2a772654883d7f3615d47bcd5dc3reed (saveLayerFlags & kPreserveLCDText_SaveLayerFlag); 1266daa57bfd4204f5a7d304c580bcf5ad99d0121e1freed const SkBaseDevice::TileUsage usage = SkBaseDevice::kNever_TileUsage; 126770ee31b2fa127eee6c0cea61cf05508e9d3ca7b1reed const SkBaseDevice::CreateInfo createInfo = SkBaseDevice::CreateInfo(info, usage, geo, 1268cd4051e1c4770edc03b27663c6c96ec8987122bdreed preserveLCDText); 12695139e501c5ac3a511e35c78395c907a176113451robertphillips newDevice.reset(priorDevice->onCreateDevice(createInfo, paint)); 12705139e501c5ac3a511e35c78395c907a176113451robertphillips if (!newDevice) { 12717503d60847c4ad22df87458aecd917772b23d293reed SkErrorInternals::SetError(kInternalError_SkError, 12727503d60847c4ad22df87458aecd917772b23d293reed "Unable to create device for layer."); 12737503d60847c4ad22df87458aecd917772b23d293reed return; 127461f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed } 1275e25c68402b38ac01dc1ae196ae8a5265b773c5f2bungeman@google.com } 12765139e501c5ac3a511e35c78395c907a176113451robertphillips newDevice->setOrigin(ir.fLeft, ir.fTop); 12777354a4b193aaaeae43fb9ede90e1158fa46c372brobertphillips 12785139e501c5ac3a511e35c78395c907a176113451robertphillips DeviceCM* layer = new DeviceCM(newDevice, paint, this, fConservativeRasterClip, stashedMatrix); 12798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com layer->fNext = fMCRec->fTopLayer; 12818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fLayer = layer; 12828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fTopLayer = layer; // this field is NOT an owner of layer 1283a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed 1284a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (rec.fBackdrop) { 1285a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed DrawDeviceWithFilter(priorDevice, rec.fBackdrop, newDevice, 1286a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed fMCRec->fMatrix, this->getClipStack()); 1287a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed } 12888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1290d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.orgint SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) { 1291bada1885da479d948f065182d6dfa85a1140bda5reed if (0xFF == alpha) { 1292bada1885da479d948f065182d6dfa85a1140bda5reed return this->saveLayer(bounds, nullptr); 1293bada1885da479d948f065182d6dfa85a1140bda5reed } else { 1294bada1885da479d948f065182d6dfa85a1140bda5reed SkPaint tmpPaint; 1295bada1885da479d948f065182d6dfa85a1140bda5reed tmpPaint.setAlpha(alpha); 1296bada1885da479d948f065182d6dfa85a1140bda5reed return this->saveLayer(bounds, &tmpPaint); 1297bada1885da479d948f065182d6dfa85a1140bda5reed } 1298d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org} 1299d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org 13008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::internalRestore() { 13018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fMCStack.count() != 0); 13028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 13048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1305687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->restore(); 13066c157640c27ee2ed6f9a484d21691b7b19dfecdecommit-bot@chromium.org 130788edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com // reserve our layer (if any) 13088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* layer = fMCRec->fLayer; // may be null 13098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now detach it from fMCRec so we can pop(). Gets freed after its drawn 131096fcdcc219d2a0d3579719b84b28bede76efba64halcanary fMCRec->fLayer = nullptr; 13118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now do the normal restore() 13138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->~MCRec(); // balanced in save() 13148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCStack.pop_back(); 13158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = (MCRec*)fMCStack.back(); 13168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* Time to draw the layer's offscreen. We can't call the public drawSprite, 13188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com since if we're being recorded, we don't want to record this (the 13198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com recorder will have already recorded the restore). 13208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 132149f085dddff10473b6ebf832a974288300224e60bsalomon if (layer) { 13228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (layer->fNext) { 13236f8f292aa768869a9e85c314b124875f57504f2creed@google.com const SkIPoint& origin = layer->fDevice->getOrigin(); 13247503d60847c4ad22df87458aecd917772b23d293reed this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(), layer->fPaint); 13258c30a8196dd5903d2d23b4d0a5dc888e802bf698reed // restore what we smashed in internalSaveLayer 13268c30a8196dd5903d2d23b4d0a5dc888e802bf698reed fMCRec->fMatrix = layer->fStashedMatrix; 13278926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com // reset this, since internalDrawDevice will have set it to true 13288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1329385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete layer; 1330b679ca8926a832274b14fdb512f88f64b61d32eareed } else { 1331b679ca8926a832274b14fdb512f88f64b61d32eareed // we're at the root 1332a499f905e9340e4935447f2562fd92e8853382b1reed SkASSERT(layer == (void*)fDeviceCMStorage); 1333b679ca8926a832274b14fdb512f88f64b61d32eareed layer->~DeviceCM(); 13348c30a8196dd5903d2d23b4d0a5dc888e802bf698reed // no need to update fMCRec, 'cause we're killing the canvas 13358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 133688edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 1337fbfa25802709139c2f14e304319c9541da65ca27msarett 1338fbfa25802709139c2f14e304319c9541da65ca27msarett if (fMCRec) { 13399637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett fIsScaleTranslate = fMCRec->fMatrix.isScaleTranslate(); 1340fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 1341fbfa25802709139c2f14e304319c9541da65ca27msarett } 13428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1344e8f3062a36d3682f4019309a32b5b84dc9eddf8creedsk_sp<SkSurface> SkCanvas::makeSurface(const SkImageInfo& info, const SkSurfaceProps* props) { 134596fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == props) { 13464a8126e7f81384526629b1e21bf89b632ea13cd9reed props = &fProps; 13474a8126e7f81384526629b1e21bf89b632ea13cd9reed } 13484a8126e7f81384526629b1e21bf89b632ea13cd9reed return this->onNewSurface(info, *props); 134976f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com} 135076f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com 1351e8f3062a36d3682f4019309a32b5b84dc9eddf8creedsk_sp<SkSurface> SkCanvas::onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props) { 135276f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com SkBaseDevice* dev = this->getDevice(); 1353e8f3062a36d3682f4019309a32b5b84dc9eddf8creed return dev ? dev->makeSurface(info, props) : nullptr; 135476f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com} 135576f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com 1356c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgSkImageInfo SkCanvas::imageInfo() const { 1357ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed return this->onImageInfo(); 1358ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed} 1359ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed 1360ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reedSkImageInfo SkCanvas::onImageInfo() const { 1361c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkBaseDevice* dev = this->getDevice(); 1362c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (dev) { 1363c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return dev->imageInfo(); 1364c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } else { 1365900ecf2f1579d42c9d2959831787af0346320f86reed@google.com return SkImageInfo::MakeUnknown(0, 0); 1366c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1367c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1368c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1369898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosmanbool SkCanvas::getProps(SkSurfaceProps* props) const { 1370ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed return this->onGetProps(props); 1371ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed} 1372ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reed 1373ea5a6513c05e3d7261b68c3ef7d42645ee5bfe17reedbool SkCanvas::onGetProps(SkSurfaceProps* props) const { 1374898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman SkBaseDevice* dev = this->getDevice(); 1375898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman if (dev) { 1376898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman if (props) { 1377898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman *props = fProps; 1378898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman } 1379898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman return true; 1380898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman } else { 1381898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman return false; 1382898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman } 1383898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman} 1384898235c4864df66aa7f6d32bc2a8b8551040ce1ebrianosman 13856ceeebd37a43d879c120b6ba100ae1febdd67a18reed#ifdef SK_SUPPORT_LEGACY_PEEKPIXELS_PARMS 1386c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgconst void* SkCanvas::peekPixels(SkImageInfo* info, size_t* rowBytes) { 1387884e97cb04db7ed053a866567ee9c6e4c01f993areed SkPixmap pmap; 13886ceeebd37a43d879c120b6ba100ae1febdd67a18reed if (this->peekPixels(&pmap)) { 13896ceeebd37a43d879c120b6ba100ae1febdd67a18reed if (info) { 13906ceeebd37a43d879c120b6ba100ae1febdd67a18reed *info = pmap.info(); 13916ceeebd37a43d879c120b6ba100ae1febdd67a18reed } 13926ceeebd37a43d879c120b6ba100ae1febdd67a18reed if (rowBytes) { 13936ceeebd37a43d879c120b6ba100ae1febdd67a18reed *rowBytes = pmap.rowBytes(); 13946ceeebd37a43d879c120b6ba100ae1febdd67a18reed } 13956ceeebd37a43d879c120b6ba100ae1febdd67a18reed return pmap.addr(); 1396884e97cb04db7ed053a866567ee9c6e4c01f993areed } 13976ceeebd37a43d879c120b6ba100ae1febdd67a18reed return nullptr; 13986ceeebd37a43d879c120b6ba100ae1febdd67a18reed} 13996ceeebd37a43d879c120b6ba100ae1febdd67a18reed#endif 14006ceeebd37a43d879c120b6ba100ae1febdd67a18reed 14016ceeebd37a43d879c120b6ba100ae1febdd67a18reedbool SkCanvas::peekPixels(SkPixmap* pmap) { 14026ceeebd37a43d879c120b6ba100ae1febdd67a18reed return this->onPeekPixels(pmap); 1403c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1404c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1405884e97cb04db7ed053a866567ee9c6e4c01f993areedbool SkCanvas::onPeekPixels(SkPixmap* pmap) { 1406c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkBaseDevice* dev = this->getDevice(); 1407884e97cb04db7ed053a866567ee9c6e4c01f993areed return dev && dev->peekPixels(pmap); 1408c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1409c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 14106b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.orgvoid* SkCanvas::accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin) { 1411884e97cb04db7ed053a866567ee9c6e4c01f993areed SkPixmap pmap; 1412884e97cb04db7ed053a866567ee9c6e4c01f993areed if (!this->onAccessTopLayerPixels(&pmap)) { 141396fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 1414884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1415884e97cb04db7ed053a866567ee9c6e4c01f993areed if (info) { 1416884e97cb04db7ed053a866567ee9c6e4c01f993areed *info = pmap.info(); 1417884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1418884e97cb04db7ed053a866567ee9c6e4c01f993areed if (rowBytes) { 1419884e97cb04db7ed053a866567ee9c6e4c01f993areed *rowBytes = pmap.rowBytes(); 1420884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1421884e97cb04db7ed053a866567ee9c6e4c01f993areed if (origin) { 14226b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org *origin = this->getTopDevice(false)->getOrigin(); 14236b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org } 1424884e97cb04db7ed053a866567ee9c6e4c01f993areed return pmap.writable_addr(); 14259c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 14269c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1427884e97cb04db7ed053a866567ee9c6e4c01f993areedbool SkCanvas::onAccessTopLayerPixels(SkPixmap* pmap) { 14289c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com SkBaseDevice* dev = this->getTopDevice(); 1429884e97cb04db7ed053a866567ee9c6e4c01f993areed return dev && dev->accessPixels(pmap); 14309c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 14319c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1432520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org///////////////////////////////////////////////////////////////////////////// 14338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14347503d60847c4ad22df87458aecd917772b23d293reedvoid SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, const SkPaint* paint) { 14358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint tmp; 143696fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 14378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint = &tmp; 14388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 14394b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 14408926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com LOOPER_BEGIN_DRAWDEVICE(*paint, SkDrawFilter::kBitmap_Type) 1441a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed 14428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 14431f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* dstDev = iter.fDevice; 144476dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com paint = &looper.paint(); 144576dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkImageFilter* filter = paint->getImageFilter(); 144676dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkIPoint pos = { x - iter.getX(), y - iter.getY() }; 1447f35566e8a2497cd7c7bcfeee00c507b3e8ba1587senorblanco if (filter) { 1448a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed dstDev->drawSpecial(iter, srcDev->snapSpecial().get(), pos.x(), pos.y(), *paint); 144976dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } else { 1450b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com dstDev->drawDevice(iter, srcDev, pos.x(), pos.y(), *paint); 145176dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } 14528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1453a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed 14544e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 14558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 145732704674f64cb6a14356dfebe060cd3484c06cc7reed///////////////////////////////////////////////////////////////////////////// 1458da420b976e61071cfe5de10556b4b23e519091d6reed 145992362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::translate(SkScalar dx, SkScalar dy) { 1460fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed if (dx || dy) { 1461fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed this->checkForDeferredSave(); 1462fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed fDeviceCMDirty = true; 1463fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed fMCRec->fMatrix.preTranslate(dx,dy); 1464cbdf007bc2eb85056a1a5c75c088202becba2d16mtklein 1465fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed // Translate shouldn't affect the is-scale-translateness of the matrix. 1466fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed SkASSERT(fIsScaleTranslate == fMCRec->fMatrix.isScaleTranslate()); 1467cbdf007bc2eb85056a1a5c75c088202becba2d16mtklein 1468fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed this->didTranslate(dx,dy); 1469fe69b5037817fdf4e64e96ca8b2b50eae6ed4f2creed } 14708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 147292362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::scale(SkScalar sx, SkScalar sy) { 1473d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1474d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setScale(sx, sy); 1475d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 14768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 147892362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::rotate(SkScalar degrees) { 1479d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1480d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setRotate(degrees); 1481d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 14828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14847438bfc0804d021aa92cdd5ea644994a4248f3dbbungemanvoid SkCanvas::rotate(SkScalar degrees, SkScalar px, SkScalar py) { 14857438bfc0804d021aa92cdd5ea644994a4248f3dbbungeman SkMatrix m; 14867438bfc0804d021aa92cdd5ea644994a4248f3dbbungeman m.setRotate(degrees, px, py); 14877438bfc0804d021aa92cdd5ea644994a4248f3dbbungeman this->concat(m); 14887438bfc0804d021aa92cdd5ea644994a4248f3dbbungeman} 14897438bfc0804d021aa92cdd5ea644994a4248f3dbbungeman 149092362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::skew(SkScalar sx, SkScalar sy) { 1491d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1492d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setSkew(sx, sy); 1493d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 149444c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org} 149544c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 149692362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::concat(const SkMatrix& matrix) { 1497d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org if (matrix.isIdentity()) { 1498d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org return; 1499d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org } 1500d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org 15012ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 15028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 15031f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix.preConcat(matrix); 15049637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett fIsScaleTranslate = fMCRec->fMatrix.isScaleTranslate(); 150544c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org this->didConcat(matrix); 150644c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org} 150744c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 15088c30a8196dd5903d2d23b4d0a5dc888e802bf698reedvoid SkCanvas::internalSetMatrix(const SkMatrix& matrix) { 15098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 15101f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix = matrix; 15119da5a5a198e5dc9148f7f30a6089377590eee55bmsarett fIsScaleTranslate = matrix.isScaleTranslate(); 15128c30a8196dd5903d2d23b4d0a5dc888e802bf698reed} 15138c30a8196dd5903d2d23b4d0a5dc888e802bf698reed 15148c30a8196dd5903d2d23b4d0a5dc888e802bf698reedvoid SkCanvas::setMatrix(const SkMatrix& matrix) { 15158c30a8196dd5903d2d23b4d0a5dc888e802bf698reed this->checkForDeferredSave(); 15168c30a8196dd5903d2d23b4d0a5dc888e802bf698reed this->internalSetMatrix(matrix); 151744c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org this->didSetMatrix(matrix); 15188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 15198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 15208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::resetMatrix() { 15218c30a8196dd5903d2d23b4d0a5dc888e802bf698reed this->setMatrix(SkMatrix::I()); 15228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 15238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 152495302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack#ifdef SK_EXPERIMENTAL_SHADOWING 1525e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblackvoid SkCanvas::translateZ(SkScalar z) { 1526e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack this->checkForDeferredSave(); 1527e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack this->fMCRec->fCurDrawDepth += z; 1528e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack this->didTranslateZ(z); 1529e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack} 1530e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack 1531e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblackSkScalar SkCanvas::getZ() const { 1532e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack return this->fMCRec->fCurDrawDepth; 1533e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack} 1534e5de130788c8637d2f7df9ddb0241b78e04d5882vjiaoblack 153595302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblackvoid SkCanvas::setLights(sk_sp<SkLights> lights) { 153695302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack this->fLights = lights; 153795302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack} 153895302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack 153995302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblacksk_sp<SkLights> SkCanvas::getLights() const { 154095302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack return this->fLights; 154195302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack} 154295302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack#endif 154395302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack 15448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 15458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1546759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { 15472d1afab8ef2db8b4f0bdab387b0e42ccee1db64freed if (!fAllowSoftClip) { 15482d1afab8ef2db8b4f0bdab387b0e42ccee1db64freed doAA = false; 15492d1afab8ef2db8b4f0bdab387b0e42ccee1db64freed } 15502d1afab8ef2db8b4f0bdab387b0e42ccee1db64freed 15512d1afab8ef2db8b4f0bdab387b0e42ccee1db64freed#ifdef SK_SUPPORT_PRECHECK_CLIPRECT 15522d1afab8ef2db8b4f0bdab387b0e42ccee1db64freed // Check if we can quick-accept the clip call (and do nothing) 15532d1afab8ef2db8b4f0bdab387b0e42ccee1db64freed // 1554744671639dae1d5589181856d54cf0dfdb59272dreed if (SkRegion::kIntersect_Op == op && !doAA && fMCRec->fMatrix.isScaleTranslate()) { 1555c5769b2e49a63516f313f42969983f2b9e4d59e0halcanary SkRect devR; 1556c5769b2e49a63516f313f42969983f2b9e4d59e0halcanary fMCRec->fMatrix.mapRectScaleTranslate(&devR, rect); 15572d1afab8ef2db8b4f0bdab387b0e42ccee1db64freed // NOTE: this check is CTM specific, since we might round differently with a different 15582d1afab8ef2db8b4f0bdab387b0e42ccee1db64freed // CTM. Thus this is only 100% reliable if there is not global CTM scale to be 15592d1afab8ef2db8b4f0bdab387b0e42ccee1db64freed // applied later (i.e. if this is going into a picture). 15602d1afab8ef2db8b4f0bdab387b0e42ccee1db64freed if (devR.round().contains(fMCRec->fRasterClip.getBounds())) { 15612d1afab8ef2db8b4f0bdab387b0e42ccee1db64freed#if 0 15622d1afab8ef2db8b4f0bdab387b0e42ccee1db64freed SkDebugf("ignored clipRect [%g %g %g %g]\n", 15632d1afab8ef2db8b4f0bdab387b0e42ccee1db64freed rect.left(), rect.top(), rect.right(), rect.bottom()); 15642d1afab8ef2db8b4f0bdab387b0e42ccee1db64freed#endif 15652d1afab8ef2db8b4f0bdab387b0e42ccee1db64freed return; 15662d1afab8ef2db8b4f0bdab387b0e42ccee1db64freed } 15672d1afab8ef2db8b4f0bdab387b0e42ccee1db64freed } 15682d1afab8ef2db8b4f0bdab387b0e42ccee1db64freed#endif 15692d1afab8ef2db8b4f0bdab387b0e42ccee1db64freed 15702ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 15718f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 15728f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(rect, op, edgeStyle); 15738f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 15748f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 15758f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 1576da17f758442f16747af39f8fbaed9c097048519creed@google.com#ifdef SK_ENABLE_CLIP_QUICKREJECT 1577da17f758442f16747af39f8fbaed9c097048519creed@google.com if (SkRegion::kIntersect_Op == op) { 15781f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fRasterClip.isEmpty()) { 15792d1afab8ef2db8b4f0bdab387b0e42ccee1db64freed return; 1580da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1581da17f758442f16747af39f8fbaed9c097048519creed@google.com 15823b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(rect)) { 1583da17f758442f16747af39f8fbaed9c097048519creed@google.com fDeviceCMDirty = true; 1584c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 1585da17f758442f16747af39f8fbaed9c097048519creed@google.com 1586687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipEmpty(); 15872d1afab8ef2db8b4f0bdab387b0e42ccee1db64freed (void)fMCRec->fRasterClip.setEmpty(); 1588fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds.setEmpty(); 15892d1afab8ef2db8b4f0bdab387b0e42ccee1db64freed return; 1590da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1591da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1592da17f758442f16747af39f8fbaed9c097048519creed@google.com#endif 1593da17f758442f16747af39f8fbaed9c097048519creed@google.com 1594744671639dae1d5589181856d54cf0dfdb59272dreed const bool isScaleTrans = fMCRec->fMatrix.isScaleTranslate(); 1595c64eff55049b1192052b791549a32a03be1c43e3reed SkRect devR; 1596744671639dae1d5589181856d54cf0dfdb59272dreed if (isScaleTrans) { 1597c5769b2e49a63516f313f42969983f2b9e4d59e0halcanary fMCRec->fMatrix.mapRectScaleTranslate(&devR, rect); 1598c64eff55049b1192052b791549a32a03be1c43e3reed } 1599c64eff55049b1192052b791549a32a03be1c43e3reed 16002d1afab8ef2db8b4f0bdab387b0e42ccee1db64freed#ifndef SK_SUPPORT_PRECHECK_CLIPRECT 1601c64eff55049b1192052b791549a32a03be1c43e3reed if (SkRegion::kIntersect_Op == op && 1602c64eff55049b1192052b791549a32a03be1c43e3reed kHard_ClipEdgeStyle == edgeStyle 1603744671639dae1d5589181856d54cf0dfdb59272dreed && isScaleTrans) 1604c64eff55049b1192052b791549a32a03be1c43e3reed { 1605c64eff55049b1192052b791549a32a03be1c43e3reed if (devR.round().contains(fMCRec->fRasterClip.getBounds())) { 1606c64eff55049b1192052b791549a32a03be1c43e3reed#if 0 1607c64eff55049b1192052b791549a32a03be1c43e3reed SkDebugf("------- ignored clipRect [%g %g %g %g]\n", 1608c64eff55049b1192052b791549a32a03be1c43e3reed rect.left(), rect.top(), rect.right(), rect.bottom()); 1609c64eff55049b1192052b791549a32a03be1c43e3reed#endif 1610c64eff55049b1192052b791549a32a03be1c43e3reed return; 1611c64eff55049b1192052b791549a32a03be1c43e3reed } 1612c64eff55049b1192052b791549a32a03be1c43e3reed } 16132d1afab8ef2db8b4f0bdab387b0e42ccee1db64freed#endif 1614c64eff55049b1192052b791549a32a03be1c43e3reed 1615c64eff55049b1192052b791549a32a03be1c43e3reed AutoValidateClip avc(this); 1616c64eff55049b1192052b791549a32a03be1c43e3reed 1617c64eff55049b1192052b791549a32a03be1c43e3reed fDeviceCMDirty = true; 16188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1619744671639dae1d5589181856d54cf0dfdb59272dreed if (isScaleTrans) { 1620c64eff55049b1192052b791549a32a03be1c43e3reed const bool isAA = kSoft_ClipEdgeStyle == edgeStyle; 1621c64eff55049b1192052b791549a32a03be1c43e3reed fClipStack->clipDevRect(devR, op, isAA); 1622afc7cce5d68663934128d76963cd501f771d71desenorblanco fMCRec->fRasterClip.op(devR, this->getTopLayerBounds(), op, isAA); 16238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 1624123671901abfa595d09ca789b487c4bc7c1f7cbcrobertphillips@google.com // since we're rotated or some such thing, we convert the rect to a path 162598de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // and clip against that, since it can handle any matrix. However, to 162698de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // avoid recursion in the case where we are subclassed (e.g. Pictures) 162798de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // we explicitly call "our" version of clipPath. 16288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath path; 16298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.addRect(rect); 1631bdc335f9b9fb8d2eb1b4a00f88b34288b06112fabsalomon path.setIsVolatile(true); 16328f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->SkCanvas::onClipPath(path, op, edgeStyle); 16338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1634fbfa25802709139c2f14e304319c9541da65ca27msarett 1635fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 16368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1638759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) { 16392ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 16408f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 16414ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (rrect.isRect()) { 16428f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(rrect.getBounds(), op, edgeStyle); 16438f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } else { 16448f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRRect(rrect, op, edgeStyle); 16454ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 16468f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 164714e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 16488f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 164914e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org SkRRect transformedRRect; 16501f836ee096bb988adef4b9757b2629c7afeda36dreed if (rrect.transform(fMCRec->fMatrix, &transformedRRect)) { 165114e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org AutoValidateClip avc(this); 165214e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 165314e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org fDeviceCMDirty = true; 16548f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!fAllowSoftClip) { 16558f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com edgeStyle = kHard_ClipEdgeStyle; 16568f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 165714e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 1658687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipDevRRect(transformedRRect, op, kSoft_ClipEdgeStyle == edgeStyle); 165914e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 1660afc7cce5d68663934128d76963cd501f771d71desenorblanco fMCRec->fRasterClip.op(transformedRRect, this->getTopLayerBounds(), op, 1661125f19a2964c31a660256132acbce60e8a3e6752robertphillips kSoft_ClipEdgeStyle == edgeStyle); 1662fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 16638f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com return; 166414e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org } 166514e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 166614e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org SkPath path; 166714e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org path.addRRect(rrect); 1668bdc335f9b9fb8d2eb1b4a00f88b34288b06112fabsalomon path.setIsVolatile(true); 166914e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org // call the non-virtual version 16708f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->SkCanvas::onClipPath(path, op, edgeStyle); 16714ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 16724ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 1673759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { 16742ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 16758f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 167639f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips 167739f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips if (!path.isInverseFillType() && fMCRec->fMatrix.rectStaysRect()) { 167839f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips SkRect r; 167939f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips if (path.isRect(&r)) { 168039f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips this->onClipRect(r, op, edgeStyle); 168139f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips return; 168239f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips } 168339f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips SkRRect rrect; 168439f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips if (path.isOval(&r)) { 168539f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips rrect.setOval(r); 168639f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips this->onClipRRect(rrect, op, edgeStyle); 168739f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips return; 168839f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips } 168939f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips if (path.isRRect(&rrect)) { 169039f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips this->onClipRRect(rrect, op, edgeStyle); 169139f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips return; 169239f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips } 16938f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 169439f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips 169539f0538178bcb182346fbbb1c746eb5a1c2925fdrobertphillips this->onClipPath(path, op, edgeStyle); 16968f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 16978f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 16988f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 1699da17f758442f16747af39f8fbaed9c097048519creed@google.com#ifdef SK_ENABLE_CLIP_QUICKREJECT 1700da17f758442f16747af39f8fbaed9c097048519creed@google.com if (SkRegion::kIntersect_Op == op && !path.isInverseFillType()) { 17011f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fRasterClip.isEmpty()) { 17022d1afab8ef2db8b4f0bdab387b0e42ccee1db64freed return; 1703da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1704fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 17053b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(path.getBounds())) { 1706da17f758442f16747af39f8fbaed9c097048519creed@google.com fDeviceCMDirty = true; 1707c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 1708fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1709687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipEmpty(); 17102d1afab8ef2db8b4f0bdab387b0e42ccee1db64freed (void)fMCRec->fRasterClip.setEmpty(); 1711fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds.setEmpty(); 17122d1afab8ef2db8b4f0bdab387b0e42ccee1db64freed return; 1713da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1714da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1715da17f758442f16747af39f8fbaed9c097048519creed@google.com#endif 1716da17f758442f16747af39f8fbaed9c097048519creed@google.com 17175c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com AutoValidateClip avc(this); 17185c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 17198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 17208f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!fAllowSoftClip) { 17218f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com edgeStyle = kHard_ClipEdgeStyle; 17228f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 17238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath devPath; 1725bdc335f9b9fb8d2eb1b4a00f88b34288b06112fabsalomon if (fMCRec->fMatrix.isIdentity()) { 1726bdc335f9b9fb8d2eb1b4a00f88b34288b06112fabsalomon devPath = path; 1727bdc335f9b9fb8d2eb1b4a00f88b34288b06112fabsalomon } else { 1728bdc335f9b9fb8d2eb1b4a00f88b34288b06112fabsalomon path.transform(fMCRec->fMatrix, &devPath); 1729bdc335f9b9fb8d2eb1b4a00f88b34288b06112fabsalomon devPath.setIsVolatile(true); 1730bdc335f9b9fb8d2eb1b4a00f88b34288b06112fabsalomon } 17318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1732fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // Check if the transfomation, or the original path itself 1733fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // made us empty. Note this can also happen if we contained NaN 1734fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // values. computing the bounds detects this, and will set our 1735fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // bounds to empty if that is the case. (see SkRect::set(pts, count)) 1736fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com if (devPath.getBounds().isEmpty()) { 1737fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // resetting the path will remove any NaN or other wanky values 1738fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // that might upset our scan converter. 1739fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com devPath.reset(); 1740fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com } 1741fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com 17425c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // if we called path.swap() we could avoid a deep copy of this path 1743687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipDevPath(devPath, op, kSoft_ClipEdgeStyle == edgeStyle); 17445c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 174545a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com if (fAllowSimplifyClip) { 17461a481fe4bf632ed4f76cb337691236fabfd4ab03fmalita bool clipIsAA = getClipStack()->asPath(&devPath); 17471a481fe4bf632ed4f76cb337691236fabfd4ab03fmalita if (clipIsAA) { 17481a481fe4bf632ed4f76cb337691236fabfd4ab03fmalita edgeStyle = kSoft_ClipEdgeStyle; 174945a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com } 17501a481fe4bf632ed4f76cb337691236fabfd4ab03fmalita 175145a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com op = SkRegion::kReplace_Op; 175245a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com } 175345a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com 1754afc7cce5d68663934128d76963cd501f771d71desenorblanco fMCRec->fRasterClip.op(devPath, this->getTopLayerBounds(), op, edgeStyle); 1755fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 17568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1758759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipRegion(const SkRegion& rgn, SkRegion::Op op) { 17592ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 17608f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRegion(rgn, op); 17618f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 17628f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 17638f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipRegion(const SkRegion& rgn, SkRegion::Op op) { 17645c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com AutoValidateClip avc(this); 17655c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 17668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 17678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17685c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // todo: signal fClipStack that we have a region, and therefore (I guess) 17695c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // we have to ignore it, and use the region directly? 1770687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipDevRect(rgn.getBounds(), op); 17715c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 17721f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fRasterClip.op(rgn, op); 1773fbfa25802709139c2f14e304319c9541da65ca27msarett fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 17748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1776819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com#ifdef SK_DEBUG 1777819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.comvoid SkCanvas::validateClip() const { 1778819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com // construct clipRgn from the clipstack 17791f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com const SkBaseDevice* device = this->getDevice(); 1780ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com if (!device) { 17815c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org SkASSERT(this->isClipEmpty()); 1782ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com return; 1783ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com } 1784ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com 1785819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com SkIRect ir; 1786819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com ir.set(0, 0, device->width(), device->height()); 1787d954498c01ccf0417feacf89e45d0c62a06a813breed SkRasterClip tmpClip(ir, fConservativeRasterClip); 1788819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 1789687fa1c745febb57f42b0d5f03d7c1f4be2530careed SkClipStack::B2TIter iter(*fClipStack); 17908182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const SkClipStack::Element* element; 179196fcdcc219d2a0d3579719b84b28bede76efba64halcanary while ((element = iter.next()) != nullptr) { 17928182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com switch (element->getType()) { 17938182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kRect_Type: 17948182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com element->getRect().round(&ir); 17958182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com tmpClip.op(ir, element->getOp()); 17968182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 17978182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kEmpty_Type: 17988182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com tmpClip.setEmpty(); 17998182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 18009cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org default: { 18019cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org SkPath path; 18029cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org element->asPath(&path); 1803afc7cce5d68663934128d76963cd501f771d71desenorblanco tmpClip.op(path, this->getTopLayerBounds(), element->getOp(), element->isAA()); 18049cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org break; 18059cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org } 1806819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com } 1807819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com } 1808819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com} 1809819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com#endif 1810819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 181190c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.comvoid SkCanvas::replayClips(ClipVisitor* visitor) const { 1812687fa1c745febb57f42b0d5f03d7c1f4be2530careed SkClipStack::B2TIter iter(*fClipStack); 18138182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const SkClipStack::Element* element; 18148182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com 181596fcdcc219d2a0d3579719b84b28bede76efba64halcanary while ((element = iter.next()) != nullptr) { 1816c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita element->replay(visitor); 181790c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com } 181890c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com} 181990c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com 18205c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com/////////////////////////////////////////////////////////////////////////////// 18215c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 1822754de5f65b466f721d952a379194cc94de376f42reed@google.combool SkCanvas::isClipEmpty() const { 18231f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.isEmpty(); 1824754de5f65b466f721d952a379194cc94de376f42reed@google.com} 1825754de5f65b466f721d952a379194cc94de376f42reed@google.com 18265c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.orgbool SkCanvas::isClipRect() const { 18271f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.isRect(); 18285c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org} 18295c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org 1830fbfa25802709139c2f14e304319c9541da65ca27msarettstatic inline bool is_nan_or_clipped(const Sk4f& devRect, const Sk4f& devClip) { 1831fbfa25802709139c2f14e304319c9541da65ca27msarett#if !defined(SKNX_NO_SIMD) && SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2 1832fbfa25802709139c2f14e304319c9541da65ca27msarett __m128 lLtT = _mm_unpacklo_ps(devRect.fVec, devClip.fVec); 1833fbfa25802709139c2f14e304319c9541da65ca27msarett __m128 RrBb = _mm_unpackhi_ps(devClip.fVec, devRect.fVec); 1834fbfa25802709139c2f14e304319c9541da65ca27msarett __m128 mask = _mm_cmplt_ps(lLtT, RrBb); 1835fbfa25802709139c2f14e304319c9541da65ca27msarett return 0xF != _mm_movemask_ps(mask); 1836fbfa25802709139c2f14e304319c9541da65ca27msarett#elif !defined(SKNX_NO_SIMD) && defined(SK_ARM_HAS_NEON) 1837fbfa25802709139c2f14e304319c9541da65ca27msarett float32x4_t lLtT = vzipq_f32(devRect.fVec, devClip.fVec).val[0]; 1838fbfa25802709139c2f14e304319c9541da65ca27msarett float32x4_t RrBb = vzipq_f32(devClip.fVec, devRect.fVec).val[1]; 1839fbfa25802709139c2f14e304319c9541da65ca27msarett uint32x4_t mask = vcltq_f32(lLtT, RrBb); 1840fbfa25802709139c2f14e304319c9541da65ca27msarett return 0xFFFFFFFFFFFFFFFF != (uint64_t) vmovn_u32(mask); 1841fbfa25802709139c2f14e304319c9541da65ca27msarett#else 1842fbfa25802709139c2f14e304319c9541da65ca27msarett SkRect devRectAsRect; 1843fbfa25802709139c2f14e304319c9541da65ca27msarett SkRect devClipAsRect; 1844fbfa25802709139c2f14e304319c9541da65ca27msarett devRect.store(&devRectAsRect.fLeft); 1845fbfa25802709139c2f14e304319c9541da65ca27msarett devClip.store(&devClipAsRect.fLeft); 1846fbfa25802709139c2f14e304319c9541da65ca27msarett return !devRectAsRect.isFinite() || !devRectAsRect.intersect(devClipAsRect); 1847fbfa25802709139c2f14e304319c9541da65ca27msarett#endif 1848fbfa25802709139c2f14e304319c9541da65ca27msarett} 1849fbfa25802709139c2f14e304319c9541da65ca27msarett 1850fbfa25802709139c2f14e304319c9541da65ca27msarett// It's important for this function to not be inlined. Otherwise the compiler will share code 1851fbfa25802709139c2f14e304319c9541da65ca27msarett// between the fast path and the slow path, resulting in two slow paths. 1852fbfa25802709139c2f14e304319c9541da65ca27msarettstatic SK_NEVER_INLINE bool quick_reject_slow_path(const SkRect& src, const SkRect& deviceClip, 1853fbfa25802709139c2f14e304319c9541da65ca27msarett const SkMatrix& matrix) { 1854fbfa25802709139c2f14e304319c9541da65ca27msarett SkRect deviceRect; 1855fbfa25802709139c2f14e304319c9541da65ca27msarett matrix.mapRect(&deviceRect, src); 1856fbfa25802709139c2f14e304319c9541da65ca27msarett return !deviceRect.isFinite() || !deviceRect.intersect(deviceClip); 1857fbfa25802709139c2f14e304319c9541da65ca27msarett} 1858d22a817ff57986407facd16af36320fc86ce02damsarett 1859fbfa25802709139c2f14e304319c9541da65ca27msarettbool SkCanvas::quickReject(const SkRect& src) const { 1860fbfa25802709139c2f14e304319c9541da65ca27msarett#ifdef SK_DEBUG 1861fbfa25802709139c2f14e304319c9541da65ca27msarett // Verify that fDeviceClipBounds are set properly. 1862fbfa25802709139c2f14e304319c9541da65ca27msarett SkRect tmp = qr_clip_bounds(fMCRec->fRasterClip.getBounds()); 18631f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fRasterClip.isEmpty()) { 18640c685ee188a5e500df25a34fa6edfceb4cbb795cmsarett SkASSERT(fDeviceClipBounds.isEmpty()); 1865fbfa25802709139c2f14e304319c9541da65ca27msarett } else { 1866fbfa25802709139c2f14e304319c9541da65ca27msarett SkASSERT(tmp == fDeviceClipBounds); 18678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18699637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett // Verify that fIsScaleTranslate is set properly. 18709637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett SkASSERT(fIsScaleTranslate == fMCRec->fMatrix.isScaleTranslate()); 1871fbfa25802709139c2f14e304319c9541da65ca27msarett#endif 1872d252db03d9650013b545ef9781fe993c07f8f314reed@android.com 18739637ea91b88ff8f8e95325bfc41417ffc4d5ee0bmsarett if (!fIsScaleTranslate) { 1874fbfa25802709139c2f14e304319c9541da65ca27msarett return quick_reject_slow_path(src, fDeviceClipBounds, fMCRec->fMatrix); 18758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1876fbfa25802709139c2f14e304319c9541da65ca27msarett 1877fbfa25802709139c2f14e304319c9541da65ca27msarett // We inline the implementation of mapScaleTranslate() for the fast path. 1878fbfa25802709139c2f14e304319c9541da65ca27msarett float sx = fMCRec->fMatrix.getScaleX(); 1879fbfa25802709139c2f14e304319c9541da65ca27msarett float sy = fMCRec->fMatrix.getScaleY(); 1880fbfa25802709139c2f14e304319c9541da65ca27msarett float tx = fMCRec->fMatrix.getTranslateX(); 1881fbfa25802709139c2f14e304319c9541da65ca27msarett float ty = fMCRec->fMatrix.getTranslateY(); 1882fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f scale(sx, sy, sx, sy); 1883fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f trans(tx, ty, tx, ty); 1884fbfa25802709139c2f14e304319c9541da65ca27msarett 1885fbfa25802709139c2f14e304319c9541da65ca27msarett // Apply matrix. 1886fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f ltrb = Sk4f::Load(&src.fLeft) * scale + trans; 1887fbfa25802709139c2f14e304319c9541da65ca27msarett 1888fbfa25802709139c2f14e304319c9541da65ca27msarett // Make sure left < right, top < bottom. 1889fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f rblt(ltrb[2], ltrb[3], ltrb[0], ltrb[1]); 1890fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f min = Sk4f::Min(ltrb, rblt); 1891fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f max = Sk4f::Max(ltrb, rblt); 1892fbfa25802709139c2f14e304319c9541da65ca27msarett // We can extract either pair [0,1] or [2,3] from min and max and be correct, but on 1893fbfa25802709139c2f14e304319c9541da65ca27msarett // ARM this sequence generates the fastest (a single instruction). 1894fbfa25802709139c2f14e304319c9541da65ca27msarett Sk4f devRect = Sk4f(min[2], min[3], max[0], max[1]); 1895fbfa25802709139c2f14e304319c9541da65ca27msarett 1896fbfa25802709139c2f14e304319c9541da65ca27msarett // Check if the device rect is NaN or outside the clip. 1897fbfa25802709139c2f14e304319c9541da65ca27msarett return is_nan_or_clipped(devRect, Sk4f::Load(&fDeviceClipBounds.fLeft)); 18988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19003b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::quickReject(const SkPath& path) const { 19013b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com return path.isEmpty() || this->quickReject(path.getBounds()); 19028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 19038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19043b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::getClipBounds(SkRect* bounds) const { 1905bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect ibounds; 19068f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!this->getClipDeviceBounds(&ibounds)) { 19078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 19088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 19098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1910d9c0f0b57affec7a472879c5919acac6637d926areed@android.com SkMatrix inverse; 1911d9c0f0b57affec7a472879c5919acac6637d926areed@android.com // if we can't invert the CTM, we can't return local clip bounds 19121f836ee096bb988adef4b9757b2629c7afeda36dreed if (!fMCRec->fMatrix.invert(&inverse)) { 191372dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com if (bounds) { 191472dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com bounds->setEmpty(); 191572dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com } 1916d9c0f0b57affec7a472879c5919acac6637d926areed@android.com return false; 1917d9c0f0b57affec7a472879c5919acac6637d926areed@android.com } 1918d9c0f0b57affec7a472879c5919acac6637d926areed@android.com 191949f085dddff10473b6ebf832a974288300224e60bsalomon if (bounds) { 1920bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkRect r; 19213b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com // adjust it outwards in case we are antialiasing 19223b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com const int inset = 1; 1923fa4d5bd09f8f1a4a92b5ae0324800dd672760898reed@google.com 19248f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com r.iset(ibounds.fLeft - inset, ibounds.fTop - inset, 19258f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com ibounds.fRight + inset, ibounds.fBottom + inset); 19268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inverse.mapRect(bounds, r); 19278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 19288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 19298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 19308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1931bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.combool SkCanvas::getClipDeviceBounds(SkIRect* bounds) const { 19321f836ee096bb988adef4b9757b2629c7afeda36dreed const SkRasterClip& clip = fMCRec->fRasterClip; 1933bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (clip.isEmpty()) { 1934bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (bounds) { 1935bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com bounds->setEmpty(); 1936bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1937bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com return false; 1938bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1939bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com 194049f085dddff10473b6ebf832a974288300224e60bsalomon if (bounds) { 1941bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com *bounds = clip.getBounds(); 1942bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1943bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com return true; 1944bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com} 1945bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com 19468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkMatrix& SkCanvas::getTotalMatrix() const { 19471f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fMatrix; 19488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 19498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19505c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.orgconst SkRegion& SkCanvas::internal_private_getTotalClip() const { 19511f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.forceGetBW(); 19525c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org} 19535c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org 1954175dd9b5e3d7d749738dac743d2ac360b5340187robertphillipsGrDrawContext* SkCanvas::internal_private_accessTopLayerDrawContext() { 19559c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com SkBaseDevice* dev = this->getTopDevice(); 1956175dd9b5e3d7d749738dac743d2ac360b5340187robertphillips return dev ? dev->accessDrawContext() : nullptr; 19579c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 19589c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1959644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.orgGrContext* SkCanvas::getGrContext() { 1960644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org SkBaseDevice* device = this->getTopDevice(); 196186ae3d161412961c27a406465b0ec5749cc2e753reed return device ? device->context() : nullptr; 1962644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org} 1963e97f0856a8044866b12527819d14cdfbcdfd96f2bsalomon@google.com 1964ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.orgvoid SkCanvas::drawDRRect(const SkRRect& outer, const SkRRect& inner, 1965ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkPaint& paint) { 19669881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawDRRect()"); 1967ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (outer.isEmpty()) { 1968ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 1969ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 1970ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (inner.isEmpty()) { 1971ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->drawRRect(outer, paint); 1972ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 1973ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 1974ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 1975ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // We don't have this method (yet), but technically this is what we should 1976ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // be able to assert... 1977ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // SkASSERT(outer.contains(inner)); 1978ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // 1979ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // For now at least check for containment of bounds 1980ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org SkASSERT(outer.getBounds().contains(inner.getBounds())); 1981ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 1982ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->onDrawDRRect(outer, inner, paint); 1983ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org} 1984ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 198541af966ab338e95eee81ab618ab28195075338f7reed// These need to stop being virtual -- clients need to override the onDraw... versions 198641af966ab338e95eee81ab618ab28195075338f7reed 198741af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawPaint(const SkPaint& paint) { 198841af966ab338e95eee81ab618ab28195075338f7reed this->onDrawPaint(paint); 198941af966ab338e95eee81ab618ab28195075338f7reed} 199041af966ab338e95eee81ab618ab28195075338f7reed 199141af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawRect(const SkRect& r, const SkPaint& paint) { 199241af966ab338e95eee81ab618ab28195075338f7reed this->onDrawRect(r, paint); 199341af966ab338e95eee81ab618ab28195075338f7reed} 199441af966ab338e95eee81ab618ab28195075338f7reed 1995dca352e2d42cfe698573947b3d11abc1eaade160msarettvoid SkCanvas::drawRegion(const SkRegion& region, const SkPaint& paint) { 1996dca352e2d42cfe698573947b3d11abc1eaade160msarett if (region.isEmpty()) { 1997dca352e2d42cfe698573947b3d11abc1eaade160msarett return; 1998dca352e2d42cfe698573947b3d11abc1eaade160msarett } 1999dca352e2d42cfe698573947b3d11abc1eaade160msarett 2000dca352e2d42cfe698573947b3d11abc1eaade160msarett if (region.isRect()) { 2001dca352e2d42cfe698573947b3d11abc1eaade160msarett return this->drawIRect(region.getBounds(), paint); 2002dca352e2d42cfe698573947b3d11abc1eaade160msarett } 2003dca352e2d42cfe698573947b3d11abc1eaade160msarett 2004dca352e2d42cfe698573947b3d11abc1eaade160msarett this->onDrawRegion(region, paint); 2005dca352e2d42cfe698573947b3d11abc1eaade160msarett} 2006dca352e2d42cfe698573947b3d11abc1eaade160msarett 200741af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawOval(const SkRect& r, const SkPaint& paint) { 200841af966ab338e95eee81ab618ab28195075338f7reed this->onDrawOval(r, paint); 200941af966ab338e95eee81ab618ab28195075338f7reed} 201041af966ab338e95eee81ab618ab28195075338f7reed 201141af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) { 201241af966ab338e95eee81ab618ab28195075338f7reed this->onDrawRRect(rrect, paint); 201341af966ab338e95eee81ab618ab28195075338f7reed} 201441af966ab338e95eee81ab618ab28195075338f7reed 201541af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint) { 201641af966ab338e95eee81ab618ab28195075338f7reed this->onDrawPoints(mode, count, pts, paint); 201741af966ab338e95eee81ab618ab28195075338f7reed} 201841af966ab338e95eee81ab618ab28195075338f7reed 201941af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawVertices(VertexMode vmode, int vertexCount, const SkPoint vertices[], 202041af966ab338e95eee81ab618ab28195075338f7reed const SkPoint texs[], const SkColor colors[], SkXfermode* xmode, 202141af966ab338e95eee81ab618ab28195075338f7reed const uint16_t indices[], int indexCount, const SkPaint& paint) { 202241af966ab338e95eee81ab618ab28195075338f7reed this->onDrawVertices(vmode, vertexCount, vertices, texs, colors, xmode, 202341af966ab338e95eee81ab618ab28195075338f7reed indices, indexCount, paint); 202441af966ab338e95eee81ab618ab28195075338f7reed} 202541af966ab338e95eee81ab618ab28195075338f7reed 202641af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawPath(const SkPath& path, const SkPaint& paint) { 202741af966ab338e95eee81ab618ab28195075338f7reed this->onDrawPath(path, paint); 202841af966ab338e95eee81ab618ab28195075338f7reed} 202941af966ab338e95eee81ab618ab28195075338f7reed 2030a85d4d0814818e4ddabb9237da209d61d6cd5854reedvoid SkCanvas::drawImage(const SkImage* image, SkScalar x, SkScalar y, const SkPaint* paint) { 2031e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 2032a85d4d0814818e4ddabb9237da209d61d6cd5854reed this->onDrawImage(image, x, y, paint); 203341af966ab338e95eee81ab618ab28195075338f7reed} 203441af966ab338e95eee81ab618ab28195075338f7reed 2035e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst, 2036e47829b6b1eeb6b0c97ccb3df3016d197046824creed const SkPaint* paint, SrcRectConstraint constraint) { 2037e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 2038e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (dst.isEmpty() || src.isEmpty()) { 2039e47829b6b1eeb6b0c97ccb3df3016d197046824creed return; 2040e47829b6b1eeb6b0c97ccb3df3016d197046824creed } 2041e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->onDrawImageRect(image, &src, dst, paint, constraint); 2042e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 204341af966ab338e95eee81ab618ab28195075338f7reed 204484984efeb64787b88c5f8bd6929cfe2d58a3ba06reedvoid SkCanvas::drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst, 204584984efeb64787b88c5f8bd6929cfe2d58a3ba06reed const SkPaint* paint, SrcRectConstraint constraint) { 2046e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 2047e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, SkRect::Make(isrc), dst, paint, constraint); 204884984efeb64787b88c5f8bd6929cfe2d58a3ba06reed} 204984984efeb64787b88c5f8bd6929cfe2d58a3ba06reed 2050e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint, 2051e47829b6b1eeb6b0c97ccb3df3016d197046824creed SrcRectConstraint constraint) { 2052e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 2053e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, SkRect::MakeIWH(image->width(), image->height()), dst, paint, 2054e47829b6b1eeb6b0c97ccb3df3016d197046824creed constraint); 2055e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 2056e47829b6b1eeb6b0c97ccb3df3016d197046824creed 20574c21dc5ddf3b482293ed34eead876d8d61a662c3reedvoid SkCanvas::drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst, 20584c21dc5ddf3b482293ed34eead876d8d61a662c3reed const SkPaint* paint) { 2059e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(image); 20604c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (dst.isEmpty()) { 20614c21dc5ddf3b482293ed34eead876d8d61a662c3reed return; 20624c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 2063552bca9afadd81d263041d04e2605d8d897940b6msarett if (SkLatticeIter::Valid(image->width(), image->height(), center)) { 2064552bca9afadd81d263041d04e2605d8d897940b6msarett this->onDrawImageNine(image, center, dst, paint); 2065552bca9afadd81d263041d04e2605d8d897940b6msarett } else { 2066e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, dst, paint); 20674c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 20684c21dc5ddf3b482293ed34eead876d8d61a662c3reed} 20694c21dc5ddf3b482293ed34eead876d8d61a662c3reed 2070168820625c35a8c19f66c661efcbce7a5e334837msarettvoid SkCanvas::drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst, 2071168820625c35a8c19f66c661efcbce7a5e334837msarett const SkPaint* paint) { 2072168820625c35a8c19f66c661efcbce7a5e334837msarett RETURN_ON_NULL(image); 2073168820625c35a8c19f66c661efcbce7a5e334837msarett if (dst.isEmpty()) { 2074168820625c35a8c19f66c661efcbce7a5e334837msarett return; 2075168820625c35a8c19f66c661efcbce7a5e334837msarett } 2076168820625c35a8c19f66c661efcbce7a5e334837msarett if (SkLatticeIter::Valid(image->width(), image->height(), lattice)) { 2077168820625c35a8c19f66c661efcbce7a5e334837msarett this->onDrawImageLattice(image, lattice, dst, paint); 2078168820625c35a8c19f66c661efcbce7a5e334837msarett } else { 2079168820625c35a8c19f66c661efcbce7a5e334837msarett this->drawImageRect(image, dst, paint); 2080168820625c35a8c19f66c661efcbce7a5e334837msarett } 2081168820625c35a8c19f66c661efcbce7a5e334837msarett} 2082168820625c35a8c19f66c661efcbce7a5e334837msarett 208341af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar dx, SkScalar dy, const SkPaint* paint) { 20844c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (bitmap.drawsNothing()) { 20852df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson return; 20862df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson } 208741af966ab338e95eee81ab618ab28195075338f7reed this->onDrawBitmap(bitmap, dx, dy, paint); 208841af966ab338e95eee81ab618ab28195075338f7reed} 208941af966ab338e95eee81ab618ab28195075338f7reed 2090e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst, 2091a5517e2b190a8083b38964972b031c13e99f1012reed const SkPaint* paint, SrcRectConstraint constraint) { 2092e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (bitmap.drawsNothing() || dst.isEmpty() || src.isEmpty()) { 2093a5517e2b190a8083b38964972b031c13e99f1012reed return; 2094a5517e2b190a8083b38964972b031c13e99f1012reed } 2095e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->onDrawBitmapRect(bitmap, &src, dst, paint, constraint); 209641af966ab338e95eee81ab618ab28195075338f7reed} 209741af966ab338e95eee81ab618ab28195075338f7reed 209884984efeb64787b88c5f8bd6929cfe2d58a3ba06reedvoid SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst, 209984984efeb64787b88c5f8bd6929cfe2d58a3ba06reed const SkPaint* paint, SrcRectConstraint constraint) { 2100e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, SkRect::Make(isrc), dst, paint, constraint); 2101e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 2102e47829b6b1eeb6b0c97ccb3df3016d197046824creed 2103e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint, 2104e47829b6b1eeb6b0c97ccb3df3016d197046824creed SrcRectConstraint constraint) { 2105e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, SkRect::MakeIWH(bitmap.width(), bitmap.height()), dst, paint, 2106e47829b6b1eeb6b0c97ccb3df3016d197046824creed constraint); 210784984efeb64787b88c5f8bd6929cfe2d58a3ba06reed} 210884984efeb64787b88c5f8bd6929cfe2d58a3ba06reed 210941af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst, 211041af966ab338e95eee81ab618ab28195075338f7reed const SkPaint* paint) { 21114c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (bitmap.drawsNothing() || dst.isEmpty()) { 21122df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson return; 21132df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson } 2114552bca9afadd81d263041d04e2605d8d897940b6msarett if (SkLatticeIter::Valid(bitmap.width(), bitmap.height(), center)) { 2115552bca9afadd81d263041d04e2605d8d897940b6msarett this->onDrawBitmapNine(bitmap, center, dst, paint); 2116552bca9afadd81d263041d04e2605d8d897940b6msarett } else { 2117a5517e2b190a8083b38964972b031c13e99f1012reed this->drawBitmapRect(bitmap, dst, paint); 21184c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 211941af966ab338e95eee81ab618ab28195075338f7reed} 212041af966ab338e95eee81ab618ab28195075338f7reed 2121c573a40ed5024b463e47088d307e3164a486dba5msarettvoid SkCanvas::drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, const SkRect& dst, 2122c573a40ed5024b463e47088d307e3164a486dba5msarett const SkPaint* paint) { 2123168820625c35a8c19f66c661efcbce7a5e334837msarett if (bitmap.drawsNothing() || dst.isEmpty()) { 2124c573a40ed5024b463e47088d307e3164a486dba5msarett return; 2125c573a40ed5024b463e47088d307e3164a486dba5msarett } 2126168820625c35a8c19f66c661efcbce7a5e334837msarett if (SkLatticeIter::Valid(bitmap.width(), bitmap.height(), lattice)) { 2127168820625c35a8c19f66c661efcbce7a5e334837msarett this->onDrawBitmapLattice(bitmap, lattice, dst, paint); 2128552bca9afadd81d263041d04e2605d8d897940b6msarett } else { 2129168820625c35a8c19f66c661efcbce7a5e334837msarett this->drawBitmapRect(bitmap, dst, paint); 2130c573a40ed5024b463e47088d307e3164a486dba5msarett } 2131c573a40ed5024b463e47088d307e3164a486dba5msarett} 2132c573a40ed5024b463e47088d307e3164a486dba5msarett 213371c3c760a83123ee0b3127b8c65c6394ce541c50reedvoid SkCanvas::drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], 213471c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkColor colors[], int count, SkXfermode::Mode mode, 213571c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkRect* cull, const SkPaint* paint) { 2136e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(atlas); 213771c3c760a83123ee0b3127b8c65c6394ce541c50reed if (count <= 0) { 213871c3c760a83123ee0b3127b8c65c6394ce541c50reed return; 213971c3c760a83123ee0b3127b8c65c6394ce541c50reed } 214071c3c760a83123ee0b3127b8c65c6394ce541c50reed SkASSERT(atlas); 214171c3c760a83123ee0b3127b8c65c6394ce541c50reed SkASSERT(xform); 214271c3c760a83123ee0b3127b8c65c6394ce541c50reed SkASSERT(tex); 214371c3c760a83123ee0b3127b8c65c6394ce541c50reed this->onDrawAtlas(atlas, xform, tex, colors, count, mode, cull, paint); 214471c3c760a83123ee0b3127b8c65c6394ce541c50reed} 214571c3c760a83123ee0b3127b8c65c6394ce541c50reed 2146f70b531daaf47db1ee95c70da9843f1dd1f418d3reedvoid SkCanvas::drawAnnotation(const SkRect& rect, const char key[], SkData* value) { 2147f70b531daaf47db1ee95c70da9843f1dd1f418d3reed if (key) { 2148f70b531daaf47db1ee95c70da9843f1dd1f418d3reed this->onDrawAnnotation(rect, key, value); 2149f70b531daaf47db1ee95c70da9843f1dd1f418d3reed } 2150f70b531daaf47db1ee95c70da9843f1dd1f418d3reed} 2151f70b531daaf47db1ee95c70da9843f1dd1f418d3reed 2152e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::legacy_drawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, 2153e47829b6b1eeb6b0c97ccb3df3016d197046824creed const SkPaint* paint, SrcRectConstraint constraint) { 2154e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (src) { 2155e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, *src, dst, paint, constraint); 2156e47829b6b1eeb6b0c97ccb3df3016d197046824creed } else { 2157e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, SkRect::MakeIWH(image->width(), image->height()), 2158e47829b6b1eeb6b0c97ccb3df3016d197046824creed dst, paint, constraint); 2159e47829b6b1eeb6b0c97ccb3df3016d197046824creed } 2160e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 2161e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::legacy_drawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, 2162e47829b6b1eeb6b0c97ccb3df3016d197046824creed const SkPaint* paint, SrcRectConstraint constraint) { 2163e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (src) { 2164e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, *src, dst, paint, constraint); 2165e47829b6b1eeb6b0c97ccb3df3016d197046824creed } else { 2166e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, SkRect::MakeIWH(bitmap.width(), bitmap.height()), 2167e47829b6b1eeb6b0c97ccb3df3016d197046824creed dst, paint, constraint); 2168e47829b6b1eeb6b0c97ccb3df3016d197046824creed } 2169e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 2170e47829b6b1eeb6b0c97ccb3df3016d197046824creed 2171cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudsonvoid SkCanvas::temporary_internal_describeTopLayer(SkMatrix* matrix, SkIRect* clip_bounds) { 2172cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson SkIRect layer_bounds = this->getTopLayerBounds(); 2173cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson if (matrix) { 2174cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson *matrix = this->getTotalMatrix(); 2175cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson matrix->preTranslate(-layer_bounds.left(), -layer_bounds.top()); 2176cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson } 2177cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson if (clip_bounds) { 2178cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson this->getClipDeviceBounds(clip_bounds); 2179cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson clip_bounds->offset(-layer_bounds.left(), -layer_bounds.top()); 2180cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson } 2181cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson} 2182cb3bd18a4b787f6281930dbe49e1c430f28a367ctomhudson 21838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 21848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// These are the virtual drawing methods 21858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 21868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 218728361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.orgvoid SkCanvas::onDiscard() { 218849f085dddff10473b6ebf832a974288300224e60bsalomon if (fSurfaceBase) { 218928361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org fSurfaceBase->aboutToDraw(SkSurface::kDiscard_ContentChangeMode); 219028361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org } 219128361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org} 219228361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org 219341af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawPaint(const SkPaint& paint) { 21949881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPaint()"); 2195fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->internalDrawPaint(paint); 2196fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com} 2197fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com 2198fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.comvoid SkCanvas::internalDrawPaint(const SkPaint& paint) { 219996fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, SkDrawFilter::kPaint_Type, nullptr, false) 22008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 22024e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPaint(iter, looper.paint()); 22038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 22048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22054e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 22068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 22078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 220841af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[], 220941af966ab338e95eee81ab618ab28195075338f7reed const SkPaint& paint) { 22109881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT1("disabled-by-default-skia", "SkCanvas::drawPoints()", "count", static_cast<uint64_t>(count)); 22118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if ((long)count <= 0) { 22128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 22138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 22148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 221578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect r, storage; 221696fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 2217a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com if (paint.canComputeFastBounds()) { 2218a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com // special-case 2 points (common for drawing a single line) 2219a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com if (2 == count) { 2220a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com r.set(pts[0], pts[1]); 2221a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } else { 2222a8c7f7702fb4bbedb615031bc653c5cd161a038ecommit-bot@chromium.org r.set(pts, SkToInt(count)); 2223a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } 222487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastStrokeBounds(r, &storage))) { 222587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 222687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 222787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &r; 2228fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 2229a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com 223096fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkASSERT(pts != nullptr); 22318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 223278cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPoint_Type, bounds) 22334b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 22348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 22354e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPoints(iter, mode, count, pts, looper.paint()); 22368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 22374b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 22384e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 22398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 22408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22414a16717bc7aa471fad10ec3157774771a76e5106reedstatic bool needs_autodrawlooper(SkCanvas* canvas, const SkPaint& paint) { 22424a16717bc7aa471fad10ec3157774771a76e5106reed return ((intptr_t)paint.getImageFilter() | 22434a16717bc7aa471fad10ec3157774771a76e5106reed#ifdef SK_SUPPORT_LEGACY_DRAWFILTER 22444a16717bc7aa471fad10ec3157774771a76e5106reed (intptr_t)canvas->getDrawFilter() | 22454a16717bc7aa471fad10ec3157774771a76e5106reed#endif 22464a16717bc7aa471fad10ec3157774771a76e5106reed (intptr_t)paint.getLooper() ) != 0; 22474a16717bc7aa471fad10ec3157774771a76e5106reed} 22484a16717bc7aa471fad10ec3157774771a76e5106reed 224941af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawRect(const SkRect& r, const SkPaint& paint) { 22509881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRect()"); 225178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 225296fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 22538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.canComputeFastBounds()) { 22548432808ad8898ac7137bc7ce1d9df6005e866401reed // Skia will draw an inverted rect, because it explicitly "sorts" it downstream. 22558432808ad8898ac7137bc7ce1d9df6005e866401reed // To prevent accidental rejecting at this stage, we have to sort it before we check. 22568432808ad8898ac7137bc7ce1d9df6005e866401reed SkRect tmp(r); 22578432808ad8898ac7137bc7ce1d9df6005e866401reed tmp.sort(); 22588432808ad8898ac7137bc7ce1d9df6005e866401reed 225987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(tmp, &storage))) { 226087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 226187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 226287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &r; 22638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 22644b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 22654a16717bc7aa471fad10ec3157774771a76e5106reed if (needs_autodrawlooper(this, paint)) { 22664a16717bc7aa471fad10ec3157774771a76e5106reed LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, SkDrawFilter::kRect_Type, bounds, false) 22678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22684a16717bc7aa471fad10ec3157774771a76e5106reed while (iter.next()) { 22694a16717bc7aa471fad10ec3157774771a76e5106reed iter.fDevice->drawRect(iter, r, looper.paint()); 22704a16717bc7aa471fad10ec3157774771a76e5106reed } 22718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22724a16717bc7aa471fad10ec3157774771a76e5106reed LOOPER_END 22734a16717bc7aa471fad10ec3157774771a76e5106reed } else { 22744a16717bc7aa471fad10ec3157774771a76e5106reed this->predrawNotify(bounds, &paint, false); 22754a16717bc7aa471fad10ec3157774771a76e5106reed SkDrawIter iter(this); 22764a16717bc7aa471fad10ec3157774771a76e5106reed while (iter.next()) { 22774a16717bc7aa471fad10ec3157774771a76e5106reed iter.fDevice->drawRect(iter, r, paint); 22784a16717bc7aa471fad10ec3157774771a76e5106reed } 22794a16717bc7aa471fad10ec3157774771a76e5106reed } 22808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 22818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 228244df651ebefc284acc2f66425dff3ea0b0e14b36msarettvoid SkCanvas::onDrawRegion(const SkRegion& region, const SkPaint& paint) { 228344df651ebefc284acc2f66425dff3ea0b0e14b36msarett SkRect storage; 228444df651ebefc284acc2f66425dff3ea0b0e14b36msarett SkRect regionRect = SkRect::Make(region.getBounds()); 228544df651ebefc284acc2f66425dff3ea0b0e14b36msarett const SkRect* bounds = nullptr; 228644df651ebefc284acc2f66425dff3ea0b0e14b36msarett if (paint.canComputeFastBounds()) { 228744df651ebefc284acc2f66425dff3ea0b0e14b36msarett if (this->quickReject(paint.computeFastBounds(regionRect, &storage))) { 228844df651ebefc284acc2f66425dff3ea0b0e14b36msarett return; 228944df651ebefc284acc2f66425dff3ea0b0e14b36msarett } 229044df651ebefc284acc2f66425dff3ea0b0e14b36msarett bounds = ®ionRect; 229144df651ebefc284acc2f66425dff3ea0b0e14b36msarett } 229244df651ebefc284acc2f66425dff3ea0b0e14b36msarett 229344df651ebefc284acc2f66425dff3ea0b0e14b36msarett LOOPER_BEGIN(paint, SkDrawFilter::kRect_Type, bounds) 229444df651ebefc284acc2f66425dff3ea0b0e14b36msarett 229544df651ebefc284acc2f66425dff3ea0b0e14b36msarett while (iter.next()) { 229644df651ebefc284acc2f66425dff3ea0b0e14b36msarett iter.fDevice->drawRegion(iter, region, looper.paint()); 229744df651ebefc284acc2f66425dff3ea0b0e14b36msarett } 229844df651ebefc284acc2f66425dff3ea0b0e14b36msarett 229944df651ebefc284acc2f66425dff3ea0b0e14b36msarett LOOPER_END 230044df651ebefc284acc2f66425dff3ea0b0e14b36msarett} 230144df651ebefc284acc2f66425dff3ea0b0e14b36msarett 230241af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) { 23039881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawOval()"); 230478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 230596fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 23064ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (paint.canComputeFastBounds()) { 230787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(oval, &storage))) { 230887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 230987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 231087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &oval; 23114ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 2312306ab9d5de38f2a547fd1d69aedbe69b5c6617ccskia.committer@gmail.com 231378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, bounds) 231446d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com 231546d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com while (iter.next()) { 231646d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com iter.fDevice->drawOval(iter, oval, looper.paint()); 231746d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com } 231846d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com 231946d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com LOOPER_END 23204ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 23214ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 2322ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomonvoid SkCanvas::onDrawArc(const SkRect& oval, SkScalar startAngle, 2323ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon SkScalar sweepAngle, bool useCenter, 2324ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon const SkPaint& paint) { 2325ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawArc()"); 2326ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon const SkRect* bounds = nullptr; 2327ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon if (paint.canComputeFastBounds()) { 2328ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon SkRect storage; 2329ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon // Note we're using the entire oval as the bounds. 2330ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon if (this->quickReject(paint.computeFastBounds(oval, &storage))) { 2331ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon return; 2332ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon } 2333ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon bounds = &oval; 2334ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon } 2335ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon 2336ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, bounds) 2337ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon 2338ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon while (iter.next()) { 2339ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon iter.fDevice->drawArc(iter, oval, startAngle, sweepAngle, useCenter, looper.paint()); 2340ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon } 2341ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon 2342ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon LOOPER_END 2343ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon} 2344ac3aa245acc7b469aa2f0d0078e53401d78ac8b9bsalomon 234541af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) { 23469881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRRect()"); 234778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 234896fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 23494ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (paint.canComputeFastBounds()) { 235087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(rrect.getBounds(), &storage))) { 235187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 235287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 235387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &rrect.getBounds(); 23544ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 23554ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 23564ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (rrect.isRect()) { 23574ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com // call the non-virtual version 23584ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->SkCanvas::drawRect(rrect.getBounds(), paint); 2359f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org return; 2360f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } else if (rrect.isOval()) { 23614ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com // call the non-virtual version 2362f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org this->SkCanvas::drawOval(rrect.getBounds(), paint); 2363f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org return; 23644ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 2365f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 236678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) 2367f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 2368f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org while (iter.next()) { 2369f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org iter.fDevice->drawRRect(iter, rrect, looper.paint()); 2370f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } 2371f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 2372f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org LOOPER_END 23734ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 23744ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 2375ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.orgvoid SkCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, 2376ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkPaint& paint) { 2377ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org SkRect storage; 237896fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 2379ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (paint.canComputeFastBounds()) { 238087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(outer.getBounds(), &storage))) { 238187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 238287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 238387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &outer.getBounds(); 2384ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 238525c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 2386ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) 238725c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 2388ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org while (iter.next()) { 2389ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org iter.fDevice->drawDRRect(iter, outer, inner, looper.paint()); 2390ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 239125c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 2392ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org LOOPER_END 2393ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org} 23944ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 239541af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) { 23969881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPath()"); 23979364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com if (!path.isFinite()) { 23989364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com return; 23999364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com } 24009364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com 240178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 240296fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 2403fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com if (!path.isInverseFillType() && paint.canComputeFastBounds()) { 240478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect& pathBounds = path.getBounds(); 240587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(pathBounds, &storage))) { 240687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 240787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 240887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &pathBounds; 24098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 24100b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org 24110b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org const SkRect& r = path.getBounds(); 24120b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org if (r.width() <= 0 && r.height() <= 0) { 24136803c219dd3be4a73e7bb5c4bb8a5b1f803624d0commit-bot@chromium.org if (path.isInverseFillType()) { 2414fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->internalDrawPaint(paint); 24156651a3238dd6affa4276ada42ab613abf1d42d1dcaryclark return; 2416fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 2417fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 24188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 241978cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, bounds) 24208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 24224e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPath(iter, path, looper.paint()); 24238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 24248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24254e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 24268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2428262a71b7f95ce98ff3dd8dba845afbd724470903reedbool SkCanvas::canDrawBitmapAsSprite(SkScalar x, SkScalar y, int w, int h, const SkPaint& paint) { 2429262a71b7f95ce98ff3dd8dba845afbd724470903reed if (!paint.getImageFilter()) { 2430262a71b7f95ce98ff3dd8dba845afbd724470903reed return false; 2431262a71b7f95ce98ff3dd8dba845afbd724470903reed } 2432262a71b7f95ce98ff3dd8dba845afbd724470903reed 2433262a71b7f95ce98ff3dd8dba845afbd724470903reed const SkMatrix& ctm = this->getTotalMatrix(); 2434c7e211acd0c9201688de7ff0c9a2271c67440adffmalita if (!SkTreatAsSprite(ctm, SkISize::Make(w, h), paint)) { 2435262a71b7f95ce98ff3dd8dba845afbd724470903reed return false; 2436262a71b7f95ce98ff3dd8dba845afbd724470903reed } 2437262a71b7f95ce98ff3dd8dba845afbd724470903reed 2438262a71b7f95ce98ff3dd8dba845afbd724470903reed // Currently we can only use the filterSprite code if we are clipped to the bitmap's bounds. 2439262a71b7f95ce98ff3dd8dba845afbd724470903reed // Once we can filter and the filter will return a result larger than itself, we should be 2440262a71b7f95ce98ff3dd8dba845afbd724470903reed // able to remove this constraint. 2441262a71b7f95ce98ff3dd8dba845afbd724470903reed // skbug.com/4526 2442262a71b7f95ce98ff3dd8dba845afbd724470903reed // 2443262a71b7f95ce98ff3dd8dba845afbd724470903reed SkPoint pt; 2444262a71b7f95ce98ff3dd8dba845afbd724470903reed ctm.mapXY(x, y, &pt); 2445262a71b7f95ce98ff3dd8dba845afbd724470903reed SkIRect ir = SkIRect::MakeXYWH(SkScalarRoundToInt(pt.x()), SkScalarRoundToInt(pt.y()), w, h); 2446262a71b7f95ce98ff3dd8dba845afbd724470903reed return ir.contains(fMCRec->fRasterClip.getBounds()); 2447262a71b7f95ce98ff3dd8dba845afbd724470903reed} 2448262a71b7f95ce98ff3dd8dba845afbd724470903reed 2449a85d4d0814818e4ddabb9237da209d61d6cd5854reedvoid SkCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, const SkPaint* paint) { 24509881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImage()"); 2451a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkRect bounds = SkRect::MakeXYWH(x, y, 2452a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkIntToScalar(image->width()), SkIntToScalar(image->height())); 245396fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 245487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect tmp = bounds; 245587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (paint) { 245687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco paint->computeFastBounds(tmp, &tmp); 245787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 245887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(tmp)) { 245987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 246087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 2461a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 24629d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2463a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkLazyPaint lazy; 246496fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 2465a85d4d0814818e4ddabb9237da209d61d6cd5854reed paint = lazy.init(); 2466a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2467262a71b7f95ce98ff3dd8dba845afbd724470903reed 2468a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed sk_sp<SkSpecialImage> special; 2469129ed1cd6d792f3f6cf563aefa9756fc6308289dreed bool drawAsSprite = this->canDrawBitmapAsSprite(x, y, image->width(), image->height(), 2470129ed1cd6d792f3f6cf563aefa9756fc6308289dreed *paint); 2471129ed1cd6d792f3f6cf563aefa9756fc6308289dreed if (drawAsSprite && paint->getImageFilter()) { 2472a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed special = this->getDevice()->makeSpecial(image); 2473a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (!special) { 2474129ed1cd6d792f3f6cf563aefa9756fc6308289dreed drawAsSprite = false; 2475129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 2476129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 2477129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 2478262a71b7f95ce98ff3dd8dba845afbd724470903reed LOOPER_BEGIN_DRAWBITMAP(*paint, drawAsSprite, &bounds) 2479262a71b7f95ce98ff3dd8dba845afbd724470903reed 2480a85d4d0814818e4ddabb9237da209d61d6cd5854reed while (iter.next()) { 2481262a71b7f95ce98ff3dd8dba845afbd724470903reed const SkPaint& pnt = looper.paint(); 2482a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (special) { 2483a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkPoint pt; 2484a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed iter.fMatrix->mapXY(x, y, &pt); 2485a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed iter.fDevice->drawSpecial(iter, special.get(), 2486a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkScalarRoundToInt(pt.fX), 2487a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkScalarRoundToInt(pt.fY), pnt); 2488262a71b7f95ce98ff3dd8dba845afbd724470903reed } else { 2489262a71b7f95ce98ff3dd8dba845afbd724470903reed iter.fDevice->drawImage(iter, image, x, y, pnt); 2490262a71b7f95ce98ff3dd8dba845afbd724470903reed } 2491a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 24929d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2493a85d4d0814818e4ddabb9237da209d61d6cd5854reed LOOPER_END 2494b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr} 2495b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 249641af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, 2497562fe4767cc73e08a4e039362bc0336aea66ecfbreed const SkPaint* paint, SrcRectConstraint constraint) { 24989881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImageRect()"); 249996fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 2500c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco SkRect storage = dst; 250187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (paint) { 250287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco paint->computeFastBounds(dst, &storage); 250387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 250487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(storage)) { 250587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 250687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 2507a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2508a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkLazyPaint lazy; 250996fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 2510a85d4d0814818e4ddabb9237da209d61d6cd5854reed paint = lazy.init(); 2511a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 25129d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2513c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, SkDrawFilter::kBitmap_Type, &dst, 2514c83a29759a5c2966da5ab973e4fd90763e4c962breed image->isOpaque()) 25159d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2516a85d4d0814818e4ddabb9237da209d61d6cd5854reed while (iter.next()) { 2517a5517e2b190a8083b38964972b031c13e99f1012reed iter.fDevice->drawImageRect(iter, image, src, dst, looper.paint(), constraint); 2518a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 25199d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2520a85d4d0814818e4ddabb9237da209d61d6cd5854reed LOOPER_END 2521b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr} 2522b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 252341af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y, const SkPaint* paint) { 25249881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmap()"); 25258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(bitmap.validate();) 25268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 252733366974d43eae80e22284a2e445225c343859dareed if (bitmap.drawsNothing()) { 252833366974d43eae80e22284a2e445225c343859dareed return; 252933366974d43eae80e22284a2e445225c343859dareed } 253033366974d43eae80e22284a2e445225c343859dareed 253133366974d43eae80e22284a2e445225c343859dareed SkLazyPaint lazy; 253233366974d43eae80e22284a2e445225c343859dareed if (nullptr == paint) { 253333366974d43eae80e22284a2e445225c343859dareed paint = lazy.init(); 253433366974d43eae80e22284a2e445225c343859dareed } 253533366974d43eae80e22284a2e445225c343859dareed 253633366974d43eae80e22284a2e445225c343859dareed const SkMatrix matrix = SkMatrix::MakeTrans(x, y); 253733366974d43eae80e22284a2e445225c343859dareed 253833366974d43eae80e22284a2e445225c343859dareed SkRect storage; 253933366974d43eae80e22284a2e445225c343859dareed const SkRect* bounds = nullptr; 254033366974d43eae80e22284a2e445225c343859dareed if (paint->canComputeFastBounds()) { 254133366974d43eae80e22284a2e445225c343859dareed bitmap.getBounds(&storage); 254233366974d43eae80e22284a2e445225c343859dareed matrix.mapRect(&storage); 254387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect tmp = storage; 254487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint->computeFastBounds(tmp, &tmp))) { 254587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 254687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 254787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &storage; 25488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 25494b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2550a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed sk_sp<SkSpecialImage> special; 2551129ed1cd6d792f3f6cf563aefa9756fc6308289dreed bool drawAsSprite = bounds && this->canDrawBitmapAsSprite(x, y, bitmap.width(), bitmap.height(), 2552129ed1cd6d792f3f6cf563aefa9756fc6308289dreed *paint); 2553129ed1cd6d792f3f6cf563aefa9756fc6308289dreed if (drawAsSprite && paint->getImageFilter()) { 2554a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed special = this->getDevice()->makeSpecial(bitmap); 2555a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (!special) { 2556129ed1cd6d792f3f6cf563aefa9756fc6308289dreed drawAsSprite = false; 2557129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 2558129ed1cd6d792f3f6cf563aefa9756fc6308289dreed } 2559129ed1cd6d792f3f6cf563aefa9756fc6308289dreed 2560262a71b7f95ce98ff3dd8dba845afbd724470903reed LOOPER_BEGIN_DRAWBITMAP(*paint, drawAsSprite, bounds) 256133366974d43eae80e22284a2e445225c343859dareed 256233366974d43eae80e22284a2e445225c343859dareed while (iter.next()) { 2563262a71b7f95ce98ff3dd8dba845afbd724470903reed const SkPaint& pnt = looper.paint(); 2564a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed if (special) { 2565262a71b7f95ce98ff3dd8dba845afbd724470903reed SkPoint pt; 2566262a71b7f95ce98ff3dd8dba845afbd724470903reed iter.fMatrix->mapXY(x, y, &pt); 2567a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed iter.fDevice->drawSpecial(iter, special.get(), 2568a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkScalarRoundToInt(pt.fX), 2569a2217ef965e57fdbbf989989e7ec1f2c04f62d39reed SkScalarRoundToInt(pt.fY), pnt); 2570262a71b7f95ce98ff3dd8dba845afbd724470903reed } else { 2571262a71b7f95ce98ff3dd8dba845afbd724470903reed iter.fDevice->drawBitmap(iter, bitmap, matrix, looper.paint()); 2572262a71b7f95ce98ff3dd8dba845afbd724470903reed } 257333366974d43eae80e22284a2e445225c343859dareed } 2574fbfa25802709139c2f14e304319c9541da65ca27msarett 257533366974d43eae80e22284a2e445225c343859dareed LOOPER_END 25768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 25778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25789987ec3791336bad6af5cbe513564786b2df55aareed@google.com// this one is non-virtual, so it can be called safely by other canvas apis 25797112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.comvoid SkCanvas::internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, 2580eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org const SkRect& dst, const SkPaint* paint, 2581a5517e2b190a8083b38964972b031c13e99f1012reed SrcRectConstraint constraint) { 258250b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org if (bitmap.drawsNothing() || dst.isEmpty()) { 25838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 25848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 258574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 258696fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 2587c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco SkRect storage; 258887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 258987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 259087e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 25918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 25923d60812865bb034851da777a91413ab584929887reed@google.com 259333535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com SkLazyPaint lazy; 259496fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 259533535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com paint = lazy.init(); 25968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 25977064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 2598c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, SkDrawFilter::kBitmap_Type, &dst, 2599c83a29759a5c2966da5ab973e4fd90763e4c962breed bitmap.isOpaque()) 26007064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 260133535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com while (iter.next()) { 2602562fe4767cc73e08a4e039362bc0336aea66ecfbreed iter.fDevice->drawBitmapRect(iter, bitmap, src, dst, looper.paint(), constraint); 2603f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 26047064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 260533535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com LOOPER_END 26068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 26078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 260841af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, 2609562fe4767cc73e08a4e039362bc0336aea66ecfbreed const SkPaint* paint, SrcRectConstraint constraint) { 26109881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmapRectToRect()"); 26119987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkDEBUGCODE(bitmap.validate();) 2612562fe4767cc73e08a4e039362bc0336aea66ecfbreed this->internalDrawBitmapRect(bitmap, src, dst, paint, constraint); 26139987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 26149987ec3791336bad6af5cbe513564786b2df55aareed@google.com 26154c21dc5ddf3b482293ed34eead876d8d61a662c3reedvoid SkCanvas::onDrawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst, 26164c21dc5ddf3b482293ed34eead876d8d61a662c3reed const SkPaint* paint) { 26174c21dc5ddf3b482293ed34eead876d8d61a662c3reed TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImageNine()"); 26189d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 261996fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 2620c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco SkRect storage; 262187e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 262287e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 262387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 26243d60812865bb034851da777a91413ab584929887reed@google.com } 26259d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 26264c21dc5ddf3b482293ed34eead876d8d61a662c3reed SkLazyPaint lazy; 262796fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 26284c21dc5ddf3b482293ed34eead876d8d61a662c3reed paint = lazy.init(); 26294c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 26309d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2631c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst) 26329d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 26334c21dc5ddf3b482293ed34eead876d8d61a662c3reed while (iter.next()) { 26344c21dc5ddf3b482293ed34eead876d8d61a662c3reed iter.fDevice->drawImageNine(iter, image, center, dst, looper.paint()); 26359987ec3791336bad6af5cbe513564786b2df55aareed@google.com } 26369d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 26374c21dc5ddf3b482293ed34eead876d8d61a662c3reed LOOPER_END 26389987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 26399987ec3791336bad6af5cbe513564786b2df55aareed@google.com 264041af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst, 264141af966ab338e95eee81ab618ab28195075338f7reed const SkPaint* paint) { 26429881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmapNine()"); 26439987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkDEBUGCODE(bitmap.validate();) 26449987ec3791336bad6af5cbe513564786b2df55aareed@google.com 264596fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint || paint->canComputeFastBounds()) { 2646c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco SkRect storage; 264787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 264887e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 264987e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 26504c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 26519d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 26524c21dc5ddf3b482293ed34eead876d8d61a662c3reed SkLazyPaint lazy; 265396fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 26544c21dc5ddf3b482293ed34eead876d8d61a662c3reed paint = lazy.init(); 26554c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 26569d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 2657c41e7e14f4a0076d277870502168ed870e558dfcsenorblanco LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst) 26589d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 26594c21dc5ddf3b482293ed34eead876d8d61a662c3reed while (iter.next()) { 26604c21dc5ddf3b482293ed34eead876d8d61a662c3reed iter.fDevice->drawBitmapNine(iter, bitmap, center, dst, looper.paint()); 26614c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 26629d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 26634c21dc5ddf3b482293ed34eead876d8d61a662c3reed LOOPER_END 26649987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 26659987ec3791336bad6af5cbe513564786b2df55aareed@google.com 2666168820625c35a8c19f66c661efcbce7a5e334837msarettvoid SkCanvas::onDrawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst, 2667168820625c35a8c19f66c661efcbce7a5e334837msarett const SkPaint* paint) { 2668168820625c35a8c19f66c661efcbce7a5e334837msarett if (nullptr == paint || paint->canComputeFastBounds()) { 2669168820625c35a8c19f66c661efcbce7a5e334837msarett SkRect storage; 2670168820625c35a8c19f66c661efcbce7a5e334837msarett if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 2671168820625c35a8c19f66c661efcbce7a5e334837msarett return; 2672168820625c35a8c19f66c661efcbce7a5e334837msarett } 2673168820625c35a8c19f66c661efcbce7a5e334837msarett } 2674168820625c35a8c19f66c661efcbce7a5e334837msarett 2675168820625c35a8c19f66c661efcbce7a5e334837msarett SkLazyPaint lazy; 2676168820625c35a8c19f66c661efcbce7a5e334837msarett if (nullptr == paint) { 2677168820625c35a8c19f66c661efcbce7a5e334837msarett paint = lazy.init(); 2678168820625c35a8c19f66c661efcbce7a5e334837msarett } 2679168820625c35a8c19f66c661efcbce7a5e334837msarett 2680168820625c35a8c19f66c661efcbce7a5e334837msarett LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst) 2681168820625c35a8c19f66c661efcbce7a5e334837msarett 2682168820625c35a8c19f66c661efcbce7a5e334837msarett while (iter.next()) { 2683168820625c35a8c19f66c661efcbce7a5e334837msarett iter.fDevice->drawImageLattice(iter, image, lattice, dst, looper.paint()); 2684168820625c35a8c19f66c661efcbce7a5e334837msarett } 2685168820625c35a8c19f66c661efcbce7a5e334837msarett 2686168820625c35a8c19f66c661efcbce7a5e334837msarett LOOPER_END 2687168820625c35a8c19f66c661efcbce7a5e334837msarett} 2688168820625c35a8c19f66c661efcbce7a5e334837msarett 2689168820625c35a8c19f66c661efcbce7a5e334837msarettvoid SkCanvas::onDrawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, 2690168820625c35a8c19f66c661efcbce7a5e334837msarett const SkRect& dst, const SkPaint* paint) { 2691168820625c35a8c19f66c661efcbce7a5e334837msarett if (nullptr == paint || paint->canComputeFastBounds()) { 2692168820625c35a8c19f66c661efcbce7a5e334837msarett SkRect storage; 2693168820625c35a8c19f66c661efcbce7a5e334837msarett if (this->quickReject(paint ? paint->computeFastBounds(dst, &storage) : dst)) { 2694168820625c35a8c19f66c661efcbce7a5e334837msarett return; 2695168820625c35a8c19f66c661efcbce7a5e334837msarett } 2696168820625c35a8c19f66c661efcbce7a5e334837msarett } 2697168820625c35a8c19f66c661efcbce7a5e334837msarett 2698168820625c35a8c19f66c661efcbce7a5e334837msarett SkLazyPaint lazy; 2699168820625c35a8c19f66c661efcbce7a5e334837msarett if (nullptr == paint) { 2700168820625c35a8c19f66c661efcbce7a5e334837msarett paint = lazy.init(); 2701168820625c35a8c19f66c661efcbce7a5e334837msarett } 2702168820625c35a8c19f66c661efcbce7a5e334837msarett 2703168820625c35a8c19f66c661efcbce7a5e334837msarett LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst) 2704168820625c35a8c19f66c661efcbce7a5e334837msarett 2705168820625c35a8c19f66c661efcbce7a5e334837msarett while (iter.next()) { 2706168820625c35a8c19f66c661efcbce7a5e334837msarett iter.fDevice->drawBitmapLattice(iter, bitmap, lattice, dst, looper.paint()); 2707168820625c35a8c19f66c661efcbce7a5e334837msarett } 2708168820625c35a8c19f66c661efcbce7a5e334837msarett 2709168820625c35a8c19f66c661efcbce7a5e334837msarett LOOPER_END 2710168820625c35a8c19f66c661efcbce7a5e334837msarett} 2711168820625c35a8c19f66c661efcbce7a5e334837msarett 2712f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.comclass SkDeviceFilteredPaint { 2713f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.compublic: 27141f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkDeviceFilteredPaint(SkBaseDevice* device, const SkPaint& paint) { 2715112e7e277702e104357f2d44742253ee1b0109acfmalita uint32_t filteredFlags = device->filterTextFlags(paint); 2716112e7e277702e104357f2d44742253ee1b0109acfmalita if (filteredFlags != paint.getFlags()) { 2717a076e9be17654a60310e72c4f70fcd5337f56dbfreed@google.com SkPaint* newPaint = fLazy.set(paint); 2718112e7e277702e104357f2d44742253ee1b0109acfmalita newPaint->setFlags(filteredFlags); 2719f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com fPaint = newPaint; 2720f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } else { 2721f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com fPaint = &paint; 2722f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } 2723f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } 2724f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 2725f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com const SkPaint& paint() const { return *fPaint; } 2726f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 2727f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.comprivate: 27282c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint* fPaint; 27292c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkLazyPaint fLazy; 2730f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com}; 2731f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 273252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.comvoid SkCanvas::DrawRect(const SkDraw& draw, const SkPaint& paint, 273352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com const SkRect& r, SkScalar textSize) { 273417b78946096265d80215a6c946286ecaa35ea7edepoger@google.com if (paint.getStyle() == SkPaint::kFill_Style) { 273552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com draw.fDevice->drawRect(draw, r, paint); 273652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } else { 273752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPaint p(paint); 273817b78946096265d80215a6c946286ecaa35ea7edepoger@google.com p.setStrokeWidth(SkScalarMul(textSize, paint.getStrokeWidth())); 273952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com draw.fDevice->drawRect(draw, r, p); 274052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 274152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com} 274252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 274352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.comvoid SkCanvas::DrawTextDecorations(const SkDraw& draw, const SkPaint& paint, 274452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com const char text[], size_t byteLength, 274552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar x, SkScalar y) { 274696fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkASSERT(byteLength == 0 || text != nullptr); 274752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 274852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com // nothing to draw 274996fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (text == nullptr || byteLength == 0 || 27501e7f5e708e5daeb0c18ae49001c9e3cd5e3b13cbreed draw.fRC->isEmpty() || 275196fcdcc219d2a0d3579719b84b28bede76efba64halcanary (paint.getAlpha() == 0 && paint.getXfermode() == nullptr)) { 275252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com return; 275352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 275452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 275552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar width = 0; 275652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPoint start; 275752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 275852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.set(0, 0); // to avoid warning 275952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (paint.getFlags() & (SkPaint::kUnderlineText_Flag | 276052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPaint::kStrikeThruText_Flag)) { 276152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com width = paint.measureText(text, byteLength); 276252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 276352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar offsetX = 0; 276452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (paint.getTextAlign() == SkPaint::kCenter_Align) { 276552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com offsetX = SkScalarHalf(width); 276652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } else if (paint.getTextAlign() == SkPaint::kRight_Align) { 276752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com offsetX = width; 276852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 276952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.set(x - offsetX, y); 277052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 277152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 277252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (0 == width) { 277352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com return; 277452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 277552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 277652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com uint32_t flags = paint.getFlags(); 277752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 277852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (flags & (SkPaint::kUnderlineText_Flag | 277952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPaint::kStrikeThruText_Flag)) { 278052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar textSize = paint.getTextSize(); 278152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar height = SkScalarMul(textSize, kStdUnderline_Thickness); 278252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkRect r; 278352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 278452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fLeft = start.fX; 278552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fRight = start.fX + width; 278652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 278752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (flags & SkPaint::kUnderlineText_Flag) { 278852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar offset = SkScalarMulAdd(textSize, kStdUnderline_Offset, 278952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.fY); 279052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fTop = offset; 279152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fBottom = offset + height; 2792fb56218292d6c7b509d382f39994c3783b2483a0caryclark DrawRect(draw, paint, r, 1); 279352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 279452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (flags & SkPaint::kStrikeThruText_Flag) { 279552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar offset = SkScalarMulAdd(textSize, kStdStrikeThru_Offset, 279652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.fY); 279752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fTop = offset; 279852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fBottom = offset + height; 2799fb56218292d6c7b509d382f39994c3783b2483a0caryclark DrawRect(draw, paint, r, 1); 280052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 280152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 280252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com} 280352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 2804e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 2805e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 280696fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 28078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 28094e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 2810f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com iter.fDevice->drawText(iter, text, byteLength, x, y, dfp.paint()); 281152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com DrawTextDecorations(iter, dfp.paint(), 281252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com static_cast<const char*>(text), byteLength, x, y); 28138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 28148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28154e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 28168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2818e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], 2819e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 282005c4a4322e7d4f3417b7df33825bab8603d52051fmalita SkPoint textOffset = SkPoint::Make(0, 0); 282105c4a4322e7d4f3417b7df33825bab8603d52051fmalita 282296fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 282387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 28248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 28254e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 282605c4a4322e7d4f3417b7df33825bab8603d52051fmalita iter.fDevice->drawPosText(iter, text, byteLength, &pos->fX, 2, textOffset, 2827f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com dfp.paint()); 28288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2829b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 28304e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 28318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2833e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], 2834e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com SkScalar constY, const SkPaint& paint) { 283505c4a4322e7d4f3417b7df33825bab8603d52051fmalita 283605c4a4322e7d4f3417b7df33825bab8603d52051fmalita SkPoint textOffset = SkPoint::Make(0, constY); 283705c4a4322e7d4f3417b7df33825bab8603d52051fmalita 283896fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 283987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 28408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 28414e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 284205c4a4322e7d4f3417b7df33825bab8603d52051fmalita iter.fDevice->drawPosText(iter, text, byteLength, xpos, 1, textOffset, 2843f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com dfp.paint()); 28448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2845b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 28464e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 28478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2849e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 2850e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkMatrix* matrix, const SkPaint& paint) { 285196fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 285287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 28538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 28548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawTextOnPath(iter, text, byteLength, path, 28554e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com matrix, looper.paint()); 28568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2857b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 2858945ec3a2bec668ca845071a65df8ec55e8f43819commit-bot@chromium.org LOOPER_END 28594325d114a5679e46f25ae75b0e43547fd7694998commit-bot@chromium.org} 28604325d114a5679e46f25ae75b0e43547fd7694998commit-bot@chromium.org 286145561a0b15fe045ba272c328684c3f7ae290785areedvoid SkCanvas::onDrawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[], 286245561a0b15fe045ba272c328684c3f7ae290785areed const SkRect* cullRect, const SkPaint& paint) { 286345561a0b15fe045ba272c328684c3f7ae290785areed if (cullRect && this->quickReject(*cullRect)) { 286445561a0b15fe045ba272c328684c3f7ae290785areed return; 286545561a0b15fe045ba272c328684c3f7ae290785areed } 286645561a0b15fe045ba272c328684c3f7ae290785areed 286745561a0b15fe045ba272c328684c3f7ae290785areed LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr) 286845561a0b15fe045ba272c328684c3f7ae290785areed 286945561a0b15fe045ba272c328684c3f7ae290785areed while (iter.next()) { 287045561a0b15fe045ba272c328684c3f7ae290785areed iter.fDevice->drawTextRSXform(iter, text, byteLength, xform, looper.paint()); 287145561a0b15fe045ba272c328684c3f7ae290785areed } 287245561a0b15fe045ba272c328684c3f7ae290785areed 287345561a0b15fe045ba272c328684c3f7ae290785areed LOOPER_END 287445561a0b15fe045ba272c328684c3f7ae290785areed} 287545561a0b15fe045ba272c328684c3f7ae290785areed 287600d5c2c6523321d25b32905ff4822f083a4173eefmalitavoid SkCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 287700d5c2c6523321d25b32905ff4822f083a4173eefmalita const SkPaint& paint) { 28787ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita 287985d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita SkRect storage; 288096fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr; 288119653d1d004610b4ba07ce563a5701164e120e45fmalita if (paint.canComputeFastBounds()) { 288285d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita storage = blob->bounds().makeOffset(x, y); 288387e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco SkRect tmp; 288487e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco if (this->quickReject(paint.computeFastBounds(storage, &tmp))) { 288587e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco return; 288687e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco } 288787e066ee80e094c8f4ccda3d6c33d907b414b91bsenorblanco bounds = &storage; 28887ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita } 28897ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita 2890024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita // We cannot filter in the looper as we normally do, because the paint is 2891024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita // incomplete at this point (text-related attributes are embedded within blob run paints). 2892024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita SkDrawFilter* drawFilter = fMCRec->fFilter; 289396fcdcc219d2a0d3579719b84b28bede76efba64halcanary fMCRec->fFilter = nullptr; 2894024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita 289585d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, bounds) 289600d5c2c6523321d25b32905ff4822f083a4173eefmalita 2897aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita while (iter.next()) { 2898aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 2899024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita iter.fDevice->drawTextBlob(iter, blob, x, y, dfp.paint(), drawFilter); 290000d5c2c6523321d25b32905ff4822f083a4173eefmalita } 290100d5c2c6523321d25b32905ff4822f083a4173eefmalita 2902aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita LOOPER_END 2903024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita 2904024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita fMCRec->fFilter = drawFilter; 290500d5c2c6523321d25b32905ff4822f083a4173eefmalita} 290600d5c2c6523321d25b32905ff4822f083a4173eefmalita 2907e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com// These will become non-virtual, so they always call the (virtual) onDraw... method 2908e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 2909e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 29109881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawText()"); 2911ac09554dce518e9d4496771f648f3ae17eca857creed if (byteLength) { 2912ac09554dce518e9d4496771f648f3ae17eca857creed this->onDrawText(text, byteLength, x, y, paint); 2913ac09554dce518e9d4496771f648f3ae17eca857creed } 2914e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2915e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawPosText(const void* text, size_t byteLength, const SkPoint pos[], 2916e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 29179881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPosText()"); 2918ac09554dce518e9d4496771f648f3ae17eca857creed if (byteLength) { 2919ac09554dce518e9d4496771f648f3ae17eca857creed this->onDrawPosText(text, byteLength, pos, paint); 2920ac09554dce518e9d4496771f648f3ae17eca857creed } 2921e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2922e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], 2923e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com SkScalar constY, const SkPaint& paint) { 29249881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPosTextH()"); 2925ac09554dce518e9d4496771f648f3ae17eca857creed if (byteLength) { 2926ac09554dce518e9d4496771f648f3ae17eca857creed this->onDrawPosTextH(text, byteLength, xpos, constY, paint); 2927ac09554dce518e9d4496771f648f3ae17eca857creed } 2928e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2929e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 2930e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkMatrix* matrix, const SkPaint& paint) { 29319881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextOnPath()"); 2932ac09554dce518e9d4496771f648f3ae17eca857creed if (byteLength) { 2933ac09554dce518e9d4496771f648f3ae17eca857creed this->onDrawTextOnPath(text, byteLength, path, matrix, paint); 2934ac09554dce518e9d4496771f648f3ae17eca857creed } 2935e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 293645561a0b15fe045ba272c328684c3f7ae290785areedvoid SkCanvas::drawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[], 293745561a0b15fe045ba272c328684c3f7ae290785areed const SkRect* cullRect, const SkPaint& paint) { 293845561a0b15fe045ba272c328684c3f7ae290785areed TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextRSXform()"); 293945561a0b15fe045ba272c328684c3f7ae290785areed if (byteLength) { 294045561a0b15fe045ba272c328684c3f7ae290785areed this->onDrawTextRSXform(text, byteLength, xform, cullRect, paint); 294145561a0b15fe045ba272c328684c3f7ae290785areed } 294245561a0b15fe045ba272c328684c3f7ae290785areed} 294300d5c2c6523321d25b32905ff4822f083a4173eefmalitavoid SkCanvas::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 294400d5c2c6523321d25b32905ff4822f083a4173eefmalita const SkPaint& paint) { 2945e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(blob); 29469881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextBlob()"); 2947e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawTextBlob(blob, x, y, paint); 294800d5c2c6523321d25b32905ff4822f083a4173eefmalita} 2949e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com 295041af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawVertices(VertexMode vmode, int vertexCount, 295141af966ab338e95eee81ab618ab28195075338f7reed const SkPoint verts[], const SkPoint texs[], 295241af966ab338e95eee81ab618ab28195075338f7reed const SkColor colors[], SkXfermode* xmode, 295341af966ab338e95eee81ab618ab28195075338f7reed const uint16_t indices[], int indexCount, 295441af966ab338e95eee81ab618ab28195075338f7reed const SkPaint& paint) { 29559881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawVertices()"); 295696fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, nullptr) 29574b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 29588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 29598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawVertices(iter, vmode, vertexCount, verts, texs, 29604e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com colors, xmode, indices, indexCount, 29614e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com looper.paint()); 29628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 29634b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 29644e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 29658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 29668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2967b3c9d1c33caf325aada244204215eb790c228c12dandovvoid SkCanvas::drawPatch(const SkPoint cubics[12], const SkColor colors[4], 2968b3c9d1c33caf325aada244204215eb790c228c12dandov const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint) { 29699881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPatch()"); 297096fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == cubics) { 2971b3c9d1c33caf325aada244204215eb790c228c12dandov return; 2972b3c9d1c33caf325aada244204215eb790c228c12dandov } 29736cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2974ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov // Since a patch is always within the convex hull of the control points, we discard it when its 2975ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov // bounding rectangle is completely outside the current clip. 2976ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov SkRect bounds; 2977b3c9d1c33caf325aada244204215eb790c228c12dandov bounds.set(cubics, SkPatchUtils::kNumCtrlPts); 2978ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov if (this->quickReject(bounds)) { 2979ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov return; 2980ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov } 29816cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2982b3c9d1c33caf325aada244204215eb790c228c12dandov this->onDrawPatch(cubics, colors, texCoords, xmode, paint); 2983b3c9d1c33caf325aada244204215eb790c228c12dandov} 2984b3c9d1c33caf325aada244204215eb790c228c12dandov 2985b3c9d1c33caf325aada244204215eb790c228c12dandovvoid SkCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], 2986b3c9d1c33caf325aada244204215eb790c228c12dandov const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint) { 2987b3c9d1c33caf325aada244204215eb790c228c12dandov 298896fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, nullptr) 29896cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2990ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov while (iter.next()) { 2991b3c9d1c33caf325aada244204215eb790c228c12dandov iter.fDevice->drawPatch(iter, cubics, colors, texCoords, xmode, paint); 2992ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov } 29936cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2994ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov LOOPER_END 2995ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov} 2996ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov 2997a8db72864a43ad1fbba3c2892cf5cd88060a43efreedvoid SkCanvas::drawDrawable(SkDrawable* dr, SkScalar x, SkScalar y) { 2998e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(dr); 2999e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed if (x || y) { 3000e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed SkMatrix matrix = SkMatrix::MakeTrans(x, y); 3001e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawDrawable(dr, &matrix); 3002e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed } else { 3003e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawDrawable(dr, nullptr); 3004a8db72864a43ad1fbba3c2892cf5cd88060a43efreed } 3005a8db72864a43ad1fbba3c2892cf5cd88060a43efreed} 3006a8db72864a43ad1fbba3c2892cf5cd88060a43efreed 3007a8db72864a43ad1fbba3c2892cf5cd88060a43efreedvoid SkCanvas::drawDrawable(SkDrawable* dr, const SkMatrix* matrix) { 3008e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(dr); 3009e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed if (matrix && matrix->isIdentity()) { 3010e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed matrix = nullptr; 30116a070dc06af4e9f305f9d08a69e34d18ade473cbreed } 3012e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawDrawable(dr, matrix); 30136a070dc06af4e9f305f9d08a69e34d18ade473cbreed} 30146a070dc06af4e9f305f9d08a69e34d18ade473cbreed 3015a8db72864a43ad1fbba3c2892cf5cd88060a43efreedvoid SkCanvas::onDrawDrawable(SkDrawable* dr, const SkMatrix* matrix) { 3016a8db72864a43ad1fbba3c2892cf5cd88060a43efreed SkRect bounds = dr->getBounds(); 3017a8db72864a43ad1fbba3c2892cf5cd88060a43efreed if (matrix) { 3018a8db72864a43ad1fbba3c2892cf5cd88060a43efreed matrix->mapRect(&bounds); 3019a8db72864a43ad1fbba3c2892cf5cd88060a43efreed } 3020a8db72864a43ad1fbba3c2892cf5cd88060a43efreed if (this->quickReject(bounds)) { 3021a8db72864a43ad1fbba3c2892cf5cd88060a43efreed return; 3022a8db72864a43ad1fbba3c2892cf5cd88060a43efreed } 3023a8db72864a43ad1fbba3c2892cf5cd88060a43efreed dr->draw(this, matrix); 30246a070dc06af4e9f305f9d08a69e34d18ade473cbreed} 30256a070dc06af4e9f305f9d08a69e34d18ade473cbreed 302671c3c760a83123ee0b3127b8c65c6394ce541c50reedvoid SkCanvas::onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], 302771c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkColor colors[], int count, SkXfermode::Mode mode, 302871c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkRect* cull, const SkPaint* paint) { 302971c3c760a83123ee0b3127b8c65c6394ce541c50reed if (cull && this->quickReject(*cull)) { 303071c3c760a83123ee0b3127b8c65c6394ce541c50reed return; 303171c3c760a83123ee0b3127b8c65c6394ce541c50reed } 303271c3c760a83123ee0b3127b8c65c6394ce541c50reed 303371c3c760a83123ee0b3127b8c65c6394ce541c50reed SkPaint pnt; 303471c3c760a83123ee0b3127b8c65c6394ce541c50reed if (paint) { 303571c3c760a83123ee0b3127b8c65c6394ce541c50reed pnt = *paint; 303671c3c760a83123ee0b3127b8c65c6394ce541c50reed } 30379d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 303896fcdcc219d2a0d3579719b84b28bede76efba64halcanary LOOPER_BEGIN(pnt, SkDrawFilter::kPath_Type, nullptr) 303971c3c760a83123ee0b3127b8c65c6394ce541c50reed while (iter.next()) { 304071c3c760a83123ee0b3127b8c65c6394ce541c50reed iter.fDevice->drawAtlas(iter, atlas, xform, tex, colors, count, mode, pnt); 304171c3c760a83123ee0b3127b8c65c6394ce541c50reed } 304271c3c760a83123ee0b3127b8c65c6394ce541c50reed LOOPER_END 304371c3c760a83123ee0b3127b8c65c6394ce541c50reed} 304471c3c760a83123ee0b3127b8c65c6394ce541c50reed 3045f70b531daaf47db1ee95c70da9843f1dd1f418d3reedvoid SkCanvas::onDrawAnnotation(const SkRect& rect, const char key[], SkData* value) { 3046f70b531daaf47db1ee95c70da9843f1dd1f418d3reed SkASSERT(key); 3047f70b531daaf47db1ee95c70da9843f1dd1f418d3reed 3048f70b531daaf47db1ee95c70da9843f1dd1f418d3reed SkPaint paint; 3049f70b531daaf47db1ee95c70da9843f1dd1f418d3reed LOOPER_BEGIN(paint, SkDrawFilter::kRect_Type, nullptr) 3050f70b531daaf47db1ee95c70da9843f1dd1f418d3reed while (iter.next()) { 3051f70b531daaf47db1ee95c70da9843f1dd1f418d3reed iter.fDevice->drawAnnotation(iter, rect, key, value); 3052f70b531daaf47db1ee95c70da9843f1dd1f418d3reed } 3053f70b531daaf47db1ee95c70da9843f1dd1f418d3reed LOOPER_END 3054f70b531daaf47db1ee95c70da9843f1dd1f418d3reed} 3055f70b531daaf47db1ee95c70da9843f1dd1f418d3reed 30568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 30578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// These methods are NOT virtual, and therefore must call back into virtual 30588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// methods, rather than actually drawing themselves. 30598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 30608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b, 3062845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com SkXfermode::Mode mode) { 30639881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawARGB()"); 30648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 30658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setARGB(a, r, g, b); 3067845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com if (SkXfermode::kSrcOver_Mode != mode) { 30680baf19375466cfc24c96532df406e7c5b1d1aae8reed@android.com paint.setXfermodeMode(mode); 30698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 30708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPaint(paint); 30718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 30728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3073845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.comvoid SkCanvas::drawColor(SkColor c, SkXfermode::Mode mode) { 30749881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawColor()"); 30758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 30768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setColor(c); 3078845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com if (SkXfermode::kSrcOver_Mode != mode) { 30790baf19375466cfc24c96532df406e7c5b1d1aae8reed@android.com paint.setXfermodeMode(mode); 30808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 30818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPaint(paint); 30828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 30838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPoint(SkScalar x, SkScalar y, const SkPaint& paint) { 30859881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPoint(SkPaint)"); 30868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pt; 30874b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 30888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pt.set(x, y); 30898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kPoints_PointMode, 1, &pt, paint); 30908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 30918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPoint(SkScalar x, SkScalar y, SkColor color) { 30939881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPoint(SkColor)"); 30948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pt; 30958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 30964b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 30978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pt.set(x, y); 30988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setColor(color); 30998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kPoints_PointMode, 1, &pt, paint); 31008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 31018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 31028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, 31038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 31049881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawLine()"); 31058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pts[2]; 31064b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 31078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pts[0].set(x0, y0); 31088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pts[1].set(x1, y1); 31098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kLines_PointMode, 2, pts, paint); 31108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 31118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 31128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawRectCoords(SkScalar left, SkScalar top, 31138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar right, SkScalar bottom, 31148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 31159881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRectCoords()"); 31168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 31178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 31188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.set(left, top, right, bottom); 31198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawRect(r, paint); 31208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 31218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 31228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, 31238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 31249881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawCircle()"); 31258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (radius < 0) { 31268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com radius = 0; 31278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 31288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 31298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 31308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.set(cx - radius, cy - radius, cx + radius, cy + radius); 31314ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->drawOval(r, paint); 31328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 31338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 31348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawRoundRect(const SkRect& r, SkScalar rx, SkScalar ry, 31358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 31369881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRoundRect()"); 31378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (rx > 0 && ry > 0) { 31384ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com SkRRect rrect; 31394ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com rrect.setRectXY(r, rx, ry); 31404ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->drawRRect(rrect, paint); 31418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 31428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawRect(r, paint); 31438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 31448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 31458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 31468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawArc(const SkRect& oval, SkScalar startAngle, 31478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar sweepAngle, bool useCenter, 31488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 31499881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawArc()"); 315021af9ca1b1f54d9ba1de055aa8475928d5c8ecdfbsalomon if (oval.isEmpty() || !sweepAngle) { 315121af9ca1b1f54d9ba1de055aa8475928d5c8ecdfbsalomon return; 31528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 315321af9ca1b1f54d9ba1de055aa8475928d5c8ecdfbsalomon this->onDrawArc(oval, startAngle, sweepAngle, useCenter, paint); 31548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 31558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 31568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawTextOnPathHV(const void* text, size_t byteLength, 31578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPath& path, SkScalar hOffset, 31588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar vOffset, const SkPaint& paint) { 31599881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextOnPathHV()"); 31608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 31614b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 31628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.setTranslate(hOffset, vOffset); 31638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawTextOnPath(text, byteLength, path, &matrix, paint); 31648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 31658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3166f76bacff7f66724072c67edb185abf9e3add11a0reed@android.com/////////////////////////////////////////////////////////////////////////////// 31671c2c441fede0ae9573afc098017011e3439624a9reed 31681c2c441fede0ae9573afc098017011e3439624a9reed/** 31691c2c441fede0ae9573afc098017011e3439624a9reed * This constant is trying to balance the speed of ref'ing a subpicture into a parent picture, 31701c2c441fede0ae9573afc098017011e3439624a9reed * against the playback cost of recursing into the subpicture to get at its actual ops. 31711c2c441fede0ae9573afc098017011e3439624a9reed * 31721c2c441fede0ae9573afc098017011e3439624a9reed * For now we pick a conservatively small value, though measurement (and other heuristics like 31731c2c441fede0ae9573afc098017011e3439624a9reed * the type of ops contained) may justify changing this value. 31741c2c441fede0ae9573afc098017011e3439624a9reed */ 31751c2c441fede0ae9573afc098017011e3439624a9reed#define kMaxPictureOpsToUnrollInsteadOfRef 1 31769b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips 3177d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedvoid SkCanvas::drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint) { 3178e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed RETURN_ON_NULL(picture); 3179e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed 31801c2c441fede0ae9573afc098017011e3439624a9reed TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPicture()"); 3181e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed if (matrix && matrix->isIdentity()) { 3182e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed matrix = nullptr; 3183e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed } 3184e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed if (picture->approximateOpCount() <= kMaxPictureOpsToUnrollInsteadOfRef) { 3185e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); 3186e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed picture->playback(this); 3187e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed } else { 3188e3b38ce43b5c5c6711e9cde4588e2bc15333c780reed this->onDrawPicture(picture, matrix, paint); 3189d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 3190d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 31919b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips 3192d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedvoid SkCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix, 3193d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed const SkPaint* paint) { 3194d028180f0310cf2b23f9744256a41697b0683e67fmalita if (!paint || paint->canComputeFastBounds()) { 3195d028180f0310cf2b23f9744256a41697b0683e67fmalita SkRect bounds = picture->cullRect(); 3196d028180f0310cf2b23f9744256a41697b0683e67fmalita if (paint) { 3197d028180f0310cf2b23f9744256a41697b0683e67fmalita paint->computeFastBounds(bounds, &bounds); 3198d028180f0310cf2b23f9744256a41697b0683e67fmalita } 3199d028180f0310cf2b23f9744256a41697b0683e67fmalita if (matrix) { 3200d028180f0310cf2b23f9744256a41697b0683e67fmalita matrix->mapRect(&bounds); 3201d028180f0310cf2b23f9744256a41697b0683e67fmalita } 3202d028180f0310cf2b23f9744256a41697b0683e67fmalita if (this->quickReject(bounds)) { 3203d028180f0310cf2b23f9744256a41697b0683e67fmalita return; 3204d028180f0310cf2b23f9744256a41697b0683e67fmalita } 3205d028180f0310cf2b23f9744256a41697b0683e67fmalita } 3206d028180f0310cf2b23f9744256a41697b0683e67fmalita 3207a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); 3208c5ba71d2e5cd426def66fa49dcf003e5b2c98dc7robertphillips picture->playback(this); 32098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 32108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 321195302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack#ifdef SK_EXPERIMENTAL_SHADOWING 321295302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblackvoid SkCanvas::drawShadowedPicture(const SkPicture* picture, 321395302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack const SkMatrix* matrix, 3214e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack const SkPaint* paint, 3215e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack const SkShadowParams& params) { 321695302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack RETURN_ON_NULL(picture); 321795302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack 321895302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawShadowedPicture()"); 321995302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack 3220e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack this->onDrawShadowedPicture(picture, matrix, paint, params); 322195302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack} 322295302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack 322395302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblackvoid SkCanvas::onDrawShadowedPicture(const SkPicture* picture, 322495302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack const SkMatrix* matrix, 3225e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack const SkPaint* paint, 3226e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack const SkShadowParams& params) { 3227904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack if (!paint || paint->canComputeFastBounds()) { 3228904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack SkRect bounds = picture->cullRect(); 3229904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack if (paint) { 3230904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack paint->computeFastBounds(bounds, &bounds); 3231904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack } 3232904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack if (matrix) { 3233904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack matrix->mapRect(&bounds); 3234904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack } 3235904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack if (this->quickReject(bounds)) { 3236904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack return; 3237904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack } 3238904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack } 3239904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3240904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); 3241904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3242e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack sk_sp<SkImage> povDepthMap; 3243e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack sk_sp<SkImage> diffuseMap; 3244e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack 3245904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack // povDepthMap 3246904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack { 3247904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack SkLights::Builder builder; 3248772b5ee446d7545eec4ca7d6dc9d75461e2a9c38vjiaoblack builder.add(SkLights::Light::MakeDirectional(SkColor3f::Make(1.0f, 1.0f, 1.0f), 3249772b5ee446d7545eec4ca7d6dc9d75461e2a9c38vjiaoblack SkVector3::Make(0.0f, 0.0f, 1.0f))); 3250904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack sk_sp<SkLights> povLight = builder.finish(); 3251904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3252904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack SkImageInfo info = SkImageInfo::Make(picture->cullRect().width(), 3253904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack picture->cullRect().height(), 3254904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack kBGRA_8888_SkColorType, 3255904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack kOpaque_SkAlphaType); 3256904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3257904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack // Create a new surface (that matches the backend of canvas) 3258904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack // to create the povDepthMap 3259904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack sk_sp<SkSurface> surf(this->makeSurface(info)); 3260904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3261904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack // Wrap another SPFCanvas around the surface 3262904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack sk_sp<SkShadowPaintFilterCanvas> depthMapCanvas = 3263904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack sk_make_sp<SkShadowPaintFilterCanvas>(surf->getCanvas()); 3264904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3265904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack // set the depth map canvas to have the light as the user's POV 3266904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack depthMapCanvas->setLights(std::move(povLight)); 3267904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3268904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack depthMapCanvas->drawPicture(picture); 3269904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack povDepthMap = surf->makeImageSnapshot(); 3270904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack } 3271904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3272904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack // diffuseMap 3273904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack { 3274904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack SkImageInfo info = SkImageInfo::Make(picture->cullRect().width(), 3275904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack picture->cullRect().height(), 3276904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack kBGRA_8888_SkColorType, 3277904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack kOpaque_SkAlphaType); 3278904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3279904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack sk_sp<SkSurface> surf(this->makeSurface(info)); 3280904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack surf->getCanvas()->drawPicture(picture); 3281904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3282904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack diffuseMap = surf->makeImageSnapshot(); 3283904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack } 3284904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3285904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack sk_sp<SkShader> povDepthShader = povDepthMap->makeShader(SkShader::kClamp_TileMode, 3286904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack SkShader::kClamp_TileMode); 3287904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack sk_sp<SkShader> diffuseShader = diffuseMap->makeShader(SkShader::kClamp_TileMode, 3288904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack SkShader::kClamp_TileMode); 3289b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3290b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // TODO: pass the depth to the shader in vertices, or uniforms 3291b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // so we don't have to render depth and color separately 3292b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack for (int i = 0; i < fLights->numLights(); ++i) { 3293b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // skip over ambient lights; they don't cast shadows 3294b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // lights that have shadow maps do not need updating (because lights are immutable) 3295b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack sk_sp<SkImage> depthMap; 3296b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkISize shMapSize; 3297b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3298b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack if (fLights->light(i).getShadowMap() != nullptr) { 3299b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack continue; 3300b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack } 3301b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3302b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack if (fLights->light(i).isRadial()) { 3303b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack shMapSize.fHeight = 1; 3304b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack shMapSize.fWidth = (int) picture->cullRect().width(); 3305b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3306b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkImageInfo info = SkImageInfo::Make(diffuseMap->width(), 1, 3307b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack kBGRA_8888_SkColorType, 3308b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack kOpaque_SkAlphaType); 3309b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3310b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // Create new surface (that matches the backend of canvas) 3311b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // for each shadow map 3312b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack sk_sp<SkSurface> surf(this->makeSurface(info)); 3313b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3314b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // Wrap another SPFCanvas around the surface 3315b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkCanvas* depthMapCanvas = surf->getCanvas(); 3316b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3317b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkLights::Builder builder; 3318b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack builder.add(fLights->light(i)); 3319b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack sk_sp<SkLights> curLight = builder.finish(); 3320b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3321b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack sk_sp<SkShader> shadowMapShader; 3322b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack shadowMapShader = SkRadialShadowMapShader::Make( 3323b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack povDepthShader, curLight, 3324b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack (int) picture->cullRect().width(), 3325b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack (int) picture->cullRect().height()); 3326b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3327b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkPaint shadowMapPaint; 3328b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack shadowMapPaint.setShader(std::move(shadowMapShader)); 3329b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3330b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack depthMapCanvas->setLights(curLight); 3331b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3332b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack depthMapCanvas->drawRect(SkRect::MakeIWH(diffuseMap->width(), 3333b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack diffuseMap->height()), 3334b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack shadowMapPaint); 3335b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3336b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack depthMap = surf->makeImageSnapshot(); 3337b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3338b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack } else { 3339b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // TODO: compute the correct size of the depth map from the light properties 3340b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // TODO: maybe add a kDepth_8_SkColorType 3341b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // TODO: find actual max depth of picture 3342b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack shMapSize = SkShadowPaintFilterCanvas::ComputeDepthMapSize( 3343b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack fLights->light(i), 255, 3344b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack (int) picture->cullRect().width(), 3345b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack (int) picture->cullRect().height()); 3346b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3347b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkImageInfo info = SkImageInfo::Make(shMapSize.fWidth, shMapSize.fHeight, 3348b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack kBGRA_8888_SkColorType, 3349b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack kOpaque_SkAlphaType); 3350b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3351b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // Create a new surface (that matches the backend of canvas) 3352b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // for each shadow map 3353b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack sk_sp<SkSurface> surf(this->makeSurface(info)); 3354b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3355b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // Wrap another SPFCanvas around the surface 3356b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack sk_sp<SkShadowPaintFilterCanvas> depthMapCanvas = 3357b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack sk_make_sp<SkShadowPaintFilterCanvas>(surf->getCanvas()); 3358b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack depthMapCanvas->setShadowParams(params); 3359b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3360b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // set the depth map canvas to have the light we're drawing. 3361b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkLights::Builder builder; 3362b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack builder.add(fLights->light(i)); 3363b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack sk_sp<SkLights> curLight = builder.finish(); 3364b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack depthMapCanvas->setLights(std::move(curLight)); 3365b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3366b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack depthMapCanvas->drawPicture(picture); 3367b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack depthMap = surf->makeImageSnapshot(); 3368b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack } 3369b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3370b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack if (params.fType == SkShadowParams::kNoBlur_ShadowType) { 3371b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack fLights->light(i).setShadowMap(std::move(depthMap)); 3372b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack } else if (params.fType == SkShadowParams::kVariance_ShadowType) { 3373b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack // we blur the variance map 3374b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkPaint blurPaint; 3375b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack blurPaint.setImageFilter(SkImageFilter::MakeBlur(params.fShadowRadius, 3376b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack params.fShadowRadius, nullptr)); 3377b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3378b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkImageInfo blurInfo = SkImageInfo::Make(shMapSize.fWidth, shMapSize.fHeight, 3379b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack kBGRA_8888_SkColorType, 3380b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack kOpaque_SkAlphaType); 3381b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3382b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack sk_sp<SkSurface> blurSurf(this->makeSurface(blurInfo)); 3383b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3384b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack blurSurf->getCanvas()->drawImage(std::move(depthMap), 0, 0, &blurPaint); 3385b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3386b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack fLights->light(i).setShadowMap(blurSurf->makeImageSnapshot()); 3387b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack } 3388b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack } 3389b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack 3390b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack SkPaint shadowPaint; 3391904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack sk_sp<SkShader> shadowShader = SkShadowShader::Make(std::move(povDepthShader), 3392904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack std::move(diffuseShader), 3393b2796fdd9eab88836795d6a54cf6811af6ecdc81vjiaoblack fLights, 3394904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack diffuseMap->width(), 3395e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack diffuseMap->height(), 3396e6f5d5623160a69e1585f5121a3695092327dfe0vjiaoblack params); 3397904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3398904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack shadowPaint.setShader(shadowShader); 3399904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack 3400904527d165ce98c9fbaa9c05d3890070e3132170vjiaoblack this->drawRect(SkRect::MakeIWH(diffuseMap->width(), diffuseMap->height()), shadowPaint); 340195302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack} 340295302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack#endif 340395302da19d8b0a3bcd9d9be0e79f486760787f09vjiaoblack 34048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 34058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 34068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 34073aafe111b6cc388400092851cc53bbbdfcb8a81creedSkCanvas::LayerIter::LayerIter(SkCanvas* canvas) { 340899fe82260633fcf5d92cca38d12ef0937ecca61cbungeman static_assert(sizeof(fStorage) >= sizeof(SkDrawIter), "fStorage_too_small"); 34098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 34108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(canvas); 34118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 34123aafe111b6cc388400092851cc53bbbdfcb8a81creed fImpl = new (fStorage) SkDrawIter(canvas); 34138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDone = !fImpl->next(); 34148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 34158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 34168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::LayerIter::~LayerIter() { 34178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fImpl->~SkDrawIter(); 34188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 34198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 34208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::LayerIter::next() { 34218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDone = !fImpl->next(); 34228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 34238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 34241f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::LayerIter::device() const { 34258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fImpl->getDevice(); 34268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 34278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 34288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkMatrix& SkCanvas::LayerIter::matrix() const { 34298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fImpl->getMatrix(); 34308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 34318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 34328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkPaint& SkCanvas::LayerIter::paint() const { 34338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* paint = fImpl->getPaint(); 343496fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == paint) { 34358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint = &fDefaultPaint; 34368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 34378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return *paint; 34388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 34398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 34401e7f5e708e5daeb0c18ae49001c9e3cd5e3b13cbreedconst SkRasterClip& SkCanvas::LayerIter::clip() const { return fImpl->getClip(); } 34418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::LayerIter::x() const { return fImpl->getX(); } 34428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::LayerIter::y() const { return fImpl->getY(); } 344320a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com 344420a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com/////////////////////////////////////////////////////////////////////////////// 344520a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com 3446c3b589a24eb4d567a906189f882c259ecf5c2f58fmalitaSkCanvasClipVisitor::~SkCanvasClipVisitor() { } 34473107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 34483107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 34493107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 34503107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.orgstatic bool supported_for_raster_canvas(const SkImageInfo& info) { 34513107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org switch (info.alphaType()) { 34523107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kPremul_SkAlphaType: 34533107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kOpaque_SkAlphaType: 34543107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org break; 34553107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org default: 34563107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return false; 34573107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 34583107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 34593107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org switch (info.colorType()) { 34603107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kAlpha_8_SkColorType: 34613107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kRGB_565_SkColorType: 346228fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org case kN32_SkColorType: 34633107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org break; 34643107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org default: 34653107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return false; 34663107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 34673107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 34683107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return true; 34693107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org} 34703107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 347142b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.orgSkCanvas* SkCanvas::NewRasterDirect(const SkImageInfo& info, void* pixels, size_t rowBytes) { 347242b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org if (!supported_for_raster_canvas(info)) { 347396fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 347442b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org } 3475eb849e5fd10cbe00cbc31307ba97fd9efca0b41bskia.committer@gmail.com 347642b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org SkBitmap bitmap; 347742b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org if (!bitmap.installPixels(info, pixels, rowBytes)) { 347896fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 347942b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org } 3480385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return new SkCanvas(bitmap); 348142b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org} 3482d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 3483d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed/////////////////////////////////////////////////////////////////////////////// 3484d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 3485d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedSkAutoCanvasMatrixPaint::SkAutoCanvasMatrixPaint(SkCanvas* canvas, const SkMatrix* matrix, 3486a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips const SkPaint* paint, const SkRect& bounds) 3487d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed : fCanvas(canvas) 3488d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed , fSaveCount(canvas->getSaveCount()) 3489d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed{ 349049f085dddff10473b6ebf832a974288300224e60bsalomon if (paint) { 3491a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkRect newBounds = bounds; 3492d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed if (matrix) { 3493a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips matrix->mapRect(&newBounds); 3494d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 3495a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips canvas->saveLayer(&newBounds, paint); 349649f085dddff10473b6ebf832a974288300224e60bsalomon } else if (matrix) { 3497d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed canvas->save(); 3498d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 34996cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 350049f085dddff10473b6ebf832a974288300224e60bsalomon if (matrix) { 3501d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed canvas->concat(*matrix); 3502d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 3503d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 3504d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 3505d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedSkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { 3506d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed fCanvas->restoreToCount(fSaveCount); 3507d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 3508e8f3062a36d3682f4019309a32b5b84dc9eddf8creed 3509e8f3062a36d3682f4019309a32b5b84dc9eddf8creed#ifdef SK_SUPPORT_LEGACY_NEW_SURFACE_API 3510e8f3062a36d3682f4019309a32b5b84dc9eddf8creedSkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* props) { 3511e8f3062a36d3682f4019309a32b5b84dc9eddf8creed return this->makeSurface(info, props).release(); 3512e8f3062a36d3682f4019309a32b5b84dc9eddf8creed} 3513e8f3062a36d3682f4019309a32b5b84dc9eddf8creed#endif 3514