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