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-2013 Apple Inc. All rights reserved. 6 * Copyright (C) Research In Motion Limited 2010. All rights reserved. 7 * Copyright (C) 2013 Google Inc. All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions are 11 * met: 12 * 13 * * Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * * Redistributions in binary form must reproduce the above 16 * copyright notice, this list of conditions and the following disclaimer 17 * in the documentation and/or other materials provided with the 18 * distribution. 19 * * Neither the name of Google Inc. nor the names of its 20 * contributors may be used to endorse or promote products derived from 21 * this software without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 29 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 33 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36 #ifndef RenderBlockFlow_h 37 #define RenderBlockFlow_h 38 39 #include "core/rendering/FloatingObjects.h" 40 #include "core/rendering/RenderBlock.h" 41 #include "core/rendering/line/TrailingObjects.h" 42 #include "core/rendering/style/RenderStyleConstants.h" 43 44 namespace WebCore { 45 46 class MarginInfo; 47 class LineBreaker; 48 class LineWidth; 49 class RenderMultiColumnFlowThread; 50 51 class RenderBlockFlow : public RenderBlock { 52 public: 53 explicit RenderBlockFlow(ContainerNode*); 54 virtual ~RenderBlockFlow(); 55 56 static RenderBlockFlow* createAnonymous(Document*); 57 58 virtual bool isRenderBlockFlow() const OVERRIDE FINAL { return true; } 59 60 virtual void layoutBlock(bool relayoutChildren) OVERRIDE; 61 62 virtual void computeOverflow(LayoutUnit oldClientAfterEdge, bool recomputeFloats = false) OVERRIDE; 63 virtual void deleteLineBoxTree() OVERRIDE FINAL; 64 65 LayoutUnit availableLogicalWidthForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const 66 { 67 return max<LayoutUnit>(0, logicalRightOffsetForLine(position, shouldIndentText, logicalHeight) - logicalLeftOffsetForLine(position, shouldIndentText, logicalHeight)); 68 } 69 LayoutUnit logicalRightOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const 70 { 71 return logicalRightOffsetForLine(position, logicalRightOffsetForContent(), shouldIndentText, logicalHeight); 72 } 73 LayoutUnit logicalLeftOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const 74 { 75 return logicalLeftOffsetForLine(position, logicalLeftOffsetForContent(), shouldIndentText, logicalHeight); 76 } 77 LayoutUnit startOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const 78 { 79 return style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(position, shouldIndentText, logicalHeight) 80 : logicalWidth() - logicalRightOffsetForLine(position, shouldIndentText, logicalHeight); 81 } 82 LayoutUnit endOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const 83 { 84 return !style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(position, shouldIndentText, logicalHeight) 85 : logicalWidth() - logicalRightOffsetForLine(position, shouldIndentText, logicalHeight); 86 } 87 88 virtual LayoutUnit logicalLeftSelectionOffset(RenderBlock* rootBlock, LayoutUnit position) OVERRIDE; 89 virtual LayoutUnit logicalRightSelectionOffset(RenderBlock* rootBlock, LayoutUnit position) OVERRIDE; 90 91 LayoutUnit computeStartPositionDeltaForChildAvoidingFloats(const RenderBox* child, LayoutUnit childMarginStart); 92 93 RootInlineBox* createAndAppendRootInlineBox(); 94 95 void markAllDescendantsWithFloatsForLayout(RenderBox* floatToRemove = 0, bool inLayout = true); 96 void markSiblingsWithFloatsForLayout(RenderBox* floatToRemove = 0); 97 98 virtual bool containsFloats() const OVERRIDE FINAL { return m_floatingObjects && !m_floatingObjects->set().isEmpty(); } 99 bool containsFloat(RenderBox*) const; 100 101 void removeFloatingObjects(); 102 103 virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0) OVERRIDE; 104 105 void moveAllChildrenIncludingFloatsTo(RenderBlock* toBlock, bool fullRemoveInsert); 106 107 bool generatesLineBoxesForInlineChild(RenderObject*); 108 109 LayoutUnit logicalTopForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->y() : floatingObject->x(); } 110 LayoutUnit logicalBottomForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->maxY() : floatingObject->maxX(); } 111 LayoutUnit logicalLeftForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->x() : floatingObject->y(); } 112 LayoutUnit logicalRightForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->maxX() : floatingObject->maxY(); } 113 LayoutUnit logicalWidthForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->width() : floatingObject->height(); } 114 LayoutUnit logicalHeightForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->height() : floatingObject->width(); } 115 LayoutSize logicalSizeForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? LayoutSize(floatingObject->width(), floatingObject->height()) : LayoutSize(floatingObject->height(), floatingObject->width()); } 116 117 int pixelSnappedLogicalTopForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->frameRect().pixelSnappedY() : floatingObject->frameRect().pixelSnappedX(); } 118 int pixelSnappedLogicalBottomForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->frameRect().pixelSnappedMaxY() : floatingObject->frameRect().pixelSnappedMaxX(); } 119 int pixelSnappedLogicalLeftForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->frameRect().pixelSnappedX() : floatingObject->frameRect().pixelSnappedY(); } 120 int pixelSnappedLogicalRightForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->frameRect().pixelSnappedMaxX() : floatingObject->frameRect().pixelSnappedMaxY(); } 121 122 void setLogicalTopForFloat(FloatingObject* floatingObject, LayoutUnit logicalTop) 123 { 124 if (isHorizontalWritingMode()) 125 floatingObject->setY(logicalTop); 126 else 127 floatingObject->setX(logicalTop); 128 } 129 void setLogicalLeftForFloat(FloatingObject* floatingObject, LayoutUnit logicalLeft) 130 { 131 if (isHorizontalWritingMode()) 132 floatingObject->setX(logicalLeft); 133 else 134 floatingObject->setY(logicalLeft); 135 } 136 void setLogicalHeightForFloat(FloatingObject* floatingObject, LayoutUnit logicalHeight) 137 { 138 if (isHorizontalWritingMode()) 139 floatingObject->setHeight(logicalHeight); 140 else 141 floatingObject->setWidth(logicalHeight); 142 } 143 void setLogicalWidthForFloat(FloatingObject* floatingObject, LayoutUnit logicalWidth) 144 { 145 if (isHorizontalWritingMode()) 146 floatingObject->setWidth(logicalWidth); 147 else 148 floatingObject->setHeight(logicalWidth); 149 } 150 151 LayoutUnit startAlignedOffsetForLine(LayoutUnit position, bool shouldIndentText); 152 153 void setStaticInlinePositionForChild(RenderBox*, LayoutUnit blockOffset, LayoutUnit inlinePosition); 154 void updateStaticInlinePositionForChild(RenderBox*, LayoutUnit logicalTop); 155 156 static bool shouldSkipCreatingRunsForObject(RenderObject* obj) 157 { 158 return obj->isFloating() || (obj->isOutOfFlowPositioned() && !obj->style()->isOriginalDisplayInlineType() && !obj->container()->isRenderInline()); 159 } 160 161 // Direction resolved from string value. 162 static TextRun constructTextRun(RenderObject* context, const Font&, const String&, RenderStyle*, 163 TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion, TextRunFlags = DefaultTextRunFlags); 164 static TextRun constructTextRun(RenderObject* context, const Font&, const RenderText*, unsigned offset, unsigned length, RenderStyle*, 165 TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion); 166 167 // Explicit direction. 168 static TextRun constructTextRun(RenderObject* context, const Font&, const String&, RenderStyle*, TextDirection, 169 TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion, TextRunFlags = DefaultTextRunFlags); 170 171 static TextRun constructTextRun(RenderObject* context, const Font&, const RenderText*, RenderStyle*, TextDirection, 172 TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion); 173 174 static TextRun constructTextRun(RenderObject* context, const Font&, const RenderText*, unsigned offset, unsigned length, RenderStyle*, TextDirection, 175 TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion); 176 177 static TextRun constructTextRun(RenderObject* context, const Font&, const RenderText*, unsigned offset, RenderStyle*, 178 TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion); 179 180 static TextRun constructTextRun(RenderObject* context, const Font&, const LChar* characters, int length, RenderStyle*, TextDirection, 181 TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion); 182 183 static TextRun constructTextRun(RenderObject* context, const Font&, const UChar* characters, int length, RenderStyle*, TextDirection, 184 TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion); 185 186 RenderMultiColumnFlowThread* multiColumnFlowThread() const { return m_rareData ? m_rareData->m_multiColumnFlowThread : 0; } 187 void resetMultiColumnFlowThread() 188 { 189 if (m_rareData) 190 m_rareData->m_multiColumnFlowThread = 0; 191 } 192 193 void addOverflowFromInlineChildren(); 194 195 // FIXME: This should be const to avoid a const_cast, but can modify child dirty bits and RenderCombineText 196 void computeInlinePreferredLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth); 197 198 GapRects inlineSelectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, 199 LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo*); 200 protected: 201 void rebuildFloatsFromIntruding(); 202 void layoutInlineChildren(bool relayoutChildren, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom, LayoutUnit afterEdge); 203 204 void createFloatingObjects(); 205 206 virtual void styleWillChange(StyleDifference, const RenderStyle& newStyle) OVERRIDE; 207 virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE; 208 209 void addOverflowFromFloats(); 210 211 LayoutUnit logicalRightOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit logicalHeight = 0) const 212 { 213 return adjustLogicalRightOffsetForLine(logicalRightFloatOffsetForLine(logicalTop, fixedOffset, logicalHeight), applyTextIndent); 214 } 215 LayoutUnit logicalLeftOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit logicalHeight = 0) const 216 { 217 return adjustLogicalLeftOffsetForLine(logicalLeftFloatOffsetForLine(logicalTop, fixedOffset, logicalHeight), applyTextIndent); 218 } 219 220 virtual RenderObject* layoutSpecialExcludedChild(bool /*relayoutChildren*/, SubtreeLayoutScope&); 221 virtual bool updateLogicalWidthAndColumnWidth() OVERRIDE; 222 223 // These functions optionally update LayoutState's layoutDelta, which is used to ensure they're repainted correctly when moved 224 enum ApplyLayoutDeltaMode { ApplyLayoutDelta, DoNotApplyLayoutDelta }; 225 void setLogicalLeftForChild(RenderBox* child, LayoutUnit logicalLeft, ApplyLayoutDeltaMode = DoNotApplyLayoutDelta); 226 void setLogicalTopForChild(RenderBox* child, LayoutUnit logicalTop, ApplyLayoutDeltaMode = DoNotApplyLayoutDelta); 227 void determineLogicalLeftPositionForChild(RenderBox* child, ApplyLayoutDeltaMode = DoNotApplyLayoutDelta); 228 229 private: 230 bool layoutBlockFlow(bool relayoutChildren, LayoutUnit& pageLogicalHeight, SubtreeLayoutScope&); 231 void layoutBlockChildren(bool relayoutChildren, SubtreeLayoutScope&, LayoutUnit beforeEdge, LayoutUnit afterEdge); 232 233 void layoutBlockChild(RenderBox* child, MarginInfo&, LayoutUnit& previousFloatLogicalBottom); 234 void adjustPositionedBlock(RenderBox* child, const MarginInfo&); 235 void adjustFloatingBlock(const MarginInfo&); 236 237 LayoutPoint flipFloatForWritingModeForChild(const FloatingObject*, const LayoutPoint&) const; 238 239 LayoutUnit xPositionForFloatIncludingMargin(const FloatingObject* child) const 240 { 241 if (isHorizontalWritingMode()) 242 return child->x() + child->renderer()->marginLeft(); 243 244 return child->x() + marginBeforeForChild(child->renderer()); 245 } 246 247 LayoutUnit yPositionForFloatIncludingMargin(const FloatingObject* child) const 248 { 249 if (isHorizontalWritingMode()) 250 return child->y() + marginBeforeForChild(child->renderer()); 251 252 return child->y() + child->renderer()->marginTop(); 253 } 254 255 LayoutPoint computeLogicalLocationForFloat(const FloatingObject*, LayoutUnit logicalTopOffset) const; 256 257 FloatingObject* insertFloatingObject(RenderBox*); 258 void removeFloatingObject(RenderBox*); 259 void removeFloatingObjectsBelow(FloatingObject*, int logicalOffset); 260 261 // Called from lineWidth, to position the floats added in the last line. 262 // Returns true if and only if it has positioned any floats. 263 bool positionNewFloats(); 264 265 LayoutUnit getClearDelta(RenderBox* child, LayoutUnit yPos); 266 267 bool hasOverhangingFloats() { return parent() && !hasColumns() && containsFloats() && lowestFloatLogicalBottom() > logicalHeight(); } 268 bool hasOverhangingFloat(RenderBox*); 269 void addIntrudingFloats(RenderBlockFlow* prev, LayoutUnit xoffset, LayoutUnit yoffset); 270 void addOverhangingFloats(RenderBlockFlow* child, bool makeChildPaintOtherFloats); 271 272 LayoutUnit lowestFloatLogicalBottom(FloatingObject::Type = FloatingObject::FloatLeftRight) const; 273 LayoutUnit nextFloatLogicalBottomBelow(LayoutUnit, ShapeOutsideFloatOffsetMode = ShapeOutsideFloatMarginBoxOffset) const; 274 275 virtual bool hitTestFloats(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset) OVERRIDE FINAL; 276 277 virtual void repaintOverhangingFloats(bool paintAllDescendants) OVERRIDE FINAL; 278 virtual void invalidatePaintForOverflow() OVERRIDE FINAL; 279 virtual void paintFloats(PaintInfo&, const LayoutPoint&, bool preservePhase = false) OVERRIDE FINAL; 280 virtual void clipOutFloatingObjects(RenderBlock*, const PaintInfo*, const LayoutPoint&, const LayoutSize&) OVERRIDE; 281 void clearFloats(EClear); 282 283 LayoutUnit logicalRightFloatOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, LayoutUnit logicalHeight) const; 284 LayoutUnit logicalLeftFloatOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, LayoutUnit logicalHeight) const; 285 286 LayoutUnit logicalRightOffsetForPositioningFloat(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* heightRemaining) const; 287 LayoutUnit logicalLeftOffsetForPositioningFloat(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* heightRemaining) const; 288 289 LayoutUnit adjustLogicalRightOffsetForLine(LayoutUnit offsetFromFloats, bool applyTextIndent) const; 290 LayoutUnit adjustLogicalLeftOffsetForLine(LayoutUnit offsetFromFloats, bool applyTextIndent) const; 291 292 virtual void adjustForBorderFit(LayoutUnit x, LayoutUnit& left, LayoutUnit& right) const OVERRIDE; // Helper function for borderFitAdjust 293 294 virtual RootInlineBox* createRootInlineBox(); // Subclassed by SVG 295 296 void createOrDestroyMultiColumnFlowThreadIfNeeded(); 297 298 void updateLogicalWidthForAlignment(const ETextAlign&, const RootInlineBox*, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float& availableLogicalWidth, unsigned expansionOpportunityCount); 299 void checkForPaginationLogicalHeightChange(LayoutUnit& pageLogicalHeight, bool& pageLogicalHeightChanged, bool& hasSpecifiedPageLogicalHeight); 300 bool shouldRelayoutForPagination(LayoutUnit& pageLogicalHeight, LayoutUnit layoutOverflowLogicalBottom) const; 301 void setColumnCountAndHeight(unsigned count, LayoutUnit pageLogicalHeight); 302 303 public: 304 struct FloatWithRect { 305 FloatWithRect(RenderBox* f) 306 : object(f) 307 , rect(LayoutRect(f->x() - f->marginLeft(), f->y() - f->marginTop(), f->width() + f->marginWidth(), f->height() + f->marginHeight())) 308 , everHadLayout(f->everHadLayout()) 309 { 310 } 311 312 RenderBox* object; 313 LayoutRect rect; 314 bool everHadLayout; 315 }; 316 317 class MarginValues { 318 public: 319 MarginValues(LayoutUnit beforePos, LayoutUnit beforeNeg, LayoutUnit afterPos, LayoutUnit afterNeg) 320 : m_positiveMarginBefore(beforePos) 321 , m_negativeMarginBefore(beforeNeg) 322 , m_positiveMarginAfter(afterPos) 323 , m_negativeMarginAfter(afterNeg) 324 { } 325 326 LayoutUnit positiveMarginBefore() const { return m_positiveMarginBefore; } 327 LayoutUnit negativeMarginBefore() const { return m_negativeMarginBefore; } 328 LayoutUnit positiveMarginAfter() const { return m_positiveMarginAfter; } 329 LayoutUnit negativeMarginAfter() const { return m_negativeMarginAfter; } 330 331 void setPositiveMarginBefore(LayoutUnit pos) { m_positiveMarginBefore = pos; } 332 void setNegativeMarginBefore(LayoutUnit neg) { m_negativeMarginBefore = neg; } 333 void setPositiveMarginAfter(LayoutUnit pos) { m_positiveMarginAfter = pos; } 334 void setNegativeMarginAfter(LayoutUnit neg) { m_negativeMarginAfter = neg; } 335 336 private: 337 LayoutUnit m_positiveMarginBefore; 338 LayoutUnit m_negativeMarginBefore; 339 LayoutUnit m_positiveMarginAfter; 340 LayoutUnit m_negativeMarginAfter; 341 }; 342 MarginValues marginValuesForChild(RenderBox* child) const; 343 344 // Allocated only when some of these fields have non-default values 345 struct RenderBlockFlowRareData { 346 WTF_MAKE_NONCOPYABLE(RenderBlockFlowRareData); WTF_MAKE_FAST_ALLOCATED; 347 public: 348 RenderBlockFlowRareData(const RenderBlockFlow* block) 349 : m_margins(positiveMarginBeforeDefault(block), negativeMarginBeforeDefault(block), positiveMarginAfterDefault(block), negativeMarginAfterDefault(block)) 350 , m_multiColumnFlowThread(0) 351 , m_discardMarginBefore(false) 352 , m_discardMarginAfter(false) 353 { 354 } 355 356 static LayoutUnit positiveMarginBeforeDefault(const RenderBlockFlow* block) 357 { 358 return std::max<LayoutUnit>(block->marginBefore(), 0); 359 } 360 static LayoutUnit negativeMarginBeforeDefault(const RenderBlockFlow* block) 361 { 362 return std::max<LayoutUnit>(-block->marginBefore(), 0); 363 } 364 static LayoutUnit positiveMarginAfterDefault(const RenderBlockFlow* block) 365 { 366 return std::max<LayoutUnit>(block->marginAfter(), 0); 367 } 368 static LayoutUnit negativeMarginAfterDefault(const RenderBlockFlow* block) 369 { 370 return std::max<LayoutUnit>(-block->marginAfter(), 0); 371 } 372 373 MarginValues m_margins; 374 375 RenderMultiColumnFlowThread* m_multiColumnFlowThread; 376 377 bool m_discardMarginBefore : 1; 378 bool m_discardMarginAfter : 1; 379 }; 380 LayoutUnit marginOffsetForSelfCollapsingBlock(); 381 382 protected: 383 LayoutUnit maxPositiveMarginBefore() const { return m_rareData ? m_rareData->m_margins.positiveMarginBefore() : RenderBlockFlowRareData::positiveMarginBeforeDefault(this); } 384 LayoutUnit maxNegativeMarginBefore() const { return m_rareData ? m_rareData->m_margins.negativeMarginBefore() : RenderBlockFlowRareData::negativeMarginBeforeDefault(this); } 385 LayoutUnit maxPositiveMarginAfter() const { return m_rareData ? m_rareData->m_margins.positiveMarginAfter() : RenderBlockFlowRareData::positiveMarginAfterDefault(this); } 386 LayoutUnit maxNegativeMarginAfter() const { return m_rareData ? m_rareData->m_margins.negativeMarginAfter() : RenderBlockFlowRareData::negativeMarginAfterDefault(this); } 387 388 void setMaxMarginBeforeValues(LayoutUnit pos, LayoutUnit neg); 389 void setMaxMarginAfterValues(LayoutUnit pos, LayoutUnit neg); 390 391 void setMustDiscardMarginBefore(bool = true); 392 void setMustDiscardMarginAfter(bool = true); 393 394 bool mustDiscardMarginBefore() const; 395 bool mustDiscardMarginAfter() const; 396 397 bool mustDiscardMarginBeforeForChild(const RenderBox*) const; 398 bool mustDiscardMarginAfterForChild(const RenderBox*) const; 399 400 bool mustSeparateMarginBeforeForChild(const RenderBox*) const; 401 bool mustSeparateMarginAfterForChild(const RenderBox*) const; 402 403 void initMaxMarginValues() 404 { 405 if (m_rareData) { 406 m_rareData->m_margins = MarginValues(RenderBlockFlowRareData::positiveMarginBeforeDefault(this) , RenderBlockFlowRareData::negativeMarginBeforeDefault(this), 407 RenderBlockFlowRareData::positiveMarginAfterDefault(this), RenderBlockFlowRareData::negativeMarginAfterDefault(this)); 408 409 m_rareData->m_discardMarginBefore = false; 410 m_rareData->m_discardMarginAfter = false; 411 } 412 } 413 414 virtual ETextAlign textAlignmentForLine(bool endsWithSoftBreak) const; 415 private: 416 virtual LayoutUnit collapsedMarginBefore() const OVERRIDE FINAL { return maxPositiveMarginBefore() - maxNegativeMarginBefore(); } 417 virtual LayoutUnit collapsedMarginAfter() const OVERRIDE FINAL { return maxPositiveMarginAfter() - maxNegativeMarginAfter(); } 418 419 LayoutUnit collapseMargins(RenderBox* child, MarginInfo&, bool childIsSelfCollapsing); 420 LayoutUnit clearFloatsIfNeeded(RenderBox* child, MarginInfo&, LayoutUnit oldTopPosMargin, LayoutUnit oldTopNegMargin, LayoutUnit yPos, bool childIsSelfCollapsing); 421 LayoutUnit estimateLogicalTopPosition(RenderBox* child, const MarginInfo&, LayoutUnit& estimateWithoutPagination); 422 void marginBeforeEstimateForChild(RenderBox*, LayoutUnit&, LayoutUnit&, bool&) const; 423 void handleAfterSideOfBlock(RenderBox* lastChild, LayoutUnit top, LayoutUnit bottom, MarginInfo&); 424 void setCollapsedBottomMargin(const MarginInfo&); 425 426 LayoutUnit applyBeforeBreak(RenderBox* child, LayoutUnit logicalOffset); // If the child has a before break, then return a new yPos that shifts to the top of the next page/column. 427 LayoutUnit applyAfterBreak(RenderBox* child, LayoutUnit logicalOffset, MarginInfo&); // If the child has an after break, then return a new offset that shifts to the top of the next page/column. 428 429 LayoutUnit adjustBlockChildForPagination(LayoutUnit logicalTopAfterClear, LayoutUnit estimateWithoutPagination, RenderBox* child, bool atBeforeSideOfBlock); 430 431 // Used to store state between styleWillChange and styleDidChange 432 static bool s_canPropagateFloatIntoSibling; 433 434 RenderBlockFlowRareData& ensureRareData(); 435 436 LayoutUnit m_repaintLogicalTop; 437 LayoutUnit m_repaintLogicalBottom; 438 439 virtual bool isSelfCollapsingBlock() const OVERRIDE; 440 protected: 441 OwnPtr<RenderBlockFlowRareData> m_rareData; 442 OwnPtr<FloatingObjects> m_floatingObjects; 443 444 friend class BreakingContext; // FIXME: It uses insertFloatingObject and positionNewFloatOnLine, if we move those out from the private scope/add a helper to LineBreaker, we can remove this friend 445 friend class MarginInfo; 446 friend class LineBreaker; 447 friend class LineWidth; // needs to know FloatingObject 448 449 // FIXME-BLOCKFLOW: These methods have implementations in 450 // RenderBlockLineLayout. They should be moved to the proper header once the 451 // line layout code is separated from RenderBlock and RenderBlockFlow. 452 // START METHODS DEFINED IN RenderBlockLineLayout 453 private: 454 InlineFlowBox* createLineBoxes(RenderObject*, const LineInfo&, InlineBox* childBox); 455 RootInlineBox* constructLine(BidiRunList<BidiRun>&, const LineInfo&); 456 void setMarginsForRubyRun(BidiRun*, RenderRubyRun*, RenderObject*, const LineInfo&); 457 void computeInlineDirectionPositionsForLine(RootInlineBox*, const LineInfo&, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&, WordMeasurements&); 458 BidiRun* computeInlineDirectionPositionsForSegment(RootInlineBox*, const LineInfo&, ETextAlign, float& logicalLeft, 459 float& availableLogicalWidth, BidiRun* firstRun, BidiRun* trailingSpaceRun, GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache&, WordMeasurements&); 460 void computeBlockDirectionPositionsForLine(RootInlineBox*, BidiRun*, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&); 461 BidiRun* handleTrailingSpaces(BidiRunList<BidiRun>&, BidiContext*); 462 void appendFloatingObjectToLastLine(FloatingObject*); 463 // Helper function for layoutInlineChildren() 464 RootInlineBox* createLineBoxesFromBidiRuns(unsigned bidiLevel, BidiRunList<BidiRun>&, const InlineIterator& end, LineInfo&, VerticalPositionCache&, BidiRun* trailingSpaceRun, WordMeasurements&); 465 void layoutRunsAndFloats(LineLayoutState&); 466 const InlineIterator& restartLayoutRunsAndFloatsInRange(LayoutUnit oldLogicalHeight, LayoutUnit newLogicalHeight, FloatingObject* lastFloatFromPreviousLine, InlineBidiResolver&, const InlineIterator&); 467 void layoutRunsAndFloatsInRange(LineLayoutState&, InlineBidiResolver&, const InlineIterator& cleanLineStart, const BidiStatus& cleanLineBidiStatus, unsigned consecutiveHyphenatedLines); 468 void linkToEndLineIfNeeded(LineLayoutState&); 469 static void repaintDirtyFloats(Vector<FloatWithRect>& floats); 470 void checkFloatsInCleanLine(RootInlineBox*, Vector<FloatWithRect>&, size_t& floatIndex, bool& encounteredNewFloat, bool& dirtiedByFloat); 471 RootInlineBox* determineStartPosition(LineLayoutState&, InlineBidiResolver&); 472 void determineEndPosition(LineLayoutState&, RootInlineBox* startBox, InlineIterator& cleanLineStart, BidiStatus& cleanLineBidiStatus); 473 bool checkPaginationAndFloatsAtEndLine(LineLayoutState&); 474 bool matchedEndLine(LineLayoutState&, const InlineBidiResolver&, const InlineIterator& endLineStart, const BidiStatus& endLineStatus); 475 void deleteEllipsisLineBoxes(); 476 void checkLinesForTextOverflow(); 477 // Positions new floats and also adjust all floats encountered on the line if any of them 478 // have to move to the next page/column. 479 bool positionNewFloatOnLine(FloatingObject* newFloat, FloatingObject* lastFloatFromPreviousLine, LineInfo&, LineWidth&); 480 481 482 // END METHODS DEFINED IN RenderBlockLineLayout 483 484 }; 485 486 DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderBlockFlow, isRenderBlockFlow()); 487 488 } // namespace WebCore 489 490 #endif // RenderBlockFlow_h 491