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 "SkBitmapDevice.h" | 8 #include "SkBitmapDevice.h" |
9 #include "SkCanvas.h" | 9 #include "SkCanvas.h" |
10 #include "SkCanvasPriv.h" | 10 #include "SkCanvasPriv.h" |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
184 by the device's XY offset and bitmap-bounds. | 184 by the device's XY offset and bitmap-bounds. |
185 */ | 185 */ |
186 struct DeviceCM { | 186 struct DeviceCM { |
187 DeviceCM* fNext; | 187 DeviceCM* fNext; |
188 SkBaseDevice* fDevice; | 188 SkBaseDevice* fDevice; |
189 SkRasterClip fClip; | 189 SkRasterClip fClip; |
190 SkPaint* fPaint; // may be null (in the future) | 190 SkPaint* fPaint; // may be null (in the future) |
191 const SkMatrix* fMatrix; | 191 const SkMatrix* fMatrix; |
192 SkMatrix fMatrixStorage; | 192 SkMatrix fMatrixStorage; |
193 const bool fDeviceIsBitmapDevice; | 193 const bool fDeviceIsBitmapDevice; |
| 194 SkMatrix fStashedMatrix; // Original CTM; used by imageFilter at
saveLayer time |
194 | 195 |
195 DeviceCM(SkBaseDevice* device, const SkPaint* paint, SkCanvas* canvas, | 196 DeviceCM(SkBaseDevice* device, const SkPaint* paint, SkCanvas* canvas, |
196 bool conservativeRasterClip, bool deviceIsBitmapDevice) | 197 bool conservativeRasterClip, bool deviceIsBitmapDevice, |
| 198 const SkMatrix& stashedMatrix) |
197 : fNext(NULL) | 199 : fNext(NULL) |
198 , fClip(conservativeRasterClip) | 200 , fClip(conservativeRasterClip) |
199 , fDeviceIsBitmapDevice(deviceIsBitmapDevice) | 201 , fDeviceIsBitmapDevice(deviceIsBitmapDevice) |
| 202 , fStashedMatrix(stashedMatrix) |
200 { | 203 { |
201 if (NULL != device) { | 204 if (NULL != device) { |
202 device->ref(); | 205 device->ref(); |
203 device->onAttachToCanvas(canvas); | 206 device->onAttachToCanvas(canvas); |
204 } | 207 } |
205 fDevice = device; | 208 fDevice = device; |
206 fPaint = paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL; | 209 fPaint = paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL; |
207 } | 210 } |
208 | 211 |
209 ~DeviceCM() { | 212 ~DeviceCM() { |
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
604 fSaveCount = 1; | 607 fSaveCount = 1; |
605 fMetaData = NULL; | 608 fMetaData = NULL; |
606 | 609 |
607 fClipStack.reset(SkNEW(SkClipStack)); | 610 fClipStack.reset(SkNEW(SkClipStack)); |
608 | 611 |
609 fMCRec = (MCRec*)fMCStack.push_back(); | 612 fMCRec = (MCRec*)fMCStack.push_back(); |
610 new (fMCRec) MCRec(fConservativeRasterClip); | 613 new (fMCRec) MCRec(fConservativeRasterClip); |
611 | 614 |
612 SkASSERT(sizeof(DeviceCM) <= sizeof(fDeviceCMStorage)); | 615 SkASSERT(sizeof(DeviceCM) <= sizeof(fDeviceCMStorage)); |
613 fMCRec->fLayer = (DeviceCM*)fDeviceCMStorage; | 616 fMCRec->fLayer = (DeviceCM*)fDeviceCMStorage; |
614 new (fDeviceCMStorage) DeviceCM(NULL, NULL, NULL, fConservativeRasterClip, f
alse); | 617 new (fDeviceCMStorage) DeviceCM(NULL, NULL, NULL, fConservativeRasterClip, f
alse, |
| 618 fMCRec->fMatrix); |
615 | 619 |
616 fMCRec->fTopLayer = fMCRec->fLayer; | 620 fMCRec->fTopLayer = fMCRec->fLayer; |
617 | 621 |
618 fSurfaceBase = NULL; | 622 fSurfaceBase = NULL; |
619 | 623 |
620 if (device) { | 624 if (device) { |
621 // The root device and the canvas should always have the same pixel geom
etry | 625 // The root device and the canvas should always have the same pixel geom
etry |
622 SkASSERT(fProps.pixelGeometry() == device->surfaceProps().pixelGeometry(
)); | 626 SkASSERT(fProps.pixelGeometry() == device->surfaceProps().pixelGeometry(
)); |
623 if (device->forceConservativeRasterClip()) { | 627 if (device->forceConservativeRasterClip()) { |
624 fConservativeRasterClip = true; | 628 fConservativeRasterClip = true; |
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1072 fSaveCount += 1; | 1076 fSaveCount += 1; |
1073 this->internalSaveLayer(bounds, paint, flags, strategy); | 1077 this->internalSaveLayer(bounds, paint, flags, strategy); |
1074 return this->getSaveCount() - 1; | 1078 return this->getSaveCount() - 1; |
1075 } | 1079 } |
1076 | 1080 |
1077 void SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, Sav
eFlags flags, | 1081 void SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, Sav
eFlags flags, |
1078 SaveLayerStrategy strategy) { | 1082 SaveLayerStrategy strategy) { |
1079 #ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG | 1083 #ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG |
1080 flags |= kClipToLayer_SaveFlag; | 1084 flags |= kClipToLayer_SaveFlag; |
1081 #endif | 1085 #endif |
| 1086 SkLazyPaint lazyP; |
| 1087 SkImageFilter* imageFilter = paint ? paint->getImageFilter() : NULL; |
| 1088 SkMatrix matrix = fMCRec->fMatrix; |
| 1089 SkMatrix remainder; |
| 1090 SkSize scale; |
| 1091 if (imageFilter && !matrix.isScaleTranslate() && matrix.decomposeScale(&scal
e, &remainder)) { |
| 1092 SkMatrix scaleMatrix = SkMatrix::MakeScale(scale.width(), scale.height()
); |
| 1093 this->internalSetMatrix(scaleMatrix); |
| 1094 SkAutoTUnref<SkImageFilter> matrixFilter(SkImageFilter::CreateMatrixFilt
er(remainder, SkFilterQuality::kLow_SkFilterQuality, imageFilter)); |
| 1095 imageFilter = matrixFilter.get(); |
| 1096 SkPaint* p = lazyP.set(*paint); |
| 1097 p->setImageFilter(imageFilter); |
| 1098 paint = p; |
| 1099 } |
1082 | 1100 |
1083 // do this before we create the layer. We don't call the public save() since | 1101 // do this before we create the layer. We don't call the public save() since |
1084 // that would invoke a possibly overridden virtual | 1102 // that would invoke a possibly overridden virtual |
1085 this->internalSave(); | 1103 this->internalSave(); |
1086 | 1104 |
1087 fDeviceCMDirty = true; | 1105 fDeviceCMDirty = true; |
1088 | 1106 |
1089 SkIRect ir; | 1107 SkIRect ir; |
1090 if (!this->clipRectBounds(bounds, flags, &ir, paint ? paint->getImageFilter(
) : NULL)) { | 1108 if (!this->clipRectBounds(bounds, flags, &ir, imageFilter)) { |
1091 return; | 1109 return; |
1092 } | 1110 } |
1093 | 1111 |
1094 // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy
really care about | 1112 // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy
really care about |
1095 // the clipRectBounds() call above? | 1113 // the clipRectBounds() call above? |
1096 if (kNoLayer_SaveLayerStrategy == strategy) { | 1114 if (kNoLayer_SaveLayerStrategy == strategy) { |
1097 return; | 1115 return; |
1098 } | 1116 } |
1099 | 1117 |
1100 bool isOpaque = !SkToBool(flags & kHasAlphaLayer_SaveFlag); | 1118 bool isOpaque = !SkToBool(flags & kHasAlphaLayer_SaveFlag); |
(...skipping 28 matching lines...) Expand all Loading... |
1129 "Unable to create device for layer.")
; | 1147 "Unable to create device for layer.")
; |
1130 return; | 1148 return; |
1131 } | 1149 } |
1132 forceSpriteOnRestore = true; | 1150 forceSpriteOnRestore = true; |
1133 } | 1151 } |
1134 device = newDev; | 1152 device = newDev; |
1135 } | 1153 } |
1136 | 1154 |
1137 device->setOrigin(ir.fLeft, ir.fTop); | 1155 device->setOrigin(ir.fLeft, ir.fTop); |
1138 DeviceCM* layer = SkNEW_ARGS(DeviceCM, (device, paint, this, fConservativeRa
sterClip, | 1156 DeviceCM* layer = SkNEW_ARGS(DeviceCM, (device, paint, this, fConservativeRa
sterClip, |
1139 forceSpriteOnRestore)); | 1157 forceSpriteOnRestore, fMCRec->fMatri
x)); |
1140 device->unref(); | 1158 device->unref(); |
1141 | 1159 |
1142 layer->fNext = fMCRec->fTopLayer; | 1160 layer->fNext = fMCRec->fTopLayer; |
1143 fMCRec->fLayer = layer; | 1161 fMCRec->fLayer = layer; |
1144 fMCRec->fTopLayer = layer; // this field is NOT an owner of layer | 1162 fMCRec->fTopLayer = layer; // this field is NOT an owner of layer |
1145 } | 1163 } |
1146 | 1164 |
1147 int SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) { | 1165 int SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) { |
1148 return this->saveLayerAlpha(bounds, alpha, kARGB_ClipLayer_SaveFlag); | 1166 return this->saveLayerAlpha(bounds, alpha, kARGB_ClipLayer_SaveFlag); |
1149 } | 1167 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1181 since if we're being recorded, we don't want to record this (the | 1199 since if we're being recorded, we don't want to record this (the |
1182 recorder will have already recorded the restore). | 1200 recorder will have already recorded the restore). |
1183 */ | 1201 */ |
1184 if (layer) { | 1202 if (layer) { |
1185 if (layer->fNext) { | 1203 if (layer->fNext) { |
1186 const SkIPoint& origin = layer->fDevice->getOrigin(); | 1204 const SkIPoint& origin = layer->fDevice->getOrigin(); |
1187 this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(), | 1205 this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(), |
1188 layer->fPaint, layer->fDeviceIsBitmapDevice
); | 1206 layer->fPaint, layer->fDeviceIsBitmapDevice
); |
1189 // reset this, since internalDrawDevice will have set it to true | 1207 // reset this, since internalDrawDevice will have set it to true |
1190 fDeviceCMDirty = true; | 1208 fDeviceCMDirty = true; |
| 1209 if (fMCRec) { |
| 1210 fMCRec->fMatrix = layer->fStashedMatrix; |
| 1211 } |
1191 SkDELETE(layer); | 1212 SkDELETE(layer); |
1192 } else { | 1213 } else { |
1193 // we're at the root | 1214 // we're at the root |
1194 SkASSERT(layer == (void*)fDeviceCMStorage); | 1215 SkASSERT(layer == (void*)fDeviceCMStorage); |
1195 layer->~DeviceCM(); | 1216 layer->~DeviceCM(); |
1196 } | 1217 } |
1197 } | 1218 } |
1198 } | 1219 } |
1199 | 1220 |
1200 SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* p
rops) { | 1221 SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* p
rops) { |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1433 } | 1454 } |
1434 | 1455 |
1435 this->checkForDeferredSave(); | 1456 this->checkForDeferredSave(); |
1436 fDeviceCMDirty = true; | 1457 fDeviceCMDirty = true; |
1437 fCachedLocalClipBoundsDirty = true; | 1458 fCachedLocalClipBoundsDirty = true; |
1438 fMCRec->fMatrix.preConcat(matrix); | 1459 fMCRec->fMatrix.preConcat(matrix); |
1439 | 1460 |
1440 this->didConcat(matrix); | 1461 this->didConcat(matrix); |
1441 } | 1462 } |
1442 | 1463 |
| 1464 void SkCanvas::internalSetMatrix(const SkMatrix& matrix) { |
| 1465 fDeviceCMDirty = true; |
| 1466 fCachedLocalClipBoundsDirty = true; |
| 1467 fMCRec->fMatrix = matrix; |
| 1468 } |
| 1469 |
1443 void SkCanvas::setMatrix(const SkMatrix& matrix) { | 1470 void SkCanvas::setMatrix(const SkMatrix& matrix) { |
1444 this->checkForDeferredSave(); | 1471 this->checkForDeferredSave(); |
1445 fDeviceCMDirty = true; | 1472 this->internalSetMatrix(matrix); |
1446 fCachedLocalClipBoundsDirty = true; | |
1447 fMCRec->fMatrix = matrix; | |
1448 this->didSetMatrix(matrix); | 1473 this->didSetMatrix(matrix); |
1449 } | 1474 } |
1450 | 1475 |
1451 void SkCanvas::resetMatrix() { | 1476 void SkCanvas::resetMatrix() { |
1452 SkMatrix matrix; | 1477 SkMatrix matrix; |
1453 | 1478 |
1454 matrix.reset(); | 1479 matrix.reset(); |
1455 this->setMatrix(matrix); | 1480 this->setMatrix(matrix); |
1456 } | 1481 } |
1457 | 1482 |
(...skipping 1439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2897 } | 2922 } |
2898 | 2923 |
2899 if (matrix) { | 2924 if (matrix) { |
2900 canvas->concat(*matrix); | 2925 canvas->concat(*matrix); |
2901 } | 2926 } |
2902 } | 2927 } |
2903 | 2928 |
2904 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { | 2929 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { |
2905 fCanvas->restoreToCount(fSaveCount); | 2930 fCanvas->restoreToCount(fSaveCount); |
2906 } | 2931 } |
OLD | NEW |