Chromium Code Reviews| 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 |