| 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 |