OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |