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

Side by Side Diff: WebCore/rendering/RenderRubyBase.cpp

Issue 554075: Merge 53525 - Bug 33266 WebCore::InlineFlowBox::determineSpacingForFlowBoxes... (Closed) Base URL: svn://chrome-svn/chrome/branches/WebKit/249s/
Patch Set: Created 10 years, 11 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 | Annotate | Revision Log
« no previous file with comments | « WebCore/rendering/RenderRubyBase.h ('k') | WebCore/rendering/RenderRubyRun.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) 2009 Google Inc. All rights reserved. 2 * Copyright (C) 2009 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 30 matching lines...) Expand all
41 41
42 RenderRubyBase::~RenderRubyBase() 42 RenderRubyBase::~RenderRubyBase()
43 { 43 {
44 } 44 }
45 45
46 bool RenderRubyBase::isChildAllowed(RenderObject* child, RenderStyle*) const 46 bool RenderRubyBase::isChildAllowed(RenderObject* child, RenderStyle*) const
47 { 47 {
48 return child->isInline(); 48 return child->isInline();
49 } 49 }
50 50
51 void RenderRubyBase::splitToLeft(RenderBlock* leftBase, RenderObject* beforeChil d) 51 bool RenderRubyBase::hasOnlyWrappedInlineChildren(RenderObject* beforeChild) con st
52 {
53 // Tests whether all children in the base before beforeChild are either floa ted/positioned,
54 // or inline objects wrapped in anonymous blocks.
55 // Note that beforeChild may be 0, in which case all children are looked at.
56 for (RenderObject* child = firstChild(); child != beforeChild; child = child ->nextSibling()) {
57 if (!child->isFloatingOrPositioned() && !(child->isAnonymousBlock() && c hild->childrenInline()))
58 return false;
59 }
60 return true;
61 }
62
63 void RenderRubyBase::moveChildren(RenderRubyBase* toBase, RenderObject* fromBefo reChild)
52 { 64 {
53 // This function removes all children that are before (!) beforeChild 65 // This function removes all children that are before (!) beforeChild
54 // and appends them to leftBase. 66 // and appends them to toBase.
55 ASSERT(leftBase); 67 ASSERT(toBase);
68
69 // First make sure that beforeChild (if set) is indeed a direct child of thi s.
70 // Inline children might be wrapped in an anonymous block if there's a conti nuation.
71 // Theoretically, in ruby bases, this can happen with only the first such a child,
72 // so it should be OK to just climb the tree.
73 while (fromBeforeChild && fromBeforeChild->parent() != this)
74 fromBeforeChild = fromBeforeChild->parent();
56 75
57 // First make sure that beforeChild (if set) is indeed a direct child of thi s. 76 if (childrenInline())
58 // Fallback: climb up the tree to make sure. This may result in somewhat inc orrect rendering. 77 moveInlineChildren(toBase, fromBeforeChild);
59 // FIXME: Can this happen? Is there a better/more correct way to solve this? 78 else
60 ASSERT(!beforeChild || beforeChild->parent() == this); 79 moveBlockChildren(toBase, fromBeforeChild);
61 while (beforeChild && beforeChild->parent() != this)
62 beforeChild = beforeChild->parent();
63 80
64 RenderObject* child = firstChild(); 81 setNeedsLayoutAndPrefWidthsRecalc();
65 while (child != beforeChild) { 82 toBase->setNeedsLayoutAndPrefWidthsRecalc();
66 RenderObject* nextChild = child->nextSibling();
67 moveChildTo(leftBase, leftBase->children(), child);
68 child = nextChild;
69 }
70 } 83 }
71 84
72 void RenderRubyBase::mergeWithRight(RenderBlock* rightBase) 85 void RenderRubyBase::moveInlineChildren(RenderRubyBase* toBase, RenderObject* fr omBeforeChild)
73 { 86 {
74 // This function removes all children and prepends (!) them to rightBase. 87 RenderBlock* toBlock;
75 ASSERT(rightBase);
76 88
77 RenderObject* firstPos = rightBase->firstChild(); 89 if (toBase->childrenInline()) {
78 RenderObject* child = lastChild(); 90 // The standard and easy case: move the children into the target base
79 while (child) { 91 toBlock = toBase;
80 moveChildTo(rightBase, rightBase->children(), firstPos, child); 92 } else {
81 firstPos = child; 93 // We need to wrap the inline objects into an anonymous block.
82 child = lastChild(); 94 // If toBase has a suitable block, we re-use it, otherwise create a new one.
95 RenderObject* lastChild = toBase->lastChild();
96 if (lastChild && lastChild->isAnonymousBlock() && lastChild->childrenInl ine())
97 toBlock = toRenderBlock(lastChild);
98 else {
99 toBlock = toBase->createAnonymousBlock();
100 toBase->children()->appendChildNode(toBase, toBlock);
101 }
83 } 102 }
103 // Move our inline children into the target block we determined above.
104 for (RenderObject* child = firstChild(); child != fromBeforeChild; child = f irstChild())
105 moveChildTo(toBlock, toBlock->children(), child);
106 }
107
108 void RenderRubyBase::moveBlockChildren(RenderRubyBase* toBase, RenderObject* fro mBeforeChild)
109 {
110 if (toBase->childrenInline()) {
111 // First check whether we move only wrapped inline objects.
112 if (hasOnlyWrappedInlineChildren(fromBeforeChild)) {
113 // The reason why the base is in block flow must be after beforeChil d.
114 // We therefore can extract the inline objects and move them to toBa se.
115 for (RenderObject* child = firstChild(); child != fromBeforeChild; c hild = firstChild()) {
116 if (child->isAnonymousBlock()) {
117 RenderBlock* anonBlock = toRenderBlock(child);
118 ASSERT(anonBlock->childrenInline());
119 ASSERT(!anonBlock->inlineContinuation());
120 anonBlock->moveAllChildrenTo(toBase, toBase->children());
121 anonBlock->deleteLineBoxTree();
122 anonBlock->destroy();
123 } else {
124 ASSERT(child->isFloatingOrPositioned());
125 moveChildTo(toBase, toBase->children(), child);
126 }
127 }
128 } else {
129 // Moving block children -> have to set toBase as block flow
130 toBase->makeChildrenNonInline();
131 // Move children, potentially collapsing anonymous block wrappers.
132 mergeBlockChildren(toBase, fromBeforeChild);
133
134 // Now we need to check if the leftover children are all inline.
135 // If so, make this base inline again.
136 if (hasOnlyWrappedInlineChildren()) {
137 RenderObject* next = 0;
138 for (RenderObject* child = firstChild(); child; child = next) {
139 next = child->nextSibling();
140 if (child->isFloatingOrPositioned())
141 continue;
142 ASSERT(child->isAnonymousBlock());
143
144 RenderBlock* anonBlock = toRenderBlock(child);
145 ASSERT(anonBlock->childrenInline());
146 ASSERT(!anonBlock->inlineContinuation());
147 // Move inline children out of anonymous block.
148 anonBlock->moveAllChildrenTo(this, children(), anonBlock);
149 anonBlock->deleteLineBoxTree();
150 anonBlock->destroy();
151 }
152 setChildrenInline(true);
153 }
154 }
155 } else
156 mergeBlockChildren(toBase, fromBeforeChild);
157 }
158
159 void RenderRubyBase::mergeBlockChildren(RenderRubyBase* toBase, RenderObject* fr omBeforeChild)
160 {
161 // This function removes all children that are before fromBeforeChild and ap pends them to toBase.
162 ASSERT(!childrenInline());
163 ASSERT(toBase);
164 ASSERT(!toBase->childrenInline());
165
166 // Quick check whether we have anything to do, to simplify the following cod e.
167 if (fromBeforeChild != firstChild())
168 return;
169
170 // If an anonymous block would be put next to another such block, then merge those.
171 RenderObject* firstChildHere = firstChild();
172 RenderObject* lastChildThere = toBase->lastChild();
173 if (firstChildHere && firstChildHere->isAnonymousBlock() && firstChildHere-> childrenInline()
174 && lastChildThere && lastChildThere->isAnonymousBlock() && lastChild There->childrenInline()) {
175 RenderBlock* anonBlockHere = toRenderBlock(firstChildHere);
176 RenderBlock* anonBlockThere = toRenderBlock(lastChildThere);
177 anonBlockHere->moveAllChildrenTo(anonBlockThere, anonBlockThere->childre n());
178 anonBlockHere->deleteLineBoxTree();
179 anonBlockHere->destroy();
180 }
181 // Move all remaining children normally.
182 for (RenderObject* child = firstChild(); child != fromBeforeChild; child = f irstChild())
183 moveChildTo(toBase, toBase->children(), child);
84 } 184 }
85 185
86 } // namespace WebCore 186 } // namespace WebCore
OLDNEW
« no previous file with comments | « WebCore/rendering/RenderRubyBase.h ('k') | WebCore/rendering/RenderRubyRun.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698