SkCanvas.cpp revision 878999965b977c4ed771c3d655f9e23ef9b5adb1
18a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* 28a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * Copyright (C) 2006-2008 The Android Open Source Project 38a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * 48a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * Licensed under the Apache License, Version 2.0 (the "License"); 58a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * you may not use this file except in compliance with the License. 68a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * You may obtain a copy of the License at 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * http://www.apache.org/licenses/LICENSE-2.0 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * Unless required by applicable law or agreed to in writing, software 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * distributed under the License is distributed on an "AS IS" BASIS, 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * See the License for the specific language governing permissions and 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * limitations under the License. 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h" 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBounder.h" 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDevice.h" 208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDraw.h" 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDrawFilter.h" 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDrawLooper.h" 238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPicture.h" 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkScalarCompare.h" 25f76bacff7f66724072c67edb185abf9e3add11a0reed@android.com#include "SkShape.h" 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTemplates.h" 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkUtils.h" 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include <new> 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//#define SK_TRACE_SAVERESTORE 318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_TRACE_SAVERESTORE 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gLayerCounter; 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_layer() { ++gLayerCounter; printf("----- inc layer %d\n", gLayerCounter); } 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_layer() { --gLayerCounter; printf("----- dec layer %d\n", gLayerCounter); } 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gRecCounter; 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_rec() { ++gRecCounter; printf("----- inc rec %d\n", gRecCounter); } 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_rec() { --gRecCounter; printf("----- dec rec %d\n", gRecCounter); } 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static int gCanvasCounter; 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void inc_canvas() { ++gCanvasCounter; printf("----- inc canvas %d\n", gCanvasCounter); } 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void dec_canvas() { --gCanvasCounter; printf("----- dec canvas %d\n", gCanvasCounter); } 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_layer() 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_layer() 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_rec() 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_rec() 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define inc_canvas() 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define dec_canvas() 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// Helpers for computing fast bounds for quickReject tests 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkCanvas::EdgeType paint2EdgeType(const SkPaint* paint) { 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return paint != NULL && paint->isAntiAlias() ? 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkCanvas::kAA_EdgeType : SkCanvas::kBW_EdgeType; 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* This is the record we keep for each SkDevice that the user installs. 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com The clip/matrix/proc are fields that reflect the top of the save/restore 658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stack. Whenever the canvas changes, it marks a dirty flag, and then before 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com these are used (assuming we're not on a layer) we rebuild these cache 678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com values: they reflect the top of the save stack, but translated and clipped 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com by the device's XY offset and bitmap-bounds. 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct DeviceCM { 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* fNext; 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDevice* fDevice; 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRegion fClip; 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix* fMatrix; 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint* fPaint; // may be null (in the future) 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int16_t fX, fY; // relative to base matrix/clip 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM(SkDevice* device, int x, int y, const SkPaint* paint) 798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com : fNext(NULL) { 808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL != device) { 818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device->ref(); 828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device->lockPixels(); 838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDevice = device; 858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fX = SkToS16(x); 868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fY = SkToS16(y); 878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint = paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL; 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ~DeviceCM() { 918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL != fDevice) { 928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDevice->unlockPixels(); 938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDevice->unref(); 948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDELETE(fPaint); 968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void updateMC(const SkMatrix& totalMatrix, const SkRegion& totalClip, 998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRegion* updateClip) { 1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int x = fX; 1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int y = fY; 1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int width = fDevice->width(); 1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int height = fDevice->height(); 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if ((x | y) == 0) { 1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = &totalMatrix; 1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fClip = totalClip; 1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrixStorage = totalMatrix; 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrixStorage.postTranslate(SkIntToScalar(-x), 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIntToScalar(-y)); 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = &fMatrixStorage; 1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com totalClip.translate(-x, -y, &fClip); 1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fClip.op(0, 0, width, height, SkRegion::kIntersect_Op); 1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // intersect clip, but don't translate it (yet) 1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (updateClip) { 1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com updateClip->op(x, y, x + width, y + height, 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRegion::kDifference_Op); 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDevice->setMatrixClip(*fMatrix, fClip); 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!fClip.isEmpty()) { 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIRect deviceR; 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com deviceR.set(0, 0, width, height); 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(deviceR.contains(fClip.getBounds())); 1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void translateClip() { 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fX | fY) { 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fClip.translate(fX, fY); 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix fMatrixStorage; 1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* This is the record we keep for each save/restore level in the stack. 1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Since a level optionally copies the matrix and/or stack, we have pointers 1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for these fields. If the value is copied for this level, the copy is 1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stored in the ...Storage field, and the pointer points to that. If the 1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value is not copied for this level, we ignore ...Storage, and just point 1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com at the corresponding value in the previous level in the stack. 1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkCanvas::MCRec { 1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com MCRec* fNext; 1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix* fMatrix; // points to either fMatrixStorage or prev MCRec 1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRegion* fRegion; // points to either fRegionStorage or prev MCRec 1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDrawFilter* fFilter; // the current filter (or null) 1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* fLayer; 1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* If there are any layers in the stack, this points to the top-most 1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com one that is at or below this level in the stack (so we know what 1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bitmap/device to draw into from this level. This value is NOT 1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com reference counted, since the real owner is either our fLayer field, 1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com or a previous one in a lower level.) 1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* fTopLayer; 1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com MCRec(const MCRec* prev, int flags) { 1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL != prev) { 1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (flags & SkCanvas::kMatrix_SaveFlag) { 1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrixStorage = *prev->fMatrix; 1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = &fMatrixStorage; 1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = prev->fMatrix; 1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (flags & SkCanvas::kClip_SaveFlag) { 1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRegionStorage = *prev->fRegion; 1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRegion = &fRegionStorage; 1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRegion = prev->fRegion; 1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFilter = prev->fFilter; 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFilter->safeRef(); 1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTopLayer = prev->fTopLayer; 1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { // no prev 1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrixStorage.reset(); 1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = &fMatrixStorage; 1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRegion = &fRegionStorage; 1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFilter = NULL; 1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTopLayer = NULL; 1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLayer = NULL; 1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // don't bother initializing fNext 2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inc_rec(); 2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ~MCRec() { 2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFilter->safeUnref(); 2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDELETE(fLayer); 2068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dec_rec(); 2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix fMatrixStorage; 2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRegion fRegionStorage; 2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkDrawIter : public SkDraw { 2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 2168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDrawIter(SkCanvas* canvas, bool skipEmptyClips = true) { 2178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCanvas = canvas; 2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com canvas->updateDeviceCMCache(); 2198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBounder = canvas->getBounder(); 2218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = canvas->fMCRec->fTopLayer; 2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fSkipEmptyClips = skipEmptyClips; 2238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool next() { 2268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // skip over recs with empty clips 2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fSkipEmptyClips) { 2288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (fCurrLayer && fCurrLayer->fClip.isEmpty()) { 2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = fCurrLayer->fNext; 2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL != fCurrLayer) { 2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const DeviceCM* rec = fCurrLayer; 2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix = rec->fMatrix; 2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fClip = &rec->fClip; 2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDevice = rec->fDevice; 2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBitmap = &fDevice->accessBitmap(true); 2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLayerX = rec->fX; 2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLayerY = rec->fY; 2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint = rec->fPaint; 2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(this->validate();) 2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCurrLayer = rec->fNext; 2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fBounder) { 2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBounder->setClip(fClip); 2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // fCurrLayer may be NULL now 251199f108f14a5f60a9c2205ffa79b26102a206ad0reed@android.com 2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCanvas->prepareForDeviceDraw(fDevice); 2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int getX() const { return fLayerX; } 2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int getY() const { return fLayerY; } 2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDevice* getDevice() const { return fDevice; } 2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& getMatrix() const { return *fMatrix; } 2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkRegion& getClip() const { return *fClip; } 2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* getPaint() const { return fPaint; } 2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkCanvas* fCanvas; 2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const DeviceCM* fCurrLayer; 2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* fPaint; // May be null. 2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int fLayerX; 2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int fLayerY; 2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkBool8 fSkipEmptyClips; 2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef SkDraw INHERITED; 2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////// 2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass AutoDrawLooper { 2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com AutoDrawLooper(SkCanvas* canvas, const SkPaint& paint, SkDrawFilter::Type t) 2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com : fCanvas(canvas), fPaint((SkPaint*)&paint), fType(t) { 2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if ((fLooper = paint.getLooper()) != NULL) { 2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLooper->init(canvas, (SkPaint*)&paint); 2838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 2848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fOnce = true; 2858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFilter = canvas->getDrawFilter(); 2878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fNeedFilterRestore = false; 2888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ~AutoDrawLooper() { 2918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fNeedFilterRestore) { 2928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fFilter); 2938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFilter->restore(fCanvas, fPaint, fType); 2948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL != fLooper) { 2968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLooper->restore(); 2978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool next() { 3018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDrawFilter* filter = fFilter; 3028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // if we drew earlier with a filter, then we need to restore first 3048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fNeedFilterRestore) { 3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(filter); 3068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com filter->restore(fCanvas, fPaint, fType); 3078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fNeedFilterRestore = false; 3088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool result; 3118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL != fLooper) { 3138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com result = fLooper->next(); 3148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 3158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com result = fOnce; 3168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fOnce = false; 3178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // if we're gonna draw, give the filter a chance to do its work 3208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (result && NULL != filter) { 3218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fNeedFilterRestore = result = filter->filter(fCanvas, fPaint, 3228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fType); 3238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return result; 3258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 3288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDrawLooper* fLooper; 3298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDrawFilter* fFilter; 3308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkCanvas* fCanvas; 3318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint* fPaint; 3328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDrawFilter::Type fType; 3338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool fOnce; 3348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool fNeedFilterRestore; 3358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* Stack helper for managing a SkBounder. In the destructor, if we were 3398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com given a bounder, we call its commit() method, signifying that we are 3408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com done accumulating bounds for that draw. 3418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 3428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkAutoBounderCommit { 3438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 3448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAutoBounderCommit(SkBounder* bounder) : fBounder(bounder) {} 3458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ~SkAutoBounderCommit() { 3468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL != fBounder) { 3478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBounder->commit(); 3488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 3518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkBounder* fBounder; 3528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorPriv.h" 3558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass AutoValidator { 3578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 3588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com AutoValidator(SkDevice* device) : fDevice(device) {} 3598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ~AutoValidator() { 3608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 3618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkBitmap& bm = fDevice->accessBitmap(false); 3628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (bm.config() == SkBitmap::kARGB_4444_Config) { 3638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int y = 0; y < bm.height(); y++) { 3648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPMColor16* p = bm.getAddr16(0, y); 3658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int x = 0; x < bm.width(); x++) { 3668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPMColor16 c = p[x]; 3678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPMColor16Assert(c); 3688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 3728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 3748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDevice* fDevice; 3758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////// macros to place around the internal draw calls ////////////////// 3788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define ITER_BEGIN(paint, type) \ 3808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* AutoValidator validator(fMCRec->fTopLayer->fDevice); */ \ 3818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com AutoDrawLooper looper(this, paint, type); \ 3828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (looper.next()) { \ 3838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAutoBounderCommit ac(fBounder); \ 3848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDrawIter iter(this); 3858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define ITER_END } 3878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////// 3898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDevice* SkCanvas::init(SkDevice* device) { 3918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBounder = NULL; 3928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLocalBoundsCompareTypeDirty = true; 393199f108f14a5f60a9c2205ffa79b26102a206ad0reed@android.com fLastDeviceToGainFocus = NULL; 3948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = (MCRec*)fMCStack.push_back(); 3968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com new (fMCRec) MCRec(NULL, 0); 3978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fLayer = SkNEW_ARGS(DeviceCM, (NULL, 0, 0, NULL)); 3998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fTopLayer = fMCRec->fLayer; 4008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fNext = NULL; 4018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->setDevice(device); 4038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::SkCanvas(SkDevice* device) 4068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) { 4078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inc_canvas(); 4088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->init(device); 4108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::SkCanvas(const SkBitmap& bitmap) 4138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) { 4148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inc_canvas(); 4158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->init(SkNEW_ARGS(SkDevice, (bitmap)))->unref(); 4178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::~SkCanvas() { 4208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // free up the contents of our deque 4218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->restoreToCount(1); // restore everything but the last 4228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->internalRestore(); // restore the last, since we're going away 4238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBounder->safeUnref(); 4258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dec_canvas(); 4278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkBounder* SkCanvas::setBounder(SkBounder* bounder) { 4308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fBounder, bounder); 4318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return bounder; 4328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDrawFilter* SkCanvas::getDrawFilter() const { 4358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fMCRec->fFilter; 4368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDrawFilter* SkCanvas::setDrawFilter(SkDrawFilter* filter) { 4398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fMCRec->fFilter, filter); 4408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return filter; 4418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 4448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDevice* SkCanvas::getDevice() const { 4468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // return root device 4478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDeque::Iter iter(fMCStack); 4488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com MCRec* rec = (MCRec*)iter.next(); 4498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(rec && rec->fLayer); 4508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return rec->fLayer->fDevice; 4518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDevice* SkCanvas::setDevice(SkDevice* device) { 4548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // return root device 4558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDeque::Iter iter(fMCStack); 4568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com MCRec* rec = (MCRec*)iter.next(); 4578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(rec && rec->fLayer); 4588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDevice* rootDevice = rec->fLayer->fDevice; 4598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (rootDevice == device) { 4618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return device; 4628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* Notify the devices that they are going in/out of scope, so they can do 4658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com things like lock/unlock their pixels, etc. 4668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 4678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (device) { 4688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device->lockPixels(); 4698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (rootDevice) { 4718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rootDevice->unlockPixels(); 4728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(rec->fLayer->fDevice, device); 4758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rootDevice = device; 4768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 4788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* Now we update our initial region to have the bounds of the new device, 4808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com and then intersect all of the clips in our stack with these bounds, 4818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com to ensure that we can't draw outside of the device's bounds (and trash 4828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memory). 4838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com NOTE: this is only a partial-fix, since if the new device is larger than 4858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com the previous one, we don't know how to "enlarge" the clips in our stack, 4868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com so drawing may be artificially restricted. Without keeping a history of 4878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com all calls to canvas->clipRect() and canvas->clipPath(), we can't exactly 4888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com reconstruct the correct clips, so this approximation will have to do. 4898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com The caller really needs to restore() back to the base if they want to 4908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com accurately take advantage of the new device bounds. 4918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 4928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == device) { 4948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec->fRegion->setEmpty(); 4958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while ((rec = (MCRec*)iter.next()) != NULL) { 4968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (void)rec->fRegion->setEmpty(); 4978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 4998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // compute our total bounds for all devices 5008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIRect bounds; 5018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bounds.set(0, 0, device->width(), device->height()); 5038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now jam our 1st clip to be bounds, and intersect the rest with that 5058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec->fRegion->setRect(bounds); 5068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while ((rec = (MCRec*)iter.next()) != NULL) { 5078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (void)rec->fRegion->op(bounds, SkRegion::kIntersect_Op); 5088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return device; 5118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDevice* SkCanvas::setBitmapDevice(const SkBitmap& bitmap) { 5148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDevice* device = this->setDevice(SkNEW_ARGS(SkDevice, (bitmap))); 5158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device->unref(); 5168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return device; 5178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 5208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkCanvas::getViewport(SkIPoint* size) const { 5228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 5238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkCanvas::setViewport(int width, int height) { 5268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 5278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::updateDeviceCMCache() { 5308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fDeviceCMDirty) { 5318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& totalMatrix = this->getTotalMatrix(); 5328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkRegion& totalClip = this->getTotalClip(); 5338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* layer = fMCRec->fTopLayer; 5348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == layer->fNext) { // only one layer 5368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com layer->updateMC(totalMatrix, totalClip, NULL); 5378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 5388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRegion clip; 5398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com clip = totalClip; // make a copy 5408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 5418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com layer->updateMC(totalMatrix, clip, &clip); 5428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while ((layer = layer->fNext) != NULL); 5438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = false; 5458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::prepareForDeviceDraw(SkDevice* device) { 5498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(device); 550199f108f14a5f60a9c2205ffa79b26102a206ad0reed@android.com if (fLastDeviceToGainFocus != device) { 551199f108f14a5f60a9c2205ffa79b26102a206ad0reed@android.com device->gainFocus(this); 552199f108f14a5f60a9c2205ffa79b26102a206ad0reed@android.com fLastDeviceToGainFocus = device; 553199f108f14a5f60a9c2205ffa79b26102a206ad0reed@android.com } 5548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 5578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::internalSave(SaveFlags flags) { 5598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int saveCount = this->getSaveCount(); // record this before the actual save 5608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com MCRec* newTop = (MCRec*)fMCStack.push_back(); 5628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com new (newTop) MCRec(fMCRec, flags); // balanced in restore() 5638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com newTop->fNext = fMCRec; 5658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = newTop; 5668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return saveCount; 5688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::save(SaveFlags flags) { 5718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // call shared impl 5728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->internalSave(flags); 5738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define C32MASK (1 << SkBitmap::kARGB_8888_Config) 5768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define C16MASK (1 << SkBitmap::kRGB_565_Config) 5778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define C8MASK (1 << SkBitmap::kA8_Config) 5788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkBitmap::Config resolve_config(SkCanvas* canvas, 5808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkIRect& bounds, 5818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkCanvas::SaveFlags flags, 5828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool* isOpaque) { 5838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *isOpaque = (flags & SkCanvas::kHasAlphaLayer_SaveFlag) == 0; 5848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#if 0 5868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // loop through and union all the configs we may draw into 5878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint32_t configMask = 0; 5888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int i = canvas->countLayerDevices() - 1; i >= 0; --i) 5898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 5908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDevice* device = canvas->getLayerDevice(i); 5918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (device->intersects(bounds)) 5928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com configMask |= 1 << device->config(); 5938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // if the caller wants alpha or fullcolor, we can't return 565 5968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (flags & (SkCanvas::kFullColorLayer_SaveFlag | 5978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkCanvas::kHasAlphaLayer_SaveFlag)) 5988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com configMask &= ~C16MASK; 5998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com switch (configMask) { 6018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case C8MASK: // if we only have A8, return that 6028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkBitmap::kA8_Config; 6038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case C16MASK: // if we only have 565, return that 6058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkBitmap::kRGB_565_Config; 6068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com default: 6088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkBitmap::kARGB_8888_Config; // default answer 6098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 6108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else 6118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkBitmap::kARGB_8888_Config; // default answer 6128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 6138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic bool bounds_affects_clip(SkCanvas::SaveFlags flags) { 6168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (flags & SkCanvas::kClipToLayer_SaveFlag) != 0; 6178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint, 6208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SaveFlags flags) { 6218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // do this before we create the layer. We don't call the public save() since 6228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // that would invoke a possibly overridden virtual 6238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int count = this->internalSave(flags); 6248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 6268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIRect ir; 6288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkIRect& clipBounds = this->getTotalClip().getBounds(); 6298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL != bounds) { 6318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 6328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->getTotalMatrix().mapRect(&r, *bounds); 6348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.roundOut(&ir); 6358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // early exit if the layer's bounds are clipped out 6368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!ir.intersect(clipBounds)) { 6378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (bounds_affects_clip(flags)) 6388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fRegion->setEmpty(); 6398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return count; 6408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 6418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { // no user bounds, so just use the clip 6428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ir = clipBounds; 6438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 6448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // early exit if the clip is now empty 6468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (bounds_affects_clip(flags) && 6478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com !fMCRec->fRegion->op(ir, SkRegion::kIntersect_Op)) { 6488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return count; 6498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 6508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool isOpaque; 6528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkBitmap::Config config = resolve_config(this, ir, flags, &isOpaque); 6538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDevice* device = this->createDevice(config, ir.width(), ir.height(), 6558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com isOpaque, true); 6568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* layer = SkNEW_ARGS(DeviceCM, (device, ir.fLeft, ir.fTop, paint)); 6578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com device->unref(); 6588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com layer->fNext = fMCRec->fTopLayer; 6608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fLayer = layer; 6618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fTopLayer = layer; // this field is NOT an owner of layer 6628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return count; 6648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha, 6678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SaveFlags flags) { 6688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (0xFF == alpha) { 6698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->saveLayer(bounds, NULL, flags); 6708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 6718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint tmpPaint; 6728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com tmpPaint.setAlpha(alpha); 6738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->saveLayer(bounds, &tmpPaint, flags); 6748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 6758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::restore() { 6788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // check for underflow 6798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fMCStack.count() > 1) { 6808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->internalRestore(); 6818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 6828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::internalRestore() { 6858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fMCStack.count() != 0); 6868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 6888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLocalBoundsCompareTypeDirty = true; 6898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // reserve our layer (if any) 6918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com DeviceCM* layer = fMCRec->fLayer; // may be null 6928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now detach it from fMCRec so we can pop(). Gets freed after its drawn 6938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fLayer = NULL; 6948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now do the normal restore() 6968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->~MCRec(); // balanced in save() 6978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCStack.pop_back(); 6988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec = (MCRec*)fMCStack.back(); 6998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* Time to draw the layer's offscreen. We can't call the public drawSprite, 7018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com since if we're being recorded, we don't want to record this (the 7028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com recorder will have already recorded the restore). 7038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 7048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL != layer) { 7058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (layer->fNext) { 7068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawDevice(layer->fDevice, layer->fX, layer->fY, 7078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com layer->fPaint); 7088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // reset this, since drawDevice will have set it to true 7098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 7108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDELETE(layer); 7128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::getSaveCount() const { 7168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fMCStack.count(); 7178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::restoreToCount(int count) { 7208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // sanity check 7218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count < 1) { 7228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com count = 1; 7238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (fMCStack.count() > count) { 7258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->restore(); 7268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////// 7308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// can't draw it if its empty, or its too big for a fixed-point width or height 7328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic bool reject_bitmap(const SkBitmap& bitmap) { 7338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return bitmap.width() <= 0 || bitmap.height() <= 0 || 7348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bitmap.width() > 32767 || bitmap.height() > 32767; 7358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::internalDrawBitmap(const SkBitmap& bitmap, 7388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& matrix, const SkPaint* paint) { 7398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (reject_bitmap(bitmap)) { 7408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 7418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == paint) { 7448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint tmpPaint; 7458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->commonDrawBitmap(bitmap, matrix, tmpPaint); 7468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 7478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->commonDrawBitmap(bitmap, matrix, *paint); 7488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawDevice(SkDevice* device, int x, int y, 7528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* paint) { 7538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint tmp; 7548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == paint) { 7558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com tmp.setDither(true); 7568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint = &tmp; 7578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ITER_BEGIN(*paint, SkDrawFilter::kBitmap_Type) 7608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 7618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawDevice(iter, device, x - iter.getX(), y - iter.getY(), 7628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *paint); 7638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ITER_END 7658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////// 7688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkCanvas::translate(SkScalar dx, SkScalar dy) { 7708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 7718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLocalBoundsCompareTypeDirty = true; 7728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fMCRec->fMatrix->preTranslate(dx, dy); 7738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkCanvas::scale(SkScalar sx, SkScalar sy) { 7768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 7778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLocalBoundsCompareTypeDirty = true; 7788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fMCRec->fMatrix->preScale(sx, sy); 7798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkCanvas::rotate(SkScalar degrees) { 7828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 7838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLocalBoundsCompareTypeDirty = true; 7848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fMCRec->fMatrix->preRotate(degrees); 7858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkCanvas::skew(SkScalar sx, SkScalar sy) { 7888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 7898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLocalBoundsCompareTypeDirty = true; 7908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fMCRec->fMatrix->preSkew(sx, sy); 7918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkCanvas::concat(const SkMatrix& matrix) { 7948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 7958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLocalBoundsCompareTypeDirty = true; 7968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fMCRec->fMatrix->preConcat(matrix); 7978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::setMatrix(const SkMatrix& matrix) { 8008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 8018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLocalBoundsCompareTypeDirty = true; 8028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *fMCRec->fMatrix = matrix; 8038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// this is not virtual, so it must call a virtual method so that subclasses 8068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// will see its action 8078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::resetMatrix() { 8088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 8098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.reset(); 8118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->setMatrix(matrix); 8128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 8158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkCanvas::clipRect(const SkRect& rect, SkRegion::Op op) { 8178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 8188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLocalBoundsCompareTypeDirty = true; 8198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fMCRec->fMatrix->rectStaysRect()) { 82198de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // for these simpler matrices, we can stay a rect ever after applying 82298de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // the matrix. This means we don't have to a) make a path, and b) tell 82398de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // the region code to scan-convert the path, only to discover that it 82498de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // is really just a rect. 8258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 8268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIRect ir; 8278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMCRec->fMatrix->mapRect(&r, rect); 8298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.round(&ir); 8308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fMCRec->fRegion->op(ir, op); 8318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 83298de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // since we're rotate or some such thing, we convert the rect to a path 83398de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // and clip against that, since it can handle any matrix. However, to 83498de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // avoid recursion in the case where we are subclassed (e.g. Pictures) 83598de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com // we explicitly call "our" version of clipPath. 8368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath path; 8378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.addRect(rect); 83998de2bdbd12a01aaf347ca2549801b5940613f3freed@android.com return this->SkCanvas::clipPath(path, op); 8408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkCanvas::clipPath(const SkPath& path, SkRegion::Op op) { 8448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 8458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLocalBoundsCompareTypeDirty = true; 8468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath devPath; 8488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.transform(*fMCRec->fMatrix, &devPath); 8498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (SkRegion::kIntersect_Op == op) { 8518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fMCRec->fRegion->setPath(devPath, *fMCRec->fRegion); 8528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 8538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRegion base; 8548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkBitmap& bm = this->getDevice()->accessBitmap(false); 8558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com base.setRect(0, 0, bm.width(), bm.height()); 8568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (SkRegion::kReplace_Op == op) { 8588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fMCRec->fRegion->setPath(devPath, base); 8598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 8608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRegion rgn; 8618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rgn.setPath(devPath, base); 8628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fMCRec->fRegion->op(rgn, op); 8638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkCanvas::clipRegion(const SkRegion& rgn, SkRegion::Op op) { 8688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDeviceCMDirty = true; 8698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLocalBoundsCompareTypeDirty = true; 8708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fMCRec->fRegion->op(rgn, op); 8728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::computeLocalClipBoundsCompareType() const { 8758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 8768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!this->getClipBounds(&r, kAA_EdgeType)) { 8788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLocalBoundsCompareType.setEmpty(); 8798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 8808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLocalBoundsCompareType.set(SkScalarToCompareType(r.fLeft), 8818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalarToCompareType(r.fTop), 8828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalarToCompareType(r.fRight), 8838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalarToCompareType(r.fBottom)); 8848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 887d252db03d9650013b545ef9781fe993c07f8f314reed@android.com/* current impl ignores edgetype, and relies on 888d252db03d9650013b545ef9781fe993c07f8f314reed@android.com getLocalClipBoundsCompareType(), which always returns a value assuming 889d252db03d9650013b545ef9781fe993c07f8f314reed@android.com antialiasing (worst case) 890d252db03d9650013b545ef9781fe993c07f8f314reed@android.com */ 8918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkCanvas::quickReject(const SkRect& rect, EdgeType) const { 8928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fMCRec->fRegion->isEmpty()) { 8938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 8948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 896a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com if (fMCRec->fMatrix->getType() & SkMatrix::kPerspective_Mask) { 897a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com SkRect dst; 898a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com fMCRec->fMatrix->mapRect(&dst, rect); 899a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com SkIRect idst; 900a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com dst.roundOut(&idst); 901a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com return !SkIRect::Intersects(idst, fMCRec->fRegion->getBounds()); 902a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com } else { 903a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com const SkRectCompareType& clipR = this->getLocalClipBoundsCompareType(); 904d252db03d9650013b545ef9781fe993c07f8f314reed@android.com 905a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com // for speed, do the most likely reject compares first 906a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com SkScalarCompareType userT = SkScalarToCompareType(rect.fTop); 907a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com SkScalarCompareType userB = SkScalarToCompareType(rect.fBottom); 908a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com if (userT >= clipR.fBottom || userB <= clipR.fTop) { 909a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com return true; 910a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com } 911a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com SkScalarCompareType userL = SkScalarToCompareType(rect.fLeft); 912a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com SkScalarCompareType userR = SkScalarToCompareType(rect.fRight); 913a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com if (userL >= clipR.fRight || userR <= clipR.fLeft) { 914a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com return true; 915a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com } 916a380ae4a9ac209f5676c06aeaceacc1b08817edareed@android.com return false; 9178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkCanvas::quickReject(const SkPath& path, EdgeType et) const { 921d252db03d9650013b545ef9781fe993c07f8f314reed@android.com return path.isEmpty() || this->quickReject(path.getBounds(), et); 9228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkCanvas::quickRejectY(SkScalar top, SkScalar bottom, EdgeType et) const { 9258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* current impl ignores edgetype, and relies on 9268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com getLocalClipBoundsCompareType(), which always returns a value assuming 9278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com antialiasing (worst case) 9288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 9298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fMCRec->fRegion->isEmpty()) { 9318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 9328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 934aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com SkScalarCompareType userT = SkScalarToCompareType(top); 935aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com SkScalarCompareType userB = SkScalarToCompareType(bottom); 9368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // check for invalid user Y coordinates (i.e. empty) 938d252db03d9650013b545ef9781fe993c07f8f314reed@android.com // reed: why do we need to do this check, since it slows us down? 9398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (userT >= userB) { 9408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 9418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // check if we are above or below the local clip bounds 9448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkRectCompareType& clipR = this->getLocalClipBoundsCompareType(); 9458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return userT >= clipR.fBottom || userB <= clipR.fTop; 9468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkCanvas::getClipBounds(SkRect* bounds, EdgeType et) const { 9498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkRegion& clip = *fMCRec->fRegion; 9508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (clip.isEmpty()) { 9518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (bounds) { 9528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bounds->setEmpty(); 9538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 9558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 957d9c0f0b57affec7a472879c5919acac6637d926areed@android.com SkMatrix inverse; 958d9c0f0b57affec7a472879c5919acac6637d926areed@android.com // if we can't invert the CTM, we can't return local clip bounds 959d9c0f0b57affec7a472879c5919acac6637d926areed@android.com if (!fMCRec->fMatrix->invert(&inverse)) { 96072dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com if (bounds) { 96172dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com bounds->setEmpty(); 96272dcd3a3c16a68f98bc345a4263678d43bc3daebreed@android.com } 963d9c0f0b57affec7a472879c5919acac6637d926areed@android.com return false; 964d9c0f0b57affec7a472879c5919acac6637d926areed@android.com } 965d9c0f0b57affec7a472879c5919acac6637d926areed@android.com 9668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL != bounds) { 9678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 9688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // get the clip's bounds 9698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkIRect& ibounds = clip.getBounds(); 9708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // adjust it outwards if we are antialiasing 9718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int inset = (kAA_EdgeType == et); 9728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.iset(ibounds.fLeft - inset, ibounds.fTop - inset, 9738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ibounds.fRight + inset, ibounds.fBottom + inset); 9748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // invert into local coordinates 9768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inverse.mapRect(bounds, r); 9778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 9798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkMatrix& SkCanvas::getTotalMatrix() const { 9828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return *fMCRec->fMatrix; 9838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkRegion& SkCanvas::getTotalClip() const { 9868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return *fMCRec->fRegion; 9878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 9908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDevice* SkCanvas::createDevice(SkBitmap::Config config, int width, 9928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int height, bool isOpaque, bool isForLayer) { 9938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkBitmap bitmap; 9948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bitmap.setConfig(config, width, height); 9968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bitmap.setIsOpaque(isOpaque); 9978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // should this happen in the device subclass? 9998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bitmap.allocPixels(); 10008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!bitmap.isOpaque()) { 10018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bitmap.eraseARGB(0, 0, 0, 0); 10028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkNEW_ARGS(SkDevice, (bitmap)); 10058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 10088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// These are the virtual drawing methods 10098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 10108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPaint(const SkPaint& paint) { 10128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ITER_BEGIN(paint, SkDrawFilter::kPaint_Type) 10138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 10158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawPaint(iter, paint); 10168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ITER_END 10198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPoints(PointMode mode, size_t count, const SkPoint pts[], 10228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 10238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if ((long)count <= 0) { 10248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 10258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(pts != NULL); 10288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ITER_BEGIN(paint, SkDrawFilter::kPoint_Type) 10308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 10328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawPoints(iter, mode, count, pts, paint); 10338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ITER_END 10368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawRect(const SkRect& r, const SkPaint& paint) { 10398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.canComputeFastBounds()) { 10408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect storage; 10418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (this->quickReject(paint.computeFastBounds(r, &storage), 10428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint2EdgeType(&paint))) { 10438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 10448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ITER_BEGIN(paint, SkDrawFilter::kRect_Type) 10488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 10508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawRect(iter, r, paint); 10518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ITER_END 10548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPath(const SkPath& path, const SkPaint& paint) { 10578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.canComputeFastBounds()) { 1058d252db03d9650013b545ef9781fe993c07f8f314reed@android.com SkRect storage; 1059d252db03d9650013b545ef9781fe993c07f8f314reed@android.com const SkRect& bounds = path.getBounds(); 1060d252db03d9650013b545ef9781fe993c07f8f314reed@android.com if (this->quickReject(paint.computeFastBounds(bounds, &storage), 10618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint2EdgeType(&paint))) { 10628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 10638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ITER_BEGIN(paint, SkDrawFilter::kPath_Type) 10678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 10698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawPath(iter, path, paint); 10708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ITER_END 10738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y, 10768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* paint) { 10778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(bitmap.validate();) 10788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == paint || (paint->getMaskFilter() == NULL)) { 10808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect fastBounds; 10818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fastBounds.set(x, y, 10828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x + SkIntToScalar(bitmap.width()), 10838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com y + SkIntToScalar(bitmap.height())); 10848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (this->quickReject(fastBounds, paint2EdgeType(paint))) { 10858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 10868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 10908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.setTranslate(x, y); 10918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->internalDrawBitmap(bitmap, matrix, paint); 10928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src, 10958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkRect& dst, const SkPaint* paint) { 10968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (bitmap.width() == 0 || bitmap.height() == 0 || dst.isEmpty()) { 10978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 10988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // do this now, to avoid the cost of calling extract for RLE bitmaps 11018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (this->quickReject(dst, paint2EdgeType(paint))) { 11028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 11038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkBitmap tmp; // storage if we need a subset of bitmap 11068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkBitmap* bitmapPtr = &bitmap; 11078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL != src) { 11098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!bitmap.extractSubset(&tmp, *src)) { 11108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; // extraction failed 11118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bitmapPtr = &tmp; 11138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 1116878999965b977c4ed771c3d655f9e23ef9b5adb1reed@android.com SkRect tmpSrc; 1117878999965b977c4ed771c3d655f9e23ef9b5adb1reed@android.com if (src) { 1118878999965b977c4ed771c3d655f9e23ef9b5adb1reed@android.com tmpSrc.set(*src); 1119878999965b977c4ed771c3d655f9e23ef9b5adb1reed@android.com // if the extract process clipped off the top or left of the 1120878999965b977c4ed771c3d655f9e23ef9b5adb1reed@android.com // original, we adjust for that here to get the position right. 1121878999965b977c4ed771c3d655f9e23ef9b5adb1reed@android.com if (tmpSrc.fLeft > 0) { 1122878999965b977c4ed771c3d655f9e23ef9b5adb1reed@android.com tmpSrc.fRight -= tmpSrc.fLeft; 1123878999965b977c4ed771c3d655f9e23ef9b5adb1reed@android.com tmpSrc.fLeft = 0; 1124fead49e3c43e67cf9648ec1999b34da959e1e36breed@android.com } 1125878999965b977c4ed771c3d655f9e23ef9b5adb1reed@android.com if (tmpSrc.fTop > 0) { 1126878999965b977c4ed771c3d655f9e23ef9b5adb1reed@android.com tmpSrc.fBottom -= tmpSrc.fTop; 1127878999965b977c4ed771c3d655f9e23ef9b5adb1reed@android.com tmpSrc.fTop = 0; 1128878999965b977c4ed771c3d655f9e23ef9b5adb1reed@android.com } 1129878999965b977c4ed771c3d655f9e23ef9b5adb1reed@android.com } else { 1130878999965b977c4ed771c3d655f9e23ef9b5adb1reed@android.com tmpSrc.set(0, 0, SkIntToScalar(bitmap.width()), 1131878999965b977c4ed771c3d655f9e23ef9b5adb1reed@android.com SkIntToScalar(bitmap.height())); 11328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1133878999965b977c4ed771c3d655f9e23ef9b5adb1reed@android.com matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit); 11348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->internalDrawBitmap(*bitmapPtr, matrix, paint); 11358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 11368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& matrix, 11388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* paint) { 11398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(bitmap.validate();) 11408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->internalDrawBitmap(bitmap, matrix, paint); 11418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 11428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::commonDrawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix, 11448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 11458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(bitmap.validate();) 11469b0390626f73cc88c05c90de64bfe0481e808f14reed@android.com 11478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ITER_BEGIN(paint, SkDrawFilter::kBitmap_Type) 11489b0390626f73cc88c05c90de64bfe0481e808f14reed@android.com 11498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 11508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawBitmap(iter, bitmap, matrix, paint); 11518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11529b0390626f73cc88c05c90de64bfe0481e808f14reed@android.com 11538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ITER_END 11548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 11558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawSprite(const SkBitmap& bitmap, int x, int y, 11578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* paint) { 11588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(bitmap.validate();) 11598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (reject_bitmap(bitmap)) { 11618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 11628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint tmp; 11658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == paint) { 11668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint = &tmp; 11678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ITER_BEGIN(*paint, SkDrawFilter::kBitmap_Type) 11708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 11728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawSprite(iter, bitmap, x - iter.getX(), y - iter.getY(), 11738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *paint); 11748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ITER_END 11768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 11778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawText(const void* text, size_t byteLength, 11798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar x, SkScalar y, const SkPaint& paint) { 11808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ITER_BEGIN(paint, SkDrawFilter::kText_Type) 11818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 11838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawText(iter, text, byteLength, x, y, paint); 11848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ITER_END 11878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 11888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPosText(const void* text, size_t byteLength, 11908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPoint pos[], const SkPaint& paint) { 11918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ITER_BEGIN(paint, SkDrawFilter::kText_Type) 11928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 11948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawPosText(iter, text, byteLength, &pos->fX, 0, 2, 11958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint); 11968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ITER_END 11998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPosTextH(const void* text, size_t byteLength, 12028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkScalar xpos[], SkScalar constY, 12038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 12048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ITER_BEGIN(paint, SkDrawFilter::kText_Type) 12058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 12078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawPosText(iter, text, byteLength, xpos, constY, 1, 12088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint); 12098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ITER_END 12128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawTextOnPath(const void* text, size_t byteLength, 12158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPath& path, const SkMatrix* matrix, 12168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 12178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ITER_BEGIN(paint, SkDrawFilter::kText_Type) 12188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 12208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawTextOnPath(iter, text, byteLength, path, 12218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix, paint); 12228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ITER_END 12258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawVertices(VertexMode vmode, int vertexCount, 12288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPoint verts[], const SkPoint texs[], 12298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkColor colors[], SkXfermode* xmode, 12308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint16_t indices[], int indexCount, 12318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 12328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ITER_BEGIN(paint, SkDrawFilter::kPath_Type) 12338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next()) { 12358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com iter.fDevice->drawVertices(iter, vmode, vertexCount, verts, texs, 12368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com colors, xmode, indices, indexCount, paint); 12378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ITER_END 12408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 12438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// These methods are NOT virtual, and therefore must call back into virtual 12448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// methods, rather than actually drawing themselves. 12458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 12468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b, 1248845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com SkXfermode::Mode mode) { 12498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 12508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setARGB(a, r, g, b); 1252845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com if (SkXfermode::kSrcOver_Mode != mode) { 12530baf19375466cfc24c96532df406e7c5b1d1aae8reed@android.com paint.setXfermodeMode(mode); 12548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPaint(paint); 12568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1258845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.comvoid SkCanvas::drawColor(SkColor c, SkXfermode::Mode mode) { 12598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 12608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setColor(c); 1262845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com if (SkXfermode::kSrcOver_Mode != mode) { 12630baf19375466cfc24c96532df406e7c5b1d1aae8reed@android.com paint.setXfermodeMode(mode); 12648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPaint(paint); 12668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPoint(SkScalar x, SkScalar y, const SkPaint& paint) { 12698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pt; 12708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pt.set(x, y); 12728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kPoints_PointMode, 1, &pt, paint); 12738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPoint(SkScalar x, SkScalar y, SkColor color) { 12768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pt; 12778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 12788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pt.set(x, y); 12808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setColor(color); 12818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kPoints_PointMode, 1, &pt, paint); 12828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, 12858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 12868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pts[2]; 12878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pts[0].set(x0, y0); 12898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pts[1].set(x1, y1); 12908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPoints(kLines_PointMode, 2, pts, paint); 12918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawRectCoords(SkScalar left, SkScalar top, 12948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar right, SkScalar bottom, 12958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 12968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 12978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.set(left, top, right, bottom); 12998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawRect(r, paint); 13008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, 13038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 13048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (radius < 0) { 13058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com radius = 0; 13068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect r; 13098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r.set(cx - radius, cy - radius, cx + radius, cy + radius); 13108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.canComputeFastBounds()) { 13128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect storage; 13138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (this->quickReject(paint.computeFastBounds(r, &storage), 13148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint2EdgeType(&paint))) { 13158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 13168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath path; 13208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.addOval(r); 13218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPath(path, paint); 13228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawRoundRect(const SkRect& r, SkScalar rx, SkScalar ry, 13258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 13268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (rx > 0 && ry > 0) { 13278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.canComputeFastBounds()) { 13288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect storage; 13298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (this->quickReject(paint.computeFastBounds(r, &storage), 13308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint2EdgeType(&paint))) { 13318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 13328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath path; 13368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.addRoundRect(r, rx, ry, SkPath::kCW_Direction); 13378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPath(path, paint); 13388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 13398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawRect(r, paint); 13408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawOval(const SkRect& oval, const SkPaint& paint) { 13448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (paint.canComputeFastBounds()) { 13458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect storage; 13468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (this->quickReject(paint.computeFastBounds(oval, &storage), 13478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint2EdgeType(&paint))) { 13488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 13498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath path; 13538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.addOval(oval); 13548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPath(path, paint); 13558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawArc(const SkRect& oval, SkScalar startAngle, 13588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar sweepAngle, bool useCenter, 13598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint) { 13608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (SkScalarAbs(sweepAngle) >= SkIntToScalar(360)) { 13618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawOval(oval, paint); 13628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 13638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath path; 13648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (useCenter) { 13658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.moveTo(oval.centerX(), oval.centerY()); 13668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.arcTo(oval, startAngle, sweepAngle, !useCenter); 13688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (useCenter) { 13698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.close(); 13708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPath(path, paint); 13728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawTextOnPathHV(const void* text, size_t byteLength, 13768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPath& path, SkScalar hOffset, 13778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar vOffset, const SkPaint& paint) { 13788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 13798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.setTranslate(hOffset, vOffset); 13818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawTextOnPath(text, byteLength, path, &matrix, paint); 13828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1384f76bacff7f66724072c67edb185abf9e3add11a0reed@android.com/////////////////////////////////////////////////////////////////////////////// 1385f76bacff7f66724072c67edb185abf9e3add11a0reed@android.com 13868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::drawPicture(SkPicture& picture) { 13878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int saveCount = save(); 13888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com picture.draw(this); 13898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com restoreToCount(saveCount); 13908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1392f76bacff7f66724072c67edb185abf9e3add11a0reed@android.comvoid SkCanvas::drawShape(SkShape* shape) { 1393f76bacff7f66724072c67edb185abf9e3add11a0reed@android.com // shape baseclass takes care of save/restore 1394f76bacff7f66724072c67edb185abf9e3add11a0reed@android.com shape->draw(this); 1395f76bacff7f66724072c67edb185abf9e3add11a0reed@android.com} 1396f76bacff7f66724072c67edb185abf9e3add11a0reed@android.com 13978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 13988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 13998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::LayerIter::LayerIter(SkCanvas* canvas, bool skipEmptyClips) { 14018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // need COMPILE_TIME_ASSERT 14028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(sizeof(fStorage) >= sizeof(SkDrawIter)); 14038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(canvas); 14058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fImpl = new (fStorage) SkDrawIter(canvas, skipEmptyClips); 14078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDone = !fImpl->next(); 14088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas::LayerIter::~LayerIter() { 14118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fImpl->~SkDrawIter(); 14128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkCanvas::LayerIter::next() { 14158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDone = !fImpl->next(); 14168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDevice* SkCanvas::LayerIter::device() const { 14198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fImpl->getDevice(); 14208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkMatrix& SkCanvas::LayerIter::matrix() const { 14238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fImpl->getMatrix(); 14248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkPaint& SkCanvas::LayerIter::paint() const { 14278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint* paint = fImpl->getPaint(); 14288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == paint) { 14298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint = &fDefaultPaint; 14308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 14318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return *paint; 14328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkRegion& SkCanvas::LayerIter::clip() const { return fImpl->getClip(); } 14358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::LayerIter::x() const { return fImpl->getX(); } 14368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkCanvas::LayerIter::y() const { return fImpl->getY(); } 14378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1438