OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 The Android Open Source Project | 2 * Copyright 2012 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 "SkMorphologyImageFilter.h" | 8 #include "SkMorphologyImageFilter.h" |
9 #include "SkBitmap.h" | 9 #include "SkBitmap.h" |
10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
(...skipping 10 matching lines...) Expand all Loading... |
21 #endif | 21 #endif |
22 | 22 |
23 SkMorphologyImageFilter::SkMorphologyImageFilter(SkFlattenableReadBuffer& buffer
) | 23 SkMorphologyImageFilter::SkMorphologyImageFilter(SkFlattenableReadBuffer& buffer
) |
24 : INHERITED(1, buffer) { | 24 : INHERITED(1, buffer) { |
25 fRadius.fWidth = buffer.readInt(); | 25 fRadius.fWidth = buffer.readInt(); |
26 fRadius.fHeight = buffer.readInt(); | 26 fRadius.fHeight = buffer.readInt(); |
27 buffer.validate((fRadius.fWidth >= 0) && | 27 buffer.validate((fRadius.fWidth >= 0) && |
28 (fRadius.fHeight >= 0)); | 28 (fRadius.fHeight >= 0)); |
29 } | 29 } |
30 | 30 |
31 SkMorphologyImageFilter::SkMorphologyImageFilter(int radiusX, int radiusY, SkIma
geFilter* input, const CropRect* cropRect) | 31 SkMorphologyImageFilter::SkMorphologyImageFilter(int radiusX, |
| 32 int radiusY, |
| 33 SkImageFilter* input, |
| 34 const CropRect* cropRect) |
32 : INHERITED(input, cropRect), fRadius(SkISize::Make(radiusX, radiusY)) { | 35 : INHERITED(input, cropRect), fRadius(SkISize::Make(radiusX, radiusY)) { |
33 } | 36 } |
34 | 37 |
35 | 38 |
36 void SkMorphologyImageFilter::flatten(SkFlattenableWriteBuffer& buffer) const { | 39 void SkMorphologyImageFilter::flatten(SkFlattenableWriteBuffer& buffer) const { |
37 this->INHERITED::flatten(buffer); | 40 this->INHERITED::flatten(buffer); |
38 buffer.writeInt(fRadius.fWidth); | 41 buffer.writeInt(fRadius.fWidth); |
39 buffer.writeInt(fRadius.fHeight); | 42 buffer.writeInt(fRadius.fHeight); |
40 } | 43 } |
41 | 44 |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 if (!src.getPixels()) { | 190 if (!src.getPixels()) { |
188 return false; | 191 return false; |
189 } | 192 } |
190 | 193 |
191 dst->setConfig(src.config(), bounds.width(), bounds.height()); | 194 dst->setConfig(src.config(), bounds.width(), bounds.height()); |
192 dst->allocPixels(); | 195 dst->allocPixels(); |
193 if (!dst->getPixels()) { | 196 if (!dst->getPixels()) { |
194 return false; | 197 return false; |
195 } | 198 } |
196 | 199 |
197 int width = radius().width(); | 200 SkVector radius = SkVector::Make(SkIntToScalar(this->radius().width()), |
198 int height = radius().height(); | 201 SkIntToScalar(this->radius().height())); |
| 202 ctm.mapVectors(&radius, 1); |
| 203 int width = SkScalarFloorToInt(radius.fX); |
| 204 int height = SkScalarFloorToInt(radius.fY); |
199 | 205 |
200 if (width < 0 || height < 0) { | 206 if (width < 0 || height < 0) { |
201 return false; | 207 return false; |
202 } | 208 } |
203 | 209 |
| 210 SkIRect srcBounds = bounds; |
| 211 srcBounds.offset(-srcOffset); |
| 212 |
204 if (width == 0 && height == 0) { | 213 if (width == 0 && height == 0) { |
205 src.extractSubset(dst, bounds); | 214 src.extractSubset(dst, srcBounds); |
206 offset->fX = bounds.left(); | 215 offset->fX = bounds.left(); |
207 offset->fY = bounds.top(); | 216 offset->fY = bounds.top(); |
208 return true; | 217 return true; |
209 } | 218 } |
210 | 219 |
211 SkBitmap temp; | 220 SkBitmap temp; |
212 temp.setConfig(dst->config(), dst->width(), dst->height()); | 221 temp.setConfig(dst->config(), dst->width(), dst->height()); |
213 if (!temp.allocPixels()) { | 222 if (!temp.allocPixels()) { |
214 return false; | 223 return false; |
215 } | 224 } |
216 | 225 |
| 226 if (width > 0 && height > 0) { |
| 227 erodeX(src, &temp, width, srcBounds); |
| 228 SkIRect tmpBounds = SkIRect::MakeWH(srcBounds.width(), srcBounds.height(
)); |
| 229 erodeY(temp, dst, height, tmpBounds); |
| 230 } else if (width > 0) { |
| 231 erodeX(src, dst, width, srcBounds); |
| 232 } else if (height > 0) { |
| 233 erodeY(src, dst, height, srcBounds); |
| 234 } |
217 offset->fX = bounds.left(); | 235 offset->fX = bounds.left(); |
218 offset->fY = bounds.top(); | 236 offset->fY = bounds.top(); |
219 bounds.offset(-srcOffset); | |
220 if (width > 0 && height > 0) { | |
221 erodeX(src, &temp, width, bounds); | |
222 SkIRect tmpBounds = SkIRect::MakeWH(bounds.width(), bounds.height()); | |
223 erodeY(temp, dst, height, tmpBounds); | |
224 } else if (width > 0) { | |
225 erodeX(src, dst, width, bounds); | |
226 } else if (height > 0) { | |
227 erodeY(src, dst, height, bounds); | |
228 } | |
229 return true; | 237 return true; |
230 } | 238 } |
231 | 239 |
232 bool SkDilateImageFilter::onFilterImage(Proxy* proxy, | 240 bool SkDilateImageFilter::onFilterImage(Proxy* proxy, |
233 const SkBitmap& source, const SkMatrix&
ctm, | 241 const SkBitmap& source, const SkMatrix&
ctm, |
234 SkBitmap* dst, SkIPoint* offset) { | 242 SkBitmap* dst, SkIPoint* offset) { |
235 SkBitmap src = source; | 243 SkBitmap src = source; |
236 SkIPoint srcOffset = SkIPoint::Make(0, 0); | 244 SkIPoint srcOffset = SkIPoint::Make(0, 0); |
237 if (getInput(0) && !getInput(0)->filterImage(proxy, source, ctm, &src, &srcO
ffset)) { | 245 if (getInput(0) && !getInput(0)->filterImage(proxy, source, ctm, &src, &srcO
ffset)) { |
238 return false; | 246 return false; |
(...skipping 13 matching lines...) Expand all Loading... |
252 if (!src.getPixels()) { | 260 if (!src.getPixels()) { |
253 return false; | 261 return false; |
254 } | 262 } |
255 | 263 |
256 dst->setConfig(src.config(), bounds.width(), bounds.height()); | 264 dst->setConfig(src.config(), bounds.width(), bounds.height()); |
257 dst->allocPixels(); | 265 dst->allocPixels(); |
258 if (!dst->getPixels()) { | 266 if (!dst->getPixels()) { |
259 return false; | 267 return false; |
260 } | 268 } |
261 | 269 |
262 int width = radius().width(); | 270 SkVector radius = SkVector::Make(SkIntToScalar(this->radius().width()), |
263 int height = radius().height(); | 271 SkIntToScalar(this->radius().height())); |
| 272 ctm.mapVectors(&radius, 1); |
| 273 int width = SkScalarFloorToInt(radius.fX); |
| 274 int height = SkScalarFloorToInt(radius.fY); |
264 | 275 |
265 if (width < 0 || height < 0) { | 276 if (width < 0 || height < 0) { |
266 return false; | 277 return false; |
267 } | 278 } |
268 | 279 |
| 280 SkIRect srcBounds = bounds; |
| 281 srcBounds.offset(-srcOffset); |
| 282 |
269 if (width == 0 && height == 0) { | 283 if (width == 0 && height == 0) { |
270 src.extractSubset(dst, bounds); | 284 src.extractSubset(dst, srcBounds); |
271 offset->fX = bounds.left(); | 285 offset->fX = bounds.left(); |
272 offset->fY = bounds.top(); | 286 offset->fY = bounds.top(); |
273 return true; | 287 return true; |
274 } | 288 } |
275 | 289 |
276 SkBitmap temp; | 290 SkBitmap temp; |
277 temp.setConfig(dst->config(), dst->width(), dst->height()); | 291 temp.setConfig(dst->config(), dst->width(), dst->height()); |
278 if (!temp.allocPixels()) { | 292 if (!temp.allocPixels()) { |
279 return false; | 293 return false; |
280 } | 294 } |
281 | 295 |
| 296 if (width > 0 && height > 0) { |
| 297 dilateX(src, &temp, width, srcBounds); |
| 298 SkIRect tmpBounds = SkIRect::MakeWH(srcBounds.width(), srcBounds.height(
)); |
| 299 dilateY(temp, dst, height, tmpBounds); |
| 300 } else if (width > 0) { |
| 301 dilateX(src, dst, width, srcBounds); |
| 302 } else if (height > 0) { |
| 303 dilateY(src, dst, height, srcBounds); |
| 304 } |
282 offset->fX = bounds.left(); | 305 offset->fX = bounds.left(); |
283 offset->fY = bounds.top(); | 306 offset->fY = bounds.top(); |
284 bounds.offset(-srcOffset); | |
285 if (width > 0 && height > 0) { | |
286 dilateX(src, &temp, width, bounds); | |
287 SkIRect tmpBounds = SkIRect::MakeWH(bounds.width(), bounds.height()); | |
288 dilateY(temp, dst, height, tmpBounds); | |
289 } else if (width > 0) { | |
290 dilateX(src, dst, width, bounds); | |
291 } else if (height > 0) { | |
292 dilateY(src, dst, height, bounds); | |
293 } | |
294 return true; | 307 return true; |
295 } | 308 } |
296 | 309 |
297 #if SK_SUPPORT_GPU | 310 #if SK_SUPPORT_GPU |
298 | 311 |
299 /////////////////////////////////////////////////////////////////////////////// | 312 /////////////////////////////////////////////////////////////////////////////// |
300 | 313 |
301 class GrGLMorphologyEffect; | 314 class GrGLMorphologyEffect; |
302 | 315 |
303 /** | 316 /** |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
562 src.reset(ast.detach()); | 575 src.reset(ast.detach()); |
563 } | 576 } |
564 return SkImageFilterUtils::WrapTexture(src, rect.width(), rect.height(), dst
); | 577 return SkImageFilterUtils::WrapTexture(src, rect.width(), rect.height(), dst
); |
565 } | 578 } |
566 | 579 |
567 }; | 580 }; |
568 | 581 |
569 bool SkDilateImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, cons
t SkMatrix& ctm, | 582 bool SkDilateImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, cons
t SkMatrix& ctm, |
570 SkBitmap* result, SkIPoint* offset) { | 583 SkBitmap* result, SkIPoint* offset) { |
571 SkBitmap input; | 584 SkBitmap input; |
572 if (!SkImageFilterUtils::GetInputResultGPU(getInput(0), proxy, src, ctm, &in
put, offset)) { | 585 SkIPoint srcOffset = SkIPoint::Make(0, 0); |
| 586 if (!SkImageFilterUtils::GetInputResultGPU(getInput(0), proxy, src, ctm, &in
put, &srcOffset)) { |
573 return false; | 587 return false; |
574 } | 588 } |
575 SkIRect bounds; | 589 SkIRect bounds; |
576 src.getBounds(&bounds); | 590 input.getBounds(&bounds); |
| 591 bounds.offset(srcOffset); |
577 if (!this->applyCropRect(&bounds, ctm)) { | 592 if (!this->applyCropRect(&bounds, ctm)) { |
578 return false; | 593 return false; |
579 } | 594 } |
580 int width = radius().width(); | 595 SkVector radius = SkVector::Make(SkIntToScalar(this->radius().width()), |
581 int height = radius().height(); | 596 SkIntToScalar(this->radius().height())); |
| 597 ctm.mapVectors(&radius, 1); |
| 598 int width = SkScalarFloorToInt(radius.fX); |
| 599 int height = SkScalarFloorToInt(radius.fY); |
582 | 600 |
583 if (width < 0 || height < 0) { | 601 if (width < 0 || height < 0) { |
584 return false; | 602 return false; |
585 } | 603 } |
586 | 604 |
| 605 SkIRect srcBounds = bounds; |
| 606 srcBounds.offset(-srcOffset); |
587 if (width == 0 && height == 0) { | 607 if (width == 0 && height == 0) { |
588 src.extractSubset(result, bounds); | 608 input.extractSubset(result, srcBounds); |
589 offset->fX = bounds.left(); | 609 offset->fX = bounds.left(); |
590 offset->fY = bounds.top(); | 610 offset->fY = bounds.top(); |
591 return true; | 611 return true; |
592 } | 612 } |
593 | 613 |
594 if (!apply_morphology(input, bounds, GrMorphologyEffect::kDilate_MorphologyT
ype, radius(), result)) { | 614 if (!apply_morphology(input, srcBounds, GrMorphologyEffect::kDilate_Morpholo
gyType, |
| 615 SkISize::Make(width, height), result)) { |
595 return false; | 616 return false; |
596 } | 617 } |
597 offset->fX = bounds.left(); | 618 offset->fX = bounds.left(); |
598 offset->fY = bounds.top(); | 619 offset->fY = bounds.top(); |
599 return true; | 620 return true; |
600 } | 621 } |
601 | 622 |
602 bool SkErodeImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const
SkMatrix& ctm, | 623 bool SkErodeImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const
SkMatrix& ctm, |
603 SkBitmap* result, SkIPoint* offset) { | 624 SkBitmap* result, SkIPoint* offset) { |
604 SkBitmap input; | 625 SkBitmap input; |
605 if (!SkImageFilterUtils::GetInputResultGPU(getInput(0), proxy, src, ctm, &in
put, offset)) { | 626 SkIPoint srcOffset = SkIPoint::Make(0, 0); |
| 627 if (!SkImageFilterUtils::GetInputResultGPU(getInput(0), proxy, src, ctm, &in
put, &srcOffset)) { |
606 return false; | 628 return false; |
607 } | 629 } |
608 SkIRect bounds; | 630 SkIRect bounds; |
609 src.getBounds(&bounds); | 631 input.getBounds(&bounds); |
| 632 bounds.offset(srcOffset); |
610 if (!this->applyCropRect(&bounds, ctm)) { | 633 if (!this->applyCropRect(&bounds, ctm)) { |
611 return false; | 634 return false; |
612 } | 635 } |
613 int width = radius().width(); | 636 SkVector radius = SkVector::Make(SkIntToScalar(this->radius().width()), |
614 int height = radius().height(); | 637 SkIntToScalar(this->radius().height())); |
| 638 ctm.mapVectors(&radius, 1); |
| 639 int width = SkScalarFloorToInt(radius.fX); |
| 640 int height = SkScalarFloorToInt(radius.fY); |
615 | 641 |
616 if (width < 0 || height < 0) { | 642 if (width < 0 || height < 0) { |
617 return false; | 643 return false; |
618 } | 644 } |
619 | 645 |
| 646 SkIRect srcBounds = bounds; |
| 647 srcBounds.offset(-srcOffset); |
| 648 |
620 if (width == 0 && height == 0) { | 649 if (width == 0 && height == 0) { |
621 src.extractSubset(result, bounds); | 650 input.extractSubset(result, srcBounds); |
622 offset->fX = bounds.left(); | 651 offset->fX = bounds.left(); |
623 offset->fY = bounds.top(); | 652 offset->fY = bounds.top(); |
624 return true; | 653 return true; |
625 } | 654 } |
626 | 655 |
627 if (!apply_morphology(input, bounds, GrMorphologyEffect::kErode_MorphologyTy
pe, radius(), result)) { | 656 if (!apply_morphology(input, srcBounds, GrMorphologyEffect::kErode_Morpholog
yType, |
| 657 SkISize::Make(width, height), result)) { |
628 return false; | 658 return false; |
629 } | 659 } |
630 offset->fX = bounds.left(); | 660 offset->fX = bounds.left(); |
631 offset->fY = bounds.top(); | 661 offset->fY = bounds.top(); |
632 return true; | 662 return true; |
633 } | 663 } |
634 | 664 |
635 #endif | 665 #endif |
OLD | NEW |