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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 #include "platform/text/BidiResolver.h" | 44 #include "platform/text/BidiResolver.h" |
45 #include "wtf/RefCountedLeakCounter.h" | 45 #include "wtf/RefCountedLeakCounter.h" |
46 #include "wtf/StdLibExtras.h" | 46 #include "wtf/StdLibExtras.h" |
47 #include "wtf/Vector.h" | 47 #include "wtf/Vector.h" |
48 #include "wtf/unicode/CharacterNames.h" | 48 #include "wtf/unicode/CharacterNames.h" |
49 | 49 |
50 namespace blink { | 50 namespace blink { |
51 | 51 |
52 using namespace WTF::Unicode; | 52 using namespace WTF::Unicode; |
53 | 53 |
54 static inline InlineBox* createInlineBoxForRenderer(LayoutObject* obj, bool isRo
otLineBox, bool isOnlyRun = false) | 54 static inline InlineBox* createInlineBoxForLayoutObject(LayoutObject* obj, bool
isRootLineBox, bool isOnlyRun = false) |
55 { | 55 { |
56 // Callers should handle text themselves. | 56 // Callers should handle text themselves. |
57 ASSERT(!obj->isText()); | 57 ASSERT(!obj->isText()); |
58 | 58 |
59 if (isRootLineBox) | 59 if (isRootLineBox) |
60 return toLayoutBlockFlow(obj)->createAndAppendRootInlineBox(); | 60 return toLayoutBlockFlow(obj)->createAndAppendRootInlineBox(); |
61 | 61 |
62 if (obj->isBox()) | 62 if (obj->isBox()) |
63 return toLayoutBox(obj)->createInlineBox(); | 63 return toLayoutBox(obj)->createInlineBox(); |
64 | 64 |
65 return toLayoutInline(obj)->createAndAppendInlineFlowBox(); | 65 return toLayoutInline(obj)->createAndAppendInlineFlowBox(); |
66 } | 66 } |
67 | 67 |
68 static inline InlineTextBox* createInlineBoxForText(BidiRun& run, bool isOnlyRun
) | 68 static inline InlineTextBox* createInlineBoxForText(BidiRun& run, bool isOnlyRun
) |
69 { | 69 { |
70 ASSERT(run.m_object->isText()); | 70 ASSERT(run.m_object->isText()); |
71 LayoutText* text = toLayoutText(run.m_object); | 71 LayoutText* text = toLayoutText(run.m_object); |
72 InlineTextBox* textBox = text->createInlineTextBox(run.m_start, run.m_stop -
run.m_start); | 72 InlineTextBox* textBox = text->createInlineTextBox(run.m_start, run.m_stop -
run.m_start); |
73 // We only treat a box as text for a <br> if we are on a line by ourself or
in strict mode | 73 // We only treat a box as text for a <br> if we are on a line by ourself or
in strict mode |
74 // (Note the use of strict mode. In "almost strict" mode, we don't treat th
e box for <br> as text.) | 74 // (Note the use of strict mode. In "almost strict" mode, we don't treat th
e box for <br> as text.) |
75 if (text->isBR()) | 75 if (text->isBR()) |
76 textBox->setIsText(isOnlyRun || text->document().inNoQuirksMode()); | 76 textBox->setIsText(isOnlyRun || text->document().inNoQuirksMode()); |
77 textBox->setDirOverride(run.dirOverride(text->style()->rtlOrdering() == Visu
alOrder)); | 77 textBox->setDirOverride(run.dirOverride(text->style()->rtlOrdering() == Visu
alOrder)); |
78 if (run.m_hasHyphen) | 78 if (run.m_hasHyphen) |
79 textBox->setHasHyphen(true); | 79 textBox->setHasHyphen(true); |
80 return textBox; | 80 return textBox; |
81 } | 81 } |
82 | 82 |
83 static inline void dirtyLineBoxesForRenderer(LayoutObject* o, bool fullLayout) | 83 static inline void dirtyLineBoxesForObject(LayoutObject* o, bool fullLayout) |
84 { | 84 { |
85 if (o->isText()) { | 85 if (o->isText()) { |
86 LayoutText* layoutText = toLayoutText(o); | 86 LayoutText* layoutText = toLayoutText(o); |
87 layoutText->dirtyOrDeleteLineBoxesIfNeeded(fullLayout); | 87 layoutText->dirtyOrDeleteLineBoxesIfNeeded(fullLayout); |
88 } else { | 88 } else { |
89 toLayoutInline(o)->dirtyLineBoxes(fullLayout); | 89 toLayoutInline(o)->dirtyLineBoxes(fullLayout); |
90 } | 90 } |
91 } | 91 } |
92 | 92 |
93 static bool parentIsConstructedOrHaveNext(InlineFlowBox* parentBox) | 93 static bool parentIsConstructedOrHaveNext(InlineFlowBox* parentBox) |
(...skipping 12 matching lines...) Expand all Loading... |
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() == ComputedStyle::
initialLineBoxContain(); | 110 bool hasDefaultLineBoxContain = style()->lineBoxContain() == ComputedStyle::
initialLineBoxContain(); |
111 do { | 111 do { |
112 ASSERT_WITH_SECURITY_IMPLICATION(obj->isLayoutInline() || obj == this); | 112 ASSERT_WITH_SECURITY_IMPLICATION(obj->isLayoutInline() || obj == this); |
113 | 113 |
114 LayoutInline* inlineFlow = (obj != this) ? toLayoutInline(obj) : 0; | 114 LayoutInline* inlineFlow = (obj != this) ? toLayoutInline(obj) : 0; |
115 | 115 |
116 // Get the last box we made for this render object. | 116 // Get the last box we made for this layout object. |
117 parentBox = inlineFlow ? inlineFlow->lastLineBox() : toLayoutBlock(obj)-
>lastLineBox(); | 117 parentBox = inlineFlow ? inlineFlow->lastLineBox() : toLayoutBlock(obj)-
>lastLineBox(); |
118 | 118 |
119 // If this box or its ancestor is constructed then it is from a previous
line, and we need | 119 // If this box or its ancestor is constructed then it is from a previous
line, and we need |
120 // to make a new box for our line. If this box or its ancestor is uncon
structed but it has | 120 // to make a new box for our line. If this box or its ancestor is uncon
structed but it has |
121 // something following it on the line, then we know we have to make a ne
w box | 121 // something following it on the line, then we know we have to make a ne
w box |
122 // as well. In this situation our inline has actually been split in two
on | 122 // as well. In this situation our inline has actually been split in two
on |
123 // the same line (this can happen with very fancy language mixtures). | 123 // the same line (this can happen with very fancy language mixtures). |
124 bool constructedNewBox = false; | 124 bool constructedNewBox = false; |
125 bool allowedToConstructNewBox = !hasDefaultLineBoxContain || !inlineFlow
|| inlineFlow->alwaysCreateLineBoxes(); | 125 bool allowedToConstructNewBox = !hasDefaultLineBoxContain || !inlineFlow
|| inlineFlow->alwaysCreateLineBoxes(); |
126 bool canUseExistingParentBox = parentBox && !parentIsConstructedOrHaveNe
xt(parentBox); | 126 bool canUseExistingParentBox = parentBox && !parentIsConstructedOrHaveNe
xt(parentBox); |
127 if (allowedToConstructNewBox && !canUseExistingParentBox) { | 127 if (allowedToConstructNewBox && !canUseExistingParentBox) { |
128 // We need to make a new box for this render object. Once | 128 // We need to make a new box for this layout object. Once |
129 // made, we need to place it at the end of the current line. | 129 // made, we need to place it at the end of the current line. |
130 InlineBox* newBox = createInlineBoxForRenderer(obj, obj == this); | 130 InlineBox* newBox = createInlineBoxForLayoutObject(obj, obj == this)
; |
131 ASSERT_WITH_SECURITY_IMPLICATION(newBox->isInlineFlowBox()); | 131 ASSERT_WITH_SECURITY_IMPLICATION(newBox->isInlineFlowBox()); |
132 parentBox = toInlineFlowBox(newBox); | 132 parentBox = toInlineFlowBox(newBox); |
133 parentBox->setFirstLineStyleBit(lineInfo.isFirstLine()); | 133 parentBox->setFirstLineStyleBit(lineInfo.isFirstLine()); |
134 parentBox->setIsHorizontal(isHorizontalWritingMode()); | 134 parentBox->setIsHorizontal(isHorizontalWritingMode()); |
135 if (!hasDefaultLineBoxContain) | 135 if (!hasDefaultLineBoxContain) |
136 parentBox->clearDescendantsHaveSameLineHeightAndBaseline(); | 136 parentBox->clearDescendantsHaveSameLineHeightAndBaseline(); |
137 constructedNewBox = true; | 137 constructedNewBox = true; |
138 } | 138 } |
139 | 139 |
140 if (constructedNewBox || canUseExistingParentBox) { | 140 if (constructedNewBox || canUseExistingParentBox) { |
(...skipping 25 matching lines...) Expand all Loading... |
166 static inline bool endsWithASCIISpaces(const CharacterType* characters, unsigned
pos, unsigned end) | 166 static inline bool endsWithASCIISpaces(const CharacterType* characters, unsigned
pos, unsigned end) |
167 { | 167 { |
168 while (isASCIISpace(characters[pos])) { | 168 while (isASCIISpace(characters[pos])) { |
169 pos++; | 169 pos++; |
170 if (pos >= end) | 170 if (pos >= end) |
171 return true; | 171 return true; |
172 } | 172 } |
173 return false; | 173 return false; |
174 } | 174 } |
175 | 175 |
176 static bool reachedEndOfTextRenderer(const BidiRunList<BidiRun>& bidiRuns) | 176 static bool reachedEndOfTextRun(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 LayoutObject* 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 LayoutText* layoutText = toLayoutText(r); | 185 LayoutText* layoutText = toLayoutText(r); |
186 unsigned length = layoutText->textLength(); | 186 unsigned length = layoutText->textLength(); |
(...skipping 18 matching lines...) Expand all Loading... |
205 if (runCount == 2 && !r->m_object->isListMarker()) | 205 if (runCount == 2 && !r->m_object->isListMarker()) |
206 isOnlyRun = (!style()->isLeftToRightDirection() ? bidiRuns.lastRun()
: bidiRuns.firstRun())->m_object->isListMarker(); | 206 isOnlyRun = (!style()->isLeftToRightDirection() ? bidiRuns.lastRun()
: bidiRuns.firstRun())->m_object->isListMarker(); |
207 | 207 |
208 if (lineInfo.isEmpty()) | 208 if (lineInfo.isEmpty()) |
209 continue; | 209 continue; |
210 | 210 |
211 InlineBox* box; | 211 InlineBox* box; |
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 = createInlineBoxForLayoutObject(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->layoutObject().selectionState() !=
LayoutObject::SelectionNone) | 222 if (!rootHasSelectedChildren && box->layoutObject().selectionState() !=
LayoutObject::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, |
(...skipping 22 matching lines...) Expand all Loading... |
248 | 248 |
249 // Set the m_selectedChildren flag on the root inline box if one of the leaf
inline box | 249 // Set the m_selectedChildren flag on the root inline box if one of the leaf
inline box |
250 // from the bidi runs walk above has a selection state. | 250 // from the bidi runs walk above has a selection state. |
251 if (rootHasSelectedChildren) | 251 if (rootHasSelectedChildren) |
252 lastLineBox()->root().setHasSelectedChildren(true); | 252 lastLineBox()->root().setHasSelectedChildren(true); |
253 | 253 |
254 // Set bits on our inline flow boxes that indicate which sides should | 254 // Set bits on our inline flow boxes that indicate which sides should |
255 // paint borders/margins/padding. This knowledge will ultimately be used wh
en | 255 // paint borders/margins/padding. This knowledge will ultimately be used wh
en |
256 // we determine the horizontal positions and widths of all the inline boxes
on | 256 // we determine the horizontal positions and widths of all the inline boxes
on |
257 // the line. | 257 // the line. |
258 bool isLogicallyLastRunWrapped = bidiRuns.logicallyLastRun()->m_object && bi
diRuns.logicallyLastRun()->m_object->isText() ? !reachedEndOfTextRenderer(bidiRu
ns) : true; | 258 bool isLogicallyLastRunWrapped = bidiRuns.logicallyLastRun()->m_object && bi
diRuns.logicallyLastRun()->m_object->isText() ? !reachedEndOfTextRun(bidiRuns) :
true; |
259 lastLineBox()->determineSpacingForFlowBoxes(lineInfo.isLastLine(), isLogical
lyLastRunWrapped, bidiRuns.logicallyLastRun()->m_object); | 259 lastLineBox()->determineSpacingForFlowBoxes(lineInfo.isLastLine(), isLogical
lyLastRunWrapped, bidiRuns.logicallyLastRun()->m_object); |
260 | 260 |
261 // Now mark the line boxes as being constructed. | 261 // Now mark the line boxes as being constructed. |
262 lastLineBox()->setConstructed(); | 262 lastLineBox()->setConstructed(); |
263 | 263 |
264 // Return the last line. | 264 // Return the last line. |
265 return lastRootBox(); | 265 return lastRootBox(); |
266 } | 266 } |
267 | 267 |
268 ETextAlign LayoutBlockFlow::textAlignmentForLine(bool endsWithSoftBreak) const | 268 ETextAlign LayoutBlockFlow::textAlignmentForLine(bool endsWithSoftBreak) const |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth(); | 343 totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth(); |
344 trailingSpaceWidth = std::min(trailingSpaceRun->m_box->logicalWidth().to
Float(), (availableLogicalWidth - totalLogicalWidth + 1) / 2); | 344 trailingSpaceWidth = std::min(trailingSpaceRun->m_box->logicalWidth().to
Float(), (availableLogicalWidth - totalLogicalWidth + 1) / 2); |
345 trailingSpaceRun->m_box->setLogicalWidth(std::max<float>(0, trailingSpac
eWidth)); | 345 trailingSpaceRun->m_box->setLogicalWidth(std::max<float>(0, trailingSpac
eWidth)); |
346 } | 346 } |
347 if (isLeftToRightDirection) | 347 if (isLeftToRightDirection) |
348 logicalLeft += std::max<float>((availableLogicalWidth - totalLogicalWidt
h) / 2, 0); | 348 logicalLeft += std::max<float>((availableLogicalWidth - totalLogicalWidt
h) / 2, 0); |
349 else | 349 else |
350 logicalLeft += totalLogicalWidth > availableLogicalWidth ? (availableLog
icalWidth - totalLogicalWidth) : (availableLogicalWidth - totalLogicalWidth) / 2
- trailingSpaceWidth; | 350 logicalLeft += totalLogicalWidth > availableLogicalWidth ? (availableLog
icalWidth - totalLogicalWidth) : (availableLogicalWidth - totalLogicalWidth) / 2
- trailingSpaceWidth; |
351 } | 351 } |
352 | 352 |
353 void LayoutBlockFlow::setMarginsForRubyRun(BidiRun* run, LayoutRubyRun* renderer
, LayoutObject* previousObject, const LineInfo& lineInfo) | 353 void LayoutBlockFlow::setMarginsForRubyRun(BidiRun* run, LayoutRubyRun* layoutRu
byRun, LayoutObject* previousObject, const LineInfo& lineInfo) |
354 { | 354 { |
355 int startOverhang; | 355 int startOverhang; |
356 int endOverhang; | 356 int endOverhang; |
357 LayoutObject* nextObject = 0; | 357 LayoutObject* nextObject = 0; |
358 for (BidiRun* runWithNextObject = run->next(); runWithNextObject; runWithNex
tObject = runWithNextObject->next()) { | 358 for (BidiRun* runWithNextObject = run->next(); runWithNextObject; runWithNex
tObject = runWithNextObject->next()) { |
359 if (!runWithNextObject->m_object->isOutOfFlowPositioned() && !runWithNex
tObject->m_box->isLineBreak()) { | 359 if (!runWithNextObject->m_object->isOutOfFlowPositioned() && !runWithNex
tObject->m_box->isLineBreak()) { |
360 nextObject = runWithNextObject->m_object; | 360 nextObject = runWithNextObject->m_object; |
361 break; | 361 break; |
362 } | 362 } |
363 } | 363 } |
364 renderer->getOverhang(lineInfo.isFirstLine(), renderer->style()->isLeftToRig
htDirection() ? previousObject : nextObject, renderer->style()->isLeftToRightDir
ection() ? nextObject : previousObject, startOverhang, endOverhang); | 364 layoutRubyRun->getOverhang(lineInfo.isFirstLine(), layoutRubyRun->style()->i
sLeftToRightDirection() ? previousObject : nextObject, layoutRubyRun->style()->i
sLeftToRightDirection() ? nextObject : previousObject, startOverhang, endOverhan
g); |
365 setMarginStartForChild(*renderer, -startOverhang); | 365 setMarginStartForChild(*layoutRubyRun, -startOverhang); |
366 setMarginEndForChild(*renderer, -endOverhang); | 366 setMarginEndForChild(*layoutRubyRun, -endOverhang); |
367 } | 367 } |
368 | 368 |
369 static inline void setLogicalWidthForTextRun(RootInlineBox* lineBox, BidiRun* ru
n, LayoutText* renderer, float xPos, const LineInfo& lineInfo, | 369 static inline void setLogicalWidthForTextRun(RootInlineBox* lineBox, BidiRun* ru
n, LayoutText* layoutText, float xPos, const LineInfo& lineInfo, |
370 GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& ver
ticalPositionCache, WordMeasurements& wordMeasurements) | 370 GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& ver
ticalPositionCache, WordMeasurements& wordMeasurements) |
371 { | 371 { |
372 HashSet<const SimpleFontData*> fallbackFonts; | 372 HashSet<const SimpleFontData*> fallbackFonts; |
373 GlyphOverflow glyphOverflow; | 373 GlyphOverflow glyphOverflow; |
374 | 374 |
375 const Font& font = renderer->style(lineInfo.isFirstLine())->font(); | 375 const Font& font = layoutText->style(lineInfo.isFirstLine())->font(); |
376 // Always compute glyph overflow if the block's line-box-contain value is "g
lyphs". | 376 // Always compute glyph overflow if the block's line-box-contain value is "g
lyphs". |
377 if (lineBox->fitsToGlyphs()) { | 377 if (lineBox->fitsToGlyphs()) { |
378 // If we don't stick out of the root line's font box, then don't bother
computing our glyph overflow. This optimization | 378 // If we don't stick out of the root line's font box, then don't bother
computing our glyph overflow. This optimization |
379 // will keep us from computing glyph bounds in nearly all cases. | 379 // will keep us from computing glyph bounds in nearly all cases. |
380 bool includeRootLine = lineBox->includesRootLineBoxFontOrLeading(); | 380 bool includeRootLine = lineBox->includesRootLineBoxFontOrLeading(); |
381 int baselineShift = lineBox->verticalPositionForBox(run->m_box, vertical
PositionCache); | 381 int baselineShift = lineBox->verticalPositionForBox(run->m_box, vertical
PositionCache); |
382 int rootDescent = includeRootLine ? font.fontMetrics().descent() : 0; | 382 int rootDescent = includeRootLine ? font.fontMetrics().descent() : 0; |
383 int rootAscent = includeRootLine ? font.fontMetrics().ascent() : 0; | 383 int rootAscent = includeRootLine ? font.fontMetrics().ascent() : 0; |
384 int boxAscent = font.fontMetrics().ascent() - baselineShift; | 384 int boxAscent = font.fontMetrics().ascent() - baselineShift; |
385 int boxDescent = font.fontMetrics().descent() + baselineShift; | 385 int boxDescent = font.fontMetrics().descent() + baselineShift; |
386 if (boxAscent > rootDescent || boxDescent > rootAscent) | 386 if (boxAscent > rootDescent || boxDescent > rootAscent) |
387 glyphOverflow.computeBounds = true; | 387 glyphOverflow.computeBounds = true; |
388 } | 388 } |
389 | 389 |
390 LayoutUnit hyphenWidth = 0; | 390 LayoutUnit hyphenWidth = 0; |
391 if (toInlineTextBox(run->m_box)->hasHyphen()) { | 391 if (toInlineTextBox(run->m_box)->hasHyphen()) { |
392 const Font& font = renderer->style(lineInfo.isFirstLine())->font(); | 392 const Font& font = layoutText->style(lineInfo.isFirstLine())->font(); |
393 hyphenWidth = measureHyphenWidth(renderer, font, run->direction()); | 393 hyphenWidth = measureHyphenWidth(layoutText, font, run->direction()); |
394 } | 394 } |
395 float measuredWidth = 0; | 395 float measuredWidth = 0; |
396 | 396 |
397 bool kerningIsEnabled = font.fontDescription().typesettingFeatures() & Kerni
ng; | 397 bool kerningIsEnabled = font.fontDescription().typesettingFeatures() & Kerni
ng; |
398 | 398 |
399 #if OS(MACOSX) | 399 #if OS(MACOSX) |
400 // FIXME: Having any font feature settings enabled can lead to selection gap
s on | 400 // FIXME: Having any font feature settings enabled can lead to selection gap
s on |
401 // Chromium-mac. https://bugs.webkit.org/show_bug.cgi?id=113418 | 401 // Chromium-mac. https://bugs.webkit.org/show_bug.cgi?id=113418 |
402 bool canUseSimpleFontCodePath = renderer->canUseSimpleFontCodePath() && !fon
t.fontDescription().featureSettings(); | 402 bool canUseSimpleFontCodePath = layoutText->canUseSimpleFontCodePath() && !f
ont.fontDescription().featureSettings(); |
403 #else | 403 #else |
404 bool canUseSimpleFontCodePath = renderer->canUseSimpleFontCodePath(); | 404 bool canUseSimpleFontCodePath = layoutText->canUseSimpleFontCodePath(); |
405 #endif | 405 #endif |
406 | 406 |
407 // For complex text we need to compute the glyph bounds as accents can exten
d outside the frameRect. | 407 // For complex text we need to compute the glyph bounds as accents can exten
d outside the frameRect. |
408 if (!canUseSimpleFontCodePath) | 408 if (!canUseSimpleFontCodePath) |
409 glyphOverflow.computeBounds = true; | 409 glyphOverflow.computeBounds = true; |
410 | 410 |
411 // Since we don't cache glyph overflows, we need to re-measure the run if | 411 // Since we don't cache glyph overflows, we need to re-measure the run if |
412 // the style is linebox-contain: glyph. | 412 // the style is linebox-contain: glyph. |
413 | 413 |
414 if (!lineBox->fitsToGlyphs() && canUseSimpleFontCodePath) { | 414 if (!lineBox->fitsToGlyphs() && canUseSimpleFontCodePath) { |
415 int lastEndOffset = run->m_start; | 415 int lastEndOffset = run->m_start; |
416 for (size_t i = 0, size = wordMeasurements.size(); i < size && lastEndOf
fset < run->m_stop; ++i) { | 416 for (size_t i = 0, size = wordMeasurements.size(); i < size && lastEndOf
fset < run->m_stop; ++i) { |
417 const WordMeasurement& wordMeasurement = wordMeasurements[i]; | 417 const WordMeasurement& wordMeasurement = wordMeasurements[i]; |
418 if (wordMeasurement.width <=0 || wordMeasurement.startOffset == word
Measurement.endOffset) | 418 if (wordMeasurement.width <=0 || wordMeasurement.startOffset == word
Measurement.endOffset) |
419 continue; | 419 continue; |
420 if (wordMeasurement.renderer != renderer || wordMeasurement.startOff
set != lastEndOffset || wordMeasurement.endOffset > run->m_stop) | 420 if (wordMeasurement.layoutText != layoutText || wordMeasurement.star
tOffset != lastEndOffset || wordMeasurement.endOffset > run->m_stop) |
421 continue; | 421 continue; |
422 | 422 |
423 lastEndOffset = wordMeasurement.endOffset; | 423 lastEndOffset = wordMeasurement.endOffset; |
424 if (kerningIsEnabled && lastEndOffset == run->m_stop) { | 424 if (kerningIsEnabled && lastEndOffset == run->m_stop) { |
425 int wordLength = lastEndOffset - wordMeasurement.startOffset; | 425 int wordLength = lastEndOffset - wordMeasurement.startOffset; |
426 measuredWidth += renderer->width(wordMeasurement.startOffset, wo
rdLength, xPos, run->direction(), lineInfo.isFirstLine()); | 426 measuredWidth += layoutText->width(wordMeasurement.startOffset,
wordLength, xPos, run->direction(), lineInfo.isFirstLine()); |
427 if (i > 0 && wordLength == 1 && renderer->characterAt(wordMeasur
ement.startOffset) == ' ') | 427 if (i > 0 && wordLength == 1 && layoutText->characterAt(wordMeas
urement.startOffset) == ' ') |
428 measuredWidth += renderer->style()->wordSpacing(); | 428 measuredWidth += layoutText->style()->wordSpacing(); |
429 } else { | 429 } else { |
430 measuredWidth += wordMeasurement.width; | 430 measuredWidth += wordMeasurement.width; |
431 } | 431 } |
432 if (!wordMeasurement.fallbackFonts.isEmpty()) { | 432 if (!wordMeasurement.fallbackFonts.isEmpty()) { |
433 HashSet<const SimpleFontData*>::const_iterator end = wordMeasure
ment.fallbackFonts.end(); | 433 HashSet<const SimpleFontData*>::const_iterator end = wordMeasure
ment.fallbackFonts.end(); |
434 for (HashSet<const SimpleFontData*>::const_iterator it = wordMea
surement.fallbackFonts.begin(); it != end; ++it) | 434 for (HashSet<const SimpleFontData*>::const_iterator it = wordMea
surement.fallbackFonts.begin(); it != end; ++it) |
435 fallbackFonts.add(*it); | 435 fallbackFonts.add(*it); |
436 } | 436 } |
437 } | 437 } |
438 if (measuredWidth && lastEndOffset != run->m_stop) { | 438 if (measuredWidth && lastEndOffset != run->m_stop) { |
439 // If we don't have enough cached data, we'll measure the run again. | 439 // If we don't have enough cached data, we'll measure the run again. |
440 measuredWidth = 0; | 440 measuredWidth = 0; |
441 fallbackFonts.clear(); | 441 fallbackFonts.clear(); |
442 } | 442 } |
443 } | 443 } |
444 | 444 |
445 if (!measuredWidth) | 445 if (!measuredWidth) |
446 measuredWidth = renderer->width(run->m_start, run->m_stop - run->m_start
, xPos, run->direction(), lineInfo.isFirstLine(), &fallbackFonts, &glyphOverflow
); | 446 measuredWidth = layoutText->width(run->m_start, run->m_stop - run->m_sta
rt, xPos, run->direction(), lineInfo.isFirstLine(), &fallbackFonts, &glyphOverfl
ow); |
447 | 447 |
448 run->m_box->setLogicalWidth(measuredWidth + hyphenWidth); | 448 run->m_box->setLogicalWidth(measuredWidth + hyphenWidth); |
449 if (!fallbackFonts.isEmpty()) { | 449 if (!fallbackFonts.isEmpty()) { |
450 ASSERT(run->m_box->isText()); | 450 ASSERT(run->m_box->isText()); |
451 GlyphOverflowAndFallbackFontsMap::ValueType* it = textBoxDataMap.add(toI
nlineTextBox(run->m_box), std::make_pair(Vector<const SimpleFontData*>(), GlyphO
verflow())).storedValue; | 451 GlyphOverflowAndFallbackFontsMap::ValueType* it = textBoxDataMap.add(toI
nlineTextBox(run->m_box), std::make_pair(Vector<const SimpleFontData*>(), GlyphO
verflow())).storedValue; |
452 ASSERT(it->value.first.isEmpty()); | 452 ASSERT(it->value.first.isEmpty()); |
453 copyToVector(fallbackFonts, it->value.first); | 453 copyToVector(fallbackFonts, it->value.first); |
454 run->m_box->parent()->clearDescendantsHaveSameLineHeightAndBaseline(); | 454 run->m_box->parent()->clearDescendantsHaveSameLineHeightAndBaseline(); |
455 } | 455 } |
456 if (!glyphOverflow.isZero()) { | 456 if (!glyphOverflow.isZero()) { |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
537 else | 537 else |
538 updateLogicalWidthForLeftAlignedBlock(style()->isLeftToRightDirectio
n(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth); | 538 updateLogicalWidthForLeftAlignedBlock(style()->isLeftToRightDirectio
n(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth); |
539 break; | 539 break; |
540 } | 540 } |
541 if (style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) | 541 if (style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) |
542 logicalLeft += verticalScrollbarWidth(); | 542 logicalLeft += verticalScrollbarWidth(); |
543 } | 543 } |
544 | 544 |
545 static void updateLogicalInlinePositions(LayoutBlockFlow* block, float& lineLogi
calLeft, float& lineLogicalRight, float& availableLogicalWidth, bool firstLine,
IndentTextOrNot shouldIndentText, LayoutUnit boxLogicalHeight) | 545 static void updateLogicalInlinePositions(LayoutBlockFlow* block, float& lineLogi
calLeft, float& lineLogicalRight, float& availableLogicalWidth, bool firstLine,
IndentTextOrNot shouldIndentText, LayoutUnit boxLogicalHeight) |
546 { | 546 { |
547 LayoutUnit lineLogicalHeight = block->minLineHeightForReplacedRenderer(first
Line, boxLogicalHeight); | 547 LayoutUnit lineLogicalHeight = block->minLineHeightForReplacedObject(firstLi
ne, boxLogicalHeight); |
548 lineLogicalLeft = block->logicalLeftOffsetForLine(block->logicalHeight(), sh
ouldIndentText == IndentText, lineLogicalHeight).toFloat(); | 548 lineLogicalLeft = block->logicalLeftOffsetForLine(block->logicalHeight(), sh
ouldIndentText == IndentText, lineLogicalHeight).toFloat(); |
549 lineLogicalRight = block->logicalRightOffsetForLine(block->logicalHeight(),
shouldIndentText == IndentText, lineLogicalHeight).toFloat(); | 549 lineLogicalRight = block->logicalRightOffsetForLine(block->logicalHeight(),
shouldIndentText == IndentText, lineLogicalHeight).toFloat(); |
550 availableLogicalWidth = lineLogicalRight - lineLogicalLeft; | 550 availableLogicalWidth = lineLogicalRight - lineLogicalLeft; |
551 } | 551 } |
552 | 552 |
553 void LayoutBlockFlow::computeInlineDirectionPositionsForLine(RootInlineBox* line
Box, const LineInfo& lineInfo, BidiRun* firstRun, BidiRun* trailingSpaceRun, boo
l reachedEnd, | 553 void LayoutBlockFlow::computeInlineDirectionPositionsForLine(RootInlineBox* line
Box, const LineInfo& lineInfo, BidiRun* firstRun, BidiRun* trailingSpaceRun, boo
l reachedEnd, |
554 GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& ver
ticalPositionCache, WordMeasurements& wordMeasurements) | 554 GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& ver
ticalPositionCache, WordMeasurements& wordMeasurements) |
555 { | 555 { |
556 ETextAlign textAlign = textAlignmentForLine(!reachedEnd && !lineBox->endsWit
hBreak()); | 556 ETextAlign textAlign = textAlignmentForLine(!reachedEnd && !lineBox->endsWit
hBreak()); |
557 | 557 |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
646 computeExpansionForJustifiedText(firstRun, trailingSpaceRun, expansionOpport
unities, expansionOpportunityCount, totalLogicalWidth, availableLogicalWidth); | 646 computeExpansionForJustifiedText(firstRun, trailingSpaceRun, expansionOpport
unities, expansionOpportunityCount, totalLogicalWidth, availableLogicalWidth); |
647 | 647 |
648 return r; | 648 return r; |
649 } | 649 } |
650 | 650 |
651 void LayoutBlockFlow::computeBlockDirectionPositionsForLine(RootInlineBox* lineB
ox, BidiRun* firstRun, GlyphOverflowAndFallbackFontsMap& textBoxDataMap, | 651 void LayoutBlockFlow::computeBlockDirectionPositionsForLine(RootInlineBox* lineB
ox, BidiRun* firstRun, GlyphOverflowAndFallbackFontsMap& textBoxDataMap, |
652 VerticalPositionCache& verticalPositionCache) | 652 VerticalPositionCache& verticalPositionCache) |
653 { | 653 { |
654 setLogicalHeight(lineBox->alignBoxesInBlockDirection(logicalHeight(), textBo
xDataMap, verticalPositionCache)); | 654 setLogicalHeight(lineBox->alignBoxesInBlockDirection(logicalHeight(), textBo
xDataMap, verticalPositionCache)); |
655 | 655 |
656 // Now make sure we place replaced render objects correctly. | 656 // Now make sure we place replaced layout objects correctly. |
657 for (BidiRun* r = firstRun; r; r = r->next()) { | 657 for (BidiRun* r = firstRun; r; r = r->next()) { |
658 ASSERT(r->m_box); | 658 ASSERT(r->m_box); |
659 if (!r->m_box) | 659 if (!r->m_box) |
660 continue; // Skip runs with no line boxes. | 660 continue; // Skip runs with no line boxes. |
661 | 661 |
662 // Align positioned boxes with the top of the line box. This is | 662 // Align positioned boxes with the top of the line box. This is |
663 // a reasonable approximation of an appropriate y position. | 663 // a reasonable approximation of an appropriate y position. |
664 if (r->m_object->isOutOfFlowPositioned()) | 664 if (r->m_object->isOutOfFlowPositioned()) |
665 r->m_box->setLogicalTop(logicalHeight().toFloat()); | 665 r->m_box->setLogicalTop(logicalHeight().toFloat()); |
666 | 666 |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
790 | 790 |
791 void LayoutBlockFlow::layoutRunsAndFloatsInRange(LineLayoutState& layoutState, | 791 void LayoutBlockFlow::layoutRunsAndFloatsInRange(LineLayoutState& layoutState, |
792 InlineBidiResolver& resolver, const InlineIterator& cleanLineStart, | 792 InlineBidiResolver& resolver, const InlineIterator& cleanLineStart, |
793 const BidiStatus& cleanLineBidiStatus) | 793 const BidiStatus& cleanLineBidiStatus) |
794 { | 794 { |
795 const ComputedStyle& styleToUse = styleRef(); | 795 const ComputedStyle& styleToUse = styleRef(); |
796 bool paginated = view()->layoutState() && view()->layoutState()->isPaginated
(); | 796 bool paginated = view()->layoutState() && view()->layoutState()->isPaginated
(); |
797 LineMidpointState& lineMidpointState = resolver.midpointState(); | 797 LineMidpointState& lineMidpointState = resolver.midpointState(); |
798 InlineIterator endOfLine = resolver.position(); | 798 InlineIterator endOfLine = resolver.position(); |
799 bool checkForEndLineMatch = layoutState.endLine(); | 799 bool checkForEndLineMatch = layoutState.endLine(); |
800 LayoutTextInfo renderTextInfo; | 800 LayoutTextInfo layoutTextInfo; |
801 VerticalPositionCache verticalPositionCache; | 801 VerticalPositionCache verticalPositionCache; |
802 | 802 |
803 LineBreaker lineBreaker(this); | 803 LineBreaker lineBreaker(this); |
804 | 804 |
805 while (!endOfLine.atEnd()) { | 805 while (!endOfLine.atEnd()) { |
806 bool logicalWidthIsAvailable = false; | 806 bool logicalWidthIsAvailable = false; |
807 | 807 |
808 // FIXME: Is this check necessary before the first iteration or can it b
e moved to the end? | 808 // FIXME: Is this check necessary before the first iteration or can it b
e moved to the end? |
809 if (checkForEndLineMatch) { | 809 if (checkForEndLineMatch) { |
810 layoutState.setEndLineMatched(matchedEndLine(layoutState, resolver,
cleanLineStart, cleanLineBidiStatus)); | 810 layoutState.setEndLineMatched(matchedEndLine(layoutState, resolver,
cleanLineStart, cleanLineBidiStatus)); |
811 if (layoutState.endLineMatched()) { | 811 if (layoutState.endLineMatched()) { |
812 resolver.setPosition(InlineIterator(resolver.position().root(),
0, 0), 0); | 812 resolver.setPosition(InlineIterator(resolver.position().root(),
0, 0), 0); |
813 break; | 813 break; |
814 } | 814 } |
815 } | 815 } |
816 | 816 |
817 lineMidpointState.reset(); | 817 lineMidpointState.reset(); |
818 | 818 |
819 layoutState.lineInfo().setEmpty(true); | 819 layoutState.lineInfo().setEmpty(true); |
820 layoutState.lineInfo().resetRunsFromLeadingWhitespace(); | 820 layoutState.lineInfo().resetRunsFromLeadingWhitespace(); |
821 | 821 |
822 const InlineIterator previousEndofLine = endOfLine; | 822 const InlineIterator previousEndofLine = endOfLine; |
823 bool isNewUBAParagraph = layoutState.lineInfo().previousLineBrokeCleanly
(); | 823 bool isNewUBAParagraph = layoutState.lineInfo().previousLineBrokeCleanly
(); |
824 FloatingObject* lastFloatFromPreviousLine = (containsFloats()) ? m_float
ingObjects->set().last().get() : 0; | 824 FloatingObject* lastFloatFromPreviousLine = (containsFloats()) ? m_float
ingObjects->set().last().get() : 0; |
825 | 825 |
826 WordMeasurements wordMeasurements; | 826 WordMeasurements wordMeasurements; |
827 endOfLine = lineBreaker.nextLineBreak(resolver, layoutState.lineInfo(),
renderTextInfo, | 827 endOfLine = lineBreaker.nextLineBreak(resolver, layoutState.lineInfo(),
layoutTextInfo, |
828 lastFloatFromPreviousLine, wordMeasurements); | 828 lastFloatFromPreviousLine, wordMeasurements); |
829 renderTextInfo.m_lineBreakIterator.resetPriorContext(); | 829 layoutTextInfo.m_lineBreakIterator.resetPriorContext(); |
830 if (resolver.position().atEnd()) { | 830 if (resolver.position().atEnd()) { |
831 // FIXME: We shouldn't be creating any runs in nextLineBreak to begi
n with! | 831 // FIXME: We shouldn't be creating any runs in nextLineBreak to begi
n with! |
832 // Once BidiRunList is separated from BidiResolver this will not be
needed. | 832 // Once BidiRunList is separated from BidiResolver this will not be
needed. |
833 resolver.runs().deleteRuns(); | 833 resolver.runs().deleteRuns(); |
834 resolver.markCurrentRunEmpty(); // FIXME: This can probably be repla
ced by an ASSERT (or just removed). | 834 resolver.markCurrentRunEmpty(); // FIXME: This can probably be repla
ced by an ASSERT (or just removed). |
835 layoutState.setCheckForFloatsFromLastLine(true); | 835 layoutState.setCheckForFloatsFromLastLine(true); |
836 resolver.setPosition(InlineIterator(resolver.position().root(), 0, 0
), 0); | 836 resolver.setPosition(InlineIterator(resolver.position().root(), 0, 0
), 0); |
837 break; | 837 break; |
838 } | 838 } |
839 | 839 |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1077 for (size_t i = 0; i < floatCount; ++i) { | 1077 for (size_t i = 0; i < floatCount; ++i) { |
1078 if (!floats[i].everHadLayout) { | 1078 if (!floats[i].everHadLayout) { |
1079 LayoutBox* f = floats[i].object; | 1079 LayoutBox* f = floats[i].object; |
1080 if (!f->location().x() && !f->location().y()) | 1080 if (!f->location().x() && !f->location().y()) |
1081 f->setShouldDoFullPaintInvalidation(); | 1081 f->setShouldDoFullPaintInvalidation(); |
1082 } | 1082 } |
1083 } | 1083 } |
1084 } | 1084 } |
1085 | 1085 |
1086 struct InlineMinMaxIterator { | 1086 struct InlineMinMaxIterator { |
1087 /* InlineMinMaxIterator is a class that will iterate over all render objects tha
t contribute to | 1087 /* InlineMinMaxIterator is a class that will iterate over all layout objects tha
t contribute to |
1088 inline min/max width calculations. Note the following about the way it walks
: | 1088 inline min/max width calculations. Note the following about the way it walks
: |
1089 (1) Positioned content is skipped (since it does not contribute to min/max wi
dth of a block) | 1089 (1) Positioned content is skipped (since it does not contribute to min/max wi
dth of a block) |
1090 (2) We do not drill into the children of floats or replaced elements, since y
ou can't break | 1090 (2) We do not drill into the children of floats or replaced elements, since y
ou can't break |
1091 in the middle of such an element. | 1091 in the middle of such an element. |
1092 (3) Inline flows (e.g., <a>, <span>, <i>) are walked twice, since each side c
an have | 1092 (3) Inline flows (e.g., <a>, <span>, <i>) are walked twice, since each side c
an have |
1093 distinct borders/margin/padding that contribute to the min/max width. | 1093 distinct borders/margin/padding that contribute to the min/max width. |
1094 */ | 1094 */ |
1095 LayoutObject* parent; | 1095 LayoutObject* parent; |
1096 LayoutObject* current; | 1096 LayoutObject* current; |
1097 bool endOfInline; | 1097 bool endOfInline; |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1220 const ComputedStyle& styleToUse = styleRef(); | 1220 const ComputedStyle& styleToUse = styleRef(); |
1221 LayoutBlock* containingBlock = this->containingBlock(); | 1221 LayoutBlock* containingBlock = this->containingBlock(); |
1222 LayoutUnit cw = containingBlock ? containingBlock->contentLogicalWidth() : L
ayoutUnit(); | 1222 LayoutUnit cw = containingBlock ? containingBlock->contentLogicalWidth() : L
ayoutUnit(); |
1223 | 1223 |
1224 // If we are at the start of a line, we want to ignore all white-space. | 1224 // If we are at the start of a line, we want to ignore all white-space. |
1225 // Also strip spaces if we previously had text that ended in a trailing spac
e. | 1225 // Also strip spaces if we previously had text that ended in a trailing spac
e. |
1226 bool stripFrontSpaces = true; | 1226 bool stripFrontSpaces = true; |
1227 LayoutObject* trailingSpaceChild = 0; | 1227 LayoutObject* trailingSpaceChild = 0; |
1228 | 1228 |
1229 // Firefox and Opera will allow a table cell to grow to fit an image inside
it under | 1229 // Firefox and Opera will allow a table cell to grow to fit an image inside
it under |
1230 // very specific cirucumstances (in order to match common WinIE renderings). | 1230 // very specific cirucumstances (in order to match common WinIE layouts). |
1231 // Not supporting the quirk has caused us to mis-render some real sites. (Se
e Bugzilla 10517.) | 1231 // Not supporting the quirk has caused us to mis-layout some real sites. (Se
e Bugzilla 10517.) |
1232 bool allowImagesToBreak = !document().inQuirksMode() || !isTableCell() || !s
tyleToUse.logicalWidth().isIntrinsicOrAuto(); | 1232 bool allowImagesToBreak = !document().inQuirksMode() || !isTableCell() || !s
tyleToUse.logicalWidth().isIntrinsicOrAuto(); |
1233 | 1233 |
1234 bool autoWrap, oldAutoWrap; | 1234 bool autoWrap, oldAutoWrap; |
1235 autoWrap = oldAutoWrap = styleToUse.autoWrap(); | 1235 autoWrap = oldAutoWrap = styleToUse.autoWrap(); |
1236 | 1236 |
1237 InlineMinMaxIterator childIterator(this); | 1237 InlineMinMaxIterator childIterator(this); |
1238 | 1238 |
1239 // Only gets added to the max preffered width once. | 1239 // Only gets added to the max preffered width once. |
1240 bool addedTextIndent = false; | 1240 bool addedTextIndent = false; |
1241 // Signals the text indent was more negative than the min preferred width | 1241 // Signals the text indent was more negative than the min preferred width |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1410 // check. | 1410 // check. |
1411 bool hasBreakableChar, hasBreak; | 1411 bool hasBreakableChar, hasBreak; |
1412 FloatWillBeLayoutUnit firstLineMinWidth, lastLineMinWidth; | 1412 FloatWillBeLayoutUnit firstLineMinWidth, lastLineMinWidth; |
1413 bool hasBreakableStart, hasBreakableEnd; | 1413 bool hasBreakableStart, hasBreakableEnd; |
1414 FloatWillBeLayoutUnit firstLineMaxWidth, lastLineMaxWidth; | 1414 FloatWillBeLayoutUnit firstLineMaxWidth, lastLineMaxWidth; |
1415 t->trimmedPrefWidths(inlineMax, | 1415 t->trimmedPrefWidths(inlineMax, |
1416 firstLineMinWidth, hasBreakableStart, lastLineMinWidth, hasB
reakableEnd, | 1416 firstLineMinWidth, hasBreakableStart, lastLineMinWidth, hasB
reakableEnd, |
1417 hasBreakableChar, hasBreak, firstLineMaxWidth, lastLineMaxWi
dth, | 1417 hasBreakableChar, hasBreak, firstLineMaxWidth, lastLineMaxWi
dth, |
1418 childMin, childMax, stripFrontSpaces, styleToUse.direction()
); | 1418 childMin, childMax, stripFrontSpaces, styleToUse.direction()
); |
1419 | 1419 |
1420 // This text object will not be rendered, but it may still provi
de a breaking opportunity. | 1420 // This text object will not be layed out, but it may still prov
ide a breaking opportunity. |
1421 if (!hasBreak && !childMax) { | 1421 if (!hasBreak && !childMax) { |
1422 if (autoWrap && (hasBreakableStart || hasBreakableEnd)) { | 1422 if (autoWrap && (hasBreakableStart || hasBreakableEnd)) { |
1423 minLogicalWidth = std::max(minLogicalWidth, inlineMin.to
LayoutUnit()); | 1423 minLogicalWidth = std::max(minLogicalWidth, inlineMin.to
LayoutUnit()); |
1424 inlineMin = FloatWillBeLayoutUnit(); | 1424 inlineMin = FloatWillBeLayoutUnit(); |
1425 } | 1425 } |
1426 continue; | 1426 continue; |
1427 } | 1427 } |
1428 | 1428 |
1429 if (stripFrontSpaces) | 1429 if (stripFrontSpaces) |
1430 trailingSpaceChild = child; | 1430 trailingSpaceChild = child; |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1578 box->dirtyLineBoxes(isFullLayout); | 1578 box->dirtyLineBoxes(isFullLayout); |
1579 if (isFullLayout) | 1579 if (isFullLayout) |
1580 replacedChildren.append(box); | 1580 replacedChildren.append(box); |
1581 else | 1581 else |
1582 o->layoutIfNeeded(); | 1582 o->layoutIfNeeded(); |
1583 } | 1583 } |
1584 } else if (o->isText() || (o->isLayoutInline() && !walker.atEndOfInl
ine())) { | 1584 } else if (o->isText() || (o->isLayoutInline() && !walker.atEndOfInl
ine())) { |
1585 if (!o->isText()) | 1585 if (!o->isText()) |
1586 toLayoutInline(o)->updateAlwaysCreateLineBoxes(layoutState.i
sFullLayout()); | 1586 toLayoutInline(o)->updateAlwaysCreateLineBoxes(layoutState.i
sFullLayout()); |
1587 if (layoutState.isFullLayout() || o->selfNeedsLayout()) | 1587 if (layoutState.isFullLayout() || o->selfNeedsLayout()) |
1588 dirtyLineBoxesForRenderer(o, layoutState.isFullLayout()); | 1588 dirtyLineBoxesForObject(o, layoutState.isFullLayout()); |
1589 o->clearNeedsLayout(); | 1589 o->clearNeedsLayout(); |
1590 } | 1590 } |
1591 } | 1591 } |
1592 | 1592 |
1593 for (size_t i = 0; i < replacedChildren.size(); i++) | 1593 for (size_t i = 0; i < replacedChildren.size(); i++) |
1594 replacedChildren[i]->layoutIfNeeded(); | 1594 replacedChildren[i]->layoutIfNeeded(); |
1595 | 1595 |
1596 layoutRunsAndFloats(layoutState); | 1596 layoutRunsAndFloats(layoutState); |
1597 } | 1597 } |
1598 | 1598 |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1798 | 1798 |
1799 // At this point, |last| is the first line in a run of clean lines that ends
with the last line | 1799 // At this point, |last| is the first line in a run of clean lines that ends
with the last line |
1800 // in the block. | 1800 // in the block. |
1801 | 1801 |
1802 RootInlineBox* prev = last->prevRootBox(); | 1802 RootInlineBox* prev = last->prevRootBox(); |
1803 cleanLineStart = InlineIterator(this, prev->lineBreakObj(), prev->lineBreakP
os()); | 1803 cleanLineStart = InlineIterator(this, prev->lineBreakObj(), prev->lineBreakP
os()); |
1804 cleanLineBidiStatus = prev->lineBreakBidiStatus(); | 1804 cleanLineBidiStatus = prev->lineBreakBidiStatus(); |
1805 layoutState.setEndLineLogicalTop(prev->lineBottomWithLeading()); | 1805 layoutState.setEndLineLogicalTop(prev->lineBottomWithLeading()); |
1806 | 1806 |
1807 for (RootInlineBox* line = last; line; line = line->nextRootBox()) | 1807 for (RootInlineBox* line = last; line; line = line->nextRootBox()) |
1808 line->extractLine(); // Disconnect all line boxes from their render obje
cts while preserving | 1808 line->extractLine(); // Disconnect all line boxes from their layout obje
cts while preserving |
1809 // their connections to one another. | 1809 // their connections to one another. |
1810 | 1810 |
1811 layoutState.setEndLine(last); | 1811 layoutState.setEndLine(last); |
1812 } | 1812 } |
1813 | 1813 |
1814 bool LayoutBlockFlow::checkPaginationAndFloatsAtEndLine(LineLayoutState& layoutS
tate) | 1814 bool LayoutBlockFlow::checkPaginationAndFloatsAtEndLine(LineLayoutState& layoutS
tate) |
1815 { | 1815 { |
1816 LayoutUnit lineDelta = logicalHeight() - layoutState.endLineLogicalTop(); | 1816 LayoutUnit lineDelta = logicalHeight() - layoutState.endLineLogicalTop(); |
1817 | 1817 |
1818 bool paginated = view()->layoutState() && view()->layoutState()->isPaginated
(); | 1818 bool paginated = view()->layoutState() && view()->layoutState()->isPaginated
(); |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2052 float logicalLeft = logicalLeftOffsetForLine(logicalHeight(), false).toFloat
(); | 2052 float logicalLeft = logicalLeftOffsetForLine(logicalHeight(), false).toFloat
(); |
2053 float availableLogicalWidth = logicalRightOffsetForLine(logicalHeight(), fal
se) - logicalLeft; | 2053 float availableLogicalWidth = logicalRightOffsetForLine(logicalHeight(), fal
se) - logicalLeft; |
2054 updateLogicalWidthForAlignment(textAlign, 0, 0, logicalLeft, totalLogicalWid
th, availableLogicalWidth, 0); | 2054 updateLogicalWidthForAlignment(textAlign, 0, 0, logicalLeft, totalLogicalWid
th, availableLogicalWidth, 0); |
2055 | 2055 |
2056 if (!style()->isLeftToRightDirection()) | 2056 if (!style()->isLeftToRightDirection()) |
2057 return logicalWidth() - logicalLeft; | 2057 return logicalWidth() - logicalLeft; |
2058 return logicalLeft; | 2058 return logicalLeft; |
2059 } | 2059 } |
2060 | 2060 |
2061 } | 2061 } |
OLD | NEW |