summaryrefslogtreecommitdiff
path: root/Source/WebCore/rendering/RenderFlowThread.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/rendering/RenderFlowThread.h')
-rw-r--r--Source/WebCore/rendering/RenderFlowThread.h149
1 files changed, 124 insertions, 25 deletions
diff --git a/Source/WebCore/rendering/RenderFlowThread.h b/Source/WebCore/rendering/RenderFlowThread.h
index c39874c64..ffd42bc16 100644
--- a/Source/WebCore/rendering/RenderFlowThread.h
+++ b/Source/WebCore/rendering/RenderFlowThread.h
@@ -35,10 +35,11 @@
#include <wtf/HashCountedSet.h>
#include <wtf/ListHashSet.h>
#include <wtf/PassRefPtr.h>
-#include <wtf/UnusedParam.h>
namespace WebCore {
+struct LayerFragment;
+typedef Vector<LayerFragment, 1> LayerFragments;
class RenderFlowThread;
class RenderStyle;
class RenderRegion;
@@ -53,7 +54,7 @@ typedef ListHashSet<RenderRegion*> RenderRegionList;
class RenderFlowThread: public RenderBlock {
public:
- RenderFlowThread(Node*);
+ RenderFlowThread();
virtual ~RenderFlowThread() { };
virtual bool isRenderFlowThread() const { return true; }
@@ -76,15 +77,17 @@ public:
virtual void updateLogicalWidth() OVERRIDE;
virtual void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues&) const OVERRIDE;
- void paintFlowThreadPortionInRegion(PaintInfo&, RenderRegion*, LayoutRect flowThreadPortionRect, LayoutRect flowThreadPortionOverflowRect, const LayoutPoint&) const;
- bool hitTestFlowThreadPortionInRegion(RenderRegion*, LayoutRect flowThreadPortionRect, LayoutRect flowThreadPortionOverflowRect, const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset) const;
+ void paintFlowThreadPortionInRegion(PaintInfo&, RenderRegion*, const LayoutRect& flowThreadPortionRect, const LayoutRect& flowThreadPortionOverflowRect, const LayoutPoint&) const;
+ bool hitTestFlowThreadPortionInRegion(RenderRegion*, const LayoutRect& flowThreadPortionRect, const LayoutRect& flowThreadPortionOverflowRect, const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset) const;
+ virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE;
bool hasRegions() const { return m_regionList.size(); }
// Check if the content is flown into at least a region with region styling rules.
bool hasRegionsWithStyling() const { return m_hasRegionsWithStyling; }
void checkRegionsWithStyling();
- void invalidateRegions() { m_regionsInvalidated = true; setNeedsLayout(true); }
+ void validateRegions();
+ void invalidateRegions();
bool hasValidRegionInfo() const { return !m_regionsInvalidated && !m_regionList.isEmpty(); }
static PassRefPtr<RenderStyle> createFlowThreadStyle(RenderStyle* parentStyle);
@@ -92,12 +95,22 @@ public:
void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
void repaintRectangleInRegions(const LayoutRect&, bool immediate) const;
+
+ LayoutPoint adjustedPositionRelativeToOffsetParent(const RenderBoxModelObject&, const LayoutPoint&);
+
+ LayoutUnit pageLogicalTopForOffset(LayoutUnit);
+ LayoutUnit pageLogicalWidthForOffset(LayoutUnit);
+ LayoutUnit pageLogicalHeightForOffset(LayoutUnit);
+ LayoutUnit pageRemainingLogicalHeightForOffset(LayoutUnit, PageBoundaryRule = IncludePageBoundary);
+
+ virtual void setPageBreak(LayoutUnit /*offset*/, LayoutUnit /*spaceShortage*/) { }
+ virtual void updateMinimumPageHeight(LayoutUnit /*offset*/, LayoutUnit /*minHeight*/) { }
- LayoutUnit pageLogicalTopForOffset(LayoutUnit) const;
- LayoutUnit pageLogicalWidthForOffset(LayoutUnit) const;
- LayoutUnit pageLogicalHeightForOffset(LayoutUnit) const;
- LayoutUnit pageRemainingLogicalHeightForOffset(LayoutUnit, PageBoundaryRule = IncludePageBoundary) const;
- RenderRegion* regionAtBlockOffset(LayoutUnit, bool extendLastRegion = false) const;
+ enum RegionAutoGenerationPolicy {
+ AllowRegionAutoGeneration,
+ DisallowRegionAutoGeneration,
+ };
+ RenderRegion* regionAtBlockOffset(LayoutUnit, bool extendLastRegion = false, RegionAutoGenerationPolicy = AllowRegionAutoGeneration);
bool regionsHaveUniformLogicalWidth() const { return m_regionsHaveUniformLogicalWidth; }
bool regionsHaveUniformLogicalHeight() const { return m_regionsHaveUniformLogicalHeight; }
@@ -105,7 +118,7 @@ public:
RenderRegion* mapFromFlowToRegion(TransformState&) const;
void removeRenderBoxRegionInfo(RenderBox*);
- bool logicalWidthChangedInRegions(const RenderBlock*, LayoutUnit offsetFromLogicalTopOfFirstPage);
+ bool logicalWidthChangedInRegionsForBlock(const RenderBlock*);
LayoutUnit contentLogicalWidthOfFirstRegion() const;
LayoutUnit contentLogicalHeightOfFirstRegion() const;
@@ -114,47 +127,88 @@ public:
RenderRegion* firstRegion() const;
RenderRegion* lastRegion() const;
+ bool previousRegionCountChanged() const { return m_previousRegionCount != m_regionList.size(); };
+ void updatePreviousRegionCount() { m_previousRegionCount = m_regionList.size(); };
+
void setRegionRangeForBox(const RenderBox*, LayoutUnit offsetFromLogicalTopOfFirstPage);
void getRegionRangeForBox(const RenderBox*, RenderRegion*& startRegion, RenderRegion*& endRegion) const;
void clearRenderObjectCustomStyle(const RenderObject*,
const RenderRegion* oldStartRegion = 0, const RenderRegion* oldEndRegion = 0,
const RenderRegion* newStartRegion = 0, const RenderRegion* newEndRegion = 0);
-
- void computeOverflowStateForRegions(LayoutUnit oldClientAfterEdge);
-
- bool overset() const { return m_overset; }
// Check if the object is in region and the region is part of this flow thread.
bool objectInFlowRegion(const RenderObject*, const RenderRegion*) const;
- void resetRegionsOverrideLogicalContentHeight();
void markAutoLogicalHeightRegionsForLayout();
bool addForcedRegionBreak(LayoutUnit, RenderObject* breakChild, bool isBefore, LayoutUnit* offsetBreakAdjustment = 0);
+ void applyBreakAfterContent(LayoutUnit);
+
+ bool pageLogicalSizeChanged() const { return m_pageLogicalSizeChanged; }
- bool pageLogicalHeightChanged() const { return m_pageLogicalHeightChanged; }
+ bool hasAutoLogicalHeightRegions() const { ASSERT(isAutoLogicalHeightRegionsCountConsistent()); return m_autoLogicalHeightRegionsCount; }
+ void incrementAutoLogicalHeightRegions();
+ void decrementAutoLogicalHeightRegions();
#ifndef NDEBUG
- unsigned autoLogicalHeightRegionsCount() const;
+ bool isAutoLogicalHeightRegionsCountConsistent() const;
#endif
+ void collectLayerFragments(LayerFragments&, const LayoutRect& layerBoundingBox, const LayoutRect& dirtyRect);
+ LayoutRect fragmentsBoundingBox(const LayoutRect& layerBoundingBox);
+
+ void setInConstrainedLayoutPhase(bool value) { m_inConstrainedLayoutPhase = value; }
+ bool inConstrainedLayoutPhase() const { return m_inConstrainedLayoutPhase; }
+
+ bool needsTwoPhasesLayout() const { return m_needsTwoPhasesLayout; }
+ void clearNeedsTwoPhasesLayout() { m_needsTwoPhasesLayout = false; }
+
+ void pushFlowThreadLayoutState(const RenderObject*);
+ void popFlowThreadLayoutState();
+ LayoutUnit offsetFromLogicalTopOfFirstRegion(const RenderBlock*) const;
+
+ // Used to estimate the maximum height of the flow thread.
+ static LayoutUnit maxLogicalHeight() { return LayoutUnit::max() / 2; }
+
protected:
virtual const char* renderName() const = 0;
- void updateRegionsFlowThreadPortionRect();
+ // Overridden by columns/pages to set up an initial logical width of the page width even when
+ // no regions have been generated yet.
+ virtual LayoutUnit initialLogicalWidth() const { return 0; };
+
+ virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = 0) const OVERRIDE;
+
+ void updateRegionsFlowThreadPortionRect(const RenderRegion* = 0);
bool shouldRepaint(const LayoutRect&) const;
bool regionInRange(const RenderRegion* targetRegion, const RenderRegion* startRegion, const RenderRegion* endRegion) const;
-
+
+ LayoutRect computeRegionClippingRect(const LayoutPoint&, const LayoutRect&, const LayoutRect&) const;
+
void setDispatchRegionLayoutUpdateEvent(bool value) { m_dispatchRegionLayoutUpdateEvent = value; }
bool shouldDispatchRegionLayoutUpdateEvent() { return m_dispatchRegionLayoutUpdateEvent; }
+ void setDispatchRegionOversetChangeEvent(bool value) { m_dispatchRegionOversetChangeEvent = value; }
+ bool shouldDispatchRegionOversetChangeEvent() const { return m_dispatchRegionOversetChangeEvent; }
+
// Override if the flow thread implementation supports dispatching events when the flow layout is updated (e.g. for named flows)
virtual void dispatchRegionLayoutUpdateEvent() { m_dispatchRegionLayoutUpdateEvent = false; }
+ virtual void dispatchRegionOversetChangeEvent() { m_dispatchRegionOversetChangeEvent = false; }
+
+ void initializeRegionsComputedAutoHeight(RenderRegion* = 0);
+
+ virtual void autoGenerateRegionsToBlockOffset(LayoutUnit) { };
- void clearOverrideLogicalContentHeightInRegions(RenderRegion* startRegion = 0);
+ inline bool hasCachedOffsetFromLogicalTopOfFirstRegion(const RenderBox*) const;
+ inline LayoutUnit cachedOffsetFromLogicalTopOfFirstRegion(const RenderBox*) const;
+ inline void setOffsetFromLogicalTopOfFirstRegion(const RenderBox*, LayoutUnit);
+ inline void clearOffsetFromLogicalTopOfFirstRegion(const RenderBox*);
+
+ inline const RenderBox* currentActiveRenderBox() const;
RenderRegionList m_regionList;
+ unsigned short m_previousRegionCount;
class RenderRegionRange {
public:
@@ -182,6 +236,28 @@ protected:
RenderRegion* m_endRegion;
};
+ typedef PODInterval<LayoutUnit, RenderRegion*> RegionInterval;
+ typedef PODIntervalTree<LayoutUnit, RenderRegion*> RegionIntervalTree;
+
+ class RegionSearchAdapter {
+ public:
+ RegionSearchAdapter(LayoutUnit offset)
+ : m_offset(offset)
+ , m_result(0)
+ {
+ }
+
+ const LayoutUnit& lowValue() const { return m_offset; }
+ const LayoutUnit& highValue() const { return m_offset; }
+ void collectIfNeeded(const RegionInterval&);
+
+ RenderRegion* result() const { return m_result; }
+
+ private:
+ LayoutUnit m_offset;
+ RenderRegion* m_result;
+ };
+
// A maps from RenderBox
typedef HashMap<const RenderBox*, RenderRegionRange> RenderRegionRangeMap;
RenderRegionRangeMap m_regionRangeMap;
@@ -190,24 +266,35 @@ protected:
RenderObjectToRegionMap m_breakBeforeToRegionMap;
RenderObjectToRegionMap m_breakAfterToRegionMap;
+ typedef ListHashSet<const RenderObject*> RenderObjectStack;
+ RenderObjectStack m_activeObjectsStack;
+ typedef HashMap<const RenderBox*, LayoutUnit> RenderBoxToOffsetMap;
+ RenderBoxToOffsetMap m_boxesToOffsetMap;
+
+ unsigned m_autoLogicalHeightRegionsCount;
+
+ RegionIntervalTree m_regionIntervalTree;
+
bool m_regionsInvalidated : 1;
bool m_regionsHaveUniformLogicalWidth : 1;
bool m_regionsHaveUniformLogicalHeight : 1;
- bool m_overset : 1;
bool m_hasRegionsWithStyling : 1;
bool m_dispatchRegionLayoutUpdateEvent : 1;
- bool m_pageLogicalHeightChanged : 1;
+ bool m_dispatchRegionOversetChangeEvent : 1;
+ bool m_pageLogicalSizeChanged : 1;
+ bool m_inConstrainedLayoutPhase : 1;
+ bool m_needsTwoPhasesLayout : 1;
};
inline RenderFlowThread* toRenderFlowThread(RenderObject* object)
{
- ASSERT(!object || object->isRenderFlowThread());
+ ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isRenderFlowThread());
return static_cast<RenderFlowThread*>(object);
}
inline const RenderFlowThread* toRenderFlowThread(const RenderObject* object)
{
- ASSERT(!object || object->isRenderFlowThread());
+ ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isRenderFlowThread());
return static_cast<const RenderFlowThread*>(object);
}
@@ -221,8 +308,20 @@ public:
~CurrentRenderFlowThreadMaintainer();
private:
RenderFlowThread* m_renderFlowThread;
+ RenderFlowThread* m_previousRenderFlowThread;
+};
+
+// These structures are used by PODIntervalTree for debugging.
+#ifndef NDEBUG
+template <> struct ValueToString<LayoutUnit> {
+ static String string(const LayoutUnit value) { return String::number(value.toFloat()); }
};
+template <> struct ValueToString<RenderRegion*> {
+ static String string(const RenderRegion* value) { return String::format("%p", value); }
+};
+#endif
+
} // namespace WebCore
#endif // RenderFlowThread_h