1/* 2 * Copyright (C) 2011 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 RenderRegion_h 31#define RenderRegion_h 32 33#include "RenderBlock.h" 34#include "StyleInheritedData.h" 35 36namespace WebCore { 37 38struct LayerFragment; 39typedef Vector<LayerFragment, 1> LayerFragments; 40class RenderBox; 41class RenderBoxRegionInfo; 42class RenderFlowThread; 43class RenderNamedFlowThread; 44 45class RenderRegion : public RenderBlock { 46public: 47 explicit RenderRegion(Element*, RenderFlowThread*); 48 49 virtual bool isRenderRegion() const { return true; } 50 51 virtual bool hitTestContents(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE; 52 53 virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle); 54 55 void setFlowThreadPortionRect(const LayoutRect& rect) { m_flowThreadPortionRect = rect; } 56 LayoutRect flowThreadPortionRect() const { return m_flowThreadPortionRect; } 57 LayoutRect flowThreadPortionOverflowRect() const; 58 59 void attachRegion(); 60 void detachRegion(); 61 62 RenderNamedFlowThread* parentNamedFlowThread() const { return m_parentNamedFlowThread; } 63 RenderFlowThread* flowThread() const { return m_flowThread; } 64 65 // Valid regions do not create circular dependencies with other flows. 66 bool isValid() const { return m_isValid; } 67 void setIsValid(bool valid) { m_isValid = valid; } 68 69 bool hasCustomRegionStyle() const { return m_hasCustomRegionStyle; } 70 void setHasCustomRegionStyle(bool hasCustomRegionStyle) { m_hasCustomRegionStyle = hasCustomRegionStyle; } 71 72 RenderBoxRegionInfo* renderBoxRegionInfo(const RenderBox*) const; 73 RenderBoxRegionInfo* setRenderBoxRegionInfo(const RenderBox*, LayoutUnit logicalLeftInset, LayoutUnit logicalRightInset, 74 bool containingBlockChainIsInset); 75 PassOwnPtr<RenderBoxRegionInfo> takeRenderBoxRegionInfo(const RenderBox*); 76 void removeRenderBoxRegionInfo(const RenderBox*); 77 78 void deleteAllRenderBoxRegionInfo(); 79 80 bool isFirstRegion() const; 81 bool isLastRegion() const; 82 83 void clearObjectStyleInRegion(const RenderObject*); 84 85 enum RegionState { 86 RegionUndefined, 87 RegionEmpty, 88 RegionFit, 89 RegionOverset 90 }; 91 92 RegionState regionState() const { return isValid() ? m_regionState : RegionUndefined; } 93 void setRegionState(RegionState regionState) { m_regionState = regionState; } 94 95 // These methods represent the width and height of a "page" and for a RenderRegion they are just the 96 // content width and content height of a region. For RenderRegionSets, however, they will be the width and 97 // height of a single column or page in the set. 98 virtual LayoutUnit pageLogicalWidth() const; 99 virtual LayoutUnit pageLogicalHeight() const; 100 LayoutUnit maxPageLogicalHeight() const; 101 102 LayoutUnit logicalTopOfFlowThreadContentRect(const LayoutRect&) const; 103 LayoutUnit logicalBottomOfFlowThreadContentRect(const LayoutRect&) const; 104 LayoutUnit logicalTopForFlowThreadContent() const { return logicalTopOfFlowThreadContentRect(flowThreadPortionRect()); }; 105 LayoutUnit logicalBottomForFlowThreadContent() const { return logicalBottomOfFlowThreadContentRect(flowThreadPortionRect()); }; 106 107 void getRanges(Vector<RefPtr<Range> >&) const; 108 109 // This method represents the logical height of the entire flow thread portion used by the region or set. 110 // For RenderRegions it matches logicalPaginationHeight(), but for sets it is the height of all the pages 111 // or columns added together. 112 virtual LayoutUnit logicalHeightOfAllFlowThreadContent() const; 113 114 bool hasAutoLogicalHeight() const { return m_hasAutoLogicalHeight; } 115 116 virtual void updateLogicalHeight() OVERRIDE; 117 118 // The top of the nearest page inside the region. For RenderRegions, this is just the logical top of the 119 // flow thread portion we contain. For sets, we have to figure out the top of the nearest column or 120 // page. 121 virtual LayoutUnit pageLogicalTopForOffset(LayoutUnit offset) const; 122 123 virtual void expandToEncompassFlowThreadContentsIfNeeded() { }; 124 125 // Whether or not this region is a set. 126 virtual bool isRenderRegionSet() const { return false; } 127 128 virtual void repaintFlowThreadContent(const LayoutRect& repaintRect, bool immediate) const; 129 130 virtual void collectLayerFragments(LayerFragments&, const LayoutRect&, const LayoutRect&) { } 131 132protected: 133 void setRegionObjectsRegionStyle(); 134 void restoreRegionObjectsOriginalStyle(); 135 136 virtual void computePreferredLogicalWidths() OVERRIDE; 137 virtual void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const OVERRIDE; 138 139 LayoutRect overflowRectForFlowThreadPortion(const LayoutRect& flowThreadPortionRect, bool isFirstPortion, bool isLastPortion) const; 140 void repaintFlowThreadContentRectangle(const LayoutRect& repaintRect, bool immediate, const LayoutRect& flowThreadPortionRect, 141 const LayoutRect& flowThreadPortionOverflowRect, const LayoutPoint& regionLocation) const; 142 143 virtual bool shouldHaveAutoLogicalHeight() const; 144 145private: 146 virtual const char* renderName() const { return "RenderRegion"; } 147 148 virtual bool canHaveChildren() const OVERRIDE { return false; } 149 virtual bool canHaveGeneratedChildren() const OVERRIDE { return true; } 150 151 virtual void insertedIntoTree() OVERRIDE; 152 virtual void willBeRemovedFromTree() OVERRIDE; 153 154 virtual void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0) OVERRIDE; 155 virtual void paintObject(PaintInfo&, const LayoutPoint&) OVERRIDE; 156 157 virtual void installFlowThread(); 158 159 PassRefPtr<RenderStyle> computeStyleInRegion(const RenderObject*); 160 void computeChildrenStyleInRegion(const RenderObject*); 161 void setObjectStyleInRegion(RenderObject*, PassRefPtr<RenderStyle>, bool objectRegionStyleCached); 162 163 void checkRegionStyle(); 164 void updateRegionHasAutoLogicalHeightFlag(); 165 166 void incrementAutoLogicalHeightCount(); 167 void decrementAutoLogicalHeightCount(); 168 169protected: 170 RenderFlowThread* m_flowThread; 171 172private: 173 // If this RenderRegion is displayed as part of another named flow, 174 // we need to create a dependency tree, so that layout of the 175 // regions is always done before the regions themselves. 176 RenderNamedFlowThread* m_parentNamedFlowThread; 177 LayoutRect m_flowThreadPortionRect; 178 179 // This map holds unique information about a block that is split across regions. 180 // A RenderBoxRegionInfo* tells us about any layout information for a RenderBox that 181 // is unique to the region. For now it just holds logical width information for RenderBlocks, but eventually 182 // it will also hold a custom style for any box (for region styling). 183 typedef HashMap<const RenderBox*, OwnPtr<RenderBoxRegionInfo> > RenderBoxRegionInfoMap; 184 RenderBoxRegionInfoMap m_renderBoxRegionInfo; 185 186 struct ObjectRegionStyleInfo { 187 // Used to store the original style of the object in region 188 // so that the original style is properly restored after paint. 189 // Also used to store computed style of the object in region between 190 // region paintings, so that the style in region is computed only 191 // when necessary. 192 RefPtr<RenderStyle> style; 193 // True if the computed style in region is cached. 194 bool cached; 195 }; 196 typedef HashMap<const RenderObject*, ObjectRegionStyleInfo > RenderObjectRegionStyleMap; 197 RenderObjectRegionStyleMap m_renderObjectRegionStyle; 198 199 bool m_isValid : 1; 200 bool m_hasCustomRegionStyle : 1; 201 bool m_hasAutoLogicalHeight : 1; 202 RegionState m_regionState; 203}; 204 205inline RenderRegion* toRenderRegion(RenderObject* object) 206{ 207 ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isRenderRegion()); 208 return static_cast<RenderRegion*>(object); 209} 210 211inline const RenderRegion* toRenderRegion(const RenderObject* object) 212{ 213 ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isRenderRegion()); 214 return static_cast<const RenderRegion*>(object); 215} 216 217// This will catch anyone doing an unnecessary cast. 218void toRenderRegion(const RenderRegion*); 219 220} // namespace WebCore 221 222#endif // RenderRegion_h 223