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 627 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |