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 |