| 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 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 107 inline void ensureLineBoxInsideIgnoredSpaces(LineMidpointState& lineMidpointStat
e, RenderObject* renderer) | 107 inline void ensureLineBoxInsideIgnoredSpaces(LineMidpointState& lineMidpointStat
e, RenderObject* renderer) |
| 108 { | 108 { |
| 109 InlineIterator midpoint(0, renderer, 0); | 109 InlineIterator midpoint(0, renderer, 0); |
| 110 stopIgnoringSpaces(lineMidpointState, midpoint); | 110 stopIgnoringSpaces(lineMidpointState, midpoint); |
| 111 startIgnoringSpaces(lineMidpointState, midpoint); | 111 startIgnoringSpaces(lineMidpointState, midpoint); |
| 112 } | 112 } |
| 113 | 113 |
| 114 // Adding a pair of midpoints before a character will split it out into a new li
ne box. | 114 // Adding a pair of midpoints before a character will split it out into a new li
ne box. |
| 115 inline void ensureCharacterGetsLineBox(LineMidpointState& lineMidpointState, Inl
ineIterator& textParagraphSeparator) | 115 inline void ensureCharacterGetsLineBox(LineMidpointState& lineMidpointState, Inl
ineIterator& textParagraphSeparator) |
| 116 { | 116 { |
| 117 InlineIterator midpoint(0, textParagraphSeparator.m_obj, textParagraphSepara
tor.m_pos); | 117 InlineIterator midpoint(0, textParagraphSeparator.object(), textParagraphSep
arator.m_pos); |
| 118 startIgnoringSpaces(lineMidpointState, InlineIterator(0, textParagraphSepara
tor.m_obj, textParagraphSeparator.m_pos - 1)); | 118 startIgnoringSpaces(lineMidpointState, InlineIterator(0, textParagraphSepara
tor.object(), textParagraphSeparator.m_pos - 1)); |
| 119 stopIgnoringSpaces(lineMidpointState, InlineIterator(0, textParagraphSeparat
or.m_obj, textParagraphSeparator.m_pos)); | 119 stopIgnoringSpaces(lineMidpointState, InlineIterator(0, textParagraphSeparat
or.object(), textParagraphSeparator.m_pos)); |
| 120 } | 120 } |
| 121 | 121 |
| 122 class TrailingObjects { | 122 class TrailingObjects { |
| 123 public: | 123 public: |
| 124 TrailingObjects(); | 124 TrailingObjects(); |
| 125 void setTrailingWhitespace(RenderText*); | 125 void setTrailingWhitespace(RenderText*); |
| 126 void clear(); | 126 void clear(); |
| 127 void appendBoxIfNeeded(RenderBox*); | 127 void appendBoxIfNeeded(RenderBox*); |
| 128 | 128 |
| 129 enum CollapseFirstSpaceOrNot { DoNotCollapseFirstSpace, CollapseFirstSpace }
; | 129 enum CollapseFirstSpaceOrNot { DoNotCollapseFirstSpace, CollapseFirstSpace }
; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 void TrailingObjects::updateMidpointsForTrailingBoxes(LineMidpointState& lineMid
pointState, const InlineIterator& lBreak, CollapseFirstSpaceOrNot collapseFirstS
pace) | 164 void TrailingObjects::updateMidpointsForTrailingBoxes(LineMidpointState& lineMid
pointState, const InlineIterator& lBreak, CollapseFirstSpaceOrNot collapseFirstS
pace) |
| 165 { | 165 { |
| 166 if (!m_whitespace) | 166 if (!m_whitespace) |
| 167 return; | 167 return; |
| 168 | 168 |
| 169 // This object is either going to be part of the last midpoint, or it is goi
ng to be the actual endpoint. | 169 // This object is either going to be part of the last midpoint, or it is goi
ng to be the actual endpoint. |
| 170 // In both cases we just decrease our pos by 1 level to exclude the space, a
llowing it to - in effect - collapse into the newline. | 170 // In both cases we just decrease our pos by 1 level to exclude the space, a
llowing it to - in effect - collapse into the newline. |
| 171 if (lineMidpointState.numMidpoints % 2) { | 171 if (lineMidpointState.numMidpoints % 2) { |
| 172 // Find the trailing space object's midpoint. | 172 // Find the trailing space object's midpoint. |
| 173 int trailingSpaceMidpoint = lineMidpointState.numMidpoints - 1; | 173 int trailingSpaceMidpoint = lineMidpointState.numMidpoints - 1; |
| 174 for ( ; trailingSpaceMidpoint > 0 && lineMidpointState.midpoints[trailin
gSpaceMidpoint].m_obj != m_whitespace; --trailingSpaceMidpoint) { } | 174 for ( ; trailingSpaceMidpoint > 0 && lineMidpointState.midpoints[trailin
gSpaceMidpoint].object() != m_whitespace; --trailingSpaceMidpoint) { } |
| 175 ASSERT(trailingSpaceMidpoint >= 0); | 175 ASSERT(trailingSpaceMidpoint >= 0); |
| 176 if (collapseFirstSpace == CollapseFirstSpace) | 176 if (collapseFirstSpace == CollapseFirstSpace) |
| 177 lineMidpointState.midpoints[trailingSpaceMidpoint].m_pos--; | 177 lineMidpointState.midpoints[trailingSpaceMidpoint].m_pos--; |
| 178 | 178 |
| 179 // Now make sure every single trailingPositionedBox following the traili
ngSpaceMidpoint properly stops and starts | 179 // Now make sure every single trailingPositionedBox following the traili
ngSpaceMidpoint properly stops and starts |
| 180 // ignoring spaces. | 180 // ignoring spaces. |
| 181 size_t currentMidpoint = trailingSpaceMidpoint + 1; | 181 size_t currentMidpoint = trailingSpaceMidpoint + 1; |
| 182 for (size_t i = 0; i < m_boxes.size(); ++i) { | 182 for (size_t i = 0; i < m_boxes.size(); ++i) { |
| 183 if (currentMidpoint >= lineMidpointState.numMidpoints) { | 183 if (currentMidpoint >= lineMidpointState.numMidpoints) { |
| 184 // We don't have a midpoint for this box yet. | 184 // We don't have a midpoint for this box yet. |
| 185 ensureLineBoxInsideIgnoredSpaces(lineMidpointState, m_boxes[i]); | 185 ensureLineBoxInsideIgnoredSpaces(lineMidpointState, m_boxes[i]); |
| 186 } else { | 186 } else { |
| 187 ASSERT(lineMidpointState.midpoints[currentMidpoint].m_obj == m_b
oxes[i]); | 187 ASSERT(lineMidpointState.midpoints[currentMidpoint].object() ==
m_boxes[i]); |
| 188 ASSERT(lineMidpointState.midpoints[currentMidpoint + 1].m_obj ==
m_boxes[i]); | 188 ASSERT(lineMidpointState.midpoints[currentMidpoint + 1].object()
== m_boxes[i]); |
| 189 } | 189 } |
| 190 currentMidpoint += 2; | 190 currentMidpoint += 2; |
| 191 } | 191 } |
| 192 } else if (!lBreak.m_obj) { | 192 } else if (!lBreak.object()) { |
| 193 ASSERT(m_whitespace->isText()); | 193 ASSERT(m_whitespace->isText()); |
| 194 ASSERT(collapseFirstSpace == CollapseFirstSpace); | 194 ASSERT(collapseFirstSpace == CollapseFirstSpace); |
| 195 // Add a new end midpoint that stops right at the very end. | 195 // Add a new end midpoint that stops right at the very end. |
| 196 unsigned length = m_whitespace->textLength(); | 196 unsigned length = m_whitespace->textLength(); |
| 197 unsigned pos = length >= 2 ? length - 2 : UINT_MAX; | 197 unsigned pos = length >= 2 ? length - 2 : UINT_MAX; |
| 198 InlineIterator endMid(0, m_whitespace, pos); | 198 InlineIterator endMid(0, m_whitespace, pos); |
| 199 startIgnoringSpaces(lineMidpointState, endMid); | 199 startIgnoringSpaces(lineMidpointState, endMid); |
| 200 for (size_t i = 0; i < m_boxes.size(); ++i) { | 200 for (size_t i = 0; i < m_boxes.size(); ++i) { |
| 201 ensureLineBoxInsideIgnoredSpaces(lineMidpointState, m_boxes[i]); | 201 ensureLineBoxInsideIgnoredSpaces(lineMidpointState, m_boxes[i]); |
| 202 } | 202 } |
| 203 } | 203 } |
| 204 } | 204 } |
| 205 | 205 |
| 206 class BreakingContext { | 206 class BreakingContext { |
| 207 public: | 207 public: |
| 208 BreakingContext(InlineBidiResolver& resolver, LineInfo& inLineInfo, LineWidt
h& lineWidth, RenderTextInfo& inRenderTextInfo, FloatingObject* inLastFloatFromP
reviousLine, bool appliedStartWidth, RenderBlockFlow* block) | 208 BreakingContext(InlineBidiResolver& resolver, LineInfo& inLineInfo, LineWidt
h& lineWidth, RenderTextInfo& inRenderTextInfo, FloatingObject* inLastFloatFromP
reviousLine, bool appliedStartWidth, RenderBlockFlow* block) |
| 209 : m_resolver(resolver) | 209 : m_resolver(resolver) |
| 210 , m_current(resolver.position()) | 210 , m_current(resolver.position()) |
| 211 , m_lineBreak(resolver.position()) | 211 , m_lineBreak(resolver.position()) |
| 212 , m_block(block) | 212 , m_block(block) |
| 213 , m_lastObject(m_current.m_obj) | 213 , m_lastObject(m_current.object()) |
| 214 , m_nextObject(0) | 214 , m_nextObject(0) |
| 215 , m_currentStyle(0) | 215 , m_currentStyle(0) |
| 216 , m_blockStyle(block->style()) | 216 , m_blockStyle(block->style()) |
| 217 , m_lineInfo(inLineInfo) | 217 , m_lineInfo(inLineInfo) |
| 218 , m_renderTextInfo(inRenderTextInfo) | 218 , m_renderTextInfo(inRenderTextInfo) |
| 219 , m_lastFloatFromPreviousLine(inLastFloatFromPreviousLine) | 219 , m_lastFloatFromPreviousLine(inLastFloatFromPreviousLine) |
| 220 , m_width(lineWidth) | 220 , m_width(lineWidth) |
| 221 , m_currWS(NORMAL) | 221 , m_currWS(NORMAL) |
| 222 , m_lastWS(NORMAL) | 222 , m_lastWS(NORMAL) |
| 223 , m_preservesNewline(false) | 223 , m_preservesNewline(false) |
| 224 , m_atStart(true) | 224 , m_atStart(true) |
| 225 , m_ignoringSpaces(false) | 225 , m_ignoringSpaces(false) |
| 226 , m_currentCharacterIsSpace(false) | 226 , m_currentCharacterIsSpace(false) |
| 227 , m_currentCharacterShouldCollapseIfPreWap(false) | 227 , m_currentCharacterShouldCollapseIfPreWap(false) |
| 228 , m_appliedStartWidth(appliedStartWidth) | 228 , m_appliedStartWidth(appliedStartWidth) |
| 229 , m_includeEndWidth(true) | 229 , m_includeEndWidth(true) |
| 230 , m_autoWrap(false) | 230 , m_autoWrap(false) |
| 231 , m_autoWrapWasEverTrueOnLine(false) | 231 , m_autoWrapWasEverTrueOnLine(false) |
| 232 , m_floatsFitOnLine(true) | 232 , m_floatsFitOnLine(true) |
| 233 , m_collapseWhiteSpace(false) | 233 , m_collapseWhiteSpace(false) |
| 234 , m_startingNewParagraph(m_lineInfo.previousLineBrokeCleanly()) | 234 , m_startingNewParagraph(m_lineInfo.previousLineBrokeCleanly()) |
| 235 , m_allowImagesToBreak(!block->document().inQuirksMode() || !block->isTa
bleCell() || !m_blockStyle->logicalWidth().isIntrinsicOrAuto()) | 235 , m_allowImagesToBreak(!block->document().inQuirksMode() || !block->isTa
bleCell() || !m_blockStyle->logicalWidth().isIntrinsicOrAuto()) |
| 236 , m_atEnd(false) | 236 , m_atEnd(false) |
| 237 , m_lineMidpointState(resolver.midpointState()) | 237 , m_lineMidpointState(resolver.midpointState()) |
| 238 { | 238 { |
| 239 m_lineInfo.setPreviousLineBrokeCleanly(false); | 239 m_lineInfo.setPreviousLineBrokeCleanly(false); |
| 240 } | 240 } |
| 241 | 241 |
| 242 RenderObject* currentObject() { return m_current.m_obj; } | 242 RenderObject* currentObject() { return m_current.object(); } |
| 243 InlineIterator lineBreak() { return m_lineBreak; } | 243 InlineIterator lineBreak() { return m_lineBreak; } |
| 244 bool atEnd() { return m_atEnd; } | 244 bool atEnd() { return m_atEnd; } |
| 245 | 245 |
| 246 void initializeForCurrentObject(); | 246 void initializeForCurrentObject(); |
| 247 | 247 |
| 248 void increment(); | 248 void increment(); |
| 249 | 249 |
| 250 void handleBR(EClear&); | 250 void handleBR(EClear&); |
| 251 void handleOutOfFlowPositioned(Vector<RenderBox*>& positionedObjects); | 251 void handleOutOfFlowPositioned(Vector<RenderBox*>& positionedObjects); |
| 252 void handleFloat(); | 252 void handleFloat(); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 inline bool alwaysRequiresLineBox(RenderObject* flow) | 335 inline bool alwaysRequiresLineBox(RenderObject* flow) |
| 336 { | 336 { |
| 337 // FIXME: Right now, we only allow line boxes for inlines that are truly emp
ty. | 337 // FIXME: Right now, we only allow line boxes for inlines that are truly emp
ty. |
| 338 // We need to fix this, though, because at the very least, inlines containin
g only | 338 // We need to fix this, though, because at the very least, inlines containin
g only |
| 339 // ignorable whitespace should should also have line boxes. | 339 // ignorable whitespace should should also have line boxes. |
| 340 return isEmptyInline(flow) && toRenderInline(flow)->hasInlineDirectionBorder
sPaddingOrMargin(); | 340 return isEmptyInline(flow) && toRenderInline(flow)->hasInlineDirectionBorder
sPaddingOrMargin(); |
| 341 } | 341 } |
| 342 | 342 |
| 343 inline bool requiresLineBox(const InlineIterator& it, const LineInfo& lineInfo =
LineInfo(), WhitespacePosition whitespacePosition = LeadingWhitespace) | 343 inline bool requiresLineBox(const InlineIterator& it, const LineInfo& lineInfo =
LineInfo(), WhitespacePosition whitespacePosition = LeadingWhitespace) |
| 344 { | 344 { |
| 345 if (it.m_obj->isFloatingOrOutOfFlowPositioned()) | 345 if (it.object()->isFloatingOrOutOfFlowPositioned()) |
| 346 return false; | 346 return false; |
| 347 | 347 |
| 348 if (it.m_obj->isRenderInline() && !alwaysRequiresLineBox(it.m_obj) && !requi
resLineBoxForContent(toRenderInline(it.m_obj), lineInfo)) | 348 if (it.object()->isRenderInline() && !alwaysRequiresLineBox(it.object()) &&
!requiresLineBoxForContent(toRenderInline(it.object()), lineInfo)) |
| 349 return false; | 349 return false; |
| 350 | 350 |
| 351 if (!shouldCollapseWhiteSpace(it.m_obj->style(), lineInfo, whitespacePositio
n) || it.m_obj->isBR()) | 351 if (!shouldCollapseWhiteSpace(it.object()->style(), lineInfo, whitespacePosi
tion) || it.object()->isBR()) |
| 352 return true; | 352 return true; |
| 353 | 353 |
| 354 UChar current = it.current(); | 354 UChar current = it.current(); |
| 355 bool notJustWhitespace = current != ' ' && current != '\t' && current != sof
tHyphen && (current != '\n' || it.m_obj->preservesNewline()); | 355 bool notJustWhitespace = current != ' ' && current != '\t' && current != sof
tHyphen && (current != '\n' || it.object()->preservesNewline()); |
| 356 return notJustWhitespace || isEmptyInline(it.m_obj); | 356 return notJustWhitespace || isEmptyInline(it.object()); |
| 357 } | 357 } |
| 358 | 358 |
| 359 inline void setStaticPositions(RenderBlockFlow* block, RenderBox* child) | 359 inline void setStaticPositions(RenderBlockFlow* block, RenderBox* child) |
| 360 { | 360 { |
| 361 // FIXME: The math here is actually not really right. It's a best-guess appr
oximation that | 361 // FIXME: The math here is actually not really right. It's a best-guess appr
oximation that |
| 362 // will work for the common cases | 362 // will work for the common cases |
| 363 RenderObject* containerBlock = child->container(); | 363 RenderObject* containerBlock = child->container(); |
| 364 LayoutUnit blockHeight = block->logicalHeight(); | 364 LayoutUnit blockHeight = block->logicalHeight(); |
| 365 if (containerBlock->isRenderInline()) { | 365 if (containerBlock->isRenderInline()) { |
| 366 // A relative positioned inline encloses us. In this case, we also have
to determine our | 366 // A relative positioned inline encloses us. In this case, we also have
to determine our |
| 367 // position as though we were an inline. Set |staticInlinePosition| and
|staticBlockPosition| on the relative positioned | 367 // position as though we were an inline. Set |staticInlinePosition| and
|staticBlockPosition| on the relative positioned |
| 368 // inline so that we can obtain the value later. | 368 // inline so that we can obtain the value later. |
| 369 toRenderInline(containerBlock)->layer()->setStaticInlinePosition(block->
startAlignedOffsetForLine(blockHeight, false)); | 369 toRenderInline(containerBlock)->layer()->setStaticInlinePosition(block->
startAlignedOffsetForLine(blockHeight, false)); |
| 370 toRenderInline(containerBlock)->layer()->setStaticBlockPosition(blockHei
ght); | 370 toRenderInline(containerBlock)->layer()->setStaticBlockPosition(blockHei
ght); |
| 371 } | 371 } |
| 372 block->updateStaticInlinePositionForChild(child, blockHeight); | 372 block->updateStaticInlinePositionForChild(child, blockHeight); |
| 373 child->layer()->setStaticBlockPosition(blockHeight); | 373 child->layer()->setStaticBlockPosition(blockHeight); |
| 374 } | 374 } |
| 375 | 375 |
| 376 // FIXME: The entire concept of the skipTrailingWhitespace function is flawed, s
ince we really need to be building | 376 // FIXME: The entire concept of the skipTrailingWhitespace function is flawed, s
ince we really need to be building |
| 377 // line boxes even for containers that may ultimately collapse away. Otherwise w
e'll never get positioned | 377 // line boxes even for containers that may ultimately collapse away. Otherwise w
e'll never get positioned |
| 378 // elements quite right. In other words, we need to build this function's work i
nto the normal line | 378 // elements quite right. In other words, we need to build this function's work i
nto the normal line |
| 379 // object iteration process. | 379 // object iteration process. |
| 380 // NB. this function will insert any floating elements that would otherwise | 380 // NB. this function will insert any floating elements that would otherwise |
| 381 // be skipped but it will not position them. | 381 // be skipped but it will not position them. |
| 382 inline void BreakingContext::skipTrailingWhitespace(InlineIterator& iterator, co
nst LineInfo& lineInfo) | 382 inline void BreakingContext::skipTrailingWhitespace(InlineIterator& iterator, co
nst LineInfo& lineInfo) |
| 383 { | 383 { |
| 384 while (!iterator.atEnd() && !requiresLineBox(iterator, lineInfo, TrailingWhi
tespace)) { | 384 while (!iterator.atEnd() && !requiresLineBox(iterator, lineInfo, TrailingWhi
tespace)) { |
| 385 RenderObject* object = iterator.m_obj; | 385 RenderObject* object = iterator.object(); |
| 386 if (object->isOutOfFlowPositioned()) | 386 if (object->isOutOfFlowPositioned()) |
| 387 setStaticPositions(m_block, toRenderBox(object)); | 387 setStaticPositions(m_block, toRenderBox(object)); |
| 388 else if (object->isFloating()) | 388 else if (object->isFloating()) |
| 389 m_block->insertFloatingObject(toRenderBox(object)); | 389 m_block->insertFloatingObject(toRenderBox(object)); |
| 390 iterator.increment(); | 390 iterator.increment(); |
| 391 } | 391 } |
| 392 } | 392 } |
| 393 | 393 |
| 394 inline void BreakingContext::initializeForCurrentObject() | 394 inline void BreakingContext::initializeForCurrentObject() |
| 395 { | 395 { |
| 396 m_currentStyle = m_current.m_obj->style(); | 396 m_currentStyle = m_current.object()->style(); |
| 397 m_nextObject = bidiNextSkippingEmptyInlines(m_block, m_current.m_obj); | 397 m_nextObject = bidiNextSkippingEmptyInlines(m_block, m_current.object()); |
| 398 if (m_nextObject && m_nextObject->parent() && !m_nextObject->parent()->isDes
cendantOf(m_current.m_obj->parent())) | 398 if (m_nextObject && m_nextObject->parent() && !m_nextObject->parent()->isDes
cendantOf(m_current.object()->parent())) |
| 399 m_includeEndWidth = true; | 399 m_includeEndWidth = true; |
| 400 | 400 |
| 401 m_currWS = m_current.m_obj->isReplaced() ? m_current.m_obj->parent()->style(
)->whiteSpace() : m_currentStyle->whiteSpace(); | 401 m_currWS = m_current.object()->isReplaced() ? m_current.object()->parent()->
style()->whiteSpace() : m_currentStyle->whiteSpace(); |
| 402 m_lastWS = m_lastObject->isReplaced() ? m_lastObject->parent()->style()->whi
teSpace() : m_lastObject->style()->whiteSpace(); | 402 m_lastWS = m_lastObject->isReplaced() ? m_lastObject->parent()->style()->whi
teSpace() : m_lastObject->style()->whiteSpace(); |
| 403 | 403 |
| 404 m_autoWrap = RenderStyle::autoWrap(m_currWS); | 404 m_autoWrap = RenderStyle::autoWrap(m_currWS); |
| 405 m_autoWrapWasEverTrueOnLine = m_autoWrapWasEverTrueOnLine || m_autoWrap; | 405 m_autoWrapWasEverTrueOnLine = m_autoWrapWasEverTrueOnLine || m_autoWrap; |
| 406 | 406 |
| 407 m_preservesNewline = m_current.m_obj->isSVGInlineText() ? false : RenderStyl
e::preserveNewline(m_currWS); | 407 m_preservesNewline = m_current.object()->isSVGInlineText() ? false : RenderS
tyle::preserveNewline(m_currWS); |
| 408 | 408 |
| 409 m_collapseWhiteSpace = RenderStyle::collapseWhiteSpace(m_currWS); | 409 m_collapseWhiteSpace = RenderStyle::collapseWhiteSpace(m_currWS); |
| 410 } | 410 } |
| 411 | 411 |
| 412 inline void BreakingContext::increment() | 412 inline void BreakingContext::increment() |
| 413 { | 413 { |
| 414 // Clear out our character space bool, since inline <pre>s don't collapse wh
itespace | 414 // Clear out our character space bool, since inline <pre>s don't collapse wh
itespace |
| 415 // with adjacent inline normal/nowrap spans. | 415 // with adjacent inline normal/nowrap spans. |
| 416 if (!m_collapseWhiteSpace) | 416 if (!m_collapseWhiteSpace) |
| 417 m_currentCharacterIsSpace = false; | 417 m_currentCharacterIsSpace = false; |
| 418 | 418 |
| 419 m_current.moveToStartOf(m_nextObject); | 419 m_current.moveToStartOf(m_nextObject); |
| 420 m_atStart = false; | 420 m_atStart = false; |
| 421 } | 421 } |
| 422 | 422 |
| 423 inline void BreakingContext::handleBR(EClear& clear) | 423 inline void BreakingContext::handleBR(EClear& clear) |
| 424 { | 424 { |
| 425 if (m_width.fitsOnLine()) { | 425 if (m_width.fitsOnLine()) { |
| 426 RenderObject* br = m_current.m_obj; | 426 RenderObject* br = m_current.object(); |
| 427 m_lineBreak.moveToStartOf(br); | 427 m_lineBreak.moveToStartOf(br); |
| 428 m_lineBreak.increment(); | 428 m_lineBreak.increment(); |
| 429 | 429 |
| 430 // A <br> always breaks a line, so don't let the line be collapsed | 430 // A <br> always breaks a line, so don't let the line be collapsed |
| 431 // away. Also, the space at the end of a line with a <br> does not | 431 // away. Also, the space at the end of a line with a <br> does not |
| 432 // get collapsed away. It only does this if the previous line broke | 432 // get collapsed away. It only does this if the previous line broke |
| 433 // cleanly. Otherwise the <br> has no effect on whether the line is | 433 // cleanly. Otherwise the <br> has no effect on whether the line is |
| 434 // empty or not. | 434 // empty or not. |
| 435 if (m_startingNewParagraph) | 435 if (m_startingNewParagraph) |
| 436 m_lineInfo.setEmpty(false, m_block, &m_width); | 436 m_lineInfo.setEmpty(false, m_block, &m_width); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 485 child = parent; | 485 child = parent; |
| 486 parent = child->parent(); | 486 parent = child->parent(); |
| 487 } | 487 } |
| 488 return extraWidth; | 488 return extraWidth; |
| 489 } | 489 } |
| 490 | 490 |
| 491 inline void BreakingContext::handleOutOfFlowPositioned(Vector<RenderBox*>& posit
ionedObjects) | 491 inline void BreakingContext::handleOutOfFlowPositioned(Vector<RenderBox*>& posit
ionedObjects) |
| 492 { | 492 { |
| 493 // If our original display wasn't an inline type, then we can | 493 // If our original display wasn't an inline type, then we can |
| 494 // go ahead and determine our static inline position now. | 494 // go ahead and determine our static inline position now. |
| 495 RenderBox* box = toRenderBox(m_current.m_obj); | 495 RenderBox* box = toRenderBox(m_current.object()); |
| 496 bool isInlineType = box->style()->isOriginalDisplayInlineType(); | 496 bool isInlineType = box->style()->isOriginalDisplayInlineType(); |
| 497 if (!isInlineType) { | 497 if (!isInlineType) { |
| 498 m_block->setStaticInlinePositionForChild(box, m_block->logicalHeight(),
m_block->startOffsetForContent(m_block->logicalHeight())); | 498 m_block->setStaticInlinePositionForChild(box, m_block->logicalHeight(),
m_block->startOffsetForContent(m_block->logicalHeight())); |
| 499 } else { | 499 } else { |
| 500 // If our original display was an INLINE type, then we can go ahead | 500 // If our original display was an INLINE type, then we can go ahead |
| 501 // and determine our static y position now. | 501 // and determine our static y position now. |
| 502 box->layer()->setStaticBlockPosition(m_block->logicalHeight()); | 502 box->layer()->setStaticBlockPosition(m_block->logicalHeight()); |
| 503 } | 503 } |
| 504 | 504 |
| 505 // If we're ignoring spaces, we have to stop and include this object and | 505 // If we're ignoring spaces, we have to stop and include this object and |
| 506 // then start ignoring spaces again. | 506 // then start ignoring spaces again. |
| 507 if (isInlineType || box->container()->isRenderInline()) { | 507 if (isInlineType || box->container()->isRenderInline()) { |
| 508 if (m_ignoringSpaces) | 508 if (m_ignoringSpaces) |
| 509 ensureLineBoxInsideIgnoredSpaces(m_lineMidpointState, box); | 509 ensureLineBoxInsideIgnoredSpaces(m_lineMidpointState, box); |
| 510 m_trailingObjects.appendBoxIfNeeded(box); | 510 m_trailingObjects.appendBoxIfNeeded(box); |
| 511 } else { | 511 } else { |
| 512 positionedObjects.append(box); | 512 positionedObjects.append(box); |
| 513 } | 513 } |
| 514 m_width.addUncommittedWidth(inlineLogicalWidth(box)); | 514 m_width.addUncommittedWidth(inlineLogicalWidth(box)); |
| 515 // Reset prior line break context characters. | 515 // Reset prior line break context characters. |
| 516 m_renderTextInfo.m_lineBreakIterator.resetPriorContext(); | 516 m_renderTextInfo.m_lineBreakIterator.resetPriorContext(); |
| 517 } | 517 } |
| 518 | 518 |
| 519 inline void BreakingContext::handleFloat() | 519 inline void BreakingContext::handleFloat() |
| 520 { | 520 { |
| 521 RenderBox* floatBox = toRenderBox(m_current.m_obj); | 521 RenderBox* floatBox = toRenderBox(m_current.object()); |
| 522 FloatingObject* floatingObject = m_block->insertFloatingObject(floatBox); | 522 FloatingObject* floatingObject = m_block->insertFloatingObject(floatBox); |
| 523 // check if it fits in the current line. | 523 // check if it fits in the current line. |
| 524 // If it does, position it now, otherwise, position | 524 // If it does, position it now, otherwise, position |
| 525 // it after moving to next line (in newLine() func) | 525 // it after moving to next line (in newLine() func) |
| 526 // FIXME: Bug 110372: Properly position multiple stacked floats with non-rec
tangular shape outside. | 526 // FIXME: Bug 110372: Properly position multiple stacked floats with non-rec
tangular shape outside. |
| 527 if (m_floatsFitOnLine && m_width.fitsOnLine(m_block->logicalWidthForFloat(fl
oatingObject))) { | 527 if (m_floatsFitOnLine && m_width.fitsOnLine(m_block->logicalWidthForFloat(fl
oatingObject))) { |
| 528 m_block->positionNewFloatOnLine(floatingObject, m_lastFloatFromPreviousL
ine, m_lineInfo, m_width); | 528 m_block->positionNewFloatOnLine(floatingObject, m_lastFloatFromPreviousL
ine, m_lineInfo, m_width); |
| 529 if (m_lineBreak.m_obj == m_current.m_obj) { | 529 if (m_lineBreak.object() == m_current.object()) { |
| 530 ASSERT(!m_lineBreak.m_pos); | 530 ASSERT(!m_lineBreak.m_pos); |
| 531 m_lineBreak.increment(); | 531 m_lineBreak.increment(); |
| 532 } | 532 } |
| 533 } else { | 533 } else { |
| 534 m_floatsFitOnLine = false; | 534 m_floatsFitOnLine = false; |
| 535 } | 535 } |
| 536 // Update prior line break context characters, using U+FFFD (OBJECT REPLACEM
ENT CHARACTER) for floating element. | 536 // Update prior line break context characters, using U+FFFD (OBJECT REPLACEM
ENT CHARACTER) for floating element. |
| 537 m_renderTextInfo.m_lineBreakIterator.updatePriorContext(replacementCharacter
); | 537 m_renderTextInfo.m_lineBreakIterator.updatePriorContext(replacementCharacter
); |
| 538 } | 538 } |
| 539 | 539 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 553 return true; | 553 return true; |
| 554 } | 554 } |
| 555 } | 555 } |
| 556 | 556 |
| 557 return false; | 557 return false; |
| 558 } | 558 } |
| 559 | 559 |
| 560 inline void BreakingContext::handleEmptyInline() | 560 inline void BreakingContext::handleEmptyInline() |
| 561 { | 561 { |
| 562 // This should only end up being called on empty inlines | 562 // This should only end up being called on empty inlines |
| 563 ASSERT(isEmptyInline(m_current.m_obj)); | 563 ASSERT(isEmptyInline(m_current.object())); |
| 564 | 564 |
| 565 RenderInline* flowBox = toRenderInline(m_current.m_obj); | 565 RenderInline* flowBox = toRenderInline(m_current.object()); |
| 566 | 566 |
| 567 // Now that some inline flows have line boxes, if we are already ignoring sp
aces, we need | 567 // Now that some inline flows have line boxes, if we are already ignoring sp
aces, we need |
| 568 // to make sure that we stop to include this object and then start ignoring
spaces again. | 568 // to make sure that we stop to include this object and then start ignoring
spaces again. |
| 569 // If this object is at the start of the line, we need to behave like list m
arkers and | 569 // If this object is at the start of the line, we need to behave like list m
arkers and |
| 570 // start ignoring spaces. | 570 // start ignoring spaces. |
| 571 bool requiresLineBox = alwaysRequiresLineBox(m_current.m_obj); | 571 bool requiresLineBox = alwaysRequiresLineBox(m_current.object()); |
| 572 if (requiresLineBox || requiresLineBoxForContent(flowBox, m_lineInfo)) { | 572 if (requiresLineBox || requiresLineBoxForContent(flowBox, m_lineInfo)) { |
| 573 // An empty inline that only has line-height, vertical-align or font-met
rics will only get a | 573 // An empty inline that only has line-height, vertical-align or font-met
rics will only get a |
| 574 // line box to affect the height of the line if the rest of the line is
not empty. | 574 // line box to affect the height of the line if the rest of the line is
not empty. |
| 575 if (requiresLineBox) | 575 if (requiresLineBox) |
| 576 m_lineInfo.setEmpty(false, m_block, &m_width); | 576 m_lineInfo.setEmpty(false, m_block, &m_width); |
| 577 if (m_ignoringSpaces) { | 577 if (m_ignoringSpaces) { |
| 578 m_trailingObjects.clear(); | 578 m_trailingObjects.clear(); |
| 579 ensureLineBoxInsideIgnoredSpaces(m_lineMidpointState, m_current.m_ob
j); | 579 ensureLineBoxInsideIgnoredSpaces(m_lineMidpointState, m_current.obje
ct()); |
| 580 } else if (m_blockStyle->collapseWhiteSpace() && m_resolver.position().m
_obj == m_current.m_obj | 580 } else if (m_blockStyle->collapseWhiteSpace() && m_resolver.position().o
bject() == m_current.object() |
| 581 && shouldSkipWhitespaceAfterStartObject(m_block, m_current.m_obj, m_
lineMidpointState)) { | 581 && shouldSkipWhitespaceAfterStartObject(m_block, m_current.object(),
m_lineMidpointState)) { |
| 582 // Like with list markers, we start ignoring spaces to make sure tha
t any | 582 // Like with list markers, we start ignoring spaces to make sure tha
t any |
| 583 // additional spaces we see will be discarded. | 583 // additional spaces we see will be discarded. |
| 584 m_currentCharacterShouldCollapseIfPreWap = m_currentCharacterIsSpace
= true; | 584 m_currentCharacterShouldCollapseIfPreWap = m_currentCharacterIsSpace
= true; |
| 585 m_ignoringSpaces = true; | 585 m_ignoringSpaces = true; |
| 586 } | 586 } |
| 587 } | 587 } |
| 588 | 588 |
| 589 m_width.addUncommittedWidth(inlineLogicalWidth(m_current.m_obj) + borderPadd
ingMarginStart(flowBox) + borderPaddingMarginEnd(flowBox)); | 589 m_width.addUncommittedWidth(inlineLogicalWidth(m_current.object()) + borderP
addingMarginStart(flowBox) + borderPaddingMarginEnd(flowBox)); |
| 590 } | 590 } |
| 591 | 591 |
| 592 inline void BreakingContext::handleReplaced() | 592 inline void BreakingContext::handleReplaced() |
| 593 { | 593 { |
| 594 RenderBox* replacedBox = toRenderBox(m_current.m_obj); | 594 RenderBox* replacedBox = toRenderBox(m_current.object()); |
| 595 | 595 |
| 596 if (m_atStart) | 596 if (m_atStart) |
| 597 m_width.updateAvailableWidth(replacedBox->logicalHeight()); | 597 m_width.updateAvailableWidth(replacedBox->logicalHeight()); |
| 598 | 598 |
| 599 // Break on replaced elements if either has normal white-space. | 599 // Break on replaced elements if either has normal white-space. |
| 600 if ((m_autoWrap || RenderStyle::autoWrap(m_lastWS)) && (!m_current.m_obj->is
Image() || m_allowImagesToBreak)) { | 600 if ((m_autoWrap || RenderStyle::autoWrap(m_lastWS)) && (!m_current.object()-
>isImage() || m_allowImagesToBreak)) { |
| 601 m_width.commit(); | 601 m_width.commit(); |
| 602 m_lineBreak.moveToStartOf(m_current.m_obj); | 602 m_lineBreak.moveToStartOf(m_current.object()); |
| 603 } | 603 } |
| 604 | 604 |
| 605 if (m_ignoringSpaces) | 605 if (m_ignoringSpaces) |
| 606 stopIgnoringSpaces(m_lineMidpointState, InlineIterator(0, m_current.m_ob
j, 0)); | 606 stopIgnoringSpaces(m_lineMidpointState, InlineIterator(0, m_current.obje
ct(), 0)); |
| 607 | 607 |
| 608 m_lineInfo.setEmpty(false, m_block, &m_width); | 608 m_lineInfo.setEmpty(false, m_block, &m_width); |
| 609 m_ignoringSpaces = false; | 609 m_ignoringSpaces = false; |
| 610 m_currentCharacterShouldCollapseIfPreWap = m_currentCharacterIsSpace = false
; | 610 m_currentCharacterShouldCollapseIfPreWap = m_currentCharacterIsSpace = false
; |
| 611 m_trailingObjects.clear(); | 611 m_trailingObjects.clear(); |
| 612 | 612 |
| 613 // Optimize for a common case. If we can't find whitespace after the list | 613 // Optimize for a common case. If we can't find whitespace after the list |
| 614 // item, then this is all moot. | 614 // item, then this is all moot. |
| 615 LayoutUnit replacedLogicalWidth = m_block->logicalWidthForChild(replacedBox)
+ m_block->marginStartForChild(replacedBox) + m_block->marginEndForChild(replac
edBox) + inlineLogicalWidth(m_current.m_obj); | 615 LayoutUnit replacedLogicalWidth = m_block->logicalWidthForChild(replacedBox)
+ m_block->marginStartForChild(replacedBox) + m_block->marginEndForChild(replac
edBox) + inlineLogicalWidth(m_current.object()); |
| 616 if (m_current.m_obj->isListMarker()) { | 616 if (m_current.object()->isListMarker()) { |
| 617 if (m_blockStyle->collapseWhiteSpace() && shouldSkipWhitespaceAfterStart
Object(m_block, m_current.m_obj, m_lineMidpointState)) { | 617 if (m_blockStyle->collapseWhiteSpace() && shouldSkipWhitespaceAfterStart
Object(m_block, m_current.object(), m_lineMidpointState)) { |
| 618 // Like with inline flows, we start ignoring spaces to make sure tha
t any | 618 // Like with inline flows, we start ignoring spaces to make sure tha
t any |
| 619 // additional spaces we see will be discarded. | 619 // additional spaces we see will be discarded. |
| 620 m_currentCharacterShouldCollapseIfPreWap = m_currentCharacterIsSpace
= true; | 620 m_currentCharacterShouldCollapseIfPreWap = m_currentCharacterIsSpace
= true; |
| 621 m_ignoringSpaces = true; | 621 m_ignoringSpaces = true; |
| 622 } | 622 } |
| 623 if (toRenderListMarker(m_current.m_obj)->isInside()) | 623 if (toRenderListMarker(m_current.object())->isInside()) |
| 624 m_width.addUncommittedWidth(replacedLogicalWidth); | 624 m_width.addUncommittedWidth(replacedLogicalWidth); |
| 625 } else { | 625 } else { |
| 626 m_width.addUncommittedWidth(replacedLogicalWidth); | 626 m_width.addUncommittedWidth(replacedLogicalWidth); |
| 627 } | 627 } |
| 628 if (m_current.m_obj->isRubyRun()) | 628 if (m_current.object()->isRubyRun()) |
| 629 m_width.applyOverhang(toRenderRubyRun(m_current.m_obj), m_lastObject, m_
nextObject); | 629 m_width.applyOverhang(toRenderRubyRun(m_current.object()), m_lastObject,
m_nextObject); |
| 630 // Update prior line break context characters, using U+FFFD (OBJECT REPLACEM
ENT CHARACTER) for replaced element. | 630 // Update prior line break context characters, using U+FFFD (OBJECT REPLACEM
ENT CHARACTER) for replaced element. |
| 631 m_renderTextInfo.m_lineBreakIterator.updatePriorContext(replacementCharacter
); | 631 m_renderTextInfo.m_lineBreakIterator.updatePriorContext(replacementCharacter
); |
| 632 } | 632 } |
| 633 | 633 |
| 634 inline bool iteratorIsBeyondEndOfRenderCombineText(const InlineIterator& iter, R
enderCombineText* renderer) | 634 inline bool iteratorIsBeyondEndOfRenderCombineText(const InlineIterator& iter, R
enderCombineText* renderer) |
| 635 { | 635 { |
| 636 return iter.m_obj == renderer && iter.m_pos >= renderer->textLength(); | 636 return iter.object() == renderer && iter.m_pos >= renderer->textLength(); |
| 637 } | 637 } |
| 638 | 638 |
| 639 inline void nextCharacter(UChar& currentCharacter, UChar& lastCharacter, UChar&
secondToLastCharacter) | 639 inline void nextCharacter(UChar& currentCharacter, UChar& lastCharacter, UChar&
secondToLastCharacter) |
| 640 { | 640 { |
| 641 secondToLastCharacter = lastCharacter; | 641 secondToLastCharacter = lastCharacter; |
| 642 lastCharacter = currentCharacter; | 642 lastCharacter = currentCharacter; |
| 643 } | 643 } |
| 644 | 644 |
| 645 inline float firstPositiveWidth(const WordMeasurements& wordMeasurements) | 645 inline float firstPositiveWidth(const WordMeasurements& wordMeasurements) |
| 646 { | 646 { |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 715 run.setTabSize(!collapseWhiteSpace, text->style()->tabSize()); | 715 run.setTabSize(!collapseWhiteSpace, text->style()->tabSize()); |
| 716 run.setXPos(xPos); | 716 run.setXPos(xPos); |
| 717 return font.width(run, fallbackFonts, &glyphOverflow); | 717 return font.width(run, fallbackFonts, &glyphOverflow); |
| 718 } | 718 } |
| 719 | 719 |
| 720 inline bool BreakingContext::handleText(WordMeasurements& wordMeasurements, bool
& hyphenated) | 720 inline bool BreakingContext::handleText(WordMeasurements& wordMeasurements, bool
& hyphenated) |
| 721 { | 721 { |
| 722 if (!m_current.m_pos) | 722 if (!m_current.m_pos) |
| 723 m_appliedStartWidth = false; | 723 m_appliedStartWidth = false; |
| 724 | 724 |
| 725 RenderText* renderText = toRenderText(m_current.m_obj); | 725 RenderText* renderText = toRenderText(m_current.object()); |
| 726 | 726 |
| 727 bool isSVGText = renderText->isSVGInlineText(); | 727 bool isSVGText = renderText->isSVGInlineText(); |
| 728 | 728 |
| 729 if (renderText->style()->hasTextCombine() && m_current.m_obj->isCombineText(
) && !toRenderCombineText(m_current.m_obj)->isCombined()) { | 729 if (renderText->style()->hasTextCombine() && m_current.object()->isCombineTe
xt() && !toRenderCombineText(m_current.object())->isCombined()) { |
| 730 RenderCombineText* combineRenderer = toRenderCombineText(m_current.m_obj
); | 730 RenderCombineText* combineRenderer = toRenderCombineText(m_current.objec
t()); |
| 731 combineRenderer->combineText(); | 731 combineRenderer->combineText(); |
| 732 // The length of the renderer's text may have changed. Increment stale i
terator positions | 732 // The length of the renderer's text may have changed. Increment stale i
terator positions |
| 733 if (iteratorIsBeyondEndOfRenderCombineText(m_lineBreak, combineRenderer)
) { | 733 if (iteratorIsBeyondEndOfRenderCombineText(m_lineBreak, combineRenderer)
) { |
| 734 ASSERT(iteratorIsBeyondEndOfRenderCombineText(m_resolver.position(),
combineRenderer)); | 734 ASSERT(iteratorIsBeyondEndOfRenderCombineText(m_resolver.position(),
combineRenderer)); |
| 735 m_lineBreak.increment(); | 735 m_lineBreak.increment(); |
| 736 m_resolver.position().increment(&m_resolver); | 736 m_resolver.position().increment(&m_resolver); |
| 737 } | 737 } |
| 738 } | 738 } |
| 739 | 739 |
| 740 RenderStyle* style = renderText->style(m_lineInfo.isFirstLine()); | 740 RenderStyle* style = renderText->style(m_lineInfo.isFirstLine()); |
| 741 const Font& font = style->font(); | 741 const Font& font = style->font(); |
| 742 bool isFixedPitch = font.isFixedPitch(); | 742 bool isFixedPitch = font.isFixedPitch(); |
| 743 | 743 |
| 744 unsigned lastSpace = m_current.m_pos; | 744 unsigned lastSpace = m_current.m_pos; |
| 745 float wordSpacing = m_currentStyle->wordSpacing(); | 745 float wordSpacing = m_currentStyle->wordSpacing(); |
| 746 float lastSpaceWordSpacing = 0; | 746 float lastSpaceWordSpacing = 0; |
| 747 float wordSpacingForWordMeasurement = 0; | 747 float wordSpacingForWordMeasurement = 0; |
| 748 | 748 |
| 749 float wrapW = m_width.uncommittedWidth() + inlineLogicalWidth(m_current.m_ob
j, !m_appliedStartWidth, true); | 749 float wrapW = m_width.uncommittedWidth() + inlineLogicalWidth(m_current.obje
ct(), !m_appliedStartWidth, true); |
| 750 float charWidth = 0; | 750 float charWidth = 0; |
| 751 // Auto-wrapping text should wrap in the middle of a word only if it could n
ot wrap before the word, | 751 // Auto-wrapping text should wrap in the middle of a word only if it could n
ot wrap before the word, |
| 752 // which is only possible if the word is the first thing on the line, that i
s, if |w| is zero. | 752 // which is only possible if the word is the first thing on the line, that i
s, if |w| is zero. |
| 753 bool breakWords = m_currentStyle->breakWords() && ((m_autoWrap && !m_width.c
ommittedWidth()) || m_currWS == PRE); | 753 bool breakWords = m_currentStyle->breakWords() && ((m_autoWrap && !m_width.c
ommittedWidth()) || m_currWS == PRE); |
| 754 bool midWordBreak = false; | 754 bool midWordBreak = false; |
| 755 bool breakAll = m_currentStyle->wordBreak() == BreakAllWordBreak && m_autoWr
ap; | 755 bool breakAll = m_currentStyle->wordBreak() == BreakAllWordBreak && m_autoWr
ap; |
| 756 float hyphenWidth = 0; | 756 float hyphenWidth = 0; |
| 757 | 757 |
| 758 if (isSVGText) { | 758 if (isSVGText) { |
| 759 breakWords = false; | 759 breakWords = false; |
| 760 breakAll = false; | 760 breakAll = false; |
| 761 } | 761 } |
| 762 | 762 |
| 763 if (renderText->isWordBreak()) { | 763 if (renderText->isWordBreak()) { |
| 764 m_width.commit(); | 764 m_width.commit(); |
| 765 m_lineBreak.moveToStartOf(m_current.m_obj); | 765 m_lineBreak.moveToStartOf(m_current.object()); |
| 766 ASSERT(m_current.m_pos == renderText->textLength()); | 766 ASSERT(m_current.m_pos == renderText->textLength()); |
| 767 } | 767 } |
| 768 | 768 |
| 769 if (m_renderTextInfo.m_text != renderText) { | 769 if (m_renderTextInfo.m_text != renderText) { |
| 770 m_renderTextInfo.m_text = renderText; | 770 m_renderTextInfo.m_text = renderText; |
| 771 m_renderTextInfo.m_font = &font; | 771 m_renderTextInfo.m_font = &font; |
| 772 m_renderTextInfo.createLayout(renderText, m_width.currentWidth(), m_coll
apseWhiteSpace); | 772 m_renderTextInfo.createLayout(renderText, m_width.currentWidth(), m_coll
apseWhiteSpace); |
| 773 m_renderTextInfo.m_lineBreakIterator.resetStringAndReleaseIterator(rende
rText->text(), style->locale()); | 773 m_renderTextInfo.m_lineBreakIterator.resetStringAndReleaseIterator(rende
rText->text(), style->locale()); |
| 774 } else if (m_renderTextInfo.m_layout && m_renderTextInfo.m_font != &font) { | 774 } else if (m_renderTextInfo.m_layout && m_renderTextInfo.m_font != &font) { |
| 775 m_renderTextInfo.m_font = &font; | 775 m_renderTextInfo.m_font = &font; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 812 if (betweenWords || midWordBreak) { | 812 if (betweenWords || midWordBreak) { |
| 813 bool stoppedIgnoringSpaces = false; | 813 bool stoppedIgnoringSpaces = false; |
| 814 if (m_ignoringSpaces) { | 814 if (m_ignoringSpaces) { |
| 815 lastSpaceWordSpacing = 0; | 815 lastSpaceWordSpacing = 0; |
| 816 if (!m_currentCharacterIsSpace) { | 816 if (!m_currentCharacterIsSpace) { |
| 817 // Stop ignoring spaces and begin at this | 817 // Stop ignoring spaces and begin at this |
| 818 // new point. | 818 // new point. |
| 819 m_ignoringSpaces = false; | 819 m_ignoringSpaces = false; |
| 820 wordSpacingForWordMeasurement = 0; | 820 wordSpacingForWordMeasurement = 0; |
| 821 lastSpace = m_current.m_pos; // e.g., "Foo goo", don't ad
d in any of the ignored spaces. | 821 lastSpace = m_current.m_pos; // e.g., "Foo goo", don't ad
d in any of the ignored spaces. |
| 822 stopIgnoringSpaces(m_lineMidpointState, InlineIterator(0, m_
current.m_obj, m_current.m_pos)); | 822 stopIgnoringSpaces(m_lineMidpointState, InlineIterator(0, m_
current.object(), m_current.m_pos)); |
| 823 stoppedIgnoringSpaces = true; | 823 stoppedIgnoringSpaces = true; |
| 824 } else { | 824 } else { |
| 825 // Just keep ignoring these spaces. | 825 // Just keep ignoring these spaces. |
| 826 nextCharacter(c, lastCharacter, secondToLastCharacter); | 826 nextCharacter(c, lastCharacter, secondToLastCharacter); |
| 827 continue; | 827 continue; |
| 828 } | 828 } |
| 829 } | 829 } |
| 830 | 830 |
| 831 wordMeasurements.grow(wordMeasurements.size() + 1); | 831 wordMeasurements.grow(wordMeasurements.size() + 1); |
| 832 WordMeasurement& wordMeasurement = wordMeasurements.last(); | 832 WordMeasurement& wordMeasurement = wordMeasurements.last(); |
| 833 | 833 |
| 834 wordMeasurement.renderer = renderText; | 834 wordMeasurement.renderer = renderText; |
| 835 wordMeasurement.endOffset = m_current.m_pos; | 835 wordMeasurement.endOffset = m_current.m_pos; |
| 836 wordMeasurement.startOffset = lastSpace; | 836 wordMeasurement.startOffset = lastSpace; |
| 837 | 837 |
| 838 float additionalTmpW; | 838 float additionalTmpW; |
| 839 if (wordTrailingSpaceWidth && c == ' ') | 839 if (wordTrailingSpaceWidth && c == ' ') |
| 840 additionalTmpW = textWidth(renderText, lastSpace, m_current.m_po
s + 1 - lastSpace, font, m_width.currentWidth(), isFixedPitch, m_collapseWhiteSp
ace, &wordMeasurement.fallbackFonts, textLayout) - wordTrailingSpaceWidth; | 840 additionalTmpW = textWidth(renderText, lastSpace, m_current.m_po
s + 1 - lastSpace, font, m_width.currentWidth(), isFixedPitch, m_collapseWhiteSp
ace, &wordMeasurement.fallbackFonts, textLayout) - wordTrailingSpaceWidth; |
| 841 else | 841 else |
| 842 additionalTmpW = textWidth(renderText, lastSpace, m_current.m_po
s - lastSpace, font, m_width.currentWidth(), isFixedPitch, m_collapseWhiteSpace,
&wordMeasurement.fallbackFonts, textLayout); | 842 additionalTmpW = textWidth(renderText, lastSpace, m_current.m_po
s - lastSpace, font, m_width.currentWidth(), isFixedPitch, m_collapseWhiteSpace,
&wordMeasurement.fallbackFonts, textLayout); |
| 843 | 843 |
| 844 wordMeasurement.width = additionalTmpW + wordSpacingForWordMeasureme
nt; | 844 wordMeasurement.width = additionalTmpW + wordSpacingForWordMeasureme
nt; |
| 845 additionalTmpW += lastSpaceWordSpacing; | 845 additionalTmpW += lastSpaceWordSpacing; |
| 846 m_width.addUncommittedWidth(additionalTmpW); | 846 m_width.addUncommittedWidth(additionalTmpW); |
| 847 if (!m_appliedStartWidth) { | 847 if (!m_appliedStartWidth) { |
| 848 m_width.addUncommittedWidth(inlineLogicalWidth(m_current.m_obj,
true, false)); | 848 m_width.addUncommittedWidth(inlineLogicalWidth(m_current.object(
), true, false)); |
| 849 m_appliedStartWidth = true; | 849 m_appliedStartWidth = true; |
| 850 } | 850 } |
| 851 | 851 |
| 852 if (m_lastFloatFromPreviousLine) | 852 if (m_lastFloatFromPreviousLine) |
| 853 updateSegmentsForShapes(m_block, m_lastFloatFromPreviousLine, wo
rdMeasurements, m_width, m_lineInfo.isFirstLine()); | 853 updateSegmentsForShapes(m_block, m_lastFloatFromPreviousLine, wo
rdMeasurements, m_width, m_lineInfo.isFirstLine()); |
| 854 | 854 |
| 855 applyWordSpacing = wordSpacing && m_currentCharacterIsSpace; | 855 applyWordSpacing = wordSpacing && m_currentCharacterIsSpace; |
| 856 | 856 |
| 857 if (!m_width.committedWidth() && m_autoWrap && !m_width.fitsOnLine()
) | 857 if (!m_width.committedWidth() && m_autoWrap && !m_width.fitsOnLine()
) |
| 858 m_width.fitBelowFloats(); | 858 m_width.fitBelowFloats(); |
| 859 | 859 |
| 860 if (m_autoWrap || breakWords) { | 860 if (m_autoWrap || breakWords) { |
| 861 // If we break only after white-space, consider the current char
acter | 861 // If we break only after white-space, consider the current char
acter |
| 862 // as candidate width for this line. | 862 // as candidate width for this line. |
| 863 bool lineWasTooWide = false; | 863 bool lineWasTooWide = false; |
| 864 if (m_width.fitsOnLine() && m_currentCharacterIsSpace && m_curre
ntStyle->breakOnlyAfterWhiteSpace() && !midWordBreak) { | 864 if (m_width.fitsOnLine() && m_currentCharacterIsSpace && m_curre
ntStyle->breakOnlyAfterWhiteSpace() && !midWordBreak) { |
| 865 float charWidth = textWidth(renderText, m_current.m_pos, 1,
font, m_width.currentWidth(), isFixedPitch, m_collapseWhiteSpace, &wordMeasureme
nt.fallbackFonts, textLayout) + (applyWordSpacing ? wordSpacing : 0); | 865 float charWidth = textWidth(renderText, m_current.m_pos, 1,
font, m_width.currentWidth(), isFixedPitch, m_collapseWhiteSpace, &wordMeasureme
nt.fallbackFonts, textLayout) + (applyWordSpacing ? wordSpacing : 0); |
| 866 // Check if line is too big even without the extra space | 866 // Check if line is too big even without the extra space |
| 867 // at the end of the line. If it is not, do nothing. | 867 // at the end of the line. If it is not, do nothing. |
| 868 // If the line needs the extra whitespace to be too long, | 868 // If the line needs the extra whitespace to be too long, |
| 869 // then move the line break to the space and skip all | 869 // then move the line break to the space and skip all |
| 870 // additional whitespace. | 870 // additional whitespace. |
| 871 if (!m_width.fitsOnLine(charWidth)) { | 871 if (!m_width.fitsOnLine(charWidth)) { |
| 872 lineWasTooWide = true; | 872 lineWasTooWide = true; |
| 873 m_lineBreak.moveTo(m_current.m_obj, m_current.m_pos, m_c
urrent.m_nextBreakablePosition); | 873 m_lineBreak.moveTo(m_current.object(), m_current.m_pos,
m_current.m_nextBreakablePosition); |
| 874 skipTrailingWhitespace(m_lineBreak, m_lineInfo); | 874 skipTrailingWhitespace(m_lineBreak, m_lineInfo); |
| 875 } | 875 } |
| 876 } | 876 } |
| 877 if (lineWasTooWide || !m_width.fitsOnLine()) { | 877 if (lineWasTooWide || !m_width.fitsOnLine()) { |
| 878 if (m_lineBreak.atTextParagraphSeparator()) { | 878 if (m_lineBreak.atTextParagraphSeparator()) { |
| 879 if (!stoppedIgnoringSpaces && m_current.m_pos > 0) | 879 if (!stoppedIgnoringSpaces && m_current.m_pos > 0) |
| 880 ensureCharacterGetsLineBox(m_lineMidpointState, m_cu
rrent); | 880 ensureCharacterGetsLineBox(m_lineMidpointState, m_cu
rrent); |
| 881 m_lineBreak.increment(); | 881 m_lineBreak.increment(); |
| 882 m_lineInfo.setPreviousLineBrokeCleanly(true); | 882 m_lineInfo.setPreviousLineBrokeCleanly(true); |
| 883 wordMeasurement.endOffset = m_lineBreak.m_pos; | 883 wordMeasurement.endOffset = m_lineBreak.m_pos; |
| 884 } | 884 } |
| 885 if (m_lineBreak.m_obj && m_lineBreak.m_pos && m_lineBreak.m_
obj->isText() && toRenderText(m_lineBreak.m_obj)->textLength() && toRenderText(m
_lineBreak.m_obj)->characterAt(m_lineBreak.m_pos - 1) == softHyphen) | 885 if (m_lineBreak.object() && m_lineBreak.m_pos && m_lineBreak
.object()->isText() && toRenderText(m_lineBreak.object())->textLength() && toRen
derText(m_lineBreak.object())->characterAt(m_lineBreak.m_pos - 1) == softHyphen) |
| 886 hyphenated = true; | 886 hyphenated = true; |
| 887 if (m_lineBreak.m_pos && m_lineBreak.m_pos != (unsigned)word
Measurement.endOffset && !wordMeasurement.width) { | 887 if (m_lineBreak.m_pos && m_lineBreak.m_pos != (unsigned)word
Measurement.endOffset && !wordMeasurement.width) { |
| 888 if (charWidth) { | 888 if (charWidth) { |
| 889 wordMeasurement.endOffset = m_lineBreak.m_pos; | 889 wordMeasurement.endOffset = m_lineBreak.m_pos; |
| 890 wordMeasurement.width = charWidth; | 890 wordMeasurement.width = charWidth; |
| 891 } | 891 } |
| 892 } | 892 } |
| 893 // Didn't fit. Jump to the end unless there's still an oppor
tunity to collapse whitespace. | 893 // Didn't fit. Jump to the end unless there's still an oppor
tunity to collapse whitespace. |
| 894 if (m_ignoringSpaces || !m_collapseWhiteSpace || !m_currentC
haracterIsSpace || !previousCharacterIsSpace) { | 894 if (m_ignoringSpaces || !m_collapseWhiteSpace || !m_currentC
haracterIsSpace || !previousCharacterIsSpace) { |
| 895 m_atEnd = true; | 895 m_atEnd = true; |
| 896 return false; | 896 return false; |
| 897 } | 897 } |
| 898 } else { | 898 } else { |
| 899 if (!betweenWords || (midWordBreak && !m_autoWrap)) | 899 if (!betweenWords || (midWordBreak && !m_autoWrap)) |
| 900 m_width.addUncommittedWidth(-additionalTmpW); | 900 m_width.addUncommittedWidth(-additionalTmpW); |
| 901 if (hyphenWidth) { | 901 if (hyphenWidth) { |
| 902 // Subtract the width of the soft hyphen out since we fi
t on a line. | 902 // Subtract the width of the soft hyphen out since we fi
t on a line. |
| 903 m_width.addUncommittedWidth(-hyphenWidth); | 903 m_width.addUncommittedWidth(-hyphenWidth); |
| 904 hyphenWidth = 0; | 904 hyphenWidth = 0; |
| 905 } | 905 } |
| 906 } | 906 } |
| 907 } | 907 } |
| 908 | 908 |
| 909 if (c == '\n' && m_preservesNewline) { | 909 if (c == '\n' && m_preservesNewline) { |
| 910 if (!stoppedIgnoringSpaces && m_current.m_pos > 0) | 910 if (!stoppedIgnoringSpaces && m_current.m_pos > 0) |
| 911 ensureCharacterGetsLineBox(m_lineMidpointState, m_current); | 911 ensureCharacterGetsLineBox(m_lineMidpointState, m_current); |
| 912 m_lineBreak.moveTo(m_current.m_obj, m_current.m_pos, m_current.m
_nextBreakablePosition); | 912 m_lineBreak.moveTo(m_current.object(), m_current.m_pos, m_curren
t.m_nextBreakablePosition); |
| 913 m_lineBreak.increment(); | 913 m_lineBreak.increment(); |
| 914 m_lineInfo.setPreviousLineBrokeCleanly(true); | 914 m_lineInfo.setPreviousLineBrokeCleanly(true); |
| 915 return true; | 915 return true; |
| 916 } | 916 } |
| 917 | 917 |
| 918 if (m_autoWrap && betweenWords) { | 918 if (m_autoWrap && betweenWords) { |
| 919 m_width.commit(); | 919 m_width.commit(); |
| 920 wrapW = 0; | 920 wrapW = 0; |
| 921 m_lineBreak.moveTo(m_current.m_obj, m_current.m_pos, m_current.m
_nextBreakablePosition); | 921 m_lineBreak.moveTo(m_current.object(), m_current.m_pos, m_curren
t.m_nextBreakablePosition); |
| 922 // Auto-wrapping text should not wrap in the middle of a word on
ce it has had an | 922 // Auto-wrapping text should not wrap in the middle of a word on
ce it has had an |
| 923 // opportunity to break after a word. | 923 // opportunity to break after a word. |
| 924 breakWords = false; | 924 breakWords = false; |
| 925 } | 925 } |
| 926 | 926 |
| 927 if (midWordBreak && !U16_IS_TRAIL(c) && !(category(c) & (Mark_NonSpa
cing | Mark_Enclosing | Mark_SpacingCombining))) { | 927 if (midWordBreak && !U16_IS_TRAIL(c) && !(category(c) & (Mark_NonSpa
cing | Mark_Enclosing | Mark_SpacingCombining))) { |
| 928 // Remember this as a breakable position in case | 928 // Remember this as a breakable position in case |
| 929 // adding the end width forces a break. | 929 // adding the end width forces a break. |
| 930 m_lineBreak.moveTo(m_current.m_obj, m_current.m_pos, m_current.m
_nextBreakablePosition); | 930 m_lineBreak.moveTo(m_current.object(), m_current.m_pos, m_curren
t.m_nextBreakablePosition); |
| 931 midWordBreak &= (breakWords || breakAll); | 931 midWordBreak &= (breakWords || breakAll); |
| 932 } | 932 } |
| 933 | 933 |
| 934 if (betweenWords) { | 934 if (betweenWords) { |
| 935 lastSpaceWordSpacing = applyWordSpacing ? wordSpacing : 0; | 935 lastSpaceWordSpacing = applyWordSpacing ? wordSpacing : 0; |
| 936 wordSpacingForWordMeasurement = (applyWordSpacing && wordMeasure
ment.width) ? wordSpacing : 0; | 936 wordSpacingForWordMeasurement = (applyWordSpacing && wordMeasure
ment.width) ? wordSpacing : 0; |
| 937 lastSpace = m_current.m_pos; | 937 lastSpace = m_current.m_pos; |
| 938 } | 938 } |
| 939 | 939 |
| 940 if (!m_ignoringSpaces && m_currentStyle->collapseWhiteSpace()) { | 940 if (!m_ignoringSpaces && m_currentStyle->collapseWhiteSpace()) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 951 m_trailingObjects.updateMidpointsForTrailingBoxes(m_lineMidp
ointState, InlineIterator(), TrailingObjects::DoNotCollapseFirstSpace); | 951 m_trailingObjects.updateMidpointsForTrailingBoxes(m_lineMidp
ointState, InlineIterator(), TrailingObjects::DoNotCollapseFirstSpace); |
| 952 } | 952 } |
| 953 } | 953 } |
| 954 } else if (m_ignoringSpaces) { | 954 } else if (m_ignoringSpaces) { |
| 955 // Stop ignoring spaces and begin at this | 955 // Stop ignoring spaces and begin at this |
| 956 // new point. | 956 // new point. |
| 957 m_ignoringSpaces = false; | 957 m_ignoringSpaces = false; |
| 958 lastSpaceWordSpacing = applyWordSpacing ? wordSpacing : 0; | 958 lastSpaceWordSpacing = applyWordSpacing ? wordSpacing : 0; |
| 959 wordSpacingForWordMeasurement = (applyWordSpacing && wordMeasurement
s.last().width) ? wordSpacing : 0; | 959 wordSpacingForWordMeasurement = (applyWordSpacing && wordMeasurement
s.last().width) ? wordSpacing : 0; |
| 960 lastSpace = m_current.m_pos; // e.g., "Foo goo", don't add in any
of the ignored spaces. | 960 lastSpace = m_current.m_pos; // e.g., "Foo goo", don't add in any
of the ignored spaces. |
| 961 stopIgnoringSpaces(m_lineMidpointState, InlineIterator(0, m_current.
m_obj, m_current.m_pos)); | 961 stopIgnoringSpaces(m_lineMidpointState, InlineIterator(0, m_current.
object(), m_current.m_pos)); |
| 962 } | 962 } |
| 963 | 963 |
| 964 if (isSVGText && m_current.m_pos > 0) { | 964 if (isSVGText && m_current.m_pos > 0) { |
| 965 // Force creation of new InlineBoxes for each absolute positioned ch
aracter (those that start new text chunks). | 965 // Force creation of new InlineBoxes for each absolute positioned ch
aracter (those that start new text chunks). |
| 966 if (toRenderSVGInlineText(renderText)->characterStartsNewTextChunk(m
_current.m_pos)) | 966 if (toRenderSVGInlineText(renderText)->characterStartsNewTextChunk(m
_current.m_pos)) |
| 967 ensureCharacterGetsLineBox(m_lineMidpointState, m_current); | 967 ensureCharacterGetsLineBox(m_lineMidpointState, m_current); |
| 968 } | 968 } |
| 969 | 969 |
| 970 if (m_currentCharacterIsSpace && !previousCharacterIsSpace) { | 970 if (m_currentCharacterIsSpace && !previousCharacterIsSpace) { |
| 971 m_startOfIgnoredSpaces.m_obj = m_current.m_obj; | 971 m_startOfIgnoredSpaces.setObject(m_current.object()); |
| 972 m_startOfIgnoredSpaces.m_pos = m_current.m_pos; | 972 m_startOfIgnoredSpaces.m_pos = m_current.m_pos; |
| 973 } | 973 } |
| 974 | 974 |
| 975 if (!m_currentCharacterIsSpace && previousCharacterShouldCollapseIfPreWa
p) { | 975 if (!m_currentCharacterIsSpace && previousCharacterShouldCollapseIfPreWa
p) { |
| 976 if (m_autoWrap && m_currentStyle->breakOnlyAfterWhiteSpace()) | 976 if (m_autoWrap && m_currentStyle->breakOnlyAfterWhiteSpace()) |
| 977 m_lineBreak.moveTo(m_current.m_obj, m_current.m_pos, m_current.m
_nextBreakablePosition); | 977 m_lineBreak.moveTo(m_current.object(), m_current.m_pos, m_curren
t.m_nextBreakablePosition); |
| 978 } | 978 } |
| 979 | 979 |
| 980 if (m_collapseWhiteSpace && m_currentCharacterIsSpace && !m_ignoringSpac
es) | 980 if (m_collapseWhiteSpace && m_currentCharacterIsSpace && !m_ignoringSpac
es) |
| 981 m_trailingObjects.setTrailingWhitespace(toRenderText(m_current.m_obj
)); | 981 m_trailingObjects.setTrailingWhitespace(toRenderText(m_current.objec
t())); |
| 982 else if (!m_currentStyle->collapseWhiteSpace() || !m_currentCharacterIsS
pace) | 982 else if (!m_currentStyle->collapseWhiteSpace() || !m_currentCharacterIsS
pace) |
| 983 m_trailingObjects.clear(); | 983 m_trailingObjects.clear(); |
| 984 | 984 |
| 985 m_atStart = false; | 985 m_atStart = false; |
| 986 nextCharacter(c, lastCharacter, secondToLastCharacter); | 986 nextCharacter(c, lastCharacter, secondToLastCharacter); |
| 987 } | 987 } |
| 988 | 988 |
| 989 m_renderTextInfo.m_lineBreakIterator.setPriorContext(lastCharacter, secondTo
LastCharacter); | 989 m_renderTextInfo.m_lineBreakIterator.setPriorContext(lastCharacter, secondTo
LastCharacter); |
| 990 | 990 |
| 991 wordMeasurements.grow(wordMeasurements.size() + 1); | 991 wordMeasurements.grow(wordMeasurements.size() + 1); |
| 992 WordMeasurement& wordMeasurement = wordMeasurements.last(); | 992 WordMeasurement& wordMeasurement = wordMeasurements.last(); |
| 993 wordMeasurement.renderer = renderText; | 993 wordMeasurement.renderer = renderText; |
| 994 | 994 |
| 995 // IMPORTANT: current.m_pos is > length here! | 995 // IMPORTANT: current.m_pos is > length here! |
| 996 float additionalTmpW = m_ignoringSpaces ? 0 : textWidth(renderText, lastSpac
e, m_current.m_pos - lastSpace, font, m_width.currentWidth(), isFixedPitch, m_co
llapseWhiteSpace, &wordMeasurement.fallbackFonts, textLayout); | 996 float additionalTmpW = m_ignoringSpaces ? 0 : textWidth(renderText, lastSpac
e, m_current.m_pos - lastSpace, font, m_width.currentWidth(), isFixedPitch, m_co
llapseWhiteSpace, &wordMeasurement.fallbackFonts, textLayout); |
| 997 wordMeasurement.startOffset = lastSpace; | 997 wordMeasurement.startOffset = lastSpace; |
| 998 wordMeasurement.endOffset = m_current.m_pos; | 998 wordMeasurement.endOffset = m_current.m_pos; |
| 999 wordMeasurement.width = m_ignoringSpaces ? 0 : additionalTmpW + wordSpacingF
orWordMeasurement; | 999 wordMeasurement.width = m_ignoringSpaces ? 0 : additionalTmpW + wordSpacingF
orWordMeasurement; |
| 1000 additionalTmpW += lastSpaceWordSpacing; | 1000 additionalTmpW += lastSpaceWordSpacing; |
| 1001 m_width.addUncommittedWidth(additionalTmpW + inlineLogicalWidth(m_current.m_
obj, !m_appliedStartWidth, m_includeEndWidth)); | 1001 m_width.addUncommittedWidth(additionalTmpW + inlineLogicalWidth(m_current.ob
ject(), !m_appliedStartWidth, m_includeEndWidth)); |
| 1002 m_includeEndWidth = false; | 1002 m_includeEndWidth = false; |
| 1003 | 1003 |
| 1004 if (!m_width.fitsOnLine()) { | 1004 if (!m_width.fitsOnLine()) { |
| 1005 if (!hyphenated && m_lineBreak.previousInSameNode() == softHyphen) { | 1005 if (!hyphenated && m_lineBreak.previousInSameNode() == softHyphen) { |
| 1006 hyphenated = true; | 1006 hyphenated = true; |
| 1007 m_atEnd = true; | 1007 m_atEnd = true; |
| 1008 } | 1008 } |
| 1009 } | 1009 } |
| 1010 return false; | 1010 return false; |
| 1011 } | 1011 } |
| 1012 | 1012 |
| 1013 inline void BreakingContext::commitAndUpdateLineBreakIfNeeded() | 1013 inline void BreakingContext::commitAndUpdateLineBreakIfNeeded() |
| 1014 { | 1014 { |
| 1015 bool checkForBreak = m_autoWrap; | 1015 bool checkForBreak = m_autoWrap; |
| 1016 if (m_width.committedWidth() && !m_width.fitsOnLine() && m_lineBreak.m_obj &
& m_currWS == NOWRAP) { | 1016 if (m_width.committedWidth() && !m_width.fitsOnLine() && m_lineBreak.object(
) && m_currWS == NOWRAP) { |
| 1017 checkForBreak = true; | 1017 checkForBreak = true; |
| 1018 } else if (m_nextObject && m_current.m_obj->isText() && m_nextObject->isText
() && !m_nextObject->isBR() && (m_autoWrap || m_nextObject->style()->autoWrap())
) { | 1018 } else if (m_nextObject && m_current.object()->isText() && m_nextObject->isT
ext() && !m_nextObject->isBR() && (m_autoWrap || m_nextObject->style()->autoWrap
())) { |
| 1019 if (m_autoWrap && m_currentCharacterIsSpace) { | 1019 if (m_autoWrap && m_currentCharacterIsSpace) { |
| 1020 checkForBreak = true; | 1020 checkForBreak = true; |
| 1021 } else { | 1021 } else { |
| 1022 RenderText* nextText = toRenderText(m_nextObject); | 1022 RenderText* nextText = toRenderText(m_nextObject); |
| 1023 if (nextText->textLength()) { | 1023 if (nextText->textLength()) { |
| 1024 UChar c = nextText->characterAt(0); | 1024 UChar c = nextText->characterAt(0); |
| 1025 // If the next item on the line is text, and if we did not end w
ith | 1025 // If the next item on the line is text, and if we did not end w
ith |
| 1026 // a space, then the next text run continues our word (and so it
needs to | 1026 // a space, then the next text run continues our word (and so it
needs to |
| 1027 // keep adding to the uncommitted width. Just update and continu
e. | 1027 // keep adding to the uncommitted width. Just update and continu
e. |
| 1028 checkForBreak = !m_currentCharacterIsSpace && (c == ' ' || c ==
'\t' || (c == '\n' && !m_nextObject->preservesNewline())); | 1028 checkForBreak = !m_currentCharacterIsSpace && (c == ' ' || c ==
'\t' || (c == '\n' && !m_nextObject->preservesNewline())); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1059 if (!m_width.fitsOnLine()) { | 1059 if (!m_width.fitsOnLine()) { |
| 1060 m_atEnd = true; | 1060 m_atEnd = true; |
| 1061 return; | 1061 return; |
| 1062 } | 1062 } |
| 1063 } else if (m_blockStyle->autoWrap() && !m_width.fitsOnLine() && !m_width.com
mittedWidth()) { | 1063 } else if (m_blockStyle->autoWrap() && !m_width.fitsOnLine() && !m_width.com
mittedWidth()) { |
| 1064 // If the container autowraps but the current child does not then we sti
ll need to ensure that it | 1064 // If the container autowraps but the current child does not then we sti
ll need to ensure that it |
| 1065 // wraps and moves below any floats. | 1065 // wraps and moves below any floats. |
| 1066 m_width.fitBelowFloats(); | 1066 m_width.fitBelowFloats(); |
| 1067 } | 1067 } |
| 1068 | 1068 |
| 1069 if (!m_current.m_obj->isFloatingOrOutOfFlowPositioned()) { | 1069 if (!m_current.object()->isFloatingOrOutOfFlowPositioned()) { |
| 1070 m_lastObject = m_current.m_obj; | 1070 m_lastObject = m_current.object(); |
| 1071 if (m_lastObject->isReplaced() && m_autoWrap && (!m_lastObject->isImage(
) || m_allowImagesToBreak) && (!m_lastObject->isListMarker() || toRenderListMark
er(m_lastObject)->isInside())) { | 1071 if (m_lastObject->isReplaced() && m_autoWrap && (!m_lastObject->isImage(
) || m_allowImagesToBreak) && (!m_lastObject->isListMarker() || toRenderListMark
er(m_lastObject)->isInside())) { |
| 1072 m_width.commit(); | 1072 m_width.commit(); |
| 1073 m_lineBreak.moveToStartOf(m_nextObject); | 1073 m_lineBreak.moveToStartOf(m_nextObject); |
| 1074 } | 1074 } |
| 1075 } | 1075 } |
| 1076 } | 1076 } |
| 1077 | 1077 |
| 1078 inline void checkMidpoints(LineMidpointState& lineMidpointState, InlineIterator&
lBreak) | 1078 inline void checkMidpoints(LineMidpointState& lineMidpointState, InlineIterator&
lBreak) |
| 1079 { | 1079 { |
| 1080 // Check to see if our last midpoint is a start point beyond the line break.
If so, | 1080 // Check to see if our last midpoint is a start point beyond the line break.
If so, |
| 1081 // shave it off the list, and shave off a trailing space if the previous end
point doesn't | 1081 // shave it off the list, and shave off a trailing space if the previous end
point doesn't |
| 1082 // preserve whitespace. | 1082 // preserve whitespace. |
| 1083 if (lBreak.m_obj && lineMidpointState.numMidpoints && !(lineMidpointState.nu
mMidpoints % 2)) { | 1083 if (lBreak.object() && lineMidpointState.numMidpoints && !(lineMidpointState
.numMidpoints % 2)) { |
| 1084 InlineIterator* midpoints = lineMidpointState.midpoints.data(); | 1084 InlineIterator* midpoints = lineMidpointState.midpoints.data(); |
| 1085 InlineIterator& endpoint = midpoints[lineMidpointState.numMidpoints - 2]
; | 1085 InlineIterator& endpoint = midpoints[lineMidpointState.numMidpoints - 2]
; |
| 1086 const InlineIterator& startpoint = midpoints[lineMidpointState.numMidpoi
nts - 1]; | 1086 const InlineIterator& startpoint = midpoints[lineMidpointState.numMidpoi
nts - 1]; |
| 1087 InlineIterator currpoint = endpoint; | 1087 InlineIterator currpoint = endpoint; |
| 1088 while (!currpoint.atEnd() && currpoint != startpoint && currpoint != lBr
eak) | 1088 while (!currpoint.atEnd() && currpoint != startpoint && currpoint != lBr
eak) |
| 1089 currpoint.increment(); | 1089 currpoint.increment(); |
| 1090 if (currpoint == lBreak) { | 1090 if (currpoint == lBreak) { |
| 1091 // We hit the line break before the start point. Shave off the start
point. | 1091 // We hit the line break before the start point. Shave off the start
point. |
| 1092 lineMidpointState.numMidpoints--; | 1092 lineMidpointState.numMidpoints--; |
| 1093 if (endpoint.m_obj->style()->collapseWhiteSpace() && endpoint.m_obj-
>isText()) | 1093 if (endpoint.object()->style()->collapseWhiteSpace() && endpoint.obj
ect()->isText()) |
| 1094 endpoint.m_pos--; | 1094 endpoint.m_pos--; |
| 1095 } | 1095 } |
| 1096 } | 1096 } |
| 1097 } | 1097 } |
| 1098 | 1098 |
| 1099 InlineIterator BreakingContext::handleEndOfLine() | 1099 InlineIterator BreakingContext::handleEndOfLine() |
| 1100 { | 1100 { |
| 1101 ShapeInsideInfo* shapeInfo = m_block->layoutShapeInsideInfo(); | 1101 ShapeInsideInfo* shapeInfo = m_block->layoutShapeInsideInfo(); |
| 1102 bool segmentAllowsOverflow = !shapeInfo || !shapeInfo->hasSegments(); | 1102 bool segmentAllowsOverflow = !shapeInfo || !shapeInfo->hasSegments(); |
| 1103 | 1103 |
| 1104 if (m_lineBreak == m_resolver.position() && (!m_lineBreak.m_obj || !m_lineBr
eak.m_obj->isBR()) && segmentAllowsOverflow) { | 1104 if (m_lineBreak == m_resolver.position() && (!m_lineBreak.object() || !m_lin
eBreak.object()->isBR()) && segmentAllowsOverflow) { |
| 1105 // we just add as much as possible | 1105 // we just add as much as possible |
| 1106 if (m_blockStyle->whiteSpace() == PRE && !m_current.m_pos) { | 1106 if (m_blockStyle->whiteSpace() == PRE && !m_current.m_pos) { |
| 1107 m_lineBreak.moveTo(m_lastObject, m_lastObject->isText() ? m_lastObje
ct->length() : 0); | 1107 m_lineBreak.moveTo(m_lastObject, m_lastObject->isText() ? m_lastObje
ct->length() : 0); |
| 1108 } else if (m_lineBreak.m_obj) { | 1108 } else if (m_lineBreak.object()) { |
| 1109 // Don't ever break in the middle of a word if we can help it. | 1109 // Don't ever break in the middle of a word if we can help it. |
| 1110 // There's no room at all. We just have to be on this line, | 1110 // There's no room at all. We just have to be on this line, |
| 1111 // even though we'll spill out. | 1111 // even though we'll spill out. |
| 1112 m_lineBreak.moveTo(m_current.m_obj, m_current.m_pos); | 1112 m_lineBreak.moveTo(m_current.object(), m_current.m_pos); |
| 1113 } | 1113 } |
| 1114 } | 1114 } |
| 1115 | 1115 |
| 1116 // FIXME Bug 100049: We do not need to consume input in a multi-segment line | 1116 // FIXME Bug 100049: We do not need to consume input in a multi-segment line |
| 1117 // unless no segment will. | 1117 // unless no segment will. |
| 1118 // make sure we consume at least one char/object. | 1118 // make sure we consume at least one char/object. |
| 1119 if (m_lineBreak == m_resolver.position() && segmentAllowsOverflow) | 1119 if (m_lineBreak == m_resolver.position() && segmentAllowsOverflow) |
| 1120 m_lineBreak.increment(); | 1120 m_lineBreak.increment(); |
| 1121 | 1121 |
| 1122 // Sanity check our midpoints. | 1122 // Sanity check our midpoints. |
| 1123 checkMidpoints(m_lineMidpointState, m_lineBreak); | 1123 checkMidpoints(m_lineMidpointState, m_lineBreak); |
| 1124 | 1124 |
| 1125 m_trailingObjects.updateMidpointsForTrailingBoxes(m_lineMidpointState, m_lin
eBreak, TrailingObjects::CollapseFirstSpace); | 1125 m_trailingObjects.updateMidpointsForTrailingBoxes(m_lineMidpointState, m_lin
eBreak, TrailingObjects::CollapseFirstSpace); |
| 1126 | 1126 |
| 1127 // We might have made lineBreak an iterator that points past the end | 1127 // We might have made lineBreak an iterator that points past the end |
| 1128 // of the object. Do this adjustment to make it point to the start | 1128 // of the object. Do this adjustment to make it point to the start |
| 1129 // of the next object instead to avoid confusing the rest of the | 1129 // of the next object instead to avoid confusing the rest of the |
| 1130 // code. | 1130 // code. |
| 1131 if (m_lineBreak.m_pos > 0) { | 1131 if (m_lineBreak.m_pos > 0) { |
| 1132 m_lineBreak.m_pos--; | 1132 m_lineBreak.m_pos--; |
| 1133 m_lineBreak.increment(); | 1133 m_lineBreak.increment(); |
| 1134 } | 1134 } |
| 1135 | 1135 |
| 1136 return m_lineBreak; | 1136 return m_lineBreak; |
| 1137 } | 1137 } |
| 1138 | 1138 |
| 1139 } | 1139 } |
| 1140 | 1140 |
| 1141 #endif // BreakingContextInlineHeaders_h | 1141 #endif // BreakingContextInlineHeaders_h |
| OLD | NEW |