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 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 values: they reflect the top of the save stack, but translated and clipped | 108 values: they reflect the top of the save stack, but translated and clipped |
109 by the device's XY offset and bitmap-bounds. | 109 by the device's XY offset and bitmap-bounds. |
110 */ | 110 */ |
111 struct DeviceCM { | 111 struct DeviceCM { |
112 DeviceCM* fNext; | 112 DeviceCM* fNext; |
113 SkBaseDevice* fDevice; | 113 SkBaseDevice* fDevice; |
114 SkRasterClip fClip; | 114 SkRasterClip fClip; |
115 SkPaint* fPaint; // may be null (in the future) | 115 SkPaint* fPaint; // may be null (in the future) |
116 const SkMatrix* fMatrix; | 116 const SkMatrix* fMatrix; |
117 SkMatrix fMatrixStorage; | 117 SkMatrix fMatrixStorage; |
| 118 SkMatrix fStashedMatrix; // Original CTM; used by imageFilter at
saveLayer time |
118 const bool fDeviceIsBitmapDevice; | 119 const bool fDeviceIsBitmapDevice; |
119 | 120 |
120 DeviceCM(SkBaseDevice* device, const SkPaint* paint, SkCanvas* canvas, | 121 DeviceCM(SkBaseDevice* device, const SkPaint* paint, SkCanvas* canvas, |
121 bool conservativeRasterClip, bool deviceIsBitmapDevice) | 122 bool conservativeRasterClip, bool deviceIsBitmapDevice, const SkMat
rix& stashed) |
122 : fNext(NULL) | 123 : fNext(NULL) |
123 , fClip(conservativeRasterClip) | 124 , fClip(conservativeRasterClip) |
| 125 , fStashedMatrix(stashed) |
124 , fDeviceIsBitmapDevice(deviceIsBitmapDevice) | 126 , fDeviceIsBitmapDevice(deviceIsBitmapDevice) |
125 { | 127 { |
126 if (NULL != device) { | 128 if (NULL != device) { |
127 device->ref(); | 129 device->ref(); |
128 device->onAttachToCanvas(canvas); | 130 device->onAttachToCanvas(canvas); |
129 } | 131 } |
130 fDevice = device; | 132 fDevice = device; |
131 fPaint = paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL; | 133 fPaint = paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL; |
132 } | 134 } |
133 | 135 |
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
521 fSaveCount = 1; | 523 fSaveCount = 1; |
522 fMetaData = NULL; | 524 fMetaData = NULL; |
523 | 525 |
524 fClipStack.reset(SkNEW(SkClipStack)); | 526 fClipStack.reset(SkNEW(SkClipStack)); |
525 | 527 |
526 fMCRec = (MCRec*)fMCStack.push_back(); | 528 fMCRec = (MCRec*)fMCStack.push_back(); |
527 new (fMCRec) MCRec(fConservativeRasterClip); | 529 new (fMCRec) MCRec(fConservativeRasterClip); |
528 | 530 |
529 SkASSERT(sizeof(DeviceCM) <= sizeof(fDeviceCMStorage)); | 531 SkASSERT(sizeof(DeviceCM) <= sizeof(fDeviceCMStorage)); |
530 fMCRec->fLayer = (DeviceCM*)fDeviceCMStorage; | 532 fMCRec->fLayer = (DeviceCM*)fDeviceCMStorage; |
531 new (fDeviceCMStorage) DeviceCM(NULL, NULL, NULL, fConservativeRasterClip, f
alse); | 533 new (fDeviceCMStorage) DeviceCM(NULL, NULL, NULL, fConservativeRasterClip, f
alse, |
| 534 fMCRec->fMatrix); |
532 | 535 |
533 fMCRec->fTopLayer = fMCRec->fLayer; | 536 fMCRec->fTopLayer = fMCRec->fLayer; |
534 | 537 |
535 fSurfaceBase = NULL; | 538 fSurfaceBase = NULL; |
536 | 539 |
537 if (device) { | 540 if (device) { |
538 device->initForRootLayer(fProps.pixelGeometry()); | 541 device->initForRootLayer(fProps.pixelGeometry()); |
539 if (device->forceConservativeRasterClip()) { | 542 if (device->forceConservativeRasterClip()) { |
540 fConservativeRasterClip = true; | 543 fConservativeRasterClip = true; |
541 } | 544 } |
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
984 fSaveCount += 1; | 987 fSaveCount += 1; |
985 this->internalSaveLayer(bounds, paint, flags, strategy); | 988 this->internalSaveLayer(bounds, paint, flags, strategy); |
986 return this->getSaveCount() - 1; | 989 return this->getSaveCount() - 1; |
987 } | 990 } |
988 | 991 |
989 void SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, Sav
eFlags flags, | 992 void SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, Sav
eFlags flags, |
990 SaveLayerStrategy strategy) { | 993 SaveLayerStrategy strategy) { |
991 #ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG | 994 #ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG |
992 flags |= kClipToLayer_SaveFlag; | 995 flags |= kClipToLayer_SaveFlag; |
993 #endif | 996 #endif |
| 997 SkLazyPaint lazyP; |
| 998 SkImageFilter* imageFilter = paint ? paint->getImageFilter() : NULL; |
| 999 SkMatrix stashedMatrix = fMCRec->fMatrix; |
| 1000 SkMatrix remainder; |
| 1001 SkSize scale; |
| 1002 if (imageFilter && |
| 1003 !stashedMatrix.isScaleTranslate() && stashedMatrix.decomposeScale(&scale
, &remainder)) { |
| 1004 // We will restore the matrix (which we are overwriting here) in restore
via fStashedMatrix |
| 1005 this->internalSetMatrix(SkMatrix::MakeScale(scale.width(), scale.height(
))); |
| 1006 SkAutoTUnref<SkImageFilter> matrixFilter(SkImageFilter::CreateMatrixFilt
er( |
| 1007 remainder, SkFilterQuality::kLow_SkFilterQua
lity, imageFilter)); |
| 1008 imageFilter = matrixFilter.get(); |
| 1009 SkPaint* p = lazyP.set(*paint); |
| 1010 p->setImageFilter(imageFilter); |
| 1011 paint = p; |
| 1012 } |
994 | 1013 |
995 // do this before we create the layer. We don't call the public save() since | 1014 // do this before we create the layer. We don't call the public save() since |
996 // that would invoke a possibly overridden virtual | 1015 // that would invoke a possibly overridden virtual |
997 this->internalSave(); | 1016 this->internalSave(); |
998 | 1017 |
999 fDeviceCMDirty = true; | 1018 fDeviceCMDirty = true; |
1000 | 1019 |
1001 SkIRect ir; | 1020 SkIRect ir; |
1002 if (!this->clipRectBounds(bounds, flags, &ir, paint ? paint->getImageFilter(
) : NULL)) { | 1021 if (!this->clipRectBounds(bounds, flags, &ir, imageFilter)) { |
1003 return; | 1022 return; |
1004 } | 1023 } |
1005 | 1024 |
1006 // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy
really care about | 1025 // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy
really care about |
1007 // the clipRectBounds() call above? | 1026 // the clipRectBounds() call above? |
1008 if (kNoLayer_SaveLayerStrategy == strategy) { | 1027 if (kNoLayer_SaveLayerStrategy == strategy) { |
1009 return; | 1028 return; |
1010 } | 1029 } |
1011 | 1030 |
1012 bool isOpaque = !SkToBool(flags & kHasAlphaLayer_SaveFlag); | 1031 bool isOpaque = !SkToBool(flags & kHasAlphaLayer_SaveFlag); |
(...skipping 27 matching lines...) Expand all Loading... |
1040 "Unable to create device for layer.")
; | 1059 "Unable to create device for layer.")
; |
1041 return; | 1060 return; |
1042 } | 1061 } |
1043 forceSpriteOnRestore = true; | 1062 forceSpriteOnRestore = true; |
1044 } | 1063 } |
1045 device = newDev; | 1064 device = newDev; |
1046 } | 1065 } |
1047 | 1066 |
1048 device->setOrigin(ir.fLeft, ir.fTop); | 1067 device->setOrigin(ir.fLeft, ir.fTop); |
1049 DeviceCM* layer = SkNEW_ARGS(DeviceCM, (device, paint, this, fConservativeRa
sterClip, | 1068 DeviceCM* layer = SkNEW_ARGS(DeviceCM, (device, paint, this, fConservativeRa
sterClip, |
1050 forceSpriteOnRestore)); | 1069 forceSpriteOnRestore, stashedMatrix)
); |
1051 device->unref(); | 1070 device->unref(); |
1052 | 1071 |
1053 layer->fNext = fMCRec->fTopLayer; | 1072 layer->fNext = fMCRec->fTopLayer; |
1054 fMCRec->fLayer = layer; | 1073 fMCRec->fLayer = layer; |
1055 fMCRec->fTopLayer = layer; // this field is NOT an owner of layer | 1074 fMCRec->fTopLayer = layer; // this field is NOT an owner of layer |
1056 } | 1075 } |
1057 | 1076 |
1058 int SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) { | 1077 int SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) { |
1059 return this->saveLayerAlpha(bounds, alpha, kARGB_ClipLayer_SaveFlag); | 1078 return this->saveLayerAlpha(bounds, alpha, kARGB_ClipLayer_SaveFlag); |
1060 } | 1079 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1098 this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(), | 1117 this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(), |
1099 layer->fPaint, layer->fDeviceIsBitmapDevice
); | 1118 layer->fPaint, layer->fDeviceIsBitmapDevice
); |
1100 // reset this, since internalDrawDevice will have set it to true | 1119 // reset this, since internalDrawDevice will have set it to true |
1101 fDeviceCMDirty = true; | 1120 fDeviceCMDirty = true; |
1102 SkDELETE(layer); | 1121 SkDELETE(layer); |
1103 } else { | 1122 } else { |
1104 // we're at the root | 1123 // we're at the root |
1105 SkASSERT(layer == (void*)fDeviceCMStorage); | 1124 SkASSERT(layer == (void*)fDeviceCMStorage); |
1106 layer->~DeviceCM(); | 1125 layer->~DeviceCM(); |
1107 } | 1126 } |
| 1127 if (fMCRec) { |
| 1128 // restore what we smashed in internalSaveLayer |
| 1129 fMCRec->fMatrix = layer->fStashedMatrix; |
| 1130 } |
1108 } | 1131 } |
1109 } | 1132 } |
1110 | 1133 |
1111 SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* p
rops) { | 1134 SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* p
rops) { |
1112 if (NULL == props) { | 1135 if (NULL == props) { |
1113 props = &fProps; | 1136 props = &fProps; |
1114 } | 1137 } |
1115 return this->onNewSurface(info, *props); | 1138 return this->onNewSurface(info, *props); |
1116 } | 1139 } |
1117 | 1140 |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1325 } | 1348 } |
1326 | 1349 |
1327 this->checkForDeferredSave(); | 1350 this->checkForDeferredSave(); |
1328 fDeviceCMDirty = true; | 1351 fDeviceCMDirty = true; |
1329 fCachedLocalClipBoundsDirty = true; | 1352 fCachedLocalClipBoundsDirty = true; |
1330 fMCRec->fMatrix.preConcat(matrix); | 1353 fMCRec->fMatrix.preConcat(matrix); |
1331 | 1354 |
1332 this->didConcat(matrix); | 1355 this->didConcat(matrix); |
1333 } | 1356 } |
1334 | 1357 |
| 1358 void SkCanvas::internalSetMatrix(const SkMatrix& matrix) { |
| 1359 fDeviceCMDirty = true; |
| 1360 fCachedLocalClipBoundsDirty = true; |
| 1361 fMCRec->fMatrix = matrix; |
| 1362 } |
| 1363 |
1335 void SkCanvas::setMatrix(const SkMatrix& matrix) { | 1364 void SkCanvas::setMatrix(const SkMatrix& matrix) { |
1336 this->checkForDeferredSave(); | 1365 this->checkForDeferredSave(); |
1337 fDeviceCMDirty = true; | 1366 this->internalSetMatrix(matrix); |
1338 fCachedLocalClipBoundsDirty = true; | |
1339 fMCRec->fMatrix = matrix; | |
1340 this->didSetMatrix(matrix); | 1367 this->didSetMatrix(matrix); |
1341 } | 1368 } |
1342 | 1369 |
1343 void SkCanvas::resetMatrix() { | 1370 void SkCanvas::resetMatrix() { |
1344 SkMatrix matrix; | 1371 SkMatrix matrix; |
1345 | 1372 |
1346 matrix.reset(); | 1373 matrix.reset(); |
1347 this->setMatrix(matrix); | 1374 this->setMatrix(matrix); |
1348 } | 1375 } |
1349 | 1376 |
(...skipping 1337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2687 } | 2714 } |
2688 | 2715 |
2689 if (matrix) { | 2716 if (matrix) { |
2690 canvas->concat(*matrix); | 2717 canvas->concat(*matrix); |
2691 } | 2718 } |
2692 } | 2719 } |
2693 | 2720 |
2694 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { | 2721 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { |
2695 fCanvas->restoreToCount(fSaveCount); | 2722 fCanvas->restoreToCount(fSaveCount); |
2696 } | 2723 } |
OLD | NEW |