| 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 * Copyright (C) 2013 Adobe Systems Incorporated. | 5 * Copyright (C) 2013 Adobe Systems Incorporated. |
| 6 * | 6 * |
| 7 * This library is free software; you can redistribute it and/or | 7 * This library is free software; you can redistribute it and/or |
| 8 * modify it under the terms of the GNU Library General Public | 8 * modify it under the terms of the GNU Library General Public |
| 9 * License as published by the Free Software Foundation; either | 9 * License as published by the Free Software Foundation; either |
| 10 * version 2 of the License, or (at your option) any later version. | 10 * version 2 of the License, or (at your option) any later version. |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 const unsigned cMaxLineDepth = 200; | 51 const unsigned cMaxLineDepth = 200; |
| 52 | 52 |
| 53 class BreakingContext { | 53 class BreakingContext { |
| 54 STACK_ALLOCATED(); | 54 STACK_ALLOCATED(); |
| 55 public: | 55 public: |
| 56 BreakingContext(InlineBidiResolver& resolver, LineInfo& inLineInfo, LineWidt
h& lineWidth, LayoutTextInfo& inLayoutTextInfo, FloatingObject* inLastFloatFromP
reviousLine, bool appliedStartWidth, LineLayoutBlockFlow block) | 56 BreakingContext(InlineBidiResolver& resolver, LineInfo& inLineInfo, LineWidt
h& lineWidth, LayoutTextInfo& inLayoutTextInfo, FloatingObject* inLastFloatFromP
reviousLine, bool appliedStartWidth, LineLayoutBlockFlow block) |
| 57 : m_resolver(resolver) | 57 : m_resolver(resolver) |
| 58 , m_current(resolver.position()) | 58 , m_current(resolver.position()) |
| 59 , m_lineBreak(resolver.position()) | 59 , m_lineBreak(resolver.position()) |
| 60 , m_block(block) | 60 , m_block(block) |
| 61 , m_lastObject(m_current.lineLayoutItem()) | 61 , m_lastObject(m_current.getLineLayoutItem()) |
| 62 , m_nextObject(nullptr) | 62 , m_nextObject(nullptr) |
| 63 , m_currentStyle(nullptr) | 63 , m_currentStyle(nullptr) |
| 64 , m_blockStyle(block.style()) | 64 , m_blockStyle(block.style()) |
| 65 , m_lineInfo(inLineInfo) | 65 , m_lineInfo(inLineInfo) |
| 66 , m_layoutTextInfo(inLayoutTextInfo) | 66 , m_layoutTextInfo(inLayoutTextInfo) |
| 67 , m_lastFloatFromPreviousLine(inLastFloatFromPreviousLine) | 67 , m_lastFloatFromPreviousLine(inLastFloatFromPreviousLine) |
| 68 , m_width(lineWidth) | 68 , m_width(lineWidth) |
| 69 , m_currWS(NORMAL) | 69 , m_currWS(NORMAL) |
| 70 , m_lastWS(NORMAL) | 70 , m_lastWS(NORMAL) |
| 71 , m_preservesNewline(false) | 71 , m_preservesNewline(false) |
| 72 , m_atStart(true) | 72 , m_atStart(true) |
| 73 , m_ignoringSpaces(false) | 73 , m_ignoringSpaces(false) |
| 74 , m_currentCharacterIsSpace(false) | 74 , m_currentCharacterIsSpace(false) |
| 75 , m_appliedStartWidth(appliedStartWidth) | 75 , m_appliedStartWidth(appliedStartWidth) |
| 76 , m_includeEndWidth(true) | 76 , m_includeEndWidth(true) |
| 77 , m_autoWrap(false) | 77 , m_autoWrap(false) |
| 78 , m_autoWrapWasEverTrueOnLine(false) | 78 , m_autoWrapWasEverTrueOnLine(false) |
| 79 , m_floatsFitOnLine(true) | 79 , m_floatsFitOnLine(true) |
| 80 , m_collapseWhiteSpace(false) | 80 , m_collapseWhiteSpace(false) |
| 81 , m_startingNewParagraph(m_lineInfo.previousLineBrokeCleanly()) | 81 , m_startingNewParagraph(m_lineInfo.previousLineBrokeCleanly()) |
| 82 , m_allowImagesToBreak(!block.document().inQuirksMode() || !block.isTabl
eCell() || !m_blockStyle->logicalWidth().isIntrinsicOrAuto()) | 82 , m_allowImagesToBreak(!block.document().inQuirksMode() || !block.isTabl
eCell() || !m_blockStyle->logicalWidth().isIntrinsicOrAuto()) |
| 83 , m_atEnd(false) | 83 , m_atEnd(false) |
| 84 , m_lineMidpointState(resolver.midpointState()) | 84 , m_lineMidpointState(resolver.midpointState()) |
| 85 { | 85 { |
| 86 m_lineInfo.setPreviousLineBrokeCleanly(false); | 86 m_lineInfo.setPreviousLineBrokeCleanly(false); |
| 87 } | 87 } |
| 88 | 88 |
| 89 LineLayoutItem currentItem() { return m_current.lineLayoutItem(); } | 89 LineLayoutItem currentItem() { return m_current.getLineLayoutItem(); } |
| 90 InlineIterator lineBreak() { return m_lineBreak; } | 90 InlineIterator lineBreak() { return m_lineBreak; } |
| 91 bool atEnd() { return m_atEnd; } | 91 bool atEnd() { return m_atEnd; } |
| 92 | 92 |
| 93 void initializeForCurrentObject(); | 93 void initializeForCurrentObject(); |
| 94 | 94 |
| 95 void increment(); | 95 void increment(); |
| 96 | 96 |
| 97 void handleBR(EClear&); | 97 void handleBR(EClear&); |
| 98 void handleOutOfFlowPositioned(Vector<LineLayoutBox>& positionedObjects); | 98 void handleOutOfFlowPositioned(Vector<LineLayoutBox>& positionedObjects); |
| 99 void handleFloat(); | 99 void handleFloat(); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 inline bool alwaysRequiresLineBox(LineLayoutItem flow) | 193 inline bool alwaysRequiresLineBox(LineLayoutItem flow) |
| 194 { | 194 { |
| 195 // FIXME: Right now, we only allow line boxes for inlines that are truly emp
ty. | 195 // FIXME: Right now, we only allow line boxes for inlines that are truly emp
ty. |
| 196 // We need to fix this, though, because at the very least, inlines containin
g only | 196 // We need to fix this, though, because at the very least, inlines containin
g only |
| 197 // ignorable whitespace should should also have line boxes. | 197 // ignorable whitespace should should also have line boxes. |
| 198 return isEmptyInline(flow) && LineLayoutInline(flow).hasInlineDirectionBorde
rsPaddingOrMargin(); | 198 return isEmptyInline(flow) && LineLayoutInline(flow).hasInlineDirectionBorde
rsPaddingOrMargin(); |
| 199 } | 199 } |
| 200 | 200 |
| 201 inline bool requiresLineBox(const InlineIterator& it, const LineInfo& lineInfo =
LineInfo(), WhitespacePosition whitespacePosition = LeadingWhitespace) | 201 inline bool requiresLineBox(const InlineIterator& it, const LineInfo& lineInfo =
LineInfo(), WhitespacePosition whitespacePosition = LeadingWhitespace) |
| 202 { | 202 { |
| 203 if (it.lineLayoutItem().isFloatingOrOutOfFlowPositioned()) | 203 if (it.getLineLayoutItem().isFloatingOrOutOfFlowPositioned()) |
| 204 return false; | 204 return false; |
| 205 | 205 |
| 206 if (it.lineLayoutItem().isLayoutInline() && !alwaysRequiresLineBox(it.lineLa
youtItem()) && !requiresLineBoxForContent(LineLayoutInline(it.lineLayoutItem()),
lineInfo)) | 206 if (it.getLineLayoutItem().isLayoutInline() && !alwaysRequiresLineBox(it.get
LineLayoutItem()) && !requiresLineBoxForContent(LineLayoutInline(it.getLineLayou
tItem()), lineInfo)) |
| 207 return false; | 207 return false; |
| 208 | 208 |
| 209 if (!shouldCollapseWhiteSpace(it.lineLayoutItem().styleRef(), lineInfo, whit
espacePosition) || it.lineLayoutItem().isBR()) | 209 if (!shouldCollapseWhiteSpace(it.getLineLayoutItem().styleRef(), lineInfo, w
hitespacePosition) || it.getLineLayoutItem().isBR()) |
| 210 return true; | 210 return true; |
| 211 | 211 |
| 212 UChar current = it.current(); | 212 UChar current = it.current(); |
| 213 bool notJustWhitespace = current != spaceCharacter && current != tabulationC
haracter && current != softHyphenCharacter && (current != newlineCharacter || it
.lineLayoutItem().preservesNewline()); | 213 bool notJustWhitespace = current != spaceCharacter && current != tabulationC
haracter && current != softHyphenCharacter && (current != newlineCharacter || it
.getLineLayoutItem().preservesNewline()); |
| 214 return notJustWhitespace || isEmptyInline(it.lineLayoutItem()); | 214 return notJustWhitespace || isEmptyInline(it.getLineLayoutItem()); |
| 215 } | 215 } |
| 216 | 216 |
| 217 inline void setStaticPositions(LineLayoutBlockFlow block, LineLayoutBox child, I
ndentTextOrNot indentText) | 217 inline void setStaticPositions(LineLayoutBlockFlow block, LineLayoutBox child, I
ndentTextOrNot indentText) |
| 218 { | 218 { |
| 219 ASSERT(child.isOutOfFlowPositioned()); | 219 ASSERT(child.isOutOfFlowPositioned()); |
| 220 // FIXME: The math here is actually not really right. It's a best-guess appr
oximation that | 220 // FIXME: The math here is actually not really right. It's a best-guess appr
oximation that |
| 221 // will work for the common cases | 221 // will work for the common cases |
| 222 LineLayoutItem containerBlock = child.container(); | 222 LineLayoutItem containerBlock = child.container(); |
| 223 LayoutUnit blockHeight = block.logicalHeight(); | 223 LayoutUnit blockHeight = block.logicalHeight(); |
| 224 if (containerBlock.isLayoutInline()) { | 224 if (containerBlock.isLayoutInline()) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 238 | 238 |
| 239 // FIXME: The entire concept of the skipTrailingWhitespace function is flawed, s
ince we really need to be building | 239 // FIXME: The entire concept of the skipTrailingWhitespace function is flawed, s
ince we really need to be building |
| 240 // line boxes even for containers that may ultimately collapse away. Otherwise w
e'll never get positioned | 240 // line boxes even for containers that may ultimately collapse away. Otherwise w
e'll never get positioned |
| 241 // elements quite right. In other words, we need to build this function's work i
nto the normal line | 241 // elements quite right. In other words, we need to build this function's work i
nto the normal line |
| 242 // object iteration process. | 242 // object iteration process. |
| 243 // NB. this function will insert any floating elements that would otherwise | 243 // NB. this function will insert any floating elements that would otherwise |
| 244 // be skipped but it will not position them. | 244 // be skipped but it will not position them. |
| 245 inline void BreakingContext::skipTrailingWhitespace(InlineIterator& iterator, co
nst LineInfo& lineInfo) | 245 inline void BreakingContext::skipTrailingWhitespace(InlineIterator& iterator, co
nst LineInfo& lineInfo) |
| 246 { | 246 { |
| 247 while (!iterator.atEnd() && !requiresLineBox(iterator, lineInfo, TrailingWhi
tespace)) { | 247 while (!iterator.atEnd() && !requiresLineBox(iterator, lineInfo, TrailingWhi
tespace)) { |
| 248 LineLayoutItem item = iterator.lineLayoutItem(); | 248 LineLayoutItem item = iterator.getLineLayoutItem(); |
| 249 if (item.isOutOfFlowPositioned()) | 249 if (item.isOutOfFlowPositioned()) |
| 250 setStaticPositions(m_block, LineLayoutBox(item), DoNotIndentText); | 250 setStaticPositions(m_block, LineLayoutBox(item), DoNotIndentText); |
| 251 else if (item.isFloating()) | 251 else if (item.isFloating()) |
| 252 m_block.insertFloatingObject(LineLayoutBox(item)); | 252 m_block.insertFloatingObject(LineLayoutBox(item)); |
| 253 iterator.increment(); | 253 iterator.increment(); |
| 254 } | 254 } |
| 255 } | 255 } |
| 256 | 256 |
| 257 inline void BreakingContext::initializeForCurrentObject() | 257 inline void BreakingContext::initializeForCurrentObject() |
| 258 { | 258 { |
| 259 m_currentStyle = m_current.lineLayoutItem().style(); | 259 m_currentStyle = m_current.getLineLayoutItem().style(); |
| 260 m_nextObject = bidiNextSkippingEmptyInlines(m_block, m_current.lineLayoutIte
m()); | 260 m_nextObject = bidiNextSkippingEmptyInlines(m_block, m_current.getLineLayout
Item()); |
| 261 if (m_nextObject && m_nextObject.parent() && !m_nextObject.parent().isDescen
dantOf(m_current.lineLayoutItem().parent())) | 261 if (m_nextObject && m_nextObject.parent() && !m_nextObject.parent().isDescen
dantOf(m_current.getLineLayoutItem().parent())) |
| 262 m_includeEndWidth = true; | 262 m_includeEndWidth = true; |
| 263 | 263 |
| 264 m_currWS = m_current.lineLayoutItem().isLayoutInline() ? m_currentStyle->whi
teSpace() : m_current.lineLayoutItem().parent().style()->whiteSpace(); | 264 m_currWS = m_current.getLineLayoutItem().isLayoutInline() ? m_currentStyle->
whiteSpace() : m_current.getLineLayoutItem().parent().style()->whiteSpace(); |
| 265 m_lastWS = m_lastObject.isLayoutInline() ? m_lastObject.style()->whiteSpace(
) : m_lastObject.parent().style()->whiteSpace(); | 265 m_lastWS = m_lastObject.isLayoutInline() ? m_lastObject.style()->whiteSpace(
) : m_lastObject.parent().style()->whiteSpace(); |
| 266 | 266 |
| 267 bool isSVGText = m_current.lineLayoutItem().isSVGInlineText(); | 267 bool isSVGText = m_current.getLineLayoutItem().isSVGInlineText(); |
| 268 m_autoWrap = !isSVGText && ComputedStyle::autoWrap(m_currWS); | 268 m_autoWrap = !isSVGText && ComputedStyle::autoWrap(m_currWS); |
| 269 m_autoWrapWasEverTrueOnLine = m_autoWrapWasEverTrueOnLine || m_autoWrap; | 269 m_autoWrapWasEverTrueOnLine = m_autoWrapWasEverTrueOnLine || m_autoWrap; |
| 270 | 270 |
| 271 m_preservesNewline = !isSVGText && ComputedStyle::preserveNewline(m_currWS); | 271 m_preservesNewline = !isSVGText && ComputedStyle::preserveNewline(m_currWS); |
| 272 | 272 |
| 273 m_collapseWhiteSpace = ComputedStyle::collapseWhiteSpace(m_currWS); | 273 m_collapseWhiteSpace = ComputedStyle::collapseWhiteSpace(m_currWS); |
| 274 | 274 |
| 275 // Ensure the whitespace in constructions like '<span style="white-space: pr
e-wrap">text <span><span> text</span>' | 275 // Ensure the whitespace in constructions like '<span style="white-space: pr
e-wrap">text <span><span> text</span>' |
| 276 // does not collapse. | 276 // does not collapse. |
| 277 if (m_collapseWhiteSpace && !ComputedStyle::collapseWhiteSpace(m_lastWS)) | 277 if (m_collapseWhiteSpace && !ComputedStyle::collapseWhiteSpace(m_lastWS)) |
| 278 m_currentCharacterIsSpace = false; | 278 m_currentCharacterIsSpace = false; |
| 279 } | 279 } |
| 280 | 280 |
| 281 inline void BreakingContext::increment() | 281 inline void BreakingContext::increment() |
| 282 { | 282 { |
| 283 m_current.moveToStartOf(m_nextObject); | 283 m_current.moveToStartOf(m_nextObject); |
| 284 | 284 |
| 285 // When the line box tree is created, this position in the line will be snap
ped to | 285 // When the line box tree is created, this position in the line will be snap
ped to |
| 286 // LayoutUnit's, and those measurements will be used by the paint code. Do
the | 286 // LayoutUnit's, and those measurements will be used by the paint code. Do
the |
| 287 // equivalent snapping here, to get consistent line measurements. | 287 // equivalent snapping here, to get consistent line measurements. |
| 288 m_width.snapUncommittedWidth(); | 288 m_width.snapUncommittedWidth(); |
| 289 | 289 |
| 290 m_atStart = false; | 290 m_atStart = false; |
| 291 } | 291 } |
| 292 | 292 |
| 293 inline void BreakingContext::handleBR(EClear& clear) | 293 inline void BreakingContext::handleBR(EClear& clear) |
| 294 { | 294 { |
| 295 if (m_width.fitsOnLine()) { | 295 if (m_width.fitsOnLine()) { |
| 296 LineLayoutItem br = m_current.lineLayoutItem(); | 296 LineLayoutItem br = m_current.getLineLayoutItem(); |
| 297 m_lineBreak.moveToStartOf(br); | 297 m_lineBreak.moveToStartOf(br); |
| 298 m_lineBreak.increment(); | 298 m_lineBreak.increment(); |
| 299 | 299 |
| 300 // A <br> always breaks a line, so don't let the line be collapsed | 300 // A <br> always breaks a line, so don't let the line be collapsed |
| 301 // away. Also, the space at the end of a line with a <br> does not | 301 // away. Also, the space at the end of a line with a <br> does not |
| 302 // get collapsed away. It only does this if the previous line broke | 302 // get collapsed away. It only does this if the previous line broke |
| 303 // cleanly. Otherwise the <br> has no effect on whether the line is | 303 // cleanly. Otherwise the <br> has no effect on whether the line is |
| 304 // empty or not. | 304 // empty or not. |
| 305 if (m_startingNewParagraph) | 305 if (m_startingNewParagraph) |
| 306 m_lineInfo.setEmpty(false, m_block, &m_width); | 306 m_lineInfo.setEmpty(false, m_block, &m_width); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 355 child = parent; | 355 child = parent; |
| 356 parent = child.parent(); | 356 parent = child.parent(); |
| 357 } | 357 } |
| 358 return extraWidth; | 358 return extraWidth; |
| 359 } | 359 } |
| 360 | 360 |
| 361 inline void BreakingContext::handleOutOfFlowPositioned(Vector<LineLayoutBox>& po
sitionedObjects) | 361 inline void BreakingContext::handleOutOfFlowPositioned(Vector<LineLayoutBox>& po
sitionedObjects) |
| 362 { | 362 { |
| 363 // If our original display wasn't an inline type, then we can | 363 // If our original display wasn't an inline type, then we can |
| 364 // go ahead and determine our static inline position now. | 364 // go ahead and determine our static inline position now. |
| 365 LineLayoutBox box(m_current.lineLayoutItem()); | 365 LineLayoutBox box(m_current.getLineLayoutItem()); |
| 366 bool isInlineType = box.style()->isOriginalDisplayInlineType(); | 366 bool isInlineType = box.style()->isOriginalDisplayInlineType(); |
| 367 if (!isInlineType) { | 367 if (!isInlineType) { |
| 368 m_block.setStaticInlinePositionForChild(box, m_block.startOffsetForConte
nt()); | 368 m_block.setStaticInlinePositionForChild(box, m_block.startOffsetForConte
nt()); |
| 369 } else { | 369 } else { |
| 370 // If our original display was an INLINE type, then we can go ahead | 370 // If our original display was an INLINE type, then we can go ahead |
| 371 // and determine our static y position now. | 371 // and determine our static y position now. |
| 372 box.layer()->setStaticBlockPosition(m_block.logicalHeight()); | 372 box.layer()->setStaticBlockPosition(m_block.logicalHeight()); |
| 373 } | 373 } |
| 374 | 374 |
| 375 // If we're ignoring spaces, we have to stop and include this object and | 375 // If we're ignoring spaces, we have to stop and include this object and |
| 376 // then start ignoring spaces again. | 376 // then start ignoring spaces again. |
| 377 if (isInlineType || box.container().isLayoutInline()) { | 377 if (isInlineType || box.container().isLayoutInline()) { |
| 378 if (m_ignoringSpaces) | 378 if (m_ignoringSpaces) |
| 379 ensureLineBoxInsideIgnoredSpaces(&m_lineMidpointState, box); | 379 ensureLineBoxInsideIgnoredSpaces(&m_lineMidpointState, box); |
| 380 m_trailingObjects.appendObjectIfNeeded(box); | 380 m_trailingObjects.appendObjectIfNeeded(box); |
| 381 } else { | 381 } else { |
| 382 positionedObjects.append(box); | 382 positionedObjects.append(box); |
| 383 } | 383 } |
| 384 m_width.addUncommittedWidth(inlineLogicalWidthFromAncestorsIfNeeded(box).toF
loat()); | 384 m_width.addUncommittedWidth(inlineLogicalWidthFromAncestorsIfNeeded(box).toF
loat()); |
| 385 // Reset prior line break context characters. | 385 // Reset prior line break context characters. |
| 386 m_layoutTextInfo.m_lineBreakIterator.resetPriorContext(); | 386 m_layoutTextInfo.m_lineBreakIterator.resetPriorContext(); |
| 387 } | 387 } |
| 388 | 388 |
| 389 inline void BreakingContext::handleFloat() | 389 inline void BreakingContext::handleFloat() |
| 390 { | 390 { |
| 391 LineLayoutBox floatBox(m_current.lineLayoutItem()); | 391 LineLayoutBox floatBox(m_current.getLineLayoutItem()); |
| 392 FloatingObject* floatingObject = m_block.insertFloatingObject(floatBox); | 392 FloatingObject* floatingObject = m_block.insertFloatingObject(floatBox); |
| 393 // check if it fits in the current line. | 393 // check if it fits in the current line. |
| 394 // If it does, position it now, otherwise, position | 394 // If it does, position it now, otherwise, position |
| 395 // it after moving to next line (in newLine() func) | 395 // it after moving to next line (in newLine() func) |
| 396 // FIXME: Bug 110372: Properly position multiple stacked floats with non-rec
tangular shape outside. | 396 // FIXME: Bug 110372: Properly position multiple stacked floats with non-rec
tangular shape outside. |
| 397 if (m_floatsFitOnLine && m_width.fitsOnLine(m_block.logicalWidthForFloat(*fl
oatingObject).toFloat(), ExcludeWhitespace)) { | 397 if (m_floatsFitOnLine && m_width.fitsOnLine(m_block.logicalWidthForFloat(*fl
oatingObject).toFloat(), ExcludeWhitespace)) { |
| 398 m_block.positionNewFloatOnLine(*floatingObject, m_lastFloatFromPreviousL
ine, m_lineInfo, m_width); | 398 m_block.positionNewFloatOnLine(*floatingObject, m_lastFloatFromPreviousL
ine, m_lineInfo, m_width); |
| 399 if (m_lineBreak.lineLayoutItem() == m_current.lineLayoutItem()) { | 399 if (m_lineBreak.getLineLayoutItem() == m_current.getLineLayoutItem()) { |
| 400 ASSERT(!m_lineBreak.offset()); | 400 ASSERT(!m_lineBreak.offset()); |
| 401 m_lineBreak.increment(); | 401 m_lineBreak.increment(); |
| 402 } | 402 } |
| 403 } else { | 403 } else { |
| 404 m_floatsFitOnLine = false; | 404 m_floatsFitOnLine = false; |
| 405 } | 405 } |
| 406 // Update prior line break context characters, using U+FFFD (OBJECT REPLACEM
ENT CHARACTER) for floating element. | 406 // Update prior line break context characters, using U+FFFD (OBJECT REPLACEM
ENT CHARACTER) for floating element. |
| 407 m_layoutTextInfo.m_lineBreakIterator.updatePriorContext(replacementCharacter
); | 407 m_layoutTextInfo.m_lineBreakIterator.updatePriorContext(replacementCharacter
); |
| 408 } | 408 } |
| 409 | 409 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 426 return true; | 426 return true; |
| 427 } | 427 } |
| 428 } | 428 } |
| 429 | 429 |
| 430 return false; | 430 return false; |
| 431 } | 431 } |
| 432 | 432 |
| 433 inline void BreakingContext::handleEmptyInline() | 433 inline void BreakingContext::handleEmptyInline() |
| 434 { | 434 { |
| 435 // This should only end up being called on empty inlines | 435 // This should only end up being called on empty inlines |
| 436 ASSERT(m_current.lineLayoutItem()); | 436 ASSERT(m_current.getLineLayoutItem()); |
| 437 | 437 |
| 438 LineLayoutInline flowBox(m_current.lineLayoutItem()); | 438 LineLayoutInline flowBox(m_current.getLineLayoutItem()); |
| 439 | 439 |
| 440 bool requiresLineBox = alwaysRequiresLineBox(m_current.lineLayoutItem()); | 440 bool requiresLineBox = alwaysRequiresLineBox(m_current.getLineLayoutItem()); |
| 441 if (requiresLineBox || requiresLineBoxForContent(flowBox, m_lineInfo)) { | 441 if (requiresLineBox || requiresLineBoxForContent(flowBox, m_lineInfo)) { |
| 442 // An empty inline that only has line-height, vertical-align or font-met
rics will | 442 // An empty inline that only has line-height, vertical-align or font-met
rics will |
| 443 // not force linebox creation (and thus affect the height of the line) i
f the rest of the line is empty. | 443 // not force linebox creation (and thus affect the height of the line) i
f the rest of the line is empty. |
| 444 if (requiresLineBox) | 444 if (requiresLineBox) |
| 445 m_lineInfo.setEmpty(false, m_block, &m_width); | 445 m_lineInfo.setEmpty(false, m_block, &m_width); |
| 446 if (m_ignoringSpaces) { | 446 if (m_ignoringSpaces) { |
| 447 // If we are in a run of ignored spaces then ensure we get a linebox
if lineboxes are eventually | 447 // If we are in a run of ignored spaces then ensure we get a linebox
if lineboxes are eventually |
| 448 // created for the line... | 448 // created for the line... |
| 449 m_trailingObjects.clear(); | 449 m_trailingObjects.clear(); |
| 450 ensureLineBoxInsideIgnoredSpaces(&m_lineMidpointState, m_current.lin
eLayoutItem()); | 450 ensureLineBoxInsideIgnoredSpaces(&m_lineMidpointState, m_current.get
LineLayoutItem()); |
| 451 } else if (m_blockStyle->collapseWhiteSpace() && m_resolver.position().l
ineLayoutItem() == m_current.lineLayoutItem() | 451 } else if (m_blockStyle->collapseWhiteSpace() && m_resolver.position().g
etLineLayoutItem() == m_current.getLineLayoutItem() |
| 452 && shouldSkipWhitespaceAfterStartObject(m_block, m_current.lineLayou
tItem(), m_lineMidpointState)) { | 452 && shouldSkipWhitespaceAfterStartObject(m_block, m_current.getLineLa
youtItem(), m_lineMidpointState)) { |
| 453 // If this object is at the start of the line, we need to behave lik
e list markers and | 453 // If this object is at the start of the line, we need to behave lik
e list markers and |
| 454 // start ignoring spaces. | 454 // start ignoring spaces. |
| 455 m_currentCharacterIsSpace = true; | 455 m_currentCharacterIsSpace = true; |
| 456 m_ignoringSpaces = true; | 456 m_ignoringSpaces = true; |
| 457 } else { | 457 } else { |
| 458 // If we are after a trailing space but aren't ignoring spaces yet t
hen ensure we get a linebox | 458 // If we are after a trailing space but aren't ignoring spaces yet t
hen ensure we get a linebox |
| 459 // if we encounter collapsible whitepace. | 459 // if we encounter collapsible whitepace. |
| 460 m_trailingObjects.appendObjectIfNeeded(m_current.lineLayoutItem()); | 460 m_trailingObjects.appendObjectIfNeeded(m_current.getLineLayoutItem()
); |
| 461 } | 461 } |
| 462 } | 462 } |
| 463 | 463 |
| 464 m_width.addUncommittedWidth((inlineLogicalWidthFromAncestorsIfNeeded(m_curre
nt.lineLayoutItem()) + borderPaddingMarginStart(flowBox) + borderPaddingMarginEn
d(flowBox)).toFloat()); | 464 m_width.addUncommittedWidth((inlineLogicalWidthFromAncestorsIfNeeded(m_curre
nt.getLineLayoutItem()) + borderPaddingMarginStart(flowBox) + borderPaddingMargi
nEnd(flowBox)).toFloat()); |
| 465 } | 465 } |
| 466 | 466 |
| 467 inline void BreakingContext::handleReplaced() | 467 inline void BreakingContext::handleReplaced() |
| 468 { | 468 { |
| 469 LineLayoutBox replacedBox(m_current.lineLayoutItem()); | 469 LineLayoutBox replacedBox(m_current.getLineLayoutItem()); |
| 470 | 470 |
| 471 if (m_atStart) | 471 if (m_atStart) |
| 472 m_width.updateAvailableWidth(replacedBox.logicalHeight()); | 472 m_width.updateAvailableWidth(replacedBox.logicalHeight()); |
| 473 | 473 |
| 474 // Break on replaced elements if either has normal white-space, | 474 // Break on replaced elements if either has normal white-space, |
| 475 // or if the replaced element is ruby that can break before. | 475 // or if the replaced element is ruby that can break before. |
| 476 if ((m_autoWrap || ComputedStyle::autoWrap(m_lastWS)) && (!m_current.lineLay
outItem().isImage() || m_allowImagesToBreak) | 476 if ((m_autoWrap || ComputedStyle::autoWrap(m_lastWS)) && (!m_current.getLine
LayoutItem().isImage() || m_allowImagesToBreak) |
| 477 && (!m_current.lineLayoutItem().isRubyRun() || LineLayoutRubyRun(m_curre
nt.lineLayoutItem()).canBreakBefore(m_layoutTextInfo.m_lineBreakIterator))) { | 477 && (!m_current.getLineLayoutItem().isRubyRun() || LineLayoutRubyRun(m_cu
rrent.getLineLayoutItem()).canBreakBefore(m_layoutTextInfo.m_lineBreakIterator))
) { |
| 478 m_width.commit(); | 478 m_width.commit(); |
| 479 m_lineBreak.moveToStartOf(m_current.lineLayoutItem()); | 479 m_lineBreak.moveToStartOf(m_current.getLineLayoutItem()); |
| 480 } | 480 } |
| 481 | 481 |
| 482 if (m_ignoringSpaces) | 482 if (m_ignoringSpaces) |
| 483 m_lineMidpointState.stopIgnoringSpaces(InlineIterator(0, m_current.lineL
ayoutItem(), 0)); | 483 m_lineMidpointState.stopIgnoringSpaces(InlineIterator(0, m_current.getLi
neLayoutItem(), 0)); |
| 484 | 484 |
| 485 m_lineInfo.setEmpty(false, m_block, &m_width); | 485 m_lineInfo.setEmpty(false, m_block, &m_width); |
| 486 m_ignoringSpaces = false; | 486 m_ignoringSpaces = false; |
| 487 m_currentCharacterIsSpace = false; | 487 m_currentCharacterIsSpace = false; |
| 488 m_trailingObjects.clear(); | 488 m_trailingObjects.clear(); |
| 489 | 489 |
| 490 // Optimize for a common case. If we can't find whitespace after the list | 490 // Optimize for a common case. If we can't find whitespace after the list |
| 491 // item, then this is all moot. | 491 // item, then this is all moot. |
| 492 LayoutUnit replacedLogicalWidth = m_block.logicalWidthForChild(replacedBox)
+ m_block.marginStartForChild(replacedBox) + m_block.marginEndForChild(replacedB
ox) + inlineLogicalWidthFromAncestorsIfNeeded(m_current.lineLayoutItem()); | 492 LayoutUnit replacedLogicalWidth = m_block.logicalWidthForChild(replacedBox)
+ m_block.marginStartForChild(replacedBox) + m_block.marginEndForChild(replacedB
ox) + inlineLogicalWidthFromAncestorsIfNeeded(m_current.getLineLayoutItem()); |
| 493 if (m_current.lineLayoutItem().isListMarker()) { | 493 if (m_current.getLineLayoutItem().isListMarker()) { |
| 494 if (m_blockStyle->collapseWhiteSpace() && shouldSkipWhitespaceAfterStart
Object(m_block, m_current.lineLayoutItem(), m_lineMidpointState)) { | 494 if (m_blockStyle->collapseWhiteSpace() && shouldSkipWhitespaceAfterStart
Object(m_block, m_current.getLineLayoutItem(), m_lineMidpointState)) { |
| 495 // Like with inline flows, we start ignoring spaces to make sure tha
t any | 495 // Like with inline flows, we start ignoring spaces to make sure tha
t any |
| 496 // additional spaces we see will be discarded. | 496 // additional spaces we see will be discarded. |
| 497 m_currentCharacterIsSpace = true; | 497 m_currentCharacterIsSpace = true; |
| 498 m_ignoringSpaces = true; | 498 m_ignoringSpaces = true; |
| 499 } | 499 } |
| 500 if (LineLayoutListMarker(m_current.lineLayoutItem()).isInside()) | 500 if (LineLayoutListMarker(m_current.getLineLayoutItem()).isInside()) |
| 501 m_width.addUncommittedWidth(replacedLogicalWidth.toFloat()); | 501 m_width.addUncommittedWidth(replacedLogicalWidth.toFloat()); |
| 502 } else { | 502 } else { |
| 503 m_width.addUncommittedWidth(replacedLogicalWidth.toFloat()); | 503 m_width.addUncommittedWidth(replacedLogicalWidth.toFloat()); |
| 504 } | 504 } |
| 505 if (m_current.lineLayoutItem().isRubyRun()) | 505 if (m_current.getLineLayoutItem().isRubyRun()) |
| 506 m_width.applyOverhang(LineLayoutRubyRun(m_current.lineLayoutItem()), m_l
astObject, m_nextObject); | 506 m_width.applyOverhang(LineLayoutRubyRun(m_current.getLineLayoutItem()),
m_lastObject, m_nextObject); |
| 507 // Update prior line break context characters, using U+FFFD (OBJECT REPLACEM
ENT CHARACTER) for replaced element. | 507 // Update prior line break context characters, using U+FFFD (OBJECT REPLACEM
ENT CHARACTER) for replaced element. |
| 508 m_layoutTextInfo.m_lineBreakIterator.updatePriorContext(replacementCharacter
); | 508 m_layoutTextInfo.m_lineBreakIterator.updatePriorContext(replacementCharacter
); |
| 509 } | 509 } |
| 510 | 510 |
| 511 inline void nextCharacter(UChar& currentCharacter, UChar& lastCharacter, UChar&
secondToLastCharacter) | 511 inline void nextCharacter(UChar& currentCharacter, UChar& lastCharacter, UChar&
secondToLastCharacter) |
| 512 { | 512 { |
| 513 secondToLastCharacter = lastCharacter; | 513 secondToLastCharacter = lastCharacter; |
| 514 lastCharacter = currentCharacter; | 514 lastCharacter = currentCharacter; |
| 515 } | 515 } |
| 516 | 516 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 538 run.setTabSize(!collapseWhiteSpace, text.style()->tabSize()); | 538 run.setTabSize(!collapseWhiteSpace, text.style()->tabSize()); |
| 539 run.setXPos(xPos); | 539 run.setXPos(xPos); |
| 540 return font.width(run, fallbackFonts, glyphBounds); | 540 return font.width(run, fallbackFonts, glyphBounds); |
| 541 } | 541 } |
| 542 | 542 |
| 543 inline bool BreakingContext::handleText(WordMeasurements& wordMeasurements, bool
& hyphenated) | 543 inline bool BreakingContext::handleText(WordMeasurements& wordMeasurements, bool
& hyphenated) |
| 544 { | 544 { |
| 545 if (!m_current.offset()) | 545 if (!m_current.offset()) |
| 546 m_appliedStartWidth = false; | 546 m_appliedStartWidth = false; |
| 547 | 547 |
| 548 LineLayoutText layoutText(m_current.lineLayoutItem()); | 548 LineLayoutText layoutText(m_current.getLineLayoutItem()); |
| 549 | 549 |
| 550 // If we have left a no-wrap inline and entered an autowrap inline while ign
oring spaces | 550 // If we have left a no-wrap inline and entered an autowrap inline while ign
oring spaces |
| 551 // then we need to mark the start of the autowrap inline as a potential line
break now. | 551 // then we need to mark the start of the autowrap inline as a potential line
break now. |
| 552 if (m_autoWrap && !ComputedStyle::autoWrap(m_lastWS) && m_ignoringSpaces) { | 552 if (m_autoWrap && !ComputedStyle::autoWrap(m_lastWS) && m_ignoringSpaces) { |
| 553 m_width.commit(); | 553 m_width.commit(); |
| 554 m_lineBreak.moveToStartOf(m_current.lineLayoutItem()); | 554 m_lineBreak.moveToStartOf(m_current.getLineLayoutItem()); |
| 555 } | 555 } |
| 556 | 556 |
| 557 const ComputedStyle& style = layoutText.styleRef(m_lineInfo.isFirstLine()); | 557 const ComputedStyle& style = layoutText.styleRef(m_lineInfo.isFirstLine()); |
| 558 const Font& font = style.font(); | 558 const Font& font = style.font(); |
| 559 | 559 |
| 560 unsigned lastSpace = m_current.offset(); | 560 unsigned lastSpace = m_current.offset(); |
| 561 float wordSpacing = m_currentStyle->wordSpacing(); | 561 float wordSpacing = m_currentStyle->wordSpacing(); |
| 562 float lastSpaceWordSpacing = 0; | 562 float lastSpaceWordSpacing = 0; |
| 563 float wordSpacingForWordMeasurement = 0; | 563 float wordSpacingForWordMeasurement = 0; |
| 564 | 564 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 581 float hyphenWidth = 0; | 581 float hyphenWidth = 0; |
| 582 | 582 |
| 583 if (layoutText.isSVGInlineText()) { | 583 if (layoutText.isSVGInlineText()) { |
| 584 breakWords = false; | 584 breakWords = false; |
| 585 breakAll = false; | 585 breakAll = false; |
| 586 keepAll = false; | 586 keepAll = false; |
| 587 } | 587 } |
| 588 | 588 |
| 589 if (layoutText.isWordBreak()) { | 589 if (layoutText.isWordBreak()) { |
| 590 m_width.commit(); | 590 m_width.commit(); |
| 591 m_lineBreak.moveToStartOf(m_current.lineLayoutItem()); | 591 m_lineBreak.moveToStartOf(m_current.getLineLayoutItem()); |
| 592 ASSERT(m_current.offset() == layoutText.textLength()); | 592 ASSERT(m_current.offset() == layoutText.textLength()); |
| 593 } | 593 } |
| 594 | 594 |
| 595 if (m_layoutTextInfo.m_text != layoutText) { | 595 if (m_layoutTextInfo.m_text != layoutText) { |
| 596 m_layoutTextInfo.m_text = layoutText; | 596 m_layoutTextInfo.m_text = layoutText; |
| 597 m_layoutTextInfo.m_font = &font; | 597 m_layoutTextInfo.m_font = &font; |
| 598 m_layoutTextInfo.m_lineBreakIterator.resetStringAndReleaseIterator(layou
tText.text(), style.locale()); | 598 m_layoutTextInfo.m_lineBreakIterator.resetStringAndReleaseIterator(layou
tText.text(), style.locale()); |
| 599 } else if (m_layoutTextInfo.m_font != &font) { | 599 } else if (m_layoutTextInfo.m_font != &font) { |
| 600 m_layoutTextInfo.m_font = &font; | 600 m_layoutTextInfo.m_font = &font; |
| 601 } | 601 } |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 679 | 679 |
| 680 // We keep track of the total width contributed by trailing space as we
often want to exclude it when determining | 680 // We keep track of the total width contributed by trailing space as we
often want to exclude it when determining |
| 681 // if a run fits on a line. | 681 // if a run fits on a line. |
| 682 if (m_collapseWhiteSpace && previousCharacterIsSpace && m_currentCharact
erIsSpace && lastWidthMeasurement) | 682 if (m_collapseWhiteSpace && previousCharacterIsSpace && m_currentCharact
erIsSpace && lastWidthMeasurement) |
| 683 m_width.setTrailingWhitespaceWidth(lastWidthMeasurement); | 683 m_width.setTrailingWhitespaceWidth(lastWidthMeasurement); |
| 684 | 684 |
| 685 // If this is the end of the first word in run of text then make sure we
apply the width from any leading inlines. | 685 // If this is the end of the first word in run of text then make sure we
apply the width from any leading inlines. |
| 686 // For example: '<span style="margin-left: 5px;"><span style="margin-lef
t: 10px;">FirstWord</span></span>' would | 686 // For example: '<span style="margin-left: 5px;"><span style="margin-lef
t: 10px;">FirstWord</span></span>' would |
| 687 // apply a width of 15px from the two span ancestors. | 687 // apply a width of 15px from the two span ancestors. |
| 688 if (!m_appliedStartWidth) { | 688 if (!m_appliedStartWidth) { |
| 689 m_width.addUncommittedWidth(inlineLogicalWidthFromAncestorsIfNeeded(
m_current.lineLayoutItem(), true, false).toFloat()); | 689 m_width.addUncommittedWidth(inlineLogicalWidthFromAncestorsIfNeeded(
m_current.getLineLayoutItem(), true, false).toFloat()); |
| 690 m_appliedStartWidth = true; | 690 m_appliedStartWidth = true; |
| 691 } | 691 } |
| 692 | 692 |
| 693 applyWordSpacing = wordSpacing && m_currentCharacterIsSpace; | 693 applyWordSpacing = wordSpacing && m_currentCharacterIsSpace; |
| 694 | 694 |
| 695 // If we haven't hit a breakable position yet and already don't fit on t
he line try to move below any floats. | 695 // If we haven't hit a breakable position yet and already don't fit on t
he line try to move below any floats. |
| 696 if (!m_width.committedWidth() && m_autoWrap && !m_width.fitsOnLine() &&
!widthMeasurementAtLastBreakOpportunity) | 696 if (!m_width.committedWidth() && m_autoWrap && !m_width.fitsOnLine() &&
!widthMeasurementAtLastBreakOpportunity) |
| 697 m_width.fitBelowFloats(m_lineInfo.isFirstLine()); | 697 m_width.fitBelowFloats(m_lineInfo.isFirstLine()); |
| 698 | 698 |
| 699 // If there is a soft-break available at this whitespace position then t
ake it. | 699 // If there is a soft-break available at this whitespace position then t
ake it. |
| 700 applyWordSpacing = wordSpacing && m_currentCharacterIsSpace; | 700 applyWordSpacing = wordSpacing && m_currentCharacterIsSpace; |
| 701 if (canBreakAtWhitespace(breakWords, wordMeasurement, stoppedIgnoringSpa
ces, hyphenated, charWidth, hyphenWidth, betweenWords, midWordBreak, breakAll, p
reviousCharacterIsSpace, lastWidthMeasurement, layoutText, font, applyWordSpacin
g, wordSpacing)) | 701 if (canBreakAtWhitespace(breakWords, wordMeasurement, stoppedIgnoringSpa
ces, hyphenated, charWidth, hyphenWidth, betweenWords, midWordBreak, breakAll, p
reviousCharacterIsSpace, lastWidthMeasurement, layoutText, font, applyWordSpacin
g, wordSpacing)) |
| 702 return false; | 702 return false; |
| 703 | 703 |
| 704 // If there is a hard-break available at this whitespace position then t
ake it. | 704 // If there is a hard-break available at this whitespace position then t
ake it. |
| 705 if (c == newlineCharacter && m_preservesNewline) { | 705 if (c == newlineCharacter && m_preservesNewline) { |
| 706 if (!stoppedIgnoringSpaces && m_current.offset()) | 706 if (!stoppedIgnoringSpaces && m_current.offset()) |
| 707 m_lineMidpointState.ensureCharacterGetsLineBox(m_current); | 707 m_lineMidpointState.ensureCharacterGetsLineBox(m_current); |
| 708 m_lineBreak.moveTo(m_current.lineLayoutItem(), m_current.offset(), m
_current.nextBreakablePosition()); | 708 m_lineBreak.moveTo(m_current.getLineLayoutItem(), m_current.offset()
, m_current.nextBreakablePosition()); |
| 709 m_lineBreak.increment(); | 709 m_lineBreak.increment(); |
| 710 m_lineInfo.setPreviousLineBrokeCleanly(true); | 710 m_lineInfo.setPreviousLineBrokeCleanly(true); |
| 711 return true; | 711 return true; |
| 712 } | 712 } |
| 713 | 713 |
| 714 // Auto-wrapping text should not wrap in the middle of a word once it ha
s had an | 714 // Auto-wrapping text should not wrap in the middle of a word once it ha
s had an |
| 715 // opportunity to break after a word. | 715 // opportunity to break after a word. |
| 716 if (m_autoWrap && betweenWords) { | 716 if (m_autoWrap && betweenWords) { |
| 717 m_width.commit(); | 717 m_width.commit(); |
| 718 widthFromLastBreakingOpportunity = 0; | 718 widthFromLastBreakingOpportunity = 0; |
| 719 m_lineBreak.moveTo(m_current.lineLayoutItem(), m_current.offset(), m
_current.nextBreakablePosition()); | 719 m_lineBreak.moveTo(m_current.getLineLayoutItem(), m_current.offset()
, m_current.nextBreakablePosition()); |
| 720 breakWords = false; | 720 breakWords = false; |
| 721 widthMeasurementAtLastBreakOpportunity = lastWidthMeasurement; | 721 widthMeasurementAtLastBreakOpportunity = lastWidthMeasurement; |
| 722 } | 722 } |
| 723 | 723 |
| 724 // Remember this as a breakable position in case adding the end width fo
rces a break. | 724 // Remember this as a breakable position in case adding the end width fo
rces a break. |
| 725 if (midWordBreak && !U16_IS_TRAIL(c) && !(WTF::Unicode::category(c) & (W
TF::Unicode::Mark_NonSpacing | WTF::Unicode::Mark_Enclosing | WTF::Unicode::Mark
_SpacingCombining))) { | 725 if (midWordBreak && !U16_IS_TRAIL(c) && !(WTF::Unicode::category(c) & (W
TF::Unicode::Mark_NonSpacing | WTF::Unicode::Mark_Enclosing | WTF::Unicode::Mark
_SpacingCombining))) { |
| 726 m_lineBreak.moveTo(m_current.lineLayoutItem(), m_current.offset(), m
_current.nextBreakablePosition()); | 726 m_lineBreak.moveTo(m_current.getLineLayoutItem(), m_current.offset()
, m_current.nextBreakablePosition()); |
| 727 midWordBreak &= (breakWords || breakAll); | 727 midWordBreak &= (breakWords || breakAll); |
| 728 } | 728 } |
| 729 | 729 |
| 730 if (betweenWords) { | 730 if (betweenWords) { |
| 731 lastSpaceWordSpacing = applyWordSpacing ? wordSpacing : 0; | 731 lastSpaceWordSpacing = applyWordSpacing ? wordSpacing : 0; |
| 732 wordSpacingForWordMeasurement = (applyWordSpacing && wordMeasurement
.width) ? wordSpacing : 0; | 732 wordSpacingForWordMeasurement = (applyWordSpacing && wordMeasurement
.width) ? wordSpacing : 0; |
| 733 lastSpace = !breakAll || m_currentCharacterIsSpace ? m_current.offse
t() : lastSpace; | 733 lastSpace = !breakAll || m_currentCharacterIsSpace ? m_current.offse
t() : lastSpace; |
| 734 } | 734 } |
| 735 | 735 |
| 736 // If we encounter a newline, or if we encounter a second space, we need
to go ahead and break up | 736 // If we encounter a newline, or if we encounter a second space, we need
to go ahead and break up |
| (...skipping 24 matching lines...) Expand all Loading... |
| 761 float lastWidthMeasurement = 0; | 761 float lastWidthMeasurement = 0; |
| 762 wordMeasurement.startOffset = lastSpace; | 762 wordMeasurement.startOffset = lastSpace; |
| 763 wordMeasurement.endOffset = m_current.offset(); | 763 wordMeasurement.endOffset = m_current.offset(); |
| 764 if (!m_ignoringSpaces) { | 764 if (!m_ignoringSpaces) { |
| 765 lastWidthMeasurement = textWidth(layoutText, lastSpace, m_current.offset
() - lastSpace, font, m_width.currentWidth(), m_collapseWhiteSpace, &wordMeasure
ment.fallbackFonts, &wordMeasurement.glyphBounds); | 765 lastWidthMeasurement = textWidth(layoutText, lastSpace, m_current.offset
() - lastSpace, font, m_width.currentWidth(), m_collapseWhiteSpace, &wordMeasure
ment.fallbackFonts, &wordMeasurement.glyphBounds); |
| 766 wordMeasurement.width = lastWidthMeasurement + wordSpacingForWordMeasure
ment; | 766 wordMeasurement.width = lastWidthMeasurement + wordSpacingForWordMeasure
ment; |
| 767 wordMeasurement.glyphBounds.move(wordSpacingForWordMeasurement, 0); | 767 wordMeasurement.glyphBounds.move(wordSpacingForWordMeasurement, 0); |
| 768 } | 768 } |
| 769 lastWidthMeasurement += lastSpaceWordSpacing; | 769 lastWidthMeasurement += lastSpaceWordSpacing; |
| 770 | 770 |
| 771 LayoutUnit additionalWidthFromAncestors = inlineLogicalWidthFromAncestorsIfN
eeded(m_current.lineLayoutItem(), !m_appliedStartWidth, m_includeEndWidth); | 771 LayoutUnit additionalWidthFromAncestors = inlineLogicalWidthFromAncestorsIfN
eeded(m_current.getLineLayoutItem(), !m_appliedStartWidth, m_includeEndWidth); |
| 772 m_width.addUncommittedWidth(lastWidthMeasurement + additionalWidthFromAncest
ors); | 772 m_width.addUncommittedWidth(lastWidthMeasurement + additionalWidthFromAncest
ors); |
| 773 | 773 |
| 774 if (m_collapseWhiteSpace && m_currentCharacterIsSpace && lastWidthMeasuremen
t) | 774 if (m_collapseWhiteSpace && m_currentCharacterIsSpace && lastWidthMeasuremen
t) |
| 775 m_width.setTrailingWhitespaceWidth(lastWidthMeasurement + additionalWidt
hFromAncestors); | 775 m_width.setTrailingWhitespaceWidth(lastWidthMeasurement + additionalWidt
hFromAncestors); |
| 776 | 776 |
| 777 m_includeEndWidth = false; | 777 m_includeEndWidth = false; |
| 778 | 778 |
| 779 if (!m_width.fitsOnLine()) { | 779 if (!m_width.fitsOnLine()) { |
| 780 if (breakAll && widthMeasurementAtLastBreakOpportunity) { | 780 if (breakAll && widthMeasurementAtLastBreakOpportunity) { |
| 781 m_width.addUncommittedWidth(widthMeasurementAtLastBreakOpportunity); | 781 m_width.addUncommittedWidth(widthMeasurementAtLastBreakOpportunity); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 795 if (layoutText.isSVGInlineText() && m_current.offset()) { | 795 if (layoutText.isSVGInlineText() && m_current.offset()) { |
| 796 // Force creation of new InlineBoxes for each absolute positioned charac
ter (those that start new text chunks). | 796 // Force creation of new InlineBoxes for each absolute positioned charac
ter (those that start new text chunks). |
| 797 if (LineLayoutSVGInlineText(layoutText).characterStartsNewTextChunk(m_cu
rrent.offset())) | 797 if (LineLayoutSVGInlineText(layoutText).characterStartsNewTextChunk(m_cu
rrent.offset())) |
| 798 m_lineMidpointState.ensureCharacterGetsLineBox(m_current); | 798 m_lineMidpointState.ensureCharacterGetsLineBox(m_current); |
| 799 } | 799 } |
| 800 if (prohibitBreakInside) { | 800 if (prohibitBreakInside) { |
| 801 m_current.setNextBreakablePosition(layoutText.textLength()); | 801 m_current.setNextBreakablePosition(layoutText.textLength()); |
| 802 prohibitBreakInside = false; | 802 prohibitBreakInside = false; |
| 803 } | 803 } |
| 804 if (m_currentCharacterIsSpace && !previousCharacterIsSpace) { | 804 if (m_currentCharacterIsSpace && !previousCharacterIsSpace) { |
| 805 m_startOfIgnoredSpaces.setLineLayoutItem(m_current.lineLayoutItem()); | 805 m_startOfIgnoredSpaces.setLineLayoutItem(m_current.getLineLayoutItem()); |
| 806 m_startOfIgnoredSpaces.setOffset(m_current.offset()); | 806 m_startOfIgnoredSpaces.setOffset(m_current.offset()); |
| 807 } | 807 } |
| 808 if (!m_currentCharacterIsSpace && previousCharacterIsSpace) { | 808 if (!m_currentCharacterIsSpace && previousCharacterIsSpace) { |
| 809 if (m_autoWrap && m_currentStyle->breakOnlyAfterWhiteSpace()) | 809 if (m_autoWrap && m_currentStyle->breakOnlyAfterWhiteSpace()) |
| 810 m_lineBreak.moveTo(m_current.lineLayoutItem(), m_current.offset(), m
_current.nextBreakablePosition()); | 810 m_lineBreak.moveTo(m_current.getLineLayoutItem(), m_current.offset()
, m_current.nextBreakablePosition()); |
| 811 } | 811 } |
| 812 if (m_collapseWhiteSpace && m_currentCharacterIsSpace && !m_ignoringSpaces) | 812 if (m_collapseWhiteSpace && m_currentCharacterIsSpace && !m_ignoringSpaces) |
| 813 m_trailingObjects.setTrailingWhitespace(LineLayoutText(m_current.lineLay
outItem())); | 813 m_trailingObjects.setTrailingWhitespace(LineLayoutText(m_current.getLine
LayoutItem())); |
| 814 else if (!m_currentStyle->collapseWhiteSpace() || !m_currentCharacterIsSpace
) | 814 else if (!m_currentStyle->collapseWhiteSpace() || !m_currentCharacterIsSpace
) |
| 815 m_trailingObjects.clear(); | 815 m_trailingObjects.clear(); |
| 816 } | 816 } |
| 817 | 817 |
| 818 | 818 |
| 819 inline void BreakingContext::stopIgnoringSpaces(unsigned& lastSpace) | 819 inline void BreakingContext::stopIgnoringSpaces(unsigned& lastSpace) |
| 820 { | 820 { |
| 821 m_ignoringSpaces = false; | 821 m_ignoringSpaces = false; |
| 822 lastSpace = m_current.offset(); // e.g., "Foo goo", don't add in any of t
he ignored spaces. | 822 lastSpace = m_current.offset(); // e.g., "Foo goo", don't add in any of t
he ignored spaces. |
| 823 m_lineMidpointState.stopIgnoringSpaces(InlineIterator(0, m_current.lineLayou
tItem(), m_current.offset())); | 823 m_lineMidpointState.stopIgnoringSpaces(InlineIterator(0, m_current.getLineLa
youtItem(), m_current.offset())); |
| 824 } | 824 } |
| 825 | 825 |
| 826 inline WordMeasurement& BreakingContext::calculateWordWidth(WordMeasurements& wo
rdMeasurements, LineLayoutText& layoutText, unsigned lastSpace, float& lastWidth
Measurement, float wordSpacingForWordMeasurement, const Font& font, float wordTr
ailingSpaceWidth, UChar c) | 826 inline WordMeasurement& BreakingContext::calculateWordWidth(WordMeasurements& wo
rdMeasurements, LineLayoutText& layoutText, unsigned lastSpace, float& lastWidth
Measurement, float wordSpacingForWordMeasurement, const Font& font, float wordTr
ailingSpaceWidth, UChar c) |
| 827 { | 827 { |
| 828 wordMeasurements.grow(wordMeasurements.size() + 1); | 828 wordMeasurements.grow(wordMeasurements.size() + 1); |
| 829 WordMeasurement& wordMeasurement = wordMeasurements.last(); | 829 WordMeasurement& wordMeasurement = wordMeasurements.last(); |
| 830 wordMeasurement.layoutText = layoutText; | 830 wordMeasurement.layoutText = layoutText; |
| 831 wordMeasurement.endOffset = m_current.offset(); | 831 wordMeasurement.endOffset = m_current.offset(); |
| 832 wordMeasurement.startOffset = lastSpace; | 832 wordMeasurement.startOffset = lastSpace; |
| 833 | 833 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 846 // If we break only after white-space, consider the current character | 846 // If we break only after white-space, consider the current character |
| 847 // as candidate width for this line. | 847 // as candidate width for this line. |
| 848 if (m_width.fitsOnLine() && m_currentCharacterIsSpace && m_currentStyle->bre
akOnlyAfterWhiteSpace() && !midWordBreak) { | 848 if (m_width.fitsOnLine() && m_currentCharacterIsSpace && m_currentStyle->bre
akOnlyAfterWhiteSpace() && !midWordBreak) { |
| 849 float charWidth = textWidth(layoutText, m_current.offset(), 1, font, m_w
idth.currentWidth(), m_collapseWhiteSpace, &wordMeasurement.fallbackFonts, &word
Measurement.glyphBounds) + (applyWordSpacing ? wordSpacing : 0); | 849 float charWidth = textWidth(layoutText, m_current.offset(), 1, font, m_w
idth.currentWidth(), m_collapseWhiteSpace, &wordMeasurement.fallbackFonts, &word
Measurement.glyphBounds) + (applyWordSpacing ? wordSpacing : 0); |
| 850 // Check if line is too big even without the extra space | 850 // Check if line is too big even without the extra space |
| 851 // at the end of the line. If it is not, do nothing. | 851 // at the end of the line. If it is not, do nothing. |
| 852 // If the line needs the extra whitespace to be too long, | 852 // If the line needs the extra whitespace to be too long, |
| 853 // then move the line break to the space and skip all | 853 // then move the line break to the space and skip all |
| 854 // additional whitespace. | 854 // additional whitespace. |
| 855 if (!m_width.fitsOnLine(charWidth)) { | 855 if (!m_width.fitsOnLine(charWidth)) { |
| 856 m_lineBreak.moveTo(m_current.lineLayoutItem(), m_current.offset(), m
_current.nextBreakablePosition()); | 856 m_lineBreak.moveTo(m_current.getLineLayoutItem(), m_current.offset()
, m_current.nextBreakablePosition()); |
| 857 skipTrailingWhitespace(m_lineBreak, m_lineInfo); | 857 skipTrailingWhitespace(m_lineBreak, m_lineInfo); |
| 858 return true; | 858 return true; |
| 859 } | 859 } |
| 860 } | 860 } |
| 861 return false; | 861 return false; |
| 862 } | 862 } |
| 863 | 863 |
| 864 inline bool BreakingContext::canBreakAtWhitespace(bool breakWords, WordMeasureme
nt& wordMeasurement, bool stoppedIgnoringSpaces, bool& hyphenated, float charWid
th, float& hyphenWidth, bool betweenWords, bool midWordBreak, bool breakAll, boo
l previousCharacterIsSpace, float lastWidthMeasurement, const LineLayoutText& la
youtText, const Font& font, bool applyWordSpacing, float wordSpacing) | 864 inline bool BreakingContext::canBreakAtWhitespace(bool breakWords, WordMeasureme
nt& wordMeasurement, bool stoppedIgnoringSpaces, bool& hyphenated, float charWid
th, float& hyphenWidth, bool betweenWords, bool midWordBreak, bool breakAll, boo
l previousCharacterIsSpace, float lastWidthMeasurement, const LineLayoutText& la
youtText, const Font& font, bool applyWordSpacing, float wordSpacing) |
| 865 { | 865 { |
| 866 if (!m_autoWrap && !breakWords) | 866 if (!m_autoWrap && !breakWords) |
| 867 return false; | 867 return false; |
| 868 | 868 |
| 869 // If we break only after white-space, consider the current character | 869 // If we break only after white-space, consider the current character |
| 870 // as candidate width for this line. | 870 // as candidate width for this line. |
| 871 if (trailingSpaceExceedsAvailableWidth(midWordBreak, layoutText, wordMeasure
ment, applyWordSpacing, wordSpacing, font) || !m_width.fitsOnLine()) { | 871 if (trailingSpaceExceedsAvailableWidth(midWordBreak, layoutText, wordMeasure
ment, applyWordSpacing, wordSpacing, font) || !m_width.fitsOnLine()) { |
| 872 if (m_lineBreak.atTextParagraphSeparator()) { | 872 if (m_lineBreak.atTextParagraphSeparator()) { |
| 873 if (!stoppedIgnoringSpaces && m_current.offset() > 0) | 873 if (!stoppedIgnoringSpaces && m_current.offset() > 0) |
| 874 m_lineMidpointState.ensureCharacterGetsLineBox(m_current); | 874 m_lineMidpointState.ensureCharacterGetsLineBox(m_current); |
| 875 m_lineBreak.increment(); | 875 m_lineBreak.increment(); |
| 876 m_lineInfo.setPreviousLineBrokeCleanly(true); | 876 m_lineInfo.setPreviousLineBrokeCleanly(true); |
| 877 wordMeasurement.endOffset = m_lineBreak.offset(); | 877 wordMeasurement.endOffset = m_lineBreak.offset(); |
| 878 } | 878 } |
| 879 if (m_lineBreak.lineLayoutItem() && m_lineBreak.offset() && m_lineBreak.
lineLayoutItem().isText() && LineLayoutText(m_lineBreak.lineLayoutItem()).textLe
ngth() && LineLayoutText(m_lineBreak.lineLayoutItem()).characterAt(m_lineBreak.o
ffset() - 1) == softHyphenCharacter) | 879 if (m_lineBreak.getLineLayoutItem() && m_lineBreak.offset() && m_lineBre
ak.getLineLayoutItem().isText() && LineLayoutText(m_lineBreak.getLineLayoutItem(
)).textLength() && LineLayoutText(m_lineBreak.getLineLayoutItem()).characterAt(m
_lineBreak.offset() - 1) == softHyphenCharacter) |
| 880 hyphenated = true; | 880 hyphenated = true; |
| 881 if (m_lineBreak.offset() && m_lineBreak.offset() != (unsigned)wordMeasur
ement.endOffset && !wordMeasurement.width) { | 881 if (m_lineBreak.offset() && m_lineBreak.offset() != (unsigned)wordMeasur
ement.endOffset && !wordMeasurement.width) { |
| 882 if (charWidth) { | 882 if (charWidth) { |
| 883 wordMeasurement.endOffset = m_lineBreak.offset(); | 883 wordMeasurement.endOffset = m_lineBreak.offset(); |
| 884 wordMeasurement.width = charWidth; | 884 wordMeasurement.width = charWidth; |
| 885 } | 885 } |
| 886 } | 886 } |
| 887 // Didn't fit. Jump to the end unless there's still an opportunity to co
llapse whitespace. | 887 // Didn't fit. Jump to the end unless there's still an opportunity to co
llapse whitespace. |
| 888 if (m_ignoringSpaces || !m_collapseWhiteSpace || !m_currentCharacterIsSp
ace || !previousCharacterIsSpace) { | 888 if (m_ignoringSpaces || !m_collapseWhiteSpace || !m_currentCharacterIsSp
ace || !previousCharacterIsSpace) { |
| 889 m_atEnd = true; | 889 m_atEnd = true; |
| 890 return true; | 890 return true; |
| 891 } | 891 } |
| 892 } else { | 892 } else { |
| 893 if (!betweenWords || (midWordBreak && !m_autoWrap) || (breakAll && !m_cu
rrentCharacterIsSpace)) | 893 if (!betweenWords || (midWordBreak && !m_autoWrap) || (breakAll && !m_cu
rrentCharacterIsSpace)) |
| 894 m_width.addUncommittedWidth(-lastWidthMeasurement); | 894 m_width.addUncommittedWidth(-lastWidthMeasurement); |
| 895 if (hyphenWidth) { | 895 if (hyphenWidth) { |
| 896 // Subtract the width of the soft hyphen out since we fit on a line. | 896 // Subtract the width of the soft hyphen out since we fit on a line. |
| 897 m_width.addUncommittedWidth(-hyphenWidth); | 897 m_width.addUncommittedWidth(-hyphenWidth); |
| 898 hyphenWidth = 0; | 898 hyphenWidth = 0; |
| 899 } | 899 } |
| 900 } | 900 } |
| 901 return false; | 901 return false; |
| 902 } | 902 } |
| 903 | 903 |
| 904 inline void BreakingContext::commitAndUpdateLineBreakIfNeeded() | 904 inline void BreakingContext::commitAndUpdateLineBreakIfNeeded() |
| 905 { | 905 { |
| 906 bool checkForBreak = m_autoWrap; | 906 bool checkForBreak = m_autoWrap; |
| 907 if (m_width.committedWidth() && !m_width.fitsOnLine() && m_lineBreak.lineLay
outItem() && m_currWS == NOWRAP) { | 907 if (m_width.committedWidth() && !m_width.fitsOnLine() && m_lineBreak.getLine
LayoutItem() && m_currWS == NOWRAP) { |
| 908 if (m_width.fitsOnLine(0, ExcludeWhitespace)) { | 908 if (m_width.fitsOnLine(0, ExcludeWhitespace)) { |
| 909 m_width.commit(); | 909 m_width.commit(); |
| 910 m_lineBreak.moveToStartOf(m_nextObject); | 910 m_lineBreak.moveToStartOf(m_nextObject); |
| 911 } | 911 } |
| 912 checkForBreak = true; | 912 checkForBreak = true; |
| 913 } else if (m_nextObject && m_current.lineLayoutItem().isText() && m_nextObje
ct.isText() && !m_nextObject.isBR() && (m_autoWrap || m_nextObject.style()->auto
Wrap())) { | 913 } else if (m_nextObject && m_current.getLineLayoutItem().isText() && m_nextO
bject.isText() && !m_nextObject.isBR() && (m_autoWrap || m_nextObject.style()->a
utoWrap())) { |
| 914 if (m_autoWrap && m_currentCharacterIsSpace) { | 914 if (m_autoWrap && m_currentCharacterIsSpace) { |
| 915 checkForBreak = true; | 915 checkForBreak = true; |
| 916 } else { | 916 } else { |
| 917 LineLayoutText nextText(m_nextObject); | 917 LineLayoutText nextText(m_nextObject); |
| 918 if (nextText.textLength()) { | 918 if (nextText.textLength()) { |
| 919 UChar c = nextText.characterAt(0); | 919 UChar c = nextText.characterAt(0); |
| 920 // If the next item on the line is text, and if we did not end w
ith | 920 // If the next item on the line is text, and if we did not end w
ith |
| 921 // a space, then the next text run continues our word (and so it
needs to | 921 // a space, then the next text run continues our word (and so it
needs to |
| 922 // keep adding to the uncommitted width. Just update and continu
e. | 922 // keep adding to the uncommitted width. Just update and continu
e. |
| 923 checkForBreak = !m_currentCharacterIsSpace && (c == spaceCharact
er || c == tabulationCharacter || (c == newlineCharacter && !m_nextObject.preser
vesNewline())); | 923 checkForBreak = !m_currentCharacterIsSpace && (c == spaceCharact
er || c == tabulationCharacter || (c == newlineCharacter && !m_nextObject.preser
vesNewline())); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 955 if (!m_width.fitsOnLine()) { | 955 if (!m_width.fitsOnLine()) { |
| 956 m_atEnd = true; | 956 m_atEnd = true; |
| 957 return; | 957 return; |
| 958 } | 958 } |
| 959 } else if (m_blockStyle->autoWrap() && !m_width.fitsOnLine() && !m_width.com
mittedWidth()) { | 959 } else if (m_blockStyle->autoWrap() && !m_width.fitsOnLine() && !m_width.com
mittedWidth()) { |
| 960 // If the container autowraps but the current child does not then we sti
ll need to ensure that it | 960 // If the container autowraps but the current child does not then we sti
ll need to ensure that it |
| 961 // wraps and moves below any floats. | 961 // wraps and moves below any floats. |
| 962 m_width.fitBelowFloats(m_lineInfo.isFirstLine()); | 962 m_width.fitBelowFloats(m_lineInfo.isFirstLine()); |
| 963 } | 963 } |
| 964 | 964 |
| 965 if (!m_current.lineLayoutItem().isFloatingOrOutOfFlowPositioned()) { | 965 if (!m_current.getLineLayoutItem().isFloatingOrOutOfFlowPositioned()) { |
| 966 m_lastObject = m_current.lineLayoutItem(); | 966 m_lastObject = m_current.getLineLayoutItem(); |
| 967 if (m_lastObject.isAtomicInlineLevel() && m_autoWrap && (!m_lastObject.i
sImage() || m_allowImagesToBreak) && (!m_lastObject.isListMarker() || LineLayout
ListMarker(m_lastObject).isInside()) | 967 if (m_lastObject.isAtomicInlineLevel() && m_autoWrap && (!m_lastObject.i
sImage() || m_allowImagesToBreak) && (!m_lastObject.isListMarker() || LineLayout
ListMarker(m_lastObject).isInside()) |
| 968 && !m_lastObject.isRubyRun()) { | 968 && !m_lastObject.isRubyRun()) { |
| 969 m_width.commit(); | 969 m_width.commit(); |
| 970 m_lineBreak.moveToStartOf(m_nextObject); | 970 m_lineBreak.moveToStartOf(m_nextObject); |
| 971 } | 971 } |
| 972 } | 972 } |
| 973 } | 973 } |
| 974 | 974 |
| 975 inline IndentTextOrNot requiresIndent(bool isFirstLine, bool isAfterHardLineBrea
k, const ComputedStyle& style) | 975 inline IndentTextOrNot requiresIndent(bool isFirstLine, bool isAfterHardLineBrea
k, const ComputedStyle& style) |
| 976 { | 976 { |
| 977 IndentTextOrNot indentText = DoNotIndentText; | 977 IndentTextOrNot indentText = DoNotIndentText; |
| 978 if (isFirstLine || (isAfterHardLineBreak && style.textIndentLine()) == TextI
ndentEachLine) | 978 if (isFirstLine || (isAfterHardLineBreak && style.textIndentLine()) == TextI
ndentEachLine) |
| 979 indentText = IndentText; | 979 indentText = IndentText; |
| 980 | 980 |
| 981 if (style.textIndentType() == TextIndentHanging) | 981 if (style.textIndentType() == TextIndentHanging) |
| 982 indentText = indentText == IndentText ? DoNotIndentText : IndentText; | 982 indentText = indentText == IndentText ? DoNotIndentText : IndentText; |
| 983 | 983 |
| 984 return indentText; | 984 return indentText; |
| 985 } | 985 } |
| 986 | 986 |
| 987 } // namespace blink | 987 } // namespace blink |
| 988 | 988 |
| 989 #endif // BreakingContextInlineHeaders_h | 989 #endif // BreakingContextInlineHeaders_h |
| OLD | NEW |