| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2008 The Android Open Source Project | 2 * Copyright 2008 The Android Open Source Project |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkCanvas.h" | 8 #include "SkCanvas.h" |
| 9 #include "SkCanvasPriv.h" | 9 #include "SkCanvasPriv.h" |
| 10 #include "SkBitmapDevice.h" | 10 #include "SkBitmapDevice.h" |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 } | 226 } |
| 227 }; | 227 }; |
| 228 | 228 |
| 229 class SkDrawIter : public SkDraw { | 229 class SkDrawIter : public SkDraw { |
| 230 public: | 230 public: |
| 231 SkDrawIter(SkCanvas* canvas, bool skipEmptyClips = true) { | 231 SkDrawIter(SkCanvas* canvas, bool skipEmptyClips = true) { |
| 232 canvas = canvas->canvasForDrawIter(); | 232 canvas = canvas->canvasForDrawIter(); |
| 233 fCanvas = canvas; | 233 fCanvas = canvas; |
| 234 canvas->updateDeviceCMCache(); | 234 canvas->updateDeviceCMCache(); |
| 235 | 235 |
| 236 fClipStack = &canvas->fClipStack; | 236 fClipStack = canvas->fClipStack; |
| 237 fCurrLayer = canvas->fMCRec->fTopLayer; | 237 fCurrLayer = canvas->fMCRec->fTopLayer; |
| 238 fSkipEmptyClips = skipEmptyClips; | 238 fSkipEmptyClips = skipEmptyClips; |
| 239 } | 239 } |
| 240 | 240 |
| 241 bool next() { | 241 bool next() { |
| 242 // skip over recs with empty clips | 242 // skip over recs with empty clips |
| 243 if (fSkipEmptyClips) { | 243 if (fSkipEmptyClips) { |
| 244 while (fCurrLayer && fCurrLayer->fClip.isEmpty()) { | 244 while (fCurrLayer && fCurrLayer->fClip.isEmpty()) { |
| 245 fCurrLayer = fCurrLayer->fNext; | 245 fCurrLayer = fCurrLayer->fNext; |
| 246 } | 246 } |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 428 SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) { | 428 SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) { |
| 429 fConservativeRasterClip = SkToBool(flags & kConservativeRasterClip_InitFlag)
; | 429 fConservativeRasterClip = SkToBool(flags & kConservativeRasterClip_InitFlag)
; |
| 430 fCachedLocalClipBounds.setEmpty(); | 430 fCachedLocalClipBounds.setEmpty(); |
| 431 fCachedLocalClipBoundsDirty = true; | 431 fCachedLocalClipBoundsDirty = true; |
| 432 fAllowSoftClip = true; | 432 fAllowSoftClip = true; |
| 433 fAllowSimplifyClip = false; | 433 fAllowSimplifyClip = false; |
| 434 fDeviceCMDirty = true; | 434 fDeviceCMDirty = true; |
| 435 fSaveCount = 1; | 435 fSaveCount = 1; |
| 436 fMetaData = NULL; | 436 fMetaData = NULL; |
| 437 | 437 |
| 438 fClipStack.reset(SkNEW(SkClipStack)); |
| 439 |
| 438 fMCRec = (MCRec*)fMCStack.push_back(); | 440 fMCRec = (MCRec*)fMCStack.push_back(); |
| 439 new (fMCRec) MCRec(fConservativeRasterClip); | 441 new (fMCRec) MCRec(fConservativeRasterClip); |
| 440 | 442 |
| 441 SkASSERT(sizeof(DeviceCM) <= sizeof(fBaseLayerStorage)); | 443 SkASSERT(sizeof(DeviceCM) <= sizeof(fBaseLayerStorage)); |
| 442 fMCRec->fLayer = (DeviceCM*)fBaseLayerStorage; | 444 fMCRec->fLayer = (DeviceCM*)fBaseLayerStorage; |
| 443 new (fBaseLayerStorage) DeviceCM(NULL, NULL, NULL, fConservativeRasterClip); | 445 new (fBaseLayerStorage) DeviceCM(NULL, NULL, NULL, fConservativeRasterClip); |
| 444 | 446 |
| 445 fMCRec->fTopLayer = fMCRec->fLayer; | 447 fMCRec->fTopLayer = fMCRec->fLayer; |
| 446 | 448 |
| 447 fSurfaceBase = NULL; | 449 fSurfaceBase = NULL; |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 732 | 734 |
| 733 ////////////////////////////////////////////////////////////////////////////// | 735 ////////////////////////////////////////////////////////////////////////////// |
| 734 | 736 |
| 735 void SkCanvas::updateDeviceCMCache() { | 737 void SkCanvas::updateDeviceCMCache() { |
| 736 if (fDeviceCMDirty) { | 738 if (fDeviceCMDirty) { |
| 737 const SkMatrix& totalMatrix = this->getTotalMatrix(); | 739 const SkMatrix& totalMatrix = this->getTotalMatrix(); |
| 738 const SkRasterClip& totalClip = fMCRec->fRasterClip; | 740 const SkRasterClip& totalClip = fMCRec->fRasterClip; |
| 739 DeviceCM* layer = fMCRec->fTopLayer; | 741 DeviceCM* layer = fMCRec->fTopLayer; |
| 740 | 742 |
| 741 if (NULL == layer->fNext) { // only one layer | 743 if (NULL == layer->fNext) { // only one layer |
| 742 layer->updateMC(totalMatrix, totalClip, fClipStack, NULL); | 744 layer->updateMC(totalMatrix, totalClip, *fClipStack, NULL); |
| 743 } else { | 745 } else { |
| 744 SkRasterClip clip(totalClip); | 746 SkRasterClip clip(totalClip); |
| 745 do { | 747 do { |
| 746 layer->updateMC(totalMatrix, clip, fClipStack, &clip); | 748 layer->updateMC(totalMatrix, clip, *fClipStack, &clip); |
| 747 } while ((layer = layer->fNext) != NULL); | 749 } while ((layer = layer->fNext) != NULL); |
| 748 } | 750 } |
| 749 fDeviceCMDirty = false; | 751 fDeviceCMDirty = false; |
| 750 } | 752 } |
| 751 } | 753 } |
| 752 | 754 |
| 753 /////////////////////////////////////////////////////////////////////////////// | 755 /////////////////////////////////////////////////////////////////////////////// |
| 754 | 756 |
| 755 void SkCanvas::checkForDeferredSave() { | 757 void SkCanvas::checkForDeferredSave() { |
| 756 if (fMCRec->fDeferredSaveCount > 0) { | 758 if (fMCRec->fDeferredSaveCount > 0) { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 813 for (int i = 0; i < n; ++i) { | 815 for (int i = 0; i < n; ++i) { |
| 814 this->restore(); | 816 this->restore(); |
| 815 } | 817 } |
| 816 } | 818 } |
| 817 | 819 |
| 818 void SkCanvas::internalSave() { | 820 void SkCanvas::internalSave() { |
| 819 MCRec* newTop = (MCRec*)fMCStack.push_back(); | 821 MCRec* newTop = (MCRec*)fMCStack.push_back(); |
| 820 new (newTop) MCRec(*fMCRec); // balanced in restore() | 822 new (newTop) MCRec(*fMCRec); // balanced in restore() |
| 821 fMCRec = newTop; | 823 fMCRec = newTop; |
| 822 | 824 |
| 823 fClipStack.save(); | 825 fClipStack->save(); |
| 824 } | 826 } |
| 825 | 827 |
| 826 static bool bounds_affects_clip(SkCanvas::SaveFlags flags) { | 828 static bool bounds_affects_clip(SkCanvas::SaveFlags flags) { |
| 827 #ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG | 829 #ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG |
| 828 return (flags & SkCanvas::kClipToLayer_SaveFlag) != 0; | 830 return (flags & SkCanvas::kClipToLayer_SaveFlag) != 0; |
| 829 #else | 831 #else |
| 830 return true; | 832 return true; |
| 831 #endif | 833 #endif |
| 832 } | 834 } |
| 833 | 835 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 858 return false; | 860 return false; |
| 859 } | 861 } |
| 860 } else { // no user bounds, so just use the clip | 862 } else { // no user bounds, so just use the clip |
| 861 ir = clipBounds; | 863 ir = clipBounds; |
| 862 } | 864 } |
| 863 SkASSERT(!ir.isEmpty()); | 865 SkASSERT(!ir.isEmpty()); |
| 864 | 866 |
| 865 if (bounds_affects_clip(flags)) { | 867 if (bounds_affects_clip(flags)) { |
| 866 // Simplify the current clips since they will be applied properly during
restore() | 868 // Simplify the current clips since they will be applied properly during
restore() |
| 867 fCachedLocalClipBoundsDirty = true; | 869 fCachedLocalClipBoundsDirty = true; |
| 868 fClipStack.clipDevRect(ir, SkRegion::kReplace_Op); | 870 fClipStack->clipDevRect(ir, SkRegion::kReplace_Op); |
| 869 fMCRec->fRasterClip.setRect(ir); | 871 fMCRec->fRasterClip.setRect(ir); |
| 870 } | 872 } |
| 871 | 873 |
| 872 if (intersection) { | 874 if (intersection) { |
| 873 *intersection = ir; | 875 *intersection = ir; |
| 874 } | 876 } |
| 875 return true; | 877 return true; |
| 876 } | 878 } |
| 877 | 879 |
| 878 int SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint) { | 880 int SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint) { |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 967 return this->saveLayer(bounds, &tmpPaint, flags); | 969 return this->saveLayer(bounds, &tmpPaint, flags); |
| 968 } | 970 } |
| 969 } | 971 } |
| 970 | 972 |
| 971 void SkCanvas::internalRestore() { | 973 void SkCanvas::internalRestore() { |
| 972 SkASSERT(fMCStack.count() != 0); | 974 SkASSERT(fMCStack.count() != 0); |
| 973 | 975 |
| 974 fDeviceCMDirty = true; | 976 fDeviceCMDirty = true; |
| 975 fCachedLocalClipBoundsDirty = true; | 977 fCachedLocalClipBoundsDirty = true; |
| 976 | 978 |
| 977 fClipStack.restore(); | 979 fClipStack->restore(); |
| 978 | 980 |
| 979 // reserve our layer (if any) | 981 // reserve our layer (if any) |
| 980 DeviceCM* layer = fMCRec->fLayer; // may be null | 982 DeviceCM* layer = fMCRec->fLayer; // may be null |
| 981 // now detach it from fMCRec so we can pop(). Gets freed after its drawn | 983 // now detach it from fMCRec so we can pop(). Gets freed after its drawn |
| 982 fMCRec->fLayer = NULL; | 984 fMCRec->fLayer = NULL; |
| 983 | 985 |
| 984 // now do the normal restore() | 986 // now do the normal restore() |
| 985 fMCRec->~MCRec(); // balanced in save() | 987 fMCRec->~MCRec(); // balanced in save() |
| 986 fMCStack.pop_back(); | 988 fMCStack.pop_back(); |
| 987 fMCRec = (MCRec*)fMCStack.back(); | 989 fMCRec = (MCRec*)fMCStack.back(); |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1254 #ifdef SK_ENABLE_CLIP_QUICKREJECT | 1256 #ifdef SK_ENABLE_CLIP_QUICKREJECT |
| 1255 if (SkRegion::kIntersect_Op == op) { | 1257 if (SkRegion::kIntersect_Op == op) { |
| 1256 if (fMCRec->fRasterClip.isEmpty()) { | 1258 if (fMCRec->fRasterClip.isEmpty()) { |
| 1257 return false; | 1259 return false; |
| 1258 } | 1260 } |
| 1259 | 1261 |
| 1260 if (this->quickReject(rect)) { | 1262 if (this->quickReject(rect)) { |
| 1261 fDeviceCMDirty = true; | 1263 fDeviceCMDirty = true; |
| 1262 fCachedLocalClipBoundsDirty = true; | 1264 fCachedLocalClipBoundsDirty = true; |
| 1263 | 1265 |
| 1264 fClipStack.clipEmpty(); | 1266 fClipStack->clipEmpty(); |
| 1265 return fMCRec->fRasterClip.setEmpty(); | 1267 return fMCRec->fRasterClip.setEmpty(); |
| 1266 } | 1268 } |
| 1267 } | 1269 } |
| 1268 #endif | 1270 #endif |
| 1269 | 1271 |
| 1270 AutoValidateClip avc(this); | 1272 AutoValidateClip avc(this); |
| 1271 | 1273 |
| 1272 fDeviceCMDirty = true; | 1274 fDeviceCMDirty = true; |
| 1273 fCachedLocalClipBoundsDirty = true; | 1275 fCachedLocalClipBoundsDirty = true; |
| 1274 if (!fAllowSoftClip) { | 1276 if (!fAllowSoftClip) { |
| 1275 edgeStyle = kHard_ClipEdgeStyle; | 1277 edgeStyle = kHard_ClipEdgeStyle; |
| 1276 } | 1278 } |
| 1277 | 1279 |
| 1278 if (fMCRec->fMatrix.rectStaysRect()) { | 1280 if (fMCRec->fMatrix.rectStaysRect()) { |
| 1279 // for these simpler matrices, we can stay a rect even after applying | 1281 // for these simpler matrices, we can stay a rect even after applying |
| 1280 // the matrix. This means we don't have to a) make a path, and b) tell | 1282 // the matrix. This means we don't have to a) make a path, and b) tell |
| 1281 // the region code to scan-convert the path, only to discover that it | 1283 // the region code to scan-convert the path, only to discover that it |
| 1282 // is really just a rect. | 1284 // is really just a rect. |
| 1283 SkRect r; | 1285 SkRect r; |
| 1284 | 1286 |
| 1285 fMCRec->fMatrix.mapRect(&r, rect); | 1287 fMCRec->fMatrix.mapRect(&r, rect); |
| 1286 fClipStack.clipDevRect(r, op, kSoft_ClipEdgeStyle == edgeStyle); | 1288 fClipStack->clipDevRect(r, op, kSoft_ClipEdgeStyle == edgeStyle); |
| 1287 fMCRec->fRasterClip.op(r, this->getBaseLayerSize(), op, kSoft_ClipEdgeSt
yle == edgeStyle); | 1289 fMCRec->fRasterClip.op(r, this->getBaseLayerSize(), op, kSoft_ClipEdgeSt
yle == edgeStyle); |
| 1288 } else { | 1290 } else { |
| 1289 // since we're rotated or some such thing, we convert the rect to a path | 1291 // since we're rotated or some such thing, we convert the rect to a path |
| 1290 // and clip against that, since it can handle any matrix. However, to | 1292 // and clip against that, since it can handle any matrix. However, to |
| 1291 // avoid recursion in the case where we are subclassed (e.g. Pictures) | 1293 // avoid recursion in the case where we are subclassed (e.g. Pictures) |
| 1292 // we explicitly call "our" version of clipPath. | 1294 // we explicitly call "our" version of clipPath. |
| 1293 SkPath path; | 1295 SkPath path; |
| 1294 | 1296 |
| 1295 path.addRect(rect); | 1297 path.addRect(rect); |
| 1296 this->SkCanvas::onClipPath(path, op, edgeStyle); | 1298 this->SkCanvas::onClipPath(path, op, edgeStyle); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1316 SkRRect transformedRRect; | 1318 SkRRect transformedRRect; |
| 1317 if (rrect.transform(fMCRec->fMatrix, &transformedRRect)) { | 1319 if (rrect.transform(fMCRec->fMatrix, &transformedRRect)) { |
| 1318 AutoValidateClip avc(this); | 1320 AutoValidateClip avc(this); |
| 1319 | 1321 |
| 1320 fDeviceCMDirty = true; | 1322 fDeviceCMDirty = true; |
| 1321 fCachedLocalClipBoundsDirty = true; | 1323 fCachedLocalClipBoundsDirty = true; |
| 1322 if (!fAllowSoftClip) { | 1324 if (!fAllowSoftClip) { |
| 1323 edgeStyle = kHard_ClipEdgeStyle; | 1325 edgeStyle = kHard_ClipEdgeStyle; |
| 1324 } | 1326 } |
| 1325 | 1327 |
| 1326 fClipStack.clipDevRRect(transformedRRect, op, kSoft_ClipEdgeStyle == edg
eStyle); | 1328 fClipStack->clipDevRRect(transformedRRect, op, kSoft_ClipEdgeStyle == ed
geStyle); |
| 1327 | 1329 |
| 1328 SkPath devPath; | 1330 SkPath devPath; |
| 1329 devPath.addRRect(transformedRRect); | 1331 devPath.addRRect(transformedRRect); |
| 1330 | 1332 |
| 1331 rasterclip_path(&fMCRec->fRasterClip, this, devPath, op, kSoft_ClipEdgeS
tyle == edgeStyle); | 1333 rasterclip_path(&fMCRec->fRasterClip, this, devPath, op, kSoft_ClipEdgeS
tyle == edgeStyle); |
| 1332 return; | 1334 return; |
| 1333 } | 1335 } |
| 1334 | 1336 |
| 1335 SkPath path; | 1337 SkPath path; |
| 1336 path.addRRect(rrect); | 1338 path.addRRect(rrect); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1353 #ifdef SK_ENABLE_CLIP_QUICKREJECT | 1355 #ifdef SK_ENABLE_CLIP_QUICKREJECT |
| 1354 if (SkRegion::kIntersect_Op == op && !path.isInverseFillType()) { | 1356 if (SkRegion::kIntersect_Op == op && !path.isInverseFillType()) { |
| 1355 if (fMCRec->fRasterClip.isEmpty()) { | 1357 if (fMCRec->fRasterClip.isEmpty()) { |
| 1356 return false; | 1358 return false; |
| 1357 } | 1359 } |
| 1358 | 1360 |
| 1359 if (this->quickReject(path.getBounds())) { | 1361 if (this->quickReject(path.getBounds())) { |
| 1360 fDeviceCMDirty = true; | 1362 fDeviceCMDirty = true; |
| 1361 fCachedLocalClipBoundsDirty = true; | 1363 fCachedLocalClipBoundsDirty = true; |
| 1362 | 1364 |
| 1363 fClipStack.clipEmpty(); | 1365 fClipStack->clipEmpty(); |
| 1364 return fMCRec->fRasterClip.setEmpty(); | 1366 return fMCRec->fRasterClip.setEmpty(); |
| 1365 } | 1367 } |
| 1366 } | 1368 } |
| 1367 #endif | 1369 #endif |
| 1368 | 1370 |
| 1369 AutoValidateClip avc(this); | 1371 AutoValidateClip avc(this); |
| 1370 | 1372 |
| 1371 fDeviceCMDirty = true; | 1373 fDeviceCMDirty = true; |
| 1372 fCachedLocalClipBoundsDirty = true; | 1374 fCachedLocalClipBoundsDirty = true; |
| 1373 if (!fAllowSoftClip) { | 1375 if (!fAllowSoftClip) { |
| 1374 edgeStyle = kHard_ClipEdgeStyle; | 1376 edgeStyle = kHard_ClipEdgeStyle; |
| 1375 } | 1377 } |
| 1376 | 1378 |
| 1377 SkPath devPath; | 1379 SkPath devPath; |
| 1378 path.transform(fMCRec->fMatrix, &devPath); | 1380 path.transform(fMCRec->fMatrix, &devPath); |
| 1379 | 1381 |
| 1380 // Check if the transfomation, or the original path itself | 1382 // Check if the transfomation, or the original path itself |
| 1381 // made us empty. Note this can also happen if we contained NaN | 1383 // made us empty. Note this can also happen if we contained NaN |
| 1382 // values. computing the bounds detects this, and will set our | 1384 // values. computing the bounds detects this, and will set our |
| 1383 // bounds to empty if that is the case. (see SkRect::set(pts, count)) | 1385 // bounds to empty if that is the case. (see SkRect::set(pts, count)) |
| 1384 if (devPath.getBounds().isEmpty()) { | 1386 if (devPath.getBounds().isEmpty()) { |
| 1385 // resetting the path will remove any NaN or other wanky values | 1387 // resetting the path will remove any NaN or other wanky values |
| 1386 // that might upset our scan converter. | 1388 // that might upset our scan converter. |
| 1387 devPath.reset(); | 1389 devPath.reset(); |
| 1388 } | 1390 } |
| 1389 | 1391 |
| 1390 // if we called path.swap() we could avoid a deep copy of this path | 1392 // if we called path.swap() we could avoid a deep copy of this path |
| 1391 fClipStack.clipDevPath(devPath, op, kSoft_ClipEdgeStyle == edgeStyle); | 1393 fClipStack->clipDevPath(devPath, op, kSoft_ClipEdgeStyle == edgeStyle); |
| 1392 | 1394 |
| 1393 if (fAllowSimplifyClip) { | 1395 if (fAllowSimplifyClip) { |
| 1394 bool clipIsAA = getClipStack()->asPath(&devPath); | 1396 bool clipIsAA = getClipStack()->asPath(&devPath); |
| 1395 if (clipIsAA) { | 1397 if (clipIsAA) { |
| 1396 edgeStyle = kSoft_ClipEdgeStyle; | 1398 edgeStyle = kSoft_ClipEdgeStyle; |
| 1397 } | 1399 } |
| 1398 | 1400 |
| 1399 op = SkRegion::kReplace_Op; | 1401 op = SkRegion::kReplace_Op; |
| 1400 } | 1402 } |
| 1401 | 1403 |
| 1402 rasterclip_path(&fMCRec->fRasterClip, this, devPath, op, edgeStyle); | 1404 rasterclip_path(&fMCRec->fRasterClip, this, devPath, op, edgeStyle); |
| 1403 } | 1405 } |
| 1404 | 1406 |
| 1405 void SkCanvas::clipRegion(const SkRegion& rgn, SkRegion::Op op) { | 1407 void SkCanvas::clipRegion(const SkRegion& rgn, SkRegion::Op op) { |
| 1406 this->checkForDeferredSave(); | 1408 this->checkForDeferredSave(); |
| 1407 this->onClipRegion(rgn, op); | 1409 this->onClipRegion(rgn, op); |
| 1408 } | 1410 } |
| 1409 | 1411 |
| 1410 void SkCanvas::onClipRegion(const SkRegion& rgn, SkRegion::Op op) { | 1412 void SkCanvas::onClipRegion(const SkRegion& rgn, SkRegion::Op op) { |
| 1411 AutoValidateClip avc(this); | 1413 AutoValidateClip avc(this); |
| 1412 | 1414 |
| 1413 fDeviceCMDirty = true; | 1415 fDeviceCMDirty = true; |
| 1414 fCachedLocalClipBoundsDirty = true; | 1416 fCachedLocalClipBoundsDirty = true; |
| 1415 | 1417 |
| 1416 // todo: signal fClipStack that we have a region, and therefore (I guess) | 1418 // todo: signal fClipStack that we have a region, and therefore (I guess) |
| 1417 // we have to ignore it, and use the region directly? | 1419 // we have to ignore it, and use the region directly? |
| 1418 fClipStack.clipDevRect(rgn.getBounds(), op); | 1420 fClipStack->clipDevRect(rgn.getBounds(), op); |
| 1419 | 1421 |
| 1420 fMCRec->fRasterClip.op(rgn, op); | 1422 fMCRec->fRasterClip.op(rgn, op); |
| 1421 } | 1423 } |
| 1422 | 1424 |
| 1423 #ifdef SK_DEBUG | 1425 #ifdef SK_DEBUG |
| 1424 void SkCanvas::validateClip() const { | 1426 void SkCanvas::validateClip() const { |
| 1425 // construct clipRgn from the clipstack | 1427 // construct clipRgn from the clipstack |
| 1426 const SkBaseDevice* device = this->getDevice(); | 1428 const SkBaseDevice* device = this->getDevice(); |
| 1427 if (!device) { | 1429 if (!device) { |
| 1428 SkASSERT(this->isClipEmpty()); | 1430 SkASSERT(this->isClipEmpty()); |
| 1429 return; | 1431 return; |
| 1430 } | 1432 } |
| 1431 | 1433 |
| 1432 SkIRect ir; | 1434 SkIRect ir; |
| 1433 ir.set(0, 0, device->width(), device->height()); | 1435 ir.set(0, 0, device->width(), device->height()); |
| 1434 SkRasterClip tmpClip(ir, fConservativeRasterClip); | 1436 SkRasterClip tmpClip(ir, fConservativeRasterClip); |
| 1435 | 1437 |
| 1436 SkClipStack::B2TIter iter(fClipStack); | 1438 SkClipStack::B2TIter iter(*fClipStack); |
| 1437 const SkClipStack::Element* element; | 1439 const SkClipStack::Element* element; |
| 1438 while ((element = iter.next()) != NULL) { | 1440 while ((element = iter.next()) != NULL) { |
| 1439 switch (element->getType()) { | 1441 switch (element->getType()) { |
| 1440 case SkClipStack::Element::kRect_Type: | 1442 case SkClipStack::Element::kRect_Type: |
| 1441 element->getRect().round(&ir); | 1443 element->getRect().round(&ir); |
| 1442 tmpClip.op(ir, element->getOp()); | 1444 tmpClip.op(ir, element->getOp()); |
| 1443 break; | 1445 break; |
| 1444 case SkClipStack::Element::kEmpty_Type: | 1446 case SkClipStack::Element::kEmpty_Type: |
| 1445 tmpClip.setEmpty(); | 1447 tmpClip.setEmpty(); |
| 1446 break; | 1448 break; |
| 1447 default: { | 1449 default: { |
| 1448 SkPath path; | 1450 SkPath path; |
| 1449 element->asPath(&path); | 1451 element->asPath(&path); |
| 1450 rasterclip_path(&tmpClip, this, path, element->getOp(), element-
>isAA()); | 1452 rasterclip_path(&tmpClip, this, path, element->getOp(), element-
>isAA()); |
| 1451 break; | 1453 break; |
| 1452 } | 1454 } |
| 1453 } | 1455 } |
| 1454 } | 1456 } |
| 1455 } | 1457 } |
| 1456 #endif | 1458 #endif |
| 1457 | 1459 |
| 1458 void SkCanvas::replayClips(ClipVisitor* visitor) const { | 1460 void SkCanvas::replayClips(ClipVisitor* visitor) const { |
| 1459 SkClipStack::B2TIter iter(fClipStack); | 1461 SkClipStack::B2TIter iter(*fClipStack); |
| 1460 const SkClipStack::Element* element; | 1462 const SkClipStack::Element* element; |
| 1461 | 1463 |
| 1462 while ((element = iter.next()) != NULL) { | 1464 while ((element = iter.next()) != NULL) { |
| 1463 element->replay(visitor); | 1465 element->replay(visitor); |
| 1464 } | 1466 } |
| 1465 } | 1467 } |
| 1466 | 1468 |
| 1467 /////////////////////////////////////////////////////////////////////////////// | 1469 /////////////////////////////////////////////////////////////////////////////// |
| 1468 | 1470 |
| 1469 bool SkCanvas::isClipEmpty() const { | 1471 bool SkCanvas::isClipEmpty() const { |
| (...skipping 1047 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2517 } | 2519 } |
| 2518 | 2520 |
| 2519 if (matrix) { | 2521 if (matrix) { |
| 2520 canvas->concat(*matrix); | 2522 canvas->concat(*matrix); |
| 2521 } | 2523 } |
| 2522 } | 2524 } |
| 2523 | 2525 |
| 2524 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { | 2526 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { |
| 2525 fCanvas->restoreToCount(fSaveCount); | 2527 fCanvas->restoreToCount(fSaveCount); |
| 2526 } | 2528 } |
| OLD | NEW |