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

Side by Side Diff: sky/engine/core/rendering/RenderBlock.cpp

Issue 729693003: First step at getting rid of anonymous blocks and continuations. (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Address review comments Created 6 years, 1 month 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 | « sky/engine/core/rendering/RenderBlock.h ('k') | sky/engine/core/rendering/RenderBlockFlow.cpp » ('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 26 matching lines...) Expand all
37 #include "core/rendering/GraphicsContextAnnotator.h" 37 #include "core/rendering/GraphicsContextAnnotator.h"
38 #include "core/rendering/HitTestLocation.h" 38 #include "core/rendering/HitTestLocation.h"
39 #include "core/rendering/HitTestResult.h" 39 #include "core/rendering/HitTestResult.h"
40 #include "core/rendering/InlineIterator.h" 40 #include "core/rendering/InlineIterator.h"
41 #include "core/rendering/InlineTextBox.h" 41 #include "core/rendering/InlineTextBox.h"
42 #include "core/rendering/PaintInfo.h" 42 #include "core/rendering/PaintInfo.h"
43 #include "core/rendering/RenderFlexibleBox.h" 43 #include "core/rendering/RenderFlexibleBox.h"
44 #include "core/rendering/RenderInline.h" 44 #include "core/rendering/RenderInline.h"
45 #include "core/rendering/RenderLayer.h" 45 #include "core/rendering/RenderLayer.h"
46 #include "core/rendering/RenderObjectInlines.h" 46 #include "core/rendering/RenderObjectInlines.h"
47 #include "core/rendering/RenderParagraph.h"
47 #include "core/rendering/RenderView.h" 48 #include "core/rendering/RenderView.h"
48 #include "core/rendering/style/RenderStyle.h" 49 #include "core/rendering/style/RenderStyle.h"
49 #include "platform/geometry/FloatQuad.h" 50 #include "platform/geometry/FloatQuad.h"
50 #include "platform/geometry/TransformState.h" 51 #include "platform/geometry/TransformState.h"
51 #include "platform/graphics/GraphicsContextCullSaver.h" 52 #include "platform/graphics/GraphicsContextCullSaver.h"
52 #include "platform/graphics/GraphicsContextStateSaver.h" 53 #include "platform/graphics/GraphicsContextStateSaver.h"
53 #include "wtf/StdLibExtras.h" 54 #include "wtf/StdLibExtras.h"
54 #include "wtf/TemporaryChange.h" 55 #include "wtf/TemporaryChange.h"
55 56
56 using namespace WTF; 57 using namespace WTF;
(...skipping 23 matching lines...) Expand all
80 static DelayedUpdateScrollInfoSet* gDelayedUpdateScrollInfoSet = 0; 81 static DelayedUpdateScrollInfoSet* gDelayedUpdateScrollInfoSet = 0;
81 82
82 RenderBlock::RenderBlock(ContainerNode* node) 83 RenderBlock::RenderBlock(ContainerNode* node)
83 : RenderBox(node) 84 : RenderBox(node)
84 , m_hasMarginBeforeQuirk(false) 85 , m_hasMarginBeforeQuirk(false)
85 , m_hasMarginAfterQuirk(false) 86 , m_hasMarginAfterQuirk(false)
86 , m_beingDestroyed(false) 87 , m_beingDestroyed(false)
87 , m_hasMarkupTruncation(false) 88 , m_hasMarkupTruncation(false)
88 , m_hasBorderOrPaddingLogicalWidthChanged(false) 89 , m_hasBorderOrPaddingLogicalWidthChanged(false)
89 { 90 {
90 // RenderBlockFlow calls setChildrenInline(true).
91 // By default, subclasses do not have inline children.
92 } 91 }
93 92
94 static void removeBlockFromDescendantAndContainerMaps(RenderBlock* block, Tracke dDescendantsMap*& descendantMap, TrackedContainerMap*& containerMap) 93 static void removeBlockFromDescendantAndContainerMaps(RenderBlock* block, Tracke dDescendantsMap*& descendantMap, TrackedContainerMap*& containerMap)
95 { 94 {
96 if (OwnPtr<TrackedRendererListHashSet> descendantSet = descendantMap->take(b lock)) { 95 if (OwnPtr<TrackedRendererListHashSet> descendantSet = descendantMap->take(b lock)) {
97 TrackedRendererListHashSet::iterator end = descendantSet->end(); 96 TrackedRendererListHashSet::iterator end = descendantSet->end();
98 for (TrackedRendererListHashSet::iterator descendant = descendantSet->be gin(); descendant != end; ++descendant) { 97 for (TrackedRendererListHashSet::iterator descendant = descendantSet->be gin(); descendant != end; ++descendant) {
99 TrackedContainerMap::iterator it = containerMap->find(*descendant); 98 TrackedContainerMap::iterator it = containerMap->find(*descendant);
100 ASSERT(it != containerMap->end()); 99 ASSERT(it != containerMap->end());
101 if (it == containerMap->end()) 100 if (it == containerMap->end())
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
435 434
436 // Now take all the children after currChild and remove them from the fromBl ock 435 // Now take all the children after currChild and remove them from the fromBl ock
437 // and put them in the toBlock. 436 // and put them in the toBlock.
438 fromBlock->moveChildrenTo(toBlock, currChildNextSibling, 0, true); 437 fromBlock->moveChildrenTo(toBlock, currChildNextSibling, 0, true);
439 } 438 }
440 439
441 void RenderBlock::addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild) 440 void RenderBlock::addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild)
442 { 441 {
443 if (beforeChild && beforeChild->parent() != this) { 442 if (beforeChild && beforeChild->parent() != this) {
444 RenderObject* beforeChildContainer = beforeChild->parent(); 443 RenderObject* beforeChildContainer = beforeChild->parent();
445 while (beforeChildContainer->parent() != this) 444 ASSERT(beforeChildContainer->parent() == this);
446 beforeChildContainer = beforeChildContainer->parent(); 445 ASSERT(beforeChildContainer->isAnonymousBlock());
447 ASSERT(beforeChildContainer); 446 addChild(newChild, beforeChildContainer);
448 447 return;
449 if (beforeChildContainer->isAnonymous()) {
450 // If the requested beforeChild is not one of our children, then thi s is because
451 // there is an anonymous container within this object that contains the beforeChild.
452 RenderObject* beforeChildAnonymousContainer = beforeChildContainer;
453 if (beforeChildAnonymousContainer->isAnonymousBlock()
454 // Full screen renderers and full screen placeholders act as ano nymous blocks, not tables:
455 ) {
456 // Insert the child into the anonymous block box instead of here .
457 if (newChild->isInline() || newChild->isFloatingOrOutOfFlowPosit ioned() || beforeChild->parent()->slowFirstChild() != beforeChild)
458 beforeChild->parent()->addChild(newChild, beforeChild);
459 else
460 addChild(newChild, beforeChild->parent());
461 return;
462 }
463
464 // This used to ASSERT(beforeChildAnonymousContainer->isTable());
465 ASSERT_NOT_REACHED();
466 }
467 } 448 }
468 449
469 bool madeBoxesNonInline = false; 450 // TODO(ojan): What should we do in this case? For now we insert an anonymou s paragraph.
470 451 // This only happens if we have a text node directly inside a non-paragraph.
471 // A block has to either have all of its children inline, or all of its chil dren as blocks. 452 if (!childrenInline() && newChild->isInline()) {
472 // So, if our children are currently inline and a block child has to be inse rted, we move all our 453 RenderBlock* newBox = createAnonymousBlock();
473 // inline children into anonymous block boxes. 454 ASSERT(newBox->childrenInline());
474 if (childrenInline() && !newChild->isInline() && !newChild->isFloatingOrOutO fFlowPositioned()) { 455 RenderBox::addChild(newBox, beforeChild);
475 // This is a block with inline content. Wrap the inline content in anony mous blocks. 456 newBox->addChild(newChild);
476 makeChildrenNonInline(beforeChild); 457 return;
477 madeBoxesNonInline = true;
478
479 if (beforeChild && beforeChild->parent() != this) {
480 beforeChild = beforeChild->parent();
481 ASSERT(beforeChild->isAnonymousBlock());
482 ASSERT(beforeChild->parent() == this);
483 }
484 } else if (!childrenInline() && (newChild->isFloatingOrOutOfFlowPositioned() || newChild->isInline())) {
485 // If we're inserting an inline child but all of our children are blocks , then we have to make sure
486 // it is put into an anomyous block box. We try to use an existing anony mous box if possible, otherwise
487 // a new one is created and inserted into our list of children in the ap propriate position.
488 RenderObject* afterChild = beforeChild ? beforeChild->previousSibling() : lastChild();
489
490 if (afterChild && afterChild->isAnonymousBlock()) {
491 afterChild->addChild(newChild);
492 return;
493 }
494
495 if (newChild->isInline()) {
496 // No suitable existing anonymous box - create a new one.
497 RenderBlock* newBox = createAnonymousBlock();
498 RenderBox::addChild(newBox, beforeChild);
499 newBox->addChild(newChild);
500 return;
501 }
502 } 458 }
503 459
504 RenderBox::addChild(newChild, beforeChild); 460 RenderBox::addChild(newChild, beforeChild);
505
506 if (madeBoxesNonInline && parent() && isAnonymousBlock() && parent()->isRend erBlock())
507 toRenderBlock(parent())->removeLeftoverAnonymousBlock(this);
508 // this object may be dead here
509 } 461 }
510 462
511 void RenderBlock::addChild(RenderObject* newChild, RenderObject* beforeChild) 463 void RenderBlock::addChild(RenderObject* newChild, RenderObject* beforeChild)
512 { 464 {
513 if (continuation() && !isAnonymousBlock()) 465 if (continuation() && !isAnonymousBlock())
514 addChildToContinuation(newChild, beforeChild); 466 addChildToContinuation(newChild, beforeChild);
515 else 467 else
516 addChildIgnoringContinuation(newChild, beforeChild); 468 addChildIgnoringContinuation(newChild, beforeChild);
517 } 469 }
518 470
519 void RenderBlock::addChildIgnoringContinuation(RenderObject* newChild, RenderObj ect* beforeChild) 471 void RenderBlock::addChildIgnoringContinuation(RenderObject* newChild, RenderObj ect* beforeChild)
520 { 472 {
521 addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild); 473 addChildIgnoringAnonymousColumnBlocks(newChild, beforeChild);
522 } 474 }
523 475
524 static void getInlineRun(RenderObject* start, RenderObject* boundary,
525 RenderObject*& inlineRunStart,
526 RenderObject*& inlineRunEnd)
527 {
528 // Beginning at |start| we find the largest contiguous run of inlines that
529 // we can. We denote the run with start and end points, |inlineRunStart|
530 // and |inlineRunEnd|. Note that these two values may be the same if
531 // we encounter only one inline.
532 //
533 // We skip any non-inlines we encounter as long as we haven't found any
534 // inlines yet.
535 //
536 // |boundary| indicates a non-inclusive boundary point. Regardless of wheth er |boundary|
537 // is inline or not, we will not include it in a run with inlines before it. It's as though we encountered
538 // a non-inline.
539
540 // Start by skipping as many non-inlines as we can.
541 RenderObject * curr = start;
542 bool sawInline;
543 do {
544 while (curr && !(curr->isInline() || curr->isFloatingOrOutOfFlowPosition ed()))
545 curr = curr->nextSibling();
546
547 inlineRunStart = inlineRunEnd = curr;
548
549 if (!curr)
550 return; // No more inline children to be found.
551
552 sawInline = curr->isInline();
553
554 curr = curr->nextSibling();
555 while (curr && (curr->isInline() || curr->isFloatingOrOutOfFlowPositione d()) && (curr != boundary)) {
556 inlineRunEnd = curr;
557 if (curr->isInline())
558 sawInline = true;
559 curr = curr->nextSibling();
560 }
561 } while (!sawInline);
562 }
563
564 void RenderBlock::deleteLineBoxTree() 476 void RenderBlock::deleteLineBoxTree()
565 { 477 {
566 ASSERT(!m_lineBoxes.firstLineBox()); 478 ASSERT(!m_lineBoxes.firstLineBox());
567 } 479 }
568 480
569 void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint) 481 void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint)
570 { 482 {
571 // makeChildrenNonInline takes a block whose children are *all* inline and i t 483 ASSERT_NOT_REACHED();
572 // makes sure that inline children are coalesced under anonymous 484 // FIXME(sky): Remove
573 // blocks. If |insertionPoint| is defined, then it represents the insertion point for
574 // the new block child that is causing us to have to wrap all the inlines. This
575 // means that we cannot coalesce inlines before |insertionPoint| with inline s following
576 // |insertionPoint|, because the new child is going to be inserted in betwee n the inlines,
577 // splitting them.
578 ASSERT(isInlineBlock() || !isInline());
579 ASSERT(!insertionPoint || insertionPoint->parent() == this);
580
581 setChildrenInline(false);
582
583 RenderObject *child = firstChild();
584 if (!child)
585 return;
586
587 deleteLineBoxTree();
588
589 while (child) {
590 RenderObject *inlineRunStart, *inlineRunEnd;
591 getInlineRun(child, insertionPoint, inlineRunStart, inlineRunEnd);
592
593 if (!inlineRunStart)
594 break;
595
596 child = inlineRunEnd->nextSibling();
597
598 RenderBlock* block = createAnonymousBlock();
599 children()->insertChildNode(this, block, inlineRunStart);
600 moveChildrenTo(block, inlineRunStart, child);
601 }
602
603 #if ENABLE(ASSERT)
604 for (RenderObject *c = firstChild(); c; c = c->nextSibling())
605 ASSERT(!c->isInline());
606 #endif
607
608 setShouldDoFullPaintInvalidation(true);
609 }
610
611 void RenderBlock::removeLeftoverAnonymousBlock(RenderBlock* child)
612 {
613 ASSERT(child->isAnonymousBlock());
614 ASSERT(!child->childrenInline());
615
616 if (child->continuation())
617 return;
618
619 RenderObject* firstAnChild = child->m_children.firstChild();
620 RenderObject* lastAnChild = child->m_children.lastChild();
621 if (firstAnChild) {
622 RenderObject* o = firstAnChild;
623 while (o) {
624 o->setParent(this);
625 o = o->nextSibling();
626 }
627 firstAnChild->setPreviousSibling(child->previousSibling());
628 lastAnChild->setNextSibling(child->nextSibling());
629 if (child->previousSibling())
630 child->previousSibling()->setNextSibling(firstAnChild);
631 if (child->nextSibling())
632 child->nextSibling()->setPreviousSibling(lastAnChild);
633
634 if (child == m_children.firstChild())
635 m_children.setFirstChild(firstAnChild);
636 if (child == m_children.lastChild())
637 m_children.setLastChild(lastAnChild);
638 } else {
639 if (child == m_children.firstChild())
640 m_children.setFirstChild(child->nextSibling());
641 if (child == m_children.lastChild())
642 m_children.setLastChild(child->previousSibling());
643
644 if (child->previousSibling())
645 child->previousSibling()->setNextSibling(child->nextSibling());
646 if (child->nextSibling())
647 child->nextSibling()->setPreviousSibling(child->previousSibling());
648 }
649
650 child->children()->setFirstChild(0);
651 child->m_next = nullptr;
652
653 child->setParent(0);
654 child->setPreviousSibling(0);
655 child->setNextSibling(0);
656
657 child->destroy();
658 } 485 }
659 486
660 static bool canMergeContiguousAnonymousBlocks(RenderObject* oldChild, RenderObje ct* prev, RenderObject* next) 487 static bool canMergeContiguousAnonymousBlocks(RenderObject* oldChild, RenderObje ct* prev, RenderObject* next)
661 { 488 {
662 if (oldChild->documentBeingDestroyed() || oldChild->isInline() || oldChild-> virtualContinuation()) 489 if (oldChild->documentBeingDestroyed() || oldChild->isInline() || oldChild-> virtualContinuation())
663 return false; 490 return false;
664 491
665 if ((prev && (!prev->isAnonymousBlock() || toRenderBlock(prev)->continuation () || toRenderBlock(prev)->beingDestroyed())) 492 if ((prev && (!prev->isAnonymousBlock() || toRenderBlock(prev)->continuation () || toRenderBlock(prev)->beingDestroyed()))
666 || (next && (!next->isAnonymousBlock() || toRenderBlock(next)->continuat ion() || toRenderBlock(next)->beingDestroyed()))) 493 || (next && (!next->isAnonymousBlock() || toRenderBlock(next)->continuat ion() || toRenderBlock(next)->beingDestroyed())))
667 return false; 494 return false;
(...skipping 1934 matching lines...) Expand 10 before | Expand all | Expand 10 after
2602 return r; 2429 return r;
2603 } 2430 }
2604 2431
2605 RenderObject* RenderBlock::hoverAncestor() const 2432 RenderObject* RenderBlock::hoverAncestor() const
2606 { 2433 {
2607 return isAnonymousBlockContinuation() ? continuation() : RenderBox::hoverAnc estor(); 2434 return isAnonymousBlockContinuation() ? continuation() : RenderBox::hoverAnc estor();
2608 } 2435 }
2609 2436
2610 void RenderBlock::childBecameNonInline(RenderObject*) 2437 void RenderBlock::childBecameNonInline(RenderObject*)
2611 { 2438 {
2612 makeChildrenNonInline(); 2439 ASSERT_NOT_REACHED();
2613 if (isAnonymousBlock() && parent() && parent()->isRenderBlock()) 2440 // FIXME(sky): Remove
2614 toRenderBlock(parent())->removeLeftoverAnonymousBlock(this);
2615 // |this| may be dead here
2616 } 2441 }
2617 2442
2618 void RenderBlock::updateHitTestResult(HitTestResult& result, const LayoutPoint& point) 2443 void RenderBlock::updateHitTestResult(HitTestResult& result, const LayoutPoint& point)
2619 { 2444 {
2620 if (result.innerNode()) 2445 if (result.innerNode())
2621 return; 2446 return;
2622 2447
2623 if (Node* n = nodeForHitTest()) { 2448 if (Node* n = nodeForHitTest()) {
2624 result.setInnerNode(n); 2449 result.setInnerNode(n);
2625 if (!result.innerNonSharedNode()) 2450 if (!result.innerNonSharedNode())
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
2712 return "RenderBlock (positioned)"; 2537 return "RenderBlock (positioned)";
2713 if (isAnonymousBlock()) 2538 if (isAnonymousBlock())
2714 return "RenderBlock (anonymous)"; 2539 return "RenderBlock (anonymous)";
2715 if (isAnonymous()) 2540 if (isAnonymous())
2716 return "RenderBlock (generated)"; 2541 return "RenderBlock (generated)";
2717 if (isRelPositioned()) 2542 if (isRelPositioned())
2718 return "RenderBlock (relative positioned)"; 2543 return "RenderBlock (relative positioned)";
2719 return "RenderBlock"; 2544 return "RenderBlock";
2720 } 2545 }
2721 2546
2722 RenderBlock* RenderBlock::createAnonymousWithParentRendererAndDisplay(const Rend erObject* parent, EDisplay display) 2547 // FIXME(sky): Clean up callers now that we no longer use the EDisplay argument.
2548 RenderBlock* RenderBlock::createAnonymousWithParentRendererAndDisplay(const Rend erObject* parent, EDisplay)
2723 { 2549 {
2724 // FIXME: Do we need to convert all our inline displays to block-type in the anonymous logic ? 2550 RenderBlock* newBox = RenderParagraph::createAnonymous(parent->document());
2725 EDisplay newDisplay; 2551 RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay( parent->style(), PARAGRAPH);
2726 RenderBlock* newBox = 0;
2727 if (display == FLEX || display == INLINE_FLEX) {
2728 newBox = RenderFlexibleBox::createAnonymous(&parent->document());
2729 newDisplay = FLEX;
2730 } else {
2731 newBox = RenderBlockFlow::createAnonymous(&parent->document());
2732 newDisplay = BLOCK;
2733 }
2734
2735 RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay( parent->style(), newDisplay);
2736 parent->updateAnonymousChildStyle(newBox, newStyle.get()); 2552 parent->updateAnonymousChildStyle(newBox, newStyle.get());
2737 newBox->setStyle(newStyle.release()); 2553 newBox->setStyle(newStyle.release());
2738 return newBox; 2554 return newBox;
2739 } 2555 }
2740 2556
2741 static bool recalcNormalFlowChildOverflowIfNeeded(RenderObject* renderer) 2557 static bool recalcNormalFlowChildOverflowIfNeeded(RenderObject* renderer)
2742 { 2558 {
2743 if (renderer->isOutOfFlowPositioned() || !renderer->needsOverflowRecalcAfter StyleChange()) 2559 if (renderer->isOutOfFlowPositioned() || !renderer->needsOverflowRecalcAfter StyleChange())
2744 return false; 2560 return false;
2745 2561
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
2845 void RenderBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* m arkedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const Render Object* obj) const 2661 void RenderBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* m arkedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const Render Object* obj) const
2846 { 2662 {
2847 showRenderObject(); 2663 showRenderObject();
2848 for (const RootInlineBox* root = firstRootBox(); root; root = root->nextRoot Box()) 2664 for (const RootInlineBox* root = firstRootBox(); root; root = root->nextRoot Box())
2849 root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLa bel2, obj, 1); 2665 root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLa bel2, obj, 1);
2850 } 2666 }
2851 2667
2852 #endif 2668 #endif
2853 2669
2854 } // namespace blink 2670 } // namespace blink
OLDNEW
« no previous file with comments | « sky/engine/core/rendering/RenderBlock.h ('k') | sky/engine/core/rendering/RenderBlockFlow.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698