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 |