| 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 * |
| 11 * This library is distributed in the hope that it will be useful, | 11 * This library is distributed in the hope that it will be useful, |
| 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 14 * Library General Public License for more details. | 14 * Library General Public License for more details. |
| 15 * | 15 * |
| 16 * You should have received a copy of the GNU Library General Public License | 16 * You should have received a copy of the GNU Library General Public License |
| 17 * along with this library; see the file COPYING.LIB. If not, write to | 17 * along with this library; see the file COPYING.LIB. If not, write to |
| 18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| 19 * Boston, MA 02110-1301, USA. | 19 * Boston, MA 02110-1301, USA. |
| 20 * | 20 * |
| 21 */ | 21 */ |
| 22 | 22 |
| 23 #include "config.h" | 23 #include "config.h" |
| 24 | 24 |
| 25 #include "core/dom/AXObjectCache.h" | 25 #include "core/dom/AXObjectCache.h" |
| 26 #include "core/layout/BidiRunForLine.h" | 26 #include "core/layout/BidiRunForLine.h" |
| 27 #include "core/layout/Layer.h" | 27 #include "core/layout/Layer.h" |
| 28 #include "core/layout/LayoutCounter.h" | 28 #include "core/layout/LayoutCounter.h" |
| 29 #include "core/layout/LayoutObject.h" |
| 29 #include "core/layout/LayoutRubyRun.h" | 30 #include "core/layout/LayoutRubyRun.h" |
| 30 #include "core/layout/line/BreakingContextInlineHeaders.h" | 31 #include "core/layout/line/BreakingContextInlineHeaders.h" |
| 31 #include "core/layout/line/LayoutTextInfo.h" | 32 #include "core/layout/line/LayoutTextInfo.h" |
| 32 #include "core/layout/line/LineLayoutState.h" | 33 #include "core/layout/line/LineLayoutState.h" |
| 33 #include "core/layout/line/LineWidth.h" | 34 #include "core/layout/line/LineWidth.h" |
| 34 #include "core/layout/line/TrailingFloatsRootInlineBox.h" | 35 #include "core/layout/line/TrailingFloatsRootInlineBox.h" |
| 35 #include "core/layout/line/WordMeasurement.h" | 36 #include "core/layout/line/WordMeasurement.h" |
| 36 #include "core/layout/svg/line/SVGRootInlineBox.h" | 37 #include "core/layout/svg/line/SVGRootInlineBox.h" |
| 37 #include "core/rendering/RenderFlowThread.h" | 38 #include "core/rendering/RenderFlowThread.h" |
| 38 #include "core/rendering/RenderListMarker.h" | 39 #include "core/rendering/RenderListMarker.h" |
| 39 #include "core/rendering/RenderObjectInlines.h" | |
| 40 #include "core/rendering/RenderRegion.h" | 40 #include "core/rendering/RenderRegion.h" |
| 41 #include "core/rendering/RenderView.h" | 41 #include "core/rendering/RenderView.h" |
| 42 #include "core/rendering/TextRunConstructor.h" | 42 #include "core/rendering/TextRunConstructor.h" |
| 43 #include "core/rendering/VerticalPositionCache.h" | 43 #include "core/rendering/VerticalPositionCache.h" |
| 44 #include "platform/fonts/Character.h" | 44 #include "platform/fonts/Character.h" |
| 45 #include "platform/text/BidiResolver.h" | 45 #include "platform/text/BidiResolver.h" |
| 46 #include "wtf/RefCountedLeakCounter.h" | 46 #include "wtf/RefCountedLeakCounter.h" |
| 47 #include "wtf/StdLibExtras.h" | 47 #include "wtf/StdLibExtras.h" |
| 48 #include "wtf/Vector.h" | 48 #include "wtf/Vector.h" |
| 49 #include "wtf/unicode/CharacterNames.h" | 49 #include "wtf/unicode/CharacterNames.h" |
| 50 | 50 |
| 51 namespace blink { | 51 namespace blink { |
| 52 | 52 |
| 53 using namespace WTF::Unicode; | 53 using namespace WTF::Unicode; |
| 54 | 54 |
| 55 static inline InlineBox* createInlineBoxForRenderer(RenderObject* obj, bool isRo
otLineBox, bool isOnlyRun = false) | 55 static inline InlineBox* createInlineBoxForRenderer(LayoutObject* obj, bool isRo
otLineBox, bool isOnlyRun = false) |
| 56 { | 56 { |
| 57 // Callers should handle text themselves. | 57 // Callers should handle text themselves. |
| 58 ASSERT(!obj->isText()); | 58 ASSERT(!obj->isText()); |
| 59 | 59 |
| 60 if (isRootLineBox) | 60 if (isRootLineBox) |
| 61 return toRenderBlockFlow(obj)->createAndAppendRootInlineBox(); | 61 return toRenderBlockFlow(obj)->createAndAppendRootInlineBox(); |
| 62 | 62 |
| 63 if (obj->isBox()) | 63 if (obj->isBox()) |
| 64 return toRenderBox(obj)->createInlineBox(); | 64 return toRenderBox(obj)->createInlineBox(); |
| 65 | 65 |
| 66 return toRenderInline(obj)->createAndAppendInlineFlowBox(); | 66 return toRenderInline(obj)->createAndAppendInlineFlowBox(); |
| 67 } | 67 } |
| 68 | 68 |
| 69 static inline InlineTextBox* createInlineBoxForText(BidiRun& run, bool isOnlyRun
) | 69 static inline InlineTextBox* createInlineBoxForText(BidiRun& run, bool isOnlyRun
) |
| 70 { | 70 { |
| 71 ASSERT(run.m_object->isText()); | 71 ASSERT(run.m_object->isText()); |
| 72 RenderText* text = toRenderText(run.m_object); | 72 RenderText* text = toRenderText(run.m_object); |
| 73 InlineTextBox* textBox = text->createInlineTextBox(run.m_start, run.m_stop -
run.m_start); | 73 InlineTextBox* textBox = text->createInlineTextBox(run.m_start, run.m_stop -
run.m_start); |
| 74 // We only treat a box as text for a <br> if we are on a line by ourself or
in strict mode | 74 // We only treat a box as text for a <br> if we are on a line by ourself or
in strict mode |
| 75 // (Note the use of strict mode. In "almost strict" mode, we don't treat th
e box for <br> as text.) | 75 // (Note the use of strict mode. In "almost strict" mode, we don't treat th
e box for <br> as text.) |
| 76 if (text->isBR()) | 76 if (text->isBR()) |
| 77 textBox->setIsText(isOnlyRun || text->document().inNoQuirksMode()); | 77 textBox->setIsText(isOnlyRun || text->document().inNoQuirksMode()); |
| 78 textBox->setDirOverride(run.dirOverride(text->style()->rtlOrdering() == Visu
alOrder)); | 78 textBox->setDirOverride(run.dirOverride(text->style()->rtlOrdering() == Visu
alOrder)); |
| 79 if (run.m_hasHyphen) | 79 if (run.m_hasHyphen) |
| 80 textBox->setHasHyphen(true); | 80 textBox->setHasHyphen(true); |
| 81 return textBox; | 81 return textBox; |
| 82 } | 82 } |
| 83 | 83 |
| 84 static inline void dirtyLineBoxesForRenderer(RenderObject* o, bool fullLayout) | 84 static inline void dirtyLineBoxesForRenderer(LayoutObject* o, bool fullLayout) |
| 85 { | 85 { |
| 86 if (o->isText()) { | 86 if (o->isText()) { |
| 87 RenderText* renderText = toRenderText(o); | 87 RenderText* renderText = toRenderText(o); |
| 88 renderText->dirtyOrDeleteLineBoxesIfNeeded(fullLayout); | 88 renderText->dirtyOrDeleteLineBoxesIfNeeded(fullLayout); |
| 89 } else | 89 } else |
| 90 toRenderInline(o)->dirtyLineBoxes(fullLayout); | 90 toRenderInline(o)->dirtyLineBoxes(fullLayout); |
| 91 } | 91 } |
| 92 | 92 |
| 93 static bool parentIsConstructedOrHaveNext(InlineFlowBox* parentBox) | 93 static bool parentIsConstructedOrHaveNext(InlineFlowBox* parentBox) |
| 94 { | 94 { |
| 95 do { | 95 do { |
| 96 if (parentBox->isConstructed() || parentBox->nextOnLine()) | 96 if (parentBox->isConstructed() || parentBox->nextOnLine()) |
| 97 return true; | 97 return true; |
| 98 parentBox = parentBox->parent(); | 98 parentBox = parentBox->parent(); |
| 99 } while (parentBox); | 99 } while (parentBox); |
| 100 return false; | 100 return false; |
| 101 } | 101 } |
| 102 | 102 |
| 103 InlineFlowBox* RenderBlockFlow::createLineBoxes(RenderObject* obj, const LineInf
o& lineInfo, InlineBox* childBox) | 103 InlineFlowBox* RenderBlockFlow::createLineBoxes(LayoutObject* obj, const LineInf
o& lineInfo, InlineBox* childBox) |
| 104 { | 104 { |
| 105 // See if we have an unconstructed line box for this object that is also | 105 // See if we have an unconstructed line box for this object that is also |
| 106 // the last item on the line. | 106 // the last item on the line. |
| 107 unsigned lineDepth = 1; | 107 unsigned lineDepth = 1; |
| 108 InlineFlowBox* parentBox = 0; | 108 InlineFlowBox* parentBox = 0; |
| 109 InlineFlowBox* result = 0; | 109 InlineFlowBox* result = 0; |
| 110 bool hasDefaultLineBoxContain = style()->lineBoxContain() == RenderStyle::in
itialLineBoxContain(); | 110 bool hasDefaultLineBoxContain = style()->lineBoxContain() == RenderStyle::in
itialLineBoxContain(); |
| 111 do { | 111 do { |
| 112 ASSERT_WITH_SECURITY_IMPLICATION(obj->isRenderInline() || obj == this); | 112 ASSERT_WITH_SECURITY_IMPLICATION(obj->isRenderInline() || obj == this); |
| 113 | 113 |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 172 } | 172 } |
| 173 return false; | 173 return false; |
| 174 } | 174 } |
| 175 | 175 |
| 176 static bool reachedEndOfTextRenderer(const BidiRunList<BidiRun>& bidiRuns) | 176 static bool reachedEndOfTextRenderer(const BidiRunList<BidiRun>& bidiRuns) |
| 177 { | 177 { |
| 178 BidiRun* run = bidiRuns.logicallyLastRun(); | 178 BidiRun* run = bidiRuns.logicallyLastRun(); |
| 179 if (!run) | 179 if (!run) |
| 180 return true; | 180 return true; |
| 181 unsigned pos = run->stop(); | 181 unsigned pos = run->stop(); |
| 182 RenderObject* r = run->m_object; | 182 LayoutObject* r = run->m_object; |
| 183 if (!r->isText() || r->isBR()) | 183 if (!r->isText() || r->isBR()) |
| 184 return false; | 184 return false; |
| 185 RenderText* renderText = toRenderText(r); | 185 RenderText* renderText = toRenderText(r); |
| 186 unsigned length = renderText->textLength(); | 186 unsigned length = renderText->textLength(); |
| 187 if (pos >= length) | 187 if (pos >= length) |
| 188 return true; | 188 return true; |
| 189 | 189 |
| 190 if (renderText->is8Bit()) | 190 if (renderText->is8Bit()) |
| 191 return endsWithASCIISpaces(renderText->characters8(), pos, length); | 191 return endsWithASCIISpaces(renderText->characters8(), pos, length); |
| 192 return endsWithASCIISpaces(renderText->characters16(), pos, length); | 192 return endsWithASCIISpaces(renderText->characters16(), pos, length); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 212 if (r->m_object->isText()) | 212 if (r->m_object->isText()) |
| 213 box = createInlineBoxForText(*r, isOnlyRun); | 213 box = createInlineBoxForText(*r, isOnlyRun); |
| 214 else | 214 else |
| 215 box = createInlineBoxForRenderer(r->m_object, false, isOnlyRun); | 215 box = createInlineBoxForRenderer(r->m_object, false, isOnlyRun); |
| 216 r->m_box = box; | 216 r->m_box = box; |
| 217 | 217 |
| 218 ASSERT(box); | 218 ASSERT(box); |
| 219 if (!box) | 219 if (!box) |
| 220 continue; | 220 continue; |
| 221 | 221 |
| 222 if (!rootHasSelectedChildren && box->renderer().selectionState() != Rend
erObject::SelectionNone) | 222 if (!rootHasSelectedChildren && box->renderer().selectionState() != Layo
utObject::SelectionNone) |
| 223 rootHasSelectedChildren = true; | 223 rootHasSelectedChildren = true; |
| 224 | 224 |
| 225 // If we have no parent box yet, or if the run is not simply a sibling, | 225 // If we have no parent box yet, or if the run is not simply a sibling, |
| 226 // then we need to construct inline boxes as necessary to properly enclo
se the | 226 // then we need to construct inline boxes as necessary to properly enclo
se the |
| 227 // run's inline box. Segments can only be siblings at the root level, as | 227 // run's inline box. Segments can only be siblings at the root level, as |
| 228 // they are positioned separately. | 228 // they are positioned separately. |
| 229 if (!parentBox || parentBox->renderer() != r->m_object->parent()) { | 229 if (!parentBox || parentBox->renderer() != r->m_object->parent()) { |
| 230 // Create new inline boxes all the way back to the appropriate inser
tion point. | 230 // Create new inline boxes all the way back to the appropriate inser
tion point. |
| 231 parentBox = createLineBoxes(r->m_object->parent(), lineInfo, box); | 231 parentBox = createLineBoxes(r->m_object->parent(), lineInfo, box); |
| 232 } else { | 232 } else { |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth(); | 342 totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth(); |
| 343 trailingSpaceWidth = std::min(trailingSpaceRun->m_box->logicalWidth().to
Float(), (availableLogicalWidth - totalLogicalWidth + 1) / 2); | 343 trailingSpaceWidth = std::min(trailingSpaceRun->m_box->logicalWidth().to
Float(), (availableLogicalWidth - totalLogicalWidth + 1) / 2); |
| 344 trailingSpaceRun->m_box->setLogicalWidth(std::max<float>(0, trailingSpac
eWidth)); | 344 trailingSpaceRun->m_box->setLogicalWidth(std::max<float>(0, trailingSpac
eWidth)); |
| 345 } | 345 } |
| 346 if (isLeftToRightDirection) | 346 if (isLeftToRightDirection) |
| 347 logicalLeft += std::max<float>((availableLogicalWidth - totalLogicalWidt
h) / 2, 0); | 347 logicalLeft += std::max<float>((availableLogicalWidth - totalLogicalWidt
h) / 2, 0); |
| 348 else | 348 else |
| 349 logicalLeft += totalLogicalWidth > availableLogicalWidth ? (availableLog
icalWidth - totalLogicalWidth) : (availableLogicalWidth - totalLogicalWidth) / 2
- trailingSpaceWidth; | 349 logicalLeft += totalLogicalWidth > availableLogicalWidth ? (availableLog
icalWidth - totalLogicalWidth) : (availableLogicalWidth - totalLogicalWidth) / 2
- trailingSpaceWidth; |
| 350 } | 350 } |
| 351 | 351 |
| 352 void RenderBlockFlow::setMarginsForRubyRun(BidiRun* run, LayoutRubyRun* renderer
, RenderObject* previousObject, const LineInfo& lineInfo) | 352 void RenderBlockFlow::setMarginsForRubyRun(BidiRun* run, LayoutRubyRun* renderer
, LayoutObject* previousObject, const LineInfo& lineInfo) |
| 353 { | 353 { |
| 354 int startOverhang; | 354 int startOverhang; |
| 355 int endOverhang; | 355 int endOverhang; |
| 356 RenderObject* nextObject = 0; | 356 LayoutObject* nextObject = 0; |
| 357 for (BidiRun* runWithNextObject = run->next(); runWithNextObject; runWithNex
tObject = runWithNextObject->next()) { | 357 for (BidiRun* runWithNextObject = run->next(); runWithNextObject; runWithNex
tObject = runWithNextObject->next()) { |
| 358 if (!runWithNextObject->m_object->isOutOfFlowPositioned() && !runWithNex
tObject->m_box->isLineBreak()) { | 358 if (!runWithNextObject->m_object->isOutOfFlowPositioned() && !runWithNex
tObject->m_box->isLineBreak()) { |
| 359 nextObject = runWithNextObject->m_object; | 359 nextObject = runWithNextObject->m_object; |
| 360 break; | 360 break; |
| 361 } | 361 } |
| 362 } | 362 } |
| 363 renderer->getOverhang(lineInfo.isFirstLine(), renderer->style()->isLeftToRig
htDirection() ? previousObject : nextObject, renderer->style()->isLeftToRightDir
ection() ? nextObject : previousObject, startOverhang, endOverhang); | 363 renderer->getOverhang(lineInfo.isFirstLine(), renderer->style()->isLeftToRig
htDirection() ? previousObject : nextObject, renderer->style()->isLeftToRightDir
ection() ? nextObject : previousObject, startOverhang, endOverhang); |
| 364 setMarginStartForChild(*renderer, -startOverhang); | 364 setMarginStartForChild(*renderer, -startOverhang); |
| 365 setMarginEndForChild(*renderer, -endOverhang); | 365 setMarginEndForChild(*renderer, -endOverhang); |
| 366 } | 366 } |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 576 | 576 |
| 577 BidiRun* RenderBlockFlow::computeInlineDirectionPositionsForSegment(RootInlineBo
x* lineBox, const LineInfo& lineInfo, ETextAlign textAlign, float& logicalLeft, | 577 BidiRun* RenderBlockFlow::computeInlineDirectionPositionsForSegment(RootInlineBo
x* lineBox, const LineInfo& lineInfo, ETextAlign textAlign, float& logicalLeft, |
| 578 float& availableLogicalWidth, BidiRun* firstRun, BidiRun* trailingSpaceRun,
GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& vertica
lPositionCache, | 578 float& availableLogicalWidth, BidiRun* firstRun, BidiRun* trailingSpaceRun,
GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& vertica
lPositionCache, |
| 579 WordMeasurements& wordMeasurements) | 579 WordMeasurements& wordMeasurements) |
| 580 { | 580 { |
| 581 bool needsWordSpacing = true; | 581 bool needsWordSpacing = true; |
| 582 float totalLogicalWidth = lineBox->getFlowSpacingLogicalWidth().toFloat(); | 582 float totalLogicalWidth = lineBox->getFlowSpacingLogicalWidth().toFloat(); |
| 583 unsigned expansionOpportunityCount = 0; | 583 unsigned expansionOpportunityCount = 0; |
| 584 bool isAfterExpansion = true; | 584 bool isAfterExpansion = true; |
| 585 Vector<unsigned, 16> expansionOpportunities; | 585 Vector<unsigned, 16> expansionOpportunities; |
| 586 RenderObject* previousObject = 0; | 586 LayoutObject* previousObject = 0; |
| 587 TextJustify textJustify = style()->textJustify(); | 587 TextJustify textJustify = style()->textJustify(); |
| 588 | 588 |
| 589 BidiRun* r = firstRun; | 589 BidiRun* r = firstRun; |
| 590 for (; r; r = r->next()) { | 590 for (; r; r = r->next()) { |
| 591 if (!r->m_box || r->m_object->isOutOfFlowPositioned() || r->m_box->isLin
eBreak()) | 591 if (!r->m_box || r->m_object->isOutOfFlowPositioned() || r->m_box->isLin
eBreak()) |
| 592 continue; // Positioned objects are only participating to figure out
their | 592 continue; // Positioned objects are only participating to figure out
their |
| 593 // correct static x position. They have no effect on the
width. | 593 // correct static x position. They have no effect on the
width. |
| 594 // Similarly, line break boxes have no effect on the width
. | 594 // Similarly, line break boxes have no effect on the width
. |
| 595 if (r->m_object->isText()) { | 595 if (r->m_object->isText()) { |
| 596 RenderText* rt = toRenderText(r->m_object); | 596 RenderText* rt = toRenderText(r->m_object); |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 749 if (!layoutState.usesPaintInvalidationBounds()) | 749 if (!layoutState.usesPaintInvalidationBounds()) |
| 750 layoutState.setPaintInvalidationRange(logicalHeight()); | 750 layoutState.setPaintInvalidationRange(logicalHeight()); |
| 751 deleteLineRange(layoutState, startLine); | 751 deleteLineRange(layoutState, startLine); |
| 752 } | 752 } |
| 753 | 753 |
| 754 if (!layoutState.isFullLayout() && lastRootBox() && lastRootBox()->endsWithB
reak()) { | 754 if (!layoutState.isFullLayout() && lastRootBox() && lastRootBox()->endsWithB
reak()) { |
| 755 // If the last line before the start line ends with a line break that cl
ear floats, | 755 // If the last line before the start line ends with a line break that cl
ear floats, |
| 756 // adjust the height accordingly. | 756 // adjust the height accordingly. |
| 757 // A line break can be either the first or the last object on a line, de
pending on its direction. | 757 // A line break can be either the first or the last object on a line, de
pending on its direction. |
| 758 if (InlineBox* lastLeafChild = lastRootBox()->lastLeafChild()) { | 758 if (InlineBox* lastLeafChild = lastRootBox()->lastLeafChild()) { |
| 759 RenderObject* lastObject = &lastLeafChild->renderer(); | 759 LayoutObject* lastObject = &lastLeafChild->renderer(); |
| 760 if (!lastObject->isBR()) | 760 if (!lastObject->isBR()) |
| 761 lastObject = &lastRootBox()->firstLeafChild()->renderer(); | 761 lastObject = &lastRootBox()->firstLeafChild()->renderer(); |
| 762 if (lastObject->isBR()) { | 762 if (lastObject->isBR()) { |
| 763 EClear clear = lastObject->style()->clear(); | 763 EClear clear = lastObject->style()->clear(); |
| 764 if (clear != CNONE) | 764 if (clear != CNONE) |
| 765 clearFloats(clear); | 765 clearFloats(clear); |
| 766 } | 766 } |
| 767 } | 767 } |
| 768 } | 768 } |
| 769 | 769 |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1081 | 1081 |
| 1082 struct InlineMinMaxIterator { | 1082 struct InlineMinMaxIterator { |
| 1083 /* InlineMinMaxIterator is a class that will iterate over all render objects tha
t contribute to | 1083 /* InlineMinMaxIterator is a class that will iterate over all render objects tha
t contribute to |
| 1084 inline min/max width calculations. Note the following about the way it walks
: | 1084 inline min/max width calculations. Note the following about the way it walks
: |
| 1085 (1) Positioned content is skipped (since it does not contribute to min/max wi
dth of a block) | 1085 (1) Positioned content is skipped (since it does not contribute to min/max wi
dth of a block) |
| 1086 (2) We do not drill into the children of floats or replaced elements, since y
ou can't break | 1086 (2) We do not drill into the children of floats or replaced elements, since y
ou can't break |
| 1087 in the middle of such an element. | 1087 in the middle of such an element. |
| 1088 (3) Inline flows (e.g., <a>, <span>, <i>) are walked twice, since each side c
an have | 1088 (3) Inline flows (e.g., <a>, <span>, <i>) are walked twice, since each side c
an have |
| 1089 distinct borders/margin/padding that contribute to the min/max width. | 1089 distinct borders/margin/padding that contribute to the min/max width. |
| 1090 */ | 1090 */ |
| 1091 RenderObject* parent; | 1091 LayoutObject* parent; |
| 1092 RenderObject* current; | 1092 LayoutObject* current; |
| 1093 bool endOfInline; | 1093 bool endOfInline; |
| 1094 | 1094 |
| 1095 InlineMinMaxIterator(RenderObject* p, bool end = false) | 1095 InlineMinMaxIterator(LayoutObject* p, bool end = false) |
| 1096 : parent(p), current(p), endOfInline(end) | 1096 : parent(p), current(p), endOfInline(end) |
| 1097 { | 1097 { |
| 1098 | 1098 |
| 1099 } | 1099 } |
| 1100 | 1100 |
| 1101 RenderObject* next(); | 1101 LayoutObject* next(); |
| 1102 }; | 1102 }; |
| 1103 | 1103 |
| 1104 RenderObject* InlineMinMaxIterator::next() | 1104 LayoutObject* InlineMinMaxIterator::next() |
| 1105 { | 1105 { |
| 1106 RenderObject* result = 0; | 1106 LayoutObject* result = 0; |
| 1107 bool oldEndOfInline = endOfInline; | 1107 bool oldEndOfInline = endOfInline; |
| 1108 endOfInline = false; | 1108 endOfInline = false; |
| 1109 while (current || current == parent) { | 1109 while (current || current == parent) { |
| 1110 if (!oldEndOfInline && (current == parent || (!current->isFloating() &&
!current->isReplaced() && !current->isOutOfFlowPositioned()))) | 1110 if (!oldEndOfInline && (current == parent || (!current->isFloating() &&
!current->isReplaced() && !current->isOutOfFlowPositioned()))) |
| 1111 result = current->slowFirstChild(); | 1111 result = current->slowFirstChild(); |
| 1112 | 1112 |
| 1113 if (!result) { | 1113 if (!result) { |
| 1114 // We hit the end of our inline. (It was empty, e.g., <span></span>.
) | 1114 // We hit the end of our inline. (It was empty, e.g., <span></span>.
) |
| 1115 if (!oldEndOfInline && current->isRenderInline()) { | 1115 if (!oldEndOfInline && current->isRenderInline()) { |
| 1116 result = current; | 1116 result = current; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1160 return getBPMWidth(child->marginEnd(), childStyle->marginEnd()) + | 1160 return getBPMWidth(child->marginEnd(), childStyle->marginEnd()) + |
| 1161 getBPMWidth(child->paddingEnd(), childStyle->paddingEnd()) + | 1161 getBPMWidth(child->paddingEnd(), childStyle->paddingEnd()) + |
| 1162 child->borderEnd(); | 1162 child->borderEnd(); |
| 1163 } | 1163 } |
| 1164 return getBPMWidth(child->marginStart(), childStyle->marginStart()) + | 1164 return getBPMWidth(child->marginStart(), childStyle->marginStart()) + |
| 1165 getBPMWidth(child->paddingStart(), childStyle->paddingStart()) + | 1165 getBPMWidth(child->paddingStart(), childStyle->paddingStart()) + |
| 1166 child->borderStart(); | 1166 child->borderStart(); |
| 1167 } | 1167 } |
| 1168 | 1168 |
| 1169 static inline void stripTrailingSpace(FloatWillBeLayoutUnit& inlineMax, FloatWil
lBeLayoutUnit& inlineMin, | 1169 static inline void stripTrailingSpace(FloatWillBeLayoutUnit& inlineMax, FloatWil
lBeLayoutUnit& inlineMin, |
| 1170 RenderObject* trailingSpaceChild) | 1170 LayoutObject* trailingSpaceChild) |
| 1171 { | 1171 { |
| 1172 if (trailingSpaceChild && trailingSpaceChild->isText()) { | 1172 if (trailingSpaceChild && trailingSpaceChild->isText()) { |
| 1173 // Collapse away the trailing space at the end of a block by finding | 1173 // Collapse away the trailing space at the end of a block by finding |
| 1174 // the first white-space character and subtracting its width. Subsequent | 1174 // the first white-space character and subtracting its width. Subsequent |
| 1175 // white-space characters have been collapsed into the first one (which | 1175 // white-space characters have been collapsed into the first one (which |
| 1176 // can be either a space or a tab character). | 1176 // can be either a space or a tab character). |
| 1177 RenderText* text = toRenderText(trailingSpaceChild); | 1177 RenderText* text = toRenderText(trailingSpaceChild); |
| 1178 UChar trailingWhitespaceChar = ' '; | 1178 UChar trailingWhitespaceChar = ' '; |
| 1179 for (unsigned i = text->textLength(); i > 0; i--) { | 1179 for (unsigned i = text->textLength(); i > 0; i--) { |
| 1180 UChar c = text->characterAt(i - 1); | 1180 UChar c = text->characterAt(i - 1); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1213 FloatWillBeLayoutUnit inlineMax; | 1213 FloatWillBeLayoutUnit inlineMax; |
| 1214 FloatWillBeLayoutUnit inlineMin; | 1214 FloatWillBeLayoutUnit inlineMin; |
| 1215 | 1215 |
| 1216 RenderStyle* styleToUse = style(); | 1216 RenderStyle* styleToUse = style(); |
| 1217 RenderBlock* containingBlock = this->containingBlock(); | 1217 RenderBlock* containingBlock = this->containingBlock(); |
| 1218 LayoutUnit cw = containingBlock ? containingBlock->contentLogicalWidth() : L
ayoutUnit(); | 1218 LayoutUnit cw = containingBlock ? containingBlock->contentLogicalWidth() : L
ayoutUnit(); |
| 1219 | 1219 |
| 1220 // If we are at the start of a line, we want to ignore all white-space. | 1220 // If we are at the start of a line, we want to ignore all white-space. |
| 1221 // Also strip spaces if we previously had text that ended in a trailing spac
e. | 1221 // Also strip spaces if we previously had text that ended in a trailing spac
e. |
| 1222 bool stripFrontSpaces = true; | 1222 bool stripFrontSpaces = true; |
| 1223 RenderObject* trailingSpaceChild = 0; | 1223 LayoutObject* trailingSpaceChild = 0; |
| 1224 | 1224 |
| 1225 // Firefox and Opera will allow a table cell to grow to fit an image inside
it under | 1225 // Firefox and Opera will allow a table cell to grow to fit an image inside
it under |
| 1226 // very specific cirucumstances (in order to match common WinIE renderings). | 1226 // very specific cirucumstances (in order to match common WinIE renderings). |
| 1227 // Not supporting the quirk has caused us to mis-render some real sites. (Se
e Bugzilla 10517.) | 1227 // Not supporting the quirk has caused us to mis-render some real sites. (Se
e Bugzilla 10517.) |
| 1228 bool allowImagesToBreak = !document().inQuirksMode() || !isTableCell() || !s
tyleToUse->logicalWidth().isIntrinsicOrAuto(); | 1228 bool allowImagesToBreak = !document().inQuirksMode() || !isTableCell() || !s
tyleToUse->logicalWidth().isIntrinsicOrAuto(); |
| 1229 | 1229 |
| 1230 bool autoWrap, oldAutoWrap; | 1230 bool autoWrap, oldAutoWrap; |
| 1231 autoWrap = oldAutoWrap = styleToUse->autoWrap(); | 1231 autoWrap = oldAutoWrap = styleToUse->autoWrap(); |
| 1232 | 1232 |
| 1233 InlineMinMaxIterator childIterator(this); | 1233 InlineMinMaxIterator childIterator(this); |
| 1234 | 1234 |
| 1235 // Only gets added to the max preffered width once. | 1235 // Only gets added to the max preffered width once. |
| 1236 bool addedTextIndent = false; | 1236 bool addedTextIndent = false; |
| 1237 // Signals the text indent was more negative than the min preferred width | 1237 // Signals the text indent was more negative than the min preferred width |
| 1238 bool hasRemainingNegativeTextIndent = false; | 1238 bool hasRemainingNegativeTextIndent = false; |
| 1239 | 1239 |
| 1240 LayoutUnit textIndent = minimumValueForLength(styleToUse->textIndent(), cw); | 1240 LayoutUnit textIndent = minimumValueForLength(styleToUse->textIndent(), cw); |
| 1241 RenderObject* prevFloat = 0; | 1241 LayoutObject* prevFloat = 0; |
| 1242 bool isPrevChildInlineFlow = false; | 1242 bool isPrevChildInlineFlow = false; |
| 1243 bool shouldBreakLineAfterText = false; | 1243 bool shouldBreakLineAfterText = false; |
| 1244 while (RenderObject* child = childIterator.next()) { | 1244 while (LayoutObject* child = childIterator.next()) { |
| 1245 autoWrap = child->isReplaced() ? child->parent()->style()->autoWrap() : | 1245 autoWrap = child->isReplaced() ? child->parent()->style()->autoWrap() : |
| 1246 child->style()->autoWrap(); | 1246 child->style()->autoWrap(); |
| 1247 | 1247 |
| 1248 if (!child->isBR()) { | 1248 if (!child->isBR()) { |
| 1249 // Step One: determine whether or not we need to go ahead and | 1249 // Step One: determine whether or not we need to go ahead and |
| 1250 // terminate our current line. Each discrete chunk can become | 1250 // terminate our current line. Each discrete chunk can become |
| 1251 // the new min-width, if it is the widest chunk seen so far, and | 1251 // the new min-width, if it is the widest chunk seen so far, and |
| 1252 // it can also become the max-width. | 1252 // it can also become the max-width. |
| 1253 | 1253 |
| 1254 // Children fall into three categories: | 1254 // Children fall into three categories: |
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1548 deleteEllipsisLineBoxes(); | 1548 deleteEllipsisLineBoxes(); |
| 1549 | 1549 |
| 1550 if (firstChild()) { | 1550 if (firstChild()) { |
| 1551 // In full layout mode, clear the line boxes of children upfront. Otherw
ise, | 1551 // In full layout mode, clear the line boxes of children upfront. Otherw
ise, |
| 1552 // siblings can run into stale root lineboxes during layout. Then layout | 1552 // siblings can run into stale root lineboxes during layout. Then layout |
| 1553 // the replaced elements later. In partial layout mode, line boxes are n
ot | 1553 // the replaced elements later. In partial layout mode, line boxes are n
ot |
| 1554 // deleted and only dirtied. In that case, we can layout the replaced | 1554 // deleted and only dirtied. In that case, we can layout the replaced |
| 1555 // elements at the same time. | 1555 // elements at the same time. |
| 1556 Vector<RenderBox*> replacedChildren; | 1556 Vector<RenderBox*> replacedChildren; |
| 1557 for (InlineWalker walker(this); !walker.atEnd(); walker.advance()) { | 1557 for (InlineWalker walker(this); !walker.atEnd(); walker.advance()) { |
| 1558 RenderObject* o = walker.current(); | 1558 LayoutObject* o = walker.current(); |
| 1559 | 1559 |
| 1560 if (!layoutState.hasInlineChild() && o->isInline()) | 1560 if (!layoutState.hasInlineChild() && o->isInline()) |
| 1561 layoutState.setHasInlineChild(true); | 1561 layoutState.setHasInlineChild(true); |
| 1562 | 1562 |
| 1563 if (o->isReplaced() || o->isFloating() || o->isOutOfFlowPositioned()
) { | 1563 if (o->isReplaced() || o->isFloating() || o->isOutOfFlowPositioned()
) { |
| 1564 RenderBox* box = toRenderBox(o); | 1564 RenderBox* box = toRenderBox(o); |
| 1565 | 1565 |
| 1566 updateBlockChildDirtyBitsBeforeLayout(relayoutChildren, *box); | 1566 updateBlockChildDirtyBitsBeforeLayout(relayoutChildren, *box); |
| 1567 | 1567 |
| 1568 if (o->isOutOfFlowPositioned()) | 1568 if (o->isOutOfFlowPositioned()) |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1881 | 1881 |
| 1882 // Now delete the lines that we failed to sync. | 1882 // Now delete the lines that we failed to sync. |
| 1883 deleteLineRange(layoutState, originalEndLine, result); | 1883 deleteLineRange(layoutState, originalEndLine, result); |
| 1884 return matched; | 1884 return matched; |
| 1885 } | 1885 } |
| 1886 } | 1886 } |
| 1887 | 1887 |
| 1888 return false; | 1888 return false; |
| 1889 } | 1889 } |
| 1890 | 1890 |
| 1891 bool RenderBlockFlow::generatesLineBoxesForInlineChild(RenderObject* inlineObj) | 1891 bool RenderBlockFlow::generatesLineBoxesForInlineChild(LayoutObject* inlineObj) |
| 1892 | 1892 |
| 1893 { | 1893 { |
| 1894 ASSERT(inlineObj->parent() == this); | 1894 ASSERT(inlineObj->parent() == this); |
| 1895 | 1895 |
| 1896 InlineIterator it(this, inlineObj, 0); | 1896 InlineIterator it(this, inlineObj, 0); |
| 1897 // FIXME: We should pass correct value for WhitespacePosition. | 1897 // FIXME: We should pass correct value for WhitespacePosition. |
| 1898 while (!it.atEnd() && !requiresLineBox(it)) | 1898 while (!it.atEnd() && !requiresLineBox(it)) |
| 1899 it.increment(); | 1899 it.increment(); |
| 1900 | 1900 |
| 1901 return !it.atEnd(); | 1901 return !it.atEnd(); |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2050 float logicalLeft = logicalLeftOffsetForLine(logicalHeight(), false).toFloat
(); | 2050 float logicalLeft = logicalLeftOffsetForLine(logicalHeight(), false).toFloat
(); |
| 2051 float availableLogicalWidth = logicalRightOffsetForLine(logicalHeight(), fal
se) - logicalLeft; | 2051 float availableLogicalWidth = logicalRightOffsetForLine(logicalHeight(), fal
se) - logicalLeft; |
| 2052 updateLogicalWidthForAlignment(textAlign, 0, 0, logicalLeft, totalLogicalWid
th, availableLogicalWidth, 0); | 2052 updateLogicalWidthForAlignment(textAlign, 0, 0, logicalLeft, totalLogicalWid
th, availableLogicalWidth, 0); |
| 2053 | 2053 |
| 2054 if (!style()->isLeftToRightDirection()) | 2054 if (!style()->isLeftToRightDirection()) |
| 2055 return logicalWidth() - logicalLeft; | 2055 return logicalWidth() - logicalLeft; |
| 2056 return logicalLeft; | 2056 return logicalLeft; |
| 2057 } | 2057 } |
| 2058 | 2058 |
| 2059 } | 2059 } |
| OLD | NEW |