| 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 #ifndef SK_SUPPORT_LEGACY_IMAGEFILTER_CTM |
| 1001 SkMatrix remainder; |
| 1002 SkSize scale; |
| 1003 /* |
| 1004 * ImageFilters (so far) do not correctly handle matrices (CTM) that contai
n rotation/skew/etc. |
| 1005 * but they do handle scaling. To accommodate this, we do the following: |
| 1006 * |
| 1007 * 1. Stash off the current CTM |
| 1008 * 2. Decompose the CTM into SCALE and REMAINDER |
| 1009 * 3. Wack the CTM to be just SCALE, and wrap the imagefilter with a Matrix
ImageFilter that |
| 1010 * contains the REMAINDER |
| 1011 * 4. Proceed as usual, allowing the client to draw into the layer (now wit
h a scale-only CTM) |
| 1012 * 5. During restore, we process the MatrixImageFilter, which applies REMAI
NDER to the output |
| 1013 * of the original imagefilter, and draw that (via drawSprite) |
| 1014 * 6. Unwack the CTM to its original state (i.e. stashedMatrix) |
| 1015 * |
| 1016 * Perhaps in the future we could augment #5 to apply REMAINDER as part of
the draw (no longer |
| 1017 * a sprite operation) to avoid the extra buffer/overhead of MatrixImageFil
ter. |
| 1018 */ |
| 1019 if (imageFilter && |
| 1020 !stashedMatrix.isScaleTranslate() && stashedMatrix.decomposeScale(&scale
, &remainder)) { |
| 1021 // We will restore the matrix (which we are overwriting here) in restore
via fStashedMatrix |
| 1022 this->internalSetMatrix(SkMatrix::MakeScale(scale.width(), scale.height(
))); |
| 1023 SkAutoTUnref<SkImageFilter> matrixFilter(SkImageFilter::CreateMatrixFilt
er( |
| 1024 remainder, SkFilterQuality::kLow_SkFilterQua
lity, imageFilter)); |
| 1025 imageFilter = matrixFilter.get(); |
| 1026 SkPaint* p = lazyP.set(*paint); |
| 1027 p->setImageFilter(imageFilter); |
| 1028 paint = p; |
| 1029 } |
| 1030 #endif |
| 994 | 1031 |
| 995 // do this before we create the layer. We don't call the public save() since | 1032 // do this before we create the layer. We don't call the public save() since |
| 996 // that would invoke a possibly overridden virtual | 1033 // that would invoke a possibly overridden virtual |
| 997 this->internalSave(); | 1034 this->internalSave(); |
| 998 | 1035 |
| 999 fDeviceCMDirty = true; | 1036 fDeviceCMDirty = true; |
| 1000 | 1037 |
| 1001 SkIRect ir; | 1038 SkIRect ir; |
| 1002 if (!this->clipRectBounds(bounds, flags, &ir, paint ? paint->getImageFilter(
) : NULL)) { | 1039 if (!this->clipRectBounds(bounds, flags, &ir, imageFilter)) { |
| 1003 return; | 1040 return; |
| 1004 } | 1041 } |
| 1005 | 1042 |
| 1006 // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy
really care about | 1043 // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy
really care about |
| 1007 // the clipRectBounds() call above? | 1044 // the clipRectBounds() call above? |
| 1008 if (kNoLayer_SaveLayerStrategy == strategy) { | 1045 if (kNoLayer_SaveLayerStrategy == strategy) { |
| 1009 return; | 1046 return; |
| 1010 } | 1047 } |
| 1011 | 1048 |
| 1012 bool isOpaque = !SkToBool(flags & kHasAlphaLayer_SaveFlag); | 1049 bool isOpaque = !SkToBool(flags & kHasAlphaLayer_SaveFlag); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1040 "Unable to create device for layer.")
; | 1077 "Unable to create device for layer.")
; |
| 1041 return; | 1078 return; |
| 1042 } | 1079 } |
| 1043 forceSpriteOnRestore = true; | 1080 forceSpriteOnRestore = true; |
| 1044 } | 1081 } |
| 1045 device = newDev; | 1082 device = newDev; |
| 1046 } | 1083 } |
| 1047 | 1084 |
| 1048 device->setOrigin(ir.fLeft, ir.fTop); | 1085 device->setOrigin(ir.fLeft, ir.fTop); |
| 1049 DeviceCM* layer = SkNEW_ARGS(DeviceCM, (device, paint, this, fConservativeRa
sterClip, | 1086 DeviceCM* layer = SkNEW_ARGS(DeviceCM, (device, paint, this, fConservativeRa
sterClip, |
| 1050 forceSpriteOnRestore)); | 1087 forceSpriteOnRestore, stashedMatrix)
); |
| 1051 device->unref(); | 1088 device->unref(); |
| 1052 | 1089 |
| 1053 layer->fNext = fMCRec->fTopLayer; | 1090 layer->fNext = fMCRec->fTopLayer; |
| 1054 fMCRec->fLayer = layer; | 1091 fMCRec->fLayer = layer; |
| 1055 fMCRec->fTopLayer = layer; // this field is NOT an owner of layer | 1092 fMCRec->fTopLayer = layer; // this field is NOT an owner of layer |
| 1056 } | 1093 } |
| 1057 | 1094 |
| 1058 int SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) { | 1095 int SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) { |
| 1059 return this->saveLayerAlpha(bounds, alpha, kARGB_ClipLayer_SaveFlag); | 1096 return this->saveLayerAlpha(bounds, alpha, kARGB_ClipLayer_SaveFlag); |
| 1060 } | 1097 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1090 | 1127 |
| 1091 /* Time to draw the layer's offscreen. We can't call the public drawSprite, | 1128 /* Time to draw the layer's offscreen. We can't call the public drawSprite, |
| 1092 since if we're being recorded, we don't want to record this (the | 1129 since if we're being recorded, we don't want to record this (the |
| 1093 recorder will have already recorded the restore). | 1130 recorder will have already recorded the restore). |
| 1094 */ | 1131 */ |
| 1095 if (layer) { | 1132 if (layer) { |
| 1096 if (layer->fNext) { | 1133 if (layer->fNext) { |
| 1097 const SkIPoint& origin = layer->fDevice->getOrigin(); | 1134 const SkIPoint& origin = layer->fDevice->getOrigin(); |
| 1098 this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(), | 1135 this->internalDrawDevice(layer->fDevice, origin.x(), origin.y(), |
| 1099 layer->fPaint, layer->fDeviceIsBitmapDevice
); | 1136 layer->fPaint, layer->fDeviceIsBitmapDevice
); |
| 1137 // restore what we smashed in internalSaveLayer |
| 1138 fMCRec->fMatrix = layer->fStashedMatrix; |
| 1100 // reset this, since internalDrawDevice will have set it to true | 1139 // reset this, since internalDrawDevice will have set it to true |
| 1101 fDeviceCMDirty = true; | 1140 fDeviceCMDirty = true; |
| 1102 SkDELETE(layer); | 1141 SkDELETE(layer); |
| 1103 } else { | 1142 } else { |
| 1104 // we're at the root | 1143 // we're at the root |
| 1105 SkASSERT(layer == (void*)fDeviceCMStorage); | 1144 SkASSERT(layer == (void*)fDeviceCMStorage); |
| 1106 layer->~DeviceCM(); | 1145 layer->~DeviceCM(); |
| 1146 // no need to update fMCRec, 'cause we're killing the canvas |
| 1107 } | 1147 } |
| 1108 } | 1148 } |
| 1109 } | 1149 } |
| 1110 | 1150 |
| 1111 SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* p
rops) { | 1151 SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* p
rops) { |
| 1112 if (NULL == props) { | 1152 if (NULL == props) { |
| 1113 props = &fProps; | 1153 props = &fProps; |
| 1114 } | 1154 } |
| 1115 return this->onNewSurface(info, *props); | 1155 return this->onNewSurface(info, *props); |
| 1116 } | 1156 } |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1325 } | 1365 } |
| 1326 | 1366 |
| 1327 this->checkForDeferredSave(); | 1367 this->checkForDeferredSave(); |
| 1328 fDeviceCMDirty = true; | 1368 fDeviceCMDirty = true; |
| 1329 fCachedLocalClipBoundsDirty = true; | 1369 fCachedLocalClipBoundsDirty = true; |
| 1330 fMCRec->fMatrix.preConcat(matrix); | 1370 fMCRec->fMatrix.preConcat(matrix); |
| 1331 | 1371 |
| 1332 this->didConcat(matrix); | 1372 this->didConcat(matrix); |
| 1333 } | 1373 } |
| 1334 | 1374 |
| 1375 void SkCanvas::internalSetMatrix(const SkMatrix& matrix) { |
| 1376 fDeviceCMDirty = true; |
| 1377 fCachedLocalClipBoundsDirty = true; |
| 1378 fMCRec->fMatrix = matrix; |
| 1379 } |
| 1380 |
| 1335 void SkCanvas::setMatrix(const SkMatrix& matrix) { | 1381 void SkCanvas::setMatrix(const SkMatrix& matrix) { |
| 1336 this->checkForDeferredSave(); | 1382 this->checkForDeferredSave(); |
| 1337 fDeviceCMDirty = true; | 1383 this->internalSetMatrix(matrix); |
| 1338 fCachedLocalClipBoundsDirty = true; | |
| 1339 fMCRec->fMatrix = matrix; | |
| 1340 this->didSetMatrix(matrix); | 1384 this->didSetMatrix(matrix); |
| 1341 } | 1385 } |
| 1342 | 1386 |
| 1343 void SkCanvas::resetMatrix() { | 1387 void SkCanvas::resetMatrix() { |
| 1344 SkMatrix matrix; | 1388 SkMatrix matrix; |
| 1345 | 1389 |
| 1346 matrix.reset(); | 1390 matrix.reset(); |
| 1347 this->setMatrix(matrix); | 1391 this->setMatrix(matrix); |
| 1348 } | 1392 } |
| 1349 | 1393 |
| (...skipping 1337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2687 } | 2731 } |
| 2688 | 2732 |
| 2689 if (matrix) { | 2733 if (matrix) { |
| 2690 canvas->concat(*matrix); | 2734 canvas->concat(*matrix); |
| 2691 } | 2735 } |
| 2692 } | 2736 } |
| 2693 | 2737 |
| 2694 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { | 2738 SkAutoCanvasMatrixPaint::~SkAutoCanvasMatrixPaint() { |
| 2695 fCanvas->restoreToCount(fSaveCount); | 2739 fCanvas->restoreToCount(fSaveCount); |
| 2696 } | 2740 } |
| OLD | NEW |