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