OLD | NEW |
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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 | 46 |
47 RenderRubyBase::~RenderRubyBase() | 47 RenderRubyBase::~RenderRubyBase() |
48 { | 48 { |
49 } | 49 } |
50 | 50 |
51 bool RenderRubyBase::isChildAllowed(RenderObject* child, RenderStyle*) const | 51 bool RenderRubyBase::isChildAllowed(RenderObject* child, RenderStyle*) const |
52 { | 52 { |
53 return child->isInline(); | 53 return child->isInline(); |
54 } | 54 } |
55 | 55 |
56 bool RenderRubyBase::hasOnlyWrappedInlineChildren(RenderObject* beforeChild) con
st | |
57 { | |
58 // Tests whether all children in the base before beforeChild are either floa
ted/positioned, | |
59 // or inline objects wrapped in anonymous blocks. | |
60 // Note that beforeChild may be 0, in which case all children are looked at. | |
61 for (RenderObject* child = firstChild(); child != beforeChild; child = child
->nextSibling()) { | |
62 if (!child->isFloatingOrPositioned() && !(child->isAnonymousBlock() && c
hild->childrenInline())) | |
63 return false; | |
64 } | |
65 return true; | |
66 } | |
67 | |
68 void RenderRubyBase::moveChildren(RenderRubyBase* toBase, RenderObject* beforeCh
ild) | 56 void RenderRubyBase::moveChildren(RenderRubyBase* toBase, RenderObject* beforeCh
ild) |
69 { | 57 { |
70 // This function removes all children that are before (!) beforeChild | 58 // This function removes all children that are before (!) beforeChild |
71 // and appends them to toBase. | 59 // and appends them to toBase. |
72 ASSERT(toBase); | 60 ASSERT_ARG(toBase, toBase); |
73 | 61 |
74 // First make sure that beforeChild (if set) is indeed a direct child of thi
s. | 62 // First make sure that beforeChild (if set) is indeed a direct child of thi
s. |
75 // Inline children might be wrapped in an anonymous block if there's a conti
nuation. | 63 // Inline children might be wrapped in an anonymous block if there's a conti
nuation. |
76 // Theoretically, in ruby bases, this can happen with only the first such a
child, | 64 // Theoretically, in ruby bases, this can happen with only the first such a
child, |
77 // so it should be OK to just climb the tree. | 65 // so it should be OK to just climb the tree. |
78 while (beforeChild && beforeChild->parent() != this) | 66 while (beforeChild && beforeChild->parent() != this) |
79 beforeChild = beforeChild->parent(); | 67 beforeChild = beforeChild->parent(); |
80 | 68 |
81 if (childrenInline()) | 69 if (childrenInline()) |
82 moveInlineChildren(toBase, beforeChild); | 70 moveInlineChildren(toBase, beforeChild); |
83 else | 71 else |
84 moveBlockChildren(toBase, beforeChild); | 72 moveBlockChildren(toBase, beforeChild); |
85 | 73 |
86 setNeedsLayoutAndPrefWidthsRecalc(); | 74 setNeedsLayoutAndPrefWidthsRecalc(); |
87 toBase->setNeedsLayoutAndPrefWidthsRecalc(); | 75 toBase->setNeedsLayoutAndPrefWidthsRecalc(); |
88 } | 76 } |
89 | 77 |
90 void RenderRubyBase::moveInlineChildren(RenderRubyBase* toBase, RenderObject* be
foreChild) | 78 void RenderRubyBase::moveInlineChildren(RenderRubyBase* toBase, RenderObject* be
foreChild) |
91 { | 79 { |
| 80 ASSERT(childrenInline()); |
| 81 ASSERT_ARG(toBase, toBase); |
| 82 |
| 83 if (!firstChild()) |
| 84 return; |
| 85 |
92 RenderBlock* toBlock; | 86 RenderBlock* toBlock; |
93 | |
94 if (toBase->childrenInline()) { | 87 if (toBase->childrenInline()) { |
95 // The standard and easy case: move the children into the target base | 88 // The standard and easy case: move the children into the target base |
96 toBlock = toBase; | 89 toBlock = toBase; |
97 } else { | 90 } else { |
98 // We need to wrap the inline objects into an anonymous block. | 91 // We need to wrap the inline objects into an anonymous block. |
99 // If toBase has a suitable block, we re-use it, otherwise create a new
one. | 92 // If toBase has a suitable block, we re-use it, otherwise create a new
one. |
100 RenderObject* lastChild = toBase->lastChild(); | 93 RenderObject* lastChild = toBase->lastChild(); |
101 if (lastChild && lastChild->isAnonymousBlock() && lastChild->childrenInl
ine()) | 94 if (lastChild && lastChild->isAnonymousBlock() && lastChild->childrenInl
ine()) |
102 toBlock = toRenderBlock(lastChild); | 95 toBlock = toRenderBlock(lastChild); |
103 else { | 96 else { |
104 toBlock = toBase->createAnonymousBlock(); | 97 toBlock = toBase->createAnonymousBlock(); |
105 toBase->children()->appendChildNode(toBase, toBlock); | 98 toBase->children()->appendChildNode(toBase, toBlock); |
106 } | 99 } |
107 } | 100 } |
108 // Move our inline children into the target block we determined above. | 101 // Move our inline children into the target block we determined above. |
109 moveChildrenTo(toBlock, firstChild(), beforeChild); | 102 moveChildrenTo(toBlock, firstChild(), beforeChild); |
110 } | 103 } |
111 | 104 |
112 void RenderRubyBase::moveBlockChildren(RenderRubyBase* toBase, RenderObject* bef
oreChild) | 105 void RenderRubyBase::moveBlockChildren(RenderRubyBase* toBase, RenderObject* bef
oreChild) |
113 { | 106 { |
114 if (toBase->childrenInline()) { | 107 ASSERT(!childrenInline()); |
115 // First check whether we move only wrapped inline objects. | 108 ASSERT_ARG(toBase, toBase); |
116 if (hasOnlyWrappedInlineChildren(beforeChild)) { | |
117 // The reason why the base is in block flow must be after beforeChil
d. | |
118 // We therefore can extract the inline objects and move them to toBa
se. | |
119 for (RenderObject* child = firstChild(); child != beforeChild; child
= firstChild()) { | |
120 if (child->isAnonymousBlock()) { | |
121 RenderBlock* anonBlock = toRenderBlock(child); | |
122 ASSERT(anonBlock->childrenInline()); | |
123 ASSERT(!anonBlock->inlineElementContinuation()); | |
124 anonBlock->moveAllChildrenTo(toBase, toBase->children()); | |
125 anonBlock->deleteLineBoxTree(); | |
126 anonBlock->destroy(); | |
127 } else { | |
128 ASSERT(child->isFloatingOrPositioned()); | |
129 moveChildTo(toBase, child); | |
130 } | |
131 } | |
132 } else { | |
133 // Moving block children -> have to set toBase as block flow | |
134 toBase->makeChildrenNonInline(); | |
135 // Move children, potentially collapsing anonymous block wrappers. | |
136 mergeBlockChildren(toBase, beforeChild); | |
137 | 109 |
138 // Now we need to check if the leftover children are all inline. | |
139 // If so, make this base inline again. | |
140 if (hasOnlyWrappedInlineChildren()) { | |
141 RenderObject* next = 0; | |
142 for (RenderObject* child = firstChild(); child; child = next) { | |
143 next = child->nextSibling(); | |
144 if (child->isFloatingOrPositioned()) | |
145 continue; | |
146 ASSERT(child->isAnonymousBlock()); | |
147 | |
148 RenderBlock* anonBlock = toRenderBlock(child); | |
149 ASSERT(anonBlock->childrenInline()); | |
150 ASSERT(!anonBlock->inlineElementContinuation()); | |
151 // Move inline children out of anonymous block. | |
152 anonBlock->moveAllChildrenTo(this, anonBlock); | |
153 anonBlock->deleteLineBoxTree(); | |
154 anonBlock->destroy(); | |
155 } | |
156 setChildrenInline(true); | |
157 } | |
158 } | |
159 } else | |
160 mergeBlockChildren(toBase, beforeChild); | |
161 } | |
162 | |
163 void RenderRubyBase::mergeBlockChildren(RenderRubyBase* toBase, RenderObject* be
foreChild) | |
164 { | |
165 // This function removes all children that are before beforeChild and append
s them to toBase. | |
166 ASSERT(!childrenInline()); | |
167 ASSERT(toBase); | |
168 ASSERT(!toBase->childrenInline()); | |
169 | |
170 // Quick check whether we have anything to do, to simplify the following cod
e. | |
171 if (!firstChild()) | 110 if (!firstChild()) |
172 return; | 111 return; |
173 | 112 |
| 113 if (toBase->childrenInline()) |
| 114 toBase->makeChildrenNonInline(); |
| 115 |
174 // If an anonymous block would be put next to another such block, then merge
those. | 116 // If an anonymous block would be put next to another such block, then merge
those. |
175 RenderObject* firstChildHere = firstChild(); | 117 RenderObject* firstChildHere = firstChild(); |
176 RenderObject* lastChildThere = toBase->lastChild(); | 118 RenderObject* lastChildThere = toBase->lastChild(); |
177 if (firstChildHere->isAnonymousBlock() && firstChildHere->childrenInline() | 119 if (firstChildHere->isAnonymousBlock() && firstChildHere->childrenInline() |
178 && lastChildThere && lastChildThere->isAnonymousBlock() && lastChild
There->childrenInline()) { | 120 && lastChildThere && lastChildThere->isAnonymousBlock() && lastChild
There->childrenInline()) { |
179 RenderBlock* anonBlockHere = toRenderBlock(firstChildHere); | 121 RenderBlock* anonBlockHere = toRenderBlock(firstChildHere); |
180 RenderBlock* anonBlockThere = toRenderBlock(lastChildThere); | 122 RenderBlock* anonBlockThere = toRenderBlock(lastChildThere); |
181 anonBlockHere->moveAllChildrenTo(anonBlockThere, anonBlockThere->childre
n()); | 123 anonBlockHere->moveAllChildrenTo(anonBlockThere, anonBlockThere->childre
n()); |
182 anonBlockHere->deleteLineBoxTree(); | 124 anonBlockHere->deleteLineBoxTree(); |
183 anonBlockHere->destroy(); | 125 anonBlockHere->destroy(); |
(...skipping 22 matching lines...) Expand all Loading... |
206 return; | 148 return; |
207 | 149 |
208 // Inset the ruby base by half the inter-ideograph expansion amount. | 150 // Inset the ruby base by half the inter-ideograph expansion amount. |
209 float inset = (logicalWidth - maxPreferredLogicalWidth) / (expansionOpportun
ityCount + 1); | 151 float inset = (logicalWidth - maxPreferredLogicalWidth) / (expansionOpportun
ityCount + 1); |
210 | 152 |
211 logicalLeft += inset / 2; | 153 logicalLeft += inset / 2; |
212 logicalWidth -= inset; | 154 logicalWidth -= inset; |
213 } | 155 } |
214 | 156 |
215 } // namespace WebCore | 157 } // namespace WebCore |
OLD | NEW |