| 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 |