| 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 | 58 |
| 59 bool LayoutRubyRun::hasRubyBase() const | 59 bool LayoutRubyRun::hasRubyBase() const |
| 60 { | 60 { |
| 61 // The only place where a ruby base can be is in the last position | 61 // The only place where a ruby base can be is in the last position |
| 62 // Note: As anonymous blocks, ruby runs do not have ':before' or ':after' co
ntent themselves. | 62 // Note: As anonymous blocks, ruby runs do not have ':before' or ':after' co
ntent themselves. |
| 63 return lastChild() && lastChild()->isRubyBase(); | 63 return lastChild() && lastChild()->isRubyBase(); |
| 64 } | 64 } |
| 65 | 65 |
| 66 LayoutRubyText* LayoutRubyRun::rubyText() const | 66 LayoutRubyText* LayoutRubyRun::rubyText() const |
| 67 { | 67 { |
| 68 RenderObject* child = firstChild(); | 68 LayoutObject* child = firstChild(); |
| 69 // If in future it becomes necessary to support floating or positioned ruby
text, | 69 // If in future it becomes necessary to support floating or positioned ruby
text, |
| 70 // layout will have to be changed to handle them properly. | 70 // layout will have to be changed to handle them properly. |
| 71 ASSERT(!child || !child->isRubyText() || !child->isFloatingOrOutOfFlowPositi
oned()); | 71 ASSERT(!child || !child->isRubyText() || !child->isFloatingOrOutOfFlowPositi
oned()); |
| 72 return child && child->isRubyText() ? static_cast<LayoutRubyText*>(child) :
0; | 72 return child && child->isRubyText() ? static_cast<LayoutRubyText*>(child) :
0; |
| 73 } | 73 } |
| 74 | 74 |
| 75 LayoutRubyBase* LayoutRubyRun::rubyBase() const | 75 LayoutRubyBase* LayoutRubyRun::rubyBase() const |
| 76 { | 76 { |
| 77 RenderObject* child = lastChild(); | 77 LayoutObject* child = lastChild(); |
| 78 return child && child->isRubyBase() ? static_cast<LayoutRubyBase*>(child) :
0; | 78 return child && child->isRubyBase() ? static_cast<LayoutRubyBase*>(child) :
0; |
| 79 } | 79 } |
| 80 | 80 |
| 81 LayoutRubyBase* LayoutRubyRun::rubyBaseSafe() | 81 LayoutRubyBase* LayoutRubyRun::rubyBaseSafe() |
| 82 { | 82 { |
| 83 LayoutRubyBase* base = rubyBase(); | 83 LayoutRubyBase* base = rubyBase(); |
| 84 if (!base) { | 84 if (!base) { |
| 85 base = createRubyBase(); | 85 base = createRubyBase(); |
| 86 RenderBlockFlow::addChild(base); | 86 RenderBlockFlow::addChild(base); |
| 87 } | 87 } |
| 88 return base; | 88 return base; |
| 89 } | 89 } |
| 90 | 90 |
| 91 bool LayoutRubyRun::isChildAllowed(RenderObject* child, const RenderStyle&) cons
t | 91 bool LayoutRubyRun::isChildAllowed(LayoutObject* child, const RenderStyle&) cons
t |
| 92 { | 92 { |
| 93 return child->isRubyText() || child->isInline(); | 93 return child->isRubyText() || child->isInline(); |
| 94 } | 94 } |
| 95 | 95 |
| 96 void LayoutRubyRun::addChild(RenderObject* child, RenderObject* beforeChild) | 96 void LayoutRubyRun::addChild(LayoutObject* child, LayoutObject* beforeChild) |
| 97 { | 97 { |
| 98 ASSERT(child); | 98 ASSERT(child); |
| 99 | 99 |
| 100 if (child->isRubyText()) { | 100 if (child->isRubyText()) { |
| 101 if (!beforeChild) { | 101 if (!beforeChild) { |
| 102 // LayoutRuby has already ascertained that we can add the child here
. | 102 // LayoutRuby has already ascertained that we can add the child here
. |
| 103 ASSERT(!hasRubyText()); | 103 ASSERT(!hasRubyText()); |
| 104 // prepend ruby texts as first child | 104 // prepend ruby texts as first child |
| 105 RenderBlockFlow::addChild(child, firstChild()); | 105 RenderBlockFlow::addChild(child, firstChild()); |
| 106 } else if (beforeChild->isRubyText()) { | 106 } else if (beforeChild->isRubyText()) { |
| 107 // New text is inserted just before another. | 107 // New text is inserted just before another. |
| 108 // In this case the new text takes the place of the old one, and | 108 // In this case the new text takes the place of the old one, and |
| 109 // the old text goes into a new run that is inserted as next sibling
. | 109 // the old text goes into a new run that is inserted as next sibling
. |
| 110 ASSERT(beforeChild->parent() == this); | 110 ASSERT(beforeChild->parent() == this); |
| 111 RenderObject* ruby = parent(); | 111 LayoutObject* ruby = parent(); |
| 112 ASSERT(ruby->isRuby()); | 112 ASSERT(ruby->isRuby()); |
| 113 RenderBlock* newRun = staticCreateRubyRun(ruby); | 113 RenderBlock* newRun = staticCreateRubyRun(ruby); |
| 114 ruby->addChild(newRun, nextSibling()); | 114 ruby->addChild(newRun, nextSibling()); |
| 115 // Add the new ruby text and move the old one to the new run | 115 // Add the new ruby text and move the old one to the new run |
| 116 // Note: Doing it in this order and not using LayoutRubyRun's method
s, | 116 // Note: Doing it in this order and not using LayoutRubyRun's method
s, |
| 117 // in order to avoid automatic removal of the ruby run in case there
is no | 117 // in order to avoid automatic removal of the ruby run in case there
is no |
| 118 // other child besides the old ruby text. | 118 // other child besides the old ruby text. |
| 119 RenderBlockFlow::addChild(child, beforeChild); | 119 RenderBlockFlow::addChild(child, beforeChild); |
| 120 RenderBlockFlow::removeChild(beforeChild); | 120 RenderBlockFlow::removeChild(beforeChild); |
| 121 newRun->addChild(beforeChild); | 121 newRun->addChild(beforeChild); |
| 122 } else if (hasRubyBase()) { | 122 } else if (hasRubyBase()) { |
| 123 // Insertion before a ruby base object. | 123 // Insertion before a ruby base object. |
| 124 // In this case we need insert a new run before the current one and
split the base. | 124 // In this case we need insert a new run before the current one and
split the base. |
| 125 RenderObject* ruby = parent(); | 125 LayoutObject* ruby = parent(); |
| 126 LayoutRubyRun* newRun = staticCreateRubyRun(ruby); | 126 LayoutRubyRun* newRun = staticCreateRubyRun(ruby); |
| 127 ruby->addChild(newRun, this); | 127 ruby->addChild(newRun, this); |
| 128 newRun->addChild(child); | 128 newRun->addChild(child); |
| 129 rubyBaseSafe()->moveChildren(newRun->rubyBaseSafe(), beforeChild); | 129 rubyBaseSafe()->moveChildren(newRun->rubyBaseSafe(), beforeChild); |
| 130 } | 130 } |
| 131 } else { | 131 } else { |
| 132 // child is not a text -> insert it into the base | 132 // child is not a text -> insert it into the base |
| 133 // (append it instead if beforeChild is the ruby text) | 133 // (append it instead if beforeChild is the ruby text) |
| 134 LayoutRubyBase* base = rubyBaseSafe(); | 134 LayoutRubyBase* base = rubyBaseSafe(); |
| 135 if (beforeChild == base) | 135 if (beforeChild == base) |
| 136 beforeChild = base->firstChild(); | 136 beforeChild = base->firstChild(); |
| 137 if (beforeChild && beforeChild->isRubyText()) | 137 if (beforeChild && beforeChild->isRubyText()) |
| 138 beforeChild = 0; | 138 beforeChild = 0; |
| 139 ASSERT(!beforeChild || beforeChild->isDescendantOf(base)); | 139 ASSERT(!beforeChild || beforeChild->isDescendantOf(base)); |
| 140 base->addChild(child, beforeChild); | 140 base->addChild(child, beforeChild); |
| 141 } | 141 } |
| 142 } | 142 } |
| 143 | 143 |
| 144 void LayoutRubyRun::removeChild(RenderObject* child) | 144 void LayoutRubyRun::removeChild(LayoutObject* child) |
| 145 { | 145 { |
| 146 // If the child is a ruby text, then merge the ruby base with the base of | 146 // If the child is a ruby text, then merge the ruby base with the base of |
| 147 // the right sibling run, if possible. | 147 // the right sibling run, if possible. |
| 148 if (!beingDestroyed() && !documentBeingDestroyed() && child->isRubyText()) { | 148 if (!beingDestroyed() && !documentBeingDestroyed() && child->isRubyText()) { |
| 149 LayoutRubyBase* base = rubyBase(); | 149 LayoutRubyBase* base = rubyBase(); |
| 150 RenderObject* rightNeighbour = nextSibling(); | 150 LayoutObject* rightNeighbour = nextSibling(); |
| 151 if (base && rightNeighbour && rightNeighbour->isRubyRun()) { | 151 if (base && rightNeighbour && rightNeighbour->isRubyRun()) { |
| 152 // Ruby run without a base can happen only at the first run. | 152 // Ruby run without a base can happen only at the first run. |
| 153 LayoutRubyRun* rightRun = toLayoutRubyRun(rightNeighbour); | 153 LayoutRubyRun* rightRun = toLayoutRubyRun(rightNeighbour); |
| 154 if (rightRun->hasRubyBase()) { | 154 if (rightRun->hasRubyBase()) { |
| 155 LayoutRubyBase* rightBase = rightRun->rubyBaseSafe(); | 155 LayoutRubyBase* rightBase = rightRun->rubyBaseSafe(); |
| 156 // Collect all children in a single base, then swap the bases. | 156 // Collect all children in a single base, then swap the bases. |
| 157 rightBase->moveChildren(base); | 157 rightBase->moveChildren(base); |
| 158 moveChildTo(rightRun, base); | 158 moveChildTo(rightRun, base); |
| 159 rightRun->moveChildTo(this, rightBase); | 159 rightRun->moveChildTo(this, rightBase); |
| 160 // The now empty ruby base will be removed below. | 160 // The now empty ruby base will be removed below. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 184 | 184 |
| 185 LayoutRubyBase* LayoutRubyRun::createRubyBase() const | 185 LayoutRubyBase* LayoutRubyRun::createRubyBase() const |
| 186 { | 186 { |
| 187 LayoutRubyBase* layoutObject = LayoutRubyBase::createAnonymous(&document()); | 187 LayoutRubyBase* layoutObject = LayoutRubyBase::createAnonymous(&document()); |
| 188 RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(
style(), BLOCK); | 188 RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(
style(), BLOCK); |
| 189 newStyle->setTextAlign(CENTER); // FIXME: use WEBKIT_CENTER? | 189 newStyle->setTextAlign(CENTER); // FIXME: use WEBKIT_CENTER? |
| 190 layoutObject->setStyle(newStyle.release()); | 190 layoutObject->setStyle(newStyle.release()); |
| 191 return layoutObject; | 191 return layoutObject; |
| 192 } | 192 } |
| 193 | 193 |
| 194 LayoutRubyRun* LayoutRubyRun::staticCreateRubyRun(const RenderObject* parentRuby
) | 194 LayoutRubyRun* LayoutRubyRun::staticCreateRubyRun(const LayoutObject* parentRuby
) |
| 195 { | 195 { |
| 196 ASSERT(parentRuby && parentRuby->isRuby()); | 196 ASSERT(parentRuby && parentRuby->isRuby()); |
| 197 LayoutRubyRun* rr = new LayoutRubyRun(); | 197 LayoutRubyRun* rr = new LayoutRubyRun(); |
| 198 rr->setDocumentForAnonymous(&parentRuby->document()); | 198 rr->setDocumentForAnonymous(&parentRuby->document()); |
| 199 RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(
parentRuby->style(), INLINE_BLOCK); | 199 RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(
parentRuby->style(), INLINE_BLOCK); |
| 200 rr->setStyle(newStyle.release()); | 200 rr->setStyle(newStyle.release()); |
| 201 return rr; | 201 return rr; |
| 202 } | 202 } |
| 203 | 203 |
| 204 RenderObject* LayoutRubyRun::layoutSpecialExcludedChild(bool relayoutChildren, S
ubtreeLayoutScope& layoutScope) | 204 LayoutObject* LayoutRubyRun::layoutSpecialExcludedChild(bool relayoutChildren, S
ubtreeLayoutScope& layoutScope) |
| 205 { | 205 { |
| 206 // Don't bother positioning the LayoutRubyRun yet. | 206 // Don't bother positioning the LayoutRubyRun yet. |
| 207 LayoutRubyText* rt = rubyText(); | 207 LayoutRubyText* rt = rubyText(); |
| 208 if (!rt) | 208 if (!rt) |
| 209 return 0; | 209 return 0; |
| 210 if (relayoutChildren) | 210 if (relayoutChildren) |
| 211 layoutScope.setChildNeedsLayout(rt); | 211 layoutScope.setChildNeedsLayout(rt); |
| 212 rt->layoutIfNeeded(); | 212 rt->layoutIfNeeded(); |
| 213 return rt; | 213 return rt; |
| 214 } | 214 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 lastLineBottom += rb->logicalTop(); | 252 lastLineBottom += rb->logicalTop(); |
| 253 } | 253 } |
| 254 | 254 |
| 255 rt->setLogicalTop(-firstLineRubyTextTop + lastLineBottom); | 255 rt->setLogicalTop(-firstLineRubyTextTop + lastLineBottom); |
| 256 } | 256 } |
| 257 | 257 |
| 258 // Update our overflow to account for the new LayoutRubyText position. | 258 // Update our overflow to account for the new LayoutRubyText position. |
| 259 computeOverflow(clientLogicalBottom()); | 259 computeOverflow(clientLogicalBottom()); |
| 260 } | 260 } |
| 261 | 261 |
| 262 void LayoutRubyRun::getOverhang(bool firstLine, RenderObject* startRenderer, Ren
derObject* endRenderer, int& startOverhang, int& endOverhang) const | 262 void LayoutRubyRun::getOverhang(bool firstLine, LayoutObject* startRenderer, Lay
outObject* endRenderer, int& startOverhang, int& endOverhang) const |
| 263 { | 263 { |
| 264 ASSERT(!needsLayout()); | 264 ASSERT(!needsLayout()); |
| 265 | 265 |
| 266 startOverhang = 0; | 266 startOverhang = 0; |
| 267 endOverhang = 0; | 267 endOverhang = 0; |
| 268 | 268 |
| 269 LayoutRubyBase* rubyBase = this->rubyBase(); | 269 LayoutRubyBase* rubyBase = this->rubyBase(); |
| 270 LayoutRubyText* rubyText = this->rubyText(); | 270 LayoutRubyText* rubyText = this->rubyText(); |
| 271 | 271 |
| 272 if (!rubyBase || !rubyText) | 272 if (!rubyBase || !rubyText) |
| (...skipping 23 matching lines...) Expand all Loading... |
| 296 // We can overhang the ruby by no more than half the width of the neighborin
g text | 296 // We can overhang the ruby by no more than half the width of the neighborin
g text |
| 297 // and no more than half the font size. | 297 // and no more than half the font size. |
| 298 int halfWidthOfFontSize = rubyText->style(firstLine)->fontSize() / 2; | 298 int halfWidthOfFontSize = rubyText->style(firstLine)->fontSize() / 2; |
| 299 if (startOverhang) | 299 if (startOverhang) |
| 300 startOverhang = std::min<int>(startOverhang, std::min<int>(toRenderText(
startRenderer)->minLogicalWidth(), halfWidthOfFontSize)); | 300 startOverhang = std::min<int>(startOverhang, std::min<int>(toRenderText(
startRenderer)->minLogicalWidth(), halfWidthOfFontSize)); |
| 301 if (endOverhang) | 301 if (endOverhang) |
| 302 endOverhang = std::min<int>(endOverhang, std::min<int>(toRenderText(endR
enderer)->minLogicalWidth(), halfWidthOfFontSize)); | 302 endOverhang = std::min<int>(endOverhang, std::min<int>(toRenderText(endR
enderer)->minLogicalWidth(), halfWidthOfFontSize)); |
| 303 } | 303 } |
| 304 | 304 |
| 305 } // namespace blink | 305 } // namespace blink |
| OLD | NEW |