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 |