Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Side by Side Diff: src/core/SkCanvas.cpp

Issue 23011012: Implement correct clipping for image filters. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Add morphology to the list of ignored tests Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « include/effects/SkOffsetImageFilter.h ('k') | src/core/SkImageFilter.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 /* 2 /*
3 * Copyright 2008 The Android Open Source Project 3 * Copyright 2008 The Android Open Source Project
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 9
10 #include "SkCanvas.h" 10 #include "SkCanvas.h"
(...skipping 773 matching lines...) Expand 10 before | Expand all | Expand 10 after
784 #else 784 #else
785 return SkBitmap::kARGB_8888_Config; // default answer 785 return SkBitmap::kARGB_8888_Config; // default answer
786 #endif 786 #endif
787 } 787 }
788 788
789 static bool bounds_affects_clip(SkCanvas::SaveFlags flags) { 789 static bool bounds_affects_clip(SkCanvas::SaveFlags flags) {
790 return (flags & SkCanvas::kClipToLayer_SaveFlag) != 0; 790 return (flags & SkCanvas::kClipToLayer_SaveFlag) != 0;
791 } 791 }
792 792
793 bool SkCanvas::clipRectBounds(const SkRect* bounds, SaveFlags flags, 793 bool SkCanvas::clipRectBounds(const SkRect* bounds, SaveFlags flags,
794 SkIRect* intersection) { 794 SkIRect* intersection, const SkImageFilter* image Filter) {
795 SkIRect clipBounds; 795 SkIRect clipBounds;
796 SkRegion::Op op = SkRegion::kIntersect_Op;
796 if (!this->getClipDeviceBounds(&clipBounds)) { 797 if (!this->getClipDeviceBounds(&clipBounds)) {
797 return false; 798 return false;
798 } 799 }
800
801 if (imageFilter) {
802 imageFilter->filterBounds(clipBounds, *fMCRec->fMatrix, &clipBounds);
803 // Filters may grow the bounds beyond the device bounds.
804 op = SkRegion::kReplace_Op;
805 }
799 SkIRect ir; 806 SkIRect ir;
800 if (NULL != bounds) { 807 if (NULL != bounds) {
801 SkRect r; 808 SkRect r;
802 809
803 this->getTotalMatrix().mapRect(&r, *bounds); 810 this->getTotalMatrix().mapRect(&r, *bounds);
804 r.roundOut(&ir); 811 r.roundOut(&ir);
805 // early exit if the layer's bounds are clipped out 812 // early exit if the layer's bounds are clipped out
806 if (!ir.intersect(clipBounds)) { 813 if (!ir.intersect(clipBounds)) {
807 if (bounds_affects_clip(flags)) { 814 if (bounds_affects_clip(flags)) {
808 fMCRec->fRasterClip->setEmpty(); 815 fMCRec->fRasterClip->setEmpty();
809 } 816 }
810 return false; 817 return false;
811 } 818 }
812 } else { // no user bounds, so just use the clip 819 } else { // no user bounds, so just use the clip
813 ir = clipBounds; 820 ir = clipBounds;
814 } 821 }
815 822
816 fClipStack.clipDevRect(ir, SkRegion::kIntersect_Op); 823 fClipStack.clipDevRect(ir, op);
817 824
818 // early exit if the clip is now empty 825 // early exit if the clip is now empty
819 if (bounds_affects_clip(flags) && 826 if (bounds_affects_clip(flags) &&
820 !fMCRec->fRasterClip->op(ir, SkRegion::kIntersect_Op)) { 827 !fMCRec->fRasterClip->op(ir, op)) {
821 return false; 828 return false;
822 } 829 }
823 830
824 if (intersection) { 831 if (intersection) {
825 *intersection = ir; 832 *intersection = ir;
826 } 833 }
827 return true; 834 return true;
828 } 835 }
829 836
830 int SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint, 837 int SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint,
831 SaveFlags flags) { 838 SaveFlags flags) {
832 return this->internalSaveLayer(bounds, paint, flags, false); 839 return this->internalSaveLayer(bounds, paint, flags, false);
833 } 840 }
834 841
835 int SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, 842 int SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint,
836 SaveFlags flags, bool justForImageFilter) { 843 SaveFlags flags, bool justForImageFilter) {
837 // do this before we create the layer. We don't call the public save() since 844 // do this before we create the layer. We don't call the public save() since
838 // that would invoke a possibly overridden virtual 845 // that would invoke a possibly overridden virtual
839 int count = this->internalSave(flags); 846 int count = this->internalSave(flags);
840 847
841 fDeviceCMDirty = true; 848 fDeviceCMDirty = true;
842 849
843 SkIRect ir; 850 SkIRect ir;
844 if (!this->clipRectBounds(bounds, flags, &ir)) { 851 if (!this->clipRectBounds(bounds, flags, &ir, paint ? paint->getImageFilter( ) : NULL)) {
845 return count; 852 return count;
846 } 853 }
847 854
848 // Kill the imagefilter if our device doesn't allow it 855 // Kill the imagefilter if our device doesn't allow it
849 SkLazyPaint lazyP; 856 SkLazyPaint lazyP;
850 if (paint && paint->getImageFilter()) { 857 if (paint && paint->getImageFilter()) {
851 if (!this->getTopDevice()->allowImageFilter(paint->getImageFilter())) { 858 if (!this->getTopDevice()->allowImageFilter(paint->getImageFilter())) {
852 if (justForImageFilter) { 859 if (justForImageFilter) {
853 // early exit if the layer was just for the imageFilter 860 // early exit if the layer was just for the imageFilter
854 return count; 861 return count;
(...skipping 1363 matching lines...) Expand 10 before | Expand all | Expand 10 after
2218 return *paint; 2225 return *paint;
2219 } 2226 }
2220 2227
2221 const SkRegion& SkCanvas::LayerIter::clip() const { return fImpl->getClip(); } 2228 const SkRegion& SkCanvas::LayerIter::clip() const { return fImpl->getClip(); }
2222 int SkCanvas::LayerIter::x() const { return fImpl->getX(); } 2229 int SkCanvas::LayerIter::x() const { return fImpl->getX(); }
2223 int SkCanvas::LayerIter::y() const { return fImpl->getY(); } 2230 int SkCanvas::LayerIter::y() const { return fImpl->getY(); }
2224 2231
2225 /////////////////////////////////////////////////////////////////////////////// 2232 ///////////////////////////////////////////////////////////////////////////////
2226 2233
2227 SkCanvas::ClipVisitor::~ClipVisitor() { } 2234 SkCanvas::ClipVisitor::~ClipVisitor() { }
OLDNEW
« no previous file with comments | « include/effects/SkOffsetImageFilter.h ('k') | src/core/SkImageFilter.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698