1 /* 2 * This file is part of the render object implementation for KHTML. 3 * 4 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 5 * (C) 1999 Antti Koivisto (koivisto@kde.org) 6 * (C) 2007 David Smith (catfish.man@gmail.com) 7 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. 8 * 9 * This library is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU Library General Public 11 * License as published by the Free Software Foundation; either 12 * version 2 of the License, or (at your option) any later version. 13 * 14 * This library is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * Library General Public License for more details. 18 * 19 * You should have received a copy of the GNU Library General Public License 20 * along with this library; see the file COPYING.LIB. If not, write to 21 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 22 * Boston, MA 02110-1301, USA. 23 */ 24 25 #ifndef RenderBlock_h 26 #define RenderBlock_h 27 28 #include "DeprecatedPtrList.h" 29 #include "GapRects.h" 30 #include "RenderFlow.h" 31 #include "RootInlineBox.h" 32 #include <wtf/ListHashSet.h> 33 34 namespace WebCore { 35 36 class InlineIterator; 37 class BidiRun; 38 class Position; 39 class RootInlineBox; 40 41 template <class Iterator, class Run> class BidiResolver; 42 typedef BidiResolver<InlineIterator, BidiRun> InlineBidiResolver; 43 44 enum CaretType { CursorCaret, DragCaret }; 45 46 class RenderBlock : public RenderFlow { 47 public: 48 RenderBlock(Node*); 49 virtual ~RenderBlock(); 50 51 virtual const char* renderName() const; 52 53 // These two functions are overridden for inline-block. 54 virtual int lineHeight(bool firstLine, bool isRootLineBox = false) const; 55 virtual int baselinePosition(bool firstLine, bool isRootLineBox = false) const; 56 isRenderBlock()57 virtual bool isRenderBlock() const { return true; } isBlockFlow()58 virtual bool isBlockFlow() const { return (!isInline() || isReplaced()) && !isTable(); } isInlineBlockOrInlineTable()59 virtual bool isInlineBlockOrInlineTable() const { return isInline() && isReplaced(); } 60 childrenInline()61 virtual bool childrenInline() const { return m_childrenInline; } setChildrenInline(bool b)62 virtual void setChildrenInline(bool b) { m_childrenInline = b; } 63 void makeChildrenNonInline(RenderObject* insertionPoint = 0); 64 void deleteLineBoxTree(); 65 66 // The height (and width) of a block when you include overflow spillage out of the bottom 67 // of the block (e.g., a <div style="height:25px"> that has a 100px tall image inside 68 // it would have an overflow height of borderTop() + paddingTop() + 100px. 69 virtual int overflowHeight(bool includeInterior = true) const; 70 virtual int overflowWidth(bool includeInterior = true) const; 71 virtual int overflowLeft(bool includeInterior = true) const; 72 virtual int overflowTop(bool includeInterior = true) const; 73 virtual IntRect overflowRect(bool includeInterior = true) const; setOverflowHeight(int h)74 virtual void setOverflowHeight(int h) { m_overflowHeight = h; } setOverflowWidth(int w)75 virtual void setOverflowWidth(int w) { m_overflowWidth = w; } 76 77 void addVisualOverflow(const IntRect&); 78 79 virtual bool isSelfCollapsingBlock() const; isTopMarginQuirk()80 virtual bool isTopMarginQuirk() const { return m_topMarginQuirk; } isBottomMarginQuirk()81 virtual bool isBottomMarginQuirk() const { return m_bottomMarginQuirk; } 82 maxTopMargin(bool positive)83 virtual int maxTopMargin(bool positive) const { return positive ? maxTopPosMargin() : maxTopNegMargin(); } maxBottomMargin(bool positive)84 virtual int maxBottomMargin(bool positive) const { return positive ? maxBottomPosMargin() : maxBottomNegMargin(); } 85 maxTopPosMargin()86 int maxTopPosMargin() const { return m_maxMargin ? m_maxMargin->m_topPos : MaxMargin::topPosDefault(this); } maxTopNegMargin()87 int maxTopNegMargin() const { return m_maxMargin ? m_maxMargin->m_topNeg : MaxMargin::topNegDefault(this); } maxBottomPosMargin()88 int maxBottomPosMargin() const { return m_maxMargin ? m_maxMargin->m_bottomPos : MaxMargin::bottomPosDefault(this); } maxBottomNegMargin()89 int maxBottomNegMargin() const { return m_maxMargin ? m_maxMargin->m_bottomNeg : MaxMargin::bottomNegDefault(this); } 90 void setMaxTopMargins(int pos, int neg); 91 void setMaxBottomMargins(int pos, int neg); 92 initMaxMarginValues()93 void initMaxMarginValues() 94 { 95 if (m_maxMargin) { 96 m_maxMargin->m_topPos = MaxMargin::topPosDefault(this); 97 m_maxMargin->m_topNeg = MaxMargin::topNegDefault(this); 98 m_maxMargin->m_bottomPos = MaxMargin::bottomPosDefault(this); 99 m_maxMargin->m_bottomNeg = MaxMargin::bottomNegDefault(this); 100 } 101 } 102 103 virtual void addChildToFlow(RenderObject* newChild, RenderObject* beforeChild); 104 virtual void removeChild(RenderObject*); 105 106 virtual void repaintOverhangingFloats(bool paintAllDescendants); 107 108 virtual void layout(); 109 virtual void layoutBlock(bool relayoutChildren); 110 void layoutBlockChildren(bool relayoutChildren, int& maxFloatBottom); 111 void layoutInlineChildren(bool relayoutChildren, int& repaintTop, int& repaintBottom); 112 113 void layoutPositionedObjects(bool relayoutChildren); 114 void insertPositionedObject(RenderBox*); 115 void removePositionedObject(RenderBox*); 116 void removePositionedObjects(RenderBlock*); 117 118 void addPercentHeightDescendant(RenderBox*); 119 static void removePercentHeightDescendant(RenderBox*); 120 positionListMarker()121 virtual void positionListMarker() { } 122 123 virtual void borderFitAdjust(int& x, int& w) const; // Shrink the box in which the border paints if border-fit is set. 124 125 // Called to lay out the legend for a fieldset. layoutLegend(bool)126 virtual RenderObject* layoutLegend(bool /*relayoutChildren*/) { return 0; } 127 128 // the implementation of the following functions is in bidi.cpp 129 struct FloatWithRect { FloatWithRectFloatWithRect130 FloatWithRect(RenderBox* f) 131 : object(f) 132 , rect(IntRect(f->x() - f->marginLeft(), f->y() - f->marginTop(), f->width() + f->marginLeft() + f->marginRight(), f->height() + f->marginTop() + f->marginBottom())) 133 { 134 } 135 136 RenderBox* object; 137 IntRect rect; 138 }; 139 140 void bidiReorderLine(InlineBidiResolver&, const InlineIterator& end); 141 RootInlineBox* determineStartPosition(bool& fullLayout, InlineBidiResolver&, Vector<FloatWithRect>& floats, unsigned& numCleanFloats); 142 RootInlineBox* determineEndPosition(RootInlineBox* startBox, InlineIterator& cleanLineStart, 143 BidiStatus& cleanLineBidiStatus, 144 int& yPos); 145 bool matchedEndLine(const InlineBidiResolver&, const InlineIterator& endLineStart, const BidiStatus& endLineStatus, 146 RootInlineBox*& endLine, int& endYPos, int& repaintBottom, int& repaintTop); 147 bool generatesLineBoxesForInlineChild(RenderObject*); 148 void skipTrailingWhitespace(InlineIterator&); 149 int skipLeadingWhitespace(InlineBidiResolver&); 150 void fitBelowFloats(int widthToFit, int& availableWidth); 151 InlineIterator findNextLineBreak(InlineBidiResolver&, EClear* clear = 0); 152 RootInlineBox* constructLine(unsigned runCount, BidiRun* firstRun, BidiRun* lastRun, bool lastLine, RenderObject* endObject); 153 InlineFlowBox* createLineBoxes(RenderObject*); 154 void computeHorizontalPositionsForLine(RootInlineBox*, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd); 155 void computeVerticalPositionsForLine(RootInlineBox*, BidiRun*); 156 void checkLinesForOverflow(); 157 void deleteEllipsisLineBoxes(); 158 void checkLinesForTextOverflow(); 159 // end bidi.cpp functions 160 161 virtual void paint(PaintInfo&, int tx, int ty); 162 virtual void paintObject(PaintInfo&, int tx, int ty); 163 void paintFloats(PaintInfo&, int tx, int ty, bool preservePhase = false); 164 void paintContents(PaintInfo&, int tx, int ty); 165 void paintColumns(PaintInfo&, int tx, int ty, bool paintFloats = false); 166 void paintChildren(PaintInfo&, int tx, int ty); 167 void paintEllipsisBoxes(PaintInfo&, int tx, int ty); 168 void paintSelection(PaintInfo&, int tx, int ty); 169 void paintCaret(PaintInfo&, int tx, int ty, CaretType); 170 171 void insertFloatingObject(RenderBox*); 172 void removeFloatingObject(RenderBox*); 173 174 // Called from lineWidth, to position the floats added in the last line. 175 // Returns ture if and only if it has positioned any floats. 176 bool positionNewFloats(); 177 void clearFloats(); 178 int getClearDelta(RenderBox* child); 179 void markAllDescendantsWithFloatsForLayout(RenderBox* floatToRemove = 0, bool inLayout = true); 180 void markPositionedObjectsForLayout(); 181 containsFloats()182 virtual bool containsFloats() { return m_floatingObjects && !m_floatingObjects->isEmpty(); } 183 virtual bool containsFloat(RenderObject*); 184 185 virtual bool avoidsFloats() const; 186 hasOverhangingFloats()187 virtual bool hasOverhangingFloats() { return !hasColumns() && floatBottom() > height(); } 188 void addIntrudingFloats(RenderBlock* prev, int xoffset, int yoffset); 189 int addOverhangingFloats(RenderBlock* child, int xoffset, int yoffset, bool makeChildPaintOtherFloats); 190 191 int nextFloatBottomBelow(int) const; 192 int floatBottom() const; 193 inline int leftBottom(); 194 inline int rightBottom(); 195 IntRect floatRect() const; 196 197 virtual int lineWidth(int) const; 198 virtual int lowestPosition(bool includeOverflowInterior = true, bool includeSelf = true) const; 199 virtual int rightmostPosition(bool includeOverflowInterior = true, bool includeSelf = true) const; 200 virtual int leftmostPosition(bool includeOverflowInterior = true, bool includeSelf = true) const; 201 202 int rightOffset() const; 203 int rightRelOffset(int y, int fixedOffset, bool applyTextIndent = true, int* heightRemaining = 0) const; rightOffset(int y)204 int rightOffset(int y) const { return rightRelOffset(y, rightOffset(), true); } 205 206 int leftOffset() const; 207 int leftRelOffset(int y, int fixedOffset, bool applyTextIndent = true, int* heightRemaining = 0) const; leftOffset(int y)208 int leftOffset(int y) const { return leftRelOffset(y, leftOffset(), true); } 209 210 virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction); 211 virtual bool hitTestColumns(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction); 212 virtual bool hitTestContents(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction); 213 214 virtual bool isPointInOverflowControl(HitTestResult&, int x, int y, int tx, int ty); 215 216 virtual VisiblePosition positionForCoordinates(int x, int y); 217 218 // Block flows subclass availableWidth to handle multi column layout (shrinking the width available to children when laying out.) 219 virtual int availableWidth() const; 220 221 virtual void calcPrefWidths(); 222 void calcInlinePrefWidths(); 223 void calcBlockPrefWidths(); 224 225 virtual int getBaselineOfFirstLineBox() const; 226 virtual int getBaselineOfLastLineBox() const; 227 firstRootBox()228 RootInlineBox* firstRootBox() const { return static_cast<RootInlineBox*>(firstLineBox()); } lastRootBox()229 RootInlineBox* lastRootBox() const { return static_cast<RootInlineBox*>(lastLineBox()); } 230 231 bool containsNonZeroBidiLevel() const; 232 233 // Obtains the nearest enclosing block (including this block) that contributes a first-line style to our inline 234 // children. 235 virtual RenderBlock* firstLineBlock() const; 236 virtual void updateFirstLetter(); 237 238 bool inRootBlockContext() const; 239 240 void setHasMarkupTruncation(bool b = true) { m_hasMarkupTruncation = b; } hasMarkupTruncation()241 bool hasMarkupTruncation() const { return m_hasMarkupTruncation; } 242 hasSelectedChildren()243 virtual bool hasSelectedChildren() const { return m_selectionState != SelectionNone; } selectionState()244 virtual SelectionState selectionState() const { return static_cast<SelectionState>(m_selectionState); } 245 virtual void setSelectionState(SelectionState s); 246 247 struct BlockSelectionInfo { 248 RenderBlock* m_block; 249 GapRects m_rects; 250 SelectionState m_state; 251 BlockSelectionInfoBlockSelectionInfo252 BlockSelectionInfo() 253 : m_block(0) 254 , m_state(SelectionNone) 255 { 256 } 257 BlockSelectionInfoBlockSelectionInfo258 BlockSelectionInfo(RenderBlock* b) 259 : m_block(b) 260 , m_rects(b->needsLayout() ? GapRects() : b->selectionGapRects()) 261 , m_state(b->selectionState()) 262 { 263 } 264 blockBlockSelectionInfo265 RenderBlock* block() const { return m_block; } rectsBlockSelectionInfo266 GapRects rects() const { return m_rects; } stateBlockSelectionInfo267 SelectionState state() const { return m_state; } 268 }; 269 selectionRect(bool)270 virtual IntRect selectionRect(bool) { return selectionGapRects(); } 271 GapRects selectionGapRects(); 272 virtual bool shouldPaintSelectionGaps() const; 273 bool isSelectionRoot() const; 274 GapRects fillSelectionGaps(RenderBlock* rootBlock, int blockX, int blockY, int tx, int ty, 275 int& lastTop, int& lastLeft, int& lastRight, const PaintInfo* = 0); 276 GapRects fillInlineSelectionGaps(RenderBlock* rootBlock, int blockX, int blockY, int tx, int ty, 277 int& lastTop, int& lastLeft, int& lastRight, const PaintInfo*); 278 GapRects fillBlockSelectionGaps(RenderBlock* rootBlock, int blockX, int blockY, int tx, int ty, 279 int& lastTop, int& lastLeft, int& lastRight, const PaintInfo*); 280 IntRect fillVerticalSelectionGap(int lastTop, int lastLeft, int lastRight, int bottomY, RenderBlock* rootBlock, 281 int blockX, int blockY, const PaintInfo*); 282 IntRect fillLeftSelectionGap(RenderObject* selObj, int xPos, int yPos, int height, RenderBlock* rootBlock, 283 int blockX, int blockY, int tx, int ty, const PaintInfo*); 284 IntRect fillRightSelectionGap(RenderObject* selObj, int xPos, int yPos, int height, RenderBlock* rootBlock, 285 int blockX, int blockY, int tx, int ty, const PaintInfo*); 286 IntRect fillHorizontalSelectionGap(RenderObject* selObj, int xPos, int yPos, int width, int height, const PaintInfo*); 287 288 void getHorizontalSelectionGapInfo(SelectionState, bool& leftGap, bool& rightGap); 289 int leftSelectionOffset(RenderBlock* rootBlock, int y); 290 int rightSelectionOffset(RenderBlock* rootBlock, int y); 291 292 // Helper methods for computing line counts and heights for line counts. 293 RootInlineBox* lineAtIndex(int); 294 int lineCount(); 295 int heightForLineCount(int); 296 void clearTruncation(); 297 298 int desiredColumnWidth() const; 299 unsigned desiredColumnCount() const; 300 Vector<IntRect>* columnRects() const; 301 void setDesiredColumnCountAndWidth(int count, int width); 302 303 void adjustRectForColumns(IntRect&) const; 304 305 void addContinuationWithOutline(RenderFlow*); 306 void paintContinuationOutlines(PaintInfo&, int tx, int ty); 307 308 private: 309 void adjustPointToColumnContents(IntPoint&) const; 310 void adjustForBorderFit(int x, int& left, int& right) const; // Helper function for borderFitAdjust 311 312 void markLinesDirtyInVerticalRange(int top, int bottom); 313 314 protected: 315 virtual void styleWillChange(RenderStyle::Diff, const RenderStyle* newStyle); 316 virtual void styleDidChange(RenderStyle::Diff, const RenderStyle* oldStyle); 317 318 void newLine(EClear); 319 virtual bool hasLineIfEmpty() const; 320 bool layoutOnlyPositionedObjects(); 321 322 private: 323 Position positionForBox(InlineBox*, bool start = true) const; 324 Position positionForRenderer(RenderObject*, bool start = true) const; 325 326 // Adjust tx and ty from painting offsets to the local coords of this renderer 327 void offsetForContents(int& tx, int& ty) const; 328 329 // columGap() is used by WebKit when hit-testing columns. It's called by 330 // CacheBuilder when it duplicates the hit-testing logic. 331 #ifdef ANDROID_EXPOSE_COLUMN_GAP 332 public: 333 #endif 334 int columnGap() const; 335 #ifdef ANDROID_EXPOSE_COLUMN_GAP 336 private: 337 #endif 338 void calcColumnWidth(); 339 int layoutColumns(int endOfContent = -1); 340 341 bool expandsToEncloseOverhangingFloats() const; 342 343 protected: 344 struct FloatingObject { 345 enum Type { 346 FloatLeft, 347 FloatRight 348 }; 349 FloatingObjectFloatingObject350 FloatingObject(Type type) 351 : m_renderer(0) 352 , m_top(0) 353 , m_bottom(0) 354 , m_left(0) 355 , m_width(0) 356 , m_type(type) 357 , m_shouldPaint(true) 358 , m_isDescendant(false) 359 { 360 } 361 typeFloatingObject362 Type type() { return static_cast<Type>(m_type); } 363 364 RenderBox* m_renderer; 365 int m_top; 366 int m_bottom; 367 int m_left; 368 int m_width; 369 unsigned m_type : 1; // Type (left or right aligned) 370 bool m_shouldPaint : 1; 371 bool m_isDescendant : 1; 372 }; 373 374 class MarginInfo { 375 // Collapsing flags for whether we can collapse our margins with our children's margins. 376 bool m_canCollapseWithChildren : 1; 377 bool m_canCollapseTopWithChildren : 1; 378 bool m_canCollapseBottomWithChildren : 1; 379 380 // Whether or not we are a quirky container, i.e., do we collapse away top and bottom 381 // margins in our container. Table cells and the body are the common examples. We 382 // also have a custom style property for Safari RSS to deal with TypePad blog articles. 383 bool m_quirkContainer : 1; 384 385 // This flag tracks whether we are still looking at child margins that can all collapse together at the beginning of a block. 386 // They may or may not collapse with the top margin of the block (|m_canCollapseTopWithChildren| tells us that), but they will 387 // always be collapsing with one another. This variable can remain set to true through multiple iterations 388 // as long as we keep encountering self-collapsing blocks. 389 bool m_atTopOfBlock : 1; 390 391 // This flag is set when we know we're examining bottom margins and we know we're at the bottom of the block. 392 bool m_atBottomOfBlock : 1; 393 394 // If our last normal flow child was a self-collapsing block that cleared a float, 395 // we track it in this variable. 396 bool m_selfCollapsingBlockClearedFloat : 1; 397 398 // These variables are used to detect quirky margins that we need to collapse away (in table cells 399 // and in the body element). 400 bool m_topQuirk : 1; 401 bool m_bottomQuirk : 1; 402 bool m_determinedTopQuirk : 1; 403 404 // These flags track the previous maximal positive and negative margins. 405 int m_posMargin; 406 int m_negMargin; 407 408 public: 409 MarginInfo(RenderBlock* b, int top, int bottom); 410 setAtTopOfBlock(bool b)411 void setAtTopOfBlock(bool b) { m_atTopOfBlock = b; } setAtBottomOfBlock(bool b)412 void setAtBottomOfBlock(bool b) { m_atBottomOfBlock = b; } clearMargin()413 void clearMargin() { m_posMargin = m_negMargin = 0; } setSelfCollapsingBlockClearedFloat(bool b)414 void setSelfCollapsingBlockClearedFloat(bool b) { m_selfCollapsingBlockClearedFloat = b; } setTopQuirk(bool b)415 void setTopQuirk(bool b) { m_topQuirk = b; } setBottomQuirk(bool b)416 void setBottomQuirk(bool b) { m_bottomQuirk = b; } setDeterminedTopQuirk(bool b)417 void setDeterminedTopQuirk(bool b) { m_determinedTopQuirk = b; } setPosMargin(int p)418 void setPosMargin(int p) { m_posMargin = p; } setNegMargin(int n)419 void setNegMargin(int n) { m_negMargin = n; } setPosMarginIfLarger(int p)420 void setPosMarginIfLarger(int p) { if (p > m_posMargin) m_posMargin = p; } setNegMarginIfLarger(int n)421 void setNegMarginIfLarger(int n) { if (n > m_negMargin) m_negMargin = n; } 422 setMargin(int p,int n)423 void setMargin(int p, int n) { m_posMargin = p; m_negMargin = n; } 424 atTopOfBlock()425 bool atTopOfBlock() const { return m_atTopOfBlock; } canCollapseWithTop()426 bool canCollapseWithTop() const { return m_atTopOfBlock && m_canCollapseTopWithChildren; } canCollapseWithBottom()427 bool canCollapseWithBottom() const { return m_atBottomOfBlock && m_canCollapseBottomWithChildren; } canCollapseTopWithChildren()428 bool canCollapseTopWithChildren() const { return m_canCollapseTopWithChildren; } canCollapseBottomWithChildren()429 bool canCollapseBottomWithChildren() const { return m_canCollapseBottomWithChildren; } selfCollapsingBlockClearedFloat()430 bool selfCollapsingBlockClearedFloat() const { return m_selfCollapsingBlockClearedFloat; } quirkContainer()431 bool quirkContainer() const { return m_quirkContainer; } determinedTopQuirk()432 bool determinedTopQuirk() const { return m_determinedTopQuirk; } topQuirk()433 bool topQuirk() const { return m_topQuirk; } bottomQuirk()434 bool bottomQuirk() const { return m_bottomQuirk; } posMargin()435 int posMargin() const { return m_posMargin; } negMargin()436 int negMargin() const { return m_negMargin; } margin()437 int margin() const { return m_posMargin - m_negMargin; } 438 }; 439 440 void adjustPositionedBlock(RenderBox* child, const MarginInfo&); 441 void adjustFloatingBlock(const MarginInfo&); 442 RenderBox* handleSpecialChild(RenderBox* child, const MarginInfo&, bool& handled); 443 RenderBox* handleFloatingChild(RenderBox* child, const MarginInfo&, bool& handled); 444 RenderBox* handlePositionedChild(RenderBox* child, const MarginInfo&, bool& handled); 445 RenderBox* handleRunInChild(RenderBox* child, bool& handled); 446 void collapseMargins(RenderBox* child, MarginInfo&, int yPosEstimate); 447 void clearFloatsIfNeeded(RenderBox* child, MarginInfo&, int oldTopPosMargin, int oldTopNegMargin); 448 int estimateVerticalPosition(RenderBox* child, const MarginInfo&); 449 void determineHorizontalPosition(RenderBox* child); 450 void handleBottomOfBlock(int top, int bottom, MarginInfo&); 451 void setCollapsedBottomMargin(const MarginInfo&); 452 // End helper functions and structs used by layoutBlockChildren. 453 454 private: 455 typedef ListHashSet<RenderBox*>::const_iterator Iterator; 456 DeprecatedPtrList<FloatingObject>* m_floatingObjects; 457 ListHashSet<RenderBox*>* m_positionedObjects; 458 459 // Allocated only when some of these fields have non-default values 460 struct MaxMargin { MaxMarginMaxMargin461 MaxMargin(const RenderBlock* o) 462 : m_topPos(topPosDefault(o)) 463 , m_topNeg(topNegDefault(o)) 464 , m_bottomPos(bottomPosDefault(o)) 465 , m_bottomNeg(bottomNegDefault(o)) 466 { 467 } 468 topPosDefaultMaxMargin469 static int topPosDefault(const RenderBlock* o) { return o->marginTop() > 0 ? o->marginTop() : 0; } topNegDefaultMaxMargin470 static int topNegDefault(const RenderBlock* o) { return o->marginTop() < 0 ? -o->marginTop() : 0; } bottomPosDefaultMaxMargin471 static int bottomPosDefault(const RenderBlock* o) { return o->marginBottom() > 0 ? o->marginBottom() : 0; } bottomNegDefaultMaxMargin472 static int bottomNegDefault(const RenderBlock* o) { return o->marginBottom() < 0 ? -o->marginBottom() : 0; } 473 474 int m_topPos; 475 int m_topNeg; 476 int m_bottomPos; 477 int m_bottomNeg; 478 }; 479 480 MaxMargin* m_maxMargin; 481 482 protected: 483 // How much content overflows out of our block vertically or horizontally. 484 int m_overflowHeight; 485 int m_overflowWidth; 486 int m_overflowLeft; 487 int m_overflowTop; 488 }; 489 490 } // namespace WebCore 491 492 #endif // RenderBlock_h 493