| 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 27 matching lines...) Expand all Loading... |
| 38 | 38 |
| 39 LayoutRubyRun::LayoutRubyRun() : LayoutBlockFlow(nullptr) { | 39 LayoutRubyRun::LayoutRubyRun() : LayoutBlockFlow(nullptr) { |
| 40 setInline(true); | 40 setInline(true); |
| 41 setIsAtomicInlineLevel(true); | 41 setIsAtomicInlineLevel(true); |
| 42 } | 42 } |
| 43 | 43 |
| 44 LayoutRubyRun::~LayoutRubyRun() {} | 44 LayoutRubyRun::~LayoutRubyRun() {} |
| 45 | 45 |
| 46 bool LayoutRubyRun::hasRubyText() const { | 46 bool LayoutRubyRun::hasRubyText() const { |
| 47 // The only place where a ruby text can be is in the first position | 47 // The only place where a ruby text can be is in the first position |
| 48 // Note: As anonymous blocks, ruby runs do not have ':before' or ':after' cont
ent themselves. | 48 // Note: As anonymous blocks, ruby runs do not have ':before' or ':after' |
| 49 // content themselves. |
| 49 return firstChild() && firstChild()->isRubyText(); | 50 return firstChild() && firstChild()->isRubyText(); |
| 50 } | 51 } |
| 51 | 52 |
| 52 bool LayoutRubyRun::hasRubyBase() const { | 53 bool LayoutRubyRun::hasRubyBase() const { |
| 53 // The only place where a ruby base can be is in the last position | 54 // The only place where a ruby base can be is in the last position |
| 54 // Note: As anonymous blocks, ruby runs do not have ':before' or ':after' cont
ent themselves. | 55 // Note: As anonymous blocks, ruby runs do not have ':before' or ':after' |
| 56 // content themselves. |
| 55 return lastChild() && lastChild()->isRubyBase(); | 57 return lastChild() && lastChild()->isRubyBase(); |
| 56 } | 58 } |
| 57 | 59 |
| 58 LayoutRubyText* LayoutRubyRun::rubyText() const { | 60 LayoutRubyText* LayoutRubyRun::rubyText() const { |
| 59 LayoutObject* child = firstChild(); | 61 LayoutObject* child = firstChild(); |
| 60 // If in future it becomes necessary to support floating or positioned ruby te
xt, | 62 // If in future it becomes necessary to support floating or positioned ruby |
| 61 // layout will have to be changed to handle them properly. | 63 // text, layout will have to be changed to handle them properly. |
| 62 ASSERT(!child || !child->isRubyText() || | 64 ASSERT(!child || !child->isRubyText() || |
| 63 !child->isFloatingOrOutOfFlowPositioned()); | 65 !child->isFloatingOrOutOfFlowPositioned()); |
| 64 return child && child->isRubyText() ? static_cast<LayoutRubyText*>(child) : 0; | 66 return child && child->isRubyText() ? static_cast<LayoutRubyText*>(child) : 0; |
| 65 } | 67 } |
| 66 | 68 |
| 67 LayoutRubyBase* LayoutRubyRun::rubyBase() const { | 69 LayoutRubyBase* LayoutRubyRun::rubyBase() const { |
| 68 LayoutObject* child = lastChild(); | 70 LayoutObject* child = lastChild(); |
| 69 return child && child->isRubyBase() ? static_cast<LayoutRubyBase*>(child) : 0; | 71 return child && child->isRubyBase() ? static_cast<LayoutRubyBase*>(child) : 0; |
| 70 } | 72 } |
| 71 | 73 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 103 ruby->addChild(newRun, nextSibling()); | 105 ruby->addChild(newRun, nextSibling()); |
| 104 // Add the new ruby text and move the old one to the new run | 106 // Add the new ruby text and move the old one to the new run |
| 105 // Note: Doing it in this order and not using LayoutRubyRun's methods, | 107 // Note: Doing it in this order and not using LayoutRubyRun's methods, |
| 106 // in order to avoid automatic removal of the ruby run in case there is no | 108 // in order to avoid automatic removal of the ruby run in case there is no |
| 107 // other child besides the old ruby text. | 109 // other child besides the old ruby text. |
| 108 LayoutBlockFlow::addChild(child, beforeChild); | 110 LayoutBlockFlow::addChild(child, beforeChild); |
| 109 LayoutBlockFlow::removeChild(beforeChild); | 111 LayoutBlockFlow::removeChild(beforeChild); |
| 110 newRun->addChild(beforeChild); | 112 newRun->addChild(beforeChild); |
| 111 } else if (hasRubyBase()) { | 113 } else if (hasRubyBase()) { |
| 112 // Insertion before a ruby base object. | 114 // Insertion before a ruby base object. |
| 113 // In this case we need insert a new run before the current one and split
the base. | 115 // In this case we need insert a new run before the current one and split |
| 116 // the base. |
| 114 LayoutObject* ruby = parent(); | 117 LayoutObject* ruby = parent(); |
| 115 LayoutRubyRun* newRun = staticCreateRubyRun(ruby); | 118 LayoutRubyRun* newRun = staticCreateRubyRun(ruby); |
| 116 ruby->addChild(newRun, this); | 119 ruby->addChild(newRun, this); |
| 117 newRun->addChild(child); | 120 newRun->addChild(child); |
| 118 | 121 |
| 119 // Make sure we don't leave anything in the percentage descendant | 122 // Make sure we don't leave anything in the percentage descendant |
| 120 // map before moving the children to the new base. | 123 // map before moving the children to the new base. |
| 121 if (hasPercentHeightDescendants()) | 124 if (hasPercentHeightDescendants()) |
| 122 clearPercentHeightDescendants(); | 125 clearPercentHeightDescendants(); |
| 123 rubyBaseSafe()->moveChildren(newRun->rubyBaseSafe(), beforeChild); | 126 rubyBaseSafe()->moveChildren(newRun->rubyBaseSafe(), beforeChild); |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 | 215 |
| 213 void LayoutRubyRun::layout() { | 216 void LayoutRubyRun::layout() { |
| 214 LayoutBlockFlow::layout(); | 217 LayoutBlockFlow::layout(); |
| 215 | 218 |
| 216 LayoutRubyText* rt = rubyText(); | 219 LayoutRubyText* rt = rubyText(); |
| 217 if (!rt) | 220 if (!rt) |
| 218 return; | 221 return; |
| 219 | 222 |
| 220 rt->setLogicalLeft(LayoutUnit()); | 223 rt->setLogicalLeft(LayoutUnit()); |
| 221 | 224 |
| 222 // Place the LayoutRubyText such that its bottom is flush with the lineTop of
the first line of the LayoutRubyBase. | 225 // Place the LayoutRubyText such that its bottom is flush with the lineTop of |
| 226 // the first line of the LayoutRubyBase. |
| 223 LayoutUnit lastLineRubyTextBottom = rt->logicalHeight(); | 227 LayoutUnit lastLineRubyTextBottom = rt->logicalHeight(); |
| 224 LayoutUnit firstLineRubyTextTop; | 228 LayoutUnit firstLineRubyTextTop; |
| 225 RootInlineBox* rootBox = rt->lastRootBox(); | 229 RootInlineBox* rootBox = rt->lastRootBox(); |
| 226 if (rootBox) { | 230 if (rootBox) { |
| 227 // In order to align, we have to ignore negative leading. | 231 // In order to align, we have to ignore negative leading. |
| 228 firstLineRubyTextTop = rt->firstRootBox()->logicalTopLayoutOverflow(); | 232 firstLineRubyTextTop = rt->firstRootBox()->logicalTopLayoutOverflow(); |
| 229 lastLineRubyTextBottom = rootBox->logicalBottomLayoutOverflow(); | 233 lastLineRubyTextBottom = rootBox->logicalBottomLayoutOverflow(); |
| 230 } | 234 } |
| 231 | 235 |
| 232 if (style()->isFlippedLinesWritingMode() == | 236 if (style()->isFlippedLinesWritingMode() == |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 296 startLayoutObject->style(firstLine)->fontSize() > | 300 startLayoutObject->style(firstLine)->fontSize() > |
| 297 rubyBase->style(firstLine)->fontSize()) | 301 rubyBase->style(firstLine)->fontSize()) |
| 298 startOverhang = 0; | 302 startOverhang = 0; |
| 299 | 303 |
| 300 if (!endLayoutObject || !endLayoutObject->isText() || | 304 if (!endLayoutObject || !endLayoutObject->isText() || |
| 301 endLayoutObject->style(firstLine)->fontSize() > | 305 endLayoutObject->style(firstLine)->fontSize() > |
| 302 rubyBase->style(firstLine)->fontSize()) | 306 rubyBase->style(firstLine)->fontSize()) |
| 303 endOverhang = 0; | 307 endOverhang = 0; |
| 304 | 308 |
| 305 // We overhang a ruby only if the neighboring layout object is a text. | 309 // We overhang a ruby only if the neighboring layout object is a text. |
| 306 // We can overhang the ruby by no more than half the width of the neighboring
text | 310 // We can overhang the ruby by no more than half the width of the neighboring |
| 307 // and no more than half the font size. | 311 // text and no more than half the font size. |
| 308 int halfWidthOfFontSize = rubyText->style(firstLine)->fontSize() / 2; | 312 int halfWidthOfFontSize = rubyText->style(firstLine)->fontSize() / 2; |
| 309 if (startOverhang) | 313 if (startOverhang) |
| 310 startOverhang = std::min<int>( | 314 startOverhang = std::min<int>( |
| 311 startOverhang, | 315 startOverhang, |
| 312 std::min<int>(toLayoutText(startLayoutObject)->minLogicalWidth(), | 316 std::min<int>(toLayoutText(startLayoutObject)->minLogicalWidth(), |
| 313 halfWidthOfFontSize)); | 317 halfWidthOfFontSize)); |
| 314 if (endOverhang) | 318 if (endOverhang) |
| 315 endOverhang = std::min<int>( | 319 endOverhang = std::min<int>( |
| 316 endOverhang, | 320 endOverhang, |
| 317 std::min<int>(toLayoutText(endLayoutObject)->minLogicalWidth(), | 321 std::min<int>(toLayoutText(endLayoutObject)->minLogicalWidth(), |
| 318 halfWidthOfFontSize)); | 322 halfWidthOfFontSize)); |
| 319 } | 323 } |
| 320 | 324 |
| 321 bool LayoutRubyRun::canBreakBefore( | 325 bool LayoutRubyRun::canBreakBefore( |
| 322 const LazyLineBreakIterator& iterator) const { | 326 const LazyLineBreakIterator& iterator) const { |
| 323 // TODO(kojii): It would be nice to improve this so that it isn't just | 327 // TODO(kojii): It would be nice to improve this so that it isn't just |
| 324 // hard-coded, but lookahead in this case is particularly problematic. | 328 // hard-coded, but lookahead in this case is particularly problematic. |
| 325 // See crbug.com/522826. | 329 // See crbug.com/522826. |
| 326 | 330 |
| 327 if (!iterator.priorContextLength()) | 331 if (!iterator.priorContextLength()) |
| 328 return true; | 332 return true; |
| 329 UChar ch = iterator.lastCharacter(); | 333 UChar ch = iterator.lastCharacter(); |
| 330 ULineBreak lineBreak = | 334 ULineBreak lineBreak = |
| 331 static_cast<ULineBreak>(u_getIntPropertyValue(ch, UCHAR_LINE_BREAK)); | 335 static_cast<ULineBreak>(u_getIntPropertyValue(ch, UCHAR_LINE_BREAK)); |
| 332 // UNICODE LINE BREAKING ALGORITHM | 336 // UNICODE LINE BREAKING ALGORITHM |
| 333 // http://www.unicode.org/reports/tr14/ | 337 // http://www.unicode.org/reports/tr14/ |
| 334 // And Requirements for Japanese Text Layout, 3.1.7 Characters Not Starting a
Line | 338 // And Requirements for Japanese Text Layout, 3.1.7 Characters Not Starting a |
| 339 // Line |
| 335 // http://www.w3.org/TR/2012/NOTE-jlreq-20120403/#characters_not_starting_a_li
ne | 340 // http://www.w3.org/TR/2012/NOTE-jlreq-20120403/#characters_not_starting_a_li
ne |
| 336 switch (lineBreak) { | 341 switch (lineBreak) { |
| 337 case U_LB_WORD_JOINER: | 342 case U_LB_WORD_JOINER: |
| 338 case U_LB_GLUE: | 343 case U_LB_GLUE: |
| 339 case U_LB_OPEN_PUNCTUATION: | 344 case U_LB_OPEN_PUNCTUATION: |
| 340 return false; | 345 return false; |
| 341 default: | 346 default: |
| 342 break; | 347 break; |
| 343 } | 348 } |
| 344 return true; | 349 return true; |
| 345 } | 350 } |
| 346 | 351 |
| 347 } // namespace blink | 352 } // namespace blink |
| OLD | NEW |