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

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: 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 626 matching lines...) Expand 10 before | Expand all | Expand 10 after
637 UseCounter::countDeprecation(canvas()->document(), UseCounter::Canva sRenderingContext2DCompositeOperationDarker); 637 UseCounter::countDeprecation(canvas()->document(), UseCounter::Canva sRenderingContext2DCompositeOperationDarker);
638 } 638 }
639 if (!parseCompositeAndBlendOperator(operationName, op, blendMode)) 639 if (!parseCompositeAndBlendOperator(operationName, op, blendMode))
640 return; 640 return;
641 SkXfermode::Mode xfermode = WebCoreCompositeToSkiaComposite(op, blendMode); 641 SkXfermode::Mode xfermode = WebCoreCompositeToSkiaComposite(op, blendMode);
642 if (state().globalComposite() == xfermode) 642 if (state().globalComposite() == xfermode)
643 return; 643 return;
644 modifiableState().setGlobalComposite(xfermode); 644 modifiableState().setGlobalComposite(xfermode);
645 } 645 }
646 646
647 String CanvasRenderingContext2D::filter() const
648 {
649 return state().unparsedFilter();
650 }
651
652 void CanvasRenderingContext2D::setFilter(const String& filterString)
653 {
654 if (filterString == state().unparsedFilter())
655 return;
656
657 RefPtrWillBeRawPtr<CSSValue> filterValue = CSSParser::parseSingleValue(CSSPr opertyWebkitFilter, filterString, CSSParserContext(HTMLStandardMode, 0));
658
659 if (!filterValue || filterValue->isInitialValue() || filterValue->isInherite dValue())
660 return;
661
662 modifiableState().setUnparsedFilter(filterString);
663 modifiableState().setFilter(filterValue.release());
664 }
665
647 PassRefPtrWillBeRawPtr<SVGMatrixTearOff> CanvasRenderingContext2D::currentTransf orm() const 666 PassRefPtrWillBeRawPtr<SVGMatrixTearOff> CanvasRenderingContext2D::currentTransf orm() const
648 { 667 {
649 return SVGMatrixTearOff::create(state().transform()); 668 return SVGMatrixTearOff::create(state().transform());
650 } 669 }
651 670
652 void CanvasRenderingContext2D::setCurrentTransform(PassRefPtrWillBeRawPtr<SVGMat rixTearOff> passMatrixTearOff) 671 void CanvasRenderingContext2D::setCurrentTransform(PassRefPtrWillBeRawPtr<SVGMat rixTearOff> passMatrixTearOff)
653 { 672 {
654 RefPtrWillBeRawPtr<SVGMatrixTearOff> matrixTearOff = passMatrixTearOff; 673 RefPtrWillBeRawPtr<SVGMatrixTearOff> matrixTearOff = passMatrixTearOff;
655 const AffineTransform& transform = matrixTearOff->value(); 674 const AffineTransform& transform = matrixTearOff->value();
656 setTransform(transform.a(), transform.b(), transform.c(), transform.d(), tra nsform.e(), transform.f()); 675 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
808 827
809 static bool isFullCanvasCompositeMode(SkXfermode::Mode op) 828 static bool isFullCanvasCompositeMode(SkXfermode::Mode op)
810 { 829 {
811 // See 4.8.11.1.3 Compositing 830 // See 4.8.11.1.3 Compositing
812 // CompositeSourceAtop and CompositeDestinationOut are not listed here as th e platforms already 831 // CompositeSourceAtop and CompositeDestinationOut are not listed here as th e platforms already
813 // implement the specification's behavior. 832 // implement the specification's behavior.
814 return op == SkXfermode::kSrcIn_Mode || op == SkXfermode::kSrcOut_Mode || op == SkXfermode::kDstIn_Mode || op == SkXfermode::kDstATop_Mode; 833 return op == SkXfermode::kSrcIn_Mode || op == SkXfermode::kSrcOut_Mode || op == SkXfermode::kDstIn_Mode || op == SkXfermode::kDstATop_Mode;
815 } 834 }
816 835
817 template<typename DrawFunc> 836 template<typename DrawFunc>
818 void CanvasRenderingContext2D::fullCanvasCompositedDraw(const DrawFunc& drawFunc , CanvasRenderingContext2DState::PaintType paintType, CanvasRenderingContext2DSt ate::ImageType imageType) 837 void CanvasRenderingContext2D::compositedDraw(const DrawFunc& drawFunc, CanvasRe nderingContext2DState::PaintType paintType, CanvasRenderingContext2DState::Image Type imageType)
819 { 838 {
820 ASSERT(isFullCanvasCompositeMode(state().globalComposite())); 839 SkImageFilter* filter = state().filter(canvas(), accessFont());
840 ASSERT(isFullCanvasCompositeMode(state().globalComposite()) || filter);
821 ASSERT(drawingCanvas()); 841 ASSERT(drawingCanvas());
822 842 SkMatrix ctm = drawingCanvas()->getTotalMatrix();
823 SkPaint layerPaint; 843 drawingCanvas()->resetMatrix();
824 layerPaint.setXfermodeMode(state().globalComposite()); 844 SkPaint compositePaint;
845 compositePaint.setXfermodeMode(state().globalComposite());
825 if (state().shouldDrawShadows()) { 846 if (state().shouldDrawShadows()) {
826 // unroll into two independently composited passes if drawing shadows 847 // unroll into two independently composited passes if drawing shadows
827 drawingCanvas()->saveLayer(nullptr, &layerPaint);
828 SkPaint shadowPaint = *state().getPaint(paintType, DrawShadowOnly, image Type); 848 SkPaint shadowPaint = *state().getPaint(paintType, DrawShadowOnly, image Type);
829 shadowPaint.setXfermodeMode(SkXfermode::kSrcOver_Mode); 849 int saveCount = drawingCanvas()->getSaveCount();
830 drawFunc(&shadowPaint); 850 if (filter) {
851 SkPaint filterPaint;
852 filterPaint.setImageFilter(filter);
853 // TODO(junov): crbug.com/502921 We could use primitive bounds if we knew that the filter
Stephen White 2015/06/22 15:28:54 There's actually a traversal to determine the mini
854 // does not affect transparent black regions.
855 drawingCanvas()->saveLayer(nullptr, &shadowPaint);
856 drawingCanvas()->saveLayer(nullptr, &filterPaint);
857 SkPaint foregroundPaint = *state().getPaint(paintType, DrawForegroun dOnly, imageType);
858 drawingCanvas()->setMatrix(ctm);
859 drawFunc(&foregroundPaint);
860 } else {
861 ASSERT(isFullCanvasCompositeMode(state().globalComposite()));
862 drawingCanvas()->saveLayer(nullptr, &compositePaint);
863 shadowPaint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
864 drawingCanvas()->setMatrix(ctm);
865 drawFunc(&shadowPaint);
866 }
831 if (!drawingCanvas()) 867 if (!drawingCanvas())
832 return; 868 return;
833 drawingCanvas()->restore(); 869 drawingCanvas()->restoreToCount(saveCount);
834 } 870 }
835 871
836 drawingCanvas()->saveLayer(nullptr, &layerPaint); 872 compositePaint.setImageFilter(filter);
873 // TODO(junov): crbug.com/502921 We could use primitive bounds if we knew th at the filter
874 // does not affect transparent black regions *and* !isFullCanvasCompositeMod e
875 drawingCanvas()->saveLayer(nullptr, &compositePaint);
837 SkPaint foregroundPaint = *state().getPaint(paintType, DrawForegroundOnly, i mageType); 876 SkPaint foregroundPaint = *state().getPaint(paintType, DrawForegroundOnly, i mageType);
838 foregroundPaint.setXfermodeMode(SkXfermode::kSrcOver_Mode); 877 foregroundPaint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
878 drawingCanvas()->setMatrix(ctm);
839 drawFunc(&foregroundPaint); 879 drawFunc(&foregroundPaint);
840 if (!drawingCanvas()) 880 if (!drawingCanvas())
841 return; 881 return;
842 drawingCanvas()->restore(); 882 drawingCanvas()->restore();
883 drawingCanvas()->setMatrix(ctm);
843 } 884 }
844 885
845 template<typename DrawFunc, typename ContainsFunc> 886 template<typename DrawFunc, typename ContainsFunc>
846 bool CanvasRenderingContext2D::draw(const DrawFunc& drawFunc, const ContainsFunc & drawCoversClipBounds, const SkRect& bounds, CanvasRenderingContext2DState::Pai ntType paintType, CanvasRenderingContext2DState::ImageType imageType) 887 bool CanvasRenderingContext2D::draw(const DrawFunc& drawFunc, const ContainsFunc & drawCoversClipBounds, const SkRect& bounds, CanvasRenderingContext2DState::Pai ntType paintType, CanvasRenderingContext2DState::ImageType imageType)
847 { 888 {
848 if (!state().isTransformInvertible()) 889 if (!state().isTransformInvertible())
849 return false; 890 return false;
850 891
851 SkIRect clipBounds; 892 SkIRect clipBounds;
852 if (!drawingCanvas() || !drawingCanvas()->getClipDeviceBounds(&clipBounds)) 893 if (!drawingCanvas() || !drawingCanvas()->getClipDeviceBounds(&clipBounds))
853 return false; 894 return false;
854 895
855 // If gradient size is zero, then paint nothing. 896 // If gradient size is zero, then paint nothing.
856 CanvasStyle* style = state().style(paintType); 897 CanvasStyle* style = state().style(paintType);
857 if (style) { 898 if (style) {
858 CanvasGradient* gradient = style->canvasGradient(); 899 CanvasGradient* gradient = style->canvasGradient();
859 if (gradient && gradient->gradient()->isZeroSize()) 900 if (gradient && gradient->gradient()->isZeroSize())
860 return false; 901 return false;
861 } 902 }
862 903
863 if (isFullCanvasCompositeMode(state().globalComposite())) { 904 if (isFullCanvasCompositeMode(state().globalComposite()) || state().filter(c anvas(), accessFont())) {
864 fullCanvasCompositedDraw(drawFunc, paintType, imageType); 905 compositedDraw(drawFunc, paintType, imageType);
865 didDraw(clipBounds); 906 didDraw(clipBounds);
866 } else if (state().globalComposite() == SkXfermode::kSrc_Mode) { 907 } else if (state().globalComposite() == SkXfermode::kSrc_Mode) {
867 clearCanvas(); // takes care of checkOvewrdraw() 908 clearCanvas(); // takes care of checkOvewrdraw()
868 const SkPaint* paint = state().getPaint(paintType, DrawForegroundOnly, i mageType); 909 const SkPaint* paint = state().getPaint(paintType, DrawForegroundOnly, i mageType);
869 drawFunc(paint); 910 drawFunc(paint);
870 didDraw(clipBounds); 911 didDraw(clipBounds);
871 } else { 912 } else {
872 SkIRect dirtyRect; 913 SkIRect dirtyRect;
873 if (computeDirtyRect(bounds, clipBounds, &dirtyRect)) { 914 if (computeDirtyRect(bounds, clipBounds, &dirtyRect)) {
874 const SkPaint* paint = state().getPaint(paintType, DrawShadowAndFore ground, imageType); 915 const SkPaint* paint = state().getPaint(paintType, DrawShadowAndFore ground, imageType);
(...skipping 1362 matching lines...) Expand 10 before | Expand all | Expand 10 after
2237 if (imageType == CanvasRenderingContext2DState::NonOpaqueImage) 2278 if (imageType == CanvasRenderingContext2DState::NonOpaqueImage)
2238 return; 2279 return;
2239 if (alpha < 0xFF) 2280 if (alpha < 0xFF)
2240 return; 2281 return;
2241 } 2282 }
2242 2283
2243 canvas()->buffer()->willOverwriteCanvas(); 2284 canvas()->buffer()->willOverwriteCanvas();
2244 } 2285 }
2245 2286
2246 } // namespace blink 2287 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698