| 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.object(), textParagraphSep
arator.m_pos); | 117 InlineIterator midpoint(0, textParagraphSeparator.object(), textParagraphSep
arator.offset()); |
| 118 startIgnoringSpaces(lineMidpointState, InlineIterator(0, textParagraphSepara
tor.object(), textParagraphSeparator.m_pos - 1)); | 118 startIgnoringSpaces(lineMidpointState, InlineIterator(0, textParagraphSepara
tor.object(), textParagraphSeparator.offset() - 1)); |
| 119 stopIgnoringSpaces(lineMidpointState, InlineIterator(0, textParagraphSeparat
or.object(), textParagraphSeparator.m_pos)); | 119 stopIgnoringSpaces(lineMidpointState, InlineIterator(0, textParagraphSeparat
or.object(), textParagraphSeparator.offset())); |
| 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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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].object() != 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].setOffset(lineMid
pointState.midpoints[trailingSpaceMidpoint].offset() -1); |
| 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].object() ==
m_boxes[i]); | 187 ASSERT(lineMidpointState.midpoints[currentMidpoint].object() ==
m_boxes[i]); |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 520 { | 520 { |
| 521 RenderBox* floatBox = toRenderBox(m_current.object()); | 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.object() == m_current.object()) { | 529 if (m_lineBreak.object() == m_current.object()) { |
| 530 ASSERT(!m_lineBreak.m_pos); | 530 ASSERT(!m_lineBreak.offset()); |
| 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 |
| 540 // This is currently just used for list markers and inline flows that have line
boxes. Neither should | 540 // This is currently just used for list markers and inline flows that have line
boxes. Neither should |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 626 m_width.addUncommittedWidth(replacedLogicalWidth); | 626 m_width.addUncommittedWidth(replacedLogicalWidth); |
| 627 } | 627 } |
| 628 if (m_current.object()->isRubyRun()) | 628 if (m_current.object()->isRubyRun()) |
| 629 m_width.applyOverhang(toRenderRubyRun(m_current.object()), 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.object() == renderer && iter.m_pos >= renderer->textLength(); | 636 return iter.object() == renderer && iter.offset() >= 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 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 712 ASSERT(run.charactersLength() >= run.length()); | 712 ASSERT(run.charactersLength() >= run.length()); |
| 713 | 713 |
| 714 run.setCharacterScanForCodePath(!text->canUseSimpleFontCodePath()); | 714 run.setCharacterScanForCodePath(!text->canUseSimpleFontCodePath()); |
| 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.offset()) |
| 723 m_appliedStartWidth = false; | 723 m_appliedStartWidth = false; |
| 724 | 724 |
| 725 RenderText* renderText = toRenderText(m_current.object()); | 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.object()->isCombineTe
xt() && !toRenderCombineText(m_current.object())->isCombined()) { | 729 if (renderText->style()->hasTextCombine() && m_current.object()->isCombineTe
xt() && !toRenderCombineText(m_current.object())->isCombined()) { |
| 730 RenderCombineText* combineRenderer = toRenderCombineText(m_current.objec
t()); | 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.offset(); |
| 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.obje
ct(), !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.object()); | 765 m_lineBreak.moveToStartOf(m_current.object()); |
| 766 ASSERT(m_current.m_pos == renderText->textLength()); | 766 ASSERT(m_current.offset() == 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; |
| 776 m_renderTextInfo.createLayout(renderText, m_width.currentWidth(), m_coll
apseWhiteSpace); | 776 m_renderTextInfo.createLayout(renderText, m_width.currentWidth(), m_coll
apseWhiteSpace); |
| 777 } | 777 } |
| 778 | 778 |
| 779 TextLayout* textLayout = m_renderTextInfo.m_layout.get(); | 779 TextLayout* textLayout = m_renderTextInfo.m_layout.get(); |
| 780 | 780 |
| 781 // Non-zero only when kerning is enabled and TextLayout isn't used, in which
case we measure | 781 // Non-zero only when kerning is enabled and TextLayout isn't used, in which
case we measure |
| 782 // words with their trailing space, then subtract its width. | 782 // words with their trailing space, then subtract its width. |
| 783 float wordTrailingSpaceWidth = (font.typesettingFeatures() & Kerning) && !te
xtLayout ? font.width(RenderBlockFlow::constructTextRun(renderText, font, &space
, 1, style)) + wordSpacing : 0; | 783 float wordTrailingSpaceWidth = (font.typesettingFeatures() & Kerning) && !te
xtLayout ? font.width(RenderBlockFlow::constructTextRun(renderText, font, &space
, 1, style)) + wordSpacing : 0; |
| 784 | 784 |
| 785 UChar lastCharacter = m_renderTextInfo.m_lineBreakIterator.lastCharacter(); | 785 UChar lastCharacter = m_renderTextInfo.m_lineBreakIterator.lastCharacter(); |
| 786 UChar secondToLastCharacter = m_renderTextInfo.m_lineBreakIterator.secondToL
astCharacter(); | 786 UChar secondToLastCharacter = m_renderTextInfo.m_lineBreakIterator.secondToL
astCharacter(); |
| 787 for (; m_current.m_pos < renderText->textLength(); m_current.fastIncrementIn
TextNode()) { | 787 for (; m_current.offset() < renderText->textLength(); m_current.fastIncremen
tInTextNode()) { |
| 788 bool previousCharacterIsSpace = m_currentCharacterIsSpace; | 788 bool previousCharacterIsSpace = m_currentCharacterIsSpace; |
| 789 bool previousCharacterShouldCollapseIfPreWap = m_currentCharacterShouldC
ollapseIfPreWap; | 789 bool previousCharacterShouldCollapseIfPreWap = m_currentCharacterShouldC
ollapseIfPreWap; |
| 790 UChar c = m_current.current(); | 790 UChar c = m_current.current(); |
| 791 m_currentCharacterShouldCollapseIfPreWap = m_currentCharacterIsSpace = c
== ' ' || c == '\t' || (!m_preservesNewline && (c == '\n')); | 791 m_currentCharacterShouldCollapseIfPreWap = m_currentCharacterIsSpace = c
== ' ' || c == '\t' || (!m_preservesNewline && (c == '\n')); |
| 792 | 792 |
| 793 if (!m_collapseWhiteSpace || !m_currentCharacterIsSpace) | 793 if (!m_collapseWhiteSpace || !m_currentCharacterIsSpace) |
| 794 m_lineInfo.setEmpty(false, m_block, &m_width); | 794 m_lineInfo.setEmpty(false, m_block, &m_width); |
| 795 | 795 |
| 796 if (c == softHyphen && m_autoWrap && !hyphenWidth) { | 796 if (c == softHyphen && m_autoWrap && !hyphenWidth) { |
| 797 hyphenWidth = measureHyphenWidth(renderText, font); | 797 hyphenWidth = measureHyphenWidth(renderText, font); |
| 798 m_width.addUncommittedWidth(hyphenWidth); | 798 m_width.addUncommittedWidth(hyphenWidth); |
| 799 } | 799 } |
| 800 | 800 |
| 801 bool applyWordSpacing = false; | 801 bool applyWordSpacing = false; |
| 802 | 802 |
| 803 if ((breakAll || breakWords) && !midWordBreak) { | 803 if ((breakAll || breakWords) && !midWordBreak) { |
| 804 wrapW += charWidth; | 804 wrapW += charWidth; |
| 805 bool midWordBreakIsBeforeSurrogatePair = U16_IS_LEAD(c) && m_current
.m_pos + 1 < renderText->textLength() && U16_IS_TRAIL((*renderText)[m_current.m_
pos + 1]); | 805 bool midWordBreakIsBeforeSurrogatePair = U16_IS_LEAD(c) && m_current
.offset() + 1 < renderText->textLength() && U16_IS_TRAIL((*renderText)[m_current
.offset() + 1]); |
| 806 charWidth = textWidth(renderText, m_current.m_pos, midWordBreakIsBef
oreSurrogatePair ? 2 : 1, font, m_width.committedWidth() + wrapW, isFixedPitch,
m_collapseWhiteSpace, 0, textLayout); | 806 charWidth = textWidth(renderText, m_current.offset(), midWordBreakIs
BeforeSurrogatePair ? 2 : 1, font, m_width.committedWidth() + wrapW, isFixedPitc
h, m_collapseWhiteSpace, 0, textLayout); |
| 807 midWordBreak = m_width.committedWidth() + wrapW + charWidth > m_widt
h.availableWidth(); | 807 midWordBreak = m_width.committedWidth() + wrapW + charWidth > m_widt
h.availableWidth(); |
| 808 } | 808 } |
| 809 | 809 |
| 810 int nextBreakablePosition = m_current.nextBreakablePosition(); | 810 int nextBreakablePosition = m_current.nextBreakablePosition(); |
| 811 bool betweenWords = c == '\n' || (m_currWS != PRE && !m_atStart && isBre
akable(m_renderTextInfo.m_lineBreakIterator, m_current.m_pos, nextBreakablePosit
ion)); | 811 bool betweenWords = c == '\n' || (m_currWS != PRE && !m_atStart && isBre
akable(m_renderTextInfo.m_lineBreakIterator, m_current.offset(), nextBreakablePo
sition)); |
| 812 m_current.setNextBreakablePosition(nextBreakablePosition); | 812 m_current.setNextBreakablePosition(nextBreakablePosition); |
| 813 | 813 |
| 814 if (betweenWords || midWordBreak) { | 814 if (betweenWords || midWordBreak) { |
| 815 bool stoppedIgnoringSpaces = false; | 815 bool stoppedIgnoringSpaces = false; |
| 816 if (m_ignoringSpaces) { | 816 if (m_ignoringSpaces) { |
| 817 lastSpaceWordSpacing = 0; | 817 lastSpaceWordSpacing = 0; |
| 818 if (!m_currentCharacterIsSpace) { | 818 if (!m_currentCharacterIsSpace) { |
| 819 // Stop ignoring spaces and begin at this | 819 // Stop ignoring spaces and begin at this |
| 820 // new point. | 820 // new point. |
| 821 m_ignoringSpaces = false; | 821 m_ignoringSpaces = false; |
| 822 wordSpacingForWordMeasurement = 0; | 822 wordSpacingForWordMeasurement = 0; |
| 823 lastSpace = m_current.m_pos; // e.g., "Foo goo", don't ad
d in any of the ignored spaces. | 823 lastSpace = m_current.offset(); // e.g., "Foo goo", don't
add in any of the ignored spaces. |
| 824 stopIgnoringSpaces(m_lineMidpointState, InlineIterator(0, m_
current.object(), m_current.m_pos)); | 824 stopIgnoringSpaces(m_lineMidpointState, InlineIterator(0, m_
current.object(), m_current.offset())); |
| 825 stoppedIgnoringSpaces = true; | 825 stoppedIgnoringSpaces = true; |
| 826 } else { | 826 } else { |
| 827 // Just keep ignoring these spaces. | 827 // Just keep ignoring these spaces. |
| 828 nextCharacter(c, lastCharacter, secondToLastCharacter); | 828 nextCharacter(c, lastCharacter, secondToLastCharacter); |
| 829 continue; | 829 continue; |
| 830 } | 830 } |
| 831 } | 831 } |
| 832 | 832 |
| 833 wordMeasurements.grow(wordMeasurements.size() + 1); | 833 wordMeasurements.grow(wordMeasurements.size() + 1); |
| 834 WordMeasurement& wordMeasurement = wordMeasurements.last(); | 834 WordMeasurement& wordMeasurement = wordMeasurements.last(); |
| 835 | 835 |
| 836 wordMeasurement.renderer = renderText; | 836 wordMeasurement.renderer = renderText; |
| 837 wordMeasurement.endOffset = m_current.m_pos; | 837 wordMeasurement.endOffset = m_current.offset(); |
| 838 wordMeasurement.startOffset = lastSpace; | 838 wordMeasurement.startOffset = lastSpace; |
| 839 | 839 |
| 840 float additionalTmpW; | 840 float additionalTmpW; |
| 841 if (wordTrailingSpaceWidth && c == ' ') | 841 if (wordTrailingSpaceWidth && c == ' ') |
| 842 additionalTmpW = textWidth(renderText, lastSpace, m_current.m_po
s + 1 - lastSpace, font, m_width.currentWidth(), isFixedPitch, m_collapseWhiteSp
ace, &wordMeasurement.fallbackFonts, textLayout) - wordTrailingSpaceWidth; | 842 additionalTmpW = textWidth(renderText, lastSpace, m_current.offs
et() + 1 - lastSpace, font, m_width.currentWidth(), isFixedPitch, m_collapseWhit
eSpace, &wordMeasurement.fallbackFonts, textLayout) - wordTrailingSpaceWidth; |
| 843 else | 843 else |
| 844 additionalTmpW = textWidth(renderText, lastSpace, m_current.m_po
s - lastSpace, font, m_width.currentWidth(), isFixedPitch, m_collapseWhiteSpace,
&wordMeasurement.fallbackFonts, textLayout); | 844 additionalTmpW = textWidth(renderText, lastSpace, m_current.offs
et() - lastSpace, font, m_width.currentWidth(), isFixedPitch, m_collapseWhiteSpa
ce, &wordMeasurement.fallbackFonts, textLayout); |
| 845 | 845 |
| 846 wordMeasurement.width = additionalTmpW + wordSpacingForWordMeasureme
nt; | 846 wordMeasurement.width = additionalTmpW + wordSpacingForWordMeasureme
nt; |
| 847 additionalTmpW += lastSpaceWordSpacing; | 847 additionalTmpW += lastSpaceWordSpacing; |
| 848 m_width.addUncommittedWidth(additionalTmpW); | 848 m_width.addUncommittedWidth(additionalTmpW); |
| 849 if (!m_appliedStartWidth) { | 849 if (!m_appliedStartWidth) { |
| 850 m_width.addUncommittedWidth(inlineLogicalWidth(m_current.object(
), true, false)); | 850 m_width.addUncommittedWidth(inlineLogicalWidth(m_current.object(
), true, false)); |
| 851 m_appliedStartWidth = true; | 851 m_appliedStartWidth = true; |
| 852 } | 852 } |
| 853 | 853 |
| 854 if (m_lastFloatFromPreviousLine) | 854 if (m_lastFloatFromPreviousLine) |
| 855 updateSegmentsForShapes(m_block, m_lastFloatFromPreviousLine, wo
rdMeasurements, m_width, m_lineInfo.isFirstLine()); | 855 updateSegmentsForShapes(m_block, m_lastFloatFromPreviousLine, wo
rdMeasurements, m_width, m_lineInfo.isFirstLine()); |
| 856 | 856 |
| 857 applyWordSpacing = wordSpacing && m_currentCharacterIsSpace; | 857 applyWordSpacing = wordSpacing && m_currentCharacterIsSpace; |
| 858 | 858 |
| 859 if (!m_width.committedWidth() && m_autoWrap && !m_width.fitsOnLine()
) | 859 if (!m_width.committedWidth() && m_autoWrap && !m_width.fitsOnLine()
) |
| 860 m_width.fitBelowFloats(); | 860 m_width.fitBelowFloats(); |
| 861 | 861 |
| 862 if (m_autoWrap || breakWords) { | 862 if (m_autoWrap || breakWords) { |
| 863 // If we break only after white-space, consider the current char
acter | 863 // If we break only after white-space, consider the current char
acter |
| 864 // as candidate width for this line. | 864 // as candidate width for this line. |
| 865 bool lineWasTooWide = false; | 865 bool lineWasTooWide = false; |
| 866 if (m_width.fitsOnLine() && m_currentCharacterIsSpace && m_curre
ntStyle->breakOnlyAfterWhiteSpace() && !midWordBreak) { | 866 if (m_width.fitsOnLine() && m_currentCharacterIsSpace && m_curre
ntStyle->breakOnlyAfterWhiteSpace() && !midWordBreak) { |
| 867 float charWidth = textWidth(renderText, m_current.m_pos, 1,
font, m_width.currentWidth(), isFixedPitch, m_collapseWhiteSpace, &wordMeasureme
nt.fallbackFonts, textLayout) + (applyWordSpacing ? wordSpacing : 0); | 867 float charWidth = textWidth(renderText, m_current.offset(),
1, font, m_width.currentWidth(), isFixedPitch, m_collapseWhiteSpace, &wordMeasur
ement.fallbackFonts, textLayout) + (applyWordSpacing ? wordSpacing : 0); |
| 868 // Check if line is too big even without the extra space | 868 // Check if line is too big even without the extra space |
| 869 // at the end of the line. If it is not, do nothing. | 869 // at the end of the line. If it is not, do nothing. |
| 870 // If the line needs the extra whitespace to be too long, | 870 // If the line needs the extra whitespace to be too long, |
| 871 // then move the line break to the space and skip all | 871 // then move the line break to the space and skip all |
| 872 // additional whitespace. | 872 // additional whitespace. |
| 873 if (!m_width.fitsOnLine(charWidth)) { | 873 if (!m_width.fitsOnLine(charWidth)) { |
| 874 lineWasTooWide = true; | 874 lineWasTooWide = true; |
| 875 m_lineBreak.moveTo(m_current.object(), m_current.m_pos,
m_current.nextBreakablePosition()); | 875 m_lineBreak.moveTo(m_current.object(), m_current.offset(
), m_current.nextBreakablePosition()); |
| 876 skipTrailingWhitespace(m_lineBreak, m_lineInfo); | 876 skipTrailingWhitespace(m_lineBreak, m_lineInfo); |
| 877 } | 877 } |
| 878 } | 878 } |
| 879 if (lineWasTooWide || !m_width.fitsOnLine()) { | 879 if (lineWasTooWide || !m_width.fitsOnLine()) { |
| 880 if (m_lineBreak.atTextParagraphSeparator()) { | 880 if (m_lineBreak.atTextParagraphSeparator()) { |
| 881 if (!stoppedIgnoringSpaces && m_current.m_pos > 0) | 881 if (!stoppedIgnoringSpaces && m_current.offset() > 0) |
| 882 ensureCharacterGetsLineBox(m_lineMidpointState, m_cu
rrent); | 882 ensureCharacterGetsLineBox(m_lineMidpointState, m_cu
rrent); |
| 883 m_lineBreak.increment(); | 883 m_lineBreak.increment(); |
| 884 m_lineInfo.setPreviousLineBrokeCleanly(true); | 884 m_lineInfo.setPreviousLineBrokeCleanly(true); |
| 885 wordMeasurement.endOffset = m_lineBreak.m_pos; | 885 wordMeasurement.endOffset = m_lineBreak.offset(); |
| 886 } | 886 } |
| 887 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) | 887 if (m_lineBreak.object() && m_lineBreak.offset() && m_lineBr
eak.object()->isText() && toRenderText(m_lineBreak.object())->textLength() && to
RenderText(m_lineBreak.object())->characterAt(m_lineBreak.offset() - 1) == softH
yphen) |
| 888 hyphenated = true; | 888 hyphenated = true; |
| 889 if (m_lineBreak.m_pos && m_lineBreak.m_pos != (unsigned)word
Measurement.endOffset && !wordMeasurement.width) { | 889 if (m_lineBreak.offset() && m_lineBreak.offset() != (unsigne
d)wordMeasurement.endOffset && !wordMeasurement.width) { |
| 890 if (charWidth) { | 890 if (charWidth) { |
| 891 wordMeasurement.endOffset = m_lineBreak.m_pos; | 891 wordMeasurement.endOffset = m_lineBreak.offset(); |
| 892 wordMeasurement.width = charWidth; | 892 wordMeasurement.width = charWidth; |
| 893 } | 893 } |
| 894 } | 894 } |
| 895 // Didn't fit. Jump to the end unless there's still an oppor
tunity to collapse whitespace. | 895 // Didn't fit. Jump to the end unless there's still an oppor
tunity to collapse whitespace. |
| 896 if (m_ignoringSpaces || !m_collapseWhiteSpace || !m_currentC
haracterIsSpace || !previousCharacterIsSpace) { | 896 if (m_ignoringSpaces || !m_collapseWhiteSpace || !m_currentC
haracterIsSpace || !previousCharacterIsSpace) { |
| 897 m_atEnd = true; | 897 m_atEnd = true; |
| 898 return false; | 898 return false; |
| 899 } | 899 } |
| 900 } else { | 900 } else { |
| 901 if (!betweenWords || (midWordBreak && !m_autoWrap)) | 901 if (!betweenWords || (midWordBreak && !m_autoWrap)) |
| 902 m_width.addUncommittedWidth(-additionalTmpW); | 902 m_width.addUncommittedWidth(-additionalTmpW); |
| 903 if (hyphenWidth) { | 903 if (hyphenWidth) { |
| 904 // Subtract the width of the soft hyphen out since we fi
t on a line. | 904 // Subtract the width of the soft hyphen out since we fi
t on a line. |
| 905 m_width.addUncommittedWidth(-hyphenWidth); | 905 m_width.addUncommittedWidth(-hyphenWidth); |
| 906 hyphenWidth = 0; | 906 hyphenWidth = 0; |
| 907 } | 907 } |
| 908 } | 908 } |
| 909 } | 909 } |
| 910 | 910 |
| 911 if (c == '\n' && m_preservesNewline) { | 911 if (c == '\n' && m_preservesNewline) { |
| 912 if (!stoppedIgnoringSpaces && m_current.m_pos > 0) | 912 if (!stoppedIgnoringSpaces && m_current.offset()) |
| 913 ensureCharacterGetsLineBox(m_lineMidpointState, m_current); | 913 ensureCharacterGetsLineBox(m_lineMidpointState, m_current); |
| 914 m_lineBreak.moveTo(m_current.object(), m_current.m_pos, m_curren
t.nextBreakablePosition()); | 914 m_lineBreak.moveTo(m_current.object(), m_current.offset(), m_cur
rent.nextBreakablePosition()); |
| 915 m_lineBreak.increment(); | 915 m_lineBreak.increment(); |
| 916 m_lineInfo.setPreviousLineBrokeCleanly(true); | 916 m_lineInfo.setPreviousLineBrokeCleanly(true); |
| 917 return true; | 917 return true; |
| 918 } | 918 } |
| 919 | 919 |
| 920 if (m_autoWrap && betweenWords) { | 920 if (m_autoWrap && betweenWords) { |
| 921 m_width.commit(); | 921 m_width.commit(); |
| 922 wrapW = 0; | 922 wrapW = 0; |
| 923 m_lineBreak.moveTo(m_current.object(), m_current.m_pos, m_curren
t.nextBreakablePosition()); | 923 m_lineBreak.moveTo(m_current.object(), m_current.offset(), m_cur
rent.nextBreakablePosition()); |
| 924 // Auto-wrapping text should not wrap in the middle of a word on
ce it has had an | 924 // Auto-wrapping text should not wrap in the middle of a word on
ce it has had an |
| 925 // opportunity to break after a word. | 925 // opportunity to break after a word. |
| 926 breakWords = false; | 926 breakWords = false; |
| 927 } | 927 } |
| 928 | 928 |
| 929 if (midWordBreak && !U16_IS_TRAIL(c) && !(category(c) & (Mark_NonSpa
cing | Mark_Enclosing | Mark_SpacingCombining))) { | 929 if (midWordBreak && !U16_IS_TRAIL(c) && !(category(c) & (Mark_NonSpa
cing | Mark_Enclosing | Mark_SpacingCombining))) { |
| 930 // Remember this as a breakable position in case | 930 // Remember this as a breakable position in case |
| 931 // adding the end width forces a break. | 931 // adding the end width forces a break. |
| 932 m_lineBreak.moveTo(m_current.object(), m_current.m_pos, m_curren
t.nextBreakablePosition()); | 932 m_lineBreak.moveTo(m_current.object(), m_current.offset(), m_cur
rent.nextBreakablePosition()); |
| 933 midWordBreak &= (breakWords || breakAll); | 933 midWordBreak &= (breakWords || breakAll); |
| 934 } | 934 } |
| 935 | 935 |
| 936 if (betweenWords) { | 936 if (betweenWords) { |
| 937 lastSpaceWordSpacing = applyWordSpacing ? wordSpacing : 0; | 937 lastSpaceWordSpacing = applyWordSpacing ? wordSpacing : 0; |
| 938 wordSpacingForWordMeasurement = (applyWordSpacing && wordMeasure
ment.width) ? wordSpacing : 0; | 938 wordSpacingForWordMeasurement = (applyWordSpacing && wordMeasure
ment.width) ? wordSpacing : 0; |
| 939 lastSpace = m_current.m_pos; | 939 lastSpace = m_current.offset(); |
| 940 } | 940 } |
| 941 | 941 |
| 942 if (!m_ignoringSpaces && m_currentStyle->collapseWhiteSpace()) { | 942 if (!m_ignoringSpaces && m_currentStyle->collapseWhiteSpace()) { |
| 943 // If we encounter a newline, or if we encounter a | 943 // If we encounter a newline, or if we encounter a |
| 944 // second space, we need to go ahead and break up this | 944 // second space, we need to go ahead and break up this |
| 945 // run and enter a mode where we start collapsing spaces. | 945 // run and enter a mode where we start collapsing spaces. |
| 946 if (m_currentCharacterIsSpace && previousCharacterIsSpace) { | 946 if (m_currentCharacterIsSpace && previousCharacterIsSpace) { |
| 947 m_ignoringSpaces = true; | 947 m_ignoringSpaces = true; |
| 948 | 948 |
| 949 // We just entered a mode where we are ignoring | 949 // We just entered a mode where we are ignoring |
| 950 // spaces. Create a midpoint to terminate the run | 950 // spaces. Create a midpoint to terminate the run |
| 951 // before the second space. | 951 // before the second space. |
| 952 startIgnoringSpaces(m_lineMidpointState, m_startOfIgnoredSpa
ces); | 952 startIgnoringSpaces(m_lineMidpointState, m_startOfIgnoredSpa
ces); |
| 953 m_trailingObjects.updateMidpointsForTrailingBoxes(m_lineMidp
ointState, InlineIterator(), TrailingObjects::DoNotCollapseFirstSpace); | 953 m_trailingObjects.updateMidpointsForTrailingBoxes(m_lineMidp
ointState, InlineIterator(), TrailingObjects::DoNotCollapseFirstSpace); |
| 954 } | 954 } |
| 955 } | 955 } |
| 956 } else if (m_ignoringSpaces) { | 956 } else if (m_ignoringSpaces) { |
| 957 // Stop ignoring spaces and begin at this | 957 // Stop ignoring spaces and begin at this |
| 958 // new point. | 958 // new point. |
| 959 m_ignoringSpaces = false; | 959 m_ignoringSpaces = false; |
| 960 lastSpaceWordSpacing = applyWordSpacing ? wordSpacing : 0; | 960 lastSpaceWordSpacing = applyWordSpacing ? wordSpacing : 0; |
| 961 wordSpacingForWordMeasurement = (applyWordSpacing && wordMeasurement
s.last().width) ? wordSpacing : 0; | 961 wordSpacingForWordMeasurement = (applyWordSpacing && wordMeasurement
s.last().width) ? wordSpacing : 0; |
| 962 lastSpace = m_current.m_pos; // e.g., "Foo goo", don't add in any
of the ignored spaces. | 962 lastSpace = m_current.offset(); // e.g., "Foo goo", don't add in
any of the ignored spaces. |
| 963 stopIgnoringSpaces(m_lineMidpointState, InlineIterator(0, m_current.
object(), m_current.m_pos)); | 963 stopIgnoringSpaces(m_lineMidpointState, InlineIterator(0, m_current.
object(), m_current.offset())); |
| 964 } | 964 } |
| 965 | 965 |
| 966 if (isSVGText && m_current.m_pos > 0) { | 966 if (isSVGText && m_current.offset()) { |
| 967 // Force creation of new InlineBoxes for each absolute positioned ch
aracter (those that start new text chunks). | 967 // Force creation of new InlineBoxes for each absolute positioned ch
aracter (those that start new text chunks). |
| 968 if (toRenderSVGInlineText(renderText)->characterStartsNewTextChunk(m
_current.m_pos)) | 968 if (toRenderSVGInlineText(renderText)->characterStartsNewTextChunk(m
_current.offset())) |
| 969 ensureCharacterGetsLineBox(m_lineMidpointState, m_current); | 969 ensureCharacterGetsLineBox(m_lineMidpointState, m_current); |
| 970 } | 970 } |
| 971 | 971 |
| 972 if (m_currentCharacterIsSpace && !previousCharacterIsSpace) { | 972 if (m_currentCharacterIsSpace && !previousCharacterIsSpace) { |
| 973 m_startOfIgnoredSpaces.setObject(m_current.object()); | 973 m_startOfIgnoredSpaces.setObject(m_current.object()); |
| 974 m_startOfIgnoredSpaces.m_pos = m_current.m_pos; | 974 m_startOfIgnoredSpaces.setOffset(m_current.offset()); |
| 975 } | 975 } |
| 976 | 976 |
| 977 if (!m_currentCharacterIsSpace && previousCharacterShouldCollapseIfPreWa
p) { | 977 if (!m_currentCharacterIsSpace && previousCharacterShouldCollapseIfPreWa
p) { |
| 978 if (m_autoWrap && m_currentStyle->breakOnlyAfterWhiteSpace()) | 978 if (m_autoWrap && m_currentStyle->breakOnlyAfterWhiteSpace()) |
| 979 m_lineBreak.moveTo(m_current.object(), m_current.m_pos, m_curren
t.nextBreakablePosition()); | 979 m_lineBreak.moveTo(m_current.object(), m_current.offset(), m_cur
rent.nextBreakablePosition()); |
| 980 } | 980 } |
| 981 | 981 |
| 982 if (m_collapseWhiteSpace && m_currentCharacterIsSpace && !m_ignoringSpac
es) | 982 if (m_collapseWhiteSpace && m_currentCharacterIsSpace && !m_ignoringSpac
es) |
| 983 m_trailingObjects.setTrailingWhitespace(toRenderText(m_current.objec
t())); | 983 m_trailingObjects.setTrailingWhitespace(toRenderText(m_current.objec
t())); |
| 984 else if (!m_currentStyle->collapseWhiteSpace() || !m_currentCharacterIsS
pace) | 984 else if (!m_currentStyle->collapseWhiteSpace() || !m_currentCharacterIsS
pace) |
| 985 m_trailingObjects.clear(); | 985 m_trailingObjects.clear(); |
| 986 | 986 |
| 987 m_atStart = false; | 987 m_atStart = false; |
| 988 nextCharacter(c, lastCharacter, secondToLastCharacter); | 988 nextCharacter(c, lastCharacter, secondToLastCharacter); |
| 989 } | 989 } |
| 990 | 990 |
| 991 m_renderTextInfo.m_lineBreakIterator.setPriorContext(lastCharacter, secondTo
LastCharacter); | 991 m_renderTextInfo.m_lineBreakIterator.setPriorContext(lastCharacter, secondTo
LastCharacter); |
| 992 | 992 |
| 993 wordMeasurements.grow(wordMeasurements.size() + 1); | 993 wordMeasurements.grow(wordMeasurements.size() + 1); |
| 994 WordMeasurement& wordMeasurement = wordMeasurements.last(); | 994 WordMeasurement& wordMeasurement = wordMeasurements.last(); |
| 995 wordMeasurement.renderer = renderText; | 995 wordMeasurement.renderer = renderText; |
| 996 | 996 |
| 997 // IMPORTANT: current.m_pos is > length here! | 997 // IMPORTANT: current.m_pos is > length here! |
| 998 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); | 998 float additionalTmpW = m_ignoringSpaces ? 0 : textWidth(renderText, lastSpac
e, m_current.offset() - lastSpace, font, m_width.currentWidth(), isFixedPitch, m
_collapseWhiteSpace, &wordMeasurement.fallbackFonts, textLayout); |
| 999 wordMeasurement.startOffset = lastSpace; | 999 wordMeasurement.startOffset = lastSpace; |
| 1000 wordMeasurement.endOffset = m_current.m_pos; | 1000 wordMeasurement.endOffset = m_current.offset(); |
| 1001 wordMeasurement.width = m_ignoringSpaces ? 0 : additionalTmpW + wordSpacingF
orWordMeasurement; | 1001 wordMeasurement.width = m_ignoringSpaces ? 0 : additionalTmpW + wordSpacingF
orWordMeasurement; |
| 1002 additionalTmpW += lastSpaceWordSpacing; | 1002 additionalTmpW += lastSpaceWordSpacing; |
| 1003 m_width.addUncommittedWidth(additionalTmpW + inlineLogicalWidth(m_current.ob
ject(), !m_appliedStartWidth, m_includeEndWidth)); | 1003 m_width.addUncommittedWidth(additionalTmpW + inlineLogicalWidth(m_current.ob
ject(), !m_appliedStartWidth, m_includeEndWidth)); |
| 1004 m_includeEndWidth = false; | 1004 m_includeEndWidth = false; |
| 1005 | 1005 |
| 1006 if (!m_width.fitsOnLine()) { | 1006 if (!m_width.fitsOnLine()) { |
| 1007 if (!hyphenated && m_lineBreak.previousInSameNode() == softHyphen) { | 1007 if (!hyphenated && m_lineBreak.previousInSameNode() == softHyphen) { |
| 1008 hyphenated = true; | 1008 hyphenated = true; |
| 1009 m_atEnd = true; | 1009 m_atEnd = true; |
| 1010 } | 1010 } |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1086 InlineIterator* midpoints = lineMidpointState.midpoints.data(); | 1086 InlineIterator* midpoints = lineMidpointState.midpoints.data(); |
| 1087 InlineIterator& endpoint = midpoints[lineMidpointState.numMidpoints - 2]
; | 1087 InlineIterator& endpoint = midpoints[lineMidpointState.numMidpoints - 2]
; |
| 1088 const InlineIterator& startpoint = midpoints[lineMidpointState.numMidpoi
nts - 1]; | 1088 const InlineIterator& startpoint = midpoints[lineMidpointState.numMidpoi
nts - 1]; |
| 1089 InlineIterator currpoint = endpoint; | 1089 InlineIterator currpoint = endpoint; |
| 1090 while (!currpoint.atEnd() && currpoint != startpoint && currpoint != lBr
eak) | 1090 while (!currpoint.atEnd() && currpoint != startpoint && currpoint != lBr
eak) |
| 1091 currpoint.increment(); | 1091 currpoint.increment(); |
| 1092 if (currpoint == lBreak) { | 1092 if (currpoint == lBreak) { |
| 1093 // We hit the line break before the start point. Shave off the start
point. | 1093 // We hit the line break before the start point. Shave off the start
point. |
| 1094 lineMidpointState.numMidpoints--; | 1094 lineMidpointState.numMidpoints--; |
| 1095 if (endpoint.object()->style()->collapseWhiteSpace() && endpoint.obj
ect()->isText()) | 1095 if (endpoint.object()->style()->collapseWhiteSpace() && endpoint.obj
ect()->isText()) |
| 1096 endpoint.m_pos--; | 1096 endpoint.setOffset(endpoint.offset() - 1); |
| 1097 } | 1097 } |
| 1098 } | 1098 } |
| 1099 } | 1099 } |
| 1100 | 1100 |
| 1101 InlineIterator BreakingContext::handleEndOfLine() | 1101 InlineIterator BreakingContext::handleEndOfLine() |
| 1102 { | 1102 { |
| 1103 ShapeInsideInfo* shapeInfo = m_block->layoutShapeInsideInfo(); | 1103 ShapeInsideInfo* shapeInfo = m_block->layoutShapeInsideInfo(); |
| 1104 bool segmentAllowsOverflow = !shapeInfo || !shapeInfo->hasSegments(); | 1104 bool segmentAllowsOverflow = !shapeInfo || !shapeInfo->hasSegments(); |
| 1105 | 1105 |
| 1106 if (m_lineBreak == m_resolver.position() && (!m_lineBreak.object() || !m_lin
eBreak.object()->isBR()) && segmentAllowsOverflow) { | 1106 if (m_lineBreak == m_resolver.position() && (!m_lineBreak.object() || !m_lin
eBreak.object()->isBR()) && segmentAllowsOverflow) { |
| 1107 // we just add as much as possible | 1107 // we just add as much as possible |
| 1108 if (m_blockStyle->whiteSpace() == PRE && !m_current.m_pos) { | 1108 if (m_blockStyle->whiteSpace() == PRE && !m_current.offset()) { |
| 1109 m_lineBreak.moveTo(m_lastObject, m_lastObject->isText() ? m_lastObje
ct->length() : 0); | 1109 m_lineBreak.moveTo(m_lastObject, m_lastObject->isText() ? m_lastObje
ct->length() : 0); |
| 1110 } else if (m_lineBreak.object()) { | 1110 } else if (m_lineBreak.object()) { |
| 1111 // Don't ever break in the middle of a word if we can help it. | 1111 // Don't ever break in the middle of a word if we can help it. |
| 1112 // There's no room at all. We just have to be on this line, | 1112 // There's no room at all. We just have to be on this line, |
| 1113 // even though we'll spill out. | 1113 // even though we'll spill out. |
| 1114 m_lineBreak.moveTo(m_current.object(), m_current.m_pos); | 1114 m_lineBreak.moveTo(m_current.object(), m_current.offset()); |
| 1115 } | 1115 } |
| 1116 } | 1116 } |
| 1117 | 1117 |
| 1118 // FIXME Bug 100049: We do not need to consume input in a multi-segment line | 1118 // FIXME Bug 100049: We do not need to consume input in a multi-segment line |
| 1119 // unless no segment will. | 1119 // unless no segment will. |
| 1120 // make sure we consume at least one char/object. | 1120 // make sure we consume at least one char/object. |
| 1121 if (m_lineBreak == m_resolver.position() && segmentAllowsOverflow) | 1121 if (m_lineBreak == m_resolver.position() && segmentAllowsOverflow) |
| 1122 m_lineBreak.increment(); | 1122 m_lineBreak.increment(); |
| 1123 | 1123 |
| 1124 // Sanity check our midpoints. | 1124 // Sanity check our midpoints. |
| 1125 checkMidpoints(m_lineMidpointState, m_lineBreak); | 1125 checkMidpoints(m_lineMidpointState, m_lineBreak); |
| 1126 | 1126 |
| 1127 m_trailingObjects.updateMidpointsForTrailingBoxes(m_lineMidpointState, m_lin
eBreak, TrailingObjects::CollapseFirstSpace); | 1127 m_trailingObjects.updateMidpointsForTrailingBoxes(m_lineMidpointState, m_lin
eBreak, TrailingObjects::CollapseFirstSpace); |
| 1128 | 1128 |
| 1129 // We might have made lineBreak an iterator that points past the end | 1129 // We might have made lineBreak an iterator that points past the end |
| 1130 // of the object. Do this adjustment to make it point to the start | 1130 // of the object. Do this adjustment to make it point to the start |
| 1131 // of the next object instead to avoid confusing the rest of the | 1131 // of the next object instead to avoid confusing the rest of the |
| 1132 // code. | 1132 // code. |
| 1133 if (m_lineBreak.m_pos > 0) { | 1133 if (m_lineBreak.offset()) { |
| 1134 // This loop enforces the invariant that line breaks should never point | 1134 // This loop enforces the invariant that line breaks should never point |
| 1135 // at an empty inline. See http://crbug.com/305904. | 1135 // at an empty inline. See http://crbug.com/305904. |
| 1136 do { | 1136 do { |
| 1137 m_lineBreak.m_pos--; | 1137 m_lineBreak.setOffset(m_lineBreak.offset() - 1); |
| 1138 m_lineBreak.increment(); | 1138 m_lineBreak.increment(); |
| 1139 } while (!m_lineBreak.atEnd() && isEmptyInline(m_lineBreak.object())); | 1139 } while (!m_lineBreak.atEnd() && isEmptyInline(m_lineBreak.object())); |
| 1140 } | 1140 } |
| 1141 | 1141 |
| 1142 return m_lineBreak; | 1142 return m_lineBreak; |
| 1143 } | 1143 } |
| 1144 | 1144 |
| 1145 } | 1145 } |
| 1146 | 1146 |
| 1147 #endif // BreakingContextInlineHeaders_h | 1147 #endif // BreakingContextInlineHeaders_h |
| OLD | NEW |