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

Side by Side Diff: Source/core/html/canvas/CanvasRenderingContext2D.cpp

Issue 1194733002: Adding the 'filter' context attribute to 2D canvas (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: applied corrections Created 5 years, 6 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved. 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
3 * Copyright (C) 2008, 2010 Nokia Corporation and/or its subsidiary(-ies) 3 * Copyright (C) 2008, 2010 Nokia Corporation and/or its subsidiary(-ies)
4 * Copyright (C) 2007 Alp Toker <alp@atoker.com> 4 * Copyright (C) 2007 Alp Toker <alp@atoker.com>
5 * Copyright (C) 2008 Eric Seidel <eric@webkit.org> 5 * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
6 * Copyright (C) 2008 Dirk Schulze <krit@webkit.org> 6 * Copyright (C) 2008 Dirk Schulze <krit@webkit.org>
7 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. 7 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved.
8 * Copyright (C) 2012, 2013 Intel Corporation. All rights reserved. 8 * Copyright (C) 2012, 2013 Intel Corporation. All rights reserved.
9 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved. 9 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
10 * 10 *
(...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after
638 UseCounter::countDeprecation(canvas()->document(), UseCounter::Canva sRenderingContext2DCompositeOperationDarker); 638 UseCounter::countDeprecation(canvas()->document(), UseCounter::Canva sRenderingContext2DCompositeOperationDarker);
639 } 639 }
640 if (!parseCompositeAndBlendOperator(operationName, op, blendMode)) 640 if (!parseCompositeAndBlendOperator(operationName, op, blendMode))
641 return; 641 return;
642 SkXfermode::Mode xfermode = WebCoreCompositeToSkiaComposite(op, blendMode); 642 SkXfermode::Mode xfermode = WebCoreCompositeToSkiaComposite(op, blendMode);
643 if (state().globalComposite() == xfermode) 643 if (state().globalComposite() == xfermode)
644 return; 644 return;
645 modifiableState().setGlobalComposite(xfermode); 645 modifiableState().setGlobalComposite(xfermode);
646 } 646 }
647 647
648 String CanvasRenderingContext2D::filter() const
649 {
650 return state().unparsedFilter();
651 }
652
653 void CanvasRenderingContext2D::setFilter(const String& filterString)
654 {
655 if (filterString == state().unparsedFilter())
656 return;
657
658 RefPtrWillBeRawPtr<CSSValue> filterValue = CSSParser::parseSingleValue(CSSPr opertyWebkitFilter, filterString, CSSParserContext(HTMLStandardMode, 0));
659
660 if (!filterValue || filterValue->isInitialValue() || filterValue->isInherite dValue())
661 return;
662
663 modifiableState().setUnparsedFilter(filterString);
664 modifiableState().setFilter(filterValue.release());
665 }
666
648 PassRefPtrWillBeRawPtr<SVGMatrixTearOff> CanvasRenderingContext2D::currentTransf orm() const 667 PassRefPtrWillBeRawPtr<SVGMatrixTearOff> CanvasRenderingContext2D::currentTransf orm() const
649 { 668 {
650 return SVGMatrixTearOff::create(state().transform()); 669 return SVGMatrixTearOff::create(state().transform());
651 } 670 }
652 671
653 void CanvasRenderingContext2D::setCurrentTransform(PassRefPtrWillBeRawPtr<SVGMat rixTearOff> passMatrixTearOff) 672 void CanvasRenderingContext2D::setCurrentTransform(PassRefPtrWillBeRawPtr<SVGMat rixTearOff> passMatrixTearOff)
654 { 673 {
655 RefPtrWillBeRawPtr<SVGMatrixTearOff> matrixTearOff = passMatrixTearOff; 674 RefPtrWillBeRawPtr<SVGMatrixTearOff> matrixTearOff = passMatrixTearOff;
656 const AffineTransform& transform = matrixTearOff->value(); 675 const AffineTransform& transform = matrixTearOff->value();
657 setTransform(transform.a(), transform.b(), transform.c(), transform.d(), tra nsform.e(), transform.f()); 676 setTransform(transform.a(), transform.b(), transform.c(), transform.d(), tra nsform.e(), transform.f());
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
809 828
810 static bool isFullCanvasCompositeMode(SkXfermode::Mode op) 829 static bool isFullCanvasCompositeMode(SkXfermode::Mode op)
811 { 830 {
812 // See 4.8.11.1.3 Compositing 831 // See 4.8.11.1.3 Compositing
813 // CompositeSourceAtop and CompositeDestinationOut are not listed here as th e platforms already 832 // CompositeSourceAtop and CompositeDestinationOut are not listed here as th e platforms already
814 // implement the specification's behavior. 833 // implement the specification's behavior.
815 return op == SkXfermode::kSrcIn_Mode || op == SkXfermode::kSrcOut_Mode || op == SkXfermode::kDstIn_Mode || op == SkXfermode::kDstATop_Mode; 834 return op == SkXfermode::kSrcIn_Mode || op == SkXfermode::kSrcOut_Mode || op == SkXfermode::kDstIn_Mode || op == SkXfermode::kDstATop_Mode;
816 } 835 }
817 836
818 template<typename DrawFunc> 837 template<typename DrawFunc>
819 void CanvasRenderingContext2D::fullCanvasCompositedDraw(const DrawFunc& drawFunc , CanvasRenderingContext2DState::PaintType paintType, CanvasRenderingContext2DSt ate::ImageType imageType) 838 void CanvasRenderingContext2D::compositedDraw(const DrawFunc& drawFunc, CanvasRe nderingContext2DState::PaintType paintType, CanvasRenderingContext2DState::Image Type imageType)
820 { 839 {
821 ASSERT(isFullCanvasCompositeMode(state().globalComposite())); 840 SkImageFilter* filter = state().getFilter(canvas(), accessFont());
841 ASSERT(isFullCanvasCompositeMode(state().globalComposite()) || filter);
822 ASSERT(drawingCanvas()); 842 ASSERT(drawingCanvas());
823 843 SkMatrix ctm = drawingCanvas()->getTotalMatrix();
824 SkPaint layerPaint; 844 drawingCanvas()->resetMatrix();
825 layerPaint.setXfermodeMode(state().globalComposite()); 845 SkPaint compositePaint;
846 compositePaint.setXfermodeMode(state().globalComposite());
826 if (state().shouldDrawShadows()) { 847 if (state().shouldDrawShadows()) {
827 // unroll into two independently composited passes if drawing shadows 848 // unroll into two independently composited passes if drawing shadows
828 drawingCanvas()->saveLayer(nullptr, &layerPaint);
829 SkPaint shadowPaint = *state().getPaint(paintType, DrawShadowOnly, image Type); 849 SkPaint shadowPaint = *state().getPaint(paintType, DrawShadowOnly, image Type);
830 shadowPaint.setXfermodeMode(SkXfermode::kSrcOver_Mode); 850 int saveCount = drawingCanvas()->getSaveCount();
831 drawFunc(&shadowPaint); 851 if (filter) {
852 SkPaint filterPaint;
853 filterPaint.setImageFilter(filter);
854 // TODO(junov): crbug.com/502921 We could use primitive bounds if we knew that the filter
855 // does not affect transparent black regions.
856 drawingCanvas()->saveLayer(nullptr, &shadowPaint);
857 drawingCanvas()->saveLayer(nullptr, &filterPaint);
858 SkPaint foregroundPaint = *state().getPaint(paintType, DrawForegroun dOnly, imageType);
859 drawingCanvas()->setMatrix(ctm);
860 drawFunc(&foregroundPaint);
861 } else {
862 ASSERT(isFullCanvasCompositeMode(state().globalComposite()));
863 drawingCanvas()->saveLayer(nullptr, &compositePaint);
864 shadowPaint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
865 drawingCanvas()->setMatrix(ctm);
866 drawFunc(&shadowPaint);
867 }
832 if (!drawingCanvas()) 868 if (!drawingCanvas())
833 return; 869 return;
834 drawingCanvas()->restore(); 870 drawingCanvas()->restoreToCount(saveCount);
835 } 871 }
836 872
837 drawingCanvas()->saveLayer(nullptr, &layerPaint); 873 compositePaint.setImageFilter(filter);
874 // TODO(junov): crbug.com/502921 We could use primitive bounds if we knew th at the filter
875 // does not affect transparent black regions *and* !isFullCanvasCompositeMod e
876 drawingCanvas()->saveLayer(nullptr, &compositePaint);
838 SkPaint foregroundPaint = *state().getPaint(paintType, DrawForegroundOnly, i mageType); 877 SkPaint foregroundPaint = *state().getPaint(paintType, DrawForegroundOnly, i mageType);
839 foregroundPaint.setXfermodeMode(SkXfermode::kSrcOver_Mode); 878 foregroundPaint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
879 drawingCanvas()->setMatrix(ctm);
840 drawFunc(&foregroundPaint); 880 drawFunc(&foregroundPaint);
841 if (!drawingCanvas()) 881 if (!drawingCanvas())
842 return; 882 return;
843 drawingCanvas()->restore(); 883 drawingCanvas()->restore();
884 drawingCanvas()->setMatrix(ctm);
844 } 885 }
845 886
846 template<typename DrawFunc, typename ContainsFunc> 887 template<typename DrawFunc, typename ContainsFunc>
847 bool CanvasRenderingContext2D::draw(const DrawFunc& drawFunc, const ContainsFunc & drawCoversClipBounds, const SkRect& bounds, CanvasRenderingContext2DState::Pai ntType paintType, CanvasRenderingContext2DState::ImageType imageType) 888 bool CanvasRenderingContext2D::draw(const DrawFunc& drawFunc, const ContainsFunc & drawCoversClipBounds, const SkRect& bounds, CanvasRenderingContext2DState::Pai ntType paintType, CanvasRenderingContext2DState::ImageType imageType)
848 { 889 {
849 if (!state().isTransformInvertible()) 890 if (!state().isTransformInvertible())
850 return false; 891 return false;
851 892
852 SkIRect clipBounds; 893 SkIRect clipBounds;
853 if (!drawingCanvas() || !drawingCanvas()->getClipDeviceBounds(&clipBounds)) 894 if (!drawingCanvas() || !drawingCanvas()->getClipDeviceBounds(&clipBounds))
854 return false; 895 return false;
855 896
856 // If gradient size is zero, then paint nothing. 897 // If gradient size is zero, then paint nothing.
857 CanvasStyle* style = state().style(paintType); 898 CanvasStyle* style = state().style(paintType);
858 if (style) { 899 if (style) {
859 CanvasGradient* gradient = style->canvasGradient(); 900 CanvasGradient* gradient = style->canvasGradient();
860 if (gradient && gradient->gradient()->isZeroSize()) 901 if (gradient && gradient->gradient()->isZeroSize())
861 return false; 902 return false;
862 } 903 }
863 904
864 if (isFullCanvasCompositeMode(state().globalComposite())) { 905 if (isFullCanvasCompositeMode(state().globalComposite()) || state().hasFilte r()) {
865 fullCanvasCompositedDraw(drawFunc, paintType, imageType); 906 compositedDraw(drawFunc, paintType, imageType);
866 didDraw(clipBounds); 907 didDraw(clipBounds);
867 } else if (state().globalComposite() == SkXfermode::kSrc_Mode) { 908 } else if (state().globalComposite() == SkXfermode::kSrc_Mode) {
868 clearCanvas(); // takes care of checkOvewrdraw() 909 clearCanvas(); // takes care of checkOvewrdraw()
869 const SkPaint* paint = state().getPaint(paintType, DrawForegroundOnly, i mageType); 910 const SkPaint* paint = state().getPaint(paintType, DrawForegroundOnly, i mageType);
870 drawFunc(paint); 911 drawFunc(paint);
871 didDraw(clipBounds); 912 didDraw(clipBounds);
872 } else { 913 } else {
873 SkIRect dirtyRect; 914 SkIRect dirtyRect;
874 if (computeDirtyRect(bounds, clipBounds, &dirtyRect)) { 915 if (computeDirtyRect(bounds, clipBounds, &dirtyRect)) {
875 const SkPaint* paint = state().getPaint(paintType, DrawShadowAndFore ground, imageType); 916 const SkPaint* paint = state().getPaint(paintType, DrawShadowAndFore ground, imageType);
(...skipping 1359 matching lines...) Expand 10 before | Expand all | Expand 10 after
2235 if (imageType == CanvasRenderingContext2DState::NonOpaqueImage) 2276 if (imageType == CanvasRenderingContext2DState::NonOpaqueImage)
2236 return; 2277 return;
2237 if (alpha < 0xFF) 2278 if (alpha < 0xFF)
2238 return; 2279 return;
2239 } 2280 }
2240 2281
2241 canvas()->buffer()->willOverwriteCanvas(); 2282 canvas()->buffer()->willOverwriteCanvas();
2242 } 2283 }
2243 2284
2244 } // namespace blink 2285 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/html/canvas/CanvasRenderingContext2D.h ('k') | Source/core/html/canvas/CanvasRenderingContext2D.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698