RenderFlowThread.h [plain text]
#ifndef RenderFlowThread_h
#define RenderFlowThread_h
#include "RenderBlock.h"
#include <wtf/HashCountedSet.h>
#include <wtf/ListHashSet.h>
#include <wtf/PassRefPtr.h>
#include <wtf/UnusedParam.h>
namespace WebCore {
class RenderFlowThread;
class RenderStyle;
class RenderRegion;
typedef ListHashSet<RenderRegion*> RenderRegionList;
class RenderFlowThread: public RenderBlock {
public:
RenderFlowThread(Node*);
virtual ~RenderFlowThread() { };
virtual bool isRenderFlowThread() const { return true; }
virtual void layout();
virtual bool requiresLayer() const { return true; }
void removeFlowChildInfo(RenderObject*);
#ifndef NDEBUG
bool hasChildInfo(RenderObject* child) const { return child && child->isBox() && m_regionRangeMap.contains(toRenderBox(child)); }
#endif
virtual void addRegionToThread(RenderRegion*);
virtual void removeRegionFromThread(RenderRegion*);
const RenderRegionList& renderRegionList() const { return m_regionList; }
void computeLogicalWidth();
void computeLogicalHeight();
void paintIntoRegion(PaintInfo&, RenderRegion*, const LayoutPoint& paintOffset);
bool hitTestRegion(RenderRegion*, const HitTestRequest&, HitTestResult&, const LayoutPoint& pointInContainer, const LayoutPoint& accumulatedOffset);
bool hasRegions() const { return m_regionList.size(); }
bool hasValidRegions() const { ASSERT(!m_regionsInvalidated); return m_hasValidRegions; }
void invalidateRegions() { m_regionsInvalidated = true; setNeedsLayout(true); }
bool hasValidRegionInfo() const { return !m_regionsInvalidated && hasValidRegions(); }
static PassRefPtr<RenderStyle> createFlowThreadStyle(RenderStyle* parentStyle);
void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
void repaintRectangleInRegions(const LayoutRect&, bool immediate);
LayoutUnit regionLogicalTopForLine(LayoutUnit position) const;
LayoutUnit regionLogicalWidthForLine(LayoutUnit position) const;
LayoutUnit regionLogicalHeightForLine(LayoutUnit position) const;
LayoutUnit regionRemainingLogicalHeightForLine(LayoutUnit position, PageBoundaryRule = IncludePageBoundary) const;
RenderRegion* renderRegionForLine(LayoutUnit position, bool extendLastRegion = false) const;
bool regionsHaveUniformLogicalWidth() const { return m_regionsHaveUniformLogicalWidth; }
bool regionsHaveUniformLogicalHeight() const { return m_regionsHaveUniformLogicalHeight; }
RenderRegion* mapFromFlowToRegion(TransformState&) const;
void removeRenderBoxRegionInfo(RenderBox*);
bool logicalWidthChangedInRegions(const RenderBlock*, LayoutUnit offsetFromLogicalTopOfFirstPage);
LayoutUnit contentLogicalWidthOfFirstRegion() const;
LayoutUnit contentLogicalHeightOfFirstRegion() const;
LayoutUnit contentLogicalLeftOfFirstRegion() const;
RenderRegion* firstRegion() const;
RenderRegion* lastRegion() const;
void setRegionRangeForBox(const RenderBox*, LayoutUnit offsetFromLogicalTopOfFirstPage);
void getRegionRangeForBox(const RenderBox*, RenderRegion*& startRegion, RenderRegion*& endRegion) const;
void clearRenderBoxCustomStyle(const RenderBox*,
const RenderRegion* oldStartRegion = 0, const RenderRegion* oldEndRegion = 0,
const RenderRegion* newStartRegion = 0, const RenderRegion* newEndRegion = 0);
void computeOverflowStateForRegions(LayoutUnit oldClientAfterEdge);
bool overflow() const { return m_overflow; }
bool objectInFlowRegion(const RenderObject*, const RenderRegion*) const;
protected:
virtual const char* renderName() const = 0;
bool shouldRepaint(const LayoutRect&) const;
void regionLayoutUpdateEventTimerFired(Timer<RenderFlowThread>*);
bool regionInRange(const RenderRegion* targetRegion, const RenderRegion* startRegion, const RenderRegion* endRegion) const;
RenderRegionList m_regionList;
class RenderRegionRange {
public:
RenderRegionRange()
{
setRange(0, 0);
}
RenderRegionRange(RenderRegion* start, RenderRegion* end)
{
setRange(start, end);
}
void setRange(RenderRegion* start, RenderRegion* end)
{
m_startRegion = start;
m_endRegion = end;
}
RenderRegion* startRegion() const { return m_startRegion; }
RenderRegion* endRegion() const { return m_endRegion; }
private:
RenderRegion* m_startRegion;
RenderRegion* m_endRegion;
};
typedef HashMap<const RenderBox*, RenderRegionRange> RenderRegionRangeMap;
RenderRegionRangeMap m_regionRangeMap;
bool m_hasValidRegions;
bool m_regionsInvalidated;
bool m_regionsHaveUniformLogicalWidth;
bool m_regionsHaveUniformLogicalHeight;
bool m_overflow;
Timer<RenderFlowThread> m_regionLayoutUpdateEventTimer;
};
inline RenderFlowThread* toRenderFlowThread(RenderObject* object)
{
ASSERT(!object || object->isRenderFlowThread());
return static_cast<RenderFlowThread*>(object);
}
inline const RenderFlowThread* toRenderFlowThread(const RenderObject* object)
{
ASSERT(!object || object->isRenderFlowThread());
return static_cast<const RenderFlowThread*>(object);
}
void toRenderFlowThread(const RenderFlowThread*);
}
#endif // RenderFlowThread_h