Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(675)

Unified Diff: Source/core/rendering/FloatingObjects.cpp

Issue 22893013: Move Floats out of RenderBlock (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Fix release bot compile error Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/rendering/FloatingObjects.h ('k') | Source/core/rendering/RenderBlock.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/rendering/FloatingObjects.cpp
diff --git a/Source/core/rendering/FloatingObjects.cpp b/Source/core/rendering/FloatingObjects.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7312d7cef3b35278741fc6f763979a9816c2a192
--- /dev/null
+++ b/Source/core/rendering/FloatingObjects.cpp
@@ -0,0 +1,319 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * (C) 2007 David Smith (catfish.man@gmail.com)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "core/rendering/FloatingObjects.h"
+
+#include "core/rendering/RenderBlock.h"
+#include "core/rendering/RenderBox.h"
+#include "core/rendering/RenderView.h"
+
+using namespace std;
+using namespace WTF;
+
+namespace WebCore {
+
+struct SameSizeAsFloatingObject {
+ void* pointers[2];
+ LayoutRect rect;
+ int paginationStrut;
+ uint32_t bitfields : 8;
+};
+
+COMPILE_ASSERT(sizeof(FloatingObject) == sizeof(SameSizeAsFloatingObject), FloatingObject_should_stay_small);
+
+template <FloatingObject::Type FloatTypeValue>
+class ComputeFloatOffsetAdapter {
+public:
+ typedef FloatingObjectInterval IntervalType;
+
+ ComputeFloatOffsetAdapter(const RenderBlock* renderer, int lineTop, int lineBottom, LayoutUnit& offset)
+ : m_renderer(renderer)
+ , m_lineTop(lineTop)
+ , m_lineBottom(lineBottom)
+ , m_offset(offset)
+ , m_outermostFloat(0)
+ {
+ }
+
+ int lowValue() const { return m_lineTop; }
+ int highValue() const { return m_lineBottom; }
+ void collectIfNeeded(const IntervalType&);
+
+ // When computing the offset caused by the floats on a given line, if
+ // the outermost float on that line has a shape-outside, the inline
+ // content that butts up against that float must be positioned using
+ // the contours of the shape, not the margin box of the float.
+ const FloatingObject* outermostFloat() const { return m_outermostFloat; }
+
+ LayoutUnit getHeightRemaining() const;
+
+private:
+ bool updateOffsetIfNeeded(const FloatingObject*);
+
+ const RenderBlock* m_renderer;
+ int m_lineTop;
+ int m_lineBottom;
+ LayoutUnit& m_offset;
+ const FloatingObject* m_outermostFloat;
+};
+
+
+FloatingObjects::~FloatingObjects()
+{
+ // FIXME: m_set should use OwnPtr instead.
+ deleteAllValues(m_set);
+}
+void FloatingObjects::clearLineBoxTreePointers()
+{
+ // Clear references to originating lines, since the lines are being deleted
+ FloatingObjectSetIterator end = m_set.end();
+ for (FloatingObjectSetIterator it = m_set.begin(); it != end; ++it) {
+ ASSERT(!((*it)->originatingLine()) || (*it)->originatingLine()->renderer() == m_renderer);
+ (*it)->setOriginatingLine(0);
+ }
+}
+
+template<>
+inline bool ComputeFloatOffsetAdapter<FloatingObject::FloatLeft>::updateOffsetIfNeeded(const FloatingObject* floatingObject)
+{
+ LayoutUnit logicalRight = floatingObject->logicalRight(m_renderer->isHorizontalWritingMode());
+ if (logicalRight > m_offset) {
+ m_offset = logicalRight;
+ return true;
+ }
+ return false;
+}
+
+FloatingObjects::FloatingObjects(const RenderBlock* renderer, bool horizontalWritingMode)
+ : m_placedFloatsTree(UninitializedTree)
+ , m_leftObjectsCount(0)
+ , m_rightObjectsCount(0)
+ , m_horizontalWritingMode(horizontalWritingMode)
+ , m_renderer(renderer)
+{
+}
+
+void FloatingObjects::clear()
+{
+ // FIXME: This should call deleteAllValues, except clearFloats
+ // like to play fast and loose with ownership of these pointers.
+ // If we move to OwnPtr that will fix this ownership oddness.
+ m_set.clear();
+ m_placedFloatsTree.clear();
+ m_leftObjectsCount = 0;
+ m_rightObjectsCount = 0;
+}
+
+inline void FloatingObjects::increaseObjectsCount(FloatingObject::Type type)
+{
+ if (type == FloatingObject::FloatLeft)
+ m_leftObjectsCount++;
+ else
+ m_rightObjectsCount++;
+}
+
+inline void FloatingObjects::decreaseObjectsCount(FloatingObject::Type type)
+{
+ if (type == FloatingObject::FloatLeft)
+ m_leftObjectsCount--;
+ else
+ m_rightObjectsCount--;
+}
+
+inline FloatingObjectInterval FloatingObjects::intervalForFloatingObject(FloatingObject* floatingObject)
+{
+ if (m_horizontalWritingMode)
+ return FloatingObjectInterval(floatingObject->frameRect().pixelSnappedY(), floatingObject->frameRect().pixelSnappedMaxY(), floatingObject);
+ return FloatingObjectInterval(floatingObject->frameRect().pixelSnappedX(), floatingObject->frameRect().pixelSnappedMaxX(), floatingObject);
+}
+
+void FloatingObjects::addPlacedObject(FloatingObject* floatingObject)
+{
+ ASSERT(!floatingObject->isInPlacedTree());
+
+ floatingObject->setIsPlaced(true);
+ if (m_placedFloatsTree.isInitialized())
+ m_placedFloatsTree.add(intervalForFloatingObject(floatingObject));
+
+#ifndef NDEBUG
+ floatingObject->setIsInPlacedTree(true);
+#endif
+}
+
+void FloatingObjects::removePlacedObject(FloatingObject* floatingObject)
+{
+ ASSERT(floatingObject->isPlaced() && floatingObject->isInPlacedTree());
+
+ if (m_placedFloatsTree.isInitialized()) {
+ bool removed = m_placedFloatsTree.remove(intervalForFloatingObject(floatingObject));
+ ASSERT_UNUSED(removed, removed);
+ }
+
+ floatingObject->setIsPlaced(false);
+#ifndef NDEBUG
+ floatingObject->setIsInPlacedTree(false);
+#endif
+}
+
+void FloatingObjects::add(FloatingObject* floatingObject)
+{
+ increaseObjectsCount(floatingObject->type());
+ m_set.add(floatingObject);
+ if (floatingObject->isPlaced())
+ addPlacedObject(floatingObject);
+}
+
+void FloatingObjects::remove(FloatingObject* floatingObject)
+{
+ decreaseObjectsCount(floatingObject->type());
+ m_set.remove(floatingObject);
+ ASSERT(floatingObject->isPlaced() || !floatingObject->isInPlacedTree());
+ if (floatingObject->isPlaced())
+ removePlacedObject(floatingObject);
+}
+
+void FloatingObjects::computePlacedFloatsTree()
+{
+ ASSERT(!m_placedFloatsTree.isInitialized());
+ if (m_set.isEmpty())
+ return;
+ m_placedFloatsTree.initIfNeeded(m_renderer->view()->intervalArena());
+ FloatingObjectSetIterator it = m_set.begin();
+ FloatingObjectSetIterator end = m_set.end();
+ for (; it != end; ++it) {
+ FloatingObject* floatingObject = *it;
+ if (floatingObject->isPlaced())
+ m_placedFloatsTree.add(intervalForFloatingObject(floatingObject));
+ }
+}
+
+LayoutUnit FloatingObjects::logicalLeftOffset(LayoutUnit fixedOffset, LayoutUnit logicalTop, LayoutUnit logicalHeight, ShapeOutsideFloatOffsetMode offsetMode, LayoutUnit *heightRemaining)
+{
+ LayoutUnit offset = fixedOffset;
+ ComputeFloatOffsetAdapter<FloatingObject::FloatLeft> adapter(m_renderer, roundToInt(logicalTop), roundToInt(logicalTop + logicalHeight), offset);
+ placedFloatsTree().allOverlapsWithAdapter(adapter);
+
+ if (heightRemaining)
+ *heightRemaining = adapter.getHeightRemaining();
+
+ const FloatingObject* outermostFloat = adapter.outermostFloat();
+ if (offsetMode == ShapeOutsideFloatShapeOffset && outermostFloat) {
+ if (ShapeOutsideInfo* shapeOutside = outermostFloat->renderer()->shapeOutsideInfo()) {
+ shapeOutside->computeSegmentsForContainingBlockLine(logicalTop, outermostFloat->logicalTop(m_horizontalWritingMode), logicalHeight);
+ offset += shapeOutside->rightSegmentMarginBoxDelta();
+ }
+ }
+
+ return offset;
+}
+
+LayoutUnit FloatingObjects::logicalRightOffset(LayoutUnit fixedOffset, LayoutUnit logicalTop, LayoutUnit logicalHeight, ShapeOutsideFloatOffsetMode offsetMode, LayoutUnit *heightRemaining)
+{
+ LayoutUnit offset = fixedOffset;
+ ComputeFloatOffsetAdapter<FloatingObject::FloatRight> adapter(m_renderer, roundToInt(logicalTop), roundToInt(logicalTop + logicalHeight), offset);
+ placedFloatsTree().allOverlapsWithAdapter(adapter);
+
+ if (heightRemaining)
+ *heightRemaining = adapter.getHeightRemaining();
+
+ const FloatingObject* outermostFloat = adapter.outermostFloat();
+ if (offsetMode == ShapeOutsideFloatShapeOffset && outermostFloat) {
+ if (ShapeOutsideInfo* shapeOutside = outermostFloat->renderer()->shapeOutsideInfo()) {
+ shapeOutside->computeSegmentsForContainingBlockLine(logicalTop, outermostFloat->logicalTop(m_horizontalWritingMode), logicalHeight);
+ offset += shapeOutside->leftSegmentMarginBoxDelta();
+ }
+ }
+
+ return min(fixedOffset, offset);
+}
+
+inline static bool rangesIntersect(int floatTop, int floatBottom, int objectTop, int objectBottom)
+{
+ if (objectTop >= floatBottom || objectBottom < floatTop)
+ return false;
+
+ // The top of the object overlaps the float
+ if (objectTop >= floatTop)
+ return true;
+
+ // The object encloses the float
+ if (objectTop < floatTop && objectBottom > floatBottom)
+ return true;
+
+ // The bottom of the object overlaps the float
+ if (objectBottom > objectTop && objectBottom > floatTop && objectBottom <= floatBottom)
+ return true;
+
+ return false;
+}
+
+template<>
+inline bool ComputeFloatOffsetAdapter<FloatingObject::FloatRight>::updateOffsetIfNeeded(const FloatingObject* floatingObject)
+{
+ LayoutUnit logicalLeft = floatingObject->logicalLeft(m_renderer->isHorizontalWritingMode());
+ if (logicalLeft < m_offset) {
+ m_offset = logicalLeft;
+ return true;
+ }
+ return false;
+}
+
+template <FloatingObject::Type FloatTypeValue>
+inline void ComputeFloatOffsetAdapter<FloatTypeValue>::collectIfNeeded(const IntervalType& interval)
+{
+ const FloatingObject* floatingObject = interval.data();
+ if (floatingObject->type() != FloatTypeValue || !rangesIntersect(interval.low(), interval.high(), m_lineTop, m_lineBottom))
+ return;
+
+ // Make sure the float hasn't changed since it was added to the placed floats tree.
+ ASSERT(floatingObject->isPlaced());
+ ASSERT(interval.low() == floatingObject->pixelSnappedLogicalTop(m_renderer->isHorizontalWritingMode()));
+ ASSERT(interval.high() == floatingObject->pixelSnappedLogicalBottom(m_renderer->isHorizontalWritingMode()));
+
+ bool floatIsNewExtreme = updateOffsetIfNeeded(floatingObject);
+ if (floatIsNewExtreme)
+ m_outermostFloat = floatingObject;
+}
+
+template <FloatingObject::Type FloatTypeValue>
+LayoutUnit ComputeFloatOffsetAdapter<FloatTypeValue>::getHeightRemaining() const
+{
+ return m_outermostFloat ? m_outermostFloat->logicalBottom(m_renderer->isHorizontalWritingMode()) - m_lineTop : LayoutUnit(1);
+}
+
+#ifndef NDEBUG
+// These helpers are only used by the PODIntervalTree for debugging purposes.
+String ValueToString<int>::string(const int value)
+{
+ return String::number(value);
+}
+
+String ValueToString<FloatingObject*>::string(const FloatingObject* floatingObject)
+{
+ return String::format("%p (%dx%d %dx%d)", floatingObject, floatingObject->frameRect().pixelSnappedX(), floatingObject->frameRect().pixelSnappedY(), floatingObject->frameRect().pixelSnappedMaxX(), floatingObject->frameRect().pixelSnappedMaxY());
+}
+#endif
+
+
+} // namespace WebCore
« no previous file with comments | « Source/core/rendering/FloatingObjects.h ('k') | Source/core/rendering/RenderBlock.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698