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 RenderFlowThread_h 31 #define RenderFlowThread_h 32 33 34 #include "core/rendering/RenderBlockFlow.h" 35 #include "wtf/HashCountedSet.h" 36 #include "wtf/ListHashSet.h" 37 #include "wtf/PassRefPtr.h" 38 39 namespace blink { 40 41 struct LayerFragment; 42 typedef Vector<LayerFragment, 1> LayerFragments; 43 class RenderFlowThread; 44 class RenderMultiColumnSet; 45 class RenderRegion; 46 47 typedef ListHashSet<RenderMultiColumnSet*> RenderMultiColumnSetList; 48 49 // RenderFlowThread is used to collect all the render objects that participate in a 50 // flow thread. It will also help in doing the layout. However, it will not render 51 // directly to screen. Instead, RenderRegion objects will redirect their paint 52 // and nodeAtPoint methods to this object. Each RenderRegion will actually be a viewPort 53 // of the RenderFlowThread. 54 55 class RenderFlowThread: public RenderBlockFlow { 56 public: 57 RenderFlowThread(); ~RenderFlowThread()58 virtual ~RenderFlowThread() { }; 59 isRenderFlowThread()60 virtual bool isRenderFlowThread() const OVERRIDE FINAL { return true; } isRenderMultiColumnFlowThread()61 virtual bool isRenderMultiColumnFlowThread() const { return false; } isRenderPagedFlowThread()62 virtual bool isRenderPagedFlowThread() const { return false; } 63 64 virtual void layout() OVERRIDE; 65 66 // Always create a RenderLayer for the RenderFlowThread so that we 67 // can easily avoid drawing the children directly. layerTypeRequired()68 virtual LayerType layerTypeRequired() const OVERRIDE FINAL { return NormalLayer; } 69 70 virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE FINAL; 71 72 virtual void addRegionToThread(RenderMultiColumnSet*) = 0; 73 virtual void removeRegionFromThread(RenderMultiColumnSet*); 74 75 virtual void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues&) const OVERRIDE; 76 hasRegions()77 bool hasRegions() const { return m_multiColumnSetList.size(); } 78 79 void validateRegions(); 80 void invalidateRegions(); hasValidRegionInfo()81 bool hasValidRegionInfo() const { return !m_regionsInvalidated && !m_multiColumnSetList.isEmpty(); } 82 83 void paintInvalidationRectangleInRegions(const LayoutRect&) const; 84 85 LayoutUnit pageLogicalHeightForOffset(LayoutUnit); 86 LayoutUnit pageRemainingLogicalHeightForOffset(LayoutUnit, PageBoundaryRule = IncludePageBoundary); 87 setPageBreak(LayoutUnit,LayoutUnit)88 virtual void setPageBreak(LayoutUnit /*offset*/, LayoutUnit /*spaceShortage*/) { } updateMinimumPageHeight(LayoutUnit,LayoutUnit)89 virtual void updateMinimumPageHeight(LayoutUnit /*offset*/, LayoutUnit /*minHeight*/) { } 90 regionsHaveUniformLogicalHeight()91 bool regionsHaveUniformLogicalHeight() const { return m_regionsHaveUniformLogicalHeight; } 92 93 // FIXME: These 2 functions should return a RenderMultiColumnSet. 94 RenderRegion* firstRegion() const; 95 RenderRegion* lastRegion() const; 96 97 virtual bool addForcedRegionBreak(LayoutUnit, RenderObject* breakChild, bool isBefore, LayoutUnit* offsetBreakAdjustment = 0) { return false; } 98 isPageLogicalHeightKnown()99 virtual bool isPageLogicalHeightKnown() const { return true; } pageLogicalSizeChanged()100 bool pageLogicalSizeChanged() const { return m_pageLogicalSizeChanged; } 101 102 void collectLayerFragments(LayerFragments&, const LayoutRect& layerBoundingBox, const LayoutRect& dirtyRect); 103 LayoutRect fragmentsBoundingBox(const LayoutRect& layerBoundingBox); 104 105 void pushFlowThreadLayoutState(const RenderObject&); 106 void popFlowThreadLayoutState(); 107 LayoutUnit offsetFromLogicalTopOfFirstRegion(const RenderBlock*) const; 108 109 // Used to estimate the maximum height of the flow thread. maxLogicalHeight()110 static LayoutUnit maxLogicalHeight() { return LayoutUnit::max() / 2; } 111 112 protected: 113 virtual const char* renderName() const = 0; 114 115 void updateRegionsFlowThreadPortionRect(); 116 bool shouldIssuePaintInvalidations(const LayoutRect&) const; 117 118 virtual RenderMultiColumnSet* columnSetAtBlockOffset(LayoutUnit) const = 0; 119 120 bool cachedOffsetFromLogicalTopOfFirstRegion(const RenderBox*, LayoutUnit&) const; 121 void setOffsetFromLogicalTopOfFirstRegion(const RenderBox*, LayoutUnit); 122 void clearOffsetFromLogicalTopOfFirstRegion(const RenderBox*); 123 124 const RenderBox* currentStatePusherRenderBox() const; 125 126 RenderMultiColumnSetList m_multiColumnSetList; 127 128 class RenderMultiColumnSetRange { 129 public: RenderMultiColumnSetRange()130 RenderMultiColumnSetRange() 131 { 132 setRange(0, 0); 133 } 134 RenderMultiColumnSetRange(RenderMultiColumnSet * start,RenderMultiColumnSet * end)135 RenderMultiColumnSetRange(RenderMultiColumnSet* start, RenderMultiColumnSet* end) 136 { 137 setRange(start, end); 138 } 139 setRange(RenderMultiColumnSet * start,RenderMultiColumnSet * end)140 void setRange(RenderMultiColumnSet* start, RenderMultiColumnSet* end) 141 { 142 m_startColumnSet = start; 143 m_endColumnSet = end; 144 } 145 startColumnSet()146 RenderMultiColumnSet* startColumnSet() const { return m_startColumnSet; } endColumnSet()147 RenderMultiColumnSet* endColumnSet() const { return m_endColumnSet; } 148 149 private: 150 RenderMultiColumnSet* m_startColumnSet; 151 RenderMultiColumnSet* m_endColumnSet; 152 }; 153 154 typedef PODInterval<LayoutUnit, RenderMultiColumnSet*> MultiColumnSetInterval; 155 typedef PODIntervalTree<LayoutUnit, RenderMultiColumnSet*> MultiColumnSetIntervalTree; 156 157 class RegionSearchAdapter { 158 public: RegionSearchAdapter(LayoutUnit offset)159 RegionSearchAdapter(LayoutUnit offset) 160 : m_offset(offset) 161 , m_result(0) 162 { 163 } 164 lowValue()165 const LayoutUnit& lowValue() const { return m_offset; } highValue()166 const LayoutUnit& highValue() const { return m_offset; } 167 void collectIfNeeded(const MultiColumnSetInterval&); 168 result()169 RenderRegion* result() const { return m_result; } 170 171 private: 172 LayoutUnit m_offset; 173 RenderRegion* m_result; 174 }; 175 176 // Stack of objects that pushed a LayoutState object on the RenderView. The 177 // objects on the stack are the ones that are curently in the process of being 178 // laid out. 179 ListHashSet<const RenderObject*> m_statePusherObjectsStack; 180 typedef HashMap<const RenderBox*, LayoutUnit> RenderBoxToOffsetMap; 181 RenderBoxToOffsetMap m_boxesToOffsetMap; 182 183 MultiColumnSetIntervalTree m_multiColumnSetIntervalTree; 184 185 bool m_regionsInvalidated : 1; 186 bool m_regionsHaveUniformLogicalHeight : 1; 187 bool m_pageLogicalSizeChanged : 1; 188 }; 189 190 DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderFlowThread, isRenderFlowThread()); 191 192 class CurrentRenderFlowThreadMaintainer { 193 WTF_MAKE_NONCOPYABLE(CurrentRenderFlowThreadMaintainer); 194 public: 195 CurrentRenderFlowThreadMaintainer(RenderFlowThread*); 196 ~CurrentRenderFlowThreadMaintainer(); 197 private: 198 RenderFlowThread* m_renderFlowThread; 199 RenderFlowThread* m_previousRenderFlowThread; 200 }; 201 202 // These structures are used by PODIntervalTree for debugging. 203 #ifndef NDEBUG 204 template <> struct ValueToString<LayoutUnit> { 205 static String string(const LayoutUnit value) { return String::number(value.toFloat()); } 206 }; 207 208 template <> struct ValueToString<RenderMultiColumnSet*> { 209 static String string(const RenderMultiColumnSet* value) { return String::format("%p", value); } 210 }; 211 #endif 212 213 } // namespace blink 214 215 #endif // RenderFlowThread_h 216