| Index: Source/WebCore/rendering/RenderBlock.cpp
|
| ===================================================================
|
| --- Source/WebCore/rendering/RenderBlock.cpp (revision 126659)
|
| +++ Source/WebCore/rendering/RenderBlock.cpp (working copy)
|
| @@ -71,7 +71,7 @@
|
| using namespace HTMLNames;
|
|
|
| struct SameSizeAsRenderBlock : public RenderBox {
|
| - void* pointers[3];
|
| + void* pointers[2];
|
| RenderObjectChildList children;
|
| RenderLineBoxList lineBoxes;
|
| uint32_t bitfields;
|
| @@ -96,11 +96,11 @@
|
| typedef WTF::HashMap<const RenderBox*, ColumnInfo*> ColumnInfoMap;
|
| static ColumnInfoMap* gColumnInfoMap = 0;
|
|
|
| -typedef WTF::HashMap<const RenderBlock*, HashSet<RenderBox*>*> PercentHeightDescendantsMap;
|
| -static PercentHeightDescendantsMap* gPercentHeightDescendantsMap = 0;
|
| +static TrackedDescendantsMap* gPositionedDescendantsMap = 0;
|
| +static TrackedDescendantsMap* gPercentHeightDescendantsMap = 0;
|
|
|
| -typedef WTF::HashMap<const RenderBox*, HashSet<RenderBlock*>*> PercentHeightContainerMap;
|
| -static PercentHeightContainerMap* gPercentHeightContainerMap = 0;
|
| +static TrackedContainerMap* gPositionedContainerMap = 0;
|
| +static TrackedContainerMap* gPercentHeightContainerMap = 0;
|
|
|
| typedef WTF::HashMap<RenderBlock*, ListHashSet<RenderInline*>*> ContinuationOutlineTableMap;
|
|
|
| @@ -196,6 +196,26 @@
|
| COMPILE_ASSERT(sizeof(RenderBlock::MarginInfo) == sizeof(SameSizeAsMarginInfo), MarginInfo_should_stay_small);
|
| }
|
|
|
| +static void removeBlockFromDescendantAndContainerMaps(RenderBlock* block, TrackedDescendantsMap*& descendantMap, TrackedContainerMap*& containerMap)
|
| +{
|
| + if (TrackedRendererListHashSet* descendantSet = descendantMap->take(block)) {
|
| + TrackedRendererListHashSet::iterator end = descendantSet->end();
|
| + for (TrackedRendererListHashSet::iterator descendant = descendantSet->begin(); descendant != end; ++descendant) {
|
| + HashSet<RenderBlock*>* containerSet = containerMap->get(*descendant);
|
| + ASSERT(containerSet);
|
| + if (!containerSet)
|
| + continue;
|
| + ASSERT(containerSet->contains(block));
|
| + containerSet->remove(block);
|
| + if (containerSet->isEmpty()) {
|
| + containerMap->remove(*descendant);
|
| + delete containerSet;
|
| + }
|
| + }
|
| + delete descendantSet;
|
| + }
|
| +}
|
| +
|
| RenderBlock::~RenderBlock()
|
| {
|
| if (m_floatingObjects)
|
| @@ -204,24 +224,10 @@
|
| if (hasColumns())
|
| delete gColumnInfoMap->take(this);
|
|
|
| - if (gPercentHeightDescendantsMap) {
|
| - if (HashSet<RenderBox*>* descendantSet = gPercentHeightDescendantsMap->take(this)) {
|
| - HashSet<RenderBox*>::iterator end = descendantSet->end();
|
| - for (HashSet<RenderBox*>::iterator descendant = descendantSet->begin(); descendant != end; ++descendant) {
|
| - HashSet<RenderBlock*>* containerSet = gPercentHeightContainerMap->get(*descendant);
|
| - ASSERT(containerSet);
|
| - if (!containerSet)
|
| - continue;
|
| - ASSERT(containerSet->contains(this));
|
| - containerSet->remove(this);
|
| - if (containerSet->isEmpty()) {
|
| - gPercentHeightContainerMap->remove(*descendant);
|
| - delete containerSet;
|
| - }
|
| - }
|
| - delete descendantSet;
|
| - }
|
| - }
|
| + if (gPercentHeightDescendantsMap)
|
| + removeBlockFromDescendantAndContainerMaps(this, gPercentHeightDescendantsMap, gPercentHeightContainerMap);
|
| + if (gPositionedDescendantsMap)
|
| + removeBlockFromDescendantAndContainerMaps(this, gPositionedDescendantsMap, gPositionedContainerMap);
|
| }
|
|
|
| void RenderBlock::willBeDestroyed()
|
| @@ -1654,20 +1660,21 @@
|
|
|
| void RenderBlock::addOverflowFromPositionedObjects()
|
| {
|
| - if (!m_positionedObjects)
|
| + TrackedRendererListHashSet* positionedDescendants = positionedObjects();
|
| + if (!positionedDescendants)
|
| return;
|
|
|
| RenderBox* positionedObject;
|
| - Iterator end = m_positionedObjects->end();
|
| - for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
|
| + TrackedRendererListHashSet::iterator end = positionedDescendants->end();
|
| + for (TrackedRendererListHashSet::iterator it = positionedDescendants->begin(); it != end; ++it) {
|
| positionedObject = *it;
|
|
|
| // Fixed positioned elements don't contribute to layout overflow, since they don't scroll with the content.
|
| if (positionedObject->style()->position() != FixedPosition) {
|
| - int x = positionedObject->x();
|
| + LayoutUnit x = positionedObject->x();
|
| if (style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
|
| x -= verticalScrollbarWidth();
|
| - addOverflowFromChild(positionedObject, IntSize(x, positionedObject->y()));
|
| + addOverflowFromChild(positionedObject, LayoutSize(x, positionedObject->y()));
|
| }
|
| }
|
| }
|
| @@ -2274,9 +2281,9 @@
|
| void RenderBlock::layoutBlockChildren(bool relayoutChildren, LayoutUnit& maxFloatLogicalBottom)
|
| {
|
| if (gPercentHeightDescendantsMap) {
|
| - if (HashSet<RenderBox*>* descendants = gPercentHeightDescendantsMap->get(this)) {
|
| - HashSet<RenderBox*>::iterator end = descendants->end();
|
| - for (HashSet<RenderBox*>::iterator it = descendants->begin(); it != end; ++it) {
|
| + if (TrackedRendererListHashSet* descendants = gPercentHeightDescendantsMap->get(this)) {
|
| + TrackedRendererListHashSet::iterator end = descendants->end();
|
| + for (TrackedRendererListHashSet::iterator it = descendants->begin(); it != end; ++it) {
|
| RenderBox* box = *it;
|
| while (box != this) {
|
| if (box->normalChildNeedsLayout())
|
| @@ -2555,15 +2562,16 @@
|
|
|
| void RenderBlock::layoutPositionedObjects(bool relayoutChildren)
|
| {
|
| - if (!m_positionedObjects)
|
| + TrackedRendererListHashSet* positionedDescendants = positionedObjects();
|
| + if (!positionedDescendants)
|
| return;
|
|
|
| if (hasColumns())
|
| view()->layoutState()->clearPaginationInformation(); // Positioned objects are not part of the column flow, so they don't paginate with the columns.
|
|
|
| RenderBox* r;
|
| - Iterator end = m_positionedObjects->end();
|
| - for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
|
| + TrackedRendererListHashSet::iterator end = positionedDescendants->end();
|
| + for (TrackedRendererListHashSet::iterator it = positionedDescendants->begin(); it != end; ++it) {
|
| r = *it;
|
| // When a non-positioned block element moves, it may have positioned children that are implicitly positioned relative to the
|
| // non-positioned block. Rather than trying to detect all of these movement cases, we just always lay out positioned
|
| @@ -2619,10 +2627,11 @@
|
|
|
| void RenderBlock::markPositionedObjectsForLayout()
|
| {
|
| - if (m_positionedObjects) {
|
| + TrackedRendererListHashSet* positionedDescendants = positionedObjects();
|
| + if (positionedDescendants) {
|
| RenderBox* r;
|
| - Iterator end = m_positionedObjects->end();
|
| - for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
|
| + TrackedRendererListHashSet::iterator end = positionedDescendants->end();
|
| + for (TrackedRendererListHashSet::iterator it = positionedDescendants->begin(); it != end; ++it) {
|
| r = *it;
|
| r->setChildNeedsLayout(true);
|
| }
|
| @@ -3244,13 +3253,13 @@
|
| }
|
| }
|
|
|
| -static void clipOutPositionedObjects(const PaintInfo* paintInfo, const LayoutPoint& offset, RenderBlock::PositionedObjectsListHashSet* positionedObjects)
|
| +static void clipOutPositionedObjects(const PaintInfo* paintInfo, const LayoutPoint& offset, TrackedRendererListHashSet* positionedObjects)
|
| {
|
| if (!positionedObjects)
|
| return;
|
|
|
| - RenderBlock::PositionedObjectsListHashSet::const_iterator end = positionedObjects->end();
|
| - for (RenderBlock::PositionedObjectsListHashSet::const_iterator it = positionedObjects->begin(); it != end; ++it) {
|
| + TrackedRendererListHashSet::const_iterator end = positionedObjects->end();
|
| + for (TrackedRendererListHashSet::const_iterator it = positionedObjects->begin(); it != end; ++it) {
|
| RenderBox* r = *it;
|
| paintInfo->context->clipOut(IntRect(offset.x() + r->x(), offset.y() + r->y(), r->width(), r->height()));
|
| }
|
| @@ -3288,10 +3297,10 @@
|
| LayoutRect flippedBlockRect(offsetFromRootBlock.width(), offsetFromRootBlock.height(), width(), height());
|
| rootBlock->flipForWritingMode(flippedBlockRect);
|
| flippedBlockRect.moveBy(rootBlockPhysicalPosition);
|
| - clipOutPositionedObjects(paintInfo, flippedBlockRect.location(), m_positionedObjects.get());
|
| + clipOutPositionedObjects(paintInfo, flippedBlockRect.location(), positionedObjects());
|
| if (isBody() || isRoot()) // The <body> must make sure to examine its containingBlock's positioned objects.
|
| for (RenderBlock* cb = containingBlock(); cb && !cb->isRenderView(); cb = cb->containingBlock())
|
| - clipOutPositionedObjects(paintInfo, LayoutPoint(cb->x(), cb->y()), cb->m_positionedObjects.get()); // FIXME: Not right for flipped writing modes.
|
| + clipOutPositionedObjects(paintInfo, LayoutPoint(cb->x(), cb->y()), cb->positionedObjects()); // FIXME: Not right for flipped writing modes.
|
| if (m_floatingObjects) {
|
| const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
|
| FloatingObjectSetIterator end = floatingObjectSet.end();
|
| @@ -3582,6 +3591,69 @@
|
| return beforeBlock;
|
| }
|
|
|
| +void RenderBlock::insertIntoTrackedRendererMaps(RenderBox* descendant, TrackedDescendantsMap*& descendantsMap, TrackedContainerMap*& containerMap)
|
| +{
|
| + if (!descendantsMap) {
|
| + descendantsMap = new TrackedDescendantsMap;
|
| + containerMap = new TrackedContainerMap;
|
| + }
|
| +
|
| + TrackedRendererListHashSet* descendantSet = descendantsMap->get(this);
|
| + if (!descendantSet) {
|
| + descendantSet = new TrackedRendererListHashSet;
|
| + descendantsMap->set(this, descendantSet);
|
| + }
|
| + bool added = descendantSet->add(descendant).isNewEntry;
|
| + if (!added) {
|
| + ASSERT(containerMap->get(descendant));
|
| + ASSERT(containerMap->get(descendant)->contains(this));
|
| + return;
|
| + }
|
| +
|
| + HashSet<RenderBlock*>* containerSet = containerMap->get(descendant);
|
| + if (!containerSet) {
|
| + containerSet = new HashSet<RenderBlock*>;
|
| + containerMap->set(descendant, containerSet);
|
| + }
|
| + ASSERT(!containerSet->contains(this));
|
| + containerSet->add(this);
|
| +}
|
| +
|
| +void RenderBlock::removeFromTrackedRendererMaps(RenderBox* descendant, TrackedDescendantsMap*& descendantsMap, TrackedContainerMap*& containerMap)
|
| +{
|
| + if (!descendantsMap)
|
| + return;
|
| +
|
| + HashSet<RenderBlock*>* containerSet = containerMap->take(descendant);
|
| + if (!containerSet)
|
| + return;
|
| +
|
| + HashSet<RenderBlock*>::iterator end = containerSet->end();
|
| + for (HashSet<RenderBlock*>::iterator it = containerSet->begin(); it != end; ++it) {
|
| + RenderBlock* container = *it;
|
| + ASSERT(descendant->isDescendantOf(container));
|
| + TrackedRendererListHashSet* descendantSet = descendantsMap->get(container);
|
| + ASSERT(descendantSet);
|
| + if (!descendantSet)
|
| + continue;
|
| + ASSERT(descendantSet->contains(descendant));
|
| + descendantSet->remove(descendant);
|
| + if (descendantSet->isEmpty()) {
|
| + descendantsMap->remove(container);
|
| + delete descendantSet;
|
| + }
|
| + }
|
| +
|
| + delete containerSet;
|
| +}
|
| +
|
| +TrackedRendererListHashSet* RenderBlock::positionedObjects() const
|
| +{
|
| + if (gPositionedDescendantsMap)
|
| + return gPositionedDescendantsMap->get(this);
|
| + return 0;
|
| +}
|
| +
|
| void RenderBlock::insertPositionedObject(RenderBox* o)
|
| {
|
| ASSERT(!isAnonymousBlock());
|
| @@ -3589,31 +3661,27 @@
|
| if (o->isRenderFlowThread())
|
| return;
|
|
|
| - // Create the list of special objects if we don't aleady have one
|
| - if (!m_positionedObjects)
|
| - m_positionedObjects = adoptPtr(new PositionedObjectsListHashSet);
|
| -
|
| - m_positionedObjects->add(o);
|
| + insertIntoTrackedRendererMaps(o, gPositionedDescendantsMap, gPositionedContainerMap);
|
| }
|
|
|
| void RenderBlock::removePositionedObject(RenderBox* o)
|
| {
|
| - if (m_positionedObjects)
|
| - m_positionedObjects->remove(o);
|
| + removeFromTrackedRendererMaps(o, gPositionedDescendantsMap, gPositionedContainerMap);
|
| }
|
|
|
| void RenderBlock::removePositionedObjects(RenderBlock* o)
|
| {
|
| - if (!m_positionedObjects)
|
| + TrackedRendererListHashSet* positionedDescendants = positionedObjects();
|
| + if (!positionedDescendants)
|
| return;
|
|
|
| RenderBox* r;
|
|
|
| - Iterator end = m_positionedObjects->end();
|
| + TrackedRendererListHashSet::iterator end = positionedDescendants->end();
|
|
|
| Vector<RenderBox*, 16> deadObjects;
|
|
|
| - for (Iterator it = m_positionedObjects->begin(); it != end; ++it) {
|
| + for (TrackedRendererListHashSet::iterator it = positionedDescendants->begin(); it != end; ++it) {
|
| r = *it;
|
| if (!o || r->isDescendantOf(o)) {
|
| if (o)
|
| @@ -3632,7 +3700,7 @@
|
| }
|
|
|
| for (unsigned i = 0; i < deadObjects.size(); i++)
|
| - m_positionedObjects->remove(deadObjects.at(i));
|
| + removePositionedObject(deadObjects.at(i));
|
| }
|
|
|
| RenderBlock::FloatingObject* RenderBlock::insertFloatingObject(RenderBox* o)
|
| @@ -3910,60 +3978,15 @@
|
|
|
| void RenderBlock::addPercentHeightDescendant(RenderBox* descendant)
|
| {
|
| - if (!gPercentHeightDescendantsMap) {
|
| - gPercentHeightDescendantsMap = new PercentHeightDescendantsMap;
|
| - gPercentHeightContainerMap = new PercentHeightContainerMap;
|
| - }
|
| -
|
| - HashSet<RenderBox*>* descendantSet = gPercentHeightDescendantsMap->get(this);
|
| - if (!descendantSet) {
|
| - descendantSet = new HashSet<RenderBox*>;
|
| - gPercentHeightDescendantsMap->set(this, descendantSet);
|
| - }
|
| - bool added = descendantSet->add(descendant).isNewEntry;
|
| - if (!added) {
|
| - ASSERT(gPercentHeightContainerMap->get(descendant));
|
| - ASSERT(gPercentHeightContainerMap->get(descendant)->contains(this));
|
| - return;
|
| - }
|
| -
|
| - HashSet<RenderBlock*>* containerSet = gPercentHeightContainerMap->get(descendant);
|
| - if (!containerSet) {
|
| - containerSet = new HashSet<RenderBlock*>;
|
| - gPercentHeightContainerMap->set(descendant, containerSet);
|
| - }
|
| - ASSERT(!containerSet->contains(this));
|
| - containerSet->add(this);
|
| + insertIntoTrackedRendererMaps(descendant, gPercentHeightDescendantsMap, gPercentHeightContainerMap);
|
| }
|
|
|
| void RenderBlock::removePercentHeightDescendant(RenderBox* descendant)
|
| {
|
| - if (!gPercentHeightContainerMap)
|
| - return;
|
| -
|
| - HashSet<RenderBlock*>* containerSet = gPercentHeightContainerMap->take(descendant);
|
| - if (!containerSet)
|
| - return;
|
| -
|
| - HashSet<RenderBlock*>::iterator end = containerSet->end();
|
| - for (HashSet<RenderBlock*>::iterator it = containerSet->begin(); it != end; ++it) {
|
| - RenderBlock* container = *it;
|
| - HashSet<RenderBox*>* descendantSet = gPercentHeightDescendantsMap->get(container);
|
| - ASSERT(descendantSet);
|
| - if (!descendantSet)
|
| - continue;
|
| - ASSERT(descendantSet->contains(descendant));
|
| - descendantSet->remove(descendant);
|
| - if (descendantSet->isEmpty()) {
|
| - gPercentHeightDescendantsMap->remove(container);
|
| - delete descendantSet;
|
| - }
|
| - }
|
| -
|
| - delete containerSet;
|
| + removeFromTrackedRendererMaps(descendant, gPercentHeightDescendantsMap, gPercentHeightContainerMap);
|
| }
|
|
|
| -HashSet<RenderBox*>* RenderBlock::percentHeightDescendants() const
|
| +TrackedRendererListHashSet* RenderBlock::percentHeightDescendants() const
|
| {
|
| return gPercentHeightDescendantsMap ? gPercentHeightDescendantsMap->get(this) : 0;
|
| }
|
| @@ -7424,9 +7447,12 @@
|
| #ifndef NDEBUG
|
| void RenderBlock::checkPositionedObjectsNeedLayout()
|
| {
|
| - if (PositionedObjectsListHashSet* positionedObjects = this->positionedObjects()) {
|
| - PositionedObjectsListHashSet::const_iterator end = positionedObjects->end();
|
| - for (PositionedObjectsListHashSet::const_iterator it = positionedObjects->begin(); it != end; ++it) {
|
| + if (!gPositionedDescendantsMap)
|
| + return;
|
| +
|
| + if (TrackedRendererListHashSet* positionedDescendantSet = positionedObjects()) {
|
| + TrackedRendererListHashSet::const_iterator end = positionedDescendantSet->end();
|
| + for (TrackedRendererListHashSet::const_iterator it = positionedDescendantSet->begin(); it != end; ++it) {
|
| RenderBox* currBox = *it;
|
| ASSERT(!currBox->needsLayout());
|
| }
|
|
|