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 |