SkCanvas.cpp revision e47829b6b1eeb6b0c97ccb3df3016d197046824c
18a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2008 The Android Open Source Project 38a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 68a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8d3ebb48320cf1b7e969974673e4bd7743816985ebungeman#include "SkBitmapDevice.h" 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h" 10d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed#include "SkCanvasPriv.h" 11d3ebb48320cf1b7e969974673e4bd7743816985ebungeman#include "SkClipStack.h" 12dbc3cefb0b624808ddb86d444e6103f216e12fa5reed#include "SkColorFilter.h" 13d3ebb48320cf1b7e969974673e4bd7743816985ebungeman#include "SkDevice.h" 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDraw.h" 153cb3840c9af6f70896cf5565a38d4ee03c02d767reed#include "SkDrawable.h" 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDrawFilter.h" 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDrawLooper.h" 185f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt#include "SkErrorInternals.h" 19b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr#include "SkImage.h" 2074bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org#include "SkMetaData.h" 214c21dc5ddf3b482293ed34eead876d8d61a662c3reed#include "SkNinePatchIter.h" 22c83a29759a5c2966da5ab973e4fd90763e4c962breed#include "SkPaintPriv.h" 23b3c9d1c33caf325aada244204215eb790c228c12dandov#include "SkPatchUtils.h" 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPicture.h" 250017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com#include "SkRasterClip.h" 2696472deea70169396b8e1f576e470138f55fdb1freed#include "SkReadPixelsRec.h" 274ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com#include "SkRRect.h" 2879fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org#include "SkSmallAllocator.h" 2997af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com#include "SkSurface_Base.h" 307ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita#include "SkTextBlob.h" 3152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com#include "SkTextFormatParams.h" 32a076e9be17654a60310e72c4f70fcd5337f56dbfreed@google.com#include "SkTLazy.h" 338f757f540a8378c7b1354aab3d4650eaa920b17adanakj#include "SkTraceEvent.h" 34d3ebb48320cf1b7e969974673e4bd7743816985ebungeman 35d3ebb48320cf1b7e969974673e4bd7743816985ebungeman#include <new> 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 37644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#if SK_SUPPORT_GPU 38644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#include "GrRenderTarget.h" 39644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#endif 40644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org 41c83a29759a5c2966da5ab973e4fd90763e4c962breed/* 42c83a29759a5c2966da5ab973e4fd90763e4c962breed * Return true if the drawing this rect would hit every pixels in the canvas. 43c83a29759a5c2966da5ab973e4fd90763e4c962breed * 44c83a29759a5c2966da5ab973e4fd90763e4c962breed * Returns false if 45c83a29759a5c2966da5ab973e4fd90763e4c962breed * - rect does not contain the canvas' bounds 46c83a29759a5c2966da5ab973e4fd90763e4c962breed * - paint is not fill 47c83a29759a5c2966da5ab973e4fd90763e4c962breed * - paint would blur or otherwise change the coverage of the rect 48c83a29759a5c2966da5ab973e4fd90763e4c962breed */ 49c83a29759a5c2966da5ab973e4fd90763e4c962breedbool SkCanvas::wouldOverwriteEntireSurface(const SkRect* rect, const SkPaint* paint, 50c83a29759a5c2966da5ab973e4fd90763e4c962breed ShaderOverrideOpacity overrideOpacity) const { 51c83a29759a5c2966da5ab973e4fd90763e4c962breed SK_COMPILE_ASSERT((int)SkPaintPriv::kNone_ShaderOverrideOpacity == 52c83a29759a5c2966da5ab973e4fd90763e4c962breed (int)kNone_ShaderOverrideOpacity, 53c83a29759a5c2966da5ab973e4fd90763e4c962breed need_matching_enums0); 54c83a29759a5c2966da5ab973e4fd90763e4c962breed SK_COMPILE_ASSERT((int)SkPaintPriv::kOpaque_ShaderOverrideOpacity == 55c83a29759a5c2966da5ab973e4fd90763e4c962breed (int)kOpaque_ShaderOverrideOpacity, 56c83a29759a5c2966da5ab973e4fd90763e4c962breed need_matching_enums1); 57c83a29759a5c2966da5ab973e4fd90763e4c962breed SK_COMPILE_ASSERT((int)SkPaintPriv::kNotOpaque_ShaderOverrideOpacity == 58c83a29759a5c2966da5ab973e4fd90763e4c962breed (int)kNotOpaque_ShaderOverrideOpacity, 59c83a29759a5c2966da5ab973e4fd90763e4c962breed need_matching_enums2); 60c83a29759a5c2966da5ab973e4fd90763e4c962breed 61c83a29759a5c2966da5ab973e4fd90763e4c962breed const SkISize size = this->getBaseLayerSize(); 62c83a29759a5c2966da5ab973e4fd90763e4c962breed const SkRect bounds = SkRect::MakeIWH(size.width(), size.height()); 63c83a29759a5c2966da5ab973e4fd90763e4c962breed if (!this->getClipStack()->quickContains(bounds)) { 64c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; 65c83a29759a5c2966da5ab973e4fd90763e4c962breed } 66c83a29759a5c2966da5ab973e4fd90763e4c962breed 67c83a29759a5c2966da5ab973e4fd90763e4c962breed if (rect) { 68c83a29759a5c2966da5ab973e4fd90763e4c962breed if (!this->getTotalMatrix().rectStaysRect()) { 69c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; // conservative 70c83a29759a5c2966da5ab973e4fd90763e4c962breed } 71c83a29759a5c2966da5ab973e4fd90763e4c962breed 72c83a29759a5c2966da5ab973e4fd90763e4c962breed SkRect devRect; 73c83a29759a5c2966da5ab973e4fd90763e4c962breed this->getTotalMatrix().mapRect(&devRect, *rect); 748c0144ccb17220db9d5140ef5ee85d5bc7837513fmalita if (!devRect.contains(bounds)) { 75c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; 76c83a29759a5c2966da5ab973e4fd90763e4c962breed } 77c83a29759a5c2966da5ab973e4fd90763e4c962breed } 78c83a29759a5c2966da5ab973e4fd90763e4c962breed 79c83a29759a5c2966da5ab973e4fd90763e4c962breed if (paint) { 80c83a29759a5c2966da5ab973e4fd90763e4c962breed SkPaint::Style paintStyle = paint->getStyle(); 81c83a29759a5c2966da5ab973e4fd90763e4c962breed if (!(paintStyle == SkPaint::kFill_Style || 82c83a29759a5c2966da5ab973e4fd90763e4c962breed paintStyle == SkPaint::kStrokeAndFill_Style)) { 83c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; 84c83a29759a5c2966da5ab973e4fd90763e4c962breed } 85c83a29759a5c2966da5ab973e4fd90763e4c962breed if (paint->getMaskFilter() || paint->getLooper() 86c83a29759a5c2966da5ab973e4fd90763e4c962breed || paint->getPathEffect() || paint->getImageFilter()) { 87c83a29759a5c2966da5ab973e4fd90763e4c962breed return false; // conservative 88c83a29759a5c2966da5ab973e4fd90763e4c962breed } 89c83a29759a5c2966da5ab973e4fd90763e4c962breed } 90c83a29759a5c2966da5ab973e4fd90763e4c962breed return SkPaintPriv::Overwrites(paint, (SkPaintPriv::ShaderOverrideOpacity)overrideOpacity); 91c83a29759a5c2966da5ab973e4fd90763e4c962breed} 92c83a29759a5c2966da5ab973e4fd90763e4c962breed 93c83a29759a5c2966da5ab973e4fd90763e4c962breed/////////////////////////////////////////////////////////////////////////////////////////////////// 94c83a29759a5c2966da5ab973e4fd90763e4c962breed 95d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareedstatic bool gIgnoreSaveLayerBounds; 96d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareedvoid SkCanvas::Internal_Private_SetIgnoreSaveLayerBounds(bool ignore) { 97d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed gIgnoreSaveLayerBounds = ignore; 98d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed} 99d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareedbool SkCanvas::Internal_Private_GetIgnoreSaveLayerBounds() { 100d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed return gIgnoreSaveLayerBounds; 101d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed} 102d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed 1030acf1b4b3645772d220c720313821bac389751b5reedstatic bool gTreatSpriteAsBitmap; 1040acf1b4b3645772d220c720313821bac389751b5reedvoid SkCanvas::Internal_Private_SetTreatSpriteAsBitmap(bool spriteAsBitmap) { 1050acf1b4b3645772d220c720313821bac389751b5reed gTreatSpriteAsBitmap = spriteAsBitmap; 1060acf1b4b3645772d220c720313821bac389751b5reed} 1070acf1b4b3645772d220c720313821bac389751b5reedbool SkCanvas::Internal_Private_GetTreatSpriteAsBitmap() { 1080acf1b4b3645772d220c720313821bac389751b5reed return gTreatSpriteAsBitmap; 1090acf1b4b3645772d220c720313821bac389751b5reed} 1100acf1b4b3645772d220c720313821bac389751b5reed 111da17f758442f16747af39f8fbaed9c097048519creed@google.com// experimental for faster tiled drawing... 112da17f758442f16747af39f8fbaed9c097048519creed@google.com//#define SK_ENABLE_CLIP_QUICKREJECT 11315e9d3e66e161ce23df30bc13f8a0c87d196b463robertphillips@google.com 1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//#define SK_TRACE_SAVERESTORE 1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_TRACE_SAVERESTORE 1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gLayerCounter; 1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_layer() { ++gLayerCounter; printf("----- inc layer %d\n", gLayerCounter); } 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_layer() { --gLayerCounter; printf("----- dec layer %d\n", gLayerCounter); } 1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gRecCounter; 1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_rec() { ++gRecCounter; printf("----- inc rec %d\n", gRecCounter); } 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_rec() { --gRecCounter; printf("----- dec rec %d\n", gRecCounter); } 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gCanvasCounter; 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_canvas() { ++gCanvasCounter; printf("----- inc canvas %d\n", gCanvasCounter); } 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_canvas() { --gCanvasCounter; printf("----- dec canvas %d\n", gCanvasCounter); } 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_layer() 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_layer() 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_rec() 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_rec() 1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_canvas() 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_canvas() 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1372c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.orgtypedef SkTLazy<SkPaint> SkLazyPaint; 1382c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org 139c83a29759a5c2966da5ab973e4fd90763e4c962breedvoid SkCanvas::predrawNotify(bool willOverwritesEntireSurface) { 14097af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com if (fSurfaceBase) { 141c83a29759a5c2966da5ab973e4fd90763e4c962breed fSurfaceBase->aboutToDraw(willOverwritesEntireSurface 142c83a29759a5c2966da5ab973e4fd90763e4c962breed ? SkSurface::kDiscard_ContentChangeMode 143c83a29759a5c2966da5ab973e4fd90763e4c962breed : SkSurface::kRetain_ContentChangeMode); 144c83a29759a5c2966da5ab973e4fd90763e4c962breed } 145c83a29759a5c2966da5ab973e4fd90763e4c962breed} 146c83a29759a5c2966da5ab973e4fd90763e4c962breed 147c83a29759a5c2966da5ab973e4fd90763e4c962breedvoid SkCanvas::predrawNotify(const SkRect* rect, const SkPaint* paint, 148c83a29759a5c2966da5ab973e4fd90763e4c962breed ShaderOverrideOpacity overrideOpacity) { 149c83a29759a5c2966da5ab973e4fd90763e4c962breed if (fSurfaceBase) { 150c83a29759a5c2966da5ab973e4fd90763e4c962breed SkSurface::ContentChangeMode mode = SkSurface::kRetain_ContentChangeMode; 151c83a29759a5c2966da5ab973e4fd90763e4c962breed // Since willOverwriteAllPixels() may not be complete free to call, we only do so if 152c83a29759a5c2966da5ab973e4fd90763e4c962breed // there is an outstanding snapshot, since w/o that, there will be no copy-on-write 153c83a29759a5c2966da5ab973e4fd90763e4c962breed // and therefore we don't care which mode we're in. 154c83a29759a5c2966da5ab973e4fd90763e4c962breed // 155c83a29759a5c2966da5ab973e4fd90763e4c962breed if (fSurfaceBase->outstandingImageSnapshot()) { 156c83a29759a5c2966da5ab973e4fd90763e4c962breed if (this->wouldOverwriteEntireSurface(rect, paint, overrideOpacity)) { 157c83a29759a5c2966da5ab973e4fd90763e4c962breed mode = SkSurface::kDiscard_ContentChangeMode; 158c83a29759a5c2966da5ab973e4fd90763e4c962breed } 159c83a29759a5c2966da5ab973e4fd90763e4c962breed } 160c83a29759a5c2966da5ab973e4fd90763e4c962breed fSurfaceBase->aboutToDraw(mode); 16197af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com } 16297af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com} 16397af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com 1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1664a8126e7f81384526629b1e21bf89b632ea13cd9reedstatic uint32_t filter_paint_flags(const SkSurfaceProps& props, uint32_t flags) { 1674a8126e7f81384526629b1e21bf89b632ea13cd9reed const uint32_t propFlags = props.flags(); 1684a8126e7f81384526629b1e21bf89b632ea13cd9reed if (propFlags & SkSurfaceProps::kDisallowDither_Flag) { 1694a8126e7f81384526629b1e21bf89b632ea13cd9reed flags &= ~SkPaint::kDither_Flag; 1704a8126e7f81384526629b1e21bf89b632ea13cd9reed } 1714a8126e7f81384526629b1e21bf89b632ea13cd9reed if (propFlags & SkSurfaceProps::kDisallowAntiAlias_Flag) { 1724a8126e7f81384526629b1e21bf89b632ea13cd9reed flags &= ~SkPaint::kAntiAlias_Flag; 1734a8126e7f81384526629b1e21bf89b632ea13cd9reed } 1744a8126e7f81384526629b1e21bf89b632ea13cd9reed return flags; 1754a8126e7f81384526629b1e21bf89b632ea13cd9reed} 1764a8126e7f81384526629b1e21bf89b632ea13cd9reed 1774a8126e7f81384526629b1e21bf89b632ea13cd9reed/////////////////////////////////////////////////////////////////////////////// 1784a8126e7f81384526629b1e21bf89b632ea13cd9reed 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; 19361f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed const bool fDeviceIsBitmapDevice; 1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19596e657d0e103b8358a77ecd913f6086929f792b8reed DeviceCM(SkBaseDevice* device, const SkPaint* paint, SkCanvas* canvas, 19686a17e7716c8db858e219a46b9db3817bb770beereed bool conservativeRasterClip, bool deviceIsBitmapDevice) 197d954498c01ccf0417feacf89e45d0c62a06a813breed : fNext(NULL) 198d954498c01ccf0417feacf89e45d0c62a06a813breed , fClip(conservativeRasterClip) 19961f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed , fDeviceIsBitmapDevice(deviceIsBitmapDevice) 200d954498c01ccf0417feacf89e45d0c62a06a813breed { 201d954498c01ccf0417feacf89e45d0c62a06a813breed if (NULL != device) { 2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device->ref(); 20340a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com device->onAttachToCanvas(canvas); 2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2054b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com fDevice = device; 2068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint = paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL; 20788edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20988edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com ~DeviceCM() { 21049f085dddff10473b6ebf832a974288300224e60bsalomon if (fDevice) { 21140a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com fDevice->onDetachFromCanvas(); 2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDevice->unref(); 2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 21488edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com SkDELETE(fPaint); 21588edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 2164b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 217feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein void reset(const SkIRect& bounds) { 218feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(!fPaint); 219feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(!fNext); 220feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(fDevice); 221feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fClip.setRect(bounds); 222feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein } 223feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 224045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com void updateMC(const SkMatrix& totalMatrix, const SkRasterClip& totalClip, 225045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com const SkClipStack& clipStack, SkRasterClip* updateClip) { 2266f8f292aa768869a9e85c314b124875f57504f2creed@google.com int x = fDevice->getOrigin().x(); 2276f8f292aa768869a9e85c314b124875f57504f2creed@google.com int y = fDevice->getOrigin().y(); 2288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int width = fDevice->width(); 2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int height = fDevice->height(); 2304b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if ((x | y) == 0) { 2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = &totalMatrix; 2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fClip = totalClip; 2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrixStorage = totalMatrix; 2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrixStorage.postTranslate(SkIntToScalar(-x), 2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIntToScalar(-y)); 2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = &fMatrixStorage; 2394b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com totalClip.translate(-x, -y, &fClip); 2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 243045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com fClip.op(SkIRect::MakeWH(width, height), SkRegion::kIntersect_Op); 2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // intersect clip, but don't translate it (yet) 2464b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (updateClip) { 248045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com updateClip->op(SkIRect::MakeXYWH(x, y, width, height), 2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRegion::kDifference_Op); 2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2514b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2523fffb2ee9fa01ae61efb2395973eb7575eda4c96robertphillips@google.com fDevice->setMatrixClip(*fMatrix, fClip.forceGetBW(), clipStack); 2533fffb2ee9fa01ae61efb2395973eb7575eda4c96robertphillips@google.com 2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!fClip.isEmpty()) { 2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIRect deviceR; 2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com deviceR.set(0, 0, width, height); 2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(deviceR.contains(fClip.getBounds())); 2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 261f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* This is the record we keep for each save/restore level in the stack. 2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Since a level optionally copies the matrix and/or stack, we have pointers 2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for these fields. If the value is copied for this level, the copy is 2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stored in the ...Storage field, and the pointer points to that. If the 2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value is not copied for this level, we ignore ...Storage, and just point 2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com at the corresponding value in the previous level in the stack. 2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkCanvas::MCRec { 2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 2731f836ee096bb988adef4b9757b2629c7afeda36dreed SkDrawFilter* fFilter; // the current filter (or null) 274d954498c01ccf0417feacf89e45d0c62a06a813breed DeviceCM* fLayer; 2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* If there are any layers in the stack, this points to the top-most 2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com one that is at or below this level in the stack (so we know what 2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bitmap/device to draw into from this level. This value is NOT 2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com reference counted, since the real owner is either our fLayer field, 2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com or a previous one in a lower level.) 2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 2812ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed DeviceCM* fTopLayer; 2822ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkRasterClip fRasterClip; 2832ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkMatrix fMatrix; 2842ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed int fDeferredSaveCount; 2858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 286d954498c01ccf0417feacf89e45d0c62a06a813breed MCRec(bool conservativeRasterClip) : fRasterClip(conservativeRasterClip) { 287d954498c01ccf0417feacf89e45d0c62a06a813breed fFilter = NULL; 288d954498c01ccf0417feacf89e45d0c62a06a813breed fLayer = NULL; 289d954498c01ccf0417feacf89e45d0c62a06a813breed fTopLayer = NULL; 2902ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fMatrix.reset(); 2912ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fDeferredSaveCount = 0; 292b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 293d954498c01ccf0417feacf89e45d0c62a06a813breed // don't bother initializing fNext 294d954498c01ccf0417feacf89e45d0c62a06a813breed inc_rec(); 295d954498c01ccf0417feacf89e45d0c62a06a813breed } 2962ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed MCRec(const MCRec& prev) : fRasterClip(prev.fRasterClip), fMatrix(prev.fMatrix) { 297d954498c01ccf0417feacf89e45d0c62a06a813breed fFilter = SkSafeRef(prev.fFilter); 2988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLayer = NULL; 299d954498c01ccf0417feacf89e45d0c62a06a813breed fTopLayer = prev.fTopLayer; 3002ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fDeferredSaveCount = 0; 301b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 3028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // don't bother initializing fNext 3038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inc_rec(); 3048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ~MCRec() { 30682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fFilter); 3078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDELETE(fLayer); 3088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dec_rec(); 3098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 310feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 311feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein void reset(const SkIRect& bounds) { 312feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(fLayer); 313feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(fDeferredSaveCount == 0); 314feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 315feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fMatrix.reset(); 316feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fRasterClip.setRect(bounds); 317feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fLayer->reset(bounds); 318feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein } 3198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkDrawIter : public SkDraw { 3228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 3238a0b0291ae4260ef2a46f4341c18a702c0ce3f8btomhudson@google.com SkDrawIter(SkCanvas* canvas, bool skipEmptyClips = true) { 3244370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com canvas = canvas->canvasForDrawIter(); 3258a0b0291ae4260ef2a46f4341c18a702c0ce3f8btomhudson@google.com fCanvas = canvas; 3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com canvas->updateDeviceCMCache(); 3278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 328687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack = canvas->fClipStack; 3298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = canvas->fMCRec->fTopLayer; 3308a0b0291ae4260ef2a46f4341c18a702c0ce3f8btomhudson@google.com fSkipEmptyClips = skipEmptyClips; 3318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3324b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 3338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool next() { 3348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // skip over recs with empty clips 3358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fSkipEmptyClips) { 3368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (fCurrLayer && fCurrLayer->fClip.isEmpty()) { 3378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = fCurrLayer->fNext; 3388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 341f68c5e2f9f05b3af2bae0979ace2684b6041b6e3reed@google.com const DeviceCM* rec = fCurrLayer; 342f68c5e2f9f05b3af2bae0979ace2684b6041b6e3reed@google.com if (rec && rec->fDevice) { 3438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = rec->fMatrix; 345045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com fClip = &((SkRasterClip*)&rec->fClip)->forceGetBW(); 346045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com fRC = &rec->fClip; 3478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDevice = rec->fDevice; 34841e010cb901c0da9066c4df562030808c9ccd7f8reed if (!fDevice->accessPixels(&fDst)) { 34941e010cb901c0da9066c4df562030808c9ccd7f8reed fDst.reset(fDevice->imageInfo(), NULL, 0); 35041e010cb901c0da9066c4df562030808c9ccd7f8reed } 3518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint = rec->fPaint; 352f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com SkDEBUGCODE(this->validate();) 3538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = rec->fNext; 3558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // fCurrLayer may be NULL now 356199f108f14a5f60a9c2205ffa79b26102a206ad0reed@android.com 3578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 3588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 3608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3614b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 3621f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* getDevice() const { return fDevice; } 3636f8f292aa768869a9e85c314b124875f57504f2creed@google.com int getX() const { return fDevice->getOrigin().x(); } 3646f8f292aa768869a9e85c314b124875f57504f2creed@google.com int getY() const { return fDevice->getOrigin().y(); } 3658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& getMatrix() const { return *fMatrix; } 3668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkRegion& getClip() const { return *fClip; } 3678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* getPaint() const { return fPaint; } 3686f8f292aa768869a9e85c314b124875f57504f2creed@google.com 3698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 3708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkCanvas* fCanvas; 3718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const DeviceCM* fCurrLayer; 3728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* fPaint; // May be null. 3738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkBool8 fSkipEmptyClips; 3748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef SkDraw INHERITED; 3768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////// 3798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 380dbc3cefb0b624808ddb86d444e6103f216e12fa5reedstatic SkPaint* set_if_needed(SkLazyPaint* lazy, const SkPaint& orig) { 381dbc3cefb0b624808ddb86d444e6103f216e12fa5reed return lazy->isValid() ? lazy->get() : lazy->set(orig); 382dbc3cefb0b624808ddb86d444e6103f216e12fa5reed} 383dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 384dbc3cefb0b624808ddb86d444e6103f216e12fa5reed/** 385dbc3cefb0b624808ddb86d444e6103f216e12fa5reed * If the paint has an imagefilter, but it can be simplified to just a colorfilter, return that 386dbc3cefb0b624808ddb86d444e6103f216e12fa5reed * colorfilter, else return NULL. 387dbc3cefb0b624808ddb86d444e6103f216e12fa5reed */ 388dbc3cefb0b624808ddb86d444e6103f216e12fa5reedstatic SkColorFilter* image_to_color_filter(const SkPaint& paint) { 389dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkImageFilter* imgf = paint.getImageFilter(); 390dbc3cefb0b624808ddb86d444e6103f216e12fa5reed if (!imgf) { 391dbc3cefb0b624808ddb86d444e6103f216e12fa5reed return NULL; 392dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 393dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 394dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkColorFilter* imgCF; 395dbc3cefb0b624808ddb86d444e6103f216e12fa5reed if (!imgf->asAColorFilter(&imgCF)) { 396dbc3cefb0b624808ddb86d444e6103f216e12fa5reed return NULL; 397dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 398dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 399dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkColorFilter* paintCF = paint.getColorFilter(); 400dbc3cefb0b624808ddb86d444e6103f216e12fa5reed if (NULL == paintCF) { 401dbc3cefb0b624808ddb86d444e6103f216e12fa5reed // there is no existing paint colorfilter, so we can just return the imagefilter's 402dbc3cefb0b624808ddb86d444e6103f216e12fa5reed return imgCF; 403dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 404dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 405dbc3cefb0b624808ddb86d444e6103f216e12fa5reed // The paint has both a colorfilter(paintCF) and an imagefilter-which-is-a-colorfilter(imgCF) 406dbc3cefb0b624808ddb86d444e6103f216e12fa5reed // and we need to combine them into a single colorfilter. 407dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkAutoTUnref<SkColorFilter> autoImgCF(imgCF); 408dbc3cefb0b624808ddb86d444e6103f216e12fa5reed return SkColorFilter::CreateComposeFilter(imgCF, paintCF); 409dbc3cefb0b624808ddb86d444e6103f216e12fa5reed} 410dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 4118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass AutoDrawLooper { 4128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 4134a8126e7f81384526629b1e21bf89b632ea13cd9reed AutoDrawLooper(SkCanvas* canvas, const SkSurfaceProps& props, const SkPaint& paint, 41478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bool skipLayerForImageFilter = false, 41578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL) : fOrigPaint(paint) { 4164e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fCanvas = canvas; 4178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFilter = canvas->getDrawFilter(); 4184a8126e7f81384526629b1e21bf89b632ea13cd9reed fPaint = &fOrigPaint; 4194e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fSaveCount = canvas->getSaveCount(); 4205c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed fTempLayerForImageFilter = false; 4214e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fDone = false; 4228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 423dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkColorFilter* simplifiedCF = image_to_color_filter(fOrigPaint); 424dbc3cefb0b624808ddb86d444e6103f216e12fa5reed if (simplifiedCF) { 425dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkPaint* paint = set_if_needed(&fLazyPaintInit, fOrigPaint); 426dbc3cefb0b624808ddb86d444e6103f216e12fa5reed paint->setColorFilter(simplifiedCF)->unref(); 427dbc3cefb0b624808ddb86d444e6103f216e12fa5reed paint->setImageFilter(NULL); 428dbc3cefb0b624808ddb86d444e6103f216e12fa5reed fPaint = paint; 429dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 430dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 431dbc3cefb0b624808ddb86d444e6103f216e12fa5reed if (!skipLayerForImageFilter && fPaint->getImageFilter()) { 4325c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed /** 4335c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * We implement ImageFilters for a given draw by creating a layer, then applying the 4345c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * imagefilter to the pixels of that layer (its backing surface/image), and then 4355c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * we call restore() to xfer that layer to the main canvas. 4365c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 4375c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 1. SaveLayer (with a paint containing the current imagefilter and xfermode) 4385c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 2. Generate the src pixels: 4395c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * Remove the imagefilter and the xfermode from the paint that we (AutoDrawLooper) 4405c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * return (fPaint). We then draw the primitive (using srcover) into a cleared 4415c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * buffer/surface. 4425c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 3. Restore the layer created in #1 4435c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * The imagefilter is passed the buffer/surface from the layer (now filled with the 4445c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * src pixels of the primitive). It returns a new "filtered" buffer, which we 4455c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * draw onto the previous layer using the xfermode from the original paint. 4465c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed */ 4478926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkPaint tmp; 448dbc3cefb0b624808ddb86d444e6103f216e12fa5reed tmp.setImageFilter(fPaint->getImageFilter()); 449dbc3cefb0b624808ddb86d444e6103f216e12fa5reed tmp.setXfermode(fPaint->getXfermode()); 450e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org (void)canvas->internalSaveLayer(bounds, &tmp, SkCanvas::kARGB_ClipLayer_SaveFlag, 45176033be81b82c44fd5d4fdf2672eb22e505da1f0reed SkCanvas::kFullLayer_SaveLayerStrategy); 4525c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed fTempLayerForImageFilter = true; 4535c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed // we remove the imagefilter/xfermode inside doNext() 4548926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 4558926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 45679fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (SkDrawLooper* looper = paint.getLooper()) { 45779fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org void* buffer = fLooperContextAllocator.reserveT<SkDrawLooper::Context>( 45879fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org looper->contextSize()); 45979fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org fLooperContext = looper->createContext(canvas, buffer); 460129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fIsSimple = false; 461129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else { 46279fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org fLooperContext = NULL; 463129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // can we be marked as simple? 4645c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed fIsSimple = !fFilter && !fTempLayerForImageFilter; 4658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 466b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 4674a8126e7f81384526629b1e21bf89b632ea13cd9reed uint32_t oldFlags = paint.getFlags(); 4684a8126e7f81384526629b1e21bf89b632ea13cd9reed fNewPaintFlags = filter_paint_flags(props, oldFlags); 4694a8126e7f81384526629b1e21bf89b632ea13cd9reed if (fIsSimple && (fNewPaintFlags != oldFlags)) { 470dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkPaint* paint = set_if_needed(&fLazyPaintInit, fOrigPaint); 4714a8126e7f81384526629b1e21bf89b632ea13cd9reed paint->setFlags(fNewPaintFlags); 4724a8126e7f81384526629b1e21bf89b632ea13cd9reed fPaint = paint; 4734a8126e7f81384526629b1e21bf89b632ea13cd9reed // if we're not simple, doNext() will take care of calling setFlags() 4744a8126e7f81384526629b1e21bf89b632ea13cd9reed } 4758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 47674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 4774e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com ~AutoDrawLooper() { 4785c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed if (fTempLayerForImageFilter) { 4798926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com fCanvas->internalRestore(); 4808926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 4814e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkASSERT(fCanvas->getSaveCount() == fSaveCount); 4828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 48374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 4844e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com const SkPaint& paint() const { 4854e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkASSERT(fPaint); 4864e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return *fPaint; 4874e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 48874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 489129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool next(SkDrawFilter::Type drawType) { 490129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com if (fDone) { 491129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return false; 492129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else if (fIsSimple) { 493129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fDone = true; 494129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return !fPaint->nothingToDraw(); 495129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else { 496129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return this->doNext(drawType); 497129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 498fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 49974b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 5008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 501dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkLazyPaint fLazyPaintInit; // base paint storage in case we need to modify it 502dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkLazyPaint fLazyPaintPerLooper; // per-draw-looper storage, so the looper can modify it 5032c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkCanvas* fCanvas; 5042c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint& fOrigPaint; 5052c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkDrawFilter* fFilter; 5062c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint* fPaint; 5072c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org int fSaveCount; 5084a8126e7f81384526629b1e21bf89b632ea13cd9reed uint32_t fNewPaintFlags; 5095c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed bool fTempLayerForImageFilter; 5102c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org bool fDone; 511129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool fIsSimple; 51279fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkDrawLooper::Context* fLooperContext; 51379fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkSmallAllocator<1, 32> fLooperContextAllocator; 514129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com 515129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool doNext(SkDrawFilter::Type drawType); 5168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 5178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 518129ec22cb054592261e001294c430c9dd4e90ff4reed@google.combool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) { 519632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com fPaint = NULL; 520129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com SkASSERT(!fIsSimple); 5215c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed SkASSERT(fLooperContext || fFilter || fTempLayerForImageFilter); 522632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com 523dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkPaint* paint = fLazyPaintPerLooper.set(fLazyPaintInit.isValid() ? 524dbc3cefb0b624808ddb86d444e6103f216e12fa5reed *fLazyPaintInit.get() : fOrigPaint); 5254a8126e7f81384526629b1e21bf89b632ea13cd9reed paint->setFlags(fNewPaintFlags); 5268926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 5275c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed if (fTempLayerForImageFilter) { 528129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com paint->setImageFilter(NULL); 5295c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed paint->setXfermode(NULL); 530129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 5318926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 53279fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (fLooperContext && !fLooperContext->next(fCanvas, paint)) { 533129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fDone = true; 534129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return false; 535129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 536129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com if (fFilter) { 537971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com if (!fFilter->filter(paint, drawType)) { 538971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com fDone = true; 539971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com return false; 540971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com } 54179fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (NULL == fLooperContext) { 542129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // no looper means we only draw once 543632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com fDone = true; 544632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com } 545129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 546129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fPaint = paint; 5478926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 548129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // if we only came in here for the imagefilter, mark us as done 54979fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (!fLooperContext && !fFilter) { 5504e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fDone = true; 5514e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 5524e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com 553632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com // call this after any possible paint modifiers 554632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com if (fPaint->nothingToDraw()) { 5554e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fPaint = NULL; 5564e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return false; 5574e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 5584e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return true; 5594e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com} 5604e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com 5618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////// macros to place around the internal draw calls ////////////////// 5628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5638926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com#define LOOPER_BEGIN_DRAWDEVICE(paint, type) \ 56497af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com this->predrawNotify(); \ 5654a8126e7f81384526629b1e21bf89b632ea13cd9reed AutoDrawLooper looper(this, fProps, paint, true); \ 5668926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com while (looper.next(type)) { \ 5678926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkDrawIter iter(this); 5688926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 56978cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org#define LOOPER_BEGIN(paint, type, bounds) \ 57097af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com this->predrawNotify(); \ 5714a8126e7f81384526629b1e21bf89b632ea13cd9reed AutoDrawLooper looper(this, fProps, paint, false, bounds); \ 5724e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com while (looper.next(type)) { \ 5738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDrawIter iter(this); 5744b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 575c83a29759a5c2966da5ab973e4fd90763e4c962breed#define LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, type, bounds, auxOpaque) \ 576c83a29759a5c2966da5ab973e4fd90763e4c962breed this->predrawNotify(bounds, &paint, auxOpaque); \ 577c83a29759a5c2966da5ab973e4fd90763e4c962breed AutoDrawLooper looper(this, fProps, paint, false, bounds); \ 578c83a29759a5c2966da5ab973e4fd90763e4c962breed while (looper.next(type)) { \ 579c83a29759a5c2966da5ab973e4fd90763e4c962breed SkDrawIter iter(this); 580c83a29759a5c2966da5ab973e4fd90763e4c962breed 5814e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com#define LOOPER_END } 5828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////// 5848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 585feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtkleinvoid SkCanvas::resetForNextPicture(const SkIRect& bounds) { 586feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein this->restoreToCount(1); 587feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fCachedLocalClipBounds.setEmpty(); 588feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fCachedLocalClipBoundsDirty = true; 589feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fClipStack->reset(); 590feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fMCRec->reset(bounds); 591feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 592feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein // We're peering through a lot of structs here. Only at this scope do we 593feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein // know that the device is an SkBitmapDevice (really an SkNoPixelsBitmapDevice). 594feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein static_cast<SkBitmapDevice*>(fMCRec->fLayer->fDevice)->setNewSize(bounds.size()); 595feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein} 596feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 597d954498c01ccf0417feacf89e45d0c62a06a813breedSkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) { 598d954498c01ccf0417feacf89e45d0c62a06a813breed fConservativeRasterClip = SkToBool(flags & kConservativeRasterClip_InitFlag); 599c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBounds.setEmpty(); 600c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 6018f0a7b8e7334187a5d7d5ab7fde5a3c3009555f5caryclark@google.com fAllowSoftClip = true; 60245a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com fAllowSimplifyClip = false; 603f92c86642a1875da54d54b447f006cb9dfbbb35creed fDeviceCMDirty = true; 6042ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount = 1; 60574bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org fMetaData = NULL; 6068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 607687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack.reset(SkNEW(SkClipStack)); 608687fa1c745febb57f42b0d5f03d7c1f4be2530careed 6098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = (MCRec*)fMCStack.push_back(); 610d954498c01ccf0417feacf89e45d0c62a06a813breed new (fMCRec) MCRec(fConservativeRasterClip); 6118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 612a499f905e9340e4935447f2562fd92e8853382b1reed SkASSERT(sizeof(DeviceCM) <= sizeof(fDeviceCMStorage)); 613a499f905e9340e4935447f2562fd92e8853382b1reed fMCRec->fLayer = (DeviceCM*)fDeviceCMStorage; 61486a17e7716c8db858e219a46b9db3817bb770beereed new (fDeviceCMStorage) DeviceCM(NULL, NULL, NULL, fConservativeRasterClip, false); 615b679ca8926a832274b14fdb512f88f64b61d32eareed 6168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fTopLayer = fMCRec->fLayer; 6178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 61897af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com fSurfaceBase = NULL; 619f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 620f92c86642a1875da54d54b447f006cb9dfbbb35creed if (device) { 621efbffedd68636e94d4379e84a2585bce80f6fb8frobertphillips // The root device and the canvas should always have the same pixel geometry 622efbffedd68636e94d4379e84a2585bce80f6fb8frobertphillips SkASSERT(fProps.pixelGeometry() == device->surfaceProps().pixelGeometry()); 6234a8126e7f81384526629b1e21bf89b632ea13cd9reed if (device->forceConservativeRasterClip()) { 6244a8126e7f81384526629b1e21bf89b632ea13cd9reed fConservativeRasterClip = true; 6254a8126e7f81384526629b1e21bf89b632ea13cd9reed } 626f92c86642a1875da54d54b447f006cb9dfbbb35creed device->onAttachToCanvas(this); 627f92c86642a1875da54d54b447f006cb9dfbbb35creed fMCRec->fLayer->fDevice = SkRef(device); 62878e276889795454891cbba48ab11927968114953reed fMCRec->fRasterClip.setRect(device->getGlobalBounds()); 629f92c86642a1875da54d54b447f006cb9dfbbb35creed } 630f92c86642a1875da54d54b447f006cb9dfbbb35creed return device; 6318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 633cde92111d50a96b6d0f3e166fbac7c9bc6eca349reed@google.comSkCanvas::SkCanvas() 634e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 6354a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 636e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org{ 6378d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org inc_canvas(); 638ba124485687130183643994f1b4b68d629fbbebaskia.committer@gmail.com 639d954498c01ccf0417feacf89e45d0c62a06a813breed this->init(NULL, kDefault_InitFlags); 6408d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org} 6418d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org 642d954498c01ccf0417feacf89e45d0c62a06a813breedstatic SkBitmap make_nopixels(int width, int height) { 643d954498c01ccf0417feacf89e45d0c62a06a813breed SkBitmap bitmap; 644d954498c01ccf0417feacf89e45d0c62a06a813breed bitmap.setInfo(SkImageInfo::MakeUnknown(width, height)); 645d954498c01ccf0417feacf89e45d0c62a06a813breed return bitmap; 646d954498c01ccf0417feacf89e45d0c62a06a813breed} 647d954498c01ccf0417feacf89e45d0c62a06a813breed 648d954498c01ccf0417feacf89e45d0c62a06a813breedclass SkNoPixelsBitmapDevice : public SkBitmapDevice { 649d954498c01ccf0417feacf89e45d0c62a06a813breedpublic: 650fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips SkNoPixelsBitmapDevice(const SkIRect& bounds, const SkSurfaceProps& surfaceProps) 651fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips : INHERITED(make_nopixels(bounds.width(), bounds.height()), surfaceProps) 65278e276889795454891cbba48ab11927968114953reed { 65378e276889795454891cbba48ab11927968114953reed this->setOrigin(bounds.x(), bounds.y()); 65478e276889795454891cbba48ab11927968114953reed } 655d954498c01ccf0417feacf89e45d0c62a06a813breed 656d954498c01ccf0417feacf89e45d0c62a06a813breedprivate: 657b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 658d954498c01ccf0417feacf89e45d0c62a06a813breed typedef SkBitmapDevice INHERITED; 659d954498c01ccf0417feacf89e45d0c62a06a813breed}; 660d954498c01ccf0417feacf89e45d0c62a06a813breed 66196a857ef5a40b3d0751ec9ebaaa96d9f20b82b21reedSkCanvas::SkCanvas(int width, int height, const SkSurfaceProps* props) 662e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 66396a857ef5a40b3d0751ec9ebaaa96d9f20b82b21reed , fProps(SkSurfacePropsCopyOrDefault(props)) 664e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org{ 665e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org inc_canvas(); 666b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 66778e276889795454891cbba48ab11927968114953reed this->init(SkNEW_ARGS(SkNoPixelsBitmapDevice, 668fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips (SkIRect::MakeWH(width, height), fProps)), kDefault_InitFlags)->unref(); 669d954498c01ccf0417feacf89e45d0c62a06a813breed} 670e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org 67178e276889795454891cbba48ab11927968114953reedSkCanvas::SkCanvas(const SkIRect& bounds, InitFlags flags) 672d954498c01ccf0417feacf89e45d0c62a06a813breed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 6734a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 674d954498c01ccf0417feacf89e45d0c62a06a813breed{ 675d954498c01ccf0417feacf89e45d0c62a06a813breed inc_canvas(); 676b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 677fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips this->init(SkNEW_ARGS(SkNoPixelsBitmapDevice, (bounds, fProps)), flags)->unref(); 67827a5e656c3d6ef22f9cb34de18e1b960da3aa241reed} 6798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 680d954498c01ccf0417feacf89e45d0c62a06a813breedSkCanvas::SkCanvas(SkBaseDevice* device) 681d954498c01ccf0417feacf89e45d0c62a06a813breed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 6827b05ff11ebc51f3f3abd1c1756337a04f563537erobertphillips , fProps(device->surfaceProps()) 683d954498c01ccf0417feacf89e45d0c62a06a813breed{ 684d954498c01ccf0417feacf89e45d0c62a06a813breed inc_canvas(); 685b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 686d954498c01ccf0417feacf89e45d0c62a06a813breed this->init(device, kDefault_InitFlags); 6878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 689fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillipsSkCanvas::SkCanvas(SkBaseDevice* device, InitFlags flags) 690fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 6917b05ff11ebc51f3f3abd1c1756337a04f563537erobertphillips , fProps(device->surfaceProps()) 692fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips{ 693fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips inc_canvas(); 694fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips 695fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips this->init(device, flags); 696fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips} 697fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips 6984a8126e7f81384526629b1e21bf89b632ea13cd9reedSkCanvas::SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props) 6993716fd067a5621bb94a6cb08d72afec8bf3acedareed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7004a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(props) 7013716fd067a5621bb94a6cb08d72afec8bf3acedareed{ 7023716fd067a5621bb94a6cb08d72afec8bf3acedareed inc_canvas(); 703b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 704fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips SkAutoTUnref<SkBaseDevice> device(SkNEW_ARGS(SkBitmapDevice, (bitmap, fProps))); 7054a8126e7f81384526629b1e21bf89b632ea13cd9reed this->init(device, kDefault_InitFlags); 7064a8126e7f81384526629b1e21bf89b632ea13cd9reed} 70729c857d0f3a1cb837f73406eeb6ba9771879b5e7reed 7084a8126e7f81384526629b1e21bf89b632ea13cd9reedSkCanvas::SkCanvas(const SkBitmap& bitmap) 7094a8126e7f81384526629b1e21bf89b632ea13cd9reed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 7104a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 7114a8126e7f81384526629b1e21bf89b632ea13cd9reed{ 7124a8126e7f81384526629b1e21bf89b632ea13cd9reed inc_canvas(); 713b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 714fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips SkAutoTUnref<SkBaseDevice> device(SkNEW_ARGS(SkBitmapDevice, (bitmap, fProps))); 7154a8126e7f81384526629b1e21bf89b632ea13cd9reed this->init(device, kDefault_InitFlags); 7168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::~SkCanvas() { 7198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // free up the contents of our deque 7208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->restoreToCount(1); // restore everything but the last 7217c2029367cea5479fa3b74fb0ca2b0297b42b709reed@google.com 7228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->internalRestore(); // restore the last, since we're going away 7238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 72474bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org SkDELETE(fMetaData); 725b70ae310bbdaa1b26786773aabce5548c1f48563vandebo@chromium.org 7268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dec_canvas(); 7278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDrawFilter* SkCanvas::getDrawFilter() const { 7308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fMCRec->fFilter; 7318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDrawFilter* SkCanvas::setDrawFilter(SkDrawFilter* filter) { 73451985e3f5e608d369e52832b7ce489d85d402422reed this->checkForDeferredSave(); 7358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fMCRec->fFilter, filter); 7368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return filter; 7378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 73974bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.orgSkMetaData& SkCanvas::getMetaData() { 74074bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org // metadata users are rare, so we lazily allocate it. If that changes we 74174bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org // can decide to just make it a field in the device (rather than a ptr) 74274bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org if (NULL == fMetaData) { 74374bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org fMetaData = new SkMetaData; 74474bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org } 74574bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org return *fMetaData; 74674bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org} 74774bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org 7488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 7498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 750bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.orgvoid SkCanvas::flush() { 7511f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* device = this->getDevice(); 752bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org if (device) { 753bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org device->flush(); 754bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org } 755bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org} 756bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org 7574ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.comSkISize SkCanvas::getTopLayerSize() const { 7584ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com SkBaseDevice* d = this->getTopDevice(); 7594ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com return d ? SkISize::Make(d->width(), d->height()) : SkISize::Make(0, 0); 7604ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com} 7614ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com 7624ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.comSkIPoint SkCanvas::getTopLayerOrigin() const { 7634ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com SkBaseDevice* d = this->getTopDevice(); 7644ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com return d ? d->getOrigin() : SkIPoint::Make(0, 0); 7654ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com} 7664ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com 7674ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.comSkISize SkCanvas::getBaseLayerSize() const { 7681f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* d = this->getDevice(); 769210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com return d ? SkISize::Make(d->width(), d->height()) : SkISize::Make(0, 0); 770210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com} 771210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com 7721f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::getDevice() const { 7738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // return root device 774c029062a0312fb747fb6c2677983aba51795c580robertphillips@google.com MCRec* rec = (MCRec*) fMCStack.front(); 7758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(rec && rec->fLayer); 7768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return rec->fLayer->fDevice; 7778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7791f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::getTopDevice(bool updateMatrixClip) const { 7800b53d59a24f667350b4282f88470713902409030reed@google.com if (updateMatrixClip) { 7810b53d59a24f667350b4282f88470713902409030reed@google.com const_cast<SkCanvas*>(this)->updateDeviceCMCache(); 7820b53d59a24f667350b4282f88470713902409030reed@google.com } 7839266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com return fMCRec->fTopLayer->fDevice; 7849266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com} 7859266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com 786a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.orgbool SkCanvas::readPixels(SkBitmap* bitmap, int x, int y) { 787a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (kUnknown_SkColorType == bitmap->colorType() || bitmap->getTexture()) { 788a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 789a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 790a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 791a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bool weAllocated = false; 792a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (NULL == bitmap->pixelRef()) { 793848250415eddc54075f7eb8795e8db79e749c6abreed if (!bitmap->tryAllocPixels()) { 794a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 795a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 796a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org weAllocated = true; 797a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 798a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 799cf01e31df6bbda270dca2ee3b4967caf51e465dcreed SkAutoPixmapUnlock unlocker; 800cf01e31df6bbda270dca2ee3b4967caf51e465dcreed if (bitmap->requestLock(&unlocker)) { 801cf01e31df6bbda270dca2ee3b4967caf51e465dcreed const SkPixmap& pm = unlocker.pixmap(); 802cf01e31df6bbda270dca2ee3b4967caf51e465dcreed if (this->readPixels(pm.info(), pm.writable_addr(), pm.rowBytes(), x, y)) { 803cf01e31df6bbda270dca2ee3b4967caf51e465dcreed return true; 804cf01e31df6bbda270dca2ee3b4967caf51e465dcreed } 805a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 806a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 807a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (weAllocated) { 808a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bitmap->setPixelRef(NULL); 809a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 810a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 811a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org} 81251df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 813c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.combool SkCanvas::readPixels(const SkIRect& srcRect, SkBitmap* bitmap) { 814a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkIRect r = srcRect; 815a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 816a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!r.intersect(0, 0, size.width(), size.height())) { 817a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bitmap->reset(); 818ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com return false; 819ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com } 82074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 821848250415eddc54075f7eb8795e8db79e749c6abreed if (!bitmap->tryAllocN32Pixels(r.width(), r.height())) { 822a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org // bitmap will already be reset. 823a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 824a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 825a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!this->readPixels(bitmap->info(), bitmap->getPixels(), bitmap->rowBytes(), r.x(), r.y())) { 826a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bitmap->reset(); 827daba14b7d4fc96b915c45d82713b22729c0d0f37bsalomon@google.com return false; 828c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } 829a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return true; 830a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org} 831c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 83296472deea70169396b8e1f576e470138f55fdb1freedbool SkCanvas::readPixels(const SkImageInfo& dstInfo, void* dstP, size_t rowBytes, int x, int y) { 833a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkBaseDevice* device = this->getDevice(); 834a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!device) { 835a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 836a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 837a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 838f0f14113431ace669f278fdd97b50950f2cf4c80mtklein 83996472deea70169396b8e1f576e470138f55fdb1freed SkReadPixelsRec rec(dstInfo, dstP, rowBytes, x, y); 84096472deea70169396b8e1f576e470138f55fdb1freed if (!rec.trim(size.width(), size.height())) { 841a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 842a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 843db0c8753775774aa3f67114491e26ac1be32f38eskia.committer@gmail.com 844a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org // The device can assert that the requested area is always contained in its bounds 84596472deea70169396b8e1f576e470138f55fdb1freed return device->readPixels(rec.fInfo, rec.fPixels, rec.fRowBytes, rec.fX, rec.fY); 84651df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com} 84751df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 8484cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgbool SkCanvas::writePixels(const SkBitmap& bitmap, int x, int y) { 8494cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (bitmap.getTexture()) { 8504cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 8514cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 852cf01e31df6bbda270dca2ee3b4967caf51e465dcreed 853cf01e31df6bbda270dca2ee3b4967caf51e465dcreed SkAutoPixmapUnlock unlocker; 854cf01e31df6bbda270dca2ee3b4967caf51e465dcreed if (bitmap.requestLock(&unlocker)) { 855cf01e31df6bbda270dca2ee3b4967caf51e465dcreed const SkPixmap& pm = unlocker.pixmap(); 856cf01e31df6bbda270dca2ee3b4967caf51e465dcreed return this->writePixels(pm.info(), pm.addr(), pm.rowBytes(), x, y); 8574cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 8584cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 8594cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org} 8604cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 8614cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgbool SkCanvas::writePixels(const SkImageInfo& origInfo, const void* pixels, size_t rowBytes, 8624cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org int x, int y) { 8634cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org switch (origInfo.colorType()) { 8644cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org case kUnknown_SkColorType: 8654cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org case kIndex_8_SkColorType: 8664cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 8674cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org default: 8684cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org break; 8694cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 8704cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (NULL == pixels || rowBytes < origInfo.minRowBytes()) { 8714cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 8724cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 8734cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 8744cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 8754cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org SkIRect target = SkIRect::MakeXYWH(x, y, origInfo.width(), origInfo.height()); 8764cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (!target.intersect(0, 0, size.width(), size.height())) { 8774cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 8784cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 8794cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 8804cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org SkBaseDevice* device = this->getDevice(); 8814cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (!device) { 8824cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 8834cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 8844cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 8854cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // the intersect may have shrunk info's logical size 886e5ea500d4714a7d84de2bf913e81be3b65d2de68reed const SkImageInfo info = origInfo.makeWH(target.width(), target.height()); 8874cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 8884cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // if x or y are negative, then we have to adjust pixels 8894cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (x > 0) { 8904cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org x = 0; 8914cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 8924cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (y > 0) { 8934cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org y = 0; 8944cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 8954cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // here x,y are either 0 or negative 8964cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org pixels = ((const char*)pixels - y * rowBytes - x * info.bytesPerPixel()); 8974cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 8984af35f348b2e2f6c428819118eb7a2f2fff53a74reed // Tell our owning surface to bump its generation ID 899c83a29759a5c2966da5ab973e4fd90763e4c962breed const bool completeOverwrite = info.dimensions() == size; 900c83a29759a5c2966da5ab973e4fd90763e4c962breed this->predrawNotify(completeOverwrite); 9014af35f348b2e2f6c428819118eb7a2f2fff53a74reed 9024cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // The device can assert that the requested area is always contained in its bounds 9034ef54f8d72420a521d4aae04ff5cd438810eca7fcommit-bot@chromium.org return device->writePixels(info, pixels, rowBytes, target.x(), target.y()); 9044cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org} 90551df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 9064370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comSkCanvas* SkCanvas::canvasForDrawIter() { 9074370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com return this; 9084370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 9094370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 9108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 9118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::updateDeviceCMCache() { 9138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fDeviceCMDirty) { 9148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& totalMatrix = this->getTotalMatrix(); 9151f836ee096bb988adef4b9757b2629c7afeda36dreed const SkRasterClip& totalClip = fMCRec->fRasterClip; 9168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* layer = fMCRec->fTopLayer; 9174b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 9188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == layer->fNext) { // only one layer 919687fa1c745febb57f42b0d5f03d7c1f4be2530careed layer->updateMC(totalMatrix, totalClip, *fClipStack, NULL); 9208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 921045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com SkRasterClip clip(totalClip); 9228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 923687fa1c745febb57f42b0d5f03d7c1f4be2530careed layer->updateMC(totalMatrix, clip, *fClipStack, &clip); 9248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while ((layer = layer->fNext) != NULL); 9258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = false; 9278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 9318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9322ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::checkForDeferredSave() { 9332ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (fMCRec->fDeferredSaveCount > 0) { 9342ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->doSave(); 9352ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 9362ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed} 9372ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed 938f0090cb80ab10a49e511aa5450ae38917fa058d9reedint SkCanvas::getSaveCount() const { 9392ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed#ifdef SK_DEBUG 9402ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed int count = 0; 9412ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkDeque::Iter iter(fMCStack, SkDeque::Iter::kFront_IterStart); 9422ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed for (;;) { 9432ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed const MCRec* rec = (const MCRec*)iter.next(); 9442ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (!rec) { 9452ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed break; 9462ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 9472ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed count += 1 + rec->fDeferredSaveCount; 9482ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 9492ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(count == fSaveCount); 9502ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed#endif 9512ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return fSaveCount; 952f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 953f0090cb80ab10a49e511aa5450ae38917fa058d9reed 954f0090cb80ab10a49e511aa5450ae38917fa058d9reedint SkCanvas::save() { 9552ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount += 1; 9562ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fMCRec->fDeferredSaveCount += 1; 9572ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return this->getSaveCount() - 1; // return our prev value 9582ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed} 9592ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed 9602ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::doSave() { 961f0090cb80ab10a49e511aa5450ae38917fa058d9reed this->willSave(); 962a62d32d1e3112c7e5a26c27e5e967d124ef8dd81fmalita 963a62d32d1e3112c7e5a26c27e5e967d124ef8dd81fmalita SkASSERT(fMCRec->fDeferredSaveCount > 0); 964a62d32d1e3112c7e5a26c27e5e967d124ef8dd81fmalita fMCRec->fDeferredSaveCount -= 1; 9652ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalSave(); 966f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 967f0090cb80ab10a49e511aa5450ae38917fa058d9reed 968f0090cb80ab10a49e511aa5450ae38917fa058d9reedvoid SkCanvas::restore() { 9692ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (fMCRec->fDeferredSaveCount > 0) { 9702ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(fSaveCount > 1); 9712ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount -= 1; 9722ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fMCRec->fDeferredSaveCount -= 1; 9732ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } else { 9742ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed // check for underflow 9752ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (fMCStack.count() > 1) { 9762ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->willRestore(); 9772ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(fSaveCount > 1); 978a644116c3375b12c642d1b51ee1e5cf4a22c1f5breed fSaveCount -= 1; 9792ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalRestore(); 9802ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->didRestore(); 9812ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 982f0090cb80ab10a49e511aa5450ae38917fa058d9reed } 983f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 984f0090cb80ab10a49e511aa5450ae38917fa058d9reed 985f0090cb80ab10a49e511aa5450ae38917fa058d9reedvoid SkCanvas::restoreToCount(int count) { 986f0090cb80ab10a49e511aa5450ae38917fa058d9reed // sanity check 987f0090cb80ab10a49e511aa5450ae38917fa058d9reed if (count < 1) { 988f0090cb80ab10a49e511aa5450ae38917fa058d9reed count = 1; 989f0090cb80ab10a49e511aa5450ae38917fa058d9reed } 990f0f14113431ace669f278fdd97b50950f2cf4c80mtklein 991f0090cb80ab10a49e511aa5450ae38917fa058d9reed int n = this->getSaveCount() - count; 992f0090cb80ab10a49e511aa5450ae38917fa058d9reed for (int i = 0; i < n; ++i) { 993f0090cb80ab10a49e511aa5450ae38917fa058d9reed this->restore(); 994f0090cb80ab10a49e511aa5450ae38917fa058d9reed } 995f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 996f0090cb80ab10a49e511aa5450ae38917fa058d9reed 9972ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::internalSave() { 9988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com MCRec* newTop = (MCRec*)fMCStack.push_back(); 999d954498c01ccf0417feacf89e45d0c62a06a813breed new (newTop) MCRec(*fMCRec); // balanced in restore() 10008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = newTop; 10014b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 1002687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->save(); 10038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic bool bounds_affects_clip(SkCanvas::SaveFlags flags) { 1006b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG 10078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (flags & SkCanvas::kClipToLayer_SaveFlag) != 0; 1008b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#else 1009b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com return true; 1010b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#endif 10118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1013a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.orgbool SkCanvas::clipRectBounds(const SkRect* bounds, SaveFlags flags, 10149b3aa54bc9605257c701cf465813f5fb1d7ba39ereed SkIRect* intersection, const SkImageFilter* imageFilter) { 1015bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect clipBounds; 1016bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (!this->getClipDeviceBounds(&clipBounds)) { 1017a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return false; 1018f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 1019c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org 102096e657d0e103b8358a77ecd913f6086929f792b8reed const SkMatrix& ctm = fMCRec->fMatrix; // this->getTotalMatrix() 102196e657d0e103b8358a77ecd913f6086929f792b8reed 1022c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org if (imageFilter) { 102396e657d0e103b8358a77ecd913f6086929f792b8reed imageFilter->filterBounds(clipBounds, ctm, &clipBounds); 1024c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org } 1025bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect ir; 102649f085dddff10473b6ebf832a974288300224e60bsalomon if (bounds) { 10278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 10284b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 102996e657d0e103b8358a77ecd913f6086929f792b8reed ctm.mapRect(&r, *bounds); 10308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.roundOut(&ir); 10318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // early exit if the layer's bounds are clipped out 10328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!ir.intersect(clipBounds)) { 1033bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (bounds_affects_clip(flags)) { 10349b3aa54bc9605257c701cf465813f5fb1d7ba39ereed fCachedLocalClipBoundsDirty = true; 10351f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fRasterClip.setEmpty(); 1036bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1037a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return false; 10388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { // no user bounds, so just use the clip 10408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ir = clipBounds; 10418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1042180aec43451dd951fdaae81a92efc710ba093260reed SkASSERT(!ir.isEmpty()); 10438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 104489f077ced4918ded7e911bc5052b61c90ad57a9asenorblanco@chromium.org if (bounds_affects_clip(flags)) { 1045180aec43451dd951fdaae81a92efc710ba093260reed // Simplify the current clips since they will be applied properly during restore() 10469b3aa54bc9605257c701cf465813f5fb1d7ba39ereed fCachedLocalClipBoundsDirty = true; 1047687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipDevRect(ir, SkRegion::kReplace_Op); 1048180aec43451dd951fdaae81a92efc710ba093260reed fMCRec->fRasterClip.setRect(ir); 1049a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org } 1050a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 1051a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org if (intersection) { 1052a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org *intersection = ir; 1053a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org } 1054a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return true; 1055a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org} 1056a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 1057d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.orgint SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint) { 1058d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed if (gIgnoreSaveLayerBounds) { 1059d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed bounds = NULL; 1060d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed } 1061d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org SaveLayerStrategy strategy = this->willSaveLayer(bounds, paint, kARGB_ClipLayer_SaveFlag); 1062a644116c3375b12c642d1b51ee1e5cf4a22c1f5breed fSaveCount += 1; 106376033be81b82c44fd5d4fdf2672eb22e505da1f0reed this->internalSaveLayer(bounds, paint, kARGB_ClipLayer_SaveFlag, strategy); 10642ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return this->getSaveCount() - 1; 1065d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org} 1066d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org 10672ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedint SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags) { 1068d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed if (gIgnoreSaveLayerBounds) { 1069d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed bounds = NULL; 1070d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed } 1071e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org SaveLayerStrategy strategy = this->willSaveLayer(bounds, paint, flags); 1072a644116c3375b12c642d1b51ee1e5cf4a22c1f5breed fSaveCount += 1; 107376033be81b82c44fd5d4fdf2672eb22e505da1f0reed this->internalSaveLayer(bounds, paint, flags, strategy); 10742ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return this->getSaveCount() - 1; 10758926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com} 10768926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 10772ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags, 107876033be81b82c44fd5d4fdf2672eb22e505da1f0reed SaveLayerStrategy strategy) { 1079b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG 10802a5cd60bfff32c92cf44a8cfc3e8c017b9aee456commit-bot@chromium.org flags |= kClipToLayer_SaveFlag; 1081b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#endif 1082b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com 1083a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org // do this before we create the layer. We don't call the public save() since 1084a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org // that would invoke a possibly overridden virtual 10852ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalSave(); 1086a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 1087a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org fDeviceCMDirty = true; 1088a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 1089a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org SkIRect ir; 1090daa57bfd4204f5a7d304c580bcf5ad99d0121e1freed if (!this->clipRectBounds(bounds, flags, &ir, paint ? paint->getImageFilter() : NULL)) { 10912ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 10928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1094e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy really care about 1095e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org // the clipRectBounds() call above? 1096e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org if (kNoLayer_SaveLayerStrategy == strategy) { 10972ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 1098e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org } 1099e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org 110076033be81b82c44fd5d4fdf2672eb22e505da1f0reed bool isOpaque = !SkToBool(flags & kHasAlphaLayer_SaveFlag); 11018dc0ccb8d33d1af7dd13228509e61fe915bc7705reed SkPixelGeometry geo = fProps.pixelGeometry(); 11028dc0ccb8d33d1af7dd13228509e61fe915bc7705reed if (paint) { 110376033be81b82c44fd5d4fdf2672eb22e505da1f0reed // TODO: perhaps add a query to filters so we might preserve opaqueness... 1104daa57bfd4204f5a7d304c580bcf5ad99d0121e1freed if (paint->getImageFilter() || paint->getColorFilter()) { 110576033be81b82c44fd5d4fdf2672eb22e505da1f0reed isOpaque = false; 11068dc0ccb8d33d1af7dd13228509e61fe915bc7705reed geo = kUnknown_SkPixelGeometry; 1107b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com } 1108b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com } 110915a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org SkImageInfo info = SkImageInfo::MakeN32(ir.width(), ir.height(), 111015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType); 11118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1112b2db898573e3cdcc8234eebf51961bfc4977ebbcreed SkBaseDevice* device = this->getTopDevice(); 1113b2db898573e3cdcc8234eebf51961bfc4977ebbcreed if (NULL == device) { 1114b2db898573e3cdcc8234eebf51961bfc4977ebbcreed SkDebugf("Unable to find device for layer."); 11152ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 1116b2db898573e3cdcc8234eebf51961bfc4977ebbcreed } 1117b2db898573e3cdcc8234eebf51961bfc4977ebbcreed 111861f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed bool forceSpriteOnRestore = false; 111961f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed { 1120daa57bfd4204f5a7d304c580bcf5ad99d0121e1freed const SkBaseDevice::TileUsage usage = SkBaseDevice::kNever_TileUsage; 112161f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed const SkBaseDevice::CreateInfo createInfo = SkBaseDevice::CreateInfo(info, usage, geo); 112261f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed SkBaseDevice* newDev = device->onCreateDevice(createInfo, paint); 112361f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed if (NULL == newDev) { 112461f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed // If onCreateDevice didn't succeed, try raster (e.g. PDF couldn't handle the paint) 11259a53fd7c41554630124522f4b6eedc16912abbb7robertphillips const SkSurfaceProps surfaceProps(fProps.flags(), createInfo.fPixelGeometry); 11269a53fd7c41554630124522f4b6eedc16912abbb7robertphillips newDev = SkBitmapDevice::Create(createInfo.fInfo, surfaceProps); 112761f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed if (NULL == newDev) { 112861f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed SkErrorInternals::SetError(kInternalError_SkError, 112961f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed "Unable to create device for layer."); 113061f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed return; 113161f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed } 113261f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed forceSpriteOnRestore = true; 113361f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed } 113461f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed device = newDev; 1135e25c68402b38ac01dc1ae196ae8a5265b773c5f2bungeman@google.com } 1136e97f0856a8044866b12527819d14cdfbcdfd96f2bsalomon@google.com 11376f8f292aa768869a9e85c314b124875f57504f2creed@google.com device->setOrigin(ir.fLeft, ir.fTop); 113861f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed DeviceCM* layer = SkNEW_ARGS(DeviceCM, (device, paint, this, fConservativeRasterClip, 113986a17e7716c8db858e219a46b9db3817bb770beereed forceSpriteOnRestore)); 11408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device->unref(); 11418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com layer->fNext = fMCRec->fTopLayer; 11438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fLayer = layer; 11448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fTopLayer = layer; // this field is NOT an owner of layer 11458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 11468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1147d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.orgint SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) { 1148d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org return this->saveLayerAlpha(bounds, alpha, kARGB_ClipLayer_SaveFlag); 1149d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org} 1150d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org 11518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha, 11528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SaveFlags flags) { 11538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (0xFF == alpha) { 11548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->saveLayer(bounds, NULL, flags); 11558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 11568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint tmpPaint; 11578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com tmpPaint.setAlpha(alpha); 11588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->saveLayer(bounds, &tmpPaint, flags); 11598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 11618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::internalRestore() { 11638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fMCStack.count() != 0); 11648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1166c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 11678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1168687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->restore(); 11696c157640c27ee2ed6f9a484d21691b7b19dfecdecommit-bot@chromium.org 117088edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com // reserve our layer (if any) 11718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* layer = fMCRec->fLayer; // may be null 11728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now detach it from fMCRec so we can pop(). Gets freed after its drawn 11738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fLayer = NULL; 11748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now do the normal restore() 11768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->~MCRec(); // balanced in save() 11778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCStack.pop_back(); 11788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = (MCRec*)fMCStack.back(); 11798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* Time to draw the layer's offscreen. We can't call the public drawSprite, 11818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com since if we're being recorded, we don't want to record this (the 11828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com recorder will have already recorded the restore). 11838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 118449f085dddff10473b6ebf832a974288300224e60bsalomon if (layer) { 11858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (layer->fNext) { 11866f8f292aa768869a9e85c314b124875f57504f2creed@google.com const SkIPoint& origin = layer->fDevice->getOrigin(); 11878926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(), 118861f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed layer->fPaint, layer->fDeviceIsBitmapDevice); 11898926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com // reset this, since internalDrawDevice will have set it to true 11908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1191b679ca8926a832274b14fdb512f88f64b61d32eareed SkDELETE(layer); 1192b679ca8926a832274b14fdb512f88f64b61d32eareed } else { 1193b679ca8926a832274b14fdb512f88f64b61d32eareed // we're at the root 1194a499f905e9340e4935447f2562fd92e8853382b1reed SkASSERT(layer == (void*)fDeviceCMStorage); 1195b679ca8926a832274b14fdb512f88f64b61d32eareed layer->~DeviceCM(); 11968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 119788edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 11988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 11998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12004a8126e7f81384526629b1e21bf89b632ea13cd9reedSkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* props) { 12014a8126e7f81384526629b1e21bf89b632ea13cd9reed if (NULL == props) { 12024a8126e7f81384526629b1e21bf89b632ea13cd9reed props = &fProps; 12034a8126e7f81384526629b1e21bf89b632ea13cd9reed } 12044a8126e7f81384526629b1e21bf89b632ea13cd9reed return this->onNewSurface(info, *props); 120576f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com} 120676f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com 12074a8126e7f81384526629b1e21bf89b632ea13cd9reedSkSurface* SkCanvas::onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props) { 120876f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com SkBaseDevice* dev = this->getDevice(); 12094a8126e7f81384526629b1e21bf89b632ea13cd9reed return dev ? dev->newSurface(info, props) : NULL; 121076f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com} 121176f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com 1212c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgSkImageInfo SkCanvas::imageInfo() const { 1213c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkBaseDevice* dev = this->getDevice(); 1214c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (dev) { 1215c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return dev->imageInfo(); 1216c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } else { 1217900ecf2f1579d42c9d2959831787af0346320f86reed@google.com return SkImageInfo::MakeUnknown(0, 0); 1218c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1219c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1220c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1221c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgconst void* SkCanvas::peekPixels(SkImageInfo* info, size_t* rowBytes) { 1222884e97cb04db7ed053a866567ee9c6e4c01f993areed SkPixmap pmap; 1223884e97cb04db7ed053a866567ee9c6e4c01f993areed if (!this->onPeekPixels(&pmap)) { 1224884e97cb04db7ed053a866567ee9c6e4c01f993areed return NULL; 1225884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1226884e97cb04db7ed053a866567ee9c6e4c01f993areed if (info) { 1227884e97cb04db7ed053a866567ee9c6e4c01f993areed *info = pmap.info(); 1228884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1229884e97cb04db7ed053a866567ee9c6e4c01f993areed if (rowBytes) { 1230884e97cb04db7ed053a866567ee9c6e4c01f993areed *rowBytes = pmap.rowBytes(); 1231884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1232884e97cb04db7ed053a866567ee9c6e4c01f993areed return pmap.addr(); 1233c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1234c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1235884e97cb04db7ed053a866567ee9c6e4c01f993areedbool SkCanvas::onPeekPixels(SkPixmap* pmap) { 1236c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkBaseDevice* dev = this->getDevice(); 1237884e97cb04db7ed053a866567ee9c6e4c01f993areed return dev && dev->peekPixels(pmap); 1238c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1239c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 12406b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.orgvoid* SkCanvas::accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin) { 1241884e97cb04db7ed053a866567ee9c6e4c01f993areed SkPixmap pmap; 1242884e97cb04db7ed053a866567ee9c6e4c01f993areed if (!this->onAccessTopLayerPixels(&pmap)) { 1243884e97cb04db7ed053a866567ee9c6e4c01f993areed return NULL; 1244884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1245884e97cb04db7ed053a866567ee9c6e4c01f993areed if (info) { 1246884e97cb04db7ed053a866567ee9c6e4c01f993areed *info = pmap.info(); 1247884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1248884e97cb04db7ed053a866567ee9c6e4c01f993areed if (rowBytes) { 1249884e97cb04db7ed053a866567ee9c6e4c01f993areed *rowBytes = pmap.rowBytes(); 1250884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1251884e97cb04db7ed053a866567ee9c6e4c01f993areed if (origin) { 12526b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org *origin = this->getTopDevice(false)->getOrigin(); 12536b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org } 1254884e97cb04db7ed053a866567ee9c6e4c01f993areed return pmap.writable_addr(); 12559c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 12569c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1257884e97cb04db7ed053a866567ee9c6e4c01f993areedbool SkCanvas::onAccessTopLayerPixels(SkPixmap* pmap) { 12589c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com SkBaseDevice* dev = this->getTopDevice(); 1259884e97cb04db7ed053a866567ee9c6e4c01f993areed return dev && dev->accessPixels(pmap); 12609c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 12619c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1262c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgSkAutoROCanvasPixels::SkAutoROCanvasPixels(SkCanvas* canvas) { 1263c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org fAddr = canvas->peekPixels(&fInfo, &fRowBytes); 1264c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (NULL == fAddr) { 1265c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org fInfo = canvas->imageInfo(); 1266848250415eddc54075f7eb8795e8db79e749c6abreed if (kUnknown_SkColorType == fInfo.colorType() || !fBitmap.tryAllocPixels(fInfo)) { 1267c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return; // failure, fAddr is NULL 1268c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1269c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (!canvas->readPixels(&fBitmap, 0, 0)) { 1270c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return; // failure, fAddr is NULL 1271c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1272c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org fAddr = fBitmap.getPixels(); 1273c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org fRowBytes = fBitmap.rowBytes(); 1274c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1275c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkASSERT(fAddr); // success 1276c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1277c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1278c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgbool SkAutoROCanvasPixels::asROBitmap(SkBitmap* bitmap) const { 1279c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (fAddr) { 128000f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org return bitmap->installPixels(fInfo, const_cast<void*>(fAddr), fRowBytes); 1281c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } else { 1282c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org bitmap->reset(); 1283c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return false; 1284c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1285c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1286c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1287520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org///////////////////////////////////////////////////////////////////////////// 12889bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.comvoid SkCanvas::internalDrawBitmap(const SkBitmap& bitmap, 12898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& matrix, const SkPaint* paint) { 129050b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org if (bitmap.drawsNothing()) { 12918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 12928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12942c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkLazyPaint lazy; 12958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == paint) { 12962c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org paint = lazy.init(); 12978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12989bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com 12999bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com SkDEBUGCODE(bitmap.validate();) 13009bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com 130178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 130278cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 130378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (paint && paint->canComputeFastBounds()) { 130478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bitmap.getBounds(&storage); 130578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org matrix.mapRect(&storage); 130678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint->computeFastBounds(storage, &storage); 130778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org } 130878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org 130978cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) 13109bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com 13119bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com while (iter.next()) { 13129bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com iter.fDevice->drawBitmap(iter, bitmap, matrix, looper.paint()); 13139bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com } 13149bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com 13159bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com LOOPER_END 13168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13181f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comvoid SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, 131961f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed const SkPaint* paint, bool deviceIsBitmapDevice) { 13208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint tmp; 13218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == paint) { 13228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint = &tmp; 13238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13244b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 13258926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com LOOPER_BEGIN_DRAWDEVICE(*paint, SkDrawFilter::kBitmap_Type) 13268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 13271f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* dstDev = iter.fDevice; 132876dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com paint = &looper.paint(); 132976dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkImageFilter* filter = paint->getImageFilter(); 133076dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkIPoint pos = { x - iter.getX(), y - iter.getY() }; 13318926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com if (filter && !dstDev->canHandleImageFilter(filter)) { 1332efbffedd68636e94d4379e84a2585bce80f6fb8frobertphillips SkImageFilter::Proxy proxy(dstDev); 133376dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkBitmap dst; 13346776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org SkIPoint offset = SkIPoint::Make(0, 0); 1335b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com const SkBitmap& src = srcDev->accessBitmap(false); 1336fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org SkMatrix matrix = *iter.fMatrix; 1337d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org matrix.postTranslate(SkIntToScalar(-pos.x()), SkIntToScalar(-pos.y())); 13384cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org SkIRect clipBounds = SkIRect::MakeWH(srcDev->width(), srcDev->height()); 1339be129b26f13d575fd6b396c6ae759838ecc9bd1asenorblanco SkAutoTUnref<SkImageFilter::Cache> cache(dstDev->getImageFilterCache()); 134055b6d8be997a447ef9ce0f029697677a940bfc24senorblanco SkImageFilter::Context ctx(matrix, clipBounds, cache.get()); 13414cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org if (filter->filterImage(&proxy, src, ctx, &dst, &offset)) { 13425efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com SkPaint tmpUnfiltered(*paint); 13435efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com tmpUnfiltered.setImageFilter(NULL); 13446776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org dstDev->drawSprite(iter, dst, pos.x() + offset.x(), pos.y() + offset.y(), 13456776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org tmpUnfiltered); 134676dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } 134761f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed } else if (deviceIsBitmapDevice) { 13489572a10c9a6a868bbb8f71d7806d0a45f183333freed const SkBitmap& src = static_cast<SkBitmapDevice*>(srcDev)->fBitmap; 134961f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed dstDev->drawSprite(iter, src, pos.x(), pos.y(), *paint); 135076dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } else { 1351b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com dstDev->drawDevice(iter, srcDev, pos.x(), pos.y(), *paint); 135276dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } 13538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13544e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 13558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 135741af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawSprite(const SkBitmap& bitmap, int x, int y, const SkPaint* paint) { 13580acf1b4b3645772d220c720313821bac389751b5reed if (gTreatSpriteAsBitmap) { 13590acf1b4b3645772d220c720313821bac389751b5reed this->save(); 13600acf1b4b3645772d220c720313821bac389751b5reed this->resetMatrix(); 13610acf1b4b3645772d220c720313821bac389751b5reed this->drawBitmap(bitmap, SkIntToScalar(x), SkIntToScalar(y), paint); 13620acf1b4b3645772d220c720313821bac389751b5reed this->restore(); 13630acf1b4b3645772d220c720313821bac389751b5reed return; 13640acf1b4b3645772d220c720313821bac389751b5reed } 13650acf1b4b3645772d220c720313821bac389751b5reed 13669881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawSprite()"); 136750b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org if (bitmap.drawsNothing()) { 13688926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com return; 13698926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 137050b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org SkDEBUGCODE(bitmap.validate();) 1371fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 13728926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkPaint tmp; 13738926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com if (NULL == paint) { 13748926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com paint = &tmp; 13758926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 1376fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 13778926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com LOOPER_BEGIN_DRAWDEVICE(*paint, SkDrawFilter::kBitmap_Type) 1378fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 13798926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com while (iter.next()) { 13808926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com paint = &looper.paint(); 13818926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkImageFilter* filter = paint->getImageFilter(); 13828926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkIPoint pos = { x - iter.getX(), y - iter.getY() }; 13838926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com if (filter && !iter.fDevice->canHandleImageFilter(filter)) { 1384efbffedd68636e94d4379e84a2585bce80f6fb8frobertphillips SkImageFilter::Proxy proxy(iter.fDevice); 13858926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkBitmap dst; 13866776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org SkIPoint offset = SkIPoint::Make(0, 0); 1387fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org SkMatrix matrix = *iter.fMatrix; 1388d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org matrix.postTranslate(SkIntToScalar(-pos.x()), SkIntToScalar(-pos.y())); 1389f622a6c8fd176acf9944de8df00d7f0bb56b67d3halcanary const SkIRect clipBounds = bitmap.bounds(); 1390be129b26f13d575fd6b396c6ae759838ecc9bd1asenorblanco SkAutoTUnref<SkImageFilter::Cache> cache(iter.fDevice->getImageFilterCache()); 139155b6d8be997a447ef9ce0f029697677a940bfc24senorblanco SkImageFilter::Context ctx(matrix, clipBounds, cache.get()); 13924cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org if (filter->filterImage(&proxy, bitmap, ctx, &dst, &offset)) { 13935efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com SkPaint tmpUnfiltered(*paint); 13945efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com tmpUnfiltered.setImageFilter(NULL); 13956776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org iter.fDevice->drawSprite(iter, dst, pos.x() + offset.x(), pos.y() + offset.y(), 13965efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com tmpUnfiltered); 13978926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 13988926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } else { 13998926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com iter.fDevice->drawSprite(iter, bitmap, pos.x(), pos.y(), *paint); 14008926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 14018926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 14028926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com LOOPER_END 14038926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com} 14048926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 14058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////// 140692362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::translate(SkScalar dx, SkScalar dy) { 1407d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1408d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setTranslate(dx, dy); 1409d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 14108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 141292362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::scale(SkScalar sx, SkScalar sy) { 1413d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1414d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setScale(sx, sy); 1415d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 14168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 141892362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::rotate(SkScalar degrees) { 1419d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1420d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setRotate(degrees); 1421d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 14228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 142492362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::skew(SkScalar sx, SkScalar sy) { 1425d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1426d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setSkew(sx, sy); 1427d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 142844c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org} 142944c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 143092362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::concat(const SkMatrix& matrix) { 1431d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org if (matrix.isIdentity()) { 1432d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org return; 1433d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org } 1434d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org 14352ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 14368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1437c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 14381f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix.preConcat(matrix); 143944c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 144044c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org this->didConcat(matrix); 144144c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org} 144244c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 144386a17e7716c8db858e219a46b9db3817bb770beereedvoid SkCanvas::setMatrix(const SkMatrix& matrix) { 144486a17e7716c8db858e219a46b9db3817bb770beereed this->checkForDeferredSave(); 14458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1446c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 14471f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix = matrix; 144844c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org this->didSetMatrix(matrix); 14498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::resetMatrix() { 14528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 14534b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 14548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.reset(); 14558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->setMatrix(matrix); 14568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 14598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1460759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { 14612ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 14628f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 14638f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(rect, op, edgeStyle); 14648f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 14658f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 14668f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 1467da17f758442f16747af39f8fbaed9c097048519creed@google.com#ifdef SK_ENABLE_CLIP_QUICKREJECT 1468da17f758442f16747af39f8fbaed9c097048519creed@google.com if (SkRegion::kIntersect_Op == op) { 14691f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fRasterClip.isEmpty()) { 1470da17f758442f16747af39f8fbaed9c097048519creed@google.com return false; 1471da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1472da17f758442f16747af39f8fbaed9c097048519creed@google.com 14733b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(rect)) { 1474da17f758442f16747af39f8fbaed9c097048519creed@google.com fDeviceCMDirty = true; 1475c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 1476da17f758442f16747af39f8fbaed9c097048519creed@google.com 1477687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipEmpty(); 14781f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.setEmpty(); 1479da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1480da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1481da17f758442f16747af39f8fbaed9c097048519creed@google.com#endif 1482da17f758442f16747af39f8fbaed9c097048519creed@google.com 14835c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com AutoValidateClip avc(this); 14845c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 14858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1486c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 14878f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!fAllowSoftClip) { 14888f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com edgeStyle = kHard_ClipEdgeStyle; 14898f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 14908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14911f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fMatrix.rectStaysRect()) { 1492123671901abfa595d09ca789b487c4bc7c1f7cbcrobertphillips@google.com // for these simpler matrices, we can stay a rect even after applying 149398de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // the matrix. This means we don't have to a) make a path, and b) tell 149498de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // the region code to scan-convert the path, only to discover that it 149598de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // is really just a rect. 14968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 14978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14981f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix.mapRect(&r, rect); 1499687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipDevRect(r, op, kSoft_ClipEdgeStyle == edgeStyle); 1500d954498c01ccf0417feacf89e45d0c62a06a813breed fMCRec->fRasterClip.op(r, this->getBaseLayerSize(), op, kSoft_ClipEdgeStyle == edgeStyle); 15018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 1502123671901abfa595d09ca789b487c4bc7c1f7cbcrobertphillips@google.com // since we're rotated or some such thing, we convert the rect to a path 150398de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // and clip against that, since it can handle any matrix. However, to 150498de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // avoid recursion in the case where we are subclassed (e.g. Pictures) 150598de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // we explicitly call "our" version of clipPath. 15068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath path; 15078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 15088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.addRect(rect); 15098f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->SkCanvas::onClipPath(path, op, edgeStyle); 15108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 15118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 15128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 151373e714eb766617ce06757829a3c0b345c7963faareedstatic void rasterclip_path(SkRasterClip* rc, const SkCanvas* canvas, const SkPath& devPath, 151473e714eb766617ce06757829a3c0b345c7963faareed SkRegion::Op op, bool doAA) { 1515d64c9487135094c83f658319f53ea2005ecc08b2reed rc->op(devPath, canvas->getBaseLayerSize(), op, doAA); 1516819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com} 1517819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 1518759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) { 15192ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 15208f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 15214ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (rrect.isRect()) { 15228f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(rrect.getBounds(), op, edgeStyle); 15238f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } else { 15248f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRRect(rrect, op, edgeStyle); 15254ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 15268f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 152714e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 15288f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 152914e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org SkRRect transformedRRect; 15301f836ee096bb988adef4b9757b2629c7afeda36dreed if (rrect.transform(fMCRec->fMatrix, &transformedRRect)) { 153114e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org AutoValidateClip avc(this); 153214e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 153314e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org fDeviceCMDirty = true; 153414e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org fCachedLocalClipBoundsDirty = true; 15358f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!fAllowSoftClip) { 15368f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com edgeStyle = kHard_ClipEdgeStyle; 15378f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 153814e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 1539687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipDevRRect(transformedRRect, op, kSoft_ClipEdgeStyle == edgeStyle); 154014e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 154114e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org SkPath devPath; 154214e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org devPath.addRRect(transformedRRect); 154314e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 154473e714eb766617ce06757829a3c0b345c7963faareed rasterclip_path(&fMCRec->fRasterClip, this, devPath, op, kSoft_ClipEdgeStyle == edgeStyle); 15458f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com return; 154614e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org } 154714e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 154814e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org SkPath path; 154914e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org path.addRRect(rrect); 155014e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org // call the non-virtual version 15518f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->SkCanvas::onClipPath(path, op, edgeStyle); 15524ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 15534ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 1554759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { 15552ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 15568f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 15578f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com SkRect r; 15588f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!path.isInverseFillType() && path.isRect(&r)) { 15598f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(r, op, edgeStyle); 15608f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } else { 15618f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipPath(path, op, edgeStyle); 15628f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 15638f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 15648f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 15658f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 1566da17f758442f16747af39f8fbaed9c097048519creed@google.com#ifdef SK_ENABLE_CLIP_QUICKREJECT 1567da17f758442f16747af39f8fbaed9c097048519creed@google.com if (SkRegion::kIntersect_Op == op && !path.isInverseFillType()) { 15681f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fRasterClip.isEmpty()) { 1569da17f758442f16747af39f8fbaed9c097048519creed@google.com return false; 1570da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1571fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 15723b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(path.getBounds())) { 1573da17f758442f16747af39f8fbaed9c097048519creed@google.com fDeviceCMDirty = true; 1574c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 1575fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1576687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipEmpty(); 15771f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.setEmpty(); 1578da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1579da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1580da17f758442f16747af39f8fbaed9c097048519creed@google.com#endif 1581da17f758442f16747af39f8fbaed9c097048519creed@google.com 15825c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com AutoValidateClip avc(this); 15835c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 15848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1585c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 15868f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!fAllowSoftClip) { 15878f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com edgeStyle = kHard_ClipEdgeStyle; 15888f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 15898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 15908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath devPath; 15911f836ee096bb988adef4b9757b2629c7afeda36dreed path.transform(fMCRec->fMatrix, &devPath); 15928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1593fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // Check if the transfomation, or the original path itself 1594fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // made us empty. Note this can also happen if we contained NaN 1595fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // values. computing the bounds detects this, and will set our 1596fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // bounds to empty if that is the case. (see SkRect::set(pts, count)) 1597fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com if (devPath.getBounds().isEmpty()) { 1598fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // resetting the path will remove any NaN or other wanky values 1599fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // that might upset our scan converter. 1600fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com devPath.reset(); 1601fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com } 1602fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com 16035c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // if we called path.swap() we could avoid a deep copy of this path 1604687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipDevPath(devPath, op, kSoft_ClipEdgeStyle == edgeStyle); 16055c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 160645a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com if (fAllowSimplifyClip) { 16071a481fe4bf632ed4f76cb337691236fabfd4ab03fmalita bool clipIsAA = getClipStack()->asPath(&devPath); 16081a481fe4bf632ed4f76cb337691236fabfd4ab03fmalita if (clipIsAA) { 16091a481fe4bf632ed4f76cb337691236fabfd4ab03fmalita edgeStyle = kSoft_ClipEdgeStyle; 161045a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com } 16111a481fe4bf632ed4f76cb337691236fabfd4ab03fmalita 161245a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com op = SkRegion::kReplace_Op; 161345a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com } 161445a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com 161573e714eb766617ce06757829a3c0b345c7963faareed rasterclip_path(&fMCRec->fRasterClip, this, devPath, op, edgeStyle); 16168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1618759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipRegion(const SkRegion& rgn, SkRegion::Op op) { 16192ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 16208f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRegion(rgn, op); 16218f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 16228f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 16238f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipRegion(const SkRegion& rgn, SkRegion::Op op) { 16245c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com AutoValidateClip avc(this); 16255c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 16268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1627c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 16288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16295c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // todo: signal fClipStack that we have a region, and therefore (I guess) 16305c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // we have to ignore it, and use the region directly? 1631687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipDevRect(rgn.getBounds(), op); 16325c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 16331f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fRasterClip.op(rgn, op); 16348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1636819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com#ifdef SK_DEBUG 1637819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.comvoid SkCanvas::validateClip() const { 1638819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com // construct clipRgn from the clipstack 16391f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com const SkBaseDevice* device = this->getDevice(); 1640ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com if (!device) { 16415c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org SkASSERT(this->isClipEmpty()); 1642ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com return; 1643ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com } 1644ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com 1645819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com SkIRect ir; 1646819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com ir.set(0, 0, device->width(), device->height()); 1647d954498c01ccf0417feacf89e45d0c62a06a813breed SkRasterClip tmpClip(ir, fConservativeRasterClip); 1648819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 1649687fa1c745febb57f42b0d5f03d7c1f4be2530careed SkClipStack::B2TIter iter(*fClipStack); 16508182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const SkClipStack::Element* element; 16518182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com while ((element = iter.next()) != NULL) { 16528182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com switch (element->getType()) { 16538182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kRect_Type: 16548182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com element->getRect().round(&ir); 16558182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com tmpClip.op(ir, element->getOp()); 16568182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 16578182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kEmpty_Type: 16588182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com tmpClip.setEmpty(); 16598182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 16609cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org default: { 16619cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org SkPath path; 16629cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org element->asPath(&path); 166373e714eb766617ce06757829a3c0b345c7963faareed rasterclip_path(&tmpClip, this, path, element->getOp(), element->isAA()); 16649cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org break; 16659cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org } 1666819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com } 1667819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com } 1668819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com} 1669819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com#endif 1670819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 167190c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.comvoid SkCanvas::replayClips(ClipVisitor* visitor) const { 1672687fa1c745febb57f42b0d5f03d7c1f4be2530careed SkClipStack::B2TIter iter(*fClipStack); 16738182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const SkClipStack::Element* element; 16748182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com 16758182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com while ((element = iter.next()) != NULL) { 1676c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita element->replay(visitor); 167790c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com } 167890c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com} 167990c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com 16805c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com/////////////////////////////////////////////////////////////////////////////// 16815c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 1682754de5f65b466f721d952a379194cc94de376f42reed@google.combool SkCanvas::isClipEmpty() const { 16831f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.isEmpty(); 1684754de5f65b466f721d952a379194cc94de376f42reed@google.com} 1685754de5f65b466f721d952a379194cc94de376f42reed@google.com 16865c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.orgbool SkCanvas::isClipRect() const { 16871f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.isRect(); 16885c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org} 16895c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org 16903b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::quickReject(const SkRect& rect) const { 16911607863b608b7db6c813228768ed5d72997bbc82reed@google.com if (!rect.isFinite()) 1692116b2bcd2c4c4d4670c7b7e2ea597414713c37fbwjmaclean@chromium.org return true; 1693116b2bcd2c4c4d4670c7b7e2ea597414713c37fbwjmaclean@chromium.org 16941f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fRasterClip.isEmpty()) { 16958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 16968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 16978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16981f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fMatrix.hasPerspective()) { 1699a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com SkRect dst; 17001f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix.mapRect(&dst, rect); 1701b07a94f1cba3976596ae1a7f23d8c2043ba353f3reed return !SkIRect::Intersects(dst.roundOut(), fMCRec->fRasterClip.getBounds()); 1702a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com } else { 1703c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com const SkRect& clipR = this->getLocalClipBounds(); 1704d252db03d9650013b545ef9781fe993c07f8f314reed@android.com 1705a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com // for speed, do the most likely reject compares first 1706c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com // TODO: should we use | instead, or compare all 4 at once? 1707c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com if (rect.fTop >= clipR.fBottom || rect.fBottom <= clipR.fTop) { 1708a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com return true; 1709a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com } 1710c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com if (rect.fLeft >= clipR.fRight || rect.fRight <= clipR.fLeft) { 1711a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com return true; 1712a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com } 1713a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com return false; 17148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 17158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17173b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::quickReject(const SkPath& path) const { 17183b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com return path.isEmpty() || this->quickReject(path.getBounds()); 17198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17213b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::getClipBounds(SkRect* bounds) const { 1722bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect ibounds; 17238f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!this->getClipDeviceBounds(&ibounds)) { 17248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 17258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 17268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1727d9c0f0b57affec7a472879c5919acac6637d926areed@android.com SkMatrix inverse; 1728d9c0f0b57affec7a472879c5919acac6637d926areed@android.com // if we can't invert the CTM, we can't return local clip bounds 17291f836ee096bb988adef4b9757b2629c7afeda36dreed if (!fMCRec->fMatrix.invert(&inverse)) { 173072dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com if (bounds) { 173172dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com bounds->setEmpty(); 173272dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com } 1733d9c0f0b57affec7a472879c5919acac6637d926areed@android.com return false; 1734d9c0f0b57affec7a472879c5919acac6637d926areed@android.com } 1735d9c0f0b57affec7a472879c5919acac6637d926areed@android.com 173649f085dddff10473b6ebf832a974288300224e60bsalomon if (bounds) { 1737bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkRect r; 17383b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com // adjust it outwards in case we are antialiasing 17393b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com const int inset = 1; 1740fa4d5bd09f8f1a4a92b5ae0324800dd672760898reed@google.com 17418f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com r.iset(ibounds.fLeft - inset, ibounds.fTop - inset, 17428f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com ibounds.fRight + inset, ibounds.fBottom + inset); 17438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inverse.mapRect(bounds, r); 17448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 17458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 17468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1748bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.combool SkCanvas::getClipDeviceBounds(SkIRect* bounds) const { 17491f836ee096bb988adef4b9757b2629c7afeda36dreed const SkRasterClip& clip = fMCRec->fRasterClip; 1750bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (clip.isEmpty()) { 1751bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (bounds) { 1752bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com bounds->setEmpty(); 1753bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1754bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com return false; 1755bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1756bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com 175749f085dddff10473b6ebf832a974288300224e60bsalomon if (bounds) { 1758bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com *bounds = clip.getBounds(); 1759bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1760bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com return true; 1761bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com} 1762bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com 17638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkMatrix& SkCanvas::getTotalMatrix() const { 17641f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fMatrix; 17658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17675c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.orgconst SkRegion& SkCanvas::internal_private_getTotalClip() const { 17681f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.forceGetBW(); 17695c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org} 17705c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org 17719c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.comGrRenderTarget* SkCanvas::internal_private_accessTopLayerRenderTarget() { 17729c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com SkBaseDevice* dev = this->getTopDevice(); 17739c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com return dev ? dev->accessRenderTarget() : NULL; 17749c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 17759c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1776644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.orgGrContext* SkCanvas::getGrContext() { 1777644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#if SK_SUPPORT_GPU 1778644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org SkBaseDevice* device = this->getTopDevice(); 177949f085dddff10473b6ebf832a974288300224e60bsalomon if (device) { 1780644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org GrRenderTarget* renderTarget = device->accessRenderTarget(); 178149f085dddff10473b6ebf832a974288300224e60bsalomon if (renderTarget) { 1782644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org return renderTarget->getContext(); 1783644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org } 1784644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org } 1785644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#endif 1786644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org 1787644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org return NULL; 1788644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org 1789644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org} 1790e97f0856a8044866b12527819d14cdfbcdfd96f2bsalomon@google.com 1791ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.orgvoid SkCanvas::drawDRRect(const SkRRect& outer, const SkRRect& inner, 1792ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkPaint& paint) { 17939881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawDRRect()"); 1794ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (outer.isEmpty()) { 1795ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 1796ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 1797ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (inner.isEmpty()) { 1798ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->drawRRect(outer, paint); 1799ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 1800ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 1801ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 1802ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // We don't have this method (yet), but technically this is what we should 1803ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // be able to assert... 1804ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // SkASSERT(outer.contains(inner)); 1805ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // 1806ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // For now at least check for containment of bounds 1807ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org SkASSERT(outer.getBounds().contains(inner.getBounds())); 1808ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 1809ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->onDrawDRRect(outer, inner, paint); 1810ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org} 1811ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 181241af966ab338e95eee81ab618ab28195075338f7reed// These need to stop being virtual -- clients need to override the onDraw... versions 181341af966ab338e95eee81ab618ab28195075338f7reed 181441af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawPaint(const SkPaint& paint) { 181541af966ab338e95eee81ab618ab28195075338f7reed this->onDrawPaint(paint); 181641af966ab338e95eee81ab618ab28195075338f7reed} 181741af966ab338e95eee81ab618ab28195075338f7reed 181841af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawRect(const SkRect& r, const SkPaint& paint) { 181941af966ab338e95eee81ab618ab28195075338f7reed this->onDrawRect(r, paint); 182041af966ab338e95eee81ab618ab28195075338f7reed} 182141af966ab338e95eee81ab618ab28195075338f7reed 182241af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawOval(const SkRect& r, const SkPaint& paint) { 182341af966ab338e95eee81ab618ab28195075338f7reed this->onDrawOval(r, paint); 182441af966ab338e95eee81ab618ab28195075338f7reed} 182541af966ab338e95eee81ab618ab28195075338f7reed 182641af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) { 182741af966ab338e95eee81ab618ab28195075338f7reed this->onDrawRRect(rrect, paint); 182841af966ab338e95eee81ab618ab28195075338f7reed} 182941af966ab338e95eee81ab618ab28195075338f7reed 183041af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint) { 183141af966ab338e95eee81ab618ab28195075338f7reed this->onDrawPoints(mode, count, pts, paint); 183241af966ab338e95eee81ab618ab28195075338f7reed} 183341af966ab338e95eee81ab618ab28195075338f7reed 183441af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawVertices(VertexMode vmode, int vertexCount, const SkPoint vertices[], 183541af966ab338e95eee81ab618ab28195075338f7reed const SkPoint texs[], const SkColor colors[], SkXfermode* xmode, 183641af966ab338e95eee81ab618ab28195075338f7reed const uint16_t indices[], int indexCount, const SkPaint& paint) { 183741af966ab338e95eee81ab618ab28195075338f7reed this->onDrawVertices(vmode, vertexCount, vertices, texs, colors, xmode, 183841af966ab338e95eee81ab618ab28195075338f7reed indices, indexCount, paint); 183941af966ab338e95eee81ab618ab28195075338f7reed} 184041af966ab338e95eee81ab618ab28195075338f7reed 184141af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawPath(const SkPath& path, const SkPaint& paint) { 184241af966ab338e95eee81ab618ab28195075338f7reed this->onDrawPath(path, paint); 184341af966ab338e95eee81ab618ab28195075338f7reed} 184441af966ab338e95eee81ab618ab28195075338f7reed 1845a85d4d0814818e4ddabb9237da209d61d6cd5854reedvoid SkCanvas::drawImage(const SkImage* image, SkScalar x, SkScalar y, const SkPaint* paint) { 1846a85d4d0814818e4ddabb9237da209d61d6cd5854reed this->onDrawImage(image, x, y, paint); 184741af966ab338e95eee81ab618ab28195075338f7reed} 184841af966ab338e95eee81ab618ab28195075338f7reed 1849e47829b6b1eeb6b0c97ccb3df3016d197046824creed#ifdef SK_SUPPORT_LEGACY_SRCPTR_DRAWIMAGERECT 185041af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, 1851a5517e2b190a8083b38964972b031c13e99f1012reed const SkPaint* paint, SrcRectConstraint constraint) { 1852a85d4d0814818e4ddabb9237da209d61d6cd5854reed if (dst.isEmpty()) { 1853a85d4d0814818e4ddabb9237da209d61d6cd5854reed return; 1854a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 1855562fe4767cc73e08a4e039362bc0336aea66ecfbreed this->onDrawImageRect(image, src, dst, paint, constraint); 185641af966ab338e95eee81ab618ab28195075338f7reed} 1857e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, 1858e47829b6b1eeb6b0c97ccb3df3016d197046824creed const SkPaint* paint, SrcRectConstraint constraint) { 1859e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (bitmap.drawsNothing() || dst.isEmpty()) { 1860e47829b6b1eeb6b0c97ccb3df3016d197046824creed return; 1861e47829b6b1eeb6b0c97ccb3df3016d197046824creed } 1862e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->onDrawBitmapRect(bitmap, src, dst, paint, constraint); 1863e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 1864e47829b6b1eeb6b0c97ccb3df3016d197046824creed#endif 1865e47829b6b1eeb6b0c97ccb3df3016d197046824creed 1866e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst, 1867e47829b6b1eeb6b0c97ccb3df3016d197046824creed const SkPaint* paint, SrcRectConstraint constraint) { 1868e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (dst.isEmpty() || src.isEmpty()) { 1869e47829b6b1eeb6b0c97ccb3df3016d197046824creed return; 1870e47829b6b1eeb6b0c97ccb3df3016d197046824creed } 1871e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->onDrawImageRect(image, &src, dst, paint, constraint); 1872e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 187341af966ab338e95eee81ab618ab28195075338f7reed 187484984efeb64787b88c5f8bd6929cfe2d58a3ba06reedvoid SkCanvas::drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst, 187584984efeb64787b88c5f8bd6929cfe2d58a3ba06reed const SkPaint* paint, SrcRectConstraint constraint) { 1876e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, SkRect::Make(isrc), dst, paint, constraint); 187784984efeb64787b88c5f8bd6929cfe2d58a3ba06reed} 187884984efeb64787b88c5f8bd6929cfe2d58a3ba06reed 1879e47829b6b1eeb6b0c97ccb3df3016d197046824creed#ifdef SK_SUPPORT_LEGACY_SIMPLE_DRAWIMAGERECT 1880e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint) { 1881e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, SkRect::MakeIWH(image->width(), image->height()), dst, paint); 1882e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 1883e47829b6b1eeb6b0c97ccb3df3016d197046824creed#else 1884e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint, 1885e47829b6b1eeb6b0c97ccb3df3016d197046824creed SrcRectConstraint constraint) { 1886e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, SkRect::MakeIWH(image->width(), image->height()), dst, paint, 1887e47829b6b1eeb6b0c97ccb3df3016d197046824creed constraint); 1888e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 1889e47829b6b1eeb6b0c97ccb3df3016d197046824creed#endif 1890e47829b6b1eeb6b0c97ccb3df3016d197046824creed 18914c21dc5ddf3b482293ed34eead876d8d61a662c3reedvoid SkCanvas::drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst, 18924c21dc5ddf3b482293ed34eead876d8d61a662c3reed const SkPaint* paint) { 18934c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (dst.isEmpty()) { 18944c21dc5ddf3b482293ed34eead876d8d61a662c3reed return; 18954c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 18964c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (!SkNinePatchIter::Valid(image->width(), image->height(), center)) { 1897e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, dst, paint); 18984c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 18994c21dc5ddf3b482293ed34eead876d8d61a662c3reed this->onDrawImageNine(image, center, dst, paint); 19004c21dc5ddf3b482293ed34eead876d8d61a662c3reed} 19014c21dc5ddf3b482293ed34eead876d8d61a662c3reed 190241af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar dx, SkScalar dy, const SkPaint* paint) { 19034c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (bitmap.drawsNothing()) { 19042df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson return; 19052df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson } 190641af966ab338e95eee81ab618ab28195075338f7reed this->onDrawBitmap(bitmap, dx, dy, paint); 190741af966ab338e95eee81ab618ab28195075338f7reed} 190841af966ab338e95eee81ab618ab28195075338f7reed 1909e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst, 1910a5517e2b190a8083b38964972b031c13e99f1012reed const SkPaint* paint, SrcRectConstraint constraint) { 1911e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (bitmap.drawsNothing() || dst.isEmpty() || src.isEmpty()) { 1912a5517e2b190a8083b38964972b031c13e99f1012reed return; 1913a5517e2b190a8083b38964972b031c13e99f1012reed } 1914e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->onDrawBitmapRect(bitmap, &src, dst, paint, constraint); 191541af966ab338e95eee81ab618ab28195075338f7reed} 191641af966ab338e95eee81ab618ab28195075338f7reed 191784984efeb64787b88c5f8bd6929cfe2d58a3ba06reedvoid SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst, 191884984efeb64787b88c5f8bd6929cfe2d58a3ba06reed const SkPaint* paint, SrcRectConstraint constraint) { 1919e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, SkRect::Make(isrc), dst, paint, constraint); 1920e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 1921e47829b6b1eeb6b0c97ccb3df3016d197046824creed 1922e47829b6b1eeb6b0c97ccb3df3016d197046824creed#ifdef SK_SUPPORT_LEGACY_SIMPLE_DRAWIMAGERECT 1923e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint) { 1924e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, SkRect::MakeIWH(bitmap.width(), bitmap.height()), dst, paint); 1925e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 1926e47829b6b1eeb6b0c97ccb3df3016d197046824creed#else 1927e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint, 1928e47829b6b1eeb6b0c97ccb3df3016d197046824creed SrcRectConstraint constraint) { 1929e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, SkRect::MakeIWH(bitmap.width(), bitmap.height()), dst, paint, 1930e47829b6b1eeb6b0c97ccb3df3016d197046824creed constraint); 193184984efeb64787b88c5f8bd6929cfe2d58a3ba06reed} 1932e47829b6b1eeb6b0c97ccb3df3016d197046824creed#endif 193384984efeb64787b88c5f8bd6929cfe2d58a3ba06reed 193441af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst, 193541af966ab338e95eee81ab618ab28195075338f7reed const SkPaint* paint) { 19364c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (bitmap.drawsNothing() || dst.isEmpty()) { 19372df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson return; 19382df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson } 19394c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (!SkNinePatchIter::Valid(bitmap.width(), bitmap.height(), center)) { 1940a5517e2b190a8083b38964972b031c13e99f1012reed this->drawBitmapRect(bitmap, dst, paint); 19414c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 194241af966ab338e95eee81ab618ab28195075338f7reed this->onDrawBitmapNine(bitmap, center, dst, paint); 194341af966ab338e95eee81ab618ab28195075338f7reed} 194441af966ab338e95eee81ab618ab28195075338f7reed 194541af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawSprite(const SkBitmap& bitmap, int left, int top, const SkPaint* paint) { 19464c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (bitmap.drawsNothing()) { 19472df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson return; 19482df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson } 194941af966ab338e95eee81ab618ab28195075338f7reed this->onDrawSprite(bitmap, left, top, paint); 195041af966ab338e95eee81ab618ab28195075338f7reed} 195141af966ab338e95eee81ab618ab28195075338f7reed 195271c3c760a83123ee0b3127b8c65c6394ce541c50reedvoid SkCanvas::drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], 195371c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkColor colors[], int count, SkXfermode::Mode mode, 195471c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkRect* cull, const SkPaint* paint) { 195571c3c760a83123ee0b3127b8c65c6394ce541c50reed if (count <= 0) { 195671c3c760a83123ee0b3127b8c65c6394ce541c50reed return; 195771c3c760a83123ee0b3127b8c65c6394ce541c50reed } 195871c3c760a83123ee0b3127b8c65c6394ce541c50reed SkASSERT(atlas); 195971c3c760a83123ee0b3127b8c65c6394ce541c50reed SkASSERT(xform); 196071c3c760a83123ee0b3127b8c65c6394ce541c50reed SkASSERT(tex); 196171c3c760a83123ee0b3127b8c65c6394ce541c50reed this->onDrawAtlas(atlas, xform, tex, colors, count, mode, cull, paint); 196271c3c760a83123ee0b3127b8c65c6394ce541c50reed} 196371c3c760a83123ee0b3127b8c65c6394ce541c50reed 1964e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::legacy_drawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, 1965e47829b6b1eeb6b0c97ccb3df3016d197046824creed const SkPaint* paint, SrcRectConstraint constraint) { 1966e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (src) { 1967e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, *src, dst, paint, constraint); 1968e47829b6b1eeb6b0c97ccb3df3016d197046824creed } else { 1969e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawImageRect(image, SkRect::MakeIWH(image->width(), image->height()), 1970e47829b6b1eeb6b0c97ccb3df3016d197046824creed dst, paint, constraint); 1971e47829b6b1eeb6b0c97ccb3df3016d197046824creed } 1972e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 1973e47829b6b1eeb6b0c97ccb3df3016d197046824creedvoid SkCanvas::legacy_drawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, 1974e47829b6b1eeb6b0c97ccb3df3016d197046824creed const SkPaint* paint, SrcRectConstraint constraint) { 1975e47829b6b1eeb6b0c97ccb3df3016d197046824creed if (src) { 1976e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, *src, dst, paint, constraint); 1977e47829b6b1eeb6b0c97ccb3df3016d197046824creed } else { 1978e47829b6b1eeb6b0c97ccb3df3016d197046824creed this->drawBitmapRect(bitmap, SkRect::MakeIWH(bitmap.width(), bitmap.height()), 1979e47829b6b1eeb6b0c97ccb3df3016d197046824creed dst, paint, constraint); 1980e47829b6b1eeb6b0c97ccb3df3016d197046824creed } 1981e47829b6b1eeb6b0c97ccb3df3016d197046824creed} 1982e47829b6b1eeb6b0c97ccb3df3016d197046824creed 19838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 19848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// These are the virtual drawing methods 19858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 19868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 198728361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.orgvoid SkCanvas::onDiscard() { 198849f085dddff10473b6ebf832a974288300224e60bsalomon if (fSurfaceBase) { 198928361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org fSurfaceBase->aboutToDraw(SkSurface::kDiscard_ContentChangeMode); 199028361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org } 199128361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org} 199228361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org 199341af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawPaint(const SkPaint& paint) { 19949881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPaint()"); 1995fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->internalDrawPaint(paint); 1996fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com} 1997fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com 1998fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.comvoid SkCanvas::internalDrawPaint(const SkPaint& paint) { 1999c83a29759a5c2966da5ab973e4fd90763e4c962breed LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, SkDrawFilter::kPaint_Type, NULL, false) 20008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 20024e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPaint(iter, looper.paint()); 20038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 20048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20054e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 20068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 20078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 200841af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[], 200941af966ab338e95eee81ab618ab28195075338f7reed const SkPaint& paint) { 20109881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT1("disabled-by-default-skia", "SkCanvas::drawPoints()", "count", static_cast<uint64_t>(count)); 20118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if ((long)count <= 0) { 20128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 20138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 20148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 201578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect r, storage; 201678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 2017a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com if (paint.canComputeFastBounds()) { 2018a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com // special-case 2 points (common for drawing a single line) 2019a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com if (2 == count) { 2020a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com r.set(pts[0], pts[1]); 2021a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } else { 2022a8c7f7702fb4bbedb615031bc653c5cd161a038ecommit-bot@chromium.org r.set(pts, SkToInt(count)); 2023a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } 202478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint.computeFastStrokeBounds(r, &storage); 202578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (this->quickReject(*bounds)) { 2026a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com return; 2027a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } 2028fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 2029a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com 20308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(pts != NULL); 20318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 203278cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPoint_Type, bounds) 20334b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 20348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 20354e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPoints(iter, mode, count, pts, looper.paint()); 20368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 20374b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 20384e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 20398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 20408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 204141af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawRect(const SkRect& r, const SkPaint& paint) { 20429881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRect()"); 204378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 204478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 20458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.canComputeFastBounds()) { 20468432808ad8898ac7137bc7ce1d9df6005e866401reed // Skia will draw an inverted rect, because it explicitly "sorts" it downstream. 20478432808ad8898ac7137bc7ce1d9df6005e866401reed // To prevent accidental rejecting at this stage, we have to sort it before we check. 20488432808ad8898ac7137bc7ce1d9df6005e866401reed SkRect tmp(r); 20498432808ad8898ac7137bc7ce1d9df6005e866401reed tmp.sort(); 20508432808ad8898ac7137bc7ce1d9df6005e866401reed 20518432808ad8898ac7137bc7ce1d9df6005e866401reed bounds = &paint.computeFastBounds(tmp, &storage); 205278cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (this->quickReject(*bounds)) { 20538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 20548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 20558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 20564b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2057c83a29759a5c2966da5ab973e4fd90763e4c962breed LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, SkDrawFilter::kRect_Type, bounds, false) 20588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 20604e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawRect(iter, r, looper.paint()); 20618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 20628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20634e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 20648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 20658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 206641af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) { 20679881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawOval()"); 206878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 206978cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 20704ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (paint.canComputeFastBounds()) { 207178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint.computeFastBounds(oval, &storage); 207278cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (this->quickReject(*bounds)) { 20734ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com return; 20744ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 20754ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 2076306ab9d5de38f2a547fd1d69aedbe69b5c6617ccskia.committer@gmail.com 207778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, bounds) 207846d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com 207946d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com while (iter.next()) { 208046d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com iter.fDevice->drawOval(iter, oval, looper.paint()); 208146d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com } 208246d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com 208346d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com LOOPER_END 20844ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 20854ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 208641af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) { 20879881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRRect()"); 208878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 208978cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 20904ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (paint.canComputeFastBounds()) { 209178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint.computeFastBounds(rrect.getBounds(), &storage); 209278cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (this->quickReject(*bounds)) { 20934ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com return; 20944ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 20954ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 20964ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 20974ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (rrect.isRect()) { 20984ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com // call the non-virtual version 20994ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->SkCanvas::drawRect(rrect.getBounds(), paint); 2100f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org return; 2101f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } else if (rrect.isOval()) { 21024ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com // call the non-virtual version 2103f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org this->SkCanvas::drawOval(rrect.getBounds(), paint); 2104f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org return; 21054ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 2106f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 210778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) 2108f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 2109f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org while (iter.next()) { 2110f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org iter.fDevice->drawRRect(iter, rrect, looper.paint()); 2111f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } 2112f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 2113f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org LOOPER_END 21144ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 21154ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 2116ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.orgvoid SkCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, 2117ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkPaint& paint) { 2118ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org SkRect storage; 2119ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkRect* bounds = NULL; 2120ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (paint.canComputeFastBounds()) { 2121ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org bounds = &paint.computeFastBounds(outer.getBounds(), &storage); 2122ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (this->quickReject(*bounds)) { 2123ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 2124ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 2125ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 212625c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 2127ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) 212825c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 2129ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org while (iter.next()) { 2130ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org iter.fDevice->drawDRRect(iter, outer, inner, looper.paint()); 2131ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 213225c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 2133ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org LOOPER_END 2134ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org} 21354ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 213641af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) { 21379881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPath()"); 21389364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com if (!path.isFinite()) { 21399364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com return; 21409364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com } 21419364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com 214278cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 214378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 2144fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com if (!path.isInverseFillType() && paint.canComputeFastBounds()) { 214578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect& pathBounds = path.getBounds(); 214678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint.computeFastBounds(pathBounds, &storage); 214778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (this->quickReject(*bounds)) { 21488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 21498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 21508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 21510b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org 21520b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org const SkRect& r = path.getBounds(); 21530b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org if (r.width() <= 0 && r.height() <= 0) { 21546803c219dd3be4a73e7bb5c4bb8a5b1f803624d0commit-bot@chromium.org if (path.isInverseFillType()) { 2155fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->internalDrawPaint(paint); 2156fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 2157fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com return; 2158fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 21598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 216078cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, bounds) 21618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 21634e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPath(iter, path, looper.paint()); 21648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 21658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21664e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 21678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 21688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2169a85d4d0814818e4ddabb9237da209d61d6cd5854reedvoid SkCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, const SkPaint* paint) { 21709881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImage()"); 2171a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkRect bounds = SkRect::MakeXYWH(x, y, 2172a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkIntToScalar(image->width()), SkIntToScalar(image->height())); 2173a85d4d0814818e4ddabb9237da209d61d6cd5854reed if (NULL == paint || paint->canComputeFastBounds()) { 2174a85d4d0814818e4ddabb9237da209d61d6cd5854reed if (paint) { 2175a85d4d0814818e4ddabb9237da209d61d6cd5854reed paint->computeFastBounds(bounds, &bounds); 2176a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2177a85d4d0814818e4ddabb9237da209d61d6cd5854reed if (this->quickReject(bounds)) { 2178a85d4d0814818e4ddabb9237da209d61d6cd5854reed return; 2179a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2180a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2181a85d4d0814818e4ddabb9237da209d61d6cd5854reed 2182a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkLazyPaint lazy; 2183a85d4d0814818e4ddabb9237da209d61d6cd5854reed if (NULL == paint) { 2184a85d4d0814818e4ddabb9237da209d61d6cd5854reed paint = lazy.init(); 2185a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2186a85d4d0814818e4ddabb9237da209d61d6cd5854reed 2187a85d4d0814818e4ddabb9237da209d61d6cd5854reed LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &bounds) 2188a85d4d0814818e4ddabb9237da209d61d6cd5854reed 2189a85d4d0814818e4ddabb9237da209d61d6cd5854reed while (iter.next()) { 2190a85d4d0814818e4ddabb9237da209d61d6cd5854reed iter.fDevice->drawImage(iter, image, x, y, looper.paint()); 2191a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2192a85d4d0814818e4ddabb9237da209d61d6cd5854reed 2193a85d4d0814818e4ddabb9237da209d61d6cd5854reed LOOPER_END 2194b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr} 2195b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 219641af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, 2197562fe4767cc73e08a4e039362bc0336aea66ecfbreed const SkPaint* paint, SrcRectConstraint constraint) { 21989881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImageRect()"); 2199a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkRect storage; 2200a85d4d0814818e4ddabb9237da209d61d6cd5854reed const SkRect* bounds = &dst; 2201a85d4d0814818e4ddabb9237da209d61d6cd5854reed if (NULL == paint || paint->canComputeFastBounds()) { 2202a85d4d0814818e4ddabb9237da209d61d6cd5854reed if (paint) { 2203a85d4d0814818e4ddabb9237da209d61d6cd5854reed bounds = &paint->computeFastBounds(dst, &storage); 2204a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2205a85d4d0814818e4ddabb9237da209d61d6cd5854reed if (this->quickReject(*bounds)) { 2206a85d4d0814818e4ddabb9237da209d61d6cd5854reed return; 2207a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2208a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2209a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkLazyPaint lazy; 2210a85d4d0814818e4ddabb9237da209d61d6cd5854reed if (NULL == paint) { 2211a85d4d0814818e4ddabb9237da209d61d6cd5854reed paint = lazy.init(); 2212a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2213a85d4d0814818e4ddabb9237da209d61d6cd5854reed 2214c83a29759a5c2966da5ab973e4fd90763e4c962breed LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, SkDrawFilter::kBitmap_Type, bounds, 2215c83a29759a5c2966da5ab973e4fd90763e4c962breed image->isOpaque()) 2216a85d4d0814818e4ddabb9237da209d61d6cd5854reed 2217a85d4d0814818e4ddabb9237da209d61d6cd5854reed while (iter.next()) { 2218a5517e2b190a8083b38964972b031c13e99f1012reed iter.fDevice->drawImageRect(iter, image, src, dst, looper.paint(), constraint); 2219a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2220a85d4d0814818e4ddabb9237da209d61d6cd5854reed 2221a85d4d0814818e4ddabb9237da209d61d6cd5854reed LOOPER_END 2222b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr} 2223b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 222441af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y, const SkPaint* paint) { 22259881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmap()"); 22268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(bitmap.validate();) 22278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22283d60812865bb034851da777a91413ab584929887reed@google.com if (NULL == paint || paint->canComputeFastBounds()) { 22299efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com SkRect bounds = { 22309efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com x, y, 22319efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com x + SkIntToScalar(bitmap.width()), 22329efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com y + SkIntToScalar(bitmap.height()) 22339efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com }; 22349efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com if (paint) { 22359efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com (void)paint->computeFastBounds(bounds, &bounds); 22369efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com } 22373b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(bounds)) { 22388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 22398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 22408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 22414b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 22428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 22438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.setTranslate(x, y); 22449bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com this->internalDrawBitmap(bitmap, matrix, paint); 22458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 22468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22479987ec3791336bad6af5cbe513564786b2df55aareed@google.com// this one is non-virtual, so it can be called safely by other canvas apis 22487112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.comvoid SkCanvas::internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, 2249eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org const SkRect& dst, const SkPaint* paint, 2250a5517e2b190a8083b38964972b031c13e99f1012reed SrcRectConstraint constraint) { 225150b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org if (bitmap.drawsNothing() || dst.isEmpty()) { 22528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 22538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 225474b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 225578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 225678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = &dst; 22573d60812865bb034851da777a91413ab584929887reed@google.com if (NULL == paint || paint->canComputeFastBounds()) { 22589efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com if (paint) { 22599efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com bounds = &paint->computeFastBounds(dst, &storage); 22609efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com } 22613b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(*bounds)) { 22623d60812865bb034851da777a91413ab584929887reed@google.com return; 22633d60812865bb034851da777a91413ab584929887reed@google.com } 22648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 22653d60812865bb034851da777a91413ab584929887reed@google.com 226633535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com SkLazyPaint lazy; 226733535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com if (NULL == paint) { 226833535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com paint = lazy.init(); 22698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 22707064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 2271c83a29759a5c2966da5ab973e4fd90763e4c962breed LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(*paint, SkDrawFilter::kBitmap_Type, bounds, 2272c83a29759a5c2966da5ab973e4fd90763e4c962breed bitmap.isOpaque()) 22737064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 227433535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com while (iter.next()) { 2275562fe4767cc73e08a4e039362bc0336aea66ecfbreed iter.fDevice->drawBitmapRect(iter, bitmap, src, dst, looper.paint(), constraint); 2276f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 22777064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 227833535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com LOOPER_END 22798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 22808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 228141af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, 2282562fe4767cc73e08a4e039362bc0336aea66ecfbreed const SkPaint* paint, SrcRectConstraint constraint) { 22839881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmapRectToRect()"); 22849987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkDEBUGCODE(bitmap.validate();) 2285562fe4767cc73e08a4e039362bc0336aea66ecfbreed this->internalDrawBitmapRect(bitmap, src, dst, paint, constraint); 22869987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 22879987ec3791336bad6af5cbe513564786b2df55aareed@google.com 22884c21dc5ddf3b482293ed34eead876d8d61a662c3reedvoid SkCanvas::onDrawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst, 22894c21dc5ddf3b482293ed34eead876d8d61a662c3reed const SkPaint* paint) { 22904c21dc5ddf3b482293ed34eead876d8d61a662c3reed TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImageNine()"); 22914c21dc5ddf3b482293ed34eead876d8d61a662c3reed 22924c21dc5ddf3b482293ed34eead876d8d61a662c3reed SkRect storage; 22934c21dc5ddf3b482293ed34eead876d8d61a662c3reed const SkRect* bounds = &dst; 22943d60812865bb034851da777a91413ab584929887reed@google.com if (NULL == paint || paint->canComputeFastBounds()) { 229560abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com if (paint) { 229660abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com bounds = &paint->computeFastBounds(dst, &storage); 229760abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com } 22983b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(*bounds)) { 22993d60812865bb034851da777a91413ab584929887reed@google.com return; 23003d60812865bb034851da777a91413ab584929887reed@google.com } 23013d60812865bb034851da777a91413ab584929887reed@google.com } 23024c21dc5ddf3b482293ed34eead876d8d61a662c3reed 23034c21dc5ddf3b482293ed34eead876d8d61a662c3reed SkLazyPaint lazy; 23044c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (NULL == paint) { 23054c21dc5ddf3b482293ed34eead876d8d61a662c3reed paint = lazy.init(); 23064c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 23074c21dc5ddf3b482293ed34eead876d8d61a662c3reed 23084c21dc5ddf3b482293ed34eead876d8d61a662c3reed LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) 23094c21dc5ddf3b482293ed34eead876d8d61a662c3reed 23104c21dc5ddf3b482293ed34eead876d8d61a662c3reed while (iter.next()) { 23114c21dc5ddf3b482293ed34eead876d8d61a662c3reed iter.fDevice->drawImageNine(iter, image, center, dst, looper.paint()); 23129987ec3791336bad6af5cbe513564786b2df55aareed@google.com } 23134c21dc5ddf3b482293ed34eead876d8d61a662c3reed 23144c21dc5ddf3b482293ed34eead876d8d61a662c3reed LOOPER_END 23159987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 23169987ec3791336bad6af5cbe513564786b2df55aareed@google.com 231741af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst, 231841af966ab338e95eee81ab618ab28195075338f7reed const SkPaint* paint) { 23199881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmapNine()"); 23209987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkDEBUGCODE(bitmap.validate();) 23219987ec3791336bad6af5cbe513564786b2df55aareed@google.com 23224c21dc5ddf3b482293ed34eead876d8d61a662c3reed SkRect storage; 23234c21dc5ddf3b482293ed34eead876d8d61a662c3reed const SkRect* bounds = &dst; 23244c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (NULL == paint || paint->canComputeFastBounds()) { 23254c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (paint) { 23264c21dc5ddf3b482293ed34eead876d8d61a662c3reed bounds = &paint->computeFastBounds(dst, &storage); 23274c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 23284c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (this->quickReject(*bounds)) { 23294c21dc5ddf3b482293ed34eead876d8d61a662c3reed return; 23304c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 23314c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 23324c21dc5ddf3b482293ed34eead876d8d61a662c3reed 23334c21dc5ddf3b482293ed34eead876d8d61a662c3reed SkLazyPaint lazy; 23344c21dc5ddf3b482293ed34eead876d8d61a662c3reed if (NULL == paint) { 23354c21dc5ddf3b482293ed34eead876d8d61a662c3reed paint = lazy.init(); 23364c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 23374c21dc5ddf3b482293ed34eead876d8d61a662c3reed 23384c21dc5ddf3b482293ed34eead876d8d61a662c3reed LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) 23394c21dc5ddf3b482293ed34eead876d8d61a662c3reed 23404c21dc5ddf3b482293ed34eead876d8d61a662c3reed while (iter.next()) { 23414c21dc5ddf3b482293ed34eead876d8d61a662c3reed iter.fDevice->drawBitmapNine(iter, bitmap, center, dst, looper.paint()); 23424c21dc5ddf3b482293ed34eead876d8d61a662c3reed } 23434c21dc5ddf3b482293ed34eead876d8d61a662c3reed 23444c21dc5ddf3b482293ed34eead876d8d61a662c3reed LOOPER_END 23459987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 23469987ec3791336bad6af5cbe513564786b2df55aareed@google.com 2347f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.comclass SkDeviceFilteredPaint { 2348f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.compublic: 23491f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkDeviceFilteredPaint(SkBaseDevice* device, const SkPaint& paint) { 2350112e7e277702e104357f2d44742253ee1b0109acfmalita uint32_t filteredFlags = device->filterTextFlags(paint); 2351112e7e277702e104357f2d44742253ee1b0109acfmalita if (filteredFlags != paint.getFlags()) { 2352a076e9be17654a60310e72c4f70fcd5337f56dbfreed@google.com SkPaint* newPaint = fLazy.set(paint); 2353112e7e277702e104357f2d44742253ee1b0109acfmalita newPaint->setFlags(filteredFlags); 2354f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com fPaint = newPaint; 2355f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } else { 2356f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com fPaint = &paint; 2357f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } 2358f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } 2359f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 2360f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com const SkPaint& paint() const { return *fPaint; } 2361f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 2362f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.comprivate: 23632c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint* fPaint; 23642c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkLazyPaint fLazy; 2365f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com}; 2366f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 236752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.comvoid SkCanvas::DrawRect(const SkDraw& draw, const SkPaint& paint, 236852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com const SkRect& r, SkScalar textSize) { 236917b78946096265d80215a6c946286ecaa35ea7edepoger@google.com if (paint.getStyle() == SkPaint::kFill_Style) { 237052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com draw.fDevice->drawRect(draw, r, paint); 237152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } else { 237252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPaint p(paint); 237317b78946096265d80215a6c946286ecaa35ea7edepoger@google.com p.setStrokeWidth(SkScalarMul(textSize, paint.getStrokeWidth())); 237452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com draw.fDevice->drawRect(draw, r, p); 237552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 237652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com} 237752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 237852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.comvoid SkCanvas::DrawTextDecorations(const SkDraw& draw, const SkPaint& paint, 237952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com const char text[], size_t byteLength, 238052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar x, SkScalar y) { 238152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkASSERT(byteLength == 0 || text != NULL); 238252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 238352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com // nothing to draw 238452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (text == NULL || byteLength == 0 || 238552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com draw.fClip->isEmpty() || 238652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com (paint.getAlpha() == 0 && paint.getXfermode() == NULL)) { 238752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com return; 238852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 238952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 239052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar width = 0; 239152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPoint start; 239252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 239352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.set(0, 0); // to avoid warning 239452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (paint.getFlags() & (SkPaint::kUnderlineText_Flag | 239552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPaint::kStrikeThruText_Flag)) { 239652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com width = paint.measureText(text, byteLength); 239752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 239852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar offsetX = 0; 239952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (paint.getTextAlign() == SkPaint::kCenter_Align) { 240052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com offsetX = SkScalarHalf(width); 240152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } else if (paint.getTextAlign() == SkPaint::kRight_Align) { 240252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com offsetX = width; 240352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 240452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.set(x - offsetX, y); 240552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 240652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 240752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (0 == width) { 240852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com return; 240952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 241052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 241152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com uint32_t flags = paint.getFlags(); 241252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 241352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (flags & (SkPaint::kUnderlineText_Flag | 241452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPaint::kStrikeThruText_Flag)) { 241552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar textSize = paint.getTextSize(); 241652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar height = SkScalarMul(textSize, kStdUnderline_Thickness); 241752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkRect r; 241852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 241952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fLeft = start.fX; 242052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fRight = start.fX + width; 242152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 242252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (flags & SkPaint::kUnderlineText_Flag) { 242352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar offset = SkScalarMulAdd(textSize, kStdUnderline_Offset, 242452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.fY); 242552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fTop = offset; 242652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fBottom = offset + height; 242752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com DrawRect(draw, paint, r, textSize); 242852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 242952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (flags & SkPaint::kStrikeThruText_Flag) { 243052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar offset = SkScalarMulAdd(textSize, kStdStrikeThru_Offset, 243152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.fY); 243252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fTop = offset; 243352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fBottom = offset + height; 243452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com DrawRect(draw, paint, r, textSize); 243552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 243652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 243752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com} 243852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 2439e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 2440e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 244178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL) 24428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 24444e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 2445f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com iter.fDevice->drawText(iter, text, byteLength, x, y, dfp.paint()); 244652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com DrawTextDecorations(iter, dfp.paint(), 244752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com static_cast<const char*>(text), byteLength, x, y); 24488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 24498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24504e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 24518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2453e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], 2454e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 245505c4a4322e7d4f3417b7df33825bab8603d52051fmalita SkPoint textOffset = SkPoint::Make(0, 0); 245605c4a4322e7d4f3417b7df33825bab8603d52051fmalita 245778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL) 245887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 24598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 24604e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 246105c4a4322e7d4f3417b7df33825bab8603d52051fmalita iter.fDevice->drawPosText(iter, text, byteLength, &pos->fX, 2, textOffset, 2462f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com dfp.paint()); 24638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2464b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 24654e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 24668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2468e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], 2469e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com SkScalar constY, const SkPaint& paint) { 247005c4a4322e7d4f3417b7df33825bab8603d52051fmalita 247105c4a4322e7d4f3417b7df33825bab8603d52051fmalita SkPoint textOffset = SkPoint::Make(0, constY); 247205c4a4322e7d4f3417b7df33825bab8603d52051fmalita 247378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL) 247487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 24758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 24764e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 247705c4a4322e7d4f3417b7df33825bab8603d52051fmalita iter.fDevice->drawPosText(iter, text, byteLength, xpos, 1, textOffset, 2478f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com dfp.paint()); 24798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2480b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 24814e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 24828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2484e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 2485e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkMatrix* matrix, const SkPaint& paint) { 248678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL) 248787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 24888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 24898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawTextOnPath(iter, text, byteLength, path, 24904e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com matrix, looper.paint()); 24918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2492b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 2493945ec3a2bec668ca845071a65df8ec55e8f43819commit-bot@chromium.org LOOPER_END 24944325d114a5679e46f25ae75b0e43547fd7694998commit-bot@chromium.org} 24954325d114a5679e46f25ae75b0e43547fd7694998commit-bot@chromium.org 249600d5c2c6523321d25b32905ff4822f083a4173eefmalitavoid SkCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 249700d5c2c6523321d25b32905ff4822f083a4173eefmalita const SkPaint& paint) { 24987ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita 249985d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita SkRect storage; 250085d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita const SkRect* bounds = NULL; 250119653d1d004610b4ba07ce563a5701164e120e45fmalita if (paint.canComputeFastBounds()) { 250285d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita storage = blob->bounds().makeOffset(x, y); 250385d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita bounds = &paint.computeFastBounds(storage, &storage); 25047ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita 250585d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita if (this->quickReject(*bounds)) { 25067ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita return; 25077ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita } 25087ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita } 25097ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita 2510024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita // We cannot filter in the looper as we normally do, because the paint is 2511024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita // incomplete at this point (text-related attributes are embedded within blob run paints). 2512024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita SkDrawFilter* drawFilter = fMCRec->fFilter; 2513024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita fMCRec->fFilter = NULL; 2514024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita 251585d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, bounds) 251600d5c2c6523321d25b32905ff4822f083a4173eefmalita 2517aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita while (iter.next()) { 2518aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 2519024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita iter.fDevice->drawTextBlob(iter, blob, x, y, dfp.paint(), drawFilter); 252000d5c2c6523321d25b32905ff4822f083a4173eefmalita } 252100d5c2c6523321d25b32905ff4822f083a4173eefmalita 2522aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita LOOPER_END 2523024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita 2524024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita fMCRec->fFilter = drawFilter; 252500d5c2c6523321d25b32905ff4822f083a4173eefmalita} 252600d5c2c6523321d25b32905ff4822f083a4173eefmalita 2527e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com// These will become non-virtual, so they always call the (virtual) onDraw... method 2528e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 2529e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 25309881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawText()"); 2531e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawText(text, byteLength, x, y, paint); 2532e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2533e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawPosText(const void* text, size_t byteLength, const SkPoint pos[], 2534e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 25359881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPosText()"); 2536e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawPosText(text, byteLength, pos, paint); 2537e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2538e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], 2539e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com SkScalar constY, const SkPaint& paint) { 25409881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPosTextH()"); 2541e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawPosTextH(text, byteLength, xpos, constY, paint); 2542e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2543e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 2544e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkMatrix* matrix, const SkPaint& paint) { 25459881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextOnPath()"); 2546e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawTextOnPath(text, byteLength, path, matrix, paint); 2547e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 254800d5c2c6523321d25b32905ff4822f083a4173eefmalitavoid SkCanvas::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 254900d5c2c6523321d25b32905ff4822f083a4173eefmalita const SkPaint& paint) { 25509881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextBlob()"); 255149f085dddff10473b6ebf832a974288300224e60bsalomon if (blob) { 255200d5c2c6523321d25b32905ff4822f083a4173eefmalita this->onDrawTextBlob(blob, x, y, paint); 255300d5c2c6523321d25b32905ff4822f083a4173eefmalita } 255400d5c2c6523321d25b32905ff4822f083a4173eefmalita} 2555e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com 255641af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawVertices(VertexMode vmode, int vertexCount, 255741af966ab338e95eee81ab618ab28195075338f7reed const SkPoint verts[], const SkPoint texs[], 255841af966ab338e95eee81ab618ab28195075338f7reed const SkColor colors[], SkXfermode* xmode, 255941af966ab338e95eee81ab618ab28195075338f7reed const uint16_t indices[], int indexCount, 256041af966ab338e95eee81ab618ab28195075338f7reed const SkPaint& paint) { 25619881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawVertices()"); 256278cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, NULL) 25634b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 25648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 25658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawVertices(iter, vmode, vertexCount, verts, texs, 25664e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com colors, xmode, indices, indexCount, 25674e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com looper.paint()); 25688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 25694b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 25704e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 25718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 25728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2573b3c9d1c33caf325aada244204215eb790c228c12dandovvoid SkCanvas::drawPatch(const SkPoint cubics[12], const SkColor colors[4], 2574b3c9d1c33caf325aada244204215eb790c228c12dandov const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint) { 25759881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPatch()"); 2576b3c9d1c33caf325aada244204215eb790c228c12dandov if (NULL == cubics) { 2577b3c9d1c33caf325aada244204215eb790c228c12dandov return; 2578b3c9d1c33caf325aada244204215eb790c228c12dandov } 25796cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2580ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov // Since a patch is always within the convex hull of the control points, we discard it when its 2581ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov // bounding rectangle is completely outside the current clip. 2582ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov SkRect bounds; 2583b3c9d1c33caf325aada244204215eb790c228c12dandov bounds.set(cubics, SkPatchUtils::kNumCtrlPts); 2584ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov if (this->quickReject(bounds)) { 2585ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov return; 2586ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov } 25876cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2588b3c9d1c33caf325aada244204215eb790c228c12dandov this->onDrawPatch(cubics, colors, texCoords, xmode, paint); 2589b3c9d1c33caf325aada244204215eb790c228c12dandov} 2590b3c9d1c33caf325aada244204215eb790c228c12dandov 2591b3c9d1c33caf325aada244204215eb790c228c12dandovvoid SkCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], 2592b3c9d1c33caf325aada244204215eb790c228c12dandov const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint) { 2593b3c9d1c33caf325aada244204215eb790c228c12dandov 2594ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, NULL) 25956cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2596ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov while (iter.next()) { 2597b3c9d1c33caf325aada244204215eb790c228c12dandov iter.fDevice->drawPatch(iter, cubics, colors, texCoords, xmode, paint); 2598ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov } 25996cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2600ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov LOOPER_END 2601ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov} 2602ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov 2603a8db72864a43ad1fbba3c2892cf5cd88060a43efreedvoid SkCanvas::drawDrawable(SkDrawable* dr, SkScalar x, SkScalar y) { 2604a8db72864a43ad1fbba3c2892cf5cd88060a43efreed if (dr) { 2605a8db72864a43ad1fbba3c2892cf5cd88060a43efreed if (x || y) { 2606a8db72864a43ad1fbba3c2892cf5cd88060a43efreed SkMatrix matrix = SkMatrix::MakeTrans(x, y); 2607a8db72864a43ad1fbba3c2892cf5cd88060a43efreed this->onDrawDrawable(dr, &matrix); 2608a8db72864a43ad1fbba3c2892cf5cd88060a43efreed } else { 2609a8db72864a43ad1fbba3c2892cf5cd88060a43efreed this->onDrawDrawable(dr, NULL); 2610a8db72864a43ad1fbba3c2892cf5cd88060a43efreed } 2611a8db72864a43ad1fbba3c2892cf5cd88060a43efreed } 2612a8db72864a43ad1fbba3c2892cf5cd88060a43efreed} 2613a8db72864a43ad1fbba3c2892cf5cd88060a43efreed 2614a8db72864a43ad1fbba3c2892cf5cd88060a43efreedvoid SkCanvas::drawDrawable(SkDrawable* dr, const SkMatrix* matrix) { 2615a8db72864a43ad1fbba3c2892cf5cd88060a43efreed if (dr) { 2616a8db72864a43ad1fbba3c2892cf5cd88060a43efreed if (matrix && matrix->isIdentity()) { 2617a8db72864a43ad1fbba3c2892cf5cd88060a43efreed matrix = NULL; 2618a8db72864a43ad1fbba3c2892cf5cd88060a43efreed } 2619a8db72864a43ad1fbba3c2892cf5cd88060a43efreed this->onDrawDrawable(dr, matrix); 26206a070dc06af4e9f305f9d08a69e34d18ade473cbreed } 26216a070dc06af4e9f305f9d08a69e34d18ade473cbreed} 26226a070dc06af4e9f305f9d08a69e34d18ade473cbreed 2623a8db72864a43ad1fbba3c2892cf5cd88060a43efreedvoid SkCanvas::onDrawDrawable(SkDrawable* dr, const SkMatrix* matrix) { 2624a8db72864a43ad1fbba3c2892cf5cd88060a43efreed SkRect bounds = dr->getBounds(); 2625a8db72864a43ad1fbba3c2892cf5cd88060a43efreed if (matrix) { 2626a8db72864a43ad1fbba3c2892cf5cd88060a43efreed matrix->mapRect(&bounds); 2627a8db72864a43ad1fbba3c2892cf5cd88060a43efreed } 2628a8db72864a43ad1fbba3c2892cf5cd88060a43efreed if (this->quickReject(bounds)) { 2629a8db72864a43ad1fbba3c2892cf5cd88060a43efreed return; 2630a8db72864a43ad1fbba3c2892cf5cd88060a43efreed } 2631a8db72864a43ad1fbba3c2892cf5cd88060a43efreed dr->draw(this, matrix); 26326a070dc06af4e9f305f9d08a69e34d18ade473cbreed} 26336a070dc06af4e9f305f9d08a69e34d18ade473cbreed 263471c3c760a83123ee0b3127b8c65c6394ce541c50reedvoid SkCanvas::onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], 263571c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkColor colors[], int count, SkXfermode::Mode mode, 263671c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkRect* cull, const SkPaint* paint) { 263771c3c760a83123ee0b3127b8c65c6394ce541c50reed if (cull && this->quickReject(*cull)) { 263871c3c760a83123ee0b3127b8c65c6394ce541c50reed return; 263971c3c760a83123ee0b3127b8c65c6394ce541c50reed } 264071c3c760a83123ee0b3127b8c65c6394ce541c50reed 264171c3c760a83123ee0b3127b8c65c6394ce541c50reed SkPaint pnt; 264271c3c760a83123ee0b3127b8c65c6394ce541c50reed if (paint) { 264371c3c760a83123ee0b3127b8c65c6394ce541c50reed pnt = *paint; 264471c3c760a83123ee0b3127b8c65c6394ce541c50reed } 264571c3c760a83123ee0b3127b8c65c6394ce541c50reed 264671c3c760a83123ee0b3127b8c65c6394ce541c50reed LOOPER_BEGIN(pnt, SkDrawFilter::kPath_Type, NULL) 264771c3c760a83123ee0b3127b8c65c6394ce541c50reed while (iter.next()) { 264871c3c760a83123ee0b3127b8c65c6394ce541c50reed iter.fDevice->drawAtlas(iter, atlas, xform, tex, colors, count, mode, pnt); 264971c3c760a83123ee0b3127b8c65c6394ce541c50reed } 265071c3c760a83123ee0b3127b8c65c6394ce541c50reed LOOPER_END 265171c3c760a83123ee0b3127b8c65c6394ce541c50reed} 265271c3c760a83123ee0b3127b8c65c6394ce541c50reed 26538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 26548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// These methods are NOT virtual, and therefore must call back into virtual 26558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// methods, rather than actually drawing themselves. 26568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 26578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 26588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b, 2659845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com SkXfermode::Mode mode) { 26609881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawARGB()"); 26618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 26628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 26638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setARGB(a, r, g, b); 2664845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com if (SkXfermode::kSrcOver_Mode != mode) { 26650baf19375466cfc24c96532df406e7c5b1d1aae8reed@android.com paint.setXfermodeMode(mode); 26668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 26678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPaint(paint); 26688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 26698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2670845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.comvoid SkCanvas::drawColor(SkColor c, SkXfermode::Mode mode) { 26719881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawColor()"); 26728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 26738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 26748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setColor(c); 2675845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com if (SkXfermode::kSrcOver_Mode != mode) { 26760baf19375466cfc24c96532df406e7c5b1d1aae8reed@android.com paint.setXfermodeMode(mode); 26778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 26788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPaint(paint); 26798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 26808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 26818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPoint(SkScalar x, SkScalar y, const SkPaint& paint) { 26829881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPoint(SkPaint)"); 26838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pt; 26844b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 26858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pt.set(x, y); 26868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kPoints_PointMode, 1, &pt, paint); 26878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 26888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 26898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPoint(SkScalar x, SkScalar y, SkColor color) { 26909881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPoint(SkColor)"); 26918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pt; 26928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 26934b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 26948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pt.set(x, y); 26958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setColor(color); 26968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kPoints_PointMode, 1, &pt, paint); 26978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 26988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 26998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, 27008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 27019881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawLine()"); 27028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pts[2]; 27034b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 27048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pts[0].set(x0, y0); 27058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pts[1].set(x1, y1); 27068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kLines_PointMode, 2, pts, paint); 27078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawRectCoords(SkScalar left, SkScalar top, 27108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar right, SkScalar bottom, 27118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 27129881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRectCoords()"); 27138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 27148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.set(left, top, right, bottom); 27168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawRect(r, paint); 27178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, 27208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 27219881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawCircle()"); 27228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (radius < 0) { 27238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com radius = 0; 27248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 27258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 27278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.set(cx - radius, cy - radius, cx + radius, cy + radius); 27284ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->drawOval(r, paint); 27298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawRoundRect(const SkRect& r, SkScalar rx, SkScalar ry, 27328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 27339881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRoundRect()"); 27348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (rx > 0 && ry > 0) { 27358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.canComputeFastBounds()) { 27368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect storage; 27373b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(paint.computeFastBounds(r, &storage))) { 27388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 27398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 27408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 27414ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com SkRRect rrect; 27424ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com rrect.setRectXY(r, rx, ry); 27434ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->drawRRect(rrect, paint); 27448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 27458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawRect(r, paint); 27468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 27478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawArc(const SkRect& oval, SkScalar startAngle, 27508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar sweepAngle, bool useCenter, 27518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 27529881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawArc()"); 27538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (SkScalarAbs(sweepAngle) >= SkIntToScalar(360)) { 27548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawOval(oval, paint); 27558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 27568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath path; 27578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (useCenter) { 27588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.moveTo(oval.centerX(), oval.centerY()); 27598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 27608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.arcTo(oval, startAngle, sweepAngle, !useCenter); 27618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (useCenter) { 27628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.close(); 27638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 27648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPath(path, paint); 27658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 27668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawTextOnPathHV(const void* text, size_t byteLength, 27698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPath& path, SkScalar hOffset, 27708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar vOffset, const SkPaint& paint) { 27719881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextOnPathHV()"); 27728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 27734b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 27748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.setTranslate(hOffset, vOffset); 27758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawTextOnPath(text, byteLength, path, &matrix, paint); 27768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 27778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2778f76bacff7f66724072c67edb185abf9e3add11a0reed@android.com/////////////////////////////////////////////////////////////////////////////// 27791c2c441fede0ae9573afc098017011e3439624a9reed 27801c2c441fede0ae9573afc098017011e3439624a9reed/** 27811c2c441fede0ae9573afc098017011e3439624a9reed * This constant is trying to balance the speed of ref'ing a subpicture into a parent picture, 27821c2c441fede0ae9573afc098017011e3439624a9reed * against the playback cost of recursing into the subpicture to get at its actual ops. 27831c2c441fede0ae9573afc098017011e3439624a9reed * 27841c2c441fede0ae9573afc098017011e3439624a9reed * For now we pick a conservatively small value, though measurement (and other heuristics like 27851c2c441fede0ae9573afc098017011e3439624a9reed * the type of ops contained) may justify changing this value. 27861c2c441fede0ae9573afc098017011e3439624a9reed */ 27871c2c441fede0ae9573afc098017011e3439624a9reed#define kMaxPictureOpsToUnrollInsteadOfRef 1 27889b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips 2789d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedvoid SkCanvas::drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint) { 27901c2c441fede0ae9573afc098017011e3439624a9reed TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPicture()"); 279149f085dddff10473b6ebf832a974288300224e60bsalomon if (picture) { 2792d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed if (matrix && matrix->isIdentity()) { 2793d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed matrix = NULL; 2794d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 27951c2c441fede0ae9573afc098017011e3439624a9reed if (picture->approximateOpCount() <= kMaxPictureOpsToUnrollInsteadOfRef) { 27961c2c441fede0ae9573afc098017011e3439624a9reed SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); 27971c2c441fede0ae9573afc098017011e3439624a9reed picture->playback(this); 27981c2c441fede0ae9573afc098017011e3439624a9reed } else { 27991c2c441fede0ae9573afc098017011e3439624a9reed this->onDrawPicture(picture, matrix, paint); 28001c2c441fede0ae9573afc098017011e3439624a9reed } 2801d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 2802d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 28039b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips 2804d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedvoid SkCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix, 2805d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed const SkPaint* paint) { 2806145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org SkBaseDevice* device = this->getTopDevice(); 280749f085dddff10473b6ebf832a974288300224e60bsalomon if (device) { 2808145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org // Canvas has to first give the device the opportunity to render 2809145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org // the picture itself. 2810d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed if (device->EXPERIMENTAL_drawPicture(this, picture, matrix, paint)) { 2811145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org return; // the device has rendered the entire picture 2812145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org } 2813145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org } 2814145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org 2815a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); 2816c5ba71d2e5cd426def66fa49dcf003e5b2c98dc7robertphillips picture->playback(this); 28178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 28208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 28218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::LayerIter::LayerIter(SkCanvas* canvas, bool skipEmptyClips) { 2823d642329293cce602ac24df8f585c14a98795da87reed@google.com SK_COMPILE_ASSERT(sizeof(fStorage) >= sizeof(SkDrawIter), fStorage_too_small); 28248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(canvas); 28268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fImpl = new (fStorage) SkDrawIter(canvas, skipEmptyClips); 28288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDone = !fImpl->next(); 28298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::LayerIter::~LayerIter() { 28328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fImpl->~SkDrawIter(); 28338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::LayerIter::next() { 28368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDone = !fImpl->next(); 28378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28391f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::LayerIter::device() const { 28408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fImpl->getDevice(); 28418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkMatrix& SkCanvas::LayerIter::matrix() const { 28448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fImpl->getMatrix(); 28458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkPaint& SkCanvas::LayerIter::paint() const { 28488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* paint = fImpl->getPaint(); 28498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == paint) { 28508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint = &fDefaultPaint; 28518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 28528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return *paint; 28538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 28548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkRegion& SkCanvas::LayerIter::clip() const { return fImpl->getClip(); } 28568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::LayerIter::x() const { return fImpl->getX(); } 28578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::LayerIter::y() const { return fImpl->getY(); } 285820a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com 285920a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com/////////////////////////////////////////////////////////////////////////////// 286020a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com 2861c3b589a24eb4d567a906189f882c259ecf5c2f58fmalitaSkCanvasClipVisitor::~SkCanvasClipVisitor() { } 28623107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 28633107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 28643107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 28653107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.orgstatic bool supported_for_raster_canvas(const SkImageInfo& info) { 28663107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org switch (info.alphaType()) { 28673107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kPremul_SkAlphaType: 28683107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kOpaque_SkAlphaType: 28693107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org break; 28703107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org default: 28713107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return false; 28723107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 28733107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 28743107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org switch (info.colorType()) { 28753107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kAlpha_8_SkColorType: 28763107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kRGB_565_SkColorType: 287728fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org case kN32_SkColorType: 28783107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org break; 28793107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org default: 28803107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return false; 28813107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 28823107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 28833107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return true; 28843107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org} 28853107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 288642b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.orgSkCanvas* SkCanvas::NewRasterDirect(const SkImageInfo& info, void* pixels, size_t rowBytes) { 288742b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org if (!supported_for_raster_canvas(info)) { 288842b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org return NULL; 288942b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org } 2890eb849e5fd10cbe00cbc31307ba97fd9efca0b41bskia.committer@gmail.com 289142b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org SkBitmap bitmap; 289242b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org if (!bitmap.installPixels(info, pixels, rowBytes)) { 289342b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org return NULL; 289442b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org } 289542b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org return SkNEW_ARGS(SkCanvas, (bitmap)); 289642b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org} 2897d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 2898d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed/////////////////////////////////////////////////////////////////////////////// 2899d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 2900d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedSkAutoCanvasMatrixPaint::SkAutoCanvasMatrixPaint(SkCanvas* canvas, const SkMatrix* matrix, 2901a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips const SkPaint* paint, const SkRect& bounds) 2902d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed : fCanvas(canvas) 2903d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed , fSaveCount(canvas->getSaveCount()) 2904d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed{ 290549f085dddff10473b6ebf832a974288300224e60bsalomon if (paint) { 2906a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkRect newBounds = bounds; 2907d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed if (matrix) { 2908a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips matrix->mapRect(&newBounds); 2909d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 2910a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips canvas->saveLayer(&newBounds, paint); 291149f085dddff10473b6ebf832a974288300224e60bsalomon } else if (matrix) { 2912d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed canvas->save(); 2913d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 29146cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 291549f085dddff10473b6ebf832a974288300224e60bsalomon if (matrix) { 2916d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed canvas->concat(*matrix); 2917d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 2918d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 2919d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 2920d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedSkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { 2921d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed fCanvas->restoreToCount(fSaveCount); 2922d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 2923