1/*
2 * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above
9 *    copyright notice, this list of conditions and the following
10 *    disclaimer.
11 * 2. Redistributions in binary form must reproduce the above
12 *    copyright notice, this list of conditions and the following
13 *    disclaimer in the documentation and/or other materials
14 *    provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
21 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
25 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
26 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#ifndef ShapeOutsideInfo_h
31#define ShapeOutsideInfo_h
32
33#if ENABLE(CSS_SHAPES)
34
35#include "LayoutSize.h"
36#include "Shape.h"
37#include <wtf/HashMap.h>
38
39namespace WebCore {
40
41class RenderBlockFlow;
42class RenderBox;
43class StyleImage;
44class FloatingObject;
45
46class ShapeOutsideInfo final {
47    WTF_MAKE_FAST_ALLOCATED;
48public:
49    ShapeOutsideInfo(const RenderBox& renderer)
50        : m_renderer(renderer)
51        , m_lineOverlapsShape(false)
52    {
53    }
54
55    static bool isEnabledFor(const RenderBox&);
56
57    LayoutUnit leftMarginBoxDelta() const { return m_leftMarginBoxDelta; }
58    LayoutUnit rightMarginBoxDelta() const { return m_rightMarginBoxDelta; }
59    bool lineOverlapsShape() const { return m_lineOverlapsShape; }
60
61    void updateDeltasForContainingBlockLine(const RenderBlockFlow&, const FloatingObject&, LayoutUnit lineTop, LayoutUnit lineHeight);
62
63    void setReferenceBoxLogicalSize(LayoutSize);
64
65    LayoutUnit shapeLogicalTop() const { return computedShape().shapeMarginLogicalBoundingBox().y() + logicalTopOffset(); }
66    LayoutUnit shapeLogicalBottom() const { return computedShape().shapeMarginLogicalBoundingBox().maxY() + logicalTopOffset(); }
67    LayoutUnit shapeLogicalLeft() const { return computedShape().shapeMarginLogicalBoundingBox().x() + logicalLeftOffset(); }
68    LayoutUnit shapeLogicalRight() const { return computedShape().shapeMarginLogicalBoundingBox().maxX() + logicalLeftOffset(); }
69    LayoutUnit shapeLogicalWidth() const { return computedShape().shapeMarginLogicalBoundingBox().width(); }
70    LayoutUnit shapeLogicalHeight() const { return computedShape().shapeMarginLogicalBoundingBox().height(); }
71
72    LayoutUnit logicalLineTop() const { return m_referenceBoxLineTop + logicalTopOffset(); }
73    LayoutUnit logicalLineBottom() const { return m_referenceBoxLineTop + m_lineHeight + logicalTopOffset(); }
74    LayoutUnit logicalLineBottom(LayoutUnit lineHeight) const { return m_referenceBoxLineTop + lineHeight + logicalTopOffset(); }
75
76    void markShapeAsDirty() { m_shape = nullptr; }
77    bool isShapeDirty() { return !m_shape; }
78
79    LayoutRect computedShapePhysicalBoundingBox() const;
80    FloatPoint shapeToRendererPoint(const FloatPoint&) const;
81    FloatSize shapeToRendererSize(const FloatSize&) const;
82
83    const Shape& computedShape() const;
84
85    static ShapeOutsideInfo& ensureInfo(const RenderBox& key)
86    {
87        InfoMap& infoMap = ShapeOutsideInfo::infoMap();
88        if (ShapeOutsideInfo* info = infoMap.get(&key))
89            return *info;
90        auto result = infoMap.add(&key, std::make_unique<ShapeOutsideInfo>(key));
91        return *result.iterator->value;
92    }
93    static void removeInfo(const RenderBox& key) { infoMap().remove(&key); }
94    static ShapeOutsideInfo* info(const RenderBox& key) { return infoMap().get(&key); }
95
96private:
97    std::unique_ptr<Shape> createShapeForImage(StyleImage*, float shapeImageThreshold, WritingMode, float margin) const;
98
99    SegmentList computeSegmentsForLine(LayoutUnit lineTop, LayoutUnit lineHeight) const;
100
101    LayoutUnit logicalTopOffset() const;
102    LayoutUnit logicalLeftOffset() const;
103
104    typedef HashMap<const RenderBox*, std::unique_ptr<ShapeOutsideInfo>> InfoMap;
105    static InfoMap& infoMap()
106    {
107        DEPRECATED_DEFINE_STATIC_LOCAL(InfoMap, staticInfoMap, ());
108        return staticInfoMap;
109    }
110
111    const RenderBox& m_renderer;
112
113    mutable std::unique_ptr<Shape> m_shape;
114    LayoutSize m_referenceBoxLogicalSize;
115    LayoutUnit m_referenceBoxLineTop;
116    LayoutUnit m_lineHeight;
117
118    LayoutUnit m_leftMarginBoxDelta;
119    LayoutUnit m_rightMarginBoxDelta;
120    LayoutUnit m_borderBoxLineTop;
121    bool m_lineOverlapsShape;
122};
123
124}
125#endif
126#endif
127