1 /* 2 * Copyright (C) 1999 Lars Knoll (knoll (at) kde.org) 3 * (C) 1999 Antti Koivisto (koivisto (at) kde.org) 4 * (C) 2007 David Smith (catfish.man (at) gmail.com) 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. 6 * Copyright (C) Research In Motion Limited 2010. All rights reserved. 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Library General Public 10 * License as published by the Free Software Foundation; either 11 * version 2 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Library General Public License for more details. 17 * 18 * You should have received a copy of the GNU Library General Public License 19 * along with this library; see the file COPYING.LIB. If not, write to 20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 21 * Boston, MA 02110-1301, USA. 22 */ 23 24 #ifndef FloatingObjects_h 25 #define FloatingObjects_h 26 27 #include "core/rendering/RootInlineBox.h" 28 #include "platform/PODFreeListArena.h" 29 #include "platform/PODIntervalTree.h" 30 #include "wtf/ListHashSet.h" 31 #include "wtf/OwnPtr.h" 32 33 namespace WebCore { 34 35 class RenderBlockFlow; 36 class RenderBox; 37 38 // FIXME this should be removed once RenderBlockFlow::nextFloatLogicalBottomBelow doesn't need it anymore. (Bug 123931) 39 enum ShapeOutsideFloatOffsetMode { ShapeOutsideFloatShapeOffset, ShapeOutsideFloatMarginBoxOffset }; 40 41 class FloatingObject { 42 WTF_MAKE_NONCOPYABLE(FloatingObject); WTF_MAKE_FAST_ALLOCATED; 43 public: 44 #ifndef NDEBUG 45 // Used by the PODIntervalTree for debugging the FloatingObject. 46 template <class> friend struct ValueToString; 47 #endif 48 49 // Note that Type uses bits so you can use FloatLeftRight as a mask to query for both left and right. 50 enum Type { FloatLeft = 1, FloatRight = 2, FloatLeftRight = 3 }; 51 52 static PassOwnPtr<FloatingObject> create(RenderBox*); 53 54 PassOwnPtr<FloatingObject> copyToNewContainer(LayoutSize, bool shouldPaint = false, bool isDescendant = false) const; 55 56 PassOwnPtr<FloatingObject> unsafeClone() const; 57 58 Type type() const { return static_cast<Type>(m_type); } 59 RenderBox* renderer() const { return m_renderer; } 60 61 bool isPlaced() const { return m_isPlaced; } 62 void setIsPlaced(bool placed = true) { m_isPlaced = placed; } 63 64 LayoutUnit x() const { ASSERT(isPlaced()); return m_frameRect.x(); } 65 LayoutUnit maxX() const { ASSERT(isPlaced()); return m_frameRect.maxX(); } 66 LayoutUnit y() const { ASSERT(isPlaced()); return m_frameRect.y(); } 67 LayoutUnit maxY() const { ASSERT(isPlaced()); return m_frameRect.maxY(); } 68 LayoutUnit width() const { return m_frameRect.width(); } 69 LayoutUnit height() const { return m_frameRect.height(); } 70 71 void setX(LayoutUnit x) { ASSERT(!isInPlacedTree()); m_frameRect.setX(x); } 72 void setY(LayoutUnit y) { ASSERT(!isInPlacedTree()); m_frameRect.setY(y); } 73 void setWidth(LayoutUnit width) { ASSERT(!isInPlacedTree()); m_frameRect.setWidth(width); } 74 void setHeight(LayoutUnit height) { ASSERT(!isInPlacedTree()); m_frameRect.setHeight(height); } 75 76 const LayoutRect& frameRect() const { ASSERT(isPlaced()); return m_frameRect; } 77 void setFrameRect(const LayoutRect& frameRect) { ASSERT(!isInPlacedTree()); m_frameRect = frameRect; } 78 79 int paginationStrut() const { return m_paginationStrut; } 80 void setPaginationStrut(int strut) { m_paginationStrut = strut; } 81 82 #ifndef NDEBUG 83 bool isInPlacedTree() const { return m_isInPlacedTree; } 84 void setIsInPlacedTree(bool value) { m_isInPlacedTree = value; } 85 #endif 86 87 bool shouldPaint() const { return m_shouldPaint; } 88 void setShouldPaint(bool shouldPaint) { m_shouldPaint = shouldPaint; } 89 bool isDescendant() const { return m_isDescendant; } 90 void setIsDescendant(bool isDescendant) { m_isDescendant = isDescendant; } 91 92 // FIXME: Callers of these methods are dangerous and should be whitelisted explicitly or removed. 93 RootInlineBox* originatingLine() const { return m_originatingLine; } 94 void setOriginatingLine(RootInlineBox* line) { m_originatingLine = line; } 95 96 private: 97 explicit FloatingObject(RenderBox*); 98 FloatingObject(RenderBox*, Type, const LayoutRect&, bool shouldPaint, bool isDescendant); 99 100 RenderBox* m_renderer; 101 RootInlineBox* m_originatingLine; 102 LayoutRect m_frameRect; 103 int m_paginationStrut; // FIXME: Is this class size-sensitive? Does this need 32-bits? 104 105 unsigned m_type : 2; // Type (left or right aligned) 106 unsigned m_shouldPaint : 1; 107 unsigned m_isDescendant : 1; 108 unsigned m_isPlaced : 1; 109 #ifndef NDEBUG 110 unsigned m_isInPlacedTree : 1; 111 #endif 112 }; 113 114 struct FloatingObjectHashFunctions { 115 static unsigned hash(FloatingObject* key) { return DefaultHash<RenderBox*>::Hash::hash(key->renderer()); } 116 static bool equal(FloatingObject* a, FloatingObject* b) { return a->renderer() == b->renderer(); } 117 static const bool safeToCompareToEmptyOrDeleted = true; 118 }; 119 struct FloatingObjectHashTranslator { 120 static unsigned hash(RenderBox* key) { return DefaultHash<RenderBox*>::Hash::hash(key); } 121 static bool equal(FloatingObject* a, RenderBox* b) { return a->renderer() == b; } 122 }; 123 typedef ListHashSet<FloatingObject*, 4, FloatingObjectHashFunctions> FloatingObjectSet; 124 typedef FloatingObjectSet::const_iterator FloatingObjectSetIterator; 125 typedef PODInterval<int, FloatingObject*> FloatingObjectInterval; 126 typedef PODIntervalTree<int, FloatingObject*> FloatingObjectTree; 127 typedef PODFreeListArena<PODRedBlackTree<FloatingObjectInterval>::Node> IntervalArena; 128 typedef HashMap<RenderBox*, FloatingObject*> RendererToFloatInfoMap; 129 130 class FloatingObjects { 131 WTF_MAKE_NONCOPYABLE(FloatingObjects); WTF_MAKE_FAST_ALLOCATED; 132 public: 133 FloatingObjects(const RenderBlockFlow*, bool horizontalWritingMode); 134 ~FloatingObjects(); 135 136 void clear(); 137 void moveAllToFloatInfoMap(RendererToFloatInfoMap&); 138 FloatingObject* add(PassOwnPtr<FloatingObject>); 139 void remove(FloatingObject*); 140 void addPlacedObject(FloatingObject*); 141 void removePlacedObject(FloatingObject*); 142 void setHorizontalWritingMode(bool b = true) { m_horizontalWritingMode = b; } 143 144 bool hasLeftObjects() const { return m_leftObjectsCount > 0; } 145 bool hasRightObjects() const { return m_rightObjectsCount > 0; } 146 const FloatingObjectSet& set() const { return m_set; } 147 void clearLineBoxTreePointers(); 148 149 LayoutUnit logicalLeftOffset(LayoutUnit fixedOffset, LayoutUnit logicalTop, LayoutUnit logicalHeight); 150 LayoutUnit logicalRightOffset(LayoutUnit fixedOffset, LayoutUnit logicalTop, LayoutUnit logicalHeight); 151 152 LayoutUnit logicalLeftOffsetForPositioningFloat(LayoutUnit fixedOffset, LayoutUnit logicalTop, LayoutUnit* heightRemaining); 153 LayoutUnit logicalRightOffsetForPositioningFloat(LayoutUnit fixedOffset, LayoutUnit logicalTop, LayoutUnit* heightRemaining); 154 155 LayoutUnit lowestFloatLogicalBottom(FloatingObject::Type); 156 157 private: 158 bool hasLowestFloatLogicalBottomCached(bool isHorizontal, FloatingObject::Type floatType) const; 159 LayoutUnit getCachedlowestFloatLogicalBottom(FloatingObject::Type floatType) const; 160 void setCachedLowestFloatLogicalBottom(bool isHorizontal, FloatingObject::Type floatType, LayoutUnit value); 161 void markLowestFloatLogicalBottomCacheAsDirty(); 162 163 void computePlacedFloatsTree(); 164 const FloatingObjectTree& placedFloatsTree() 165 { 166 if (!m_placedFloatsTree.isInitialized()) 167 computePlacedFloatsTree(); 168 return m_placedFloatsTree; 169 } 170 void increaseObjectsCount(FloatingObject::Type); 171 void decreaseObjectsCount(FloatingObject::Type); 172 FloatingObjectInterval intervalForFloatingObject(FloatingObject*); 173 174 FloatingObjectSet m_set; 175 FloatingObjectTree m_placedFloatsTree; 176 unsigned m_leftObjectsCount; 177 unsigned m_rightObjectsCount; 178 bool m_horizontalWritingMode; 179 const RenderBlockFlow* m_renderer; 180 181 struct FloatBottomCachedValue { 182 FloatBottomCachedValue(); 183 LayoutUnit value; 184 bool dirty; 185 }; 186 FloatBottomCachedValue m_lowestFloatBottomCache[2]; 187 bool m_cachedHorizontalWritingMode; 188 }; 189 190 #ifndef NDEBUG 191 // These structures are used by PODIntervalTree for debugging purposes. 192 template <> struct ValueToString<int> { 193 static String string(const int value); 194 }; 195 template<> struct ValueToString<FloatingObject*> { 196 static String string(const FloatingObject*); 197 }; 198 #endif 199 200 } // namespace WebCore 201 202 #endif // FloatingObjects_h 203