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

Side by Side Diff: Source/core/rendering/RenderBlock.cpp

Issue 148823002: *** DO NOT LAND *** Measure the size and complexity of the old multicol implementation. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 10 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 unified diff | Download patch
« no previous file with comments | « Source/core/rendering/RenderBlock.h ('k') | Source/core/rendering/RenderBlockFlow.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2007 David Smith (catfish.man@gmail.com) 4 * (C) 2007 David Smith (catfish.man@gmail.com)
5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. 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. 6 * Copyright (C) Research In Motion Limited 2010. All rights reserved.
7 * 7 *
8 * This library is free software; you can redistribute it and/or 8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public 9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either 10 * License as published by the Free Software Foundation; either
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 struct SameSizeAsRenderBlockRareData { 86 struct SameSizeAsRenderBlockRareData {
87 int paginationStrut; 87 int paginationStrut;
88 int pageLogicalOffset; 88 int pageLogicalOffset;
89 void* pointers[1]; 89 void* pointers[1];
90 uint32_t bitfields; 90 uint32_t bitfields;
91 }; 91 };
92 92
93 COMPILE_ASSERT(sizeof(RenderBlock) == sizeof(SameSizeAsRenderBlock), RenderBlock _should_stay_small); 93 COMPILE_ASSERT(sizeof(RenderBlock) == sizeof(SameSizeAsRenderBlock), RenderBlock _should_stay_small);
94 COMPILE_ASSERT(sizeof(RenderBlock::RenderBlockRareData) == sizeof(SameSizeAsRend erBlockRareData), RenderBlockRareData_should_stay_small); 94 COMPILE_ASSERT(sizeof(RenderBlock::RenderBlockRareData) == sizeof(SameSizeAsRend erBlockRareData), RenderBlockRareData_should_stay_small);
95 95
96 typedef WTF::HashMap<const RenderBox*, OwnPtr<ColumnInfo> > ColumnInfoMap;
97 static ColumnInfoMap* gColumnInfoMap = 0;
98
99 static TrackedDescendantsMap* gPositionedDescendantsMap = 0; 96 static TrackedDescendantsMap* gPositionedDescendantsMap = 0;
100 static TrackedDescendantsMap* gPercentHeightDescendantsMap = 0; 97 static TrackedDescendantsMap* gPercentHeightDescendantsMap = 0;
101 98
102 static TrackedContainerMap* gPositionedContainerMap = 0; 99 static TrackedContainerMap* gPositionedContainerMap = 0;
103 static TrackedContainerMap* gPercentHeightContainerMap = 0; 100 static TrackedContainerMap* gPercentHeightContainerMap = 0;
104 101
105 typedef WTF::HashMap<RenderBlock*, OwnPtr<ListHashSet<RenderInline*> > > Continu ationOutlineTableMap; 102 typedef WTF::HashMap<RenderBlock*, OwnPtr<ListHashSet<RenderInline*> > > Continu ationOutlineTableMap;
106 103
107 typedef WTF::HashSet<RenderBlock*> DelayedUpdateScrollInfoSet; 104 typedef WTF::HashSet<RenderBlock*> DelayedUpdateScrollInfoSet;
108 static int gDelayUpdateScrollInfo = 0; 105 static int gDelayUpdateScrollInfo = 0;
109 static DelayedUpdateScrollInfoSet* gDelayedUpdateScrollInfoSet = 0; 106 static DelayedUpdateScrollInfoSet* gDelayedUpdateScrollInfoSet = 0;
110 107
111 static bool gColumnFlowSplitEnabled = true;
112
113 // This class helps dispatching the 'overflow' event on layout change. overflow can be set on RenderBoxes, yet the existing code 108 // This class helps dispatching the 'overflow' event on layout change. overflow can be set on RenderBoxes, yet the existing code
114 // only works on RenderBlocks. If this changes, this class should be shared with other RenderBoxes. 109 // only works on RenderBlocks. If this changes, this class should be shared with other RenderBoxes.
115 class OverflowEventDispatcher { 110 class OverflowEventDispatcher {
116 WTF_MAKE_NONCOPYABLE(OverflowEventDispatcher); 111 WTF_MAKE_NONCOPYABLE(OverflowEventDispatcher);
117 public: 112 public:
118 OverflowEventDispatcher(const RenderBlock* block) 113 OverflowEventDispatcher(const RenderBlock* block)
119 : m_block(block) 114 : m_block(block)
120 { 115 {
121 m_shouldDispatchEvent = !m_block->isAnonymous() && m_block->hasOverflowC lip() && m_block->document().hasListenerType(Document::OVERFLOWCHANGED_LISTENER) ; 116 m_shouldDispatchEvent = !m_block->isAnonymous() && m_block->hasOverflowC lip() && m_block->document().hasListenerType(Document::OVERFLOWCHANGED_LISTENER) ;
122 if (m_shouldDispatchEvent) { 117 if (m_shouldDispatchEvent) {
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 if (blockStyle.boxReflect()) 206 if (blockStyle.boxReflect())
212 appendImageIfNotNull(images, blockStyle.boxReflect()->mask().image()); 207 appendImageIfNotNull(images, blockStyle.boxReflect()->mask().image());
213 appendImageIfNotNull(images, blockStyle.listStyleImage()); 208 appendImageIfNotNull(images, blockStyle.listStyleImage());
214 appendImageIfNotNull(images, blockStyle.borderImageSource()); 209 appendImageIfNotNull(images, blockStyle.borderImageSource());
215 appendImageIfNotNull(images, blockStyle.maskBoxImageSource()); 210 appendImageIfNotNull(images, blockStyle.maskBoxImageSource());
216 } 211 }
217 212
218 RenderBlock::~RenderBlock() 213 RenderBlock::~RenderBlock()
219 { 214 {
220 ResourceLoadPriorityOptimizer::resourceLoadPriorityOptimizer()->removeRender Object(this); 215 ResourceLoadPriorityOptimizer::resourceLoadPriorityOptimizer()->removeRender Object(this);
221 if (hasColumns())
222 gColumnInfoMap->take(this);
223 if (gPercentHeightDescendantsMap) 216 if (gPercentHeightDescendantsMap)
224 removeBlockFromDescendantAndContainerMaps(this, gPercentHeightDescendant sMap, gPercentHeightContainerMap); 217 removeBlockFromDescendantAndContainerMaps(this, gPercentHeightDescendant sMap, gPercentHeightContainerMap);
225 if (gPositionedDescendantsMap) 218 if (gPositionedDescendantsMap)
226 removeBlockFromDescendantAndContainerMaps(this, gPositionedDescendantsMa p, gPositionedContainerMap); 219 removeBlockFromDescendantAndContainerMaps(this, gPositionedDescendantsMa p, gPositionedContainerMap);
227 } 220 }
228 221
229 void RenderBlock::willBeDestroyed() 222 void RenderBlock::willBeDestroyed()
230 { 223 {
231 // Mark as being destroyed to avoid trouble with merges in removeChild(). 224 // Mark as being destroyed to avoid trouble with merges in removeChild().
232 m_beingDestroyed = true; 225 m_beingDestroyed = true;
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 } 374 }
382 375
383 if (!beforeChild && !last->firstChild()) 376 if (!beforeChild && !last->firstChild())
384 return nextToLast; 377 return nextToLast;
385 return last; 378 return last;
386 } 379 }
387 380
388 void RenderBlock::addChildToContinuation(RenderObject* newChild, RenderObject* b eforeChild) 381 void RenderBlock::addChildToContinuation(RenderObject* newChild, RenderObject* b eforeChild)
389 { 382 {
390 RenderBlock* flow = continuationBefore(beforeChild); 383 RenderBlock* flow = continuationBefore(beforeChild);
391 ASSERT(!beforeChild || beforeChild->parent()->isAnonymousColumnSpanBlock() | | beforeChild->parent()->isRenderBlock()); 384 ASSERT(!beforeChild || beforeChild->parent()->isRenderBlock());
392 RenderBoxModelObject* beforeChildParent = 0; 385 RenderBoxModelObject* beforeChildParent = 0;
393 if (beforeChild) 386 if (beforeChild)
394 beforeChildParent = toRenderBoxModelObject(beforeChild->parent()); 387 beforeChildParent = toRenderBoxModelObject(beforeChild->parent());
395 else { 388 else {
396 RenderBoxModelObject* cont = flow->continuation(); 389 RenderBoxModelObject* cont = flow->continuation();
397 if (cont) 390 if (cont)
398 beforeChildParent = cont; 391 beforeChildParent = cont;
399 else 392 else
400 beforeChildParent = flow; 393 beforeChildParent = flow;
401 } 394 }
402 395
403 if (newChild->isFloatingOrOutOfFlowPositioned()) { 396 if (newChild->isFloatingOrOutOfFlowPositioned()) {
404 beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild); 397 beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
405 return; 398 return;
406 } 399 }
407 400
408 // A continuation always consists of two potential candidates: a block or an anonymous
409 // column span box holding column span children.
410 bool childIsNormal = newChild->isInline() || !newChild->style()->columnSpan( );
411 bool bcpIsNormal = beforeChildParent->isInline() || !beforeChildParent->styl e()->columnSpan();
412 bool flowIsNormal = flow->isInline() || !flow->style()->columnSpan();
413
414 if (flow == beforeChildParent) { 401 if (flow == beforeChildParent) {
415 flow->addChildIgnoringContinuation(newChild, beforeChild); 402 flow->addChildIgnoringContinuation(newChild, beforeChild);
416 return; 403 return;
417 } 404 }
418 405
419 // The goal here is to match up if we can, so that we can coalesce and creat e the
420 // minimal # of continuations needed for the inline.
421 if (childIsNormal == bcpIsNormal) {
422 beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
423 return;
424 }
425 if (flowIsNormal == childIsNormal) {
426 flow->addChildIgnoringContinuation(newChild, 0); // Just treat like an a ppend.
427 return;
428 }
429 beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild); 406 beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
430 } 407 }
431 408
432
433 void RenderBlock::addChildToAnonymousColumnBlocks(RenderObject* newChild, Render Object* beforeChild)
434 {
435 ASSERT(!continuation()); // We don't yet support column spans that aren't im mediate children of the multi-column block.
436
437 // The goal is to locate a suitable box in which to place our child.
438 RenderBlock* beforeChildParent = 0;
439 if (beforeChild) {
440 RenderObject* curr = beforeChild;
441 while (curr && curr->parent() != this)
442 curr = curr->parent();
443 beforeChildParent = toRenderBlock(curr);
444 ASSERT(beforeChildParent);
445 ASSERT(beforeChildParent->isAnonymousColumnsBlock() || beforeChildParent ->isAnonymousColumnSpanBlock());
446 } else
447 beforeChildParent = toRenderBlock(lastChild());
448
449 // If the new child is floating or positioned it can just go in that block.
450 if (newChild->isFloatingOrOutOfFlowPositioned()) {
451 beforeChildParent->addChildIgnoringAnonymousColumnBlocks(newChild, befor eChild);
452 return;
453 }
454
455 // See if the child can be placed in the box.
456 bool newChildHasColumnSpan = newChild->style()->columnSpan() && !newChild->i sInline();
457 bool beforeChildParentHoldsColumnSpans = beforeChildParent->isAnonymousColum nSpanBlock();
458
459 if (newChildHasColumnSpan == beforeChildParentHoldsColumnSpans) {
460 beforeChildParent->addChildIgnoringAnonymousColumnBlocks(newChild, befor eChild);
461 return;
462 }
463
464 if (!beforeChild) {
465 // Create a new block of the correct type.
466 RenderBlock* newBox = newChildHasColumnSpan ? createAnonymousColumnSpanB lock() : createAnonymousColumnsBlock();
467 children()->appendChildNode(this, newBox);
468 newBox->addChildIgnoringAnonymousColumnBlocks(newChild, 0);
469 return;
470 }
471
472 RenderObject* immediateChild = beforeChild;
473 bool isPreviousBlockViable = true;
474 while (immediateChild->parent() != this) {
475 if (isPreviousBlockViable)
476 isPreviousBlockViable = !immediateChild->previousSibling();
477 immediateChild = immediateChild->parent();
478 }
479 if (isPreviousBlockViable && immediateChild->previousSibling()) {
480 toRenderBlock(immediateChild->previousSibling())->addChildIgnoringAnonym ousColumnBlocks(newChild, 0); // Treat like an append.
481 return;
482 }
483
484 // Split our anonymous blocks.
485 RenderObject* newBeforeChild = splitAnonymousBoxesAroundChild(beforeChild);
486
487
488 // Create a new anonymous box of the appropriate type.
489 RenderBlock* newBox = newChildHasColumnSpan ? createAnonymousColumnSpanBlock () : createAnonymousColumnsBlock();
490 children()->insertChildNode(this, newBox, newBeforeChild);
491 newBox->addChildIgnoringAnonymousColumnBlocks(newChild, 0);
492 return;
493 }
494
495 RenderBlockFlow* RenderBlock::containingColumnsBlock(bool allowAnonymousColumnBl ock)
496 {
497 RenderBlock* firstChildIgnoringAnonymousWrappers = 0;
498 for (RenderObject* curr = this; curr; curr = curr->parent()) {
499 if (!curr->isRenderBlock() || curr->isFloatingOrOutOfFlowPositioned() || curr->isTableCell() || curr->isRoot() || curr->isRenderView() || curr->hasOverf lowClip()
500 || curr->isInlineBlockOrInlineTable())
501 return 0;
502
503 // FIXME: Renderers that do special management of their children (tables , buttons,
504 // lists, flexboxes, etc.) breaks when the flow is split through them. D isabling
505 // multi-column for them to avoid this problem.)
506 if (!curr->isRenderBlockFlow() || curr->isListItem())
507 return 0;
508
509 RenderBlockFlow* currBlock = toRenderBlockFlow(curr);
510 if (!currBlock->createsAnonymousWrapper())
511 firstChildIgnoringAnonymousWrappers = currBlock;
512
513 if (currBlock->style()->specifiesColumns() && (allowAnonymousColumnBlock || !currBlock->isAnonymousColumnsBlock()))
514 return toRenderBlockFlow(firstChildIgnoringAnonymousWrappers);
515
516 if (currBlock->isAnonymousColumnSpanBlock())
517 return 0;
518 }
519 return 0;
520 }
521
522 RenderBlock* RenderBlock::clone() const 409 RenderBlock* RenderBlock::clone() const
523 { 410 {
524 RenderBlock* cloneBlock; 411 RenderBlock* cloneBlock;
525 if (isAnonymousBlock()) { 412 if (isAnonymousBlock()) {
526 cloneBlock = createAnonymousBlock(); 413 cloneBlock = createAnonymousBlock();
527 cloneBlock->setChildrenInline(childrenInline()); 414 cloneBlock->setChildrenInline(childrenInline());
528 } 415 }
529 else { 416 else {
530 RenderObject* cloneRenderer = toElement(node())->createRenderer(style()) ; 417 RenderObject* cloneRenderer = toElement(node())->createRenderer(style()) ;
531 cloneBlock = toRenderBlock(cloneRenderer); 418 cloneBlock = toRenderBlock(cloneRenderer);
532 cloneBlock->setStyle(style()); 419 cloneBlock->setStyle(style());
533 420
534 // This takes care of setting the right value of childrenInline in case 421 // This takes care of setting the right value of childrenInline in case
535 // generated content is added to cloneBlock and 'this' does not have 422 // generated content is added to cloneBlock and 'this' does not have
536 // generated content added yet. 423 // generated content added yet.
537 cloneBlock->setChildrenInline(cloneBlock->firstChild() ? cloneBlock->fir stChild()->isInline() : childrenInline()); 424 cloneBlock->setChildrenInline(cloneBlock->firstChild() ? cloneBlock->fir stChild()->isInline() : childrenInline());
538 } 425 }
539 cloneBlock->setFlowThreadState(flowThreadState()); 426 cloneBlock->setFlowThreadState(flowThreadState());
540 return cloneBlock; 427 return cloneBlock;
541 } 428 }
542 429
543 void RenderBlock::splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock,
544 RenderBlock* middleBlock,
545 RenderObject* beforeChild, RenderBoxModelObject* o ldCont)
546 {
547 // Create a clone of this inline.
548 RenderBlock* cloneBlock = clone();
549 if (!isAnonymousBlock())
550 cloneBlock->setContinuation(oldCont);
551
552 if (!beforeChild && isAfterContent(lastChild()))
553 beforeChild = lastChild();
554
555 // If we are moving inline children from |this| to cloneBlock, then we need
556 // to clear our line box tree.
557 if (beforeChild && childrenInline())
558 deleteLineBoxTree();
559
560 // Now take all of the children from beforeChild to the end and remove
561 // them from |this| and place them in the clone.
562 moveChildrenTo(cloneBlock, beforeChild, 0, true);
563
564 // Hook |clone| up as the continuation of the middle block.
565 if (!cloneBlock->isAnonymousBlock())
566 middleBlock->setContinuation(cloneBlock);
567
568 // We have been reparented and are now under the fromBlock. We need
569 // to walk up our block parent chain until we hit the containing anonymous c olumns block.
570 // Once we hit the anonymous columns block we're done.
571 RenderBoxModelObject* curr = toRenderBoxModelObject(parent());
572 RenderBoxModelObject* currChild = this;
573 RenderObject* currChildNextSibling = currChild->nextSibling();
574
575 while (curr && curr->isDescendantOf(fromBlock) && curr != fromBlock) {
576 ASSERT_WITH_SECURITY_IMPLICATION(curr->isRenderBlock());
577
578 RenderBlock* blockCurr = toRenderBlock(curr);
579
580 // Create a new clone.
581 RenderBlock* cloneChild = cloneBlock;
582 cloneBlock = blockCurr->clone();
583
584 // Insert our child clone as the first child.
585 cloneBlock->addChildIgnoringContinuation(cloneChild, 0);
586
587 // Hook the clone up as a continuation of |curr|. Note we do encounter
588 // anonymous blocks possibly as we walk up the block chain. When we spl it an
589 // anonymous block, there's no need to do any continuation hookup, since we haven't
590 // actually split a real element.
591 if (!blockCurr->isAnonymousBlock()) {
592 oldCont = blockCurr->continuation();
593 blockCurr->setContinuation(cloneBlock);
594 cloneBlock->setContinuation(oldCont);
595 }
596
597 // Now we need to take all of the children starting from the first child
598 // *after* currChild and append them all to the clone.
599 blockCurr->moveChildrenTo(cloneBlock, currChildNextSibling, 0, true);
600
601 // Keep walking up the chain.
602 currChild = curr;
603 currChildNextSibling = currChild->nextSibling();
604 curr = toRenderBoxModelObject(curr->parent());
605 }
606
607 // Now we are at the columns block level. We need to put the clone into the toBlock.
608 toBlock->children()->appendChildNode(toBlock, cloneBlock);
609
610 // Now take all the children after currChild and remove them from the fromBl ock
611 // and put them in the toBlock.
612 fromBlock->moveChildrenTo(toBlock, currChildNextSibling, 0, true);
613 }
614
615 void RenderBlock::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox,
616 RenderObject* newChild, RenderBoxModelObject* oldCon t)
617 {
618 RenderBlock* pre = 0;
619 RenderBlock* block = containingColumnsBlock();
620
621 // Delete our line boxes before we do the inline split into continuations.
622 block->deleteLineBoxTree();
623
624 bool madeNewBeforeBlock = false;
625 if (block->isAnonymousColumnsBlock()) {
626 // We can reuse this block and make it the preBlock of the next continua tion.
627 pre = block;
628 pre->removePositionedObjects(0);
629 if (block->isRenderBlockFlow())
630 toRenderBlockFlow(pre)->removeFloatingObjects();
631 block = toRenderBlock(block->parent());
632 } else {
633 // No anonymous block available for use. Make one.
634 pre = block->createAnonymousColumnsBlock();
635 pre->setChildrenInline(false);
636 madeNewBeforeBlock = true;
637 }
638
639 RenderBlock* post = block->createAnonymousColumnsBlock();
640 post->setChildrenInline(false);
641
642 RenderObject* boxFirst = madeNewBeforeBlock ? block->firstChild() : pre->nex tSibling();
643 if (madeNewBeforeBlock)
644 block->children()->insertChildNode(block, pre, boxFirst);
645 block->children()->insertChildNode(block, newBlockBox, boxFirst);
646 block->children()->insertChildNode(block, post, boxFirst);
647 block->setChildrenInline(false);
648
649 if (madeNewBeforeBlock)
650 block->moveChildrenTo(pre, boxFirst, 0, true);
651
652 splitBlocks(pre, post, newBlockBox, beforeChild, oldCont);
653
654 // We already know the newBlockBox isn't going to contain inline kids, so av oid wasting
655 // time in makeChildrenNonInline by just setting this explicitly up front.
656 newBlockBox->setChildrenInline(false);
657
658 newBlockBox->addChild(newChild);
659
660 // Always just do a full layout in order to ensure that line boxes (especial ly wrappers for images)
661 // get deleted properly. Because objects moves from the pre block into the post block, we want to
662 // make new line boxes instead of leaving the old line boxes around.
663 pre->setNeedsLayoutAndPrefWidthsRecalc();
664 block->setNeedsLayoutAndPrefWidthsRecalc();
665 post->setNeedsLayoutAndPrefWidthsRecalc();
666 }
667
668 void RenderBlock::makeChildrenAnonymousColumnBlocks(RenderObject* beforeChild, R enderBlockFlow* newBlockBox, RenderObject* newChild)
669 {
670 RenderBlockFlow* pre = 0;
671 RenderBlockFlow* post = 0;
672 RenderBlock* block = this; // Eventually block will not just be |this|, but will also be a block nested inside |this|. Assign to a variable
673 // so that we don't have to patch all of the rest of the code later on.
674
675 // Delete the block's line boxes before we do the split.
676 block->deleteLineBoxTree();
677
678 if (beforeChild && beforeChild->parent() != this)
679 beforeChild = splitAnonymousBoxesAroundChild(beforeChild);
680
681 if (beforeChild != firstChild()) {
682 pre = block->createAnonymousColumnsBlock();
683 pre->setChildrenInline(block->childrenInline());
684 }
685
686 if (beforeChild) {
687 post = block->createAnonymousColumnsBlock();
688 post->setChildrenInline(block->childrenInline());
689 }
690
691 RenderObject* boxFirst = block->firstChild();
692 if (pre)
693 block->children()->insertChildNode(block, pre, boxFirst);
694 block->children()->insertChildNode(block, newBlockBox, boxFirst);
695 if (post)
696 block->children()->insertChildNode(block, post, boxFirst);
697 block->setChildrenInline(false);
698
699 // The pre/post blocks always have layers, so we know to always do a full in sert/remove (so we pass true as the last argument).
700 block->moveChildrenTo(pre, boxFirst, beforeChild, true);
701 block->moveChildrenTo(post, beforeChild, 0, true);
702
703 // We already know the newBlockBox isn't going to contain inline kids, so av oid wasting
704 // time in makeChildrenNonInline by just setting this explicitly up front.
705 newBlockBox->setChildrenInline(false);
706
707 newBlockBox->addChild(newChild);
708
709 // Always just do a full layout in order to ensure that line boxes (especial ly wrappers for images)
710 // get deleted properly. Because objects moved from the pre block into the post block, we want to
711 // make new line boxes instead of leaving the old line boxes around.
712 if (pre)
713 pre->setNeedsLayoutAndPrefWidthsRecalc();
714 block->setNeedsLayoutAndPrefWidthsRecalc();
715 if (post)
716 post->setNeedsLayoutAndPrefWidthsRecalc();
717 }
718
719 RenderBlockFlow* RenderBlock::columnsBlockForSpanningElement(RenderObject* newCh ild)
720 {
721 // FIXME: This function is the gateway for the addition of column-span suppo rt. It will
722 // be added to in three stages:
723 // (1) Immediate children of a multi-column block can span.
724 // (2) Nested block-level children with only block-level ancestors between t hem and the multi-column block can span.
725 // (3) Nested children with block or inline ancestors between them and the m ulti-column block can span (this is when we
726 // cross the streams and have to cope with both types of continuations mixed together).
727 // This function currently supports (1) and (2).
728 RenderBlockFlow* columnsBlockAncestor = 0;
729 if (!newChild->isText() && newChild->style()->columnSpan() && !newChild->isB eforeOrAfterContent()
730 && !newChild->isFloatingOrOutOfFlowPositioned() && !newChild->isInline() && !isAnonymousColumnSpanBlock()) {
731 columnsBlockAncestor = containingColumnsBlock(false);
732 if (columnsBlockAncestor) {
733 // Make sure that none of the parent ancestors have a continuation.
734 // If yes, we do not want split the block into continuations.
735 RenderObject* curr = this;
736 while (curr && curr != columnsBlockAncestor) {
737 if (curr->isRenderBlock() && toRenderBlock(curr)->continuation() ) {
738 columnsBlockAncestor = 0;
739 break;
740 }
741 curr = curr->parent();
742 }
743 }
744 }
745 return columnsBlockAncestor;
746 }
747
748 void RenderBlock::addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild) 430 void RenderBlock::addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild)
749 { 431 {
750 if (beforeChild && beforeChild->parent() != this) { 432 if (beforeChild && beforeChild->parent() != this) {
751 RenderObject* beforeChildContainer = beforeChild->parent(); 433 RenderObject* beforeChildContainer = beforeChild->parent();
752 while (beforeChildContainer->parent() != this) 434 while (beforeChildContainer->parent() != this)
753 beforeChildContainer = beforeChildContainer->parent(); 435 beforeChildContainer = beforeChildContainer->parent();
754 ASSERT(beforeChildContainer); 436 ASSERT(beforeChildContainer);
755 437
756 if (beforeChildContainer->isAnonymous()) { 438 if (beforeChildContainer->isAnonymous()) {
757 // If the requested beforeChild is not one of our children, then thi s is because 439 // If the requested beforeChild is not one of our children, then thi s is because
(...skipping 23 matching lines...) Expand all
781 463
782 ASSERT(beforeChild->parent() == this); 464 ASSERT(beforeChild->parent() == this);
783 if (beforeChild->parent() != this) { 465 if (beforeChild->parent() != this) {
784 // We should never reach here. If we do, we need to use the 466 // We should never reach here. If we do, we need to use the
785 // safe fallback to use the topmost beforeChild container. 467 // safe fallback to use the topmost beforeChild container.
786 beforeChild = beforeChildContainer; 468 beforeChild = beforeChildContainer;
787 } 469 }
788 } 470 }
789 } 471 }
790 472
791 // Check for a spanning element in columns.
792 if (gColumnFlowSplitEnabled) {
793 RenderBlockFlow* columnsBlockAncestor = columnsBlockForSpanningElement(n ewChild);
794 if (columnsBlockAncestor) {
795 TemporaryChange<bool> columnFlowSplitEnabled(gColumnFlowSplitEnabled , false);
796 // We are placing a column-span element inside a block.
797 RenderBlockFlow* newBox = createAnonymousColumnSpanBlock();
798
799 if (columnsBlockAncestor != this && !isRenderFlowThread()) {
800 // We are nested inside a multi-column element and are being spl it by the span. We have to break up
801 // our block into continuations.
802 RenderBoxModelObject* oldContinuation = continuation();
803
804 // When we split an anonymous block, there's no need to do any c ontinuation hookup,
805 // since we haven't actually split a real element.
806 if (!isAnonymousBlock())
807 setContinuation(newBox);
808
809 splitFlow(beforeChild, newBox, newChild, oldContinuation);
810 return;
811 }
812
813 // We have to perform a split of this block's children. This involve s creating an anonymous block box to hold
814 // the column-spanning |newChild|. We take all of the children from before |newChild| and put them into
815 // one anonymous columns block, and all of the children after |newCh ild| go into another anonymous block.
816 makeChildrenAnonymousColumnBlocks(beforeChild, newBox, newChild);
817 return;
818 }
819 }
820
821 bool madeBoxesNonInline = false; 473 bool madeBoxesNonInline = false;
822 474
823 // A block has to either have all of its children inline, or all of its chil dren as blocks. 475 // A block has to either have all of its children inline, or all of its chil dren as blocks.
824 // So, if our children are currently inline and a block child has to be inse rted, we move all our 476 // So, if our children are currently inline and a block child has to be inse rted, we move all our
825 // inline children into anonymous block boxes. 477 // inline children into anonymous block boxes.
826 if (childrenInline() && !newChild->isInline() && !newChild->isFloatingOrOutO fFlowPositioned()) { 478 if (childrenInline() && !newChild->isInline() && !newChild->isFloatingOrOutO fFlowPositioned()) {
827 // This is a block with inline content. Wrap the inline content in anony mous blocks. 479 // This is a block with inline content. Wrap the inline content in anony mous blocks.
828 makeChildrenNonInline(beforeChild); 480 makeChildrenNonInline(beforeChild);
829 madeBoxesNonInline = true; 481 madeBoxesNonInline = true;
830 482
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
863 void RenderBlock::addChild(RenderObject* newChild, RenderObject* beforeChild) 515 void RenderBlock::addChild(RenderObject* newChild, RenderObject* beforeChild)
864 { 516 {
865 if (continuation() && !isAnonymousBlock()) 517 if (continuation() && !isAnonymousBlock())
866 addChildToContinuation(newChild, beforeChild); 518 addChildToContinuation(newChild, beforeChild);
867 else 519 else
868 addChildIgnoringContinuation(newChild, beforeChild); 520 addChildIgnoringContinuation(newChild, beforeChild);
869 } 521 }
870 522
871 void RenderBlock::addChildIgnoringContinuation(RenderObject* newChild, RenderObj ect* beforeChild) 523 void RenderBlock::addChildIgnoringContinuation(RenderObject* newChild, RenderObj ect* beforeChild)
872 { 524 {
873 if (!isAnonymousBlock() && firstChild() && (firstChild()->isAnonymousColumns Block() || firstChild()->isAnonymousColumnSpanBlock())) 525 addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
874 addChildToAnonymousColumnBlocks(newChild, beforeChild);
875 else
876 addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
877 } 526 }
878 527
879 static void getInlineRun(RenderObject* start, RenderObject* boundary, 528 static void getInlineRun(RenderObject* start, RenderObject* boundary,
880 RenderObject*& inlineRunStart, 529 RenderObject*& inlineRunStart,
881 RenderObject*& inlineRunEnd) 530 RenderObject*& inlineRunEnd)
882 { 531 {
883 // Beginning at |start| we find the largest contiguous run of inlines that 532 // Beginning at |start| we find the largest contiguous run of inlines that
884 // we can. We denote the run with start and end points, |inlineRunStart| 533 // we can. We denote the run with start and end points, |inlineRunStart|
885 // and |inlineRunEnd|. Note that these two values may be the same if 534 // and |inlineRunEnd|. Note that these two values may be the same if
886 // we encounter only one inline. 535 // we encounter only one inline.
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
964 #endif 613 #endif
965 614
966 repaint(); 615 repaint();
967 } 616 }
968 617
969 void RenderBlock::removeLeftoverAnonymousBlock(RenderBlock* child) 618 void RenderBlock::removeLeftoverAnonymousBlock(RenderBlock* child)
970 { 619 {
971 ASSERT(child->isAnonymousBlock()); 620 ASSERT(child->isAnonymousBlock());
972 ASSERT(!child->childrenInline()); 621 ASSERT(!child->childrenInline());
973 622
974 if (child->continuation() || (child->firstChild() && (child->isAnonymousColu mnSpanBlock() || child->isAnonymousColumnsBlock()))) 623 if (child->continuation())
975 return; 624 return;
976 625
977 RenderObject* firstAnChild = child->m_children.firstChild(); 626 RenderObject* firstAnChild = child->m_children.firstChild();
978 RenderObject* lastAnChild = child->m_children.lastChild(); 627 RenderObject* lastAnChild = child->m_children.lastChild();
979 if (firstAnChild) { 628 if (firstAnChild) {
980 RenderObject* o = firstAnChild; 629 RenderObject* o = firstAnChild;
981 while (o) { 630 while (o) {
982 o->setParent(this); 631 o->setParent(this);
983 o = o->nextSibling(); 632 o = o->nextSibling();
984 } 633 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1024 return false; 673 return false;
1025 674
1026 if ((prev && (!prev->isAnonymousBlock() || toRenderBlock(prev)->continuation () || toRenderBlock(prev)->beingDestroyed())) 675 if ((prev && (!prev->isAnonymousBlock() || toRenderBlock(prev)->continuation () || toRenderBlock(prev)->beingDestroyed()))
1027 || (next && (!next->isAnonymousBlock() || toRenderBlock(next)->continuat ion() || toRenderBlock(next)->beingDestroyed()))) 676 || (next && (!next->isAnonymousBlock() || toRenderBlock(next)->continuat ion() || toRenderBlock(next)->beingDestroyed())))
1028 return false; 677 return false;
1029 678
1030 if ((prev && (prev->isRubyRun() || prev->isRubyBase())) 679 if ((prev && (prev->isRubyRun() || prev->isRubyBase()))
1031 || (next && (next->isRubyRun() || next->isRubyBase()))) 680 || (next && (next->isRubyRun() || next->isRubyBase())))
1032 return false; 681 return false;
1033 682
1034 if (!prev || !next) 683 return true;
1035 return true;
1036
1037 // Make sure the types of the anonymous blocks match up.
1038 return prev->isAnonymousColumnsBlock() == next->isAnonymousColumnsBlock()
1039 && prev->isAnonymousColumnSpanBlock() == next->isAnonymousColumnSpanB lock();
1040 } 684 }
1041 685
1042 void RenderBlock::collapseAnonymousBlockChild(RenderBlock* parent, RenderBlock* child) 686 void RenderBlock::collapseAnonymousBlockChild(RenderBlock* parent, RenderBlock* child)
1043 { 687 {
1044 // It's possible that this block's destruction may have been triggered by th e 688 // It's possible that this block's destruction may have been triggered by th e
1045 // child's removal. Just bail if the anonymous child block is already being 689 // child's removal. Just bail if the anonymous child block is already being
1046 // destroyed. See crbug.com/282088 690 // destroyed. See crbug.com/282088
1047 if (child->beingDestroyed()) 691 if (child->beingDestroyed())
1048 return; 692 return;
1049 parent->setNeedsLayoutAndPrefWidthsRecalc(); 693 parent->setNeedsLayoutAndPrefWidthsRecalc();
(...skipping 15 matching lines...) Expand all
1065 709
1066 void RenderBlock::removeChild(RenderObject* oldChild) 710 void RenderBlock::removeChild(RenderObject* oldChild)
1067 { 711 {
1068 // No need to waste time in merging or removing empty anonymous blocks. 712 // No need to waste time in merging or removing empty anonymous blocks.
1069 // We can just bail out if our document is getting destroyed. 713 // We can just bail out if our document is getting destroyed.
1070 if (documentBeingDestroyed()) { 714 if (documentBeingDestroyed()) {
1071 RenderBox::removeChild(oldChild); 715 RenderBox::removeChild(oldChild);
1072 return; 716 return;
1073 } 717 }
1074 718
1075 // This protects against column split flows when anonymous blocks are gettin g merged.
1076 TemporaryChange<bool> columnFlowSplitEnabled(gColumnFlowSplitEnabled, false) ;
1077
1078 // If this child is a block, and if our previous and next siblings are 719 // If this child is a block, and if our previous and next siblings are
1079 // both anonymous blocks with inline content, then we can go ahead and 720 // both anonymous blocks with inline content, then we can go ahead and
1080 // fold the inline content back together. 721 // fold the inline content back together.
1081 RenderObject* prev = oldChild->previousSibling(); 722 RenderObject* prev = oldChild->previousSibling();
1082 RenderObject* next = oldChild->nextSibling(); 723 RenderObject* next = oldChild->nextSibling();
1083 bool canMergeAnonymousBlocks = canMergeContiguousAnonymousBlocks(oldChild, p rev, next); 724 bool canMergeAnonymousBlocks = canMergeContiguousAnonymousBlocks(oldChild, p rev, next);
1084 if (canMergeAnonymousBlocks && prev && next) { 725 if (canMergeAnonymousBlocks && prev && next) {
1085 prev->setNeedsLayoutAndPrefWidthsRecalc(); 726 prev->setNeedsLayoutAndPrefWidthsRecalc();
1086 RenderBlockFlow* nextBlock = toRenderBlockFlow(next); 727 RenderBlockFlow* nextBlock = toRenderBlockFlow(next);
1087 RenderBlockFlow* prevBlock = toRenderBlockFlow(prev); 728 RenderBlockFlow* prevBlock = toRenderBlockFlow(prev);
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after
1483 1124
1484 void RenderBlock::computeRegionRangeForBlock(RenderFlowThread* flowThread) 1125 void RenderBlock::computeRegionRangeForBlock(RenderFlowThread* flowThread)
1485 { 1126 {
1486 if (flowThread) 1127 if (flowThread)
1487 flowThread->setRegionRangeForBox(this, offsetFromLogicalTopOfFirstPage() ); 1128 flowThread->setRegionRangeForBox(this, offsetFromLogicalTopOfFirstPage() );
1488 } 1129 }
1489 1130
1490 bool RenderBlock::updateLogicalWidthAndColumnWidth() 1131 bool RenderBlock::updateLogicalWidthAndColumnWidth()
1491 { 1132 {
1492 LayoutUnit oldWidth = logicalWidth(); 1133 LayoutUnit oldWidth = logicalWidth();
1493 LayoutUnit oldColumnWidth = desiredColumnWidth();
1494 1134
1495 updateLogicalWidth(); 1135 updateLogicalWidth();
1496 calcColumnWidth();
1497 1136
1498 bool hasBorderOrPaddingLogicalWidthChanged = m_hasBorderOrPaddingLogicalWidt hChanged; 1137 bool hasBorderOrPaddingLogicalWidthChanged = m_hasBorderOrPaddingLogicalWidt hChanged;
1499 m_hasBorderOrPaddingLogicalWidthChanged = false; 1138 m_hasBorderOrPaddingLogicalWidthChanged = false;
1500 1139
1501 return oldWidth != logicalWidth() || oldColumnWidth != desiredColumnWidth() || hasBorderOrPaddingLogicalWidthChanged; 1140 return oldWidth != logicalWidth() || hasBorderOrPaddingLogicalWidthChanged;
1502 } 1141 }
1503 1142
1504 void RenderBlock::checkForPaginationLogicalHeightChange(LayoutUnit& pageLogicalH eight, bool& pageLogicalHeightChanged, bool& hasSpecifiedPageLogicalHeight) 1143 void RenderBlock::checkForPaginationLogicalHeightChange(LayoutUnit& pageLogicalH eight, bool& pageLogicalHeightChanged, bool& hasSpecifiedPageLogicalHeight)
1505 { 1144 {
1506 ColumnInfo* colInfo = columnInfo(); 1145 if (isRenderFlowThread()) {
1507 if (hasColumns()) {
1508 if (!pageLogicalHeight) {
1509 LayoutUnit oldLogicalHeight = logicalHeight();
1510 setLogicalHeight(0);
1511 // We need to go ahead and set our explicit page height if one exist s, so that we can
1512 // avoid doing two layout passes.
1513 updateLogicalHeight();
1514 LayoutUnit columnHeight = contentLogicalHeight();
1515 if (columnHeight > 0) {
1516 pageLogicalHeight = columnHeight;
1517 hasSpecifiedPageLogicalHeight = true;
1518 }
1519 setLogicalHeight(oldLogicalHeight);
1520 }
1521 if (colInfo->columnHeight() != pageLogicalHeight && everHadLayout()) {
1522 colInfo->setColumnHeight(pageLogicalHeight);
1523 pageLogicalHeightChanged = true;
1524 }
1525
1526 if (!hasSpecifiedPageLogicalHeight && !pageLogicalHeight)
1527 colInfo->clearForcedBreaks();
1528
1529 colInfo->setPaginationUnit(paginationUnit());
1530 } else if (isRenderFlowThread()) {
1531 pageLogicalHeight = 1; // This is just a hack to always make sure we hav e a page logical height. 1146 pageLogicalHeight = 1; // This is just a hack to always make sure we hav e a page logical height.
1532 pageLogicalHeightChanged = toRenderFlowThread(this)->pageLogicalSizeChan ged(); 1147 pageLogicalHeightChanged = toRenderFlowThread(this)->pageLogicalSizeChan ged();
1533 } 1148 }
1534 } 1149 }
1535 1150
1536 void RenderBlock::layoutBlock(bool) 1151 void RenderBlock::layoutBlock(bool)
1537 { 1152 {
1538 ASSERT_NOT_REACHED(); 1153 ASSERT_NOT_REACHED();
1539 clearNeedsLayout(); 1154 clearNeedsLayout();
1540 } 1155 }
1541 1156
1542 void RenderBlock::addOverflowFromChildren() 1157 void RenderBlock::addOverflowFromChildren()
1543 { 1158 {
1544 if (!hasColumns()) { 1159 if (childrenInline())
1545 if (childrenInline()) 1160 toRenderBlockFlow(this)->addOverflowFromInlineChildren();
1546 toRenderBlockFlow(this)->addOverflowFromInlineChildren(); 1161 else
1547 else 1162 addOverflowFromBlockChildren();
1548 addOverflowFromBlockChildren();
1549 } else {
1550 ColumnInfo* colInfo = columnInfo();
1551 if (columnCount(colInfo)) {
1552 LayoutRect lastRect = columnRectAt(colInfo, columnCount(colInfo) - 1 );
1553 addLayoutOverflow(lastRect);
1554 addContentsVisualOverflow(lastRect);
1555 }
1556 }
1557 } 1163 }
1558 1164
1559 void RenderBlock::computeOverflow(LayoutUnit oldClientAfterEdge, bool) 1165 void RenderBlock::computeOverflow(LayoutUnit oldClientAfterEdge, bool)
1560 { 1166 {
1561 m_overflow.clear(); 1167 m_overflow.clear();
1562 1168
1563 // Add overflow from children. 1169 // Add overflow from children.
1564 addOverflowFromChildren(); 1170 addOverflowFromChildren();
1565 1171
1566 // Add in the overflow from positioned objects. 1172 // Add in the overflow from positioned objects.
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1622 return; 1228 return;
1623 1229
1624 IntRect inflatedRect = pixelSnappedBorderBoxRect(); 1230 IntRect inflatedRect = pixelSnappedBorderBoxRect();
1625 RenderTheme::theme().adjustRepaintRect(this, inflatedRect); 1231 RenderTheme::theme().adjustRepaintRect(this, inflatedRect);
1626 addVisualOverflow(inflatedRect); 1232 addVisualOverflow(inflatedRect);
1627 } 1233 }
1628 1234
1629 bool RenderBlock::expandsToEncloseOverhangingFloats() const 1235 bool RenderBlock::expandsToEncloseOverhangingFloats() const
1630 { 1236 {
1631 return isInlineBlockOrInlineTable() || isFloatingOrOutOfFlowPositioned() || hasOverflowClip() || (parent() && parent()->isFlexibleBoxIncludingDeprecated()) 1237 return isInlineBlockOrInlineTable() || isFloatingOrOutOfFlowPositioned() || hasOverflowClip() || (parent() && parent()->isFlexibleBoxIncludingDeprecated())
1632 || hasColumns() || isTableCell() || isTableCaption() || isFieldset() || isWritingModeRoot() || isRoot(); 1238 || isTableCell() || isTableCaption() || isFieldset() || isWritingModeRoo t() || isRoot();
1633 } 1239 }
1634 1240
1635 void RenderBlock::determineLogicalLeftPositionForChild(RenderBox* child, ApplyLa youtDeltaMode applyDelta) 1241 void RenderBlock::determineLogicalLeftPositionForChild(RenderBox* child, ApplyLa youtDeltaMode applyDelta)
1636 { 1242 {
1637 LayoutUnit startPosition = borderStart() + paddingStart(); 1243 LayoutUnit startPosition = borderStart() + paddingStart();
1638 if (style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) 1244 if (style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
1639 startPosition -= verticalScrollbarWidth(); 1245 startPosition -= verticalScrollbarWidth();
1640 LayoutUnit totalAvailableLogicalWidth = borderAndPaddingLogicalWidth() + ava ilableLogicalWidth(); 1246 LayoutUnit totalAvailableLogicalWidth = borderAndPaddingLogicalWidth() + ava ilableLogicalWidth();
1641 1247
1642 // Add in our start margin. 1248 // Add in our start margin.
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1718 box->layoutIfNeeded(); 1324 box->layoutIfNeeded();
1719 } 1325 }
1720 } 1326 }
1721 } 1327 }
1722 1328
1723 bool RenderBlock::simplifiedLayout() 1329 bool RenderBlock::simplifiedLayout()
1724 { 1330 {
1725 if ((!posChildNeedsLayout() && !needsSimplifiedNormalFlowLayout()) || normal ChildNeedsLayout() || selfNeedsLayout()) 1331 if ((!posChildNeedsLayout() && !needsSimplifiedNormalFlowLayout()) || normal ChildNeedsLayout() || selfNeedsLayout())
1726 return false; 1332 return false;
1727 1333
1728 LayoutStateMaintainer statePusher(view(), this, locationOffset(), hasColumns () || hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode() ); 1334 LayoutStateMaintainer statePusher(view(), this, locationOffset(), hasTransfo rm() || hasReflection() || style()->isFlippedBlocksWritingMode());
1729 1335
1730 if (needsPositionedMovementLayout() && !tryLayoutDoingPositionedMovementOnly ()) 1336 if (needsPositionedMovementLayout() && !tryLayoutDoingPositionedMovementOnly ())
1731 return false; 1337 return false;
1732 1338
1733 // Lay out positioned descendants or objects that just need to recompute ove rflow. 1339 // Lay out positioned descendants or objects that just need to recompute ove rflow.
1734 if (needsSimplifiedNormalFlowLayout()) 1340 if (needsSimplifiedNormalFlowLayout())
1735 simplifiedNormalFlowLayout(); 1341 simplifiedNormalFlowLayout();
1736 1342
1737 // Make sure a forced break is applied after the content if we are a flow th read in a simplified layout. 1343 // Make sure a forced break is applied after the content if we are a flow th read in a simplified layout.
1738 // This ensures the size information is correctly computed for the last auto -height region receiving content. 1344 // This ensures the size information is correctly computed for the last auto -height region receiving content.
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1812 margin += marginRight.value(); 1418 margin += marginRight.value();
1813 return margin; 1419 return margin;
1814 } 1420 }
1815 1421
1816 void RenderBlock::layoutPositionedObjects(bool relayoutChildren, bool fixedPosit ionObjectsOnly) 1422 void RenderBlock::layoutPositionedObjects(bool relayoutChildren, bool fixedPosit ionObjectsOnly)
1817 { 1423 {
1818 TrackedRendererListHashSet* positionedDescendants = positionedObjects(); 1424 TrackedRendererListHashSet* positionedDescendants = positionedObjects();
1819 if (!positionedDescendants) 1425 if (!positionedDescendants)
1820 return; 1426 return;
1821 1427
1822 if (hasColumns())
1823 view()->layoutState()->clearPaginationInformation(); // Positioned objec ts are not part of the column flow, so they don't paginate with the columns.
1824
1825 RenderBox* r; 1428 RenderBox* r;
1826 TrackedRendererListHashSet::iterator end = positionedDescendants->end(); 1429 TrackedRendererListHashSet::iterator end = positionedDescendants->end();
1827 for (TrackedRendererListHashSet::iterator it = positionedDescendants->begin( ); it != end; ++it) { 1430 for (TrackedRendererListHashSet::iterator it = positionedDescendants->begin( ); it != end; ++it) {
1828 r = *it; 1431 r = *it;
1829 1432
1830 SubtreeLayoutScope layoutScope(r); 1433 SubtreeLayoutScope layoutScope(r);
1831 // A fixed position element with an absolute positioned ancestor has no way of knowing if the latter has changed position. So 1434 // A fixed position element with an absolute positioned ancestor has no way of knowing if the latter has changed position. So
1832 // if this is a fixed position element, mark it for layout if it has an abspos ancestor and needs to move with that ancestor, i.e. 1435 // if this is a fixed position element, mark it for layout if it has an abspos ancestor and needs to move with that ancestor, i.e.
1833 // it has static position. 1436 // it has static position.
1834 markFixedPositionObjectForLayoutIfNeeded(r, layoutScope); 1437 markFixedPositionObjectForLayoutIfNeeded(r, layoutScope);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1867 r->updateLogicalWidth(); 1470 r->updateLogicalWidth();
1868 oldLogicalTop = logicalTopForChild(r); 1471 oldLogicalTop = logicalTopForChild(r);
1869 } 1472 }
1870 1473
1871 r->layoutIfNeeded(); 1474 r->layoutIfNeeded();
1872 1475
1873 // Lay out again if our estimate was wrong. 1476 // Lay out again if our estimate was wrong.
1874 if (needsBlockDirectionLocationSetBeforeLayout && logicalTopForChild(r) != oldLogicalTop) 1477 if (needsBlockDirectionLocationSetBeforeLayout && logicalTopForChild(r) != oldLogicalTop)
1875 r->forceChildLayout(); 1478 r->forceChildLayout();
1876 } 1479 }
1877
1878 if (hasColumns())
1879 view()->layoutState()->m_columnInfo = columnInfo(); // FIXME: Kind of gr oss. We just put this back into the layout state so that pop() will work.
1880 } 1480 }
1881 1481
1882 void RenderBlock::markPositionedObjectsForLayout() 1482 void RenderBlock::markPositionedObjectsForLayout()
1883 { 1483 {
1884 TrackedRendererListHashSet* positionedDescendants = positionedObjects(); 1484 TrackedRendererListHashSet* positionedDescendants = positionedObjects();
1885 if (positionedDescendants) { 1485 if (positionedDescendants) {
1886 RenderBox* r; 1486 RenderBox* r;
1887 TrackedRendererListHashSet::iterator end = positionedDescendants->end(); 1487 TrackedRendererListHashSet::iterator end = positionedDescendants->end();
1888 for (TrackedRendererListHashSet::iterator it = positionedDescendants->be gin(); it != end; ++it) { 1488 for (TrackedRendererListHashSet::iterator it = positionedDescendants->be gin(); it != end; ++it) {
1889 r = *it; 1489 r = *it;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1933 if (pushedClip) 1533 if (pushedClip)
1934 popContentsClip(paintInfo, phase, adjustedPaintOffset); 1534 popContentsClip(paintInfo, phase, adjustedPaintOffset);
1935 1535
1936 // Our scrollbar widgets paint exactly when we tell them to, so that they wo rk properly with 1536 // Our scrollbar widgets paint exactly when we tell them to, so that they wo rk properly with
1937 // z-index. We paint after we painted the background/border, so that the sc rollbars will 1537 // z-index. We paint after we painted the background/border, so that the sc rollbars will
1938 // sit above the background/border. 1538 // sit above the background/border.
1939 if (hasOverflowClip() && style()->visibility() == VISIBLE && (phase == Paint PhaseBlockBackground || phase == PaintPhaseChildBlockBackground) && paintInfo.sh ouldPaintWithinRoot(this) && !paintInfo.paintRootBackgroundOnly()) 1539 if (hasOverflowClip() && style()->visibility() == VISIBLE && (phase == Paint PhaseBlockBackground || phase == PaintPhaseChildBlockBackground) && paintInfo.sh ouldPaintWithinRoot(this) && !paintInfo.paintRootBackgroundOnly())
1940 layer()->scrollableArea()->paintOverflowControls(paintInfo.context, roun dedIntPoint(adjustedPaintOffset), paintInfo.rect, false /* paintingOverlayContro ls */); 1540 layer()->scrollableArea()->paintOverflowControls(paintInfo.context, roun dedIntPoint(adjustedPaintOffset), paintInfo.rect, false /* paintingOverlayContro ls */);
1941 } 1541 }
1942 1542
1943 void RenderBlock::paintColumnRules(PaintInfo& paintInfo, const LayoutPoint& pain tOffset)
1944 {
1945 if (paintInfo.context->paintingDisabled())
1946 return;
1947
1948 const Color& ruleColor = resolveColor(CSSPropertyWebkitColumnRuleColor);
1949 bool ruleTransparent = style()->columnRuleIsTransparent();
1950 EBorderStyle ruleStyle = style()->columnRuleStyle();
1951 LayoutUnit ruleThickness = style()->columnRuleWidth();
1952 LayoutUnit colGap = columnGap();
1953 bool renderRule = ruleStyle > BHIDDEN && !ruleTransparent;
1954 if (!renderRule)
1955 return;
1956
1957 ColumnInfo* colInfo = columnInfo();
1958 unsigned colCount = columnCount(colInfo);
1959
1960 bool antialias = shouldAntialiasLines(paintInfo.context);
1961
1962 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) {
1963 bool leftToRight = style()->isLeftToRightDirection() ^ colInfo->progress ionIsReversed();
1964 LayoutUnit currLogicalLeftOffset = leftToRight ? LayoutUnit() : contentL ogicalWidth();
1965 LayoutUnit ruleAdd = logicalLeftOffsetForContent();
1966 LayoutUnit ruleLogicalLeft = leftToRight ? LayoutUnit() : contentLogical Width();
1967 LayoutUnit inlineDirectionSize = colInfo->desiredColumnWidth();
1968 BoxSide boxSide = isHorizontalWritingMode()
1969 ? leftToRight ? BSLeft : BSRight
1970 : leftToRight ? BSTop : BSBottom;
1971
1972 for (unsigned i = 0; i < colCount; i++) {
1973 // Move to the next position.
1974 if (leftToRight) {
1975 ruleLogicalLeft += inlineDirectionSize + colGap / 2;
1976 currLogicalLeftOffset += inlineDirectionSize + colGap;
1977 } else {
1978 ruleLogicalLeft -= (inlineDirectionSize + colGap / 2);
1979 currLogicalLeftOffset -= (inlineDirectionSize + colGap);
1980 }
1981
1982 // Now paint the column rule.
1983 if (i < colCount - 1) {
1984 LayoutUnit ruleLeft = isHorizontalWritingMode() ? paintOffset.x( ) + ruleLogicalLeft - ruleThickness / 2 + ruleAdd : paintOffset.x() + borderLeft () + paddingLeft();
1985 LayoutUnit ruleRight = isHorizontalWritingMode() ? ruleLeft + ru leThickness : ruleLeft + contentWidth();
1986 LayoutUnit ruleTop = isHorizontalWritingMode() ? paintOffset.y() + borderTop() + paddingTop() : paintOffset.y() + ruleLogicalLeft - ruleThicknes s / 2 + ruleAdd;
1987 LayoutUnit ruleBottom = isHorizontalWritingMode() ? ruleTop + co ntentHeight() : ruleTop + ruleThickness;
1988 IntRect pixelSnappedRuleRect = pixelSnappedIntRectFromEdges(rule Left, ruleTop, ruleRight, ruleBottom);
1989 drawLineForBoxSide(paintInfo.context, pixelSnappedRuleRect.x(), pixelSnappedRuleRect.y(), pixelSnappedRuleRect.maxX(), pixelSnappedRuleRect.maxY (), boxSide, ruleColor, ruleStyle, 0, 0, antialias);
1990 }
1991
1992 ruleLogicalLeft = currLogicalLeftOffset;
1993 }
1994 } else {
1995 bool topToBottom = !style()->isFlippedBlocksWritingMode() ^ colInfo->pro gressionIsReversed();
1996 LayoutUnit ruleLeft = isHorizontalWritingMode()
1997 ? borderLeft() + paddingLeft()
1998 : colGap / 2 - colGap - ruleThickness / 2 + (!colInfo->progressionIs Reversed() ? borderBefore() + paddingBefore() : borderAfter() + paddingAfter());
1999 LayoutUnit ruleWidth = isHorizontalWritingMode() ? contentWidth() : rule Thickness;
2000 LayoutUnit ruleTop = isHorizontalWritingMode()
2001 ? colGap / 2 - colGap - ruleThickness / 2 + (!colInfo->progressionIs Reversed() ? borderBefore() + paddingBefore() : borderAfter() + paddingAfter())
2002 : borderStart() + paddingStart();
2003 LayoutUnit ruleHeight = isHorizontalWritingMode() ? ruleThickness : cont entHeight();
2004 LayoutRect ruleRect(ruleLeft, ruleTop, ruleWidth, ruleHeight);
2005
2006 if (!topToBottom) {
2007 if (isHorizontalWritingMode())
2008 ruleRect.setY(height() - ruleRect.maxY());
2009 else
2010 ruleRect.setX(width() - ruleRect.maxX());
2011 }
2012
2013 ruleRect.moveBy(paintOffset);
2014
2015 BoxSide boxSide = isHorizontalWritingMode()
2016 ? topToBottom ? BSTop : BSBottom
2017 : topToBottom ? BSLeft : BSRight;
2018
2019 LayoutSize step(0, topToBottom ? colInfo->columnHeight() + colGap : -(co lInfo->columnHeight() + colGap));
2020 if (!isHorizontalWritingMode())
2021 step = step.transposedSize();
2022
2023 for (unsigned i = 1; i < colCount; i++) {
2024 ruleRect.move(step);
2025 IntRect pixelSnappedRuleRect = pixelSnappedIntRect(ruleRect);
2026 drawLineForBoxSide(paintInfo.context, pixelSnappedRuleRect.x(), pixe lSnappedRuleRect.y(), pixelSnappedRuleRect.maxX(), pixelSnappedRuleRect.maxY(), boxSide, ruleColor, ruleStyle, 0, 0, antialias);
2027 }
2028 }
2029 }
2030
2031 void RenderBlock::paintColumnContents(PaintInfo& paintInfo, const LayoutPoint& p aintOffset, bool paintingFloats)
2032 {
2033 // We need to do multiple passes, breaking up our child painting into strips .
2034 GraphicsContext* context = paintInfo.context;
2035 ColumnInfo* colInfo = columnInfo();
2036 unsigned colCount = columnCount(colInfo);
2037 if (!colCount)
2038 return;
2039 LayoutUnit currLogicalTopOffset = 0;
2040 LayoutUnit colGap = columnGap();
2041 for (unsigned i = 0; i < colCount; i++) {
2042 // For each rect, we clip to the rect, and then we adjust our coords.
2043 LayoutRect colRect = columnRectAt(colInfo, i);
2044 flipForWritingMode(colRect);
2045 LayoutUnit logicalLeftOffset = (isHorizontalWritingMode() ? colRect.x() : colRect.y()) - logicalLeftOffsetForContent();
2046 LayoutSize offset = isHorizontalWritingMode() ? LayoutSize(logicalLeftOf fset, currLogicalTopOffset) : LayoutSize(currLogicalTopOffset, logicalLeftOffset );
2047 if (colInfo->progressionAxis() == ColumnInfo::BlockAxis) {
2048 if (isHorizontalWritingMode())
2049 offset.expand(0, colRect.y() - borderTop() - paddingTop());
2050 else
2051 offset.expand(colRect.x() - borderLeft() - paddingLeft(), 0);
2052 }
2053 colRect.moveBy(paintOffset);
2054 PaintInfo info(paintInfo);
2055 info.rect.intersect(pixelSnappedIntRect(colRect));
2056
2057 if (!info.rect.isEmpty()) {
2058 GraphicsContextStateSaver stateSaver(*context);
2059 LayoutRect clipRect(colRect);
2060
2061 if (i < colCount - 1) {
2062 if (isHorizontalWritingMode())
2063 clipRect.expand(colGap / 2, 0);
2064 else
2065 clipRect.expand(0, colGap / 2);
2066 }
2067 // Each strip pushes a clip, since column boxes are specified as bei ng
2068 // like overflow:hidden.
2069 // FIXME: Content and column rules that extend outside column boxes at the edges of the multi-column element
2070 // are clipped according to the 'overflow' property.
2071 context->clip(pixelSnappedIntRect(clipRect));
2072
2073 // Adjust our x and y when painting.
2074 LayoutPoint adjustedPaintOffset = paintOffset + offset;
2075 if (paintingFloats)
2076 paintFloats(info, adjustedPaintOffset, paintInfo.phase == PaintP haseSelection || paintInfo.phase == PaintPhaseTextClip);
2077 else
2078 paintContents(info, adjustedPaintOffset);
2079 }
2080
2081 LayoutUnit blockDelta = (isHorizontalWritingMode() ? colRect.height() : colRect.width());
2082 if (style()->isFlippedBlocksWritingMode())
2083 currLogicalTopOffset += blockDelta;
2084 else
2085 currLogicalTopOffset -= blockDelta;
2086 }
2087 }
2088
2089 void RenderBlock::paintContents(PaintInfo& paintInfo, const LayoutPoint& paintOf fset) 1543 void RenderBlock::paintContents(PaintInfo& paintInfo, const LayoutPoint& paintOf fset)
2090 { 1544 {
2091 // Avoid painting descendants of the root element when stylesheets haven't l oaded. This eliminates FOUC. 1545 // Avoid painting descendants of the root element when stylesheets haven't l oaded. This eliminates FOUC.
2092 // It's ok not to draw, because later on, when all the stylesheets do load, styleResolverChanged() on the Document 1546 // It's ok not to draw, because later on, when all the stylesheets do load, styleResolverChanged() on the Document
2093 // will do a full repaint. 1547 // will do a full repaint.
2094 if (document().didLayoutWithPendingStylesheets() && !isRenderView()) 1548 if (document().didLayoutWithPendingStylesheets() && !isRenderView())
2095 return; 1549 return;
2096 1550
2097 if (childrenInline()) 1551 if (childrenInline())
2098 m_lineBoxes.paint(this, paintInfo, paintOffset); 1552 m_lineBoxes.paint(this, paintInfo, paintOffset);
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
2186 1640
2187 // Adjust our painting position if we're inside a scrolled layer (e.g., an o verflow:auto div). 1641 // Adjust our painting position if we're inside a scrolled layer (e.g., an o verflow:auto div).
2188 LayoutPoint scrolledOffset = paintOffset; 1642 LayoutPoint scrolledOffset = paintOffset;
2189 if (hasOverflowClip()) 1643 if (hasOverflowClip())
2190 scrolledOffset.move(-scrolledContentOffset()); 1644 scrolledOffset.move(-scrolledContentOffset());
2191 1645
2192 // 1. paint background, borders etc 1646 // 1. paint background, borders etc
2193 if ((paintPhase == PaintPhaseBlockBackground || paintPhase == PaintPhaseChil dBlockBackground) && style()->visibility() == VISIBLE) { 1647 if ((paintPhase == PaintPhaseBlockBackground || paintPhase == PaintPhaseChil dBlockBackground) && style()->visibility() == VISIBLE) {
2194 if (hasBoxDecorations()) 1648 if (hasBoxDecorations())
2195 paintBoxDecorations(paintInfo, paintOffset); 1649 paintBoxDecorations(paintInfo, paintOffset);
2196 if (hasColumns() && !paintInfo.paintRootBackgroundOnly())
2197 paintColumnRules(paintInfo, scrolledOffset);
2198 } 1650 }
2199 1651
2200 if (paintPhase == PaintPhaseMask && style()->visibility() == VISIBLE) { 1652 if (paintPhase == PaintPhaseMask && style()->visibility() == VISIBLE) {
2201 paintMask(paintInfo, paintOffset); 1653 paintMask(paintInfo, paintOffset);
2202 return; 1654 return;
2203 } 1655 }
2204 1656
2205 if (paintPhase == PaintPhaseClippingMask && style()->visibility() == VISIBLE ) { 1657 if (paintPhase == PaintPhaseClippingMask && style()->visibility() == VISIBLE ) {
2206 paintClippingMask(paintInfo, paintOffset); 1658 paintClippingMask(paintInfo, paintOffset);
2207 return; 1659 return;
2208 } 1660 }
2209 1661
2210 // We're done. We don't bother painting any children. 1662 // We're done. We don't bother painting any children.
2211 if (paintPhase == PaintPhaseBlockBackground || paintInfo.paintRootBackground Only()) 1663 if (paintPhase == PaintPhaseBlockBackground || paintInfo.paintRootBackground Only())
2212 return; 1664 return;
2213 1665
2214 // 2. paint contents 1666 // 2. paint contents
2215 if (paintPhase != PaintPhaseSelfOutline) { 1667 if (paintPhase != PaintPhaseSelfOutline)
2216 if (hasColumns()) 1668 paintContents(paintInfo, scrolledOffset);
2217 paintColumnContents(paintInfo, scrolledOffset);
2218 else
2219 paintContents(paintInfo, scrolledOffset);
2220 }
2221 1669
2222 // 3. paint selection 1670 // 3. paint selection
2223 // FIXME: Make this work with multi column layouts. For now don't fill gaps . 1671 // FIXME: Make this work with multi column layouts. For now don't fill gaps .
2224 bool isPrinting = document().printing(); 1672 bool isPrinting = document().printing();
2225 if (!isPrinting && !hasColumns()) 1673 if (!isPrinting)
2226 paintSelection(paintInfo, scrolledOffset); // Fill in gaps in selection on lines and between blocks. 1674 paintSelection(paintInfo, scrolledOffset); // Fill in gaps in selection on lines and between blocks.
2227 1675
2228 // 4. paint floats. 1676 // 4. paint floats.
2229 if (paintPhase == PaintPhaseFloat || paintPhase == PaintPhaseSelection || pa intPhase == PaintPhaseTextClip) { 1677 if (paintPhase == PaintPhaseFloat || paintPhase == PaintPhaseSelection || pa intPhase == PaintPhaseTextClip)
2230 if (hasColumns()) 1678 paintFloats(paintInfo, scrolledOffset, paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip);
2231 paintColumnContents(paintInfo, scrolledOffset, true);
2232 else
2233 paintFloats(paintInfo, scrolledOffset, paintPhase == PaintPhaseSelec tion || paintPhase == PaintPhaseTextClip);
2234 }
2235 1679
2236 // 5. paint outline. 1680 // 5. paint outline.
2237 if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && hasOutline() && style()->visibility() == VISIBLE) 1681 if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && hasOutline() && style()->visibility() == VISIBLE)
2238 paintOutline(paintInfo, LayoutRect(paintOffset, size())); 1682 paintOutline(paintInfo, LayoutRect(paintOffset, size()));
2239 1683
2240 // 6. paint continuation outlines. 1684 // 6. paint continuation outlines.
2241 if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseChildOutline s)) { 1685 if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseChildOutline s)) {
2242 RenderInline* inlineCont = inlineElementContinuation(); 1686 RenderInline* inlineCont = inlineElementContinuation();
2243 if (inlineCont && inlineCont->hasOutline() && inlineCont->style()->visib ility() == VISIBLE) { 1687 if (inlineCont && inlineCont->hasOutline() && inlineCont->style()->visib ility() == VISIBLE) {
2244 RenderInline* inlineRenderer = toRenderInline(inlineCont->node()->re nderer()); 1688 RenderInline* inlineRenderer = toRenderInline(inlineCont->node()->re nderer());
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
2475 clipOutPositionedObjects(paintInfo, LayoutPoint(cb->x(), cb->y() ), cb->positionedObjects()); // FIXME: Not right for flipped writing modes. 1919 clipOutPositionedObjects(paintInfo, LayoutPoint(cb->x(), cb->y() ), cb->positionedObjects()); // FIXME: Not right for flipped writing modes.
2476 clipOutFloatingObjects(rootBlock, paintInfo, rootBlockPhysicalPosition, offsetFromRootBlock); 1920 clipOutFloatingObjects(rootBlock, paintInfo, rootBlockPhysicalPosition, offsetFromRootBlock);
2477 } 1921 }
2478 1922
2479 // FIXME: overflow: auto/scroll regions need more math here, since painting in the border box is different from painting in the padding box (one is scrolled , the other is 1923 // FIXME: overflow: auto/scroll regions need more math here, since painting in the border box is different from painting in the padding box (one is scrolled , the other is
2480 // fixed). 1924 // fixed).
2481 GapRects result; 1925 GapRects result;
2482 if (!isRenderBlockFlow() && !isFlexibleBoxIncludingDeprecated()) // FIXME: M ake multi-column selection gap filling work someday. 1926 if (!isRenderBlockFlow() && !isFlexibleBoxIncludingDeprecated()) // FIXME: M ake multi-column selection gap filling work someday.
2483 return result; 1927 return result;
2484 1928
2485 if (hasColumns() || hasTransform() || style()->columnSpan()) { 1929 if (hasTransform() || style()->columnSpan()) {
2486 // FIXME: We should learn how to gap fill multiple columns and transform s eventually. 1930 // FIXME: We should learn how to gap fill multiple columns and transform s eventually.
2487 lastLogicalTop = rootBlock->blockDirectionOffset(offsetFromRootBlock) + logicalHeight(); 1931 lastLogicalTop = rootBlock->blockDirectionOffset(offsetFromRootBlock) + logicalHeight();
2488 lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight()) ; 1932 lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight()) ;
2489 lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight( )); 1933 lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight( ));
2490 return result; 1934 return result;
2491 } 1935 }
2492 1936
2493 if (childrenInline()) 1937 if (childrenInline())
2494 result = toRenderBlockFlow(this)->inlineSelectionGaps(rootBlock, rootBlo ckPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLo gicalRight, paintInfo); 1938 result = toRenderBlockFlow(this)->inlineSelectionGaps(rootBlock, rootBlo ckPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLo gicalRight, paintInfo);
2495 else 1939 else
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after
2910 afterLowest = lowestDirtyLine; 2354 afterLowest = lowestDirtyLine;
2911 lowestDirtyLine = lowestDirtyLine->prevRootBox(); 2355 lowestDirtyLine = lowestDirtyLine->prevRootBox();
2912 } 2356 }
2913 2357
2914 while (afterLowest && afterLowest != highest && (afterLowest->lineBottomWith Leading() >= logicalTop || afterLowest->lineBottomWithLeading() < 0)) { 2358 while (afterLowest && afterLowest != highest && (afterLowest->lineBottomWith Leading() >= logicalTop || afterLowest->lineBottomWithLeading() < 0)) {
2915 afterLowest->markDirty(); 2359 afterLowest->markDirty();
2916 afterLowest = afterLowest->prevRootBox(); 2360 afterLowest = afterLowest->prevRootBox();
2917 } 2361 }
2918 } 2362 }
2919 2363
2920 bool RenderBlock::avoidsFloats() const
2921 {
2922 // Floats can't intrude into our box if we have a non-auto column count or w idth.
2923 return RenderBox::avoidsFloats() || !style()->hasAutoColumnCount() || !style ()->hasAutoColumnWidth();
2924 }
2925
2926 void RenderBlock::markShapeInsideDescendantsForLayout() 2364 void RenderBlock::markShapeInsideDescendantsForLayout()
2927 { 2365 {
2928 if (!everHadLayout()) 2366 if (!everHadLayout())
2929 return; 2367 return;
2930 if (childrenInline()) { 2368 if (childrenInline()) {
2931 setNeedsLayout(); 2369 setNeedsLayout();
2932 return; 2370 return;
2933 } 2371 }
2934 for (RenderObject* child = firstChild(); child; child = child->nextSibling() ) { 2372 for (RenderObject* child = firstChild(); child; child = child->nextSibling() ) {
2935 if (!child->isRenderBlock()) 2373 if (!child->isRenderBlock())
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
2981 // If we have clipping, then we can't have any spillout. 2419 // If we have clipping, then we can't have any spillout.
2982 bool useOverflowClip = hasOverflowClip() && !hasSelfPaintingLayer(); 2420 bool useOverflowClip = hasOverflowClip() && !hasSelfPaintingLayer();
2983 bool useClip = (hasControlClip() || useOverflowClip); 2421 bool useClip = (hasControlClip() || useOverflowClip);
2984 bool checkChildren = !useClip || (hasControlClip() ? locationInContainer.int ersects(controlClipRect(adjustedLocation)) : locationInContainer.intersects(over flowClipRect(adjustedLocation, locationInContainer.region(), IncludeOverlayScrol lbarSize))); 2422 bool checkChildren = !useClip || (hasControlClip() ? locationInContainer.int ersects(controlClipRect(adjustedLocation)) : locationInContainer.intersects(over flowClipRect(adjustedLocation, locationInContainer.region(), IncludeOverlayScrol lbarSize)));
2985 if (checkChildren) { 2423 if (checkChildren) {
2986 // Hit test descendants first. 2424 // Hit test descendants first.
2987 LayoutSize scrolledOffset(localOffset); 2425 LayoutSize scrolledOffset(localOffset);
2988 if (hasOverflowClip()) 2426 if (hasOverflowClip())
2989 scrolledOffset -= scrolledContentOffset(); 2427 scrolledOffset -= scrolledContentOffset();
2990 2428
2991 // Hit test contents if we don't have columns. 2429 if (hitTestContents(request, result, locationInContainer, toLayoutPoint( scrolledOffset), hitTestAction)) {
2992 if (!hasColumns()) {
2993 if (hitTestContents(request, result, locationInContainer, toLayoutPo int(scrolledOffset), hitTestAction)) {
2994 updateHitTestResult(result, flipForWritingMode(locationInContain er.point() - localOffset));
2995 return true;
2996 }
2997 if (hitTestAction == HitTestFloat && hitTestFloats(request, result, locationInContainer, toLayoutPoint(scrolledOffset)))
2998 return true;
2999 } else if (hitTestColumns(request, result, locationInContainer, toLayout Point(scrolledOffset), hitTestAction)) {
3000 updateHitTestResult(result, flipForWritingMode(locationInContainer.p oint() - localOffset)); 2430 updateHitTestResult(result, flipForWritingMode(locationInContainer.p oint() - localOffset));
3001 return true; 2431 return true;
3002 } 2432 }
2433 if (hitTestAction == HitTestFloat && hitTestFloats(request, result, loca tionInContainer, toLayoutPoint(scrolledOffset)))
2434 return true;
3003 } 2435 }
3004 2436
3005 // Check if the point is outside radii. 2437 // Check if the point is outside radii.
3006 if (!isRenderView() && style()->hasBorderRadius()) { 2438 if (!isRenderView() && style()->hasBorderRadius()) {
3007 LayoutRect borderRect = borderBoxRect(); 2439 LayoutRect borderRect = borderBoxRect();
3008 borderRect.moveBy(adjustedLocation); 2440 borderRect.moveBy(adjustedLocation);
3009 RoundedRect border = style()->getRoundedBorderFor(borderRect); 2441 RoundedRect border = style()->getRoundedBorderFor(borderRect);
3010 if (!locationInContainer.intersects(border)) 2442 if (!locationInContainer.intersects(border))
3011 return false; 2443 return false;
3012 } 2444 }
3013 2445
3014 // Now hit test our background 2446 // Now hit test our background
3015 if (hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChild BlockBackground) { 2447 if (hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChild BlockBackground) {
3016 LayoutRect boundsRect(adjustedLocation, size()); 2448 LayoutRect boundsRect(adjustedLocation, size());
3017 if (visibleToHitTestRequest(request) && locationInContainer.intersects(b oundsRect)) { 2449 if (visibleToHitTestRequest(request) && locationInContainer.intersects(b oundsRect)) {
3018 updateHitTestResult(result, flipForWritingMode(locationInContainer.p oint() - localOffset)); 2450 updateHitTestResult(result, flipForWritingMode(locationInContainer.p oint() - localOffset));
3019 if (!result.addNodeToRectBasedTestResult(nodeForHitTest(), request, locationInContainer, boundsRect)) 2451 if (!result.addNodeToRectBasedTestResult(nodeForHitTest(), request, locationInContainer, boundsRect))
3020 return true; 2452 return true;
3021 } 2453 }
3022 } 2454 }
3023 2455
3024 return false; 2456 return false;
3025 } 2457 }
3026 2458
3027 class ColumnRectIterator {
3028 WTF_MAKE_NONCOPYABLE(ColumnRectIterator);
3029 public:
3030 ColumnRectIterator(const RenderBlock& block)
3031 : m_block(block)
3032 , m_colInfo(block.columnInfo())
3033 , m_direction(m_block.style()->isFlippedBlocksWritingMode() ? 1 : -1)
3034 , m_isHorizontal(block.isHorizontalWritingMode())
3035 , m_logicalLeft(block.logicalLeftOffsetForContent())
3036 {
3037 int colCount = m_colInfo->columnCount();
3038 m_colIndex = colCount - 1;
3039 m_currLogicalTopOffset = colCount * m_colInfo->columnHeight() * m_direct ion;
3040 update();
3041 }
3042
3043 void advance()
3044 {
3045 ASSERT(hasMore());
3046 m_colIndex--;
3047 update();
3048 }
3049
3050 LayoutRect columnRect() const { return m_colRect; }
3051 bool hasMore() const { return m_colIndex >= 0; }
3052
3053 void adjust(LayoutSize& offset) const
3054 {
3055 LayoutUnit currLogicalLeftOffset = (m_isHorizontal ? m_colRect.x() : m_c olRect.y()) - m_logicalLeft;
3056 offset += m_isHorizontal ? LayoutSize(currLogicalLeftOffset, m_currLogic alTopOffset) : LayoutSize(m_currLogicalTopOffset, currLogicalLeftOffset);
3057 if (m_colInfo->progressionAxis() == ColumnInfo::BlockAxis) {
3058 if (m_isHorizontal)
3059 offset.expand(0, m_colRect.y() - m_block.borderTop() - m_block.p addingTop());
3060 else
3061 offset.expand(m_colRect.x() - m_block.borderLeft() - m_block.pad dingLeft(), 0);
3062 }
3063 }
3064
3065 private:
3066 void update()
3067 {
3068 if (m_colIndex < 0)
3069 return;
3070
3071 m_colRect = m_block.columnRectAt(const_cast<ColumnInfo*>(m_colInfo), m_c olIndex);
3072 m_block.flipForWritingMode(m_colRect);
3073 m_currLogicalTopOffset -= (m_isHorizontal ? m_colRect.height() : m_colRe ct.width()) * m_direction;
3074 }
3075
3076 const RenderBlock& m_block;
3077 const ColumnInfo* const m_colInfo;
3078 const int m_direction;
3079 const bool m_isHorizontal;
3080 const LayoutUnit m_logicalLeft;
3081 int m_colIndex;
3082 LayoutUnit m_currLogicalTopOffset;
3083 LayoutRect m_colRect;
3084 };
3085
3086 bool RenderBlock::hitTestColumns(const HitTestRequest& request, HitTestResult& r esult, const HitTestLocation& locationInContainer, const LayoutPoint& accumulate dOffset, HitTestAction hitTestAction)
3087 {
3088 // We need to do multiple passes, breaking up our hit testing into strips.
3089 if (!hasColumns())
3090 return false;
3091
3092 for (ColumnRectIterator it(*this); it.hasMore(); it.advance()) {
3093 LayoutRect hitRect = locationInContainer.boundingBox();
3094 LayoutRect colRect = it.columnRect();
3095 colRect.moveBy(accumulatedOffset);
3096 if (locationInContainer.intersects(colRect)) {
3097 // The point is inside this column.
3098 // Adjust accumulatedOffset to change where we hit test.
3099 LayoutSize offset;
3100 it.adjust(offset);
3101 LayoutPoint finalLocation = accumulatedOffset + offset;
3102 if (!result.isRectBasedTest() || colRect.contains(hitRect))
3103 return hitTestContents(request, result, locationInContainer, fin alLocation, hitTestAction) || (hitTestAction == HitTestFloat && hitTestFloats(re quest, result, locationInContainer, finalLocation));
3104
3105 hitTestContents(request, result, locationInContainer, finalLocation, hitTestAction);
3106 }
3107 }
3108
3109 return false;
3110 }
3111
3112 void RenderBlock::adjustForColumnRect(LayoutSize& offset, const LayoutPoint& loc ationInContainer) const
3113 {
3114 for (ColumnRectIterator it(*this); it.hasMore(); it.advance()) {
3115 LayoutRect colRect = it.columnRect();
3116 if (colRect.contains(locationInContainer)) {
3117 it.adjust(offset);
3118 return;
3119 }
3120 }
3121 }
3122
3123 bool RenderBlock::hitTestContents(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulat edOffset, HitTestAction hitTestAction) 2459 bool RenderBlock::hitTestContents(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulat edOffset, HitTestAction hitTestAction)
3124 { 2460 {
3125 if (isRenderRegion()) 2461 if (isRenderRegion())
3126 return toRenderRegion(this)->hitTestFlowThreadContents(request, result, locationInContainer, accumulatedOffset, hitTestAction); 2462 return toRenderRegion(this)->hitTestFlowThreadContents(request, result, locationInContainer, accumulatedOffset, hitTestAction);
3127 2463
3128 if (childrenInline() && !isTable()) { 2464 if (childrenInline() && !isTable()) {
3129 // We have to hit-test our line boxes. 2465 // We have to hit-test our line boxes.
3130 if (m_lineBoxes.hitTest(this, request, result, locationInContainer, accu mulatedOffset, hitTestAction)) 2466 if (m_lineBoxes.hitTest(this, request, result, locationInContainer, accu mulatedOffset, hitTestAction))
3131 return true; 2467 return true;
3132 } else { 2468 } else {
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
3349 return RenderBox::positionForPoint(point); 2685 return RenderBox::positionForPoint(point);
3350 } 2686 }
3351 2687
3352 void RenderBlock::offsetForContents(LayoutPoint& offset) const 2688 void RenderBlock::offsetForContents(LayoutPoint& offset) const
3353 { 2689 {
3354 offset = flipForWritingMode(offset); 2690 offset = flipForWritingMode(offset);
3355 2691
3356 if (hasOverflowClip()) 2692 if (hasOverflowClip())
3357 offset += scrolledContentOffset(); 2693 offset += scrolledContentOffset();
3358 2694
3359 if (hasColumns())
3360 adjustPointToColumnContents(offset);
3361
3362 offset = flipForWritingMode(offset); 2695 offset = flipForWritingMode(offset);
3363 } 2696 }
3364 2697
3365 LayoutUnit RenderBlock::availableLogicalWidth() const
3366 {
3367 // If we have multiple columns, then the available logical width is reduced to our column width.
3368 if (hasColumns())
3369 return desiredColumnWidth();
3370 return RenderBox::availableLogicalWidth();
3371 }
3372
3373 int RenderBlock::columnGap() const 2698 int RenderBlock::columnGap() const
3374 { 2699 {
3375 if (style()->hasNormalColumnGap()) 2700 if (style()->hasNormalColumnGap())
3376 return style()->fontDescription().computedPixelSize(); // "1em" is recom mended as the normal gap setting. Matches <p> margins. 2701 return style()->fontDescription().computedPixelSize(); // "1em" is recom mended as the normal gap setting. Matches <p> margins.
3377 return static_cast<int>(style()->columnGap()); 2702 return static_cast<int>(style()->columnGap());
3378 } 2703 }
3379 2704
3380 void RenderBlock::calcColumnWidth()
3381 {
3382 if (document().regionBasedColumnsEnabled())
3383 return;
3384
3385 // Calculate our column width and column count.
3386 // FIXME: Can overflow on fast/block/float/float-not-removed-from-next-sibli ng4.html, see https://bugs.webkit.org/show_bug.cgi?id=68744
3387 unsigned desiredColumnCount = 1;
3388 LayoutUnit desiredColumnWidth = contentLogicalWidth();
3389
3390 // For now, we don't support multi-column layouts when printing, since we ha ve to do a lot of work for proper pagination.
3391 if (document().paginated() || (style()->hasAutoColumnCount() && style()->has AutoColumnWidth()) || !style()->hasInlineColumnAxis()) {
3392 setDesiredColumnCountAndWidth(desiredColumnCount, desiredColumnWidth);
3393 return;
3394 }
3395
3396 LayoutUnit availWidth = desiredColumnWidth;
3397 LayoutUnit colGap = columnGap();
3398 LayoutUnit colWidth = max<LayoutUnit>(1, LayoutUnit(style()->columnWidth())) ;
3399 int colCount = max<int>(1, style()->columnCount());
3400
3401 if (style()->hasAutoColumnWidth() && !style()->hasAutoColumnCount()) {
3402 desiredColumnCount = colCount;
3403 desiredColumnWidth = max<LayoutUnit>(0, (availWidth - ((desiredColumnCou nt - 1) * colGap)) / desiredColumnCount);
3404 } else if (!style()->hasAutoColumnWidth() && style()->hasAutoColumnCount()) {
3405 desiredColumnCount = max<LayoutUnit>(1, (availWidth + colGap) / (colWidt h + colGap));
3406 desiredColumnWidth = ((availWidth + colGap) / desiredColumnCount) - colG ap;
3407 } else {
3408 desiredColumnCount = max<LayoutUnit>(min<LayoutUnit>(colCount, (availWid th + colGap) / (colWidth + colGap)), 1);
3409 desiredColumnWidth = ((availWidth + colGap) / desiredColumnCount) - colG ap;
3410 }
3411 setDesiredColumnCountAndWidth(desiredColumnCount, desiredColumnWidth);
3412 }
3413
3414 bool RenderBlock::requiresColumns(int desiredColumnCount) const 2705 bool RenderBlock::requiresColumns(int desiredColumnCount) const
3415 { 2706 {
3416 // If overflow-y is set to paged-x or paged-y on the body or html element, w e'll handle the paginating 2707 // If overflow-y is set to paged-x or paged-y on the body or html element, w e'll handle the paginating
3417 // in the RenderView instead. 2708 // in the RenderView instead.
3418 bool isPaginated = (style()->overflowY() == OPAGEDX || style()->overflowY() == OPAGEDY) && !(isRoot() || isBody()); 2709 bool isPaginated = (style()->overflowY() == OPAGEDX || style()->overflowY() == OPAGEDY) && !(isRoot() || isBody());
3419 2710
3420 return firstChild() 2711 return firstChild()
3421 && (desiredColumnCount != 1 || !style()->hasAutoColumnWidth() || !style( )->hasInlineColumnAxis() || isPaginated) 2712 && (desiredColumnCount != 1 || !style()->hasAutoColumnWidth() || !style( )->hasInlineColumnAxis() || isPaginated);
3422 && !firstChild()->isAnonymousColumnsBlock()
3423 && !firstChild()->isAnonymousColumnSpanBlock();
3424 }
3425
3426 void RenderBlock::setDesiredColumnCountAndWidth(int count, LayoutUnit width)
3427 {
3428 bool destroyColumns = !requiresColumns(count);
3429 if (destroyColumns) {
3430 if (hasColumns()) {
3431 gColumnInfoMap->take(this);
3432 setHasColumns(false);
3433 }
3434 } else {
3435 ColumnInfo* info;
3436 if (hasColumns())
3437 info = gColumnInfoMap->get(this);
3438 else {
3439 if (!gColumnInfoMap)
3440 gColumnInfoMap = new ColumnInfoMap;
3441 info = new ColumnInfo;
3442 gColumnInfoMap->add(this, adoptPtr(info));
3443 setHasColumns(true);
3444 }
3445 info->setDesiredColumnCount(count);
3446 info->setDesiredColumnWidth(width);
3447 info->setProgressionAxis(style()->hasInlineColumnAxis() ? ColumnInfo::In lineAxis : ColumnInfo::BlockAxis);
3448 info->setProgressionIsReversed(style()->columnProgression() == ReverseCo lumnProgression);
3449 }
3450 }
3451
3452 void RenderBlock::updateColumnInfoFromStyle(RenderStyle* style)
3453 {
3454 if (!hasColumns())
3455 return;
3456
3457 ColumnInfo* info = gColumnInfoMap->get(this);
3458
3459 bool needsLayout = false;
3460 ColumnInfo::Axis oldAxis = info->progressionAxis();
3461 ColumnInfo::Axis newAxis = style->hasInlineColumnAxis() ? ColumnInfo::Inline Axis : ColumnInfo::BlockAxis;
3462 if (oldAxis != newAxis) {
3463 info->setProgressionAxis(newAxis);
3464 needsLayout = true;
3465 }
3466
3467 bool oldProgressionIsReversed = info->progressionIsReversed();
3468 bool newProgressionIsReversed = style->columnProgression() == ReverseColumnP rogression;
3469 if (oldProgressionIsReversed != newProgressionIsReversed) {
3470 info->setProgressionIsReversed(newProgressionIsReversed);
3471 needsLayout = true;
3472 }
3473
3474 if (needsLayout)
3475 setNeedsLayoutAndPrefWidthsRecalc();
3476 }
3477
3478 LayoutUnit RenderBlock::desiredColumnWidth() const
3479 {
3480 if (!hasColumns())
3481 return contentLogicalWidth();
3482 return gColumnInfoMap->get(this)->desiredColumnWidth();
3483 }
3484
3485 ColumnInfo* RenderBlock::columnInfo() const
3486 {
3487 if (!hasColumns())
3488 return 0;
3489 return gColumnInfoMap->get(this);
3490 }
3491
3492 unsigned RenderBlock::columnCount(ColumnInfo* colInfo) const
3493 {
3494 ASSERT(hasColumns());
3495 ASSERT(gColumnInfoMap->get(this) == colInfo);
3496 return colInfo->columnCount();
3497 }
3498
3499 LayoutRect RenderBlock::columnRectAt(ColumnInfo* colInfo, unsigned index) const
3500 {
3501 ASSERT(hasColumns() && gColumnInfoMap->get(this) == colInfo);
3502
3503 // Compute the appropriate rect based off our information.
3504 LayoutUnit colLogicalWidth = colInfo->desiredColumnWidth();
3505 LayoutUnit colLogicalHeight = colInfo->columnHeight();
3506 LayoutUnit colLogicalTop = borderBefore() + paddingBefore();
3507 LayoutUnit colLogicalLeft = logicalLeftOffsetForContent();
3508 LayoutUnit colGap = columnGap();
3509 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) {
3510 if (style()->isLeftToRightDirection() ^ colInfo->progressionIsReversed() )
3511 colLogicalLeft += index * (colLogicalWidth + colGap);
3512 else
3513 colLogicalLeft += contentLogicalWidth() - colLogicalWidth - index * (colLogicalWidth + colGap);
3514 } else {
3515 if (!colInfo->progressionIsReversed())
3516 colLogicalTop += index * (colLogicalHeight + colGap);
3517 else
3518 colLogicalTop += contentLogicalHeight() - colLogicalHeight - index * (colLogicalHeight + colGap);
3519 }
3520
3521 if (isHorizontalWritingMode())
3522 return LayoutRect(colLogicalLeft, colLogicalTop, colLogicalWidth, colLog icalHeight);
3523 return LayoutRect(colLogicalTop, colLogicalLeft, colLogicalHeight, colLogica lWidth);
3524 } 2713 }
3525 2714
3526 bool RenderBlock::relayoutToAvoidWidows(LayoutStateMaintainer& statePusher) 2715 bool RenderBlock::relayoutToAvoidWidows(LayoutStateMaintainer& statePusher)
3527 { 2716 {
3528 if (!shouldBreakAtLineToAvoidWidow()) 2717 if (!shouldBreakAtLineToAvoidWidow())
3529 return false; 2718 return false;
3530 2719
3531 statePusher.pop(); 2720 statePusher.pop();
3532 setEverHadLayout(true); 2721 setEverHadLayout(true);
3533 layoutBlock(false); 2722 layoutBlock(false);
3534 return true; 2723 return true;
3535 } 2724 }
3536 2725
3537 void RenderBlock::adjustPointToColumnContents(LayoutPoint& point) const
3538 {
3539 // Just bail if we have no columns.
3540 if (!hasColumns())
3541 return;
3542
3543 ColumnInfo* colInfo = columnInfo();
3544 if (!columnCount(colInfo))
3545 return;
3546
3547 // Determine which columns we intersect.
3548 LayoutUnit colGap = columnGap();
3549 LayoutUnit halfColGap = colGap / 2;
3550 LayoutPoint columnPoint(columnRectAt(colInfo, 0).location());
3551 LayoutUnit logicalOffset = 0;
3552 for (unsigned i = 0; i < colInfo->columnCount(); i++) {
3553 // Add in half the column gap to the left and right of the rect.
3554 LayoutRect colRect = columnRectAt(colInfo, i);
3555 flipForWritingMode(colRect);
3556 if (isHorizontalWritingMode() == (colInfo->progressionAxis() == ColumnIn fo::InlineAxis)) {
3557 LayoutRect gapAndColumnRect(colRect.x() - halfColGap, colRect.y(), c olRect.width() + colGap, colRect.height());
3558 if (point.x() >= gapAndColumnRect.x() && point.x() < gapAndColumnRec t.maxX()) {
3559 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) {
3560 // FIXME: The clamping that follows is not completely right for right-to-left
3561 // content.
3562 // Clamp everything above the column to its top left.
3563 if (point.y() < gapAndColumnRect.y())
3564 point = gapAndColumnRect.location();
3565 // Clamp everything below the column to the next column's to p left. If there is
3566 // no next column, this still maps to just after this column .
3567 else if (point.y() >= gapAndColumnRect.maxY()) {
3568 point = gapAndColumnRect.location();
3569 point.move(0, gapAndColumnRect.height());
3570 }
3571 } else {
3572 if (point.x() < colRect.x())
3573 point.setX(colRect.x());
3574 else if (point.x() >= colRect.maxX())
3575 point.setX(colRect.maxX() - 1);
3576 }
3577
3578 // We're inside the column. Translate the x and y into our colu mn coordinate space.
3579 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis)
3580 point.move(columnPoint.x() - colRect.x(), (!style()->isFlipp edBlocksWritingMode() ? logicalOffset : -logicalOffset));
3581 else
3582 point.move((!style()->isFlippedBlocksWritingMode() ? logical Offset : -logicalOffset) - colRect.x() + borderLeft() + paddingLeft(), 0);
3583 return;
3584 }
3585
3586 // Move to the next position.
3587 logicalOffset += colInfo->progressionAxis() == ColumnInfo::InlineAxi s ? colRect.height() : colRect.width();
3588 } else {
3589 LayoutRect gapAndColumnRect(colRect.x(), colRect.y() - halfColGap, c olRect.width(), colRect.height() + colGap);
3590 if (point.y() >= gapAndColumnRect.y() && point.y() < gapAndColumnRec t.maxY()) {
3591 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) {
3592 // FIXME: The clamping that follows is not completely right for right-to-left
3593 // content.
3594 // Clamp everything above the column to its top left.
3595 if (point.x() < gapAndColumnRect.x())
3596 point = gapAndColumnRect.location();
3597 // Clamp everything below the column to the next column's to p left. If there is
3598 // no next column, this still maps to just after this column .
3599 else if (point.x() >= gapAndColumnRect.maxX()) {
3600 point = gapAndColumnRect.location();
3601 point.move(gapAndColumnRect.width(), 0);
3602 }
3603 } else {
3604 if (point.y() < colRect.y())
3605 point.setY(colRect.y());
3606 else if (point.y() >= colRect.maxY())
3607 point.setY(colRect.maxY() - 1);
3608 }
3609
3610 // We're inside the column. Translate the x and y into our colu mn coordinate space.
3611 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis)
3612 point.move((!style()->isFlippedBlocksWritingMode() ? logical Offset : -logicalOffset), columnPoint.y() - colRect.y());
3613 else
3614 point.move(0, (!style()->isFlippedBlocksWritingMode() ? logi calOffset : -logicalOffset) - colRect.y() + borderTop() + paddingTop());
3615 return;
3616 }
3617
3618 // Move to the next position.
3619 logicalOffset += colInfo->progressionAxis() == ColumnInfo::InlineAxi s ? colRect.width() : colRect.height();
3620 }
3621 }
3622 }
3623
3624 void RenderBlock::adjustRectForColumns(LayoutRect& r) const
3625 {
3626 // Just bail if we have no columns.
3627 if (!hasColumns())
3628 return;
3629
3630 ColumnInfo* colInfo = columnInfo();
3631
3632 // Determine which columns we intersect.
3633 unsigned colCount = columnCount(colInfo);
3634 if (!colCount)
3635 return;
3636
3637 // Begin with a result rect that is empty.
3638 LayoutRect result;
3639
3640 bool isHorizontal = isHorizontalWritingMode();
3641 LayoutUnit beforeBorderPadding = borderBefore() + paddingBefore();
3642 LayoutUnit colHeight = colInfo->columnHeight();
3643 if (!colHeight)
3644 return;
3645
3646 LayoutUnit startOffset = max(isHorizontal ? r.y() : r.x(), beforeBorderPaddi ng);
3647 LayoutUnit endOffset = max(min<LayoutUnit>(isHorizontal ? r.maxY() : r.maxX( ), beforeBorderPadding + colCount * colHeight), beforeBorderPadding);
3648
3649 // FIXME: Can overflow on fast/block/float/float-not-removed-from-next-sibli ng4.html, see https://bugs.webkit.org/show_bug.cgi?id=68744
3650 unsigned startColumn = (startOffset - beforeBorderPadding) / colHeight;
3651 unsigned endColumn = (endOffset - beforeBorderPadding) / colHeight;
3652
3653 if (startColumn == endColumn) {
3654 // The rect is fully contained within one column. Adjust for our offsets
3655 // and repaint only that portion.
3656 LayoutUnit logicalLeftOffset = logicalLeftOffsetForContent();
3657 LayoutRect colRect = columnRectAt(colInfo, startColumn);
3658 LayoutRect repaintRect = r;
3659
3660 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) {
3661 if (isHorizontal)
3662 repaintRect.move(colRect.x() - logicalLeftOffset, - static_cast< int>(startColumn) * colHeight);
3663 else
3664 repaintRect.move(- static_cast<int>(startColumn) * colHeight, co lRect.y() - logicalLeftOffset);
3665 } else {
3666 if (isHorizontal)
3667 repaintRect.move(0, colRect.y() - startColumn * colHeight - befo reBorderPadding);
3668 else
3669 repaintRect.move(colRect.x() - startColumn * colHeight - beforeB orderPadding, 0);
3670 }
3671 repaintRect.intersect(colRect);
3672 result.unite(repaintRect);
3673 } else {
3674 // We span multiple columns. We can just unite the start and end column to get the final
3675 // repaint rect.
3676 result.unite(columnRectAt(colInfo, startColumn));
3677 result.unite(columnRectAt(colInfo, endColumn));
3678 }
3679
3680 r = result;
3681 }
3682
3683 LayoutPoint RenderBlock::flipForWritingModeIncludingColumns(const LayoutPoint& p oint) const
3684 {
3685 ASSERT(hasColumns());
3686 if (!hasColumns() || !style()->isFlippedBlocksWritingMode())
3687 return point;
3688 ColumnInfo* colInfo = columnInfo();
3689 LayoutUnit columnLogicalHeight = colInfo->columnHeight();
3690 LayoutUnit expandedLogicalHeight = borderBefore() + paddingBefore() + column Count(colInfo) * columnLogicalHeight + borderAfter() + paddingAfter() + scrollba rLogicalHeight();
3691 if (isHorizontalWritingMode())
3692 return LayoutPoint(point.x(), expandedLogicalHeight - point.y());
3693 return LayoutPoint(expandedLogicalHeight - point.x(), point.y());
3694 }
3695
3696 void RenderBlock::adjustStartEdgeForWritingModeIncludingColumns(LayoutRect& rect ) const
3697 {
3698 ASSERT(hasColumns());
3699 if (!hasColumns() || !style()->isFlippedBlocksWritingMode())
3700 return;
3701
3702 ColumnInfo* colInfo = columnInfo();
3703 LayoutUnit columnLogicalHeight = colInfo->columnHeight();
3704 LayoutUnit expandedLogicalHeight = borderBefore() + paddingBefore() + column Count(colInfo) * columnLogicalHeight + borderAfter() + paddingAfter() + scrollba rLogicalHeight();
3705
3706 if (isHorizontalWritingMode())
3707 rect.setY(expandedLogicalHeight - rect.maxY());
3708 else
3709 rect.setX(expandedLogicalHeight - rect.maxX());
3710 }
3711
3712 void RenderBlock::adjustForColumns(LayoutSize& offset, const LayoutPoint& point) const
3713 {
3714 if (!hasColumns())
3715 return;
3716
3717 ColumnInfo* colInfo = columnInfo();
3718
3719 LayoutUnit logicalLeft = logicalLeftOffsetForContent();
3720 unsigned colCount = columnCount(colInfo);
3721 LayoutUnit colLogicalWidth = colInfo->desiredColumnWidth();
3722 LayoutUnit colLogicalHeight = colInfo->columnHeight();
3723
3724 for (unsigned i = 0; i < colCount; ++i) {
3725 // Compute the edges for a given column in the block progression directi on.
3726 LayoutRect sliceRect = LayoutRect(logicalLeft, borderBefore() + paddingB efore() + i * colLogicalHeight, colLogicalWidth, colLogicalHeight);
3727 if (!isHorizontalWritingMode())
3728 sliceRect = sliceRect.transposedRect();
3729
3730 LayoutUnit logicalOffset = i * colLogicalHeight;
3731
3732 // Now we're in the same coordinate space as the point. See if it is in side the rectangle.
3733 if (isHorizontalWritingMode()) {
3734 if (point.y() >= sliceRect.y() && point.y() < sliceRect.maxY()) {
3735 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis)
3736 offset.expand(columnRectAt(colInfo, i).x() - logicalLeft, -l ogicalOffset);
3737 else
3738 offset.expand(0, columnRectAt(colInfo, i).y() - logicalOffse t - borderBefore() - paddingBefore());
3739 return;
3740 }
3741 } else {
3742 if (point.x() >= sliceRect.x() && point.x() < sliceRect.maxX()) {
3743 if (colInfo->progressionAxis() == ColumnInfo::InlineAxis)
3744 offset.expand(-logicalOffset, columnRectAt(colInfo, i).y() - logicalLeft);
3745 else
3746 offset.expand(columnRectAt(colInfo, i).x() - logicalOffset - borderBefore() - paddingBefore(), 0);
3747 return;
3748 }
3749 }
3750 }
3751 }
3752
3753 void RenderBlock::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, Lay outUnit& maxLogicalWidth) const 2726 void RenderBlock::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, Lay outUnit& maxLogicalWidth) const
3754 { 2727 {
3755 if (childrenInline()) { 2728 if (childrenInline()) {
3756 // FIXME: Remove this const_cast. 2729 // FIXME: Remove this const_cast.
3757 const_cast<RenderBlock*>(this)->computeInlinePreferredLogicalWidths(minL ogicalWidth, maxLogicalWidth); 2730 const_cast<RenderBlock*>(this)->computeInlinePreferredLogicalWidths(minL ogicalWidth, maxLogicalWidth);
3758 } else 2731 } else
3759 computeBlockPreferredLogicalWidths(minLogicalWidth, maxLogicalWidth); 2732 computeBlockPreferredLogicalWidths(minLogicalWidth, maxLogicalWidth);
3760 2733
3761 maxLogicalWidth = max(minLogicalWidth, maxLogicalWidth); 2734 maxLogicalWidth = max(minLogicalWidth, maxLogicalWidth);
3762 2735
(...skipping 1427 matching lines...) Expand 10 before | Expand all | Expand 10 after
5190 LayoutRect rect(layerOffset.x() + curr->x(), layerOffset.y() + top, curr->width(), bottom - top); 4163 LayoutRect rect(layerOffset.x() + curr->x(), layerOffset.y() + top, curr->width(), bottom - top);
5191 // It's common for this rect to be entirely contained in our box, so exclude that simple case. 4164 // It's common for this rect to be entirely contained in our box, so exclude that simple case.
5192 if (!rect.isEmpty() && (rects.isEmpty() || !rects[0].contains(rect)) ) 4165 if (!rect.isEmpty() && (rects.isEmpty() || !rects[0].contains(rect)) )
5193 rects.append(rect); 4166 rects.append(rect);
5194 } 4167 }
5195 } 4168 }
5196 } 4169 }
5197 4170
5198 RenderBox* RenderBlock::createAnonymousBoxWithSameTypeAs(const RenderObject* par ent) const 4171 RenderBox* RenderBlock::createAnonymousBoxWithSameTypeAs(const RenderObject* par ent) const
5199 { 4172 {
5200 if (isAnonymousColumnsBlock())
5201 return createAnonymousColumnsWithParentRenderer(parent);
5202 if (isAnonymousColumnSpanBlock())
5203 return createAnonymousColumnSpanWithParentRenderer(parent);
5204 return createAnonymousWithParentRendererAndDisplay(parent, style()->display( )); 4173 return createAnonymousWithParentRendererAndDisplay(parent, style()->display( ));
5205 } 4174 }
5206 4175
5207 bool RenderBlock::hasNextPage(LayoutUnit logicalOffset, PageBoundaryRule pageBou ndaryRule) const 4176 bool RenderBlock::hasNextPage(LayoutUnit logicalOffset, PageBoundaryRule pageBou ndaryRule) const
5208 { 4177 {
5209 ASSERT(view()->layoutState() && view()->layoutState()->isPaginated()); 4178 ASSERT(view()->layoutState() && view()->layoutState()->isPaginated());
5210 4179
5211 RenderFlowThread* flowThread = flowThreadContainingBlock(); 4180 RenderFlowThread* flowThread = flowThreadContainingBlock();
5212 if (!flowThread) 4181 if (!flowThread)
5213 return true; // Printing and multi-column both make new pages to accommo date content. 4182 return true; // Printing and multi-column both make new pages to accommo date content.
(...skipping 15 matching lines...) Expand all
5229 if (!pageLogicalHeight) 4198 if (!pageLogicalHeight)
5230 return logicalOffset; 4199 return logicalOffset;
5231 4200
5232 // The logicalOffset is in our coordinate space. We can add in our pushed o ffset. 4201 // The logicalOffset is in our coordinate space. We can add in our pushed o ffset.
5233 LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(logi calOffset); 4202 LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(logi calOffset);
5234 if (pageBoundaryRule == ExcludePageBoundary) 4203 if (pageBoundaryRule == ExcludePageBoundary)
5235 return logicalOffset + (remainingLogicalHeight ? remainingLogicalHeight : pageLogicalHeight); 4204 return logicalOffset + (remainingLogicalHeight ? remainingLogicalHeight : pageLogicalHeight);
5236 return logicalOffset + remainingLogicalHeight; 4205 return logicalOffset + remainingLogicalHeight;
5237 } 4206 }
5238 4207
5239 ColumnInfo::PaginationUnit RenderBlock::paginationUnit() const
5240 {
5241 return ColumnInfo::Column;
5242 }
5243
5244 LayoutUnit RenderBlock::pageLogicalTopForOffset(LayoutUnit offset) const 4208 LayoutUnit RenderBlock::pageLogicalTopForOffset(LayoutUnit offset) const
5245 { 4209 {
5246 RenderView* renderView = view(); 4210 RenderView* renderView = view();
5247 LayoutUnit firstPageLogicalTop = isHorizontalWritingMode() ? renderView->lay outState()->m_pageOffset.height() : renderView->layoutState()->m_pageOffset.widt h(); 4211 LayoutUnit firstPageLogicalTop = isHorizontalWritingMode() ? renderView->lay outState()->m_pageOffset.height() : renderView->layoutState()->m_pageOffset.widt h();
5248 LayoutUnit blockLogicalTop = isHorizontalWritingMode() ? renderView->layoutS tate()->m_layoutOffset.height() : renderView->layoutState()->m_layoutOffset.widt h(); 4212 LayoutUnit blockLogicalTop = isHorizontalWritingMode() ? renderView->layoutS tate()->m_layoutOffset.height() : renderView->layoutState()->m_layoutOffset.widt h();
5249 4213
5250 LayoutUnit cumulativeOffset = offset + blockLogicalTop; 4214 LayoutUnit cumulativeOffset = offset + blockLogicalTop;
5251 RenderFlowThread* flowThread = flowThreadContainingBlock(); 4215 RenderFlowThread* flowThread = flowThreadContainingBlock();
5252 if (!flowThread) { 4216 if (!flowThread) {
5253 LayoutUnit pageLogicalHeight = renderView->layoutState()->pageLogicalHei ght(); 4217 LayoutUnit pageLogicalHeight = renderView->layoutState()->pageLogicalHei ght();
(...skipping 28 matching lines...) Expand all
5282 remainingHeight = intMod(remainingHeight, pageLogicalHeight); 4246 remainingHeight = intMod(remainingHeight, pageLogicalHeight);
5283 } 4247 }
5284 return remainingHeight; 4248 return remainingHeight;
5285 } 4249 }
5286 4250
5287 return flowThread->pageRemainingLogicalHeightForOffset(offset, pageBoundaryR ule); 4251 return flowThread->pageRemainingLogicalHeightForOffset(offset, pageBoundaryR ule);
5288 } 4252 }
5289 4253
5290 LayoutUnit RenderBlock::adjustForUnsplittableChild(RenderBox* child, LayoutUnit logicalOffset, bool includeMargins) 4254 LayoutUnit RenderBlock::adjustForUnsplittableChild(RenderBox* child, LayoutUnit logicalOffset, bool includeMargins)
5291 { 4255 {
5292 bool checkColumnBreaks = view()->layoutState()->isPaginatingColumns(); 4256 bool checkPageBreaks = view()->layoutState()->m_pageLogicalHeight;
5293 bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->m_pageLo gicalHeight;
5294 RenderFlowThread* flowThread = flowThreadContainingBlock(); 4257 RenderFlowThread* flowThread = flowThreadContainingBlock();
5295 bool checkRegionBreaks = flowThread && flowThread->isRenderNamedFlowThread() ; 4258 bool checkRegionBreaks = flowThread && flowThread->isRenderNamedFlowThread() ;
5296 bool isUnsplittable = child->isUnsplittableForPagination() || (checkColumnBr eaks && child->style()->columnBreakInside() == PBAVOID) 4259 bool isUnsplittable = child->isUnsplittableForPagination()
5297 || (checkPageBreaks && child->style()->pageBreakInside() == PBAVOID) 4260 || (checkPageBreaks && child->style()->pageBreakInside() == PBAVOID)
5298 || (checkRegionBreaks && child->style()->regionBreakInside() == PBAVOID) ; 4261 || (checkRegionBreaks && child->style()->regionBreakInside() == PBAVOID) ;
5299 if (!isUnsplittable) 4262 if (!isUnsplittable)
5300 return logicalOffset; 4263 return logicalOffset;
5301 LayoutUnit childLogicalHeight = logicalHeightForChild(child) + (includeMargi ns ? marginBeforeForChild(child) + marginAfterForChild(child) : LayoutUnit()); 4264 LayoutUnit childLogicalHeight = logicalHeightForChild(child) + (includeMargi ns ? marginBeforeForChild(child) + marginAfterForChild(child) : LayoutUnit());
5302 LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset); 4265 LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset);
5303 bool hasUniformPageLogicalHeight = !flowThread || flowThread->regionsHaveUni formLogicalHeight(); 4266 bool hasUniformPageLogicalHeight = !flowThread || flowThread->regionsHaveUni formLogicalHeight();
5304 updateMinimumPageHeight(logicalOffset, childLogicalHeight); 4267 updateMinimumPageHeight(logicalOffset, childLogicalHeight);
5305 if (!pageLogicalHeight || (hasUniformPageLogicalHeight && childLogicalHeight > pageLogicalHeight) 4268 if (!pageLogicalHeight || (hasUniformPageLogicalHeight && childLogicalHeight > pageLogicalHeight)
5306 || !hasNextPage(logicalOffset)) 4269 || !hasNextPage(logicalOffset))
(...skipping 25 matching lines...) Expand all
5332 void RenderBlock::setPageBreak(LayoutUnit offset, LayoutUnit spaceShortage) 4295 void RenderBlock::setPageBreak(LayoutUnit offset, LayoutUnit spaceShortage)
5333 { 4296 {
5334 if (RenderFlowThread* flowThread = flowThreadContainingBlock()) 4297 if (RenderFlowThread* flowThread = flowThreadContainingBlock())
5335 flowThread->setPageBreak(offsetFromLogicalTopOfFirstPage() + offset, spa ceShortage); 4298 flowThread->setPageBreak(offsetFromLogicalTopOfFirstPage() + offset, spa ceShortage);
5336 } 4299 }
5337 4300
5338 void RenderBlock::updateMinimumPageHeight(LayoutUnit offset, LayoutUnit minHeigh t) 4301 void RenderBlock::updateMinimumPageHeight(LayoutUnit offset, LayoutUnit minHeigh t)
5339 { 4302 {
5340 if (RenderFlowThread* flowThread = flowThreadContainingBlock()) 4303 if (RenderFlowThread* flowThread = flowThreadContainingBlock())
5341 flowThread->updateMinimumPageHeight(offsetFromLogicalTopOfFirstPage() + offset, minHeight); 4304 flowThread->updateMinimumPageHeight(offsetFromLogicalTopOfFirstPage() + offset, minHeight);
5342 else if (ColumnInfo* colInfo = view()->layoutState()->m_columnInfo)
5343 colInfo->updateMinimumColumnHeight(minHeight);
5344 } 4305 }
5345 4306
5346 static inline LayoutUnit calculateMinimumPageHeight(RenderStyle* renderStyle, Ro otInlineBox* lastLine, LayoutUnit lineTop, LayoutUnit lineBottom) 4307 static inline LayoutUnit calculateMinimumPageHeight(RenderStyle* renderStyle, Ro otInlineBox* lastLine, LayoutUnit lineTop, LayoutUnit lineBottom)
5347 { 4308 {
5348 // We may require a certain minimum number of lines per page in order to sat isfy 4309 // We may require a certain minimum number of lines per page in order to sat isfy
5349 // orphans and widows, and that may affect the minimum page height. 4310 // orphans and widows, and that may affect the minimum page height.
5350 unsigned lineCount = max<unsigned>(renderStyle->hasAutoOrphans() ? 1 : rende rStyle->orphans(), renderStyle->hasAutoWidows() ? 1 : renderStyle->widows()); 4311 unsigned lineCount = max<unsigned>(renderStyle->hasAutoOrphans() ? 1 : rende rStyle->orphans(), renderStyle->hasAutoWidows() ? 1 : renderStyle->widows());
5351 if (lineCount > 1) { 4312 if (lineCount > 1) {
5352 RootInlineBox* line = lastLine; 4313 RootInlineBox* line = lastLine;
5353 for (unsigned i = 1; i < lineCount && line->prevRootBox(); i++) 4314 for (unsigned i = 1; i < lineCount && line->prevRootBox(); i++)
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
5594 4555
5595 const char* RenderBlock::renderName() const 4556 const char* RenderBlock::renderName() const
5596 { 4557 {
5597 if (isBody()) 4558 if (isBody())
5598 return "RenderBody"; // FIXME: Temporary hack until we know that the reg ression tests pass. 4559 return "RenderBody"; // FIXME: Temporary hack until we know that the reg ression tests pass.
5599 4560
5600 if (isFloating()) 4561 if (isFloating())
5601 return "RenderBlock (floating)"; 4562 return "RenderBlock (floating)";
5602 if (isOutOfFlowPositioned()) 4563 if (isOutOfFlowPositioned())
5603 return "RenderBlock (positioned)"; 4564 return "RenderBlock (positioned)";
5604 if (isAnonymousColumnsBlock())
5605 return "RenderBlock (anonymous multi-column)";
5606 if (isAnonymousColumnSpanBlock())
5607 return "RenderBlock (anonymous multi-column span)";
5608 if (isAnonymousBlock()) 4565 if (isAnonymousBlock())
5609 return "RenderBlock (anonymous)"; 4566 return "RenderBlock (anonymous)";
5610 // FIXME: Temporary hack while the new generated content system is being imp lemented. 4567 // FIXME: Temporary hack while the new generated content system is being imp lemented.
5611 if (isPseudoElement()) 4568 if (isPseudoElement())
5612 return "RenderBlock (generated)"; 4569 return "RenderBlock (generated)";
5613 if (isAnonymous()) 4570 if (isAnonymous())
5614 return "RenderBlock (generated)"; 4571 return "RenderBlock (generated)";
5615 if (isRelPositioned()) 4572 if (isRelPositioned())
5616 return "RenderBlock (relative positioned)"; 4573 return "RenderBlock (relative positioned)";
5617 if (isStickyPositioned()) 4574 if (isStickyPositioned())
(...skipping 16 matching lines...) Expand all
5634 } else { 4591 } else {
5635 newBox = RenderBlockFlow::createAnonymous(&parent->document()); 4592 newBox = RenderBlockFlow::createAnonymous(&parent->document());
5636 newDisplay = BLOCK; 4593 newDisplay = BLOCK;
5637 } 4594 }
5638 4595
5639 RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay( parent->style(), newDisplay); 4596 RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay( parent->style(), newDisplay);
5640 newBox->setStyle(newStyle.release()); 4597 newBox->setStyle(newStyle.release());
5641 return newBox; 4598 return newBox;
5642 } 4599 }
5643 4600
5644 RenderBlockFlow* RenderBlock::createAnonymousColumnsWithParentRenderer(const Ren derObject* parent)
5645 {
5646 RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay( parent->style(), BLOCK);
5647 newStyle->inheritColumnPropertiesFrom(parent->style());
5648
5649 RenderBlockFlow* newBox = RenderBlockFlow::createAnonymous(&parent->document ());
5650 newBox->setStyle(newStyle.release());
5651 return newBox;
5652 }
5653
5654 RenderBlockFlow* RenderBlock::createAnonymousColumnSpanWithParentRenderer(const RenderObject* parent)
5655 {
5656 RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay( parent->style(), BLOCK);
5657 newStyle->setColumnSpan(ColumnSpanAll);
5658
5659 RenderBlockFlow* newBox = RenderBlockFlow::createAnonymous(&parent->document ());
5660 newBox->setStyle(newStyle.release());
5661 return newBox;
5662 }
5663
5664 #ifndef NDEBUG 4601 #ifndef NDEBUG
5665 void RenderBlock::checkPositionedObjectsNeedLayout() 4602 void RenderBlock::checkPositionedObjectsNeedLayout()
5666 { 4603 {
5667 if (!gPositionedDescendantsMap) 4604 if (!gPositionedDescendantsMap)
5668 return; 4605 return;
5669 4606
5670 if (TrackedRendererListHashSet* positionedDescendantSet = positionedObjects( )) { 4607 if (TrackedRendererListHashSet* positionedDescendantSet = positionedObjects( )) {
5671 TrackedRendererListHashSet::const_iterator end = positionedDescendantSet ->end(); 4608 TrackedRendererListHashSet::const_iterator end = positionedDescendantSet ->end();
5672 for (TrackedRendererListHashSet::const_iterator it = positionedDescendan tSet->begin(); it != end; ++it) { 4609 for (TrackedRendererListHashSet::const_iterator it = positionedDescendan tSet->begin(); it != end; ++it) {
5673 RenderBox* currBox = *it; 4610 RenderBox* currBox = *it;
5674 ASSERT(!currBox->needsLayout()); 4611 ASSERT(!currBox->needsLayout());
5675 } 4612 }
5676 } 4613 }
5677 } 4614 }
5678 4615
5679 void RenderBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* m arkedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const Render Object* obj) const 4616 void RenderBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* m arkedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const Render Object* obj) const
5680 { 4617 {
5681 showRenderObject(); 4618 showRenderObject();
5682 for (const RootInlineBox* root = firstRootBox(); root; root = root->nextRoot Box()) 4619 for (const RootInlineBox* root = firstRootBox(); root; root = root->nextRoot Box())
5683 root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLa bel2, obj, 1); 4620 root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLa bel2, obj, 1);
5684 } 4621 }
5685 4622
5686 #endif 4623 #endif
5687 4624
5688 } // namespace WebCore 4625 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/rendering/RenderBlock.h ('k') | Source/core/rendering/RenderBlockFlow.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698