/* * Copyright (C) 2012, 2013 Adobe Systems Incorporated. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef ClipPathOperation_h #define ClipPathOperation_h #include "BasicShapes.h" #include "Path.h" #include "RenderStyleConstants.h" #include #include #include namespace WebCore { class ClipPathOperation : public RefCounted { public: enum OperationType { Reference, Shape, Box }; virtual ~ClipPathOperation() { } virtual bool operator==(const ClipPathOperation&) const = 0; bool operator!=(const ClipPathOperation& o) const { return !(*this == o); } OperationType type() const { return m_type; } bool isSameType(const ClipPathOperation& o) const { return o.type() == m_type; } protected: explicit ClipPathOperation(OperationType type) : m_type(type) { } OperationType m_type; }; class ReferenceClipPathOperation final : public ClipPathOperation { public: static Ref create(const String& url, const String& fragment) { return adoptRef(*new ReferenceClipPathOperation(url, fragment)); } const String& url() const { return m_url; } const String& fragment() const { return m_fragment; } private: virtual bool operator==(const ClipPathOperation& other) const override { if (!isSameType(other)) return false; auto& referenceClip = downcast(other); return m_url == referenceClip.m_url; } ReferenceClipPathOperation(const String& url, const String& fragment) : ClipPathOperation(Reference) , m_url(url) , m_fragment(fragment) { } String m_url; String m_fragment; }; class ShapeClipPathOperation final : public ClipPathOperation { public: static Ref create(Ref&& shape) { return adoptRef(*new ShapeClipPathOperation(WTFMove(shape))); } const BasicShape& basicShape() const { return m_shape; } WindRule windRule() const { return m_shape.get().windRule(); } const Path& pathForReferenceRect(const FloatRect& boundingRect) { return m_shape.get().path(boundingRect); } void setReferenceBox(CSSBoxType referenceBox) { m_referenceBox = referenceBox; } CSSBoxType referenceBox() const { return m_referenceBox; } private: virtual bool operator==(const ClipPathOperation& other) const override { if (!isSameType(other)) return false; auto& shapeClip = downcast(other); return m_referenceBox == shapeClip.referenceBox() && (m_shape.ptr() == shapeClip.m_shape.ptr() || m_shape.get() == shapeClip.m_shape.get()); } explicit ShapeClipPathOperation(Ref&& shape) : ClipPathOperation(Shape) , m_shape(WTFMove(shape)) , m_referenceBox(BoxMissing) { } Ref m_shape; CSSBoxType m_referenceBox; }; class BoxClipPathOperation final : public ClipPathOperation { public: static Ref create(CSSBoxType referenceBox) { return adoptRef(*new BoxClipPathOperation(referenceBox)); } const Path pathForReferenceRect(const FloatRoundedRect& boundingRect) const { Path path; path.addRoundedRect(boundingRect); return path; } CSSBoxType referenceBox() const { return m_referenceBox; } private: virtual bool operator==(const ClipPathOperation& other) const override { if (!isSameType(other)) return false; auto& boxClip = downcast(other); return m_referenceBox == boxClip.m_referenceBox; } explicit BoxClipPathOperation(CSSBoxType referenceBox) : ClipPathOperation(Box) , m_referenceBox(referenceBox) { } CSSBoxType m_referenceBox; }; } // namespace WebCore #define SPECIALIZE_TYPE_TRAITS_CLIP_PATH_OPERATION(ToValueTypeName, predicate) \ SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToValueTypeName) \ static bool isType(const WebCore::ClipPathOperation& operation) { return operation.type() == WebCore::predicate; } \ SPECIALIZE_TYPE_TRAITS_END() SPECIALIZE_TYPE_TRAITS_CLIP_PATH_OPERATION(ReferenceClipPathOperation, ClipPathOperation::Reference) SPECIALIZE_TYPE_TRAITS_CLIP_PATH_OPERATION(ShapeClipPathOperation, ClipPathOperation::Shape) SPECIALIZE_TYPE_TRAITS_CLIP_PATH_OPERATION(BoxClipPathOperation, ClipPathOperation::Box) #endif // ClipPathOperation_h