SkCanvas.cpp revision 71c3c760a83123ee0b3127b8c65c6394ce541c50
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 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h" 9d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed#include "SkCanvasPriv.h" 101f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com#include "SkBitmapDevice.h" 11dbc3cefb0b624808ddb86d444e6103f216e12fa5reed#include "SkColorFilter.h" 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDraw.h" 133cb3840c9af6f70896cf5565a38d4ee03c02d767reed#include "SkDrawable.h" 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDrawFilter.h" 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDrawLooper.h" 165f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt#include "SkErrorInternals.h" 17b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr#include "SkImage.h" 1874bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org#include "SkMetaData.h" 1945a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com#include "SkPathOps.h" 20b3c9d1c33caf325aada244204215eb790c228c12dandov#include "SkPatchUtils.h" 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPicture.h" 220017708a5bcb6d0fbff0fac565085bef65de7433reed@google.com#include "SkRasterClip.h" 2396472deea70169396b8e1f576e470138f55fdb1freed#include "SkReadPixelsRec.h" 244ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com#include "SkRRect.h" 2579fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org#include "SkSmallAllocator.h" 2697af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com#include "SkSurface_Base.h" 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTemplates.h" 287ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita#include "SkTextBlob.h" 2952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com#include "SkTextFormatParams.h" 30a076e9be17654a60310e72c4f70fcd5337f56dbfreed@google.com#include "SkTLazy.h" 318f757f540a8378c7b1354aab3d4650eaa920b17adanakj#include "SkTraceEvent.h" 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkUtils.h" 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 34644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#if SK_SUPPORT_GPU 35644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#include "GrRenderTarget.h" 36644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#endif 37644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org 38d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareedstatic bool gIgnoreSaveLayerBounds; 39d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareedvoid SkCanvas::Internal_Private_SetIgnoreSaveLayerBounds(bool ignore) { 40d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed gIgnoreSaveLayerBounds = ignore; 41d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed} 42d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareedbool SkCanvas::Internal_Private_GetIgnoreSaveLayerBounds() { 43d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed return gIgnoreSaveLayerBounds; 44d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed} 45d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed 460acf1b4b3645772d220c720313821bac389751b5reedstatic bool gTreatSpriteAsBitmap; 470acf1b4b3645772d220c720313821bac389751b5reedvoid SkCanvas::Internal_Private_SetTreatSpriteAsBitmap(bool spriteAsBitmap) { 480acf1b4b3645772d220c720313821bac389751b5reed gTreatSpriteAsBitmap = spriteAsBitmap; 490acf1b4b3645772d220c720313821bac389751b5reed} 500acf1b4b3645772d220c720313821bac389751b5reedbool SkCanvas::Internal_Private_GetTreatSpriteAsBitmap() { 510acf1b4b3645772d220c720313821bac389751b5reed return gTreatSpriteAsBitmap; 520acf1b4b3645772d220c720313821bac389751b5reed} 530acf1b4b3645772d220c720313821bac389751b5reed 54da17f758442f16747af39f8fbaed9c097048519creed@google.com// experimental for faster tiled drawing... 55da17f758442f16747af39f8fbaed9c097048519creed@google.com//#define SK_ENABLE_CLIP_QUICKREJECT 5615e9d3e66e161ce23df30bc13f8a0c87d196b463robertphillips@google.com 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//#define SK_TRACE_SAVERESTORE 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_TRACE_SAVERESTORE 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gLayerCounter; 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_layer() { ++gLayerCounter; printf("----- inc layer %d\n", gLayerCounter); } 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_layer() { --gLayerCounter; printf("----- dec layer %d\n", gLayerCounter); } 638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gRecCounter; 658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_rec() { ++gRecCounter; printf("----- inc rec %d\n", gRecCounter); } 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_rec() { --gRecCounter; printf("----- dec rec %d\n", gRecCounter); } 678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gCanvasCounter; 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_canvas() { ++gCanvasCounter; printf("----- inc canvas %d\n", gCanvasCounter); } 708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_canvas() { --gCanvasCounter; printf("----- dec canvas %d\n", gCanvasCounter); } 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_layer() 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_layer() 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_rec() 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_rec() 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_canvas() 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_canvas() 788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 802c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.orgtypedef SkTLazy<SkPaint> SkLazyPaint; 812c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org 8297af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.comvoid SkCanvas::predrawNotify() { 8397af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com if (fSurfaceBase) { 84c4c9870953037be94da00ac9db887d171f6e479ccommit-bot@chromium.org fSurfaceBase->aboutToDraw(SkSurface::kRetain_ContentChangeMode); 8597af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com } 8697af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com} 8797af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 904a8126e7f81384526629b1e21bf89b632ea13cd9reedstatic uint32_t filter_paint_flags(const SkSurfaceProps& props, uint32_t flags) { 914a8126e7f81384526629b1e21bf89b632ea13cd9reed const uint32_t propFlags = props.flags(); 924a8126e7f81384526629b1e21bf89b632ea13cd9reed if (propFlags & SkSurfaceProps::kDisallowDither_Flag) { 934a8126e7f81384526629b1e21bf89b632ea13cd9reed flags &= ~SkPaint::kDither_Flag; 944a8126e7f81384526629b1e21bf89b632ea13cd9reed } 954a8126e7f81384526629b1e21bf89b632ea13cd9reed if (propFlags & SkSurfaceProps::kDisallowAntiAlias_Flag) { 964a8126e7f81384526629b1e21bf89b632ea13cd9reed flags &= ~SkPaint::kAntiAlias_Flag; 974a8126e7f81384526629b1e21bf89b632ea13cd9reed } 984a8126e7f81384526629b1e21bf89b632ea13cd9reed return flags; 994a8126e7f81384526629b1e21bf89b632ea13cd9reed} 1004a8126e7f81384526629b1e21bf89b632ea13cd9reed 1014a8126e7f81384526629b1e21bf89b632ea13cd9reed/////////////////////////////////////////////////////////////////////////////// 1024a8126e7f81384526629b1e21bf89b632ea13cd9reed 1031f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com/* This is the record we keep for each SkBaseDevice that the user installs. 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com The clip/matrix/proc are fields that reflect the top of the save/restore 1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stack. Whenever the canvas changes, it marks a dirty flag, and then before 1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com these are used (assuming we're not on a layer) we rebuild these cache 1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com values: they reflect the top of the save stack, but translated and clipped 1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com by the device's XY offset and bitmap-bounds. 1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct DeviceCM { 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* fNext; 1121f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* fDevice; 113045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com SkRasterClip fClip; 1146f8f292aa768869a9e85c314b124875f57504f2creed@google.com SkPaint* fPaint; // may be null (in the future) 11561f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed const SkMatrix* fMatrix; 11661f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed SkMatrix fMatrixStorage; 11761f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed const bool fDeviceIsBitmapDevice; 1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11996e657d0e103b8358a77ecd913f6086929f792b8reed DeviceCM(SkBaseDevice* device, const SkPaint* paint, SkCanvas* canvas, 12086a17e7716c8db858e219a46b9db3817bb770beereed bool conservativeRasterClip, bool deviceIsBitmapDevice) 121d954498c01ccf0417feacf89e45d0c62a06a813breed : fNext(NULL) 122d954498c01ccf0417feacf89e45d0c62a06a813breed , fClip(conservativeRasterClip) 12361f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed , fDeviceIsBitmapDevice(deviceIsBitmapDevice) 124d954498c01ccf0417feacf89e45d0c62a06a813breed { 125d954498c01ccf0417feacf89e45d0c62a06a813breed if (NULL != device) { 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device->ref(); 12740a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com device->onAttachToCanvas(canvas); 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1294b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com fDevice = device; 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint = paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL; 13188edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13388edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com ~DeviceCM() { 13449f085dddff10473b6ebf832a974288300224e60bsalomon if (fDevice) { 13540a1ae4df28810aa5aa5cf2627d8387b2dfb867arobertphillips@google.com fDevice->onDetachFromCanvas(); 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDevice->unref(); 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13888edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com SkDELETE(fPaint); 13988edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 1404b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 141feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein void reset(const SkIRect& bounds) { 142feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(!fPaint); 143feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(!fNext); 144feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(fDevice); 145feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fClip.setRect(bounds); 146feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein } 147feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 148045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com void updateMC(const SkMatrix& totalMatrix, const SkRasterClip& totalClip, 149045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com const SkClipStack& clipStack, SkRasterClip* updateClip) { 1506f8f292aa768869a9e85c314b124875f57504f2creed@google.com int x = fDevice->getOrigin().x(); 1516f8f292aa768869a9e85c314b124875f57504f2creed@google.com int y = fDevice->getOrigin().y(); 1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int width = fDevice->width(); 1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int height = fDevice->height(); 1544b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if ((x | y) == 0) { 1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = &totalMatrix; 1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fClip = totalClip; 1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrixStorage = totalMatrix; 1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrixStorage.postTranslate(SkIntToScalar(-x), 1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIntToScalar(-y)); 1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = &fMatrixStorage; 1634b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com totalClip.translate(-x, -y, &fClip); 1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 167045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com fClip.op(SkIRect::MakeWH(width, height), SkRegion::kIntersect_Op); 1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // intersect clip, but don't translate it (yet) 1704b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (updateClip) { 172045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com updateClip->op(SkIRect::MakeXYWH(x, y, width, height), 1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRegion::kDifference_Op); 1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1754b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 1763fffb2ee9fa01ae61efb2395973eb7575eda4c96robertphillips@google.com fDevice->setMatrixClip(*fMatrix, fClip.forceGetBW(), clipStack); 1773fffb2ee9fa01ae61efb2395973eb7575eda4c96robertphillips@google.com 1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!fClip.isEmpty()) { 1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIRect deviceR; 1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com deviceR.set(0, 0, width, height); 1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(deviceR.contains(fClip.getBounds())); 1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 185f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* This is the record we keep for each save/restore level in the stack. 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Since a level optionally copies the matrix and/or stack, we have pointers 1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for these fields. If the value is copied for this level, the copy is 1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stored in the ...Storage field, and the pointer points to that. If the 1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value is not copied for this level, we ignore ...Storage, and just point 1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com at the corresponding value in the previous level in the stack. 1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkCanvas::MCRec { 1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 1971f836ee096bb988adef4b9757b2629c7afeda36dreed SkDrawFilter* fFilter; // the current filter (or null) 198d954498c01ccf0417feacf89e45d0c62a06a813breed DeviceCM* fLayer; 1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* If there are any layers in the stack, this points to the top-most 2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com one that is at or below this level in the stack (so we know what 2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bitmap/device to draw into from this level. This value is NOT 2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com reference counted, since the real owner is either our fLayer field, 2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com or a previous one in a lower level.) 2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 2052ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed DeviceCM* fTopLayer; 2062ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkRasterClip fRasterClip; 2072ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkMatrix fMatrix; 2082ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed int fDeferredSaveCount; 2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 210d954498c01ccf0417feacf89e45d0c62a06a813breed MCRec(bool conservativeRasterClip) : fRasterClip(conservativeRasterClip) { 211d954498c01ccf0417feacf89e45d0c62a06a813breed fFilter = NULL; 212d954498c01ccf0417feacf89e45d0c62a06a813breed fLayer = NULL; 213d954498c01ccf0417feacf89e45d0c62a06a813breed fTopLayer = NULL; 2142ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fMatrix.reset(); 2152ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fDeferredSaveCount = 0; 216b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 217d954498c01ccf0417feacf89e45d0c62a06a813breed // don't bother initializing fNext 218d954498c01ccf0417feacf89e45d0c62a06a813breed inc_rec(); 219d954498c01ccf0417feacf89e45d0c62a06a813breed } 2202ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed MCRec(const MCRec& prev) : fRasterClip(prev.fRasterClip), fMatrix(prev.fMatrix) { 221d954498c01ccf0417feacf89e45d0c62a06a813breed fFilter = SkSafeRef(prev.fFilter); 2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLayer = NULL; 223d954498c01ccf0417feacf89e45d0c62a06a813breed fTopLayer = prev.fTopLayer; 2242ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fDeferredSaveCount = 0; 225b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 2268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // don't bother initializing fNext 2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inc_rec(); 2288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ~MCRec() { 23082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fFilter); 2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDELETE(fLayer); 2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dec_rec(); 2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 234feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 235feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein void reset(const SkIRect& bounds) { 236feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(fLayer); 237feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein SkASSERT(fDeferredSaveCount == 0); 238feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 239feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fMatrix.reset(); 240feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fRasterClip.setRect(bounds); 241feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fLayer->reset(bounds); 242feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein } 2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkDrawIter : public SkDraw { 2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 2478a0b0291ae4260ef2a46f4341c18a702c0ce3f8btomhudson@google.com SkDrawIter(SkCanvas* canvas, bool skipEmptyClips = true) { 2484370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com canvas = canvas->canvasForDrawIter(); 2498a0b0291ae4260ef2a46f4341c18a702c0ce3f8btomhudson@google.com fCanvas = canvas; 2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com canvas->updateDeviceCMCache(); 2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 252687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack = canvas->fClipStack; 2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = canvas->fMCRec->fTopLayer; 2548a0b0291ae4260ef2a46f4341c18a702c0ce3f8btomhudson@google.com fSkipEmptyClips = skipEmptyClips; 2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2564b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool next() { 2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // skip over recs with empty clips 2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fSkipEmptyClips) { 2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (fCurrLayer && fCurrLayer->fClip.isEmpty()) { 2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = fCurrLayer->fNext; 2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 265f68c5e2f9f05b3af2bae0979ace2684b6041b6e3reed@google.com const DeviceCM* rec = fCurrLayer; 266f68c5e2f9f05b3af2bae0979ace2684b6041b6e3reed@google.com if (rec && rec->fDevice) { 2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = rec->fMatrix; 269045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com fClip = &((SkRasterClip*)&rec->fClip)->forceGetBW(); 270045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com fRC = &rec->fClip; 2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDevice = rec->fDevice; 27241e010cb901c0da9066c4df562030808c9ccd7f8reed if (!fDevice->accessPixels(&fDst)) { 27341e010cb901c0da9066c4df562030808c9ccd7f8reed fDst.reset(fDevice->imageInfo(), NULL, 0); 27441e010cb901c0da9066c4df562030808c9ccd7f8reed } 2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint = rec->fPaint; 276f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com SkDEBUGCODE(this->validate();) 2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = rec->fNext; 2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // fCurrLayer may be NULL now 280199f108f14a5f60a9c2205ffa79b26102a206ad0reed@android.com 2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 2848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2854b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 2861f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* getDevice() const { return fDevice; } 2876f8f292aa768869a9e85c314b124875f57504f2creed@google.com int getX() const { return fDevice->getOrigin().x(); } 2886f8f292aa768869a9e85c314b124875f57504f2creed@google.com int getY() const { return fDevice->getOrigin().y(); } 2898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& getMatrix() const { return *fMatrix; } 2908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkRegion& getClip() const { return *fClip; } 2918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* getPaint() const { return fPaint; } 2926f8f292aa768869a9e85c314b124875f57504f2creed@google.com 2938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 2948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkCanvas* fCanvas; 2958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const DeviceCM* fCurrLayer; 2968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* fPaint; // May be null. 2978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkBool8 fSkipEmptyClips; 2988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef SkDraw INHERITED; 3008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////// 3038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 304dbc3cefb0b624808ddb86d444e6103f216e12fa5reedstatic SkPaint* set_if_needed(SkLazyPaint* lazy, const SkPaint& orig) { 305dbc3cefb0b624808ddb86d444e6103f216e12fa5reed return lazy->isValid() ? lazy->get() : lazy->set(orig); 306dbc3cefb0b624808ddb86d444e6103f216e12fa5reed} 307dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 308dbc3cefb0b624808ddb86d444e6103f216e12fa5reed/** 309dbc3cefb0b624808ddb86d444e6103f216e12fa5reed * If the paint has an imagefilter, but it can be simplified to just a colorfilter, return that 310dbc3cefb0b624808ddb86d444e6103f216e12fa5reed * colorfilter, else return NULL. 311dbc3cefb0b624808ddb86d444e6103f216e12fa5reed */ 312dbc3cefb0b624808ddb86d444e6103f216e12fa5reedstatic SkColorFilter* image_to_color_filter(const SkPaint& paint) { 313dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkImageFilter* imgf = paint.getImageFilter(); 314dbc3cefb0b624808ddb86d444e6103f216e12fa5reed if (!imgf) { 315dbc3cefb0b624808ddb86d444e6103f216e12fa5reed return NULL; 316dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 317dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 318dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkColorFilter* imgCF; 319dbc3cefb0b624808ddb86d444e6103f216e12fa5reed if (!imgf->asAColorFilter(&imgCF)) { 320dbc3cefb0b624808ddb86d444e6103f216e12fa5reed return NULL; 321dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 322dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 323dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkColorFilter* paintCF = paint.getColorFilter(); 324dbc3cefb0b624808ddb86d444e6103f216e12fa5reed if (NULL == paintCF) { 325dbc3cefb0b624808ddb86d444e6103f216e12fa5reed // there is no existing paint colorfilter, so we can just return the imagefilter's 326dbc3cefb0b624808ddb86d444e6103f216e12fa5reed return imgCF; 327dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 328dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 329dbc3cefb0b624808ddb86d444e6103f216e12fa5reed // The paint has both a colorfilter(paintCF) and an imagefilter-which-is-a-colorfilter(imgCF) 330dbc3cefb0b624808ddb86d444e6103f216e12fa5reed // and we need to combine them into a single colorfilter. 331dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkAutoTUnref<SkColorFilter> autoImgCF(imgCF); 332dbc3cefb0b624808ddb86d444e6103f216e12fa5reed return SkColorFilter::CreateComposeFilter(imgCF, paintCF); 333dbc3cefb0b624808ddb86d444e6103f216e12fa5reed} 334dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 3358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass AutoDrawLooper { 3368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 3374a8126e7f81384526629b1e21bf89b632ea13cd9reed AutoDrawLooper(SkCanvas* canvas, const SkSurfaceProps& props, const SkPaint& paint, 33878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bool skipLayerForImageFilter = false, 33978cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL) : fOrigPaint(paint) { 3404e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fCanvas = canvas; 3418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFilter = canvas->getDrawFilter(); 3424a8126e7f81384526629b1e21bf89b632ea13cd9reed fPaint = &fOrigPaint; 3434e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fSaveCount = canvas->getSaveCount(); 3445c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed fTempLayerForImageFilter = false; 3454e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fDone = false; 3468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 347dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkColorFilter* simplifiedCF = image_to_color_filter(fOrigPaint); 348dbc3cefb0b624808ddb86d444e6103f216e12fa5reed if (simplifiedCF) { 349dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkPaint* paint = set_if_needed(&fLazyPaintInit, fOrigPaint); 350dbc3cefb0b624808ddb86d444e6103f216e12fa5reed paint->setColorFilter(simplifiedCF)->unref(); 351dbc3cefb0b624808ddb86d444e6103f216e12fa5reed paint->setImageFilter(NULL); 352dbc3cefb0b624808ddb86d444e6103f216e12fa5reed fPaint = paint; 353dbc3cefb0b624808ddb86d444e6103f216e12fa5reed } 354dbc3cefb0b624808ddb86d444e6103f216e12fa5reed 355dbc3cefb0b624808ddb86d444e6103f216e12fa5reed if (!skipLayerForImageFilter && fPaint->getImageFilter()) { 3565c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed /** 3575c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * We implement ImageFilters for a given draw by creating a layer, then applying the 3585c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * imagefilter to the pixels of that layer (its backing surface/image), and then 3595c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * we call restore() to xfer that layer to the main canvas. 3605c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 3615c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 1. SaveLayer (with a paint containing the current imagefilter and xfermode) 3625c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 2. Generate the src pixels: 3635c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * Remove the imagefilter and the xfermode from the paint that we (AutoDrawLooper) 3645c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * return (fPaint). We then draw the primitive (using srcover) into a cleared 3655c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * buffer/surface. 3665c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * 3. Restore the layer created in #1 3675c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * The imagefilter is passed the buffer/surface from the layer (now filled with the 3685c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * src pixels of the primitive). It returns a new "filtered" buffer, which we 3695c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed * draw onto the previous layer using the xfermode from the original paint. 3705c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed */ 3718926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkPaint tmp; 372dbc3cefb0b624808ddb86d444e6103f216e12fa5reed tmp.setImageFilter(fPaint->getImageFilter()); 373dbc3cefb0b624808ddb86d444e6103f216e12fa5reed tmp.setXfermode(fPaint->getXfermode()); 374e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org (void)canvas->internalSaveLayer(bounds, &tmp, SkCanvas::kARGB_ClipLayer_SaveFlag, 37576033be81b82c44fd5d4fdf2672eb22e505da1f0reed SkCanvas::kFullLayer_SaveLayerStrategy); 3765c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed fTempLayerForImageFilter = true; 3775c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed // we remove the imagefilter/xfermode inside doNext() 3788926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 3798926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 38079fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (SkDrawLooper* looper = paint.getLooper()) { 38179fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org void* buffer = fLooperContextAllocator.reserveT<SkDrawLooper::Context>( 38279fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org looper->contextSize()); 38379fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org fLooperContext = looper->createContext(canvas, buffer); 384129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fIsSimple = false; 385129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else { 38679fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org fLooperContext = NULL; 387129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // can we be marked as simple? 3885c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed fIsSimple = !fFilter && !fTempLayerForImageFilter; 3898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 390b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 3914a8126e7f81384526629b1e21bf89b632ea13cd9reed uint32_t oldFlags = paint.getFlags(); 3924a8126e7f81384526629b1e21bf89b632ea13cd9reed fNewPaintFlags = filter_paint_flags(props, oldFlags); 3934a8126e7f81384526629b1e21bf89b632ea13cd9reed if (fIsSimple && (fNewPaintFlags != oldFlags)) { 394dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkPaint* paint = set_if_needed(&fLazyPaintInit, fOrigPaint); 3954a8126e7f81384526629b1e21bf89b632ea13cd9reed paint->setFlags(fNewPaintFlags); 3964a8126e7f81384526629b1e21bf89b632ea13cd9reed fPaint = paint; 3974a8126e7f81384526629b1e21bf89b632ea13cd9reed // if we're not simple, doNext() will take care of calling setFlags() 3984a8126e7f81384526629b1e21bf89b632ea13cd9reed } 3998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 40074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 4014e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com ~AutoDrawLooper() { 4025c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed if (fTempLayerForImageFilter) { 4038926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com fCanvas->internalRestore(); 4048926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 4054e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkASSERT(fCanvas->getSaveCount() == fSaveCount); 4068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 40774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 4084e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com const SkPaint& paint() const { 4094e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkASSERT(fPaint); 4104e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return *fPaint; 4114e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 41274b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 413129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool next(SkDrawFilter::Type drawType) { 414129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com if (fDone) { 415129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return false; 416129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else if (fIsSimple) { 417129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fDone = true; 418129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return !fPaint->nothingToDraw(); 419129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } else { 420129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return this->doNext(drawType); 421129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 422fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 42374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 4248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 425dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkLazyPaint fLazyPaintInit; // base paint storage in case we need to modify it 426dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkLazyPaint fLazyPaintPerLooper; // per-draw-looper storage, so the looper can modify it 4272c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkCanvas* fCanvas; 4282c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint& fOrigPaint; 4292c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkDrawFilter* fFilter; 4302c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint* fPaint; 4312c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org int fSaveCount; 4324a8126e7f81384526629b1e21bf89b632ea13cd9reed uint32_t fNewPaintFlags; 4335c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed bool fTempLayerForImageFilter; 4342c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org bool fDone; 435129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool fIsSimple; 43679fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkDrawLooper::Context* fLooperContext; 43779fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org SkSmallAllocator<1, 32> fLooperContextAllocator; 438129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com 439129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com bool doNext(SkDrawFilter::Type drawType); 4408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 4418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 442129ec22cb054592261e001294c430c9dd4e90ff4reed@google.combool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) { 443632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com fPaint = NULL; 444129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com SkASSERT(!fIsSimple); 4455c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed SkASSERT(fLooperContext || fFilter || fTempLayerForImageFilter); 446632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com 447dbc3cefb0b624808ddb86d444e6103f216e12fa5reed SkPaint* paint = fLazyPaintPerLooper.set(fLazyPaintInit.isValid() ? 448dbc3cefb0b624808ddb86d444e6103f216e12fa5reed *fLazyPaintInit.get() : fOrigPaint); 4494a8126e7f81384526629b1e21bf89b632ea13cd9reed paint->setFlags(fNewPaintFlags); 4508926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 4515c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed if (fTempLayerForImageFilter) { 452129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com paint->setImageFilter(NULL); 4535c476fb2776639bdbf0e974dd38d1c5d4c4ff1aareed paint->setXfermode(NULL); 454129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 4558926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 45679fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (fLooperContext && !fLooperContext->next(fCanvas, paint)) { 457129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fDone = true; 458129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com return false; 459129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 460129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com if (fFilter) { 461971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com if (!fFilter->filter(paint, drawType)) { 462971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com fDone = true; 463971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com return false; 464971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com } 46579fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (NULL == fLooperContext) { 466129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // no looper means we only draw once 467632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com fDone = true; 468632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com } 469129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com } 470129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com fPaint = paint; 4718926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 472129ec22cb054592261e001294c430c9dd4e90ff4reed@google.com // if we only came in here for the imagefilter, mark us as done 47379fbb40bca9d815ef79b896b31ba6ee736817e0fcommit-bot@chromium.org if (!fLooperContext && !fFilter) { 4744e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fDone = true; 4754e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 4764e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com 477632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com // call this after any possible paint modifiers 478632e1a281bc66fb545dce690dff27b51cef41a8ereed@google.com if (fPaint->nothingToDraw()) { 4794e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com fPaint = NULL; 4804e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return false; 4814e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com } 4824e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com return true; 4834e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com} 4844e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com 4858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////// macros to place around the internal draw calls ////////////////// 4868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4878926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com#define LOOPER_BEGIN_DRAWDEVICE(paint, type) \ 48897af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com this->predrawNotify(); \ 4894a8126e7f81384526629b1e21bf89b632ea13cd9reed AutoDrawLooper looper(this, fProps, paint, true); \ 4908926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com while (looper.next(type)) { \ 4918926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkDrawIter iter(this); 4928926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 49378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org#define LOOPER_BEGIN(paint, type, bounds) \ 49497af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com this->predrawNotify(); \ 4954a8126e7f81384526629b1e21bf89b632ea13cd9reed AutoDrawLooper looper(this, fProps, paint, false, bounds); \ 4964e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com while (looper.next(type)) { \ 4978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDrawIter iter(this); 4984b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 4994e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com#define LOOPER_END } 5008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////// 5028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 503feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtkleinvoid SkCanvas::resetForNextPicture(const SkIRect& bounds) { 504feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein this->restoreToCount(1); 505feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fCachedLocalClipBounds.setEmpty(); 506feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fCachedLocalClipBoundsDirty = true; 507feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fClipStack->reset(); 508feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein fMCRec->reset(bounds); 509feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 510feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein // We're peering through a lot of structs here. Only at this scope do we 511feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein // know that the device is an SkBitmapDevice (really an SkNoPixelsBitmapDevice). 512feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein static_cast<SkBitmapDevice*>(fMCRec->fLayer->fDevice)->setNewSize(bounds.size()); 513feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein} 514feaadee1c38e1d4e1ec0069a3509ef6fbc5fbeffmtklein 515d954498c01ccf0417feacf89e45d0c62a06a813breedSkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) { 516d954498c01ccf0417feacf89e45d0c62a06a813breed fConservativeRasterClip = SkToBool(flags & kConservativeRasterClip_InitFlag); 517c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBounds.setEmpty(); 518c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 5198f0a7b8e7334187a5d7d5ab7fde5a3c3009555f5caryclark@google.com fAllowSoftClip = true; 52045a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com fAllowSimplifyClip = false; 521f92c86642a1875da54d54b447f006cb9dfbbb35creed fDeviceCMDirty = true; 5222ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount = 1; 52374bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org fMetaData = NULL; 5248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 525687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack.reset(SkNEW(SkClipStack)); 526687fa1c745febb57f42b0d5f03d7c1f4be2530careed 5278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = (MCRec*)fMCStack.push_back(); 528d954498c01ccf0417feacf89e45d0c62a06a813breed new (fMCRec) MCRec(fConservativeRasterClip); 5298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 530a499f905e9340e4935447f2562fd92e8853382b1reed SkASSERT(sizeof(DeviceCM) <= sizeof(fDeviceCMStorage)); 531a499f905e9340e4935447f2562fd92e8853382b1reed fMCRec->fLayer = (DeviceCM*)fDeviceCMStorage; 53286a17e7716c8db858e219a46b9db3817bb770beereed new (fDeviceCMStorage) DeviceCM(NULL, NULL, NULL, fConservativeRasterClip, false); 533b679ca8926a832274b14fdb512f88f64b61d32eareed 5348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fTopLayer = fMCRec->fLayer; 5358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 53697af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com fSurfaceBase = NULL; 537f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 538f92c86642a1875da54d54b447f006cb9dfbbb35creed if (device) { 539efbffedd68636e94d4379e84a2585bce80f6fb8frobertphillips // The root device and the canvas should always have the same pixel geometry 540efbffedd68636e94d4379e84a2585bce80f6fb8frobertphillips SkASSERT(fProps.pixelGeometry() == device->surfaceProps().pixelGeometry()); 5414a8126e7f81384526629b1e21bf89b632ea13cd9reed if (device->forceConservativeRasterClip()) { 5424a8126e7f81384526629b1e21bf89b632ea13cd9reed fConservativeRasterClip = true; 5434a8126e7f81384526629b1e21bf89b632ea13cd9reed } 544f92c86642a1875da54d54b447f006cb9dfbbb35creed device->onAttachToCanvas(this); 545f92c86642a1875da54d54b447f006cb9dfbbb35creed fMCRec->fLayer->fDevice = SkRef(device); 54678e276889795454891cbba48ab11927968114953reed fMCRec->fRasterClip.setRect(device->getGlobalBounds()); 547f92c86642a1875da54d54b447f006cb9dfbbb35creed } 548f92c86642a1875da54d54b447f006cb9dfbbb35creed return device; 5498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 551cde92111d50a96b6d0f3e166fbac7c9bc6eca349reed@google.comSkCanvas::SkCanvas() 552e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 5534a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 554e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org{ 5558d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org inc_canvas(); 556ba124485687130183643994f1b4b68d629fbbebaskia.committer@gmail.com 557d954498c01ccf0417feacf89e45d0c62a06a813breed this->init(NULL, kDefault_InitFlags); 5588d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org} 5598d84fac294682647694b0d2d8a87ac2bd19b6aabvandebo@chromium.org 560d954498c01ccf0417feacf89e45d0c62a06a813breedstatic SkBitmap make_nopixels(int width, int height) { 561d954498c01ccf0417feacf89e45d0c62a06a813breed SkBitmap bitmap; 562d954498c01ccf0417feacf89e45d0c62a06a813breed bitmap.setInfo(SkImageInfo::MakeUnknown(width, height)); 563d954498c01ccf0417feacf89e45d0c62a06a813breed return bitmap; 564d954498c01ccf0417feacf89e45d0c62a06a813breed} 565d954498c01ccf0417feacf89e45d0c62a06a813breed 566d954498c01ccf0417feacf89e45d0c62a06a813breedclass SkNoPixelsBitmapDevice : public SkBitmapDevice { 567d954498c01ccf0417feacf89e45d0c62a06a813breedpublic: 568fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips SkNoPixelsBitmapDevice(const SkIRect& bounds, const SkSurfaceProps& surfaceProps) 569fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips : INHERITED(make_nopixels(bounds.width(), bounds.height()), surfaceProps) 57078e276889795454891cbba48ab11927968114953reed { 57178e276889795454891cbba48ab11927968114953reed this->setOrigin(bounds.x(), bounds.y()); 57278e276889795454891cbba48ab11927968114953reed } 573d954498c01ccf0417feacf89e45d0c62a06a813breed 574d954498c01ccf0417feacf89e45d0c62a06a813breedprivate: 575b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 576d954498c01ccf0417feacf89e45d0c62a06a813breed typedef SkBitmapDevice INHERITED; 577d954498c01ccf0417feacf89e45d0c62a06a813breed}; 578d954498c01ccf0417feacf89e45d0c62a06a813breed 57996a857ef5a40b3d0751ec9ebaaa96d9f20b82b21reedSkCanvas::SkCanvas(int width, int height, const SkSurfaceProps* props) 580e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 58196a857ef5a40b3d0751ec9ebaaa96d9f20b82b21reed , fProps(SkSurfacePropsCopyOrDefault(props)) 582e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org{ 583e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org inc_canvas(); 584b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 58578e276889795454891cbba48ab11927968114953reed this->init(SkNEW_ARGS(SkNoPixelsBitmapDevice, 586fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips (SkIRect::MakeWH(width, height), fProps)), kDefault_InitFlags)->unref(); 587d954498c01ccf0417feacf89e45d0c62a06a813breed} 588e254310a55d55a710309714c48f7fbbe7a6126f7commit-bot@chromium.org 58978e276889795454891cbba48ab11927968114953reedSkCanvas::SkCanvas(const SkIRect& bounds, InitFlags flags) 590d954498c01ccf0417feacf89e45d0c62a06a813breed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 5914a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 592d954498c01ccf0417feacf89e45d0c62a06a813breed{ 593d954498c01ccf0417feacf89e45d0c62a06a813breed inc_canvas(); 594b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 595fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips this->init(SkNEW_ARGS(SkNoPixelsBitmapDevice, (bounds, fProps)), flags)->unref(); 59627a5e656c3d6ef22f9cb34de18e1b960da3aa241reed} 5978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 598d954498c01ccf0417feacf89e45d0c62a06a813breedSkCanvas::SkCanvas(SkBaseDevice* device) 599d954498c01ccf0417feacf89e45d0c62a06a813breed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 6007b05ff11ebc51f3f3abd1c1756337a04f563537erobertphillips , fProps(device->surfaceProps()) 601d954498c01ccf0417feacf89e45d0c62a06a813breed{ 602d954498c01ccf0417feacf89e45d0c62a06a813breed inc_canvas(); 603b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 604d954498c01ccf0417feacf89e45d0c62a06a813breed this->init(device, kDefault_InitFlags); 6058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 607fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillipsSkCanvas::SkCanvas(SkBaseDevice* device, InitFlags flags) 608fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 6097b05ff11ebc51f3f3abd1c1756337a04f563537erobertphillips , fProps(device->surfaceProps()) 610fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips{ 611fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips inc_canvas(); 612fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips 613fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips this->init(device, flags); 614fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips} 615fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips 6164a8126e7f81384526629b1e21bf89b632ea13cd9reedSkCanvas::SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props) 6173716fd067a5621bb94a6cb08d72afec8bf3acedareed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 6184a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(props) 6193716fd067a5621bb94a6cb08d72afec8bf3acedareed{ 6203716fd067a5621bb94a6cb08d72afec8bf3acedareed inc_canvas(); 621b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 622fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips SkAutoTUnref<SkBaseDevice> device(SkNEW_ARGS(SkBitmapDevice, (bitmap, fProps))); 6234a8126e7f81384526629b1e21bf89b632ea13cd9reed this->init(device, kDefault_InitFlags); 6244a8126e7f81384526629b1e21bf89b632ea13cd9reed} 62529c857d0f3a1cb837f73406eeb6ba9771879b5e7reed 6264a8126e7f81384526629b1e21bf89b632ea13cd9reedSkCanvas::SkCanvas(const SkBitmap& bitmap) 6274a8126e7f81384526629b1e21bf89b632ea13cd9reed : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) 6284a8126e7f81384526629b1e21bf89b632ea13cd9reed , fProps(SkSurfaceProps::kLegacyFontHost_InitType) 6294a8126e7f81384526629b1e21bf89b632ea13cd9reed{ 6304a8126e7f81384526629b1e21bf89b632ea13cd9reed inc_canvas(); 631b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 632fcf7829b67b798aff4c41c4688daa9c7381991e6robertphillips SkAutoTUnref<SkBaseDevice> device(SkNEW_ARGS(SkBitmapDevice, (bitmap, fProps))); 6334a8126e7f81384526629b1e21bf89b632ea13cd9reed this->init(device, kDefault_InitFlags); 6348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::~SkCanvas() { 6378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // free up the contents of our deque 6388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->restoreToCount(1); // restore everything but the last 6397c2029367cea5479fa3b74fb0ca2b0297b42b709reed@google.com 6408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->internalRestore(); // restore the last, since we're going away 6418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 64274bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org SkDELETE(fMetaData); 643b70ae310bbdaa1b26786773aabce5548c1f48563vandebo@chromium.org 6448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dec_canvas(); 6458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDrawFilter* SkCanvas::getDrawFilter() const { 6488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fMCRec->fFilter; 6498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDrawFilter* SkCanvas::setDrawFilter(SkDrawFilter* filter) { 65251985e3f5e608d369e52832b7ce489d85d402422reed this->checkForDeferredSave(); 6538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fMCRec->fFilter, filter); 6548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return filter; 6558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 65774bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.orgSkMetaData& SkCanvas::getMetaData() { 65874bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org // metadata users are rare, so we lazily allocate it. If that changes we 65974bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org // can decide to just make it a field in the device (rather than a ptr) 66074bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org if (NULL == fMetaData) { 66174bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org fMetaData = new SkMetaData; 66274bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org } 66374bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org return *fMetaData; 66474bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org} 66574bb77ee4c747b8c70c5c613987c9f93df71df06mike@reedtribe.org 6668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 6678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 668bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.orgvoid SkCanvas::flush() { 6691f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* device = this->getDevice(); 670bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org if (device) { 671bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org device->flush(); 672bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org } 673bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org} 674bf6c1e4aff4d233f6502157fb73459cf69d0ab37junov@chromium.org 6754ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.comSkISize SkCanvas::getTopLayerSize() const { 6764ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com SkBaseDevice* d = this->getTopDevice(); 6774ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com return d ? SkISize::Make(d->width(), d->height()) : SkISize::Make(0, 0); 6784ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com} 6794ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com 6804ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.comSkIPoint SkCanvas::getTopLayerOrigin() const { 6814ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com SkBaseDevice* d = this->getTopDevice(); 6824ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com return d ? d->getOrigin() : SkIPoint::Make(0, 0); 6834ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com} 6844ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.com 6854ebe3821888d550d8a8b89341ec251ba942f0225bsalomon@google.comSkISize SkCanvas::getBaseLayerSize() const { 6861f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* d = this->getDevice(); 687210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com return d ? SkISize::Make(d->width(), d->height()) : SkISize::Make(0, 0); 688210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com} 689210ce003a5ec039dda80de0569fb47ca4efc4dc7reed@google.com 6901f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::getDevice() const { 6918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // return root device 692c029062a0312fb747fb6c2677983aba51795c580robertphillips@google.com MCRec* rec = (MCRec*) fMCStack.front(); 6938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(rec && rec->fLayer); 6948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return rec->fLayer->fDevice; 6958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6971f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::getTopDevice(bool updateMatrixClip) const { 6980b53d59a24f667350b4282f88470713902409030reed@google.com if (updateMatrixClip) { 6990b53d59a24f667350b4282f88470713902409030reed@google.com const_cast<SkCanvas*>(this)->updateDeviceCMCache(); 7000b53d59a24f667350b4282f88470713902409030reed@google.com } 7019266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com return fMCRec->fTopLayer->fDevice; 7029266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com} 7039266fed56a46a4edc710a52c7be8d46fd7c2bc7areed@google.com 704a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.orgbool SkCanvas::readPixels(SkBitmap* bitmap, int x, int y) { 705a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (kUnknown_SkColorType == bitmap->colorType() || bitmap->getTexture()) { 706a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 707a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 708a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 709a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bool weAllocated = false; 710a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (NULL == bitmap->pixelRef()) { 711848250415eddc54075f7eb8795e8db79e749c6abreed if (!bitmap->tryAllocPixels()) { 712a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 713a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 714a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org weAllocated = true; 715a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 716a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 717cf01e31df6bbda270dca2ee3b4967caf51e465dcreed SkAutoPixmapUnlock unlocker; 718cf01e31df6bbda270dca2ee3b4967caf51e465dcreed if (bitmap->requestLock(&unlocker)) { 719cf01e31df6bbda270dca2ee3b4967caf51e465dcreed const SkPixmap& pm = unlocker.pixmap(); 720cf01e31df6bbda270dca2ee3b4967caf51e465dcreed if (this->readPixels(pm.info(), pm.writable_addr(), pm.rowBytes(), x, y)) { 721cf01e31df6bbda270dca2ee3b4967caf51e465dcreed return true; 722cf01e31df6bbda270dca2ee3b4967caf51e465dcreed } 723a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 724a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 725a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (weAllocated) { 726a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bitmap->setPixelRef(NULL); 727a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 728a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 729a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org} 73051df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 731c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.combool SkCanvas::readPixels(const SkIRect& srcRect, SkBitmap* bitmap) { 732a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkIRect r = srcRect; 733a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 734a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!r.intersect(0, 0, size.width(), size.height())) { 735a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bitmap->reset(); 736ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com return false; 737ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com } 73874b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 739848250415eddc54075f7eb8795e8db79e749c6abreed if (!bitmap->tryAllocN32Pixels(r.width(), r.height())) { 740a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org // bitmap will already be reset. 741a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 742a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 743a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!this->readPixels(bitmap->info(), bitmap->getPixels(), bitmap->rowBytes(), r.x(), r.y())) { 744a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org bitmap->reset(); 745daba14b7d4fc96b915c45d82713b22729c0d0f37bsalomon@google.com return false; 746c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com } 747a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return true; 748a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org} 749c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com 75096472deea70169396b8e1f576e470138f55fdb1freedbool SkCanvas::readPixels(const SkImageInfo& dstInfo, void* dstP, size_t rowBytes, int x, int y) { 751a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkBaseDevice* device = this->getDevice(); 752a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org if (!device) { 753a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 754a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 755a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 756f0f14113431ace669f278fdd97b50950f2cf4c80mtklein 75796472deea70169396b8e1f576e470138f55fdb1freed SkReadPixelsRec rec(dstInfo, dstP, rowBytes, x, y); 75896472deea70169396b8e1f576e470138f55fdb1freed if (!rec.trim(size.width(), size.height())) { 759a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org return false; 760a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org } 761db0c8753775774aa3f67114491e26ac1be32f38eskia.committer@gmail.com 762a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org // The device can assert that the requested area is always contained in its bounds 76396472deea70169396b8e1f576e470138f55fdb1freed return device->readPixels(rec.fInfo, rec.fPixels, rec.fRowBytes, rec.fX, rec.fY); 76451df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com} 76551df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 7664cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgbool SkCanvas::writePixels(const SkBitmap& bitmap, int x, int y) { 7674cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (bitmap.getTexture()) { 7684cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 7694cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 770cf01e31df6bbda270dca2ee3b4967caf51e465dcreed 771cf01e31df6bbda270dca2ee3b4967caf51e465dcreed SkAutoPixmapUnlock unlocker; 772cf01e31df6bbda270dca2ee3b4967caf51e465dcreed if (bitmap.requestLock(&unlocker)) { 773cf01e31df6bbda270dca2ee3b4967caf51e465dcreed const SkPixmap& pm = unlocker.pixmap(); 774cf01e31df6bbda270dca2ee3b4967caf51e465dcreed return this->writePixels(pm.info(), pm.addr(), pm.rowBytes(), x, y); 7754cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7764cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 7774cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org} 7784cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 7794cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgbool SkCanvas::writePixels(const SkImageInfo& origInfo, const void* pixels, size_t rowBytes, 7804cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org int x, int y) { 7814cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org switch (origInfo.colorType()) { 7824cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org case kUnknown_SkColorType: 7834cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org case kIndex_8_SkColorType: 7844cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 7854cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org default: 7864cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org break; 7874cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7884cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (NULL == pixels || rowBytes < origInfo.minRowBytes()) { 7894cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 7904cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7914cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 7924cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org const SkISize size = this->getBaseLayerSize(); 7934cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org SkIRect target = SkIRect::MakeXYWH(x, y, origInfo.width(), origInfo.height()); 7944cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (!target.intersect(0, 0, size.width(), size.height())) { 7954cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 7964cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 7974cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 7984cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org SkBaseDevice* device = this->getDevice(); 7994cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (!device) { 8004cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return false; 8014cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 8024cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 8034cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // the intersect may have shrunk info's logical size 804e5ea500d4714a7d84de2bf913e81be3b65d2de68reed const SkImageInfo info = origInfo.makeWH(target.width(), target.height()); 8054cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 8064cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // if x or y are negative, then we have to adjust pixels 8074cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (x > 0) { 8084cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org x = 0; 8094cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 8104cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org if (y > 0) { 8114cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org y = 0; 8124cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org } 8134cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // here x,y are either 0 or negative 8144cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org pixels = ((const char*)pixels - y * rowBytes - x * info.bytesPerPixel()); 8154cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 8164af35f348b2e2f6c428819118eb7a2f2fff53a74reed // Tell our owning surface to bump its generation ID 8174af35f348b2e2f6c428819118eb7a2f2fff53a74reed this->predrawNotify(); 8184af35f348b2e2f6c428819118eb7a2f2fff53a74reed 8194cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // The device can assert that the requested area is always contained in its bounds 8204ef54f8d72420a521d4aae04ff5cd438810eca7fcommit-bot@chromium.org return device->writePixels(info, pixels, rowBytes, target.x(), target.y()); 8214cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org} 82251df9e3fe3c1aec370854b2718df16fc02faa1b2reed@google.com 8234370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.comSkCanvas* SkCanvas::canvasForDrawIter() { 8244370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com return this; 8254370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com} 8264370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com 8278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 8288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::updateDeviceCMCache() { 8308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fDeviceCMDirty) { 8318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& totalMatrix = this->getTotalMatrix(); 8321f836ee096bb988adef4b9757b2629c7afeda36dreed const SkRasterClip& totalClip = fMCRec->fRasterClip; 8338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* layer = fMCRec->fTopLayer; 8344b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 8358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == layer->fNext) { // only one layer 836687fa1c745febb57f42b0d5f03d7c1f4be2530careed layer->updateMC(totalMatrix, totalClip, *fClipStack, NULL); 8378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 838045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com SkRasterClip clip(totalClip); 8398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 840687fa1c745febb57f42b0d5f03d7c1f4be2530careed layer->updateMC(totalMatrix, clip, *fClipStack, &clip); 8418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while ((layer = layer->fNext) != NULL); 8428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = false; 8448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 8488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8492ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::checkForDeferredSave() { 8502ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (fMCRec->fDeferredSaveCount > 0) { 8512ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->doSave(); 8522ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 8532ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed} 8542ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed 855f0090cb80ab10a49e511aa5450ae38917fa058d9reedint SkCanvas::getSaveCount() const { 8562ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed#ifdef SK_DEBUG 8572ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed int count = 0; 8582ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkDeque::Iter iter(fMCStack, SkDeque::Iter::kFront_IterStart); 8592ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed for (;;) { 8602ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed const MCRec* rec = (const MCRec*)iter.next(); 8612ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (!rec) { 8622ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed break; 8632ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 8642ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed count += 1 + rec->fDeferredSaveCount; 8652ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 8662ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(count == fSaveCount); 8672ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed#endif 8682ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return fSaveCount; 869f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 870f0090cb80ab10a49e511aa5450ae38917fa058d9reed 871f0090cb80ab10a49e511aa5450ae38917fa058d9reedint SkCanvas::save() { 8722ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount += 1; 8732ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fMCRec->fDeferredSaveCount += 1; 8742ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return this->getSaveCount() - 1; // return our prev value 8752ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed} 8762ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed 8772ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::doSave() { 878f0090cb80ab10a49e511aa5450ae38917fa058d9reed this->willSave(); 879a62d32d1e3112c7e5a26c27e5e967d124ef8dd81fmalita 880a62d32d1e3112c7e5a26c27e5e967d124ef8dd81fmalita SkASSERT(fMCRec->fDeferredSaveCount > 0); 881a62d32d1e3112c7e5a26c27e5e967d124ef8dd81fmalita fMCRec->fDeferredSaveCount -= 1; 8822ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalSave(); 883f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 884f0090cb80ab10a49e511aa5450ae38917fa058d9reed 885f0090cb80ab10a49e511aa5450ae38917fa058d9reedvoid SkCanvas::restore() { 8862ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (fMCRec->fDeferredSaveCount > 0) { 8872ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(fSaveCount > 1); 8882ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fSaveCount -= 1; 8892ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed fMCRec->fDeferredSaveCount -= 1; 8902ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } else { 8912ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed // check for underflow 8922ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (fMCStack.count() > 1) { 8932ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->willRestore(); 8942ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(fSaveCount > 1); 895a644116c3375b12c642d1b51ee1e5cf4a22c1f5breed fSaveCount -= 1; 8962ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalRestore(); 8972ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->didRestore(); 8982ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 899f0090cb80ab10a49e511aa5450ae38917fa058d9reed } 900f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 901f0090cb80ab10a49e511aa5450ae38917fa058d9reed 902f0090cb80ab10a49e511aa5450ae38917fa058d9reedvoid SkCanvas::restoreToCount(int count) { 903f0090cb80ab10a49e511aa5450ae38917fa058d9reed // sanity check 904f0090cb80ab10a49e511aa5450ae38917fa058d9reed if (count < 1) { 905f0090cb80ab10a49e511aa5450ae38917fa058d9reed count = 1; 906f0090cb80ab10a49e511aa5450ae38917fa058d9reed } 907f0f14113431ace669f278fdd97b50950f2cf4c80mtklein 908f0090cb80ab10a49e511aa5450ae38917fa058d9reed int n = this->getSaveCount() - count; 909f0090cb80ab10a49e511aa5450ae38917fa058d9reed for (int i = 0; i < n; ++i) { 910f0090cb80ab10a49e511aa5450ae38917fa058d9reed this->restore(); 911f0090cb80ab10a49e511aa5450ae38917fa058d9reed } 912f0090cb80ab10a49e511aa5450ae38917fa058d9reed} 913f0090cb80ab10a49e511aa5450ae38917fa058d9reed 9142ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::internalSave() { 9158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com MCRec* newTop = (MCRec*)fMCStack.push_back(); 916d954498c01ccf0417feacf89e45d0c62a06a813breed new (newTop) MCRec(*fMCRec); // balanced in restore() 9178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = newTop; 9184b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 919687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->save(); 9208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic bool bounds_affects_clip(SkCanvas::SaveFlags flags) { 923b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG 9248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (flags & SkCanvas::kClipToLayer_SaveFlag) != 0; 925b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#else 926b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com return true; 927b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#endif 9288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 930a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.orgbool SkCanvas::clipRectBounds(const SkRect* bounds, SaveFlags flags, 9319b3aa54bc9605257c701cf465813f5fb1d7ba39ereed SkIRect* intersection, const SkImageFilter* imageFilter) { 932bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect clipBounds; 933bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (!this->getClipDeviceBounds(&clipBounds)) { 934a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return false; 935f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 936c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org 93796e657d0e103b8358a77ecd913f6086929f792b8reed const SkMatrix& ctm = fMCRec->fMatrix; // this->getTotalMatrix() 93896e657d0e103b8358a77ecd913f6086929f792b8reed 939c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org if (imageFilter) { 94096e657d0e103b8358a77ecd913f6086929f792b8reed imageFilter->filterBounds(clipBounds, ctm, &clipBounds); 941c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org } 942bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect ir; 94349f085dddff10473b6ebf832a974288300224e60bsalomon if (bounds) { 9448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 9454b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 94696e657d0e103b8358a77ecd913f6086929f792b8reed ctm.mapRect(&r, *bounds); 9478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.roundOut(&ir); 9488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // early exit if the layer's bounds are clipped out 9498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!ir.intersect(clipBounds)) { 950bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (bounds_affects_clip(flags)) { 9519b3aa54bc9605257c701cf465813f5fb1d7ba39ereed fCachedLocalClipBoundsDirty = true; 9521f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fRasterClip.setEmpty(); 953bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 954a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return false; 9558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { // no user bounds, so just use the clip 9578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ir = clipBounds; 9588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 959180aec43451dd951fdaae81a92efc710ba093260reed SkASSERT(!ir.isEmpty()); 9608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 96189f077ced4918ded7e911bc5052b61c90ad57a9asenorblanco@chromium.org if (bounds_affects_clip(flags)) { 962180aec43451dd951fdaae81a92efc710ba093260reed // Simplify the current clips since they will be applied properly during restore() 9639b3aa54bc9605257c701cf465813f5fb1d7ba39ereed fCachedLocalClipBoundsDirty = true; 964687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipDevRect(ir, SkRegion::kReplace_Op); 965180aec43451dd951fdaae81a92efc710ba093260reed fMCRec->fRasterClip.setRect(ir); 966a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org } 967a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 968a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org if (intersection) { 969a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org *intersection = ir; 970a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org } 971a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org return true; 972a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org} 973a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 974d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.orgint SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint) { 975d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed if (gIgnoreSaveLayerBounds) { 976d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed bounds = NULL; 977d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed } 978d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org SaveLayerStrategy strategy = this->willSaveLayer(bounds, paint, kARGB_ClipLayer_SaveFlag); 979a644116c3375b12c642d1b51ee1e5cf4a22c1f5breed fSaveCount += 1; 98076033be81b82c44fd5d4fdf2672eb22e505da1f0reed this->internalSaveLayer(bounds, paint, kARGB_ClipLayer_SaveFlag, strategy); 9812ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return this->getSaveCount() - 1; 982d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org} 983d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org 9842ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedint SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags) { 985d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed if (gIgnoreSaveLayerBounds) { 986d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed bounds = NULL; 987d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed } 988e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org SaveLayerStrategy strategy = this->willSaveLayer(bounds, paint, flags); 989a644116c3375b12c642d1b51ee1e5cf4a22c1f5breed fSaveCount += 1; 99076033be81b82c44fd5d4fdf2672eb22e505da1f0reed this->internalSaveLayer(bounds, paint, flags, strategy); 9912ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return this->getSaveCount() - 1; 9928926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com} 9938926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 9942ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedvoid SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags, 99576033be81b82c44fd5d4fdf2672eb22e505da1f0reed SaveLayerStrategy strategy) { 996b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG 9972a5cd60bfff32c92cf44a8cfc3e8c017b9aee456commit-bot@chromium.org flags |= kClipToLayer_SaveFlag; 998b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com#endif 999b93ba45b58ad24e0e2cb75b842e24ff711c368b0reed@google.com 1000a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org // do this before we create the layer. We don't call the public save() since 1001a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org // that would invoke a possibly overridden virtual 10022ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->internalSave(); 1003a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 1004a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org fDeviceCMDirty = true; 1005a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org 1006a907ac3e3e3458fbb5d673c3feafb31fd7647b38junov@chromium.org SkIRect ir; 1007daa57bfd4204f5a7d304c580bcf5ad99d0121e1freed if (!this->clipRectBounds(bounds, flags, &ir, paint ? paint->getImageFilter() : NULL)) { 10082ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 10098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1011e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy really care about 1012e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org // the clipRectBounds() call above? 1013e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org if (kNoLayer_SaveLayerStrategy == strategy) { 10142ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 1015e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org } 1016e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org 101776033be81b82c44fd5d4fdf2672eb22e505da1f0reed bool isOpaque = !SkToBool(flags & kHasAlphaLayer_SaveFlag); 10188dc0ccb8d33d1af7dd13228509e61fe915bc7705reed SkPixelGeometry geo = fProps.pixelGeometry(); 10198dc0ccb8d33d1af7dd13228509e61fe915bc7705reed if (paint) { 102076033be81b82c44fd5d4fdf2672eb22e505da1f0reed // TODO: perhaps add a query to filters so we might preserve opaqueness... 1021daa57bfd4204f5a7d304c580bcf5ad99d0121e1freed if (paint->getImageFilter() || paint->getColorFilter()) { 102276033be81b82c44fd5d4fdf2672eb22e505da1f0reed isOpaque = false; 10238dc0ccb8d33d1af7dd13228509e61fe915bc7705reed geo = kUnknown_SkPixelGeometry; 1024b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com } 1025b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com } 102615a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org SkImageInfo info = SkImageInfo::MakeN32(ir.width(), ir.height(), 102715a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType); 10288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1029b2db898573e3cdcc8234eebf51961bfc4977ebbcreed SkBaseDevice* device = this->getTopDevice(); 1030b2db898573e3cdcc8234eebf51961bfc4977ebbcreed if (NULL == device) { 1031b2db898573e3cdcc8234eebf51961bfc4977ebbcreed SkDebugf("Unable to find device for layer."); 10322ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed return; 1033b2db898573e3cdcc8234eebf51961bfc4977ebbcreed } 1034b2db898573e3cdcc8234eebf51961bfc4977ebbcreed 103561f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed bool forceSpriteOnRestore = false; 103661f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed { 1037daa57bfd4204f5a7d304c580bcf5ad99d0121e1freed const SkBaseDevice::TileUsage usage = SkBaseDevice::kNever_TileUsage; 103861f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed const SkBaseDevice::CreateInfo createInfo = SkBaseDevice::CreateInfo(info, usage, geo); 103961f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed SkBaseDevice* newDev = device->onCreateDevice(createInfo, paint); 104061f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed if (NULL == newDev) { 104161f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed // If onCreateDevice didn't succeed, try raster (e.g. PDF couldn't handle the paint) 10429a53fd7c41554630124522f4b6eedc16912abbb7robertphillips const SkSurfaceProps surfaceProps(fProps.flags(), createInfo.fPixelGeometry); 10439a53fd7c41554630124522f4b6eedc16912abbb7robertphillips newDev = SkBitmapDevice::Create(createInfo.fInfo, surfaceProps); 104461f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed if (NULL == newDev) { 104561f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed SkErrorInternals::SetError(kInternalError_SkError, 104661f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed "Unable to create device for layer."); 104761f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed return; 104861f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed } 104961f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed forceSpriteOnRestore = true; 105061f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed } 105161f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed device = newDev; 1052e25c68402b38ac01dc1ae196ae8a5265b773c5f2bungeman@google.com } 1053e97f0856a8044866b12527819d14cdfbcdfd96f2bsalomon@google.com 10546f8f292aa768869a9e85c314b124875f57504f2creed@google.com device->setOrigin(ir.fLeft, ir.fTop); 105561f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed DeviceCM* layer = SkNEW_ARGS(DeviceCM, (device, paint, this, fConservativeRasterClip, 105686a17e7716c8db858e219a46b9db3817bb770beereed forceSpriteOnRestore)); 10578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device->unref(); 10588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com layer->fNext = fMCRec->fTopLayer; 10608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fLayer = layer; 10618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fTopLayer = layer; // this field is NOT an owner of layer 10628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1064d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.orgint SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) { 1065d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org return this->saveLayerAlpha(bounds, alpha, kARGB_ClipLayer_SaveFlag); 1066d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org} 1067d70fa2013adccaa52d1f3e6ca501a4d4ab1520f3commit-bot@chromium.org 10688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha, 10698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SaveFlags flags) { 10708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (0xFF == alpha) { 10718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->saveLayer(bounds, NULL, flags); 10728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 10738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint tmpPaint; 10748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com tmpPaint.setAlpha(alpha); 10758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->saveLayer(bounds, &tmpPaint, flags); 10768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::internalRestore() { 10808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fMCStack.count() != 0); 10818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1083c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 10848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1085687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->restore(); 10866c157640c27ee2ed6f9a484d21691b7b19dfecdecommit-bot@chromium.org 108788edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com // reserve our layer (if any) 10888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* layer = fMCRec->fLayer; // may be null 10898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now detach it from fMCRec so we can pop(). Gets freed after its drawn 10908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fLayer = NULL; 10918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now do the normal restore() 10938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->~MCRec(); // balanced in save() 10948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCStack.pop_back(); 10958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = (MCRec*)fMCStack.back(); 10968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* Time to draw the layer's offscreen. We can't call the public drawSprite, 10988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com since if we're being recorded, we don't want to record this (the 10998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com recorder will have already recorded the restore). 11008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 110149f085dddff10473b6ebf832a974288300224e60bsalomon if (layer) { 11028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (layer->fNext) { 11036f8f292aa768869a9e85c314b124875f57504f2creed@google.com const SkIPoint& origin = layer->fDevice->getOrigin(); 11048926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(), 110561f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed layer->fPaint, layer->fDeviceIsBitmapDevice); 11068926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com // reset this, since internalDrawDevice will have set it to true 11078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1108b679ca8926a832274b14fdb512f88f64b61d32eareed SkDELETE(layer); 1109b679ca8926a832274b14fdb512f88f64b61d32eareed } else { 1110b679ca8926a832274b14fdb512f88f64b61d32eareed // we're at the root 1111a499f905e9340e4935447f2562fd92e8853382b1reed SkASSERT(layer == (void*)fDeviceCMStorage); 1112b679ca8926a832274b14fdb512f88f64b61d32eareed layer->~DeviceCM(); 11138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 111488edf1e50794e6d8cd7cc671ffce4f5e329ef888bungeman@google.com } 11158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 11168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11174a8126e7f81384526629b1e21bf89b632ea13cd9reedSkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* props) { 11184a8126e7f81384526629b1e21bf89b632ea13cd9reed if (NULL == props) { 11194a8126e7f81384526629b1e21bf89b632ea13cd9reed props = &fProps; 11204a8126e7f81384526629b1e21bf89b632ea13cd9reed } 11214a8126e7f81384526629b1e21bf89b632ea13cd9reed return this->onNewSurface(info, *props); 112276f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com} 112376f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com 11244a8126e7f81384526629b1e21bf89b632ea13cd9reedSkSurface* SkCanvas::onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props) { 112576f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com SkBaseDevice* dev = this->getDevice(); 11264a8126e7f81384526629b1e21bf89b632ea13cd9reed return dev ? dev->newSurface(info, props) : NULL; 112776f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com} 112876f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com 1129c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgSkImageInfo SkCanvas::imageInfo() const { 1130c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkBaseDevice* dev = this->getDevice(); 1131c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (dev) { 1132c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return dev->imageInfo(); 1133c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } else { 1134900ecf2f1579d42c9d2959831787af0346320f86reed@google.com return SkImageInfo::MakeUnknown(0, 0); 1135c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1136c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1137c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1138c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgconst void* SkCanvas::peekPixels(SkImageInfo* info, size_t* rowBytes) { 1139884e97cb04db7ed053a866567ee9c6e4c01f993areed SkPixmap pmap; 1140884e97cb04db7ed053a866567ee9c6e4c01f993areed if (!this->onPeekPixels(&pmap)) { 1141884e97cb04db7ed053a866567ee9c6e4c01f993areed return NULL; 1142884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1143884e97cb04db7ed053a866567ee9c6e4c01f993areed if (info) { 1144884e97cb04db7ed053a866567ee9c6e4c01f993areed *info = pmap.info(); 1145884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1146884e97cb04db7ed053a866567ee9c6e4c01f993areed if (rowBytes) { 1147884e97cb04db7ed053a866567ee9c6e4c01f993areed *rowBytes = pmap.rowBytes(); 1148884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1149884e97cb04db7ed053a866567ee9c6e4c01f993areed return pmap.addr(); 1150c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1151c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1152884e97cb04db7ed053a866567ee9c6e4c01f993areedbool SkCanvas::onPeekPixels(SkPixmap* pmap) { 1153c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkBaseDevice* dev = this->getDevice(); 1154884e97cb04db7ed053a866567ee9c6e4c01f993areed return dev && dev->peekPixels(pmap); 1155c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1156c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 11576b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.orgvoid* SkCanvas::accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin) { 1158884e97cb04db7ed053a866567ee9c6e4c01f993areed SkPixmap pmap; 1159884e97cb04db7ed053a866567ee9c6e4c01f993areed if (!this->onAccessTopLayerPixels(&pmap)) { 1160884e97cb04db7ed053a866567ee9c6e4c01f993areed return NULL; 1161884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1162884e97cb04db7ed053a866567ee9c6e4c01f993areed if (info) { 1163884e97cb04db7ed053a866567ee9c6e4c01f993areed *info = pmap.info(); 1164884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1165884e97cb04db7ed053a866567ee9c6e4c01f993areed if (rowBytes) { 1166884e97cb04db7ed053a866567ee9c6e4c01f993areed *rowBytes = pmap.rowBytes(); 1167884e97cb04db7ed053a866567ee9c6e4c01f993areed } 1168884e97cb04db7ed053a866567ee9c6e4c01f993areed if (origin) { 11696b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org *origin = this->getTopDevice(false)->getOrigin(); 11706b4aaa77dcc4f17d0e22986f5f4cca70011d1ee5commit-bot@chromium.org } 1171884e97cb04db7ed053a866567ee9c6e4c01f993areed return pmap.writable_addr(); 11729c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 11739c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1174884e97cb04db7ed053a866567ee9c6e4c01f993areedbool SkCanvas::onAccessTopLayerPixels(SkPixmap* pmap) { 11759c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com SkBaseDevice* dev = this->getTopDevice(); 1176884e97cb04db7ed053a866567ee9c6e4c01f993areed return dev && dev->accessPixels(pmap); 11779c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 11789c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1179c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgSkAutoROCanvasPixels::SkAutoROCanvasPixels(SkCanvas* canvas) { 1180c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org fAddr = canvas->peekPixels(&fInfo, &fRowBytes); 1181c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (NULL == fAddr) { 1182c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org fInfo = canvas->imageInfo(); 1183848250415eddc54075f7eb8795e8db79e749c6abreed if (kUnknown_SkColorType == fInfo.colorType() || !fBitmap.tryAllocPixels(fInfo)) { 1184c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return; // failure, fAddr is NULL 1185c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1186c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (!canvas->readPixels(&fBitmap, 0, 0)) { 1187c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return; // failure, fAddr is NULL 1188c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1189c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org fAddr = fBitmap.getPixels(); 1190c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org fRowBytes = fBitmap.rowBytes(); 1191c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1192c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org SkASSERT(fAddr); // success 1193c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1194c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1195c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.orgbool SkAutoROCanvasPixels::asROBitmap(SkBitmap* bitmap) const { 1196c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org if (fAddr) { 119700f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org return bitmap->installPixels(fInfo, const_cast<void*>(fAddr), fRowBytes); 1198c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } else { 1199c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org bitmap->reset(); 1200c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org return false; 1201c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org } 1202c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org} 1203c3bd8af6d5722e854feca70c40d92f4954c5b67bcommit-bot@chromium.org 1204520cf8b33e788268432c6314c52dfcef22e776aecommit-bot@chromium.org///////////////////////////////////////////////////////////////////////////// 12059bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.comvoid SkCanvas::internalDrawBitmap(const SkBitmap& bitmap, 12068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& matrix, const SkPaint* paint) { 120750b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org if (bitmap.drawsNothing()) { 12088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 12098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12112c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkLazyPaint lazy; 12128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == paint) { 12132c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org paint = lazy.init(); 12148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12159bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com 12169bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com SkDEBUGCODE(bitmap.validate();) 12179bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com 121878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 121978cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 122078cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (paint && paint->canComputeFastBounds()) { 122178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bitmap.getBounds(&storage); 122278cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org matrix.mapRect(&storage); 122378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint->computeFastBounds(storage, &storage); 122478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org } 122578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org 122678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) 12279bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com 12289bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com while (iter.next()) { 12299bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com iter.fDevice->drawBitmap(iter, bitmap, matrix, looper.paint()); 12309bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com } 12319bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com 12329bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com LOOPER_END 12338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12351f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comvoid SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, 123661f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed const SkPaint* paint, bool deviceIsBitmapDevice) { 12378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint tmp; 12388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == paint) { 12398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint = &tmp; 12408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12414b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 12428926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com LOOPER_BEGIN_DRAWDEVICE(*paint, SkDrawFilter::kBitmap_Type) 12438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 12441f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkBaseDevice* dstDev = iter.fDevice; 124576dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com paint = &looper.paint(); 124676dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkImageFilter* filter = paint->getImageFilter(); 124776dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkIPoint pos = { x - iter.getX(), y - iter.getY() }; 12488926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com if (filter && !dstDev->canHandleImageFilter(filter)) { 1249efbffedd68636e94d4379e84a2585bce80f6fb8frobertphillips SkImageFilter::Proxy proxy(dstDev); 125076dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com SkBitmap dst; 12516776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org SkIPoint offset = SkIPoint::Make(0, 0); 1252b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com const SkBitmap& src = srcDev->accessBitmap(false); 1253fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org SkMatrix matrix = *iter.fMatrix; 1254d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org matrix.postTranslate(SkIntToScalar(-pos.x()), SkIntToScalar(-pos.y())); 12554cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org SkIRect clipBounds = SkIRect::MakeWH(srcDev->width(), srcDev->height()); 1256be129b26f13d575fd6b396c6ae759838ecc9bd1asenorblanco SkAutoTUnref<SkImageFilter::Cache> cache(dstDev->getImageFilterCache()); 125755b6d8be997a447ef9ce0f029697677a940bfc24senorblanco SkImageFilter::Context ctx(matrix, clipBounds, cache.get()); 12584cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org if (filter->filterImage(&proxy, src, ctx, &dst, &offset)) { 12595efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com SkPaint tmpUnfiltered(*paint); 12605efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com tmpUnfiltered.setImageFilter(NULL); 12616776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org dstDev->drawSprite(iter, dst, pos.x() + offset.x(), pos.y() + offset.y(), 12626776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org tmpUnfiltered); 126376dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } 126461f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed } else if (deviceIsBitmapDevice) { 12659572a10c9a6a868bbb8f71d7806d0a45f183333freed const SkBitmap& src = static_cast<SkBitmapDevice*>(srcDev)->fBitmap; 126661f501f8c675da8d5915e5e7fd32dfdb113f1cfbreed dstDev->drawSprite(iter, src, pos.x(), pos.y(), *paint); 126776dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } else { 1268b55deeb1c7c692023603639a9b29c0e3de124eacreed@google.com dstDev->drawDevice(iter, srcDev, pos.x(), pos.y(), *paint); 126976dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com } 12708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12714e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 12728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 127441af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawSprite(const SkBitmap& bitmap, int x, int y, const SkPaint* paint) { 12750acf1b4b3645772d220c720313821bac389751b5reed if (gTreatSpriteAsBitmap) { 12760acf1b4b3645772d220c720313821bac389751b5reed this->save(); 12770acf1b4b3645772d220c720313821bac389751b5reed this->resetMatrix(); 12780acf1b4b3645772d220c720313821bac389751b5reed this->drawBitmap(bitmap, SkIntToScalar(x), SkIntToScalar(y), paint); 12790acf1b4b3645772d220c720313821bac389751b5reed this->restore(); 12800acf1b4b3645772d220c720313821bac389751b5reed return; 12810acf1b4b3645772d220c720313821bac389751b5reed } 12820acf1b4b3645772d220c720313821bac389751b5reed 12839881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawSprite()"); 128450b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org if (bitmap.drawsNothing()) { 12858926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com return; 12868926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 128750b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org SkDEBUGCODE(bitmap.validate();) 1288fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 12898926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkPaint tmp; 12908926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com if (NULL == paint) { 12918926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com paint = &tmp; 12928926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 1293fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 12948926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com LOOPER_BEGIN_DRAWDEVICE(*paint, SkDrawFilter::kBitmap_Type) 1295fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 12968926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com while (iter.next()) { 12978926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com paint = &looper.paint(); 12988926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkImageFilter* filter = paint->getImageFilter(); 12998926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkIPoint pos = { x - iter.getX(), y - iter.getY() }; 13008926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com if (filter && !iter.fDevice->canHandleImageFilter(filter)) { 1301efbffedd68636e94d4379e84a2585bce80f6fb8frobertphillips SkImageFilter::Proxy proxy(iter.fDevice); 13028926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com SkBitmap dst; 13036776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org SkIPoint offset = SkIPoint::Make(0, 0); 1304fbaea5336690ffc4fd9ee695608e9457da10eeabsenorblanco@chromium.org SkMatrix matrix = *iter.fMatrix; 1305d5424a425bc21280afe2161f6ac1e5d9eb97e6b2senorblanco@chromium.org matrix.postTranslate(SkIntToScalar(-pos.x()), SkIntToScalar(-pos.y())); 1306f622a6c8fd176acf9944de8df00d7f0bb56b67d3halcanary const SkIRect clipBounds = bitmap.bounds(); 1307be129b26f13d575fd6b396c6ae759838ecc9bd1asenorblanco SkAutoTUnref<SkImageFilter::Cache> cache(iter.fDevice->getImageFilterCache()); 130855b6d8be997a447ef9ce0f029697677a940bfc24senorblanco SkImageFilter::Context ctx(matrix, clipBounds, cache.get()); 13094cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org if (filter->filterImage(&proxy, bitmap, ctx, &dst, &offset)) { 13105efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com SkPaint tmpUnfiltered(*paint); 13115efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com tmpUnfiltered.setImageFilter(NULL); 13126776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org iter.fDevice->drawSprite(iter, dst, pos.x() + offset.x(), pos.y() + offset.y(), 13135efe0cb04961ef98fbe520ee732fbe50b4195ad3tomhudson@google.com tmpUnfiltered); 13148926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 13158926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } else { 13168926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com iter.fDevice->drawSprite(iter, bitmap, pos.x(), pos.y(), *paint); 13178926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 13188926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com } 13198926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com LOOPER_END 13208926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com} 13218926b169f6a0dfa4c2129a98ec2aee205f0c8527reed@google.com 13228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////// 132392362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::translate(SkScalar dx, SkScalar dy) { 1324d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1325d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setTranslate(dx, dy); 1326d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 13278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 132992362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::scale(SkScalar sx, SkScalar sy) { 1330d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1331d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setScale(sx, sy); 1332d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 13338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 133592362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::rotate(SkScalar degrees) { 1336d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1337d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setRotate(degrees); 1338d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 13398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 134192362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::skew(SkScalar sx, SkScalar sy) { 1342d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkMatrix m; 1343d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org m.setSkew(sx, sy); 1344d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->concat(m); 134544c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org} 134644c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 134792362383a4de7b0d819c88fa8b74242bb2507602commit-bot@chromium.orgvoid SkCanvas::concat(const SkMatrix& matrix) { 1348d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org if (matrix.isIdentity()) { 1349d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org return; 1350d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org } 1351d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org 13522ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 13538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1354c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 13551f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix.preConcat(matrix); 135644c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 135744c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org this->didConcat(matrix); 135844c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org} 135944c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org 136086a17e7716c8db858e219a46b9db3817bb770beereedvoid SkCanvas::setMatrix(const SkMatrix& matrix) { 136186a17e7716c8db858e219a46b9db3817bb770beereed this->checkForDeferredSave(); 13628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1363c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 13641f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix = matrix; 136544c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org this->didSetMatrix(matrix); 13668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::resetMatrix() { 13698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 13704b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 13718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.reset(); 13728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->setMatrix(matrix); 13738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 13768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1377759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { 13782ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 13798f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 13808f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(rect, op, edgeStyle); 13818f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 13828f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 13838f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 1384da17f758442f16747af39f8fbaed9c097048519creed@google.com#ifdef SK_ENABLE_CLIP_QUICKREJECT 1385da17f758442f16747af39f8fbaed9c097048519creed@google.com if (SkRegion::kIntersect_Op == op) { 13861f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fRasterClip.isEmpty()) { 1387da17f758442f16747af39f8fbaed9c097048519creed@google.com return false; 1388da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1389da17f758442f16747af39f8fbaed9c097048519creed@google.com 13903b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(rect)) { 1391da17f758442f16747af39f8fbaed9c097048519creed@google.com fDeviceCMDirty = true; 1392c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 1393da17f758442f16747af39f8fbaed9c097048519creed@google.com 1394687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipEmpty(); 13951f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.setEmpty(); 1396da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1397da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1398da17f758442f16747af39f8fbaed9c097048519creed@google.com#endif 1399da17f758442f16747af39f8fbaed9c097048519creed@google.com 14005c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com AutoValidateClip avc(this); 14015c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 14028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1403c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 14048f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!fAllowSoftClip) { 14058f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com edgeStyle = kHard_ClipEdgeStyle; 14068f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 14078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14081f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fMatrix.rectStaysRect()) { 1409123671901abfa595d09ca789b487c4bc7c1f7cbcrobertphillips@google.com // for these simpler matrices, we can stay a rect even after applying 141098de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // the matrix. This means we don't have to a) make a path, and b) tell 141198de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // the region code to scan-convert the path, only to discover that it 141298de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // is really just a rect. 14138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 14148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14151f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix.mapRect(&r, rect); 1416687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipDevRect(r, op, kSoft_ClipEdgeStyle == edgeStyle); 1417d954498c01ccf0417feacf89e45d0c62a06a813breed fMCRec->fRasterClip.op(r, this->getBaseLayerSize(), op, kSoft_ClipEdgeStyle == edgeStyle); 14188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 1419123671901abfa595d09ca789b487c4bc7c1f7cbcrobertphillips@google.com // since we're rotated or some such thing, we convert the rect to a path 142098de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // and clip against that, since it can handle any matrix. However, to 142198de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // avoid recursion in the case where we are subclassed (e.g. Pictures) 142298de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // we explicitly call "our" version of clipPath. 14238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath path; 14248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.addRect(rect); 14268f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->SkCanvas::onClipPath(path, op, edgeStyle); 14278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 14288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 143073e714eb766617ce06757829a3c0b345c7963faareedstatic void rasterclip_path(SkRasterClip* rc, const SkCanvas* canvas, const SkPath& devPath, 143173e714eb766617ce06757829a3c0b345c7963faareed SkRegion::Op op, bool doAA) { 1432d64c9487135094c83f658319f53ea2005ecc08b2reed rc->op(devPath, canvas->getBaseLayerSize(), op, doAA); 1433819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com} 1434819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 1435759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) { 14362ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 14378f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 14384ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (rrect.isRect()) { 14398f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(rrect.getBounds(), op, edgeStyle); 14408f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } else { 14418f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRRect(rrect, op, edgeStyle); 14424ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 14438f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 144414e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 14458f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 144614e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org SkRRect transformedRRect; 14471f836ee096bb988adef4b9757b2629c7afeda36dreed if (rrect.transform(fMCRec->fMatrix, &transformedRRect)) { 144814e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org AutoValidateClip avc(this); 144914e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 145014e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org fDeviceCMDirty = true; 145114e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org fCachedLocalClipBoundsDirty = true; 14528f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!fAllowSoftClip) { 14538f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com edgeStyle = kHard_ClipEdgeStyle; 14548f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 145514e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 1456687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipDevRRect(transformedRRect, op, kSoft_ClipEdgeStyle == edgeStyle); 145714e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 145814e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org SkPath devPath; 145914e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org devPath.addRRect(transformedRRect); 146014e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 146173e714eb766617ce06757829a3c0b345c7963faareed rasterclip_path(&fMCRec->fRasterClip, this, devPath, op, kSoft_ClipEdgeStyle == edgeStyle); 14628f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com return; 146314e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org } 146414e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org 146514e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org SkPath path; 146614e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org path.addRRect(rrect); 146714e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org // call the non-virtual version 14688f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->SkCanvas::onClipPath(path, op, edgeStyle); 14694ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 14704ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 1471759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { 14722ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 14738f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; 14748f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com SkRect r; 14758f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!path.isInverseFillType() && path.isRect(&r)) { 14768f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRect(r, op, edgeStyle); 14778f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } else { 14788f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipPath(path, op, edgeStyle); 14798f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 14808f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 14818f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 14828f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 1483da17f758442f16747af39f8fbaed9c097048519creed@google.com#ifdef SK_ENABLE_CLIP_QUICKREJECT 1484da17f758442f16747af39f8fbaed9c097048519creed@google.com if (SkRegion::kIntersect_Op == op && !path.isInverseFillType()) { 14851f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fRasterClip.isEmpty()) { 1486da17f758442f16747af39f8fbaed9c097048519creed@google.com return false; 1487da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1488fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 14893b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(path.getBounds())) { 1490da17f758442f16747af39f8fbaed9c097048519creed@google.com fDeviceCMDirty = true; 1491c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 1492fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1493687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipEmpty(); 14941f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.setEmpty(); 1495da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1496da17f758442f16747af39f8fbaed9c097048519creed@google.com } 1497da17f758442f16747af39f8fbaed9c097048519creed@google.com#endif 1498da17f758442f16747af39f8fbaed9c097048519creed@google.com 14995c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com AutoValidateClip avc(this); 15005c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 15018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1502c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 15038f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!fAllowSoftClip) { 15048f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com edgeStyle = kHard_ClipEdgeStyle; 15058f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } 15068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 15078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath devPath; 15081f836ee096bb988adef4b9757b2629c7afeda36dreed path.transform(fMCRec->fMatrix, &devPath); 15098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1510fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // Check if the transfomation, or the original path itself 1511fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // made us empty. Note this can also happen if we contained NaN 1512fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // values. computing the bounds detects this, and will set our 1513fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // bounds to empty if that is the case. (see SkRect::set(pts, count)) 1514fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com if (devPath.getBounds().isEmpty()) { 1515fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // resetting the path will remove any NaN or other wanky values 1516fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com // that might upset our scan converter. 1517fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com devPath.reset(); 1518fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com } 1519fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com 15205c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // if we called path.swap() we could avoid a deep copy of this path 1521687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipDevPath(devPath, op, kSoft_ClipEdgeStyle == edgeStyle); 15225c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 152345a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com if (fAllowSimplifyClip) { 15241a481fe4bf632ed4f76cb337691236fabfd4ab03fmalita bool clipIsAA = getClipStack()->asPath(&devPath); 15251a481fe4bf632ed4f76cb337691236fabfd4ab03fmalita if (clipIsAA) { 15261a481fe4bf632ed4f76cb337691236fabfd4ab03fmalita edgeStyle = kSoft_ClipEdgeStyle; 152745a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com } 15281a481fe4bf632ed4f76cb337691236fabfd4ab03fmalita 152945a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com op = SkRegion::kReplace_Op; 153045a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com } 153145a75fb4d0ca5daa0ac5e634238970306e3b5838caryclark@google.com 153273e714eb766617ce06757829a3c0b345c7963faareed rasterclip_path(&fMCRec->fRasterClip, this, devPath, op, edgeStyle); 15338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 15348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1535759cf4846804be137229393e04925752423de2d0commit-bot@chromium.orgvoid SkCanvas::clipRegion(const SkRegion& rgn, SkRegion::Op op) { 15362ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed this->checkForDeferredSave(); 15378f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->onClipRegion(rgn, op); 15388f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 15398f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 15408f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkCanvas::onClipRegion(const SkRegion& rgn, SkRegion::Op op) { 15415c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com AutoValidateClip avc(this); 15425c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 15438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 1544c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com fCachedLocalClipBoundsDirty = true; 15458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 15465c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // todo: signal fClipStack that we have a region, and therefore (I guess) 15475c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com // we have to ignore it, and use the region directly? 1548687fa1c745febb57f42b0d5f03d7c1f4be2530careed fClipStack->clipDevRect(rgn.getBounds(), op); 15495c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 15501f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fRasterClip.op(rgn, op); 15518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 15528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1553819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com#ifdef SK_DEBUG 1554819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.comvoid SkCanvas::validateClip() const { 1555819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com // construct clipRgn from the clipstack 15561f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com const SkBaseDevice* device = this->getDevice(); 1557ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com if (!device) { 15585c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org SkASSERT(this->isClipEmpty()); 1559ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com return; 1560ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com } 1561ccfee2a3620e32053b4bf635f0e31e31018dcd96djsollen@google.com 1562819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com SkIRect ir; 1563819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com ir.set(0, 0, device->width(), device->height()); 1564d954498c01ccf0417feacf89e45d0c62a06a813breed SkRasterClip tmpClip(ir, fConservativeRasterClip); 1565819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 1566687fa1c745febb57f42b0d5f03d7c1f4be2530careed SkClipStack::B2TIter iter(*fClipStack); 15678182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const SkClipStack::Element* element; 15688182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com while ((element = iter.next()) != NULL) { 15698182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com switch (element->getType()) { 15708182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kRect_Type: 15718182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com element->getRect().round(&ir); 15728182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com tmpClip.op(ir, element->getOp()); 15738182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 15748182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com case SkClipStack::Element::kEmpty_Type: 15758182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com tmpClip.setEmpty(); 15768182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com break; 15779cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org default: { 15789cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org SkPath path; 15799cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org element->asPath(&path); 158073e714eb766617ce06757829a3c0b345c7963faareed rasterclip_path(&tmpClip, this, path, element->getOp(), element->isAA()); 15819cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org break; 15829cb671a0017e8f2906e8351ff35efcd6d8fbf7b0commit-bot@chromium.org } 1583819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com } 1584819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com } 1585819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com} 1586819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com#endif 1587819c921b0445fa9f45f18d4a560603cd9fde6ba4reed@google.com 158890c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.comvoid SkCanvas::replayClips(ClipVisitor* visitor) const { 1589687fa1c745febb57f42b0d5f03d7c1f4be2530careed SkClipStack::B2TIter iter(*fClipStack); 15908182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com const SkClipStack::Element* element; 15918182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com 15928182fa0cac76e7e6d583aebba060229230516887bsalomon@google.com while ((element = iter.next()) != NULL) { 1593c3b589a24eb4d567a906189f882c259ecf5c2f58fmalita element->replay(visitor); 159490c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com } 159590c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com} 159690c07ea1d0aa6b7f20252c43fe23ee5ddc1d23cbreed@google.com 15975c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com/////////////////////////////////////////////////////////////////////////////// 15985c3d1471e4908706cd053a5e2ea9ded3a6c2eaebreed@google.com 1599754de5f65b466f721d952a379194cc94de376f42reed@google.combool SkCanvas::isClipEmpty() const { 16001f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.isEmpty(); 1601754de5f65b466f721d952a379194cc94de376f42reed@google.com} 1602754de5f65b466f721d952a379194cc94de376f42reed@google.com 16035c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.orgbool SkCanvas::isClipRect() const { 16041f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.isRect(); 16055c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org} 16065c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org 16073b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::quickReject(const SkRect& rect) const { 16081607863b608b7db6c813228768ed5d72997bbc82reed@google.com if (!rect.isFinite()) 1609116b2bcd2c4c4d4670c7b7e2ea597414713c37fbwjmaclean@chromium.org return true; 1610116b2bcd2c4c4d4670c7b7e2ea597414713c37fbwjmaclean@chromium.org 16111f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fRasterClip.isEmpty()) { 16128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 16138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 16148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16151f836ee096bb988adef4b9757b2629c7afeda36dreed if (fMCRec->fMatrix.hasPerspective()) { 1616a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com SkRect dst; 16171f836ee096bb988adef4b9757b2629c7afeda36dreed fMCRec->fMatrix.mapRect(&dst, rect); 1618b07a94f1cba3976596ae1a7f23d8c2043ba353f3reed return !SkIRect::Intersects(dst.roundOut(), fMCRec->fRasterClip.getBounds()); 1619a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com } else { 1620c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com const SkRect& clipR = this->getLocalClipBounds(); 1621d252db03d9650013b545ef9781fe993c07f8f314reed@android.com 1622a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com // for speed, do the most likely reject compares first 1623c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com // TODO: should we use | instead, or compare all 4 at once? 1624c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com if (rect.fTop >= clipR.fBottom || rect.fBottom <= clipR.fTop) { 1625a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com return true; 1626a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com } 1627c0784dbd408596aff13a5d97448f7a9e5d3cf7d9reed@google.com if (rect.fLeft >= clipR.fRight || rect.fRight <= clipR.fLeft) { 1628a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com return true; 1629a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com } 1630a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com return false; 16318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 16328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16343b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::quickReject(const SkPath& path) const { 16353b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com return path.isEmpty() || this->quickReject(path.getBounds()); 16368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16383b3e895df6f8ee0f33010367c215944cd16a8334reed@google.combool SkCanvas::getClipBounds(SkRect* bounds) const { 1639bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkIRect ibounds; 16408f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!this->getClipDeviceBounds(&ibounds)) { 16418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 16428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 16438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1644d9c0f0b57affec7a472879c5919acac6637d926areed@android.com SkMatrix inverse; 1645d9c0f0b57affec7a472879c5919acac6637d926areed@android.com // if we can't invert the CTM, we can't return local clip bounds 16461f836ee096bb988adef4b9757b2629c7afeda36dreed if (!fMCRec->fMatrix.invert(&inverse)) { 164772dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com if (bounds) { 164872dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com bounds->setEmpty(); 164972dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com } 1650d9c0f0b57affec7a472879c5919acac6637d926areed@android.com return false; 1651d9c0f0b57affec7a472879c5919acac6637d926areed@android.com } 1652d9c0f0b57affec7a472879c5919acac6637d926areed@android.com 165349f085dddff10473b6ebf832a974288300224e60bsalomon if (bounds) { 1654bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com SkRect r; 16553b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com // adjust it outwards in case we are antialiasing 16563b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com const int inset = 1; 1657fa4d5bd09f8f1a4a92b5ae0324800dd672760898reed@google.com 16588f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com r.iset(ibounds.fLeft - inset, ibounds.fTop - inset, 16598f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com ibounds.fRight + inset, ibounds.fBottom + inset); 16608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inverse.mapRect(bounds, r); 16618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 16628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 16638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1665bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.combool SkCanvas::getClipDeviceBounds(SkIRect* bounds) const { 16661f836ee096bb988adef4b9757b2629c7afeda36dreed const SkRasterClip& clip = fMCRec->fRasterClip; 1667bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (clip.isEmpty()) { 1668bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com if (bounds) { 1669bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com bounds->setEmpty(); 1670bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1671bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com return false; 1672bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1673bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com 167449f085dddff10473b6ebf832a974288300224e60bsalomon if (bounds) { 1675bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com *bounds = clip.getBounds(); 1676bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com } 1677bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com return true; 1678bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com} 1679bcb671c82a7341253864cda3a5c46d396402d7fbtomhudson@google.com 16808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkMatrix& SkCanvas::getTotalMatrix() const { 16811f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fMatrix; 16828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 16838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16845c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.orgconst SkRegion& SkCanvas::internal_private_getTotalClip() const { 16851f836ee096bb988adef4b9757b2629c7afeda36dreed return fMCRec->fRasterClip.forceGetBW(); 16865c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org} 16875c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org 16889c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.comGrRenderTarget* SkCanvas::internal_private_accessTopLayerRenderTarget() { 16899c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com SkBaseDevice* dev = this->getTopDevice(); 16909c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com return dev ? dev->accessRenderTarget() : NULL; 16919c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com} 16929c135db83d198e7d8200027c7d2cf60f38517ee3reed@google.com 1693644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.orgGrContext* SkCanvas::getGrContext() { 1694644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#if SK_SUPPORT_GPU 1695644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org SkBaseDevice* device = this->getTopDevice(); 169649f085dddff10473b6ebf832a974288300224e60bsalomon if (device) { 1697644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org GrRenderTarget* renderTarget = device->accessRenderTarget(); 169849f085dddff10473b6ebf832a974288300224e60bsalomon if (renderTarget) { 1699644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org return renderTarget->getContext(); 1700644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org } 1701644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org } 1702644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org#endif 1703644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org 1704644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org return NULL; 1705644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org 1706644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org} 1707e97f0856a8044866b12527819d14cdfbcdfd96f2bsalomon@google.com 1708ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.orgvoid SkCanvas::drawDRRect(const SkRRect& outer, const SkRRect& inner, 1709ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkPaint& paint) { 17109881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawDRRect()"); 1711ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (outer.isEmpty()) { 1712ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 1713ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 1714ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (inner.isEmpty()) { 1715ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->drawRRect(outer, paint); 1716ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 1717ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 1718ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 1719ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // We don't have this method (yet), but technically this is what we should 1720ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // be able to assert... 1721ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // SkASSERT(outer.contains(inner)); 1722ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // 1723ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // For now at least check for containment of bounds 1724ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org SkASSERT(outer.getBounds().contains(inner.getBounds())); 1725ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 1726ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->onDrawDRRect(outer, inner, paint); 1727ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org} 1728ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 172941af966ab338e95eee81ab618ab28195075338f7reed// These need to stop being virtual -- clients need to override the onDraw... versions 173041af966ab338e95eee81ab618ab28195075338f7reed 173141af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawPaint(const SkPaint& paint) { 173241af966ab338e95eee81ab618ab28195075338f7reed this->onDrawPaint(paint); 173341af966ab338e95eee81ab618ab28195075338f7reed} 173441af966ab338e95eee81ab618ab28195075338f7reed 173541af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawRect(const SkRect& r, const SkPaint& paint) { 173641af966ab338e95eee81ab618ab28195075338f7reed this->onDrawRect(r, paint); 173741af966ab338e95eee81ab618ab28195075338f7reed} 173841af966ab338e95eee81ab618ab28195075338f7reed 173941af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawOval(const SkRect& r, const SkPaint& paint) { 174041af966ab338e95eee81ab618ab28195075338f7reed this->onDrawOval(r, paint); 174141af966ab338e95eee81ab618ab28195075338f7reed} 174241af966ab338e95eee81ab618ab28195075338f7reed 174341af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) { 174441af966ab338e95eee81ab618ab28195075338f7reed this->onDrawRRect(rrect, paint); 174541af966ab338e95eee81ab618ab28195075338f7reed} 174641af966ab338e95eee81ab618ab28195075338f7reed 174741af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint) { 174841af966ab338e95eee81ab618ab28195075338f7reed this->onDrawPoints(mode, count, pts, paint); 174941af966ab338e95eee81ab618ab28195075338f7reed} 175041af966ab338e95eee81ab618ab28195075338f7reed 175141af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawVertices(VertexMode vmode, int vertexCount, const SkPoint vertices[], 175241af966ab338e95eee81ab618ab28195075338f7reed const SkPoint texs[], const SkColor colors[], SkXfermode* xmode, 175341af966ab338e95eee81ab618ab28195075338f7reed const uint16_t indices[], int indexCount, const SkPaint& paint) { 175441af966ab338e95eee81ab618ab28195075338f7reed this->onDrawVertices(vmode, vertexCount, vertices, texs, colors, xmode, 175541af966ab338e95eee81ab618ab28195075338f7reed indices, indexCount, paint); 175641af966ab338e95eee81ab618ab28195075338f7reed} 175741af966ab338e95eee81ab618ab28195075338f7reed 175841af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawPath(const SkPath& path, const SkPaint& paint) { 175941af966ab338e95eee81ab618ab28195075338f7reed this->onDrawPath(path, paint); 176041af966ab338e95eee81ab618ab28195075338f7reed} 176141af966ab338e95eee81ab618ab28195075338f7reed 1762a85d4d0814818e4ddabb9237da209d61d6cd5854reedvoid SkCanvas::drawImage(const SkImage* image, SkScalar x, SkScalar y, const SkPaint* paint) { 1763a85d4d0814818e4ddabb9237da209d61d6cd5854reed this->onDrawImage(image, x, y, paint); 176441af966ab338e95eee81ab618ab28195075338f7reed} 176541af966ab338e95eee81ab618ab28195075338f7reed 176641af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, 176741af966ab338e95eee81ab618ab28195075338f7reed const SkPaint* paint) { 1768a85d4d0814818e4ddabb9237da209d61d6cd5854reed if (dst.isEmpty()) { 1769a85d4d0814818e4ddabb9237da209d61d6cd5854reed return; 1770a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 177141af966ab338e95eee81ab618ab28195075338f7reed this->onDrawImageRect(image, src, dst, paint); 177241af966ab338e95eee81ab618ab28195075338f7reed} 177341af966ab338e95eee81ab618ab28195075338f7reed 177441af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar dx, SkScalar dy, const SkPaint* paint) { 17752df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson if (bitmap.empty()) { 17762df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson return; 17772df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson } 177841af966ab338e95eee81ab618ab28195075338f7reed this->onDrawBitmap(bitmap, dx, dy, paint); 177941af966ab338e95eee81ab618ab28195075338f7reed} 178041af966ab338e95eee81ab618ab28195075338f7reed 178141af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, 178241af966ab338e95eee81ab618ab28195075338f7reed const SkPaint* paint, DrawBitmapRectFlags flags) { 17832df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson if (bitmap.empty()) { 17842df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson return; 17852df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson } 178641af966ab338e95eee81ab618ab28195075338f7reed this->onDrawBitmapRect(bitmap, src, dst, paint, flags); 178741af966ab338e95eee81ab618ab28195075338f7reed} 178841af966ab338e95eee81ab618ab28195075338f7reed 178941af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst, 179041af966ab338e95eee81ab618ab28195075338f7reed const SkPaint* paint) { 17912df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson if (bitmap.empty()) { 17922df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson return; 17932df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson } 179441af966ab338e95eee81ab618ab28195075338f7reed this->onDrawBitmapNine(bitmap, center, dst, paint); 179541af966ab338e95eee81ab618ab28195075338f7reed} 179641af966ab338e95eee81ab618ab28195075338f7reed 179741af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::drawSprite(const SkBitmap& bitmap, int left, int top, const SkPaint* paint) { 17982df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson if (bitmap.empty()) { 17992df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson return; 18002df6fd650cb12af8eeb7884b2819d2bf8ba7a5bftomhudson } 180141af966ab338e95eee81ab618ab28195075338f7reed this->onDrawSprite(bitmap, left, top, paint); 180241af966ab338e95eee81ab618ab28195075338f7reed} 180341af966ab338e95eee81ab618ab28195075338f7reed 180471c3c760a83123ee0b3127b8c65c6394ce541c50reedvoid SkCanvas::drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], 180571c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkColor colors[], int count, SkXfermode::Mode mode, 180671c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkRect* cull, const SkPaint* paint) { 180771c3c760a83123ee0b3127b8c65c6394ce541c50reed if (count <= 0) { 180871c3c760a83123ee0b3127b8c65c6394ce541c50reed return; 180971c3c760a83123ee0b3127b8c65c6394ce541c50reed } 181071c3c760a83123ee0b3127b8c65c6394ce541c50reed SkASSERT(atlas); 181171c3c760a83123ee0b3127b8c65c6394ce541c50reed SkASSERT(xform); 181271c3c760a83123ee0b3127b8c65c6394ce541c50reed SkASSERT(tex); 181371c3c760a83123ee0b3127b8c65c6394ce541c50reed this->onDrawAtlas(atlas, xform, tex, colors, count, mode, cull, paint); 181471c3c760a83123ee0b3127b8c65c6394ce541c50reed} 181571c3c760a83123ee0b3127b8c65c6394ce541c50reed 18168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 18178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// These are the virtual drawing methods 18188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 18198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 182028361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.orgvoid SkCanvas::onDiscard() { 182149f085dddff10473b6ebf832a974288300224e60bsalomon if (fSurfaceBase) { 182228361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org fSurfaceBase->aboutToDraw(SkSurface::kDiscard_ContentChangeMode); 182328361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org } 182428361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org} 182528361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org 182641af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawPaint(const SkPaint& paint) { 18279881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPaint()"); 1828fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->internalDrawPaint(paint); 1829fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com} 1830fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com 1831fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.comvoid SkCanvas::internalDrawPaint(const SkPaint& paint) { 183278cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPaint_Type, NULL) 18338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 18354e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPaint(iter, looper.paint()); 18368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18384e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 18398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 184141af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[], 184241af966ab338e95eee81ab618ab28195075338f7reed const SkPaint& paint) { 18439881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT1("disabled-by-default-skia", "SkCanvas::drawPoints()", "count", static_cast<uint64_t>(count)); 18448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if ((long)count <= 0) { 18458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 18468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 184878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect r, storage; 184978cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 1850a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com if (paint.canComputeFastBounds()) { 1851a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com // special-case 2 points (common for drawing a single line) 1852a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com if (2 == count) { 1853a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com r.set(pts[0], pts[1]); 1854a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } else { 1855a8c7f7702fb4bbedb615031bc653c5cd161a038ecommit-bot@chromium.org r.set(pts, SkToInt(count)); 1856a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } 185778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint.computeFastStrokeBounds(r, &storage); 185878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (this->quickReject(*bounds)) { 1859a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com return; 1860a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com } 1861fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 1862a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com 18638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(pts != NULL); 18648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 186578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPoint_Type, bounds) 18664b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 18678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 18684e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPoints(iter, mode, count, pts, looper.paint()); 18698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18704b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 18714e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 18728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 187441af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawRect(const SkRect& r, const SkPaint& paint) { 18759881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRect()"); 187678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 187778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 18788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.canComputeFastBounds()) { 18798432808ad8898ac7137bc7ce1d9df6005e866401reed // Skia will draw an inverted rect, because it explicitly "sorts" it downstream. 18808432808ad8898ac7137bc7ce1d9df6005e866401reed // To prevent accidental rejecting at this stage, we have to sort it before we check. 18818432808ad8898ac7137bc7ce1d9df6005e866401reed SkRect tmp(r); 18828432808ad8898ac7137bc7ce1d9df6005e866401reed tmp.sort(); 18838432808ad8898ac7137bc7ce1d9df6005e866401reed 18848432808ad8898ac7137bc7ce1d9df6005e866401reed bounds = &paint.computeFastBounds(tmp, &storage); 188578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (this->quickReject(*bounds)) { 18868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 18878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18894b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 189078cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kRect_Type, bounds) 18918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 18934e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawRect(iter, r, looper.paint()); 18948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18964e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 18978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 189941af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) { 19009881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawOval()"); 190178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 190278cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 19034ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (paint.canComputeFastBounds()) { 190478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint.computeFastBounds(oval, &storage); 190578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (this->quickReject(*bounds)) { 19064ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com return; 19074ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 19084ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 1909306ab9d5de38f2a547fd1d69aedbe69b5c6617ccskia.committer@gmail.com 191078cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, bounds) 191146d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com 191246d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com while (iter.next()) { 191346d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com iter.fDevice->drawOval(iter, oval, looper.paint()); 191446d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com } 191546d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com 191646d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com LOOPER_END 19174ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 19184ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 191941af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) { 19209881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRRect()"); 192178cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 192278cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 19234ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (paint.canComputeFastBounds()) { 192478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint.computeFastBounds(rrect.getBounds(), &storage); 192578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (this->quickReject(*bounds)) { 19264ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com return; 19274ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 19284ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 19294ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 19304ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com if (rrect.isRect()) { 19314ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com // call the non-virtual version 19324ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->SkCanvas::drawRect(rrect.getBounds(), paint); 1933f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org return; 1934f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } else if (rrect.isOval()) { 19354ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com // call the non-virtual version 1936f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org this->SkCanvas::drawOval(rrect.getBounds(), paint); 1937f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org return; 19384ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 1939f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 194078cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) 1941f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 1942f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org while (iter.next()) { 1943f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org iter.fDevice->drawRRect(iter, rrect, looper.paint()); 1944f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } 1945f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 1946f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org LOOPER_END 19474ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 19484ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 1949ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.orgvoid SkCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, 1950ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkPaint& paint) { 1951ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org SkRect storage; 1952ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkRect* bounds = NULL; 1953ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (paint.canComputeFastBounds()) { 1954ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org bounds = &paint.computeFastBounds(outer.getBounds(), &storage); 1955ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org if (this->quickReject(*bounds)) { 1956ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org return; 1957ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 1958ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 195925c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 1960ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) 196125c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 1962ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org while (iter.next()) { 1963ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org iter.fDevice->drawDRRect(iter, outer, inner, looper.paint()); 1964ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org } 196525c7127c904aa6e03209220e8ecb7128d3595f11skia.committer@gmail.com 1966ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org LOOPER_END 1967ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org} 19684ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 196941af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) { 19709881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPath()"); 19719364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com if (!path.isFinite()) { 19729364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com return; 19739364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com } 19749364511bd17d7414efc5df3ee38faa78c6f89eb1reed@google.com 197578cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 197678cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = NULL; 1977fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com if (!path.isInverseFillType() && paint.canComputeFastBounds()) { 197878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect& pathBounds = path.getBounds(); 197978cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org bounds = &paint.computeFastBounds(pathBounds, &storage); 198078cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org if (this->quickReject(*bounds)) { 19818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 19828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 19838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 19840b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org 19850b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org const SkRect& r = path.getBounds(); 19860b45dc45d67144421904555ccf53782cc8d9969dcommit-bot@chromium.org if (r.width() <= 0 && r.height() <= 0) { 19876803c219dd3be4a73e7bb5c4bb8a5b1f803624d0commit-bot@chromium.org if (path.isInverseFillType()) { 1988fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->internalDrawPaint(paint); 1989fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 1990fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com return; 1991fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 19928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 199378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, bounds) 19948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 19964e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com iter.fDevice->drawPath(iter, path, looper.paint()); 19978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 19988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19994e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 20008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 20018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2002a85d4d0814818e4ddabb9237da209d61d6cd5854reedvoid SkCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, const SkPaint* paint) { 20039881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImage()"); 2004a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkRect bounds = SkRect::MakeXYWH(x, y, 2005a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkIntToScalar(image->width()), SkIntToScalar(image->height())); 2006a85d4d0814818e4ddabb9237da209d61d6cd5854reed if (NULL == paint || paint->canComputeFastBounds()) { 2007a85d4d0814818e4ddabb9237da209d61d6cd5854reed if (paint) { 2008a85d4d0814818e4ddabb9237da209d61d6cd5854reed paint->computeFastBounds(bounds, &bounds); 2009a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2010a85d4d0814818e4ddabb9237da209d61d6cd5854reed if (this->quickReject(bounds)) { 2011a85d4d0814818e4ddabb9237da209d61d6cd5854reed return; 2012a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2013a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2014a85d4d0814818e4ddabb9237da209d61d6cd5854reed 2015a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkLazyPaint lazy; 2016a85d4d0814818e4ddabb9237da209d61d6cd5854reed if (NULL == paint) { 2017a85d4d0814818e4ddabb9237da209d61d6cd5854reed paint = lazy.init(); 2018a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2019a85d4d0814818e4ddabb9237da209d61d6cd5854reed 2020a85d4d0814818e4ddabb9237da209d61d6cd5854reed LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &bounds) 2021a85d4d0814818e4ddabb9237da209d61d6cd5854reed 2022a85d4d0814818e4ddabb9237da209d61d6cd5854reed while (iter.next()) { 2023a85d4d0814818e4ddabb9237da209d61d6cd5854reed iter.fDevice->drawImage(iter, image, x, y, looper.paint()); 2024a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2025a85d4d0814818e4ddabb9237da209d61d6cd5854reed 2026a85d4d0814818e4ddabb9237da209d61d6cd5854reed LOOPER_END 2027b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr} 2028b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 202941af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, 203041af966ab338e95eee81ab618ab28195075338f7reed const SkPaint* paint) { 20319881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawImageRect()"); 2032a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkRect storage; 2033a85d4d0814818e4ddabb9237da209d61d6cd5854reed const SkRect* bounds = &dst; 2034a85d4d0814818e4ddabb9237da209d61d6cd5854reed if (NULL == paint || paint->canComputeFastBounds()) { 2035a85d4d0814818e4ddabb9237da209d61d6cd5854reed if (paint) { 2036a85d4d0814818e4ddabb9237da209d61d6cd5854reed bounds = &paint->computeFastBounds(dst, &storage); 2037a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2038a85d4d0814818e4ddabb9237da209d61d6cd5854reed if (this->quickReject(*bounds)) { 2039a85d4d0814818e4ddabb9237da209d61d6cd5854reed return; 2040a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2041a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2042a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkLazyPaint lazy; 2043a85d4d0814818e4ddabb9237da209d61d6cd5854reed if (NULL == paint) { 2044a85d4d0814818e4ddabb9237da209d61d6cd5854reed paint = lazy.init(); 2045a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2046a85d4d0814818e4ddabb9237da209d61d6cd5854reed 2047a85d4d0814818e4ddabb9237da209d61d6cd5854reed LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) 2048a85d4d0814818e4ddabb9237da209d61d6cd5854reed 2049a85d4d0814818e4ddabb9237da209d61d6cd5854reed while (iter.next()) { 2050a85d4d0814818e4ddabb9237da209d61d6cd5854reed iter.fDevice->drawImageRect(iter, image, src, dst, looper.paint()); 2051a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 2052a85d4d0814818e4ddabb9237da209d61d6cd5854reed 2053a85d4d0814818e4ddabb9237da209d61d6cd5854reed LOOPER_END 2054b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr} 2055b5fae93d72c7b6480f83fd8a7b534cd1fdfcd49apiotaixr 205641af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y, const SkPaint* paint) { 20579881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmap()"); 20588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(bitmap.validate();) 20598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20603d60812865bb034851da777a91413ab584929887reed@google.com if (NULL == paint || paint->canComputeFastBounds()) { 20619efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com SkRect bounds = { 20629efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com x, y, 20639efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com x + SkIntToScalar(bitmap.width()), 20649efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com y + SkIntToScalar(bitmap.height()) 20659efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com }; 20669efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com if (paint) { 20679efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com (void)paint->computeFastBounds(bounds, &bounds); 20689efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com } 20693b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(bounds)) { 20708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 20718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 20728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 20734b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 20748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 20758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.setTranslate(x, y); 20769bf380ce7f848dfb5886dd52b82746521454b739robertphillips@google.com this->internalDrawBitmap(bitmap, matrix, paint); 20778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 20788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20799987ec3791336bad6af5cbe513564786b2df55aareed@google.com// this one is non-virtual, so it can be called safely by other canvas apis 20807112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.comvoid SkCanvas::internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, 2081eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org const SkRect& dst, const SkPaint* paint, 2082eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org DrawBitmapRectFlags flags) { 208350b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org if (bitmap.drawsNothing() || dst.isEmpty()) { 20848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 20858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 208674b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 208778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org SkRect storage; 208878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org const SkRect* bounds = &dst; 20893d60812865bb034851da777a91413ab584929887reed@google.com if (NULL == paint || paint->canComputeFastBounds()) { 20909efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com if (paint) { 20919efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com bounds = &paint->computeFastBounds(dst, &storage); 20929efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com } 20933b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(*bounds)) { 20943d60812865bb034851da777a91413ab584929887reed@google.com return; 20953d60812865bb034851da777a91413ab584929887reed@google.com } 20968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 20973d60812865bb034851da777a91413ab584929887reed@google.com 209833535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com SkLazyPaint lazy; 209933535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com if (NULL == paint) { 210033535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com paint = lazy.init(); 21018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 21027064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 210378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, bounds) 21047064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 210533535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com while (iter.next()) { 2106eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org iter.fDevice->drawBitmapRect(iter, bitmap, src, dst, looper.paint(), flags); 2107f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 21087064e9a3fc2fe54856d66ede84eddee2cace01b9skia.committer@gmail.com 210933535f3c48bf723c46f334a93d4a06d782dad30ereed@google.com LOOPER_END 21108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 21118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 211241af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, 211341af966ab338e95eee81ab618ab28195075338f7reed const SkPaint* paint, DrawBitmapRectFlags flags) { 21149881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmapRectToRect()"); 21159987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkDEBUGCODE(bitmap.validate();) 2116eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org this->internalDrawBitmapRect(bitmap, src, dst, paint, flags); 21179987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 21189987ec3791336bad6af5cbe513564786b2df55aareed@google.com 21199987ec3791336bad6af5cbe513564786b2df55aareed@google.comvoid SkCanvas::internalDrawBitmapNine(const SkBitmap& bitmap, 21209987ec3791336bad6af5cbe513564786b2df55aareed@google.com const SkIRect& center, const SkRect& dst, 21219987ec3791336bad6af5cbe513564786b2df55aareed@google.com const SkPaint* paint) { 212250b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org if (bitmap.drawsNothing()) { 212350b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org return; 212450b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org } 21253d60812865bb034851da777a91413ab584929887reed@google.com if (NULL == paint || paint->canComputeFastBounds()) { 212660abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com SkRect storage; 212760abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com const SkRect* bounds = &dst; 212860abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com if (paint) { 212960abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com bounds = &paint->computeFastBounds(dst, &storage); 213060abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com } 21313b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(*bounds)) { 21323d60812865bb034851da777a91413ab584929887reed@google.com return; 21333d60812865bb034851da777a91413ab584929887reed@google.com } 21343d60812865bb034851da777a91413ab584929887reed@google.com } 21353d60812865bb034851da777a91413ab584929887reed@google.com 21369987ec3791336bad6af5cbe513564786b2df55aareed@google.com const int32_t w = bitmap.width(); 21379987ec3791336bad6af5cbe513564786b2df55aareed@google.com const int32_t h = bitmap.height(); 21389987ec3791336bad6af5cbe513564786b2df55aareed@google.com 21399987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkIRect c = center; 21409987ec3791336bad6af5cbe513564786b2df55aareed@google.com // pin center to the bounds of the bitmap 21419987ec3791336bad6af5cbe513564786b2df55aareed@google.com c.fLeft = SkMax32(0, center.fLeft); 21429987ec3791336bad6af5cbe513564786b2df55aareed@google.com c.fTop = SkMax32(0, center.fTop); 21439987ec3791336bad6af5cbe513564786b2df55aareed@google.com c.fRight = SkPin32(center.fRight, c.fLeft, w); 21449987ec3791336bad6af5cbe513564786b2df55aareed@google.com c.fBottom = SkPin32(center.fBottom, c.fTop, h); 21459987ec3791336bad6af5cbe513564786b2df55aareed@google.com 21467112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com const SkScalar srcX[4] = { 21477d474f8a84a74421bd8d119124daa64ec1710f76rmistry@google.com 0, SkIntToScalar(c.fLeft), SkIntToScalar(c.fRight), SkIntToScalar(w) 21487112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com }; 21497112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com const SkScalar srcY[4] = { 21507d474f8a84a74421bd8d119124daa64ec1710f76rmistry@google.com 0, SkIntToScalar(c.fTop), SkIntToScalar(c.fBottom), SkIntToScalar(h) 21517112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com }; 21529987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkScalar dstX[4] = { 21539987ec3791336bad6af5cbe513564786b2df55aareed@google.com dst.fLeft, dst.fLeft + SkIntToScalar(c.fLeft), 21549987ec3791336bad6af5cbe513564786b2df55aareed@google.com dst.fRight - SkIntToScalar(w - c.fRight), dst.fRight 21559987ec3791336bad6af5cbe513564786b2df55aareed@google.com }; 21569987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkScalar dstY[4] = { 21579987ec3791336bad6af5cbe513564786b2df55aareed@google.com dst.fTop, dst.fTop + SkIntToScalar(c.fTop), 21589987ec3791336bad6af5cbe513564786b2df55aareed@google.com dst.fBottom - SkIntToScalar(h - c.fBottom), dst.fBottom 21599987ec3791336bad6af5cbe513564786b2df55aareed@google.com }; 216074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 21619987ec3791336bad6af5cbe513564786b2df55aareed@google.com if (dstX[1] > dstX[2]) { 21629987ec3791336bad6af5cbe513564786b2df55aareed@google.com dstX[1] = dstX[0] + (dstX[3] - dstX[0]) * c.fLeft / (w - c.width()); 21639987ec3791336bad6af5cbe513564786b2df55aareed@google.com dstX[2] = dstX[1]; 21649987ec3791336bad6af5cbe513564786b2df55aareed@google.com } 216574b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 21669987ec3791336bad6af5cbe513564786b2df55aareed@google.com if (dstY[1] > dstY[2]) { 21679987ec3791336bad6af5cbe513564786b2df55aareed@google.com dstY[1] = dstY[0] + (dstY[3] - dstY[0]) * c.fTop / (h - c.height()); 21689987ec3791336bad6af5cbe513564786b2df55aareed@google.com dstY[2] = dstY[1]; 21699987ec3791336bad6af5cbe513564786b2df55aareed@google.com } 217074b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 21719987ec3791336bad6af5cbe513564786b2df55aareed@google.com for (int y = 0; y < 3; y++) { 21727112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com SkRect s, d; 21737112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com 21749987ec3791336bad6af5cbe513564786b2df55aareed@google.com s.fTop = srcY[y]; 21759987ec3791336bad6af5cbe513564786b2df55aareed@google.com s.fBottom = srcY[y+1]; 21769987ec3791336bad6af5cbe513564786b2df55aareed@google.com d.fTop = dstY[y]; 21779987ec3791336bad6af5cbe513564786b2df55aareed@google.com d.fBottom = dstY[y+1]; 21789987ec3791336bad6af5cbe513564786b2df55aareed@google.com for (int x = 0; x < 3; x++) { 21799987ec3791336bad6af5cbe513564786b2df55aareed@google.com s.fLeft = srcX[x]; 21809987ec3791336bad6af5cbe513564786b2df55aareed@google.com s.fRight = srcX[x+1]; 21819987ec3791336bad6af5cbe513564786b2df55aareed@google.com d.fLeft = dstX[x]; 21829987ec3791336bad6af5cbe513564786b2df55aareed@google.com d.fRight = dstX[x+1]; 2183eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org this->internalDrawBitmapRect(bitmap, &s, d, paint, 218431acc11977815402e4ef2681350f8559285bec97robertphillips@google.com kNone_DrawBitmapRectFlag); 21859987ec3791336bad6af5cbe513564786b2df55aareed@google.com } 21869987ec3791336bad6af5cbe513564786b2df55aareed@google.com } 21879987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 21889987ec3791336bad6af5cbe513564786b2df55aareed@google.com 218941af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst, 219041af966ab338e95eee81ab618ab28195075338f7reed const SkPaint* paint) { 21919881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawBitmapNine()"); 21929987ec3791336bad6af5cbe513564786b2df55aareed@google.com SkDEBUGCODE(bitmap.validate();) 21939987ec3791336bad6af5cbe513564786b2df55aareed@google.com 21949987ec3791336bad6af5cbe513564786b2df55aareed@google.com // Need a device entry-point, so gpu can use a mesh 21959987ec3791336bad6af5cbe513564786b2df55aareed@google.com this->internalDrawBitmapNine(bitmap, center, dst, paint); 21969987ec3791336bad6af5cbe513564786b2df55aareed@google.com} 21979987ec3791336bad6af5cbe513564786b2df55aareed@google.com 2198f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.comclass SkDeviceFilteredPaint { 2199f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.compublic: 22001f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com SkDeviceFilteredPaint(SkBaseDevice* device, const SkPaint& paint) { 2201112e7e277702e104357f2d44742253ee1b0109acfmalita uint32_t filteredFlags = device->filterTextFlags(paint); 2202112e7e277702e104357f2d44742253ee1b0109acfmalita if (filteredFlags != paint.getFlags()) { 2203a076e9be17654a60310e72c4f70fcd5337f56dbfreed@google.com SkPaint* newPaint = fLazy.set(paint); 2204112e7e277702e104357f2d44742253ee1b0109acfmalita newPaint->setFlags(filteredFlags); 2205f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com fPaint = newPaint; 2206f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } else { 2207f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com fPaint = &paint; 2208f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } 2209f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com } 2210f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 2211f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com const SkPaint& paint() const { return *fPaint; } 2212f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 2213f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.comprivate: 22142c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org const SkPaint* fPaint; 22152c8fc5a7038cdfbb28a8364fd0057f3c21f90bfdmike@reedtribe.org SkLazyPaint fLazy; 2216f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com}; 2217f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com 221852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.comvoid SkCanvas::DrawRect(const SkDraw& draw, const SkPaint& paint, 221952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com const SkRect& r, SkScalar textSize) { 222017b78946096265d80215a6c946286ecaa35ea7edepoger@google.com if (paint.getStyle() == SkPaint::kFill_Style) { 222152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com draw.fDevice->drawRect(draw, r, paint); 222252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } else { 222352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPaint p(paint); 222417b78946096265d80215a6c946286ecaa35ea7edepoger@google.com p.setStrokeWidth(SkScalarMul(textSize, paint.getStrokeWidth())); 222552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com draw.fDevice->drawRect(draw, r, p); 222652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 222752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com} 222852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 222952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.comvoid SkCanvas::DrawTextDecorations(const SkDraw& draw, const SkPaint& paint, 223052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com const char text[], size_t byteLength, 223152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar x, SkScalar y) { 223252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkASSERT(byteLength == 0 || text != NULL); 223352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 223452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com // nothing to draw 223552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (text == NULL || byteLength == 0 || 223652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com draw.fClip->isEmpty() || 223752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com (paint.getAlpha() == 0 && paint.getXfermode() == NULL)) { 223852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com return; 223952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 224052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 224152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar width = 0; 224252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPoint start; 224352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 224452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.set(0, 0); // to avoid warning 224552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (paint.getFlags() & (SkPaint::kUnderlineText_Flag | 224652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPaint::kStrikeThruText_Flag)) { 224752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com width = paint.measureText(text, byteLength); 224852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 224952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar offsetX = 0; 225052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (paint.getTextAlign() == SkPaint::kCenter_Align) { 225152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com offsetX = SkScalarHalf(width); 225252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } else if (paint.getTextAlign() == SkPaint::kRight_Align) { 225352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com offsetX = width; 225452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 225552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.set(x - offsetX, y); 225652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 225752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 225852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (0 == width) { 225952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com return; 226052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 226152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 226252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com uint32_t flags = paint.getFlags(); 226352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 226452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (flags & (SkPaint::kUnderlineText_Flag | 226552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkPaint::kStrikeThruText_Flag)) { 226652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar textSize = paint.getTextSize(); 226752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar height = SkScalarMul(textSize, kStdUnderline_Thickness); 226852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkRect r; 226952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 227052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fLeft = start.fX; 227152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fRight = start.fX + width; 227252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 227352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (flags & SkPaint::kUnderlineText_Flag) { 227452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar offset = SkScalarMulAdd(textSize, kStdUnderline_Offset, 227552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.fY); 227652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fTop = offset; 227752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fBottom = offset + height; 227852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com DrawRect(draw, paint, r, textSize); 227952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 228052c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com if (flags & SkPaint::kStrikeThruText_Flag) { 228152c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com SkScalar offset = SkScalarMulAdd(textSize, kStdStrikeThru_Offset, 228252c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com start.fY); 228352c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fTop = offset; 228452c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com r.fBottom = offset + height; 228552c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com DrawRect(draw, paint, r, textSize); 228652c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 228752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com } 228852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com} 228952c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com 2290e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 2291e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 229278cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL) 22938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 22954e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 2296f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com iter.fDevice->drawText(iter, text, byteLength, x, y, dfp.paint()); 229752c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com DrawTextDecorations(iter, dfp.paint(), 229852c748b1691f02f90b27c35bc05074fcef709e66bungeman@google.com static_cast<const char*>(text), byteLength, x, y); 22998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23014e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 23028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2304e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], 2305e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 230605c4a4322e7d4f3417b7df33825bab8603d52051fmalita SkPoint textOffset = SkPoint::Make(0, 0); 230705c4a4322e7d4f3417b7df33825bab8603d52051fmalita 230878cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL) 230987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 23108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 23114e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 231205c4a4322e7d4f3417b7df33825bab8603d52051fmalita iter.fDevice->drawPosText(iter, text, byteLength, &pos->fX, 2, textOffset, 2313f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com dfp.paint()); 23148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2315b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 23164e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 23178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2319e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], 2320e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com SkScalar constY, const SkPaint& paint) { 232105c4a4322e7d4f3417b7df33825bab8603d52051fmalita 232205c4a4322e7d4f3417b7df33825bab8603d52051fmalita SkPoint textOffset = SkPoint::Make(0, constY); 232305c4a4322e7d4f3417b7df33825bab8603d52051fmalita 232478cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL) 232587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 23268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 23274e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 232805c4a4322e7d4f3417b7df33825bab8603d52051fmalita iter.fDevice->drawPosText(iter, text, byteLength, xpos, 1, textOffset, 2329f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com dfp.paint()); 23308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2331b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 23324e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 23338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2335e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 2336e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkMatrix* matrix, const SkPaint& paint) { 233778cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL) 233887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 23398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 23408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawTextOnPath(iter, text, byteLength, path, 23414e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com matrix, looper.paint()); 23428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2343b0430d024572b1a5e5d7b80e406c668e975e3030skia.committer@gmail.com 2344945ec3a2bec668ca845071a65df8ec55e8f43819commit-bot@chromium.org LOOPER_END 23454325d114a5679e46f25ae75b0e43547fd7694998commit-bot@chromium.org} 23464325d114a5679e46f25ae75b0e43547fd7694998commit-bot@chromium.org 234700d5c2c6523321d25b32905ff4822f083a4173eefmalitavoid SkCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 234800d5c2c6523321d25b32905ff4822f083a4173eefmalita const SkPaint& paint) { 23497ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita 235085d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita SkRect storage; 235185d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita const SkRect* bounds = NULL; 235219653d1d004610b4ba07ce563a5701164e120e45fmalita if (paint.canComputeFastBounds()) { 235385d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita storage = blob->bounds().makeOffset(x, y); 235485d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita bounds = &paint.computeFastBounds(storage, &storage); 23557ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita 235685d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita if (this->quickReject(*bounds)) { 23577ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita return; 23587ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita } 23597ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita } 23607ba7aa7e82c749b0b794f85b546f588ccf2ca777fmalita 2361024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita // We cannot filter in the looper as we normally do, because the paint is 2362024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita // incomplete at this point (text-related attributes are embedded within blob run paints). 2363024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita SkDrawFilter* drawFilter = fMCRec->fFilter; 2364024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita fMCRec->fFilter = NULL; 2365024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita 236685d5eb92940868baf8f6962dffe8ed28caa62d0dfmalita LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, bounds) 236700d5c2c6523321d25b32905ff4822f083a4173eefmalita 2368aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita while (iter.next()) { 2369aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint()); 2370024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita iter.fDevice->drawTextBlob(iter, blob, x, y, dfp.paint(), drawFilter); 237100d5c2c6523321d25b32905ff4822f083a4173eefmalita } 237200d5c2c6523321d25b32905ff4822f083a4173eefmalita 2373aa1b9120463fc69be7a5545eb83e6fbe6955a424fmalita LOOPER_END 2374024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita 2375024f996c1daac32ecad1f9ffec15f0e54fb207f4fmalita fMCRec->fFilter = drawFilter; 237600d5c2c6523321d25b32905ff4822f083a4173eefmalita} 237700d5c2c6523321d25b32905ff4822f083a4173eefmalita 2378e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com// These will become non-virtual, so they always call the (virtual) onDraw... method 2379e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 2380e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 23819881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawText()"); 2382e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawText(text, byteLength, x, y, paint); 2383e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2384e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawPosText(const void* text, size_t byteLength, const SkPoint pos[], 2385e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 23869881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPosText()"); 2387e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawPosText(text, byteLength, pos, paint); 2388e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2389e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], 2390e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com SkScalar constY, const SkPaint& paint) { 23919881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPosTextH()"); 2392e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawPosTextH(text, byteLength, xpos, constY, paint); 2393e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 2394e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkCanvas::drawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 2395e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkMatrix* matrix, const SkPaint& paint) { 23969881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextOnPath()"); 2397e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com this->onDrawTextOnPath(text, byteLength, path, matrix, paint); 2398e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com} 239900d5c2c6523321d25b32905ff4822f083a4173eefmalitavoid SkCanvas::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 240000d5c2c6523321d25b32905ff4822f083a4173eefmalita const SkPaint& paint) { 24019881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextBlob()"); 240249f085dddff10473b6ebf832a974288300224e60bsalomon if (blob) { 240300d5c2c6523321d25b32905ff4822f083a4173eefmalita this->onDrawTextBlob(blob, x, y, paint); 240400d5c2c6523321d25b32905ff4822f083a4173eefmalita } 240500d5c2c6523321d25b32905ff4822f083a4173eefmalita} 2406e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com 240741af966ab338e95eee81ab618ab28195075338f7reedvoid SkCanvas::onDrawVertices(VertexMode vmode, int vertexCount, 240841af966ab338e95eee81ab618ab28195075338f7reed const SkPoint verts[], const SkPoint texs[], 240941af966ab338e95eee81ab618ab28195075338f7reed const SkColor colors[], SkXfermode* xmode, 241041af966ab338e95eee81ab618ab28195075338f7reed const uint16_t indices[], int indexCount, 241141af966ab338e95eee81ab618ab28195075338f7reed const SkPaint& paint) { 24129881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawVertices()"); 241378cf11980d87700be0b3fded86a6d8f0d43f24d9senorblanco@chromium.org LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, NULL) 24144b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 24158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 24168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawVertices(iter, vmode, vertexCount, verts, texs, 24174e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com colors, xmode, indices, indexCount, 24184e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com looper.paint()); 24198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 24204b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 24214e2b3d3fb1288c6dc0f3ea1c0aa4a0d7c603bd7breed@google.com LOOPER_END 24228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2424b3c9d1c33caf325aada244204215eb790c228c12dandovvoid SkCanvas::drawPatch(const SkPoint cubics[12], const SkColor colors[4], 2425b3c9d1c33caf325aada244204215eb790c228c12dandov const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint) { 24269881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPatch()"); 2427b3c9d1c33caf325aada244204215eb790c228c12dandov if (NULL == cubics) { 2428b3c9d1c33caf325aada244204215eb790c228c12dandov return; 2429b3c9d1c33caf325aada244204215eb790c228c12dandov } 24306cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2431ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov // Since a patch is always within the convex hull of the control points, we discard it when its 2432ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov // bounding rectangle is completely outside the current clip. 2433ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov SkRect bounds; 2434b3c9d1c33caf325aada244204215eb790c228c12dandov bounds.set(cubics, SkPatchUtils::kNumCtrlPts); 2435ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov if (this->quickReject(bounds)) { 2436ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov return; 2437ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov } 24386cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2439b3c9d1c33caf325aada244204215eb790c228c12dandov this->onDrawPatch(cubics, colors, texCoords, xmode, paint); 2440b3c9d1c33caf325aada244204215eb790c228c12dandov} 2441b3c9d1c33caf325aada244204215eb790c228c12dandov 2442b3c9d1c33caf325aada244204215eb790c228c12dandovvoid SkCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], 2443b3c9d1c33caf325aada244204215eb790c228c12dandov const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint) { 2444b3c9d1c33caf325aada244204215eb790c228c12dandov 2445ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, NULL) 24466cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2447ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov while (iter.next()) { 2448b3c9d1c33caf325aada244204215eb790c228c12dandov iter.fDevice->drawPatch(iter, cubics, colors, texCoords, xmode, paint); 2449ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov } 24506cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 2451ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov LOOPER_END 2452ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov} 2453ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov 24543cb3840c9af6f70896cf5565a38d4ee03c02d767reedvoid SkCanvas::drawDrawable(SkDrawable* dr) { 24556be2aa9a251bf6022570a03140f956655b3ef1dareed if (dr && !this->quickReject(dr->getBounds())) { 24566be2aa9a251bf6022570a03140f956655b3ef1dareed this->onDrawDrawable(dr); 24576a070dc06af4e9f305f9d08a69e34d18ade473cbreed } 24586a070dc06af4e9f305f9d08a69e34d18ade473cbreed} 24596a070dc06af4e9f305f9d08a69e34d18ade473cbreed 24603cb3840c9af6f70896cf5565a38d4ee03c02d767reedvoid SkCanvas::onDrawDrawable(SkDrawable* dr) { 24616a070dc06af4e9f305f9d08a69e34d18ade473cbreed dr->draw(this); 24626a070dc06af4e9f305f9d08a69e34d18ade473cbreed} 24636a070dc06af4e9f305f9d08a69e34d18ade473cbreed 246471c3c760a83123ee0b3127b8c65c6394ce541c50reedvoid SkCanvas::onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], 246571c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkColor colors[], int count, SkXfermode::Mode mode, 246671c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkRect* cull, const SkPaint* paint) { 246771c3c760a83123ee0b3127b8c65c6394ce541c50reed if (cull && this->quickReject(*cull)) { 246871c3c760a83123ee0b3127b8c65c6394ce541c50reed return; 246971c3c760a83123ee0b3127b8c65c6394ce541c50reed } 247071c3c760a83123ee0b3127b8c65c6394ce541c50reed 247171c3c760a83123ee0b3127b8c65c6394ce541c50reed SkPaint pnt; 247271c3c760a83123ee0b3127b8c65c6394ce541c50reed if (paint) { 247371c3c760a83123ee0b3127b8c65c6394ce541c50reed pnt = *paint; 247471c3c760a83123ee0b3127b8c65c6394ce541c50reed } 247571c3c760a83123ee0b3127b8c65c6394ce541c50reed 247671c3c760a83123ee0b3127b8c65c6394ce541c50reed LOOPER_BEGIN(pnt, SkDrawFilter::kPath_Type, NULL) 247771c3c760a83123ee0b3127b8c65c6394ce541c50reed while (iter.next()) { 247871c3c760a83123ee0b3127b8c65c6394ce541c50reed iter.fDevice->drawAtlas(iter, atlas, xform, tex, colors, count, mode, pnt); 247971c3c760a83123ee0b3127b8c65c6394ce541c50reed } 248071c3c760a83123ee0b3127b8c65c6394ce541c50reed LOOPER_END 248171c3c760a83123ee0b3127b8c65c6394ce541c50reed} 248271c3c760a83123ee0b3127b8c65c6394ce541c50reed 24838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 24848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// These methods are NOT virtual, and therefore must call back into virtual 24858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// methods, rather than actually drawing themselves. 24868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 24878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b, 2489845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com SkXfermode::Mode mode) { 24909881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawARGB()"); 24918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 24928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setARGB(a, r, g, b); 2494845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com if (SkXfermode::kSrcOver_Mode != mode) { 24950baf19375466cfc24c96532df406e7c5b1d1aae8reed@android.com paint.setXfermodeMode(mode); 24968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 24978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPaint(paint); 24988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2500845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.comvoid SkCanvas::drawColor(SkColor c, SkXfermode::Mode mode) { 25019881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawColor()"); 25028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 25038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setColor(c); 2505845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com if (SkXfermode::kSrcOver_Mode != mode) { 25060baf19375466cfc24c96532df406e7c5b1d1aae8reed@android.com paint.setXfermodeMode(mode); 25078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 25088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPaint(paint); 25098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 25108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPoint(SkScalar x, SkScalar y, const SkPaint& paint) { 25129881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPoint(SkPaint)"); 25138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pt; 25144b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 25158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pt.set(x, y); 25168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kPoints_PointMode, 1, &pt, paint); 25178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 25188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPoint(SkScalar x, SkScalar y, SkColor color) { 25209881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPoint(SkColor)"); 25218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pt; 25228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 25234b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 25248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pt.set(x, y); 25258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setColor(color); 25268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kPoints_PointMode, 1, &pt, paint); 25278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 25288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, 25308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 25319881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawLine()"); 25328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pts[2]; 25334b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 25348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pts[0].set(x0, y0); 25358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pts[1].set(x1, y1); 25368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kLines_PointMode, 2, pts, paint); 25378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 25388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawRectCoords(SkScalar left, SkScalar top, 25408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar right, SkScalar bottom, 25418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 25429881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRectCoords()"); 25438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 25448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.set(left, top, right, bottom); 25468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawRect(r, paint); 25478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 25488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, 25508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 25519881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawCircle()"); 25528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (radius < 0) { 25538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com radius = 0; 25548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 25558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 25578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.set(cx - radius, cy - radius, cx + radius, cy + radius); 25584ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->drawOval(r, paint); 25598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 25608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawRoundRect(const SkRect& r, SkScalar rx, SkScalar ry, 25628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 25639881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawRoundRect()"); 25648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (rx > 0 && ry > 0) { 25658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.canComputeFastBounds()) { 25668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect storage; 25673b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com if (this->quickReject(paint.computeFastBounds(r, &storage))) { 25688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 25698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 25708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 25714ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com SkRRect rrect; 25724ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com rrect.setRectXY(r, rx, ry); 25734ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com this->drawRRect(rrect, paint); 25748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 25758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawRect(r, paint); 25768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 25778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 25788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawArc(const SkRect& oval, SkScalar startAngle, 25808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar sweepAngle, bool useCenter, 25818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 25829881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawArc()"); 25838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (SkScalarAbs(sweepAngle) >= SkIntToScalar(360)) { 25848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawOval(oval, paint); 25858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 25868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath path; 25878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (useCenter) { 25888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.moveTo(oval.centerX(), oval.centerY()); 25898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 25908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.arcTo(oval, startAngle, sweepAngle, !useCenter); 25918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (useCenter) { 25928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.close(); 25938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 25948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPath(path, paint); 25958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 25968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 25978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawTextOnPathHV(const void* text, size_t byteLength, 25998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPath& path, SkScalar hOffset, 26008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar vOffset, const SkPaint& paint) { 26019881d63c57002ffbdf2adf623965ece280279989danakj TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawTextOnPathHV()"); 26028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 26034b226023832011bc3bcdd1e5092ff0645ad0bdeereed@google.com 26048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.setTranslate(hOffset, vOffset); 26058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawTextOnPath(text, byteLength, path, &matrix, paint); 26068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 26078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2608f76bacff7f66724072c67edb185abf9e3add11a0reed@android.com/////////////////////////////////////////////////////////////////////////////// 26091c2c441fede0ae9573afc098017011e3439624a9reed 26101c2c441fede0ae9573afc098017011e3439624a9reed/** 26111c2c441fede0ae9573afc098017011e3439624a9reed * This constant is trying to balance the speed of ref'ing a subpicture into a parent picture, 26121c2c441fede0ae9573afc098017011e3439624a9reed * against the playback cost of recursing into the subpicture to get at its actual ops. 26131c2c441fede0ae9573afc098017011e3439624a9reed * 26141c2c441fede0ae9573afc098017011e3439624a9reed * For now we pick a conservatively small value, though measurement (and other heuristics like 26151c2c441fede0ae9573afc098017011e3439624a9reed * the type of ops contained) may justify changing this value. 26161c2c441fede0ae9573afc098017011e3439624a9reed */ 26171c2c441fede0ae9573afc098017011e3439624a9reed#define kMaxPictureOpsToUnrollInsteadOfRef 1 26189b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips 2619d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedvoid SkCanvas::drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint) { 26201c2c441fede0ae9573afc098017011e3439624a9reed TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPicture()"); 262149f085dddff10473b6ebf832a974288300224e60bsalomon if (picture) { 2622d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed if (matrix && matrix->isIdentity()) { 2623d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed matrix = NULL; 2624d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 26251c2c441fede0ae9573afc098017011e3439624a9reed if (picture->approximateOpCount() <= kMaxPictureOpsToUnrollInsteadOfRef) { 26261c2c441fede0ae9573afc098017011e3439624a9reed SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); 26271c2c441fede0ae9573afc098017011e3439624a9reed picture->playback(this); 26281c2c441fede0ae9573afc098017011e3439624a9reed } else { 26291c2c441fede0ae9573afc098017011e3439624a9reed this->onDrawPicture(picture, matrix, paint); 26301c2c441fede0ae9573afc098017011e3439624a9reed } 2631d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 2632d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 26339b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips 2634d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedvoid SkCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix, 2635d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed const SkPaint* paint) { 2636145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org SkBaseDevice* device = this->getTopDevice(); 263749f085dddff10473b6ebf832a974288300224e60bsalomon if (device) { 2638145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org // Canvas has to first give the device the opportunity to render 2639145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org // the picture itself. 2640d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed if (device->EXPERIMENTAL_drawPicture(this, picture, matrix, paint)) { 2641145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org return; // the device has rendered the entire picture 2642145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org } 2643145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org } 2644145d1c0fdcef63991d7f910cc067a653a8aa2c4ccommit-bot@chromium.org 2645a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect()); 2646c5ba71d2e5cd426def66fa49dcf003e5b2c98dc7robertphillips picture->playback(this); 26478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 26488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 26498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 26508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 26518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 26528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::LayerIter::LayerIter(SkCanvas* canvas, bool skipEmptyClips) { 2653d642329293cce602ac24df8f585c14a98795da87reed@google.com SK_COMPILE_ASSERT(sizeof(fStorage) >= sizeof(SkDrawIter), fStorage_too_small); 26548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 26558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(canvas); 26568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 26578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fImpl = new (fStorage) SkDrawIter(canvas, skipEmptyClips); 26588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDone = !fImpl->next(); 26598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 26608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 26618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::LayerIter::~LayerIter() { 26628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fImpl->~SkDrawIter(); 26638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 26648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 26658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::LayerIter::next() { 26668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDone = !fImpl->next(); 26678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 26688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 26691f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comSkBaseDevice* SkCanvas::LayerIter::device() const { 26708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fImpl->getDevice(); 26718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 26728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 26738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkMatrix& SkCanvas::LayerIter::matrix() const { 26748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fImpl->getMatrix(); 26758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 26768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 26778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkPaint& SkCanvas::LayerIter::paint() const { 26788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* paint = fImpl->getPaint(); 26798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == paint) { 26808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint = &fDefaultPaint; 26818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 26828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return *paint; 26838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 26848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 26858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkRegion& SkCanvas::LayerIter::clip() const { return fImpl->getClip(); } 26868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::LayerIter::x() const { return fImpl->getX(); } 26878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::LayerIter::y() const { return fImpl->getY(); } 268820a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com 268920a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com/////////////////////////////////////////////////////////////////////////////// 269020a550c6ea947f0ab239da1d4ecba209d76a98fdjustinlin@google.com 2691c3b589a24eb4d567a906189f882c259ecf5c2f58fmalitaSkCanvasClipVisitor::~SkCanvasClipVisitor() { } 26923107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 26933107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 26943107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 26953107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.orgstatic bool supported_for_raster_canvas(const SkImageInfo& info) { 26963107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org switch (info.alphaType()) { 26973107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kPremul_SkAlphaType: 26983107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kOpaque_SkAlphaType: 26993107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org break; 27003107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org default: 27013107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return false; 27023107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 27033107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 27043107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org switch (info.colorType()) { 27053107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kAlpha_8_SkColorType: 27063107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org case kRGB_565_SkColorType: 270728fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org case kN32_SkColorType: 27083107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org break; 27093107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org default: 27103107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return false; 27113107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org } 27123107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 27133107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org return true; 27143107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org} 27153107b6a85eee7914b37382f7145ab658e8c27667commit-bot@chromium.org 271642b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.orgSkCanvas* SkCanvas::NewRasterDirect(const SkImageInfo& info, void* pixels, size_t rowBytes) { 271742b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org if (!supported_for_raster_canvas(info)) { 271842b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org return NULL; 271942b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org } 2720eb849e5fd10cbe00cbc31307ba97fd9efca0b41bskia.committer@gmail.com 272142b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org SkBitmap bitmap; 272242b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org if (!bitmap.installPixels(info, pixels, rowBytes)) { 272342b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org return NULL; 272442b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org } 272542b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org return SkNEW_ARGS(SkCanvas, (bitmap)); 272642b08932e81abd8ebf296bede1994d297811511dcommit-bot@chromium.org} 2727d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 2728d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed/////////////////////////////////////////////////////////////////////////////// 2729d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 2730d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedSkAutoCanvasMatrixPaint::SkAutoCanvasMatrixPaint(SkCanvas* canvas, const SkMatrix* matrix, 2731a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips const SkPaint* paint, const SkRect& bounds) 2732d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed : fCanvas(canvas) 2733d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed , fSaveCount(canvas->getSaveCount()) 2734d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed{ 273549f085dddff10473b6ebf832a974288300224e60bsalomon if (paint) { 2736a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips SkRect newBounds = bounds; 2737d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed if (matrix) { 2738a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips matrix->mapRect(&newBounds); 2739d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 2740a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips canvas->saveLayer(&newBounds, paint); 274149f085dddff10473b6ebf832a974288300224e60bsalomon } else if (matrix) { 2742d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed canvas->save(); 2743d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 27446cfa73a29a26edf1d03bca224ad6860396308ffcmtklein 274549f085dddff10473b6ebf832a974288300224e60bsalomon if (matrix) { 2746d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed canvas->concat(*matrix); 2747d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 2748d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 2749d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 2750d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedSkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { 2751d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed fCanvas->restoreToCount(fSaveCount); 2752d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed} 2753