| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2000 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 2000 Lars Knoll (knoll@kde.org) |
| 3 * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r
ight reserved. | 3 * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r
ight reserved. |
| 4 * Copyright (C) 2010 Google Inc. All rights reserved. | 4 * Copyright (C) 2010 Google Inc. All rights reserved. |
| 5 * | 5 * |
| 6 * This library is free software; you can redistribute it and/or | 6 * This library is free software; you can redistribute it and/or |
| 7 * modify it under the terms of the GNU Library General Public | 7 * modify it under the terms of the GNU Library General Public |
| 8 * License as published by the Free Software Foundation; either | 8 * License as published by the Free Software Foundation; either |
| 9 * version 2 of the License, or (at your option) any later version. | 9 * version 2 of the License, or (at your option) any later version. |
| 10 * | 10 * |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 static bool parentIsConstructedOrHaveNext(InlineFlowBox* parentBox) | 133 static bool parentIsConstructedOrHaveNext(InlineFlowBox* parentBox) |
| 134 { | 134 { |
| 135 do { | 135 do { |
| 136 if (parentBox->isConstructed() || parentBox->nextOnLine()) | 136 if (parentBox->isConstructed() || parentBox->nextOnLine()) |
| 137 return true; | 137 return true; |
| 138 parentBox = parentBox->parent(); | 138 parentBox = parentBox->parent(); |
| 139 } while (parentBox); | 139 } while (parentBox); |
| 140 return false; | 140 return false; |
| 141 } | 141 } |
| 142 | 142 |
| 143 InlineFlowBox* RenderBlockFlow::createLineBoxes(RenderObject* obj, const LineInf
o& lineInfo, InlineBox* childBox, bool startNewSegment) | 143 InlineFlowBox* RenderBlockFlow::createLineBoxes(RenderObject* obj, const LineInf
o& lineInfo, InlineBox* childBox) |
| 144 { | 144 { |
| 145 // See if we have an unconstructed line box for this object that is also | 145 // See if we have an unconstructed line box for this object that is also |
| 146 // the last item on the line. | 146 // the last item on the line. |
| 147 unsigned lineDepth = 1; | 147 unsigned lineDepth = 1; |
| 148 InlineFlowBox* parentBox = 0; | 148 InlineFlowBox* parentBox = 0; |
| 149 InlineFlowBox* result = 0; | 149 InlineFlowBox* result = 0; |
| 150 bool hasDefaultLineBoxContain = style()->lineBoxContain() == RenderStyle::in
itialLineBoxContain(); | 150 bool hasDefaultLineBoxContain = style()->lineBoxContain() == RenderStyle::in
itialLineBoxContain(); |
| 151 do { | 151 do { |
| 152 ASSERT_WITH_SECURITY_IMPLICATION(obj->isRenderInline() || obj == this); | 152 ASSERT_WITH_SECURITY_IMPLICATION(obj->isRenderInline() || obj == this); |
| 153 | 153 |
| 154 RenderInline* inlineFlow = (obj != this) ? toRenderInline(obj) : 0; | 154 RenderInline* inlineFlow = (obj != this) ? toRenderInline(obj) : 0; |
| 155 | 155 |
| 156 // Get the last box we made for this render object. | 156 // Get the last box we made for this render object. |
| 157 parentBox = inlineFlow ? inlineFlow->lastLineBox() : toRenderBlock(obj)-
>lastLineBox(); | 157 parentBox = inlineFlow ? inlineFlow->lastLineBox() : toRenderBlock(obj)-
>lastLineBox(); |
| 158 | 158 |
| 159 // If this box or its ancestor is constructed then it is from a previous
line, and we need | 159 // If this box or its ancestor is constructed then it is from a previous
line, and we need |
| 160 // to make a new box for our line. If this box or its ancestor is uncon
structed but it has | 160 // to make a new box for our line. If this box or its ancestor is uncon
structed but it has |
| 161 // something following it on the line, then we know we have to make a ne
w box | 161 // something following it on the line, then we know we have to make a ne
w box |
| 162 // as well. In this situation our inline has actually been split in two
on | 162 // as well. In this situation our inline has actually been split in two
on |
| 163 // the same line (this can happen with very fancy language mixtures). | 163 // the same line (this can happen with very fancy language mixtures). |
| 164 bool constructedNewBox = false; | 164 bool constructedNewBox = false; |
| 165 bool allowedToConstructNewBox = !hasDefaultLineBoxContain || !inlineFlow
|| inlineFlow->alwaysCreateLineBoxes(); | 165 bool allowedToConstructNewBox = !hasDefaultLineBoxContain || !inlineFlow
|| inlineFlow->alwaysCreateLineBoxes(); |
| 166 bool mustCreateBoxesToRoot = startNewSegment && !(parentBox && parentBox
->isRootInlineBox()); | 166 bool canUseExistingParentBox = parentBox && !parentIsConstructedOrHaveNe
xt(parentBox); |
| 167 bool canUseExistingParentBox = parentBox && !parentIsConstructedOrHaveNe
xt(parentBox) && !mustCreateBoxesToRoot; | |
| 168 if (allowedToConstructNewBox && !canUseExistingParentBox) { | 167 if (allowedToConstructNewBox && !canUseExistingParentBox) { |
| 169 // We need to make a new box for this render object. Once | 168 // We need to make a new box for this render object. Once |
| 170 // made, we need to place it at the end of the current line. | 169 // made, we need to place it at the end of the current line. |
| 171 InlineBox* newBox = createInlineBoxForRenderer(obj, obj == this); | 170 InlineBox* newBox = createInlineBoxForRenderer(obj, obj == this); |
| 172 ASSERT_WITH_SECURITY_IMPLICATION(newBox->isInlineFlowBox()); | 171 ASSERT_WITH_SECURITY_IMPLICATION(newBox->isInlineFlowBox()); |
| 173 parentBox = toInlineFlowBox(newBox); | 172 parentBox = toInlineFlowBox(newBox); |
| 174 parentBox->setFirstLineStyleBit(lineInfo.isFirstLine()); | 173 parentBox->setFirstLineStyleBit(lineInfo.isFirstLine()); |
| 175 parentBox->setIsHorizontal(isHorizontalWritingMode()); | 174 parentBox->setIsHorizontal(isHorizontalWritingMode()); |
| 176 if (!hasDefaultLineBoxContain) | 175 if (!hasDefaultLineBoxContain) |
| 177 parentBox->clearDescendantsHaveSameLineHeightAndBaseline(); | 176 parentBox->clearDescendantsHaveSameLineHeightAndBaseline(); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 256 if (!box) | 255 if (!box) |
| 257 continue; | 256 continue; |
| 258 | 257 |
| 259 if (!rootHasSelectedChildren && box->renderer().selectionState() != Rend
erObject::SelectionNone) | 258 if (!rootHasSelectedChildren && box->renderer().selectionState() != Rend
erObject::SelectionNone) |
| 260 rootHasSelectedChildren = true; | 259 rootHasSelectedChildren = true; |
| 261 | 260 |
| 262 // If we have no parent box yet, or if the run is not simply a sibling, | 261 // If we have no parent box yet, or if the run is not simply a sibling, |
| 263 // then we need to construct inline boxes as necessary to properly enclo
se the | 262 // then we need to construct inline boxes as necessary to properly enclo
se the |
| 264 // run's inline box. Segments can only be siblings at the root level, as | 263 // run's inline box. Segments can only be siblings at the root level, as |
| 265 // they are positioned separately. | 264 // they are positioned separately. |
| 266 bool runStartsSegment = r->m_startsSegment; | 265 if (!parentBox || parentBox->renderer() != r->m_object->parent()) { |
| 267 | |
| 268 if (!parentBox || parentBox->renderer() != r->m_object->parent() || runS
tartsSegment) | |
| 269 // Create new inline boxes all the way back to the appropriate inser
tion point. | 266 // Create new inline boxes all the way back to the appropriate inser
tion point. |
| 270 parentBox = createLineBoxes(r->m_object->parent(), lineInfo, box, ru
nStartsSegment); | 267 parentBox = createLineBoxes(r->m_object->parent(), lineInfo, box); |
| 271 else { | 268 } else { |
| 272 // Append the inline box to this line. | 269 // Append the inline box to this line. |
| 273 parentBox->addToLine(box); | 270 parentBox->addToLine(box); |
| 274 } | 271 } |
| 275 | 272 |
| 276 bool visuallyOrdered = r->m_object->style()->rtlOrdering() == VisualOrde
r; | 273 bool visuallyOrdered = r->m_object->style()->rtlOrdering() == VisualOrde
r; |
| 277 box->setBidiLevel(r->level()); | 274 box->setBidiLevel(r->level()); |
| 278 | 275 |
| 279 if (box->isInlineTextBox()) { | 276 if (box->isInlineTextBox()) { |
| 280 InlineTextBox* text = toInlineTextBox(box); | 277 InlineTextBox* text = toInlineTextBox(box); |
| 281 text->setStart(r->m_start); | 278 text->setStart(r->m_start); |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 504 } | 501 } |
| 505 } | 502 } |
| 506 | 503 |
| 507 static inline void computeExpansionForJustifiedText(BidiRun* firstRun, BidiRun*
trailingSpaceRun, Vector<unsigned, 16>& expansionOpportunities, unsigned expansi
onOpportunityCount, float& totalLogicalWidth, float availableLogicalWidth) | 504 static inline void computeExpansionForJustifiedText(BidiRun* firstRun, BidiRun*
trailingSpaceRun, Vector<unsigned, 16>& expansionOpportunities, unsigned expansi
onOpportunityCount, float& totalLogicalWidth, float availableLogicalWidth) |
| 508 { | 505 { |
| 509 if (!expansionOpportunityCount || availableLogicalWidth <= totalLogicalWidth
) | 506 if (!expansionOpportunityCount || availableLogicalWidth <= totalLogicalWidth
) |
| 510 return; | 507 return; |
| 511 | 508 |
| 512 size_t i = 0; | 509 size_t i = 0; |
| 513 for (BidiRun* r = firstRun; r; r = r->next()) { | 510 for (BidiRun* r = firstRun; r; r = r->next()) { |
| 514 // This method is called once per segment, do not move past the current
segment. | |
| 515 if (r->m_startsSegment) | |
| 516 break; | |
| 517 if (!r->m_box || r == trailingSpaceRun) | 511 if (!r->m_box || r == trailingSpaceRun) |
| 518 continue; | 512 continue; |
| 519 | 513 |
| 520 if (r->m_object->isText()) { | 514 if (r->m_object->isText()) { |
| 521 unsigned opportunitiesInRun = expansionOpportunities[i++]; | 515 unsigned opportunitiesInRun = expansionOpportunities[i++]; |
| 522 | 516 |
| 523 ASSERT(opportunitiesInRun <= expansionOpportunityCount); | 517 ASSERT(opportunitiesInRun <= expansionOpportunityCount); |
| 524 | 518 |
| 525 // Only justify text if whitespace is collapsed. | 519 // Only justify text if whitespace is collapsed. |
| 526 if (r->m_object->style()->collapseWhiteSpace()) { | 520 if (r->m_object->style()->collapseWhiteSpace()) { |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 633 bool needsWordSpacing = false; | 627 bool needsWordSpacing = false; |
| 634 float totalLogicalWidth = lineBox->getFlowSpacingLogicalWidth().toFloat(); | 628 float totalLogicalWidth = lineBox->getFlowSpacingLogicalWidth().toFloat(); |
| 635 unsigned expansionOpportunityCount = 0; | 629 unsigned expansionOpportunityCount = 0; |
| 636 bool isAfterExpansion = true; | 630 bool isAfterExpansion = true; |
| 637 Vector<unsigned, 16> expansionOpportunities; | 631 Vector<unsigned, 16> expansionOpportunities; |
| 638 RenderObject* previousObject = 0; | 632 RenderObject* previousObject = 0; |
| 639 TextJustify textJustify = style()->textJustify(); | 633 TextJustify textJustify = style()->textJustify(); |
| 640 | 634 |
| 641 BidiRun* r = firstRun; | 635 BidiRun* r = firstRun; |
| 642 for (; r; r = r->next()) { | 636 for (; r; r = r->next()) { |
| 643 // Once we have reached the start of the next segment, we have finished | |
| 644 // computing the positions for this segment's contents. | |
| 645 if (r->m_startsSegment) | |
| 646 break; | |
| 647 if (!r->m_box || r->m_object->isOutOfFlowPositioned() || r->m_box->isLin
eBreak()) | 637 if (!r->m_box || r->m_object->isOutOfFlowPositioned() || r->m_box->isLin
eBreak()) |
| 648 continue; // Positioned objects are only participating to figure out
their | 638 continue; // Positioned objects are only participating to figure out
their |
| 649 // correct static x position. They have no effect on the
width. | 639 // correct static x position. They have no effect on the
width. |
| 650 // Similarly, line break boxes have no effect on the width
. | 640 // Similarly, line break boxes have no effect on the width
. |
| 651 if (r->m_object->isText()) { | 641 if (r->m_object->isText()) { |
| 652 RenderText* rt = toRenderText(r->m_object); | 642 RenderText* rt = toRenderText(r->m_object); |
| 653 if (textAlign == JUSTIFY && r != trailingSpaceRun && textJustify !=
TextJustifyNone) { | 643 if (textAlign == JUSTIFY && r != trailingSpaceRun && textJustify !=
TextJustifyNone) { |
| 654 if (!isAfterExpansion) | 644 if (!isAfterExpansion) |
| 655 toInlineTextBox(r->m_box)->setCanHaveLeadingExpansion(true); | 645 toInlineTextBox(r->m_box)->setCanHaveLeadingExpansion(true); |
| 656 unsigned opportunitiesInRun; | 646 unsigned opportunitiesInRun; |
| (...skipping 1549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2206 float logicalLeft = logicalLeftOffsetForLine(logicalHeight(), false).toFloat
(); | 2196 float logicalLeft = logicalLeftOffsetForLine(logicalHeight(), false).toFloat
(); |
| 2207 float availableLogicalWidth = logicalRightOffsetForLine(logicalHeight(), fal
se) - logicalLeft; | 2197 float availableLogicalWidth = logicalRightOffsetForLine(logicalHeight(), fal
se) - logicalLeft; |
| 2208 updateLogicalWidthForAlignment(textAlign, 0, 0, logicalLeft, totalLogicalWid
th, availableLogicalWidth, 0); | 2198 updateLogicalWidthForAlignment(textAlign, 0, 0, logicalLeft, totalLogicalWid
th, availableLogicalWidth, 0); |
| 2209 | 2199 |
| 2210 if (!style()->isLeftToRightDirection()) | 2200 if (!style()->isLeftToRightDirection()) |
| 2211 return logicalWidth() - logicalLeft; | 2201 return logicalWidth() - logicalLeft; |
| 2212 return logicalLeft; | 2202 return logicalLeft; |
| 2213 } | 2203 } |
| 2214 | 2204 |
| 2215 } | 2205 } |
| OLD | NEW |