| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2013 The Android Open Source Project | 2 * Copyright 2013 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 "SkPictureImageFilter.h" | 8 #include "SkPictureImageFilter.h" |
| 9 #include "SkDevice.h" | 9 |
| 10 #include "SkCanvas.h" | 10 #include "SkCanvas.h" |
| 11 #include "SkReadBuffer.h" | 11 #include "SkReadBuffer.h" |
| 12 #include "SkSurfaceProps.h" | 12 #include "SkSpecialImage.h" |
| 13 #include "SkSpecialSurface.h" |
| 13 #include "SkWriteBuffer.h" | 14 #include "SkWriteBuffer.h" |
| 14 #include "SkValidationUtils.h" | 15 #include "SkValidationUtils.h" |
| 15 | 16 |
| 16 SkPictureImageFilter::SkPictureImageFilter(sk_sp<SkPicture> picture) | 17 SkPictureImageFilter::SkPictureImageFilter(sk_sp<SkPicture> picture) |
| 17 : INHERITED(nullptr, 0, nullptr) | 18 : INHERITED(nullptr, 0, nullptr) |
| 18 , fPicture(std::move(picture)) | 19 , fPicture(std::move(picture)) |
| 19 , fCropRect(fPicture ? fPicture->cullRect() : SkRect::MakeEmpty()) | 20 , fCropRect(fPicture ? fPicture->cullRect() : SkRect::MakeEmpty()) |
| 20 , fPictureResolution(kDeviceSpace_PictureResolution) | 21 , fPictureResolution(kDeviceSpace_PictureResolution) |
| 21 , fFilterQuality(kLow_SkFilterQuality) { | 22 , fFilterQuality(kLow_SkFilterQuality) { |
| 22 } | 23 } |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 73 fPicture->flatten(buffer); | 74 fPicture->flatten(buffer); |
| 74 } | 75 } |
| 75 } | 76 } |
| 76 buffer.writeRect(fCropRect); | 77 buffer.writeRect(fCropRect); |
| 77 buffer.writeInt(fPictureResolution); | 78 buffer.writeInt(fPictureResolution); |
| 78 if (kLocalSpace_PictureResolution == fPictureResolution) { | 79 if (kLocalSpace_PictureResolution == fPictureResolution) { |
| 79 buffer.writeInt(fFilterQuality); | 80 buffer.writeInt(fFilterQuality); |
| 80 } | 81 } |
| 81 } | 82 } |
| 82 | 83 |
| 83 bool SkPictureImageFilter::onFilterImageDeprecated(Proxy* proxy, const SkBitmap&
, | 84 sk_sp<SkSpecialImage> SkPictureImageFilter::onFilterImage(SkSpecialImage* source
, |
| 84 const Context& ctx, | 85 const Context& ctx, |
| 85 SkBitmap* result, SkIPoint* o
ffset) const { | 86 SkIPoint* offset) cons
t { |
| 86 if (!fPicture) { | 87 if (!fPicture) { |
| 87 offset->fX = offset->fY = 0; | 88 return nullptr; |
| 88 return true; | |
| 89 } | 89 } |
| 90 | 90 |
| 91 SkRect floatBounds; | 91 SkRect floatBounds; |
| 92 ctx.ctm().mapRect(&floatBounds, fCropRect); | 92 ctx.ctm().mapRect(&floatBounds, fCropRect); |
| 93 SkIRect bounds = floatBounds.roundOut(); | 93 SkIRect bounds = floatBounds.roundOut(); |
| 94 if (!bounds.intersect(ctx.clipBounds())) { | 94 if (!bounds.intersect(ctx.clipBounds())) { |
| 95 return false; | 95 return nullptr; |
| 96 } | 96 } |
| 97 | 97 |
| 98 if (bounds.isEmpty()) { | 98 SkASSERT(!bounds.isEmpty()); |
| 99 offset->fX = offset->fY = 0; | 99 |
| 100 return true; | 100 SkImageInfo info = SkImageInfo::MakeN32(bounds.width(), bounds.height(), kPr
emul_SkAlphaType); |
| 101 sk_sp<SkSpecialSurface> surf(source->makeSurface(info)); |
| 102 if (!surf) { |
| 103 return nullptr; |
| 101 } | 104 } |
| 102 | 105 |
| 103 SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds.width(), bounds
.height())); | 106 SkCanvas* canvas = surf->getCanvas(); |
| 104 if (nullptr == device.get()) { | 107 SkASSERT(canvas); |
| 105 return false; | 108 |
| 109 canvas->clear(0x0); |
| 110 |
| 111 if (kDeviceSpace_PictureResolution == fPictureResolution || |
| 112 0 == (ctx.ctm().getType() & ~SkMatrix::kTranslate_Mask)) { |
| 113 this->drawPictureAtDeviceResolution(canvas, bounds, ctx); |
| 114 } else { |
| 115 this->drawPictureAtLocalResolution(source, canvas, bounds, ctx); |
| 106 } | 116 } |
| 107 | 117 |
| 108 if (kDeviceSpace_PictureResolution == fPictureResolution || | |
| 109 0 == (ctx.ctm().getType() & ~SkMatrix::kTranslate_Mask)) { | |
| 110 this->drawPictureAtDeviceResolution(device.get(), bounds, ctx); | |
| 111 } else { | |
| 112 this->drawPictureAtLocalResolution(proxy, device.get(), bounds, ctx); | |
| 113 } | |
| 114 | |
| 115 *result = device.get()->accessBitmap(false); | |
| 116 offset->fX = bounds.fLeft; | 118 offset->fX = bounds.fLeft; |
| 117 offset->fY = bounds.fTop; | 119 offset->fY = bounds.fTop; |
| 118 return true; | 120 return surf->makeImageSnapshot(); |
| 119 } | 121 } |
| 120 | 122 |
| 121 void SkPictureImageFilter::drawPictureAtDeviceResolution(SkBaseDevice* device, | 123 void SkPictureImageFilter::drawPictureAtDeviceResolution(SkCanvas* canvas, |
| 122 const SkIRect& deviceBo
unds, | 124 const SkIRect& deviceBo
unds, |
| 123 const Context& ctx) con
st { | 125 const Context& ctx) con
st { |
| 124 SkCanvas canvas(device); | 126 canvas->translate(-SkIntToScalar(deviceBounds.fLeft), -SkIntToScalar(deviceB
ounds.fTop)); |
| 125 | 127 canvas->concat(ctx.ctm()); |
| 126 canvas.translate(-SkIntToScalar(deviceBounds.fLeft), -SkIntToScalar(deviceBo
unds.fTop)); | 128 canvas->drawPicture(fPicture); |
| 127 canvas.concat(ctx.ctm()); | |
| 128 canvas.drawPicture(fPicture); | |
| 129 } | 129 } |
| 130 | 130 |
| 131 void SkPictureImageFilter::drawPictureAtLocalResolution(Proxy* proxy, SkBaseDevi
ce* device, | 131 void SkPictureImageFilter::drawPictureAtLocalResolution(SkSpecialImage* source, |
| 132 SkCanvas* canvas, |
| 132 const SkIRect& deviceBou
nds, | 133 const SkIRect& deviceBou
nds, |
| 133 const Context& ctx) cons
t { | 134 const Context& ctx) cons
t { |
| 134 SkMatrix inverseCtm; | 135 SkMatrix inverseCtm; |
| 135 if (!ctx.ctm().invert(&inverseCtm)) { | 136 if (!ctx.ctm().invert(&inverseCtm)) { |
| 136 return; | 137 return; |
| 137 } | 138 } |
| 138 | 139 |
| 139 SkRect localBounds = SkRect::Make(ctx.clipBounds()); | 140 SkRect localBounds = SkRect::Make(ctx.clipBounds()); |
| 140 inverseCtm.mapRect(&localBounds); | 141 inverseCtm.mapRect(&localBounds); |
| 141 if (!localBounds.intersect(fCropRect)) { | 142 if (!localBounds.intersect(fCropRect)) { |
| 142 return; | 143 return; |
| 143 } | 144 } |
| 144 SkIRect localIBounds = localBounds.roundOut(); | 145 SkIRect localIBounds = localBounds.roundOut(); |
| 145 SkAutoTUnref<SkBaseDevice> localDevice(proxy->createDevice(localIBounds.widt
h(), localIBounds.height())); | |
| 146 | 146 |
| 147 SkCanvas localCanvas(localDevice); | 147 sk_sp<SkSpecialImage> localImg; |
| 148 localCanvas.translate(-SkIntToScalar(localIBounds.fLeft), -SkIntToScalar(loc
alIBounds.fTop)); | 148 { |
| 149 localCanvas.drawPicture(fPicture); | 149 const SkImageInfo info = SkImageInfo::MakeN32(localIBounds.width(), loca
lIBounds.height(), |
| 150 kPremul_SkAlphaType); |
| 150 | 151 |
| 151 SkCanvas canvas(device); | 152 sk_sp<SkSpecialSurface> localSurface(source->makeSurface(info)); |
| 153 if (!localSurface) { |
| 154 return; |
| 155 } |
| 152 | 156 |
| 153 canvas.translate(-SkIntToScalar(deviceBounds.fLeft), -SkIntToScalar(deviceBo
unds.fTop)); | 157 SkCanvas* localCanvas = localSurface->getCanvas(); |
| 154 canvas.concat(ctx.ctm()); | 158 SkASSERT(localCanvas); |
| 155 SkPaint paint; | 159 |
| 156 paint.setFilterQuality(fFilterQuality); | 160 localCanvas->translate(-SkIntToScalar(localIBounds.fLeft), |
| 157 canvas.drawBitmap(localDevice.get()->accessBitmap(false), SkIntToScalar(loca
lIBounds.fLeft), | 161 -SkIntToScalar(localIBounds.fTop)); |
| 158 SkIntToScalar(localIBounds.fTop), &paint); | 162 localCanvas->drawPicture(fPicture); |
| 163 |
| 164 localImg = localSurface->makeImageSnapshot(); |
| 165 SkASSERT(localImg); |
| 166 } |
| 167 |
| 168 { |
| 169 canvas->translate(-SkIntToScalar(deviceBounds.fLeft), -SkIntToScalar(dev
iceBounds.fTop)); |
| 170 canvas->concat(ctx.ctm()); |
| 171 SkPaint paint; |
| 172 paint.setFilterQuality(fFilterQuality); |
| 173 |
| 174 localImg->draw(canvas, |
| 175 SkIntToScalar(localIBounds.fLeft), |
| 176 SkIntToScalar(localIBounds.fTop), |
| 177 &paint); |
| 178 } |
| 159 } | 179 } |
| 160 | 180 |
| 161 #ifndef SK_IGNORE_TO_STRING | 181 #ifndef SK_IGNORE_TO_STRING |
| 162 void SkPictureImageFilter::toString(SkString* str) const { | 182 void SkPictureImageFilter::toString(SkString* str) const { |
| 163 str->appendf("SkPictureImageFilter: ("); | 183 str->appendf("SkPictureImageFilter: ("); |
| 164 str->appendf("crop: (%f,%f,%f,%f) ", | 184 str->appendf("crop: (%f,%f,%f,%f) ", |
| 165 fCropRect.fLeft, fCropRect.fTop, fCropRect.fRight, fCropRect.fB
ottom); | 185 fCropRect.fLeft, fCropRect.fTop, fCropRect.fRight, fCropRect.fB
ottom); |
| 166 if (fPicture) { | 186 if (fPicture) { |
| 167 str->appendf("picture: (%f,%f,%f,%f)", | 187 str->appendf("picture: (%f,%f,%f,%f)", |
| 168 fPicture->cullRect().fLeft, fPicture->cullRect().fTop, | 188 fPicture->cullRect().fLeft, fPicture->cullRect().fTop, |
| 169 fPicture->cullRect().fRight, fPicture->cullRect().fBottom); | 189 fPicture->cullRect().fRight, fPicture->cullRect().fBottom); |
| 170 } | 190 } |
| 171 str->append(")"); | 191 str->append(")"); |
| 172 } | 192 } |
| 173 #endif | 193 #endif |
| OLD | NEW |