Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: third_party/WebKit/Source/core/layout/line/BreakingContextInlineHeaders.h

Issue 1504083002: Refactor BreakingContext::handleText (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
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_currentCharacterShouldCollapseIfPreWap(false) 75 , m_currentCharacterShouldCollapseIfPreWrap(false)
76 , m_appliedStartWidth(appliedStartWidth) 76 , m_appliedStartWidth(appliedStartWidth)
77 , m_includeEndWidth(true) 77 , m_includeEndWidth(true)
78 , m_autoWrap(false) 78 , m_autoWrap(false)
79 , m_autoWrapWasEverTrueOnLine(false) 79 , m_autoWrapWasEverTrueOnLine(false)
80 , m_floatsFitOnLine(true) 80 , m_floatsFitOnLine(true)
81 , m_collapseWhiteSpace(false) 81 , m_collapseWhiteSpace(false)
82 , m_startingNewParagraph(m_lineInfo.previousLineBrokeCleanly()) 82 , m_startingNewParagraph(m_lineInfo.previousLineBrokeCleanly())
83 , m_allowImagesToBreak(!block.document().inQuirksMode() || !block.isTabl eCell() || !m_blockStyle->logicalWidth().isIntrinsicOrAuto()) 83 , m_allowImagesToBreak(!block.document().inQuirksMode() || !block.isTabl eCell() || !m_blockStyle->logicalWidth().isIntrinsicOrAuto())
84 , m_atEnd(false) 84 , m_atEnd(false)
85 , m_lineMidpointState(resolver.midpointState()) 85 , m_lineMidpointState(resolver.midpointState())
86 { 86 {
87 m_lineInfo.setPreviousLineBrokeCleanly(false); 87 m_lineInfo.setPreviousLineBrokeCleanly(false);
88 } 88 }
89 89
90 LayoutObject* currentObject() { return m_current.object(); } 90 LayoutObject* currentObject() { return m_current.object(); }
91 InlineIterator lineBreak() { return m_lineBreak; } 91 InlineIterator lineBreak() { return m_lineBreak; }
92 bool atEnd() { return m_atEnd; } 92 bool atEnd() { return m_atEnd; }
93 93
94 void initializeForCurrentObject(); 94 void initializeForCurrentObject();
95 95
96 void increment(); 96 void increment();
97 97
98 void handleBR(EClear&); 98 void handleBR(EClear&);
99 void handleOutOfFlowPositioned(Vector<LineLayoutBox>& positionedObjects); 99 void handleOutOfFlowPositioned(Vector<LineLayoutBox>& positionedObjects);
100 void handleFloat(); 100 void handleFloat();
101 void handleEmptyInline(); 101 void handleEmptyInline();
102 void handleReplaced(); 102 void handleReplaced();
103 bool handleText(WordMeasurements&, bool& hyphenated); 103 bool handleText(WordMeasurements&, bool& hyphenated);
104 void prepareForNextCharacter(const LineLayoutText&, bool& prohibitBreakInsid e, bool previousCharacterIsSpace, bool previousCharacterShouldCollapseIfPreWap);
105 bool canBreakAtWhitespace(bool breakWords, WordMeasurement&, bool stoppedIgn oringSpaces, bool& hyphenated, float charWidth, float& hyphenWidth, bool between Words, bool midWordBreak, bool breakAll, bool previousCharacterIsSpace, float la stWidthMeasurement, const LineLayoutText&, const Font&, bool applyWordSpacing, f loat wordSpacing);
106 bool trailingSpaceExceedsAvailableWidth(bool midWordBreak, const LineLayoutT ext&, WordMeasurement&, bool applyWordSpacing, bool wordSpacing, const Font&);
107 WordMeasurement& calculateWordWidth(WordMeasurements&, LineLayoutText&, floa t lastSpace, float& lastWidthMeasurement, float wordSpacingForWordMeasurement, c onst Font&, float wordTrailingSpaceWidth, UChar);
108 void stopIgnoringSpaces(unsigned& lastSpace);
104 void commitAndUpdateLineBreakIfNeeded(); 109 void commitAndUpdateLineBreakIfNeeded();
105 InlineIterator handleEndOfLine(); 110 InlineIterator handleEndOfLine();
106 111
107 void clearLineBreakIfFitsOnLine() 112 void clearLineBreakIfFitsOnLine()
108 { 113 {
109 if (m_width.fitsOnLine() || m_lastWS == NOWRAP) 114 if (m_width.fitsOnLine() || m_lastWS == NOWRAP)
110 m_lineBreak.clear(); 115 m_lineBreak.clear();
111 } 116 }
112 117
113 private: 118 private:
(...skipping 20 matching lines...) Expand all
134 139
135 LineWidth m_width; 140 LineWidth m_width;
136 141
137 EWhiteSpace m_currWS; 142 EWhiteSpace m_currWS;
138 EWhiteSpace m_lastWS; 143 EWhiteSpace m_lastWS;
139 144
140 bool m_preservesNewline; 145 bool m_preservesNewline;
141 bool m_atStart; 146 bool m_atStart;
142 bool m_ignoringSpaces; 147 bool m_ignoringSpaces;
143 bool m_currentCharacterIsSpace; 148 bool m_currentCharacterIsSpace;
144 bool m_currentCharacterShouldCollapseIfPreWap; 149 bool m_currentCharacterShouldCollapseIfPreWrap;
145 bool m_appliedStartWidth; 150 bool m_appliedStartWidth;
146 bool m_includeEndWidth; 151 bool m_includeEndWidth;
147 bool m_autoWrap; 152 bool m_autoWrap;
148 bool m_autoWrapWasEverTrueOnLine; 153 bool m_autoWrapWasEverTrueOnLine;
149 bool m_floatsFitOnLine; 154 bool m_floatsFitOnLine;
150 bool m_collapseWhiteSpace; 155 bool m_collapseWhiteSpace;
151 bool m_startingNewParagraph; 156 bool m_startingNewParagraph;
152 bool m_allowImagesToBreak; 157 bool m_allowImagesToBreak;
153 bool m_atEnd; 158 bool m_atEnd;
154 159
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 m_lineInfo.setEmpty(false, m_block, &m_width); 447 m_lineInfo.setEmpty(false, m_block, &m_width);
443 if (m_ignoringSpaces) { 448 if (m_ignoringSpaces) {
444 // If we are in a run of ignored spaces then ensure we get a linebox if lineboxes are eventually 449 // If we are in a run of ignored spaces then ensure we get a linebox if lineboxes are eventually
445 // created for the line... 450 // created for the line...
446 m_trailingObjects.clear(); 451 m_trailingObjects.clear();
447 ensureLineBoxInsideIgnoredSpaces(&m_lineMidpointState, m_current.obj ect()); 452 ensureLineBoxInsideIgnoredSpaces(&m_lineMidpointState, m_current.obj ect());
448 } else if (m_blockStyle->collapseWhiteSpace() && m_resolver.position().o bject() == m_current.object() 453 } else if (m_blockStyle->collapseWhiteSpace() && m_resolver.position().o bject() == m_current.object()
449 && shouldSkipWhitespaceAfterStartObject(m_block, m_current.object(), m_lineMidpointState)) { 454 && shouldSkipWhitespaceAfterStartObject(m_block, m_current.object(), m_lineMidpointState)) {
450 // If this object is at the start of the line, we need to behave lik e list markers and 455 // If this object is at the start of the line, we need to behave lik e list markers and
451 // start ignoring spaces. 456 // start ignoring spaces.
452 m_currentCharacterShouldCollapseIfPreWap = m_currentCharacterIsSpace = true; 457 m_currentCharacterShouldCollapseIfPreWrap = m_currentCharacterIsSpac e = true;
453 m_ignoringSpaces = true; 458 m_ignoringSpaces = true;
454 } else { 459 } else {
455 // If we are after a trailing space but aren't ignoring spaces yet t hen ensure we get a linebox 460 // If we are after a trailing space but aren't ignoring spaces yet t hen ensure we get a linebox
456 // if we encounter collapsible whitepace. 461 // if we encounter collapsible whitepace.
457 m_trailingObjects.appendObjectIfNeeded(m_current.object()); 462 m_trailingObjects.appendObjectIfNeeded(m_current.object());
458 } 463 }
459 } 464 }
460 465
461 m_width.addUncommittedWidth((inlineLogicalWidthFromAncestorsIfNeeded(m_curre nt.object()) + borderPaddingMarginStart(flowBox) + borderPaddingMarginEnd(flowBo x)).toFloat()); 466 m_width.addUncommittedWidth((inlineLogicalWidthFromAncestorsIfNeeded(m_curre nt.object()) + borderPaddingMarginStart(flowBox) + borderPaddingMarginEnd(flowBo x)).toFloat());
462 } 467 }
(...skipping 11 matching lines...) Expand all
474 && (!m_current.object().isRubyRun() || toLayoutRubyRun(m_current.object( ))->canBreakBefore(m_layoutTextInfo.m_lineBreakIterator))) { 479 && (!m_current.object().isRubyRun() || toLayoutRubyRun(m_current.object( ))->canBreakBefore(m_layoutTextInfo.m_lineBreakIterator))) {
475 m_width.commit(); 480 m_width.commit();
476 m_lineBreak.moveToStartOf(m_current.object()); 481 m_lineBreak.moveToStartOf(m_current.object());
477 } 482 }
478 483
479 if (m_ignoringSpaces) 484 if (m_ignoringSpaces)
480 m_lineMidpointState.stopIgnoringSpaces(InlineIterator(0, m_current.objec t(), 0)); 485 m_lineMidpointState.stopIgnoringSpaces(InlineIterator(0, m_current.objec t(), 0));
481 486
482 m_lineInfo.setEmpty(false, m_block, &m_width); 487 m_lineInfo.setEmpty(false, m_block, &m_width);
483 m_ignoringSpaces = false; 488 m_ignoringSpaces = false;
484 m_currentCharacterShouldCollapseIfPreWap = m_currentCharacterIsSpace = false ; 489 m_currentCharacterShouldCollapseIfPreWrap = m_currentCharacterIsSpace = fals e;
485 m_trailingObjects.clear(); 490 m_trailingObjects.clear();
486 491
487 // Optimize for a common case. If we can't find whitespace after the list 492 // Optimize for a common case. If we can't find whitespace after the list
488 // item, then this is all moot. 493 // item, then this is all moot.
489 LayoutUnit replacedLogicalWidth = m_block.logicalWidthForChild(replacedBox) + m_block.marginStartForChild(replacedBox) + m_block.marginEndForChild(replacedB ox) + inlineLogicalWidthFromAncestorsIfNeeded(m_current.object()); 494 LayoutUnit replacedLogicalWidth = m_block.logicalWidthForChild(replacedBox) + m_block.marginStartForChild(replacedBox) + m_block.marginEndForChild(replacedB ox) + inlineLogicalWidthFromAncestorsIfNeeded(m_current.object());
490 if (m_current.object().isListMarker()) { 495 if (m_current.object().isListMarker()) {
491 if (m_blockStyle->collapseWhiteSpace() && shouldSkipWhitespaceAfterStart Object(m_block, m_current.object(), m_lineMidpointState)) { 496 if (m_blockStyle->collapseWhiteSpace() && shouldSkipWhitespaceAfterStart Object(m_block, m_current.object(), m_lineMidpointState)) {
492 // Like with inline flows, we start ignoring spaces to make sure tha t any 497 // Like with inline flows, we start ignoring spaces to make sure tha t any
493 // additional spaces we see will be discarded. 498 // additional spaces we see will be discarded.
494 m_currentCharacterShouldCollapseIfPreWap = m_currentCharacterIsSpace = true; 499 m_currentCharacterShouldCollapseIfPreWrap = m_currentCharacterIsSpac e = true;
495 m_ignoringSpaces = true; 500 m_ignoringSpaces = true;
496 } 501 }
497 if (LineLayoutListMarker(m_current.object()).isInside()) 502 if (LineLayoutListMarker(m_current.object()).isInside())
498 m_width.addUncommittedWidth(replacedLogicalWidth.toFloat()); 503 m_width.addUncommittedWidth(replacedLogicalWidth.toFloat());
499 } else { 504 } else {
500 m_width.addUncommittedWidth(replacedLogicalWidth.toFloat()); 505 m_width.addUncommittedWidth(replacedLogicalWidth.toFloat());
501 } 506 }
502 if (m_current.object().isRubyRun()) 507 if (m_current.object().isRubyRun())
503 m_width.applyOverhang(LineLayoutRubyRun(m_current.object()), m_lastObjec t, m_nextObject); 508 m_width.applyOverhang(LineLayoutRubyRun(m_current.object()), m_lastObjec t, m_nextObject);
504 // Update prior line break context characters, using U+FFFD (OBJECT REPLACEM ENT CHARACTER) for replaced element. 509 // Update prior line break context characters, using U+FFFD (OBJECT REPLACEM ENT CHARACTER) for replaced element.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 return font.width(run, fallbackFonts, glyphBounds); 543 return font.width(run, fallbackFonts, glyphBounds);
539 } 544 }
540 545
541 inline bool BreakingContext::handleText(WordMeasurements& wordMeasurements, bool & hyphenated) 546 inline bool BreakingContext::handleText(WordMeasurements& wordMeasurements, bool & hyphenated)
542 { 547 {
543 if (!m_current.offset()) 548 if (!m_current.offset())
544 m_appliedStartWidth = false; 549 m_appliedStartWidth = false;
545 550
546 LineLayoutText layoutText(m_current.object()); 551 LineLayoutText layoutText(m_current.object());
547 552
548 bool isSVGText = layoutText.isSVGInlineText();
549
550 // If we have left a no-wrap inline and entered an autowrap inline while ign oring spaces 553 // 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. 554 // 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) { 555 if (m_autoWrap && !ComputedStyle::autoWrap(m_lastWS) && m_ignoringSpaces) {
553 m_width.commit(); 556 m_width.commit();
554 m_lineBreak.moveToStartOf(m_current.object()); 557 m_lineBreak.moveToStartOf(m_current.object());
555 } 558 }
556 559
557 const ComputedStyle& style = layoutText.styleRef(m_lineInfo.isFirstLine()); 560 const ComputedStyle& style = layoutText.styleRef(m_lineInfo.isFirstLine());
558 const Font& font = style.font(); 561 const Font& font = style.font();
559 562
(...skipping 13 matching lines...) Expand all
573 bool prohibitBreakInside = m_currentStyle->hasTextCombine() && layoutText.is CombineText() && LineLayoutTextCombine(layoutText).isCombined(); 576 bool prohibitBreakInside = m_currentStyle->hasTextCombine() && layoutText.is CombineText() && LineLayoutTextCombine(layoutText).isCombined();
574 577
575 // This is currently only used for word-break: break-all, specifically for t he case 578 // This is currently only used for word-break: break-all, specifically for t he case
576 // where we have a break opportunity within a word, then a string of non-bre akable 579 // where we have a break opportunity within a word, then a string of non-bre akable
577 // content that ends up making our word wider than the current line. 580 // content that ends up making our word wider than the current line.
578 // See: fast/css3-text/css3-word-break/word-break-all-wrap-with-floats.html 581 // See: fast/css3-text/css3-word-break/word-break-all-wrap-with-floats.html
579 float widthMeasurementAtLastBreakOpportunity = 0; 582 float widthMeasurementAtLastBreakOpportunity = 0;
580 583
581 float hyphenWidth = 0; 584 float hyphenWidth = 0;
582 585
583 if (isSVGText) { 586 if (layoutText.isSVGInlineText()) {
584 breakWords = false; 587 breakWords = false;
585 breakAll = false; 588 breakAll = false;
586 keepAll = false; 589 keepAll = false;
587 } 590 }
588 591
589 if (layoutText.isWordBreak()) { 592 if (layoutText.isWordBreak()) {
590 m_width.commit(); 593 m_width.commit();
591 m_lineBreak.moveToStartOf(m_current.object()); 594 m_lineBreak.moveToStartOf(m_current.object());
592 ASSERT(m_current.offset() == layoutText.textLength()); 595 ASSERT(m_current.offset() == layoutText.textLength());
593 } 596 }
594 597
595 if (m_layoutTextInfo.m_text != layoutText) { 598 if (m_layoutTextInfo.m_text != layoutText) {
596 m_layoutTextInfo.m_text = layoutText; 599 m_layoutTextInfo.m_text = layoutText;
597 m_layoutTextInfo.m_font = &font; 600 m_layoutTextInfo.m_font = &font;
598 m_layoutTextInfo.m_lineBreakIterator.resetStringAndReleaseIterator(layou tText.text(), style.locale()); 601 m_layoutTextInfo.m_lineBreakIterator.resetStringAndReleaseIterator(layou tText.text(), style.locale());
599 } else if (m_layoutTextInfo.m_font != &font) { 602 } else if (m_layoutTextInfo.m_font != &font) {
600 m_layoutTextInfo.m_font = &font; 603 m_layoutTextInfo.m_font = &font;
601 } 604 }
602 605
603 // Non-zero only when kerning is enabled, in which case we measure 606 // Non-zero only when kerning is enabled, in which case we measure
604 // words with their trailing space, then subtract its width. 607 // words with their trailing space, then subtract its width.
605 float wordTrailingSpaceWidth = (font.fontDescription().typesettingFeatures() & Kerning) ? 608 float wordTrailingSpaceWidth = (font.fontDescription().typesettingFeatures() & Kerning) ?
606 font.width(constructTextRun(font, &spaceCharacter, 1, style, style.direc tion())) + wordSpacing 609 font.width(constructTextRun(font, &spaceCharacter, 1, style, style.direc tion())) + wordSpacing
607 : 0; 610 : 0;
608 611
609 UChar lastCharacter = m_layoutTextInfo.m_lineBreakIterator.lastCharacter(); 612 UChar lastCharacter = m_layoutTextInfo.m_lineBreakIterator.lastCharacter();
610 UChar secondToLastCharacter = m_layoutTextInfo.m_lineBreakIterator.secondToL astCharacter(); 613 UChar secondToLastCharacter = m_layoutTextInfo.m_lineBreakIterator.secondToL astCharacter();
611 for (; m_current.offset() < layoutText.textLength(); m_current.fastIncrement InTextNode()) { 614 for (; m_current.offset() < layoutText.textLength(); m_current.fastIncrement InTextNode()) {
612 bool previousCharacterIsSpace = m_currentCharacterIsSpace; 615 bool previousCharacterIsSpace = m_currentCharacterIsSpace;
613 bool previousCharacterShouldCollapseIfPreWap = m_currentCharacterShouldC ollapseIfPreWap; 616 bool previousCharacterShouldCollapseIfPreWap = m_currentCharacterShouldC ollapseIfPreWrap;
614 UChar c = m_current.current(); 617 UChar c = m_current.current();
615 m_currentCharacterShouldCollapseIfPreWap = m_currentCharacterIsSpace = c == spaceCharacter || c == tabulationCharacter || (!m_preservesNewline && (c == newlineCharacter)); 618 m_currentCharacterShouldCollapseIfPreWrap = m_currentCharacterIsSpace = c == spaceCharacter || c == tabulationCharacter || (!m_preservesNewline && (c == newlineCharacter));
616 619
617 if (!m_collapseWhiteSpace || !m_currentCharacterIsSpace) 620 if (!m_collapseWhiteSpace || !m_currentCharacterIsSpace)
618 m_lineInfo.setEmpty(false, m_block, &m_width); 621 m_lineInfo.setEmpty(false, m_block, &m_width);
619 622
620 if (c == softHyphenCharacter && m_autoWrap && !hyphenWidth) { 623 if (c == softHyphenCharacter && m_autoWrap && !hyphenWidth) {
621 hyphenWidth = layoutText.hyphenWidth(font, textDirectionFromUnicode( m_resolver.position().direction())); 624 hyphenWidth = layoutText.hyphenWidth(font, textDirectionFromUnicode( m_resolver.position().direction()));
622 m_width.addUncommittedWidth(hyphenWidth); 625 m_width.addUncommittedWidth(hyphenWidth);
623 } 626 }
624 627
625 bool applyWordSpacing = false; 628 bool applyWordSpacing = false;
626 629
630 // Determine if we should try breaking in the middle of a word.
627 if (breakWords && !midWordBreak) { 631 if (breakWords && !midWordBreak) {
628 widthFromLastBreakingOpportunity += charWidth; 632 widthFromLastBreakingOpportunity += charWidth;
629 bool midWordBreakIsBeforeSurrogatePair = U16_IS_LEAD(c) && m_current .offset() + 1 < layoutText.textLength() && U16_IS_TRAIL(layoutText.uncheckedChar acterAt(m_current.offset() + 1)); 633 bool midWordBreakIsBeforeSurrogatePair = U16_IS_LEAD(c) && m_current .offset() + 1 < layoutText.textLength() && U16_IS_TRAIL(layoutText.uncheckedChar acterAt(m_current.offset() + 1));
630 charWidth = textWidth(layoutText, m_current.offset(), midWordBreakIs BeforeSurrogatePair ? 2 : 1, font, m_width.committedWidth() + widthFromLastBreak ingOpportunity, m_collapseWhiteSpace); 634 charWidth = textWidth(layoutText, m_current.offset(), midWordBreakIs BeforeSurrogatePair ? 2 : 1, font, m_width.committedWidth() + widthFromLastBreak ingOpportunity, m_collapseWhiteSpace);
631 midWordBreak = m_width.committedWidth() + widthFromLastBreakingOppor tunity + charWidth > m_width.availableWidth(); 635 midWordBreak = m_width.committedWidth() + widthFromLastBreakingOppor tunity + charWidth > m_width.availableWidth();
632 } 636 }
633 637
638 // Determine if we are in the whitespace between words.
634 int nextBreakablePosition = m_current.nextBreakablePosition(); 639 int nextBreakablePosition = m_current.nextBreakablePosition();
635 bool betweenWords = c == newlineCharacter || (m_currWS != PRE && !m_atSt art && m_layoutTextInfo.m_lineBreakIterator.isBreakable(m_current.offset(), next BreakablePosition, breakAll ? LineBreakType::BreakAll : keepAll ? LineBreakType: :KeepAll : LineBreakType::Normal)); 640 bool betweenWords = c == newlineCharacter || (m_currWS != PRE && !m_atSt art && m_layoutTextInfo.m_lineBreakIterator.isBreakable(m_current.offset(), next BreakablePosition, breakAll ? LineBreakType::BreakAll : keepAll ? LineBreakType: :KeepAll : LineBreakType::Normal));
636 m_current.setNextBreakablePosition(nextBreakablePosition); 641 m_current.setNextBreakablePosition(nextBreakablePosition);
637 642
638 if (betweenWords || midWordBreak) { 643 // if we're in the middle of a word or at the start of a new one and can 't break there then continue to the next character.
639 bool stoppedIgnoringSpaces = false; 644 if (!betweenWords && !midWordBreak) {
640 if (m_ignoringSpaces) { 645 if (m_ignoringSpaces) {
641 lastSpaceWordSpacing = 0; 646 lastSpaceWordSpacing = applyWordSpacing ? wordSpacing : 0;
642 if (!m_currentCharacterIsSpace) { 647 wordSpacingForWordMeasurement = (applyWordSpacing && wordMeasure ments.last().width) ? wordSpacing : 0;
643 // Stop ignoring spaces and begin at this 648 stopIgnoringSpaces(lastSpace);
644 // new point.
645 m_ignoringSpaces = false;
646 wordSpacingForWordMeasurement = 0;
647 lastSpace = m_current.offset(); // e.g., "Foo goo", don't add in any of the ignored spaces.
648 m_lineMidpointState.stopIgnoringSpaces(InlineIterator(0, m_c urrent.object(), m_current.offset()));
649 stoppedIgnoringSpaces = true;
650 } else {
651 // Just keep ignoring these spaces.
652 nextCharacter(c, lastCharacter, secondToLastCharacter);
653 continue;
654 }
655 } 649 }
656 650 prepareForNextCharacter(layoutText, prohibitBreakInside, previousCha racterIsSpace, previousCharacterShouldCollapseIfPreWap);
657 wordMeasurements.grow(wordMeasurements.size() + 1); 651 m_atStart = false;
658 WordMeasurement& wordMeasurement = wordMeasurements.last(); 652 nextCharacter(c, lastCharacter, secondToLastCharacter);
659 653 continue;
660 wordMeasurement.layoutText = layoutText;
661 wordMeasurement.endOffset = m_current.offset();
662 wordMeasurement.startOffset = lastSpace;
663
664 float lastWidthMeasurement;
665 if (wordTrailingSpaceWidth && c == spaceCharacter)
666 lastWidthMeasurement = textWidth(layoutText, lastSpace, m_curren t.offset() + 1 - lastSpace, font, m_width.currentWidth(), m_collapseWhiteSpace, &wordMeasurement.fallbackFonts, &wordMeasurement.glyphBounds) - wordTrailingSpac eWidth;
667 else
668 lastWidthMeasurement = textWidth(layoutText, lastSpace, m_curren t.offset() - lastSpace, font, m_width.currentWidth(), m_collapseWhiteSpace, &wor dMeasurement.fallbackFonts, &wordMeasurement.glyphBounds);
669
670 wordMeasurement.width = lastWidthMeasurement + wordSpacingForWordMea surement;
671 wordMeasurement.glyphBounds.move(wordSpacingForWordMeasurement, 0);
672 lastWidthMeasurement += lastSpaceWordSpacing;
673 m_width.addUncommittedWidth(lastWidthMeasurement);
674
675 if (m_collapseWhiteSpace && previousCharacterIsSpace && m_currentCha racterIsSpace && lastWidthMeasurement)
676 m_width.setTrailingWhitespaceWidth(lastWidthMeasurement);
677
678 if (!m_appliedStartWidth) {
679 m_width.addUncommittedWidth(inlineLogicalWidthFromAncestorsIfNee ded(m_current.object(), true, false).toFloat());
680 m_appliedStartWidth = true;
681 }
682
683 applyWordSpacing = wordSpacing && m_currentCharacterIsSpace;
684
685 if (!m_width.committedWidth() && m_autoWrap && !m_width.fitsOnLine() && !widthMeasurementAtLastBreakOpportunity)
686 m_width.fitBelowFloats(m_lineInfo.isFirstLine());
687
688 if (m_autoWrap || breakWords) {
689 // If we break only after white-space, consider the current char acter
690 // as candidate width for this line.
691 bool lineWasTooWide = false;
692 if (m_width.fitsOnLine() && m_currentCharacterIsSpace && m_curre ntStyle->breakOnlyAfterWhiteSpace() && !midWordBreak) {
693 float charWidth = textWidth(layoutText, m_current.offset(), 1, font, m_width.currentWidth(), m_collapseWhiteSpace, &wordMeasurement.fallback Fonts, &wordMeasurement.glyphBounds) + (applyWordSpacing ? wordSpacing : 0);
694 // Check if line is too big even without the extra space
695 // at the end of the line. If it is not, do nothing.
696 // If the line needs the extra whitespace to be too long,
697 // then move the line break to the space and skip all
698 // additional whitespace.
699 if (!m_width.fitsOnLine(charWidth)) {
700 lineWasTooWide = true;
701 m_lineBreak.moveTo(m_current.object(), m_current.offset( ), m_current.nextBreakablePosition());
702 skipTrailingWhitespace(m_lineBreak, m_lineInfo);
703 }
704 }
705 if (lineWasTooWide || !m_width.fitsOnLine()) {
706 if (m_lineBreak.atTextParagraphSeparator()) {
707 if (!stoppedIgnoringSpaces && m_current.offset() > 0)
708 m_lineMidpointState.ensureCharacterGetsLineBox(m_cur rent);
709 m_lineBreak.increment();
710 m_lineInfo.setPreviousLineBrokeCleanly(true);
711 wordMeasurement.endOffset = m_lineBreak.offset();
712 }
713 if (m_lineBreak.object() && m_lineBreak.offset() && m_lineBr eak.object().isText() && LineLayoutText(m_lineBreak.object()).textLength() && Li neLayoutText(m_lineBreak.object()).characterAt(m_lineBreak.offset() - 1) == soft HyphenCharacter)
714 hyphenated = true;
715 if (m_lineBreak.offset() && m_lineBreak.offset() != (unsigne d)wordMeasurement.endOffset && !wordMeasurement.width) {
716 if (charWidth) {
717 wordMeasurement.endOffset = m_lineBreak.offset();
718 wordMeasurement.width = charWidth;
719 }
720 }
721 // Didn't fit. Jump to the end unless there's still an oppor tunity to collapse whitespace.
722 if (m_ignoringSpaces || !m_collapseWhiteSpace || !m_currentC haracterIsSpace || !previousCharacterIsSpace) {
723 m_atEnd = true;
724 return false;
725 }
726 } else {
727 if (!betweenWords || (midWordBreak && !m_autoWrap) || (break All && !m_currentCharacterIsSpace))
728 m_width.addUncommittedWidth(-lastWidthMeasurement);
729 if (hyphenWidth) {
730 // Subtract the width of the soft hyphen out since we fi t on a line.
731 m_width.addUncommittedWidth(-hyphenWidth);
732 hyphenWidth = 0;
733 }
734 }
735 }
736
737 if (c == newlineCharacter && m_preservesNewline) {
738 if (!stoppedIgnoringSpaces && m_current.offset())
739 m_lineMidpointState.ensureCharacterGetsLineBox(m_current);
740 m_lineBreak.moveTo(m_current.object(), m_current.offset(), m_cur rent.nextBreakablePosition());
741 m_lineBreak.increment();
742 m_lineInfo.setPreviousLineBrokeCleanly(true);
743 return true;
744 }
745
746 if (m_autoWrap && betweenWords) {
747 m_width.commit();
748 widthFromLastBreakingOpportunity = 0;
749 m_lineBreak.moveTo(m_current.object(), m_current.offset(), m_cur rent.nextBreakablePosition());
750 // Auto-wrapping text should not wrap in the middle of a word on ce it has had an
751 // opportunity to break after a word.
752 breakWords = false;
753 widthMeasurementAtLastBreakOpportunity = lastWidthMeasurement;
754 }
755
756 if (midWordBreak && !U16_IS_TRAIL(c) && !(WTF::Unicode::category(c) & (WTF::Unicode::Mark_NonSpacing | WTF::Unicode::Mark_Enclosing | WTF::Unicode:: Mark_SpacingCombining))) {
757 // Remember this as a breakable position in case
758 // adding the end width forces a break.
759 m_lineBreak.moveTo(m_current.object(), m_current.offset(), m_cur rent.nextBreakablePosition());
760 midWordBreak &= (breakWords || breakAll);
761 }
762
763 if (betweenWords) {
764 lastSpaceWordSpacing = applyWordSpacing ? wordSpacing : 0;
765 wordSpacingForWordMeasurement = (applyWordSpacing && wordMeasure ment.width) ? wordSpacing : 0;
766 lastSpace = !breakAll || m_currentCharacterIsSpace ? m_current.o ffset() : lastSpace;
767 }
768
769 if (!m_ignoringSpaces && m_currentStyle->collapseWhiteSpace()) {
770 // If we encounter a newline, or if we encounter a
771 // second space, we need to go ahead and break up this
772 // run and enter a mode where we start collapsing spaces.
773 if (m_currentCharacterIsSpace && previousCharacterIsSpace) {
774 m_ignoringSpaces = true;
775
776 // We just entered a mode where we are ignoring
777 // spaces. Create a midpoint to terminate the run
778 // before the second space.
779 m_lineMidpointState.startIgnoringSpaces(m_startOfIgnoredSpac es);
780 m_trailingObjects.updateMidpointsForTrailingObjects(m_lineMi dpointState, InlineIterator(), TrailingObjects::DoNotCollapseFirstSpace);
781 }
782 }
783 } else if (m_ignoringSpaces) {
784 // Stop ignoring spaces and begin at this
785 // new point.
786 m_ignoringSpaces = false;
787 lastSpaceWordSpacing = applyWordSpacing ? wordSpacing : 0;
788 wordSpacingForWordMeasurement = (applyWordSpacing && wordMeasurement s.last().width) ? wordSpacing : 0;
789 lastSpace = m_current.offset(); // e.g., "Foo goo", don't add in any of the ignored spaces.
790 m_lineMidpointState.stopIgnoringSpaces(InlineIterator(0, m_current.o bject(), m_current.offset()));
791 } 654 }
792 655
793 if (isSVGText && m_current.offset()) { 656 // If we're ignoring space and we're at a collapsible space such as a sp ace or tab, continue to the next character.
794 // Force creation of new InlineBoxes for each absolute positioned ch aracter (those that start new text chunks). 657 bool stoppedIgnoringSpaces = false;
795 if (LineLayoutSVGInlineText(layoutText).characterStartsNewTextChunk( m_current.offset())) 658 if (m_ignoringSpaces && m_currentCharacterIsSpace) {
796 m_lineMidpointState.ensureCharacterGetsLineBox(m_current); 659 lastSpaceWordSpacing = 0;
660 // Just keep ignoring these spaces.
661 nextCharacter(c, lastCharacter, secondToLastCharacter);
662 continue;
797 } 663 }
798 664
799 if (prohibitBreakInside) { 665 // So we're in the first whitespace after a word or in whitespace that w e don't collapse, which means we may have a breaking opportunity here.
800 m_current.setNextBreakablePosition(layoutText.textLength()); 666
801 prohibitBreakInside = false; 667 // If we're here and we're ignoring spaces then the current character is n't a space, it's some of other form of whitespace. Stop ignoring spaces.
668 if (m_ignoringSpaces) {
669 lastSpaceWordSpacing = 0;
670 wordSpacingForWordMeasurement = 0;
671 stoppedIgnoringSpaces = true;
672 stopIgnoringSpaces(lastSpace);
802 } 673 }
803 674
804 if (m_currentCharacterIsSpace && !previousCharacterIsSpace) { 675 // Update our tally of the width since the last breakable position with the width of the word we're now at the end of.
805 m_startOfIgnoredSpaces.setObject(m_current.object()); 676 float lastWidthMeasurement;
806 m_startOfIgnoredSpaces.setOffset(m_current.offset()); 677 WordMeasurement& wordMeasurement = calculateWordWidth(wordMeasurements, layoutText, lastSpace, lastWidthMeasurement, wordSpacingForWordMeasurement, font , wordTrailingSpaceWidth, c);
678 lastWidthMeasurement += lastSpaceWordSpacing;
679 m_width.addUncommittedWidth(lastWidthMeasurement);
680
681 // We keep track of the total width contributed by trailing space as we often want to exclude it when determining
682 // if a run fits on a line.
683 if (m_collapseWhiteSpace && previousCharacterIsSpace && m_currentCharact erIsSpace && lastWidthMeasurement)
684 m_width.setTrailingWhitespaceWidth(lastWidthMeasurement);
685
686 // If this is the end of the first word in run of text then make sure we apply the width from any leading inlines.
687 // For example: '<span style="margin-left: 5px;"><span style="margin-lef t: 10px;">FirstWord</span></span>' would
688 // apply a width of 15px from the two span ancestors.
689 if (!m_appliedStartWidth) {
690 m_width.addUncommittedWidth(inlineLogicalWidthFromAncestorsIfNeeded( m_current.object(), true, false).toFloat());
691 m_appliedStartWidth = true;
807 } 692 }
808 693
809 if (!m_currentCharacterIsSpace && previousCharacterShouldCollapseIfPreWa p) { 694 // If we haven't hit a breakable position yet and already don't fit on t he line try to move below any floats.
810 if (m_autoWrap && m_currentStyle->breakOnlyAfterWhiteSpace()) 695 if (!m_width.committedWidth() && m_autoWrap && !m_width.fitsOnLine() && !widthMeasurementAtLastBreakOpportunity)
811 m_lineBreak.moveTo(m_current.object(), m_current.offset(), m_cur rent.nextBreakablePosition()); 696 m_width.fitBelowFloats(m_lineInfo.isFirstLine());
697
698 // If there is a soft-break available at this whitespace position then t ake it.
699 applyWordSpacing = wordSpacing && m_currentCharacterIsSpace;
700 if (canBreakAtWhitespace(breakWords, wordMeasurement, stoppedIgnoringSpa ces, hyphenated, charWidth, hyphenWidth, betweenWords, midWordBreak, breakAll, p reviousCharacterIsSpace, lastWidthMeasurement, layoutText, font, applyWordSpacin g, wordSpacing))
701 return false;
702
703 // If there is a hard-break available at this whitespace position then t ake it.
704 if (c == newlineCharacter && m_preservesNewline) {
705 if (!stoppedIgnoringSpaces && m_current.offset())
706 m_lineMidpointState.ensureCharacterGetsLineBox(m_current);
707 m_lineBreak.moveTo(m_current.object(), m_current.offset(), m_current .nextBreakablePosition());
708 m_lineBreak.increment();
709 m_lineInfo.setPreviousLineBrokeCleanly(true);
710 return true;
812 } 711 }
813 712
814 if (m_collapseWhiteSpace && m_currentCharacterIsSpace && !m_ignoringSpac es) 713 // Auto-wrapping text should not wrap in the middle of a word once it ha s had an
815 m_trailingObjects.setTrailingWhitespace(LineLayoutText(m_current.obj ect())); 714 // opportunity to break after a word.
816 else if (!m_currentStyle->collapseWhiteSpace() || !m_currentCharacterIsS pace) 715 if (m_autoWrap && betweenWords) {
817 m_trailingObjects.clear(); 716 m_width.commit();
717 widthFromLastBreakingOpportunity = 0;
718 m_lineBreak.moveTo(m_current.object(), m_current.offset(), m_current .nextBreakablePosition());
719 breakWords = false;
720 widthMeasurementAtLastBreakOpportunity = lastWidthMeasurement;
721 }
818 722
723 // Remember this as a breakable position in case adding the end width fo rces a break.
724 if (midWordBreak && !U16_IS_TRAIL(c) && !(WTF::Unicode::category(c) & (W TF::Unicode::Mark_NonSpacing | WTF::Unicode::Mark_Enclosing | WTF::Unicode::Mark _SpacingCombining))) {
725 m_lineBreak.moveTo(m_current.object(), m_current.offset(), m_current .nextBreakablePosition());
726 midWordBreak &= (breakWords || breakAll);
727 }
728
729 if (betweenWords) {
730 lastSpaceWordSpacing = applyWordSpacing ? wordSpacing : 0;
731 wordSpacingForWordMeasurement = (applyWordSpacing && wordMeasurement .width) ? wordSpacing : 0;
732 lastSpace = !breakAll || m_currentCharacterIsSpace ? m_current.offse t() : lastSpace;
733 }
734
735 // If we encounter a newline, or if we encounter a second space, we need to go ahead and break up this run and enter a mode where we start collapsing sp aces.
736 if (!m_ignoringSpaces && m_currentStyle->collapseWhiteSpace()) {
737 if (m_currentCharacterIsSpace && previousCharacterIsSpace) {
738 m_ignoringSpaces = true;
739 // We just entered a mode where we are ignoring spaces. Create a midpoint to terminate the run before the second space.
kojii 2015/12/08 08:02:10 nit: two spaces between "run" and "before".
740 m_lineMidpointState.startIgnoringSpaces(m_startOfIgnoredSpaces);
741 m_trailingObjects.updateMidpointsForTrailingObjects(m_lineMidpoi ntState, InlineIterator(), TrailingObjects::DoNotCollapseFirstSpace);
742 }
743 }
744
745 prepareForNextCharacter(layoutText, prohibitBreakInside, previousCharact erIsSpace, previousCharacterShouldCollapseIfPreWap);
819 m_atStart = false; 746 m_atStart = false;
820 nextCharacter(c, lastCharacter, secondToLastCharacter); 747 nextCharacter(c, lastCharacter, secondToLastCharacter);
821 } 748 }
822 749
823 m_layoutTextInfo.m_lineBreakIterator.setPriorContext(lastCharacter, secondTo LastCharacter); 750 m_layoutTextInfo.m_lineBreakIterator.setPriorContext(lastCharacter, secondTo LastCharacter);
824 751
825 wordMeasurements.grow(wordMeasurements.size() + 1); 752 wordMeasurements.grow(wordMeasurements.size() + 1);
826 WordMeasurement& wordMeasurement = wordMeasurements.last(); 753 WordMeasurement& wordMeasurement = wordMeasurements.last();
827 wordMeasurement.layoutText = layoutText; 754 wordMeasurement.layoutText = layoutText;
828 755
(...skipping 23 matching lines...) Expand all
852 return true; 779 return true;
853 } 780 }
854 if (!hyphenated && m_lineBreak.previousInSameNode() == softHyphenCharact er) { 781 if (!hyphenated && m_lineBreak.previousInSameNode() == softHyphenCharact er) {
855 hyphenated = true; 782 hyphenated = true;
856 m_atEnd = true; 783 m_atEnd = true;
857 } 784 }
858 } 785 }
859 return false; 786 return false;
860 } 787 }
861 788
789 inline void BreakingContext::stopIgnoringSpaces(unsigned& lastSpace)
790 {
791 m_ignoringSpaces = false;
792 lastSpace = m_current.offset(); // e.g., "Foo goo", don't add in any of t he ignored spaces.
793 m_lineMidpointState.stopIgnoringSpaces(InlineIterator(0, m_current.object(), m_current.offset()));
794 }
795
796 inline WordMeasurement& BreakingContext::calculateWordWidth(WordMeasurements& wo rdMeasurements, LineLayoutText& layoutText, float lastSpace, float& lastWidthMea surement, float wordSpacingForWordMeasurement, const Font& font, float wordTrail ingSpaceWidth, UChar c)
kojii 2015/12/08 08:02:10 Shouldn't lastSpace be unsigned rather than float?
797 {
798 wordMeasurements.grow(wordMeasurements.size() + 1);
799 WordMeasurement& wordMeasurement = wordMeasurements.last();
800 wordMeasurement.layoutText = layoutText;
801 wordMeasurement.endOffset = m_current.offset();
802 wordMeasurement.startOffset = lastSpace;
803
804 if (wordTrailingSpaceWidth && c == spaceCharacter)
805 lastWidthMeasurement = textWidth(layoutText, lastSpace, m_current.offset () + 1 - lastSpace, font, m_width.currentWidth(), m_collapseWhiteSpace, &wordMea surement.fallbackFonts, &wordMeasurement.glyphBounds) - wordTrailingSpaceWidth;
806 else
807 lastWidthMeasurement = textWidth(layoutText, lastSpace, m_current.offset () - lastSpace, font, m_width.currentWidth(), m_collapseWhiteSpace, &wordMeasure ment.fallbackFonts, &wordMeasurement.glyphBounds);
808
809 wordMeasurement.width = lastWidthMeasurement + wordSpacingForWordMeasurement ;
810 wordMeasurement.glyphBounds.move(wordSpacingForWordMeasurement, 0);
811 return wordMeasurement;
812 }
813
814 inline bool BreakingContext::trailingSpaceExceedsAvailableWidth(bool midWordBrea k, const LineLayoutText& layoutText, WordMeasurement& wordMeasurement, bool appl yWordSpacing, bool wordSpacing, const Font& font)
815 {
816 // If we break only after white-space, consider the current character
817 // as candidate width for this line.
818 if (m_width.fitsOnLine() && m_currentCharacterIsSpace && m_currentStyle->bre akOnlyAfterWhiteSpace() && !midWordBreak) {
819 float charWidth = textWidth(layoutText, m_current.offset(), 1, font, m_w idth.currentWidth(), m_collapseWhiteSpace, &wordMeasurement.fallbackFonts, &word Measurement.glyphBounds) + (applyWordSpacing ? wordSpacing : 0);
820 // Check if line is too big even without the extra space
821 // at the end of the line. If it is not, do nothing.
822 // If the line needs the extra whitespace to be too long,
823 // then move the line break to the space and skip all
824 // additional whitespace.
825 if (!m_width.fitsOnLine(charWidth)) {
826 m_lineBreak.moveTo(m_current.object(), m_current.offset(), m_current .nextBreakablePosition());
827 skipTrailingWhitespace(m_lineBreak, m_lineInfo);
828 return true;
829 }
830 }
831 return false;
832 }
833
834 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)
835 {
836 if (!m_autoWrap && !breakWords)
837 return false;
838
839 // If we break only after white-space, consider the current character
840 // as candidate width for this line.
841 if (trailingSpaceExceedsAvailableWidth(midWordBreak, layoutText, wordMeasure ment, applyWordSpacing, wordSpacing, font) || !m_width.fitsOnLine()) {
842 if (m_lineBreak.atTextParagraphSeparator()) {
843 if (!stoppedIgnoringSpaces && m_current.offset() > 0)
844 m_lineMidpointState.ensureCharacterGetsLineBox(m_current);
845 m_lineBreak.increment();
846 m_lineInfo.setPreviousLineBrokeCleanly(true);
847 wordMeasurement.endOffset = m_lineBreak.offset();
848 }
849 if (m_lineBreak.object() && m_lineBreak.offset() && m_lineBreak.object() .isText() && LineLayoutText(m_lineBreak.object()).textLength() && LineLayoutText (m_lineBreak.object()).characterAt(m_lineBreak.offset() - 1) == softHyphenCharac ter)
850 hyphenated = true;
851 if (m_lineBreak.offset() && m_lineBreak.offset() != (unsigned)wordMeasur ement.endOffset && !wordMeasurement.width) {
852 if (charWidth) {
853 wordMeasurement.endOffset = m_lineBreak.offset();
854 wordMeasurement.width = charWidth;
855 }
856 }
857 // Didn't fit. Jump to the end unless there's still an opportunity to co llapse whitespace.
858 if (m_ignoringSpaces || !m_collapseWhiteSpace || !m_currentCharacterIsSp ace || !previousCharacterIsSpace) {
859 m_atEnd = true;
860 return true;
861 }
862 } else {
863 if (!betweenWords || (midWordBreak && !m_autoWrap) || (breakAll && !m_cu rrentCharacterIsSpace))
864 m_width.addUncommittedWidth(-lastWidthMeasurement);
865 if (hyphenWidth) {
866 // Subtract the width of the soft hyphen out since we fit on a line.
867 m_width.addUncommittedWidth(-hyphenWidth);
868 hyphenWidth = 0;
869 }
870 }
871 return false;
872 }
873
874 inline void BreakingContext::prepareForNextCharacter(const LineLayoutText& layou tText, bool& prohibitBreakInside, bool previousCharacterIsSpace, bool previousCh aracterShouldCollapseIfPreWap)
875 {
876 if (layoutText.isSVGInlineText() && m_current.offset()) {
877 // Force creation of new InlineBoxes for each absolute positioned charac ter (those that start new text chunks).
878 if (LineLayoutSVGInlineText(layoutText).characterStartsNewTextChunk(m_cu rrent.offset()))
879 m_lineMidpointState.ensureCharacterGetsLineBox(m_current);
880 }
881
882 if (prohibitBreakInside) {
883 m_current.setNextBreakablePosition(layoutText.textLength());
884 prohibitBreakInside = false;
885 }
886
887 if (m_currentCharacterIsSpace && !previousCharacterIsSpace) {
888 m_startOfIgnoredSpaces.setObject(m_current.object());
889 m_startOfIgnoredSpaces.setOffset(m_current.offset());
890 }
891
892 if (!m_currentCharacterIsSpace && previousCharacterShouldCollapseIfPreWap) {
893 if (m_autoWrap && m_currentStyle->breakOnlyAfterWhiteSpace())
894 m_lineBreak.moveTo(m_current.object(), m_current.offset(), m_current .nextBreakablePosition());
895 }
896
897 if (m_collapseWhiteSpace && m_currentCharacterIsSpace && !m_ignoringSpaces)
898 m_trailingObjects.setTrailingWhitespace(LineLayoutText(m_current.object( )));
899 else if (!m_currentStyle->collapseWhiteSpace() || !m_currentCharacterIsSpace )
900 m_trailingObjects.clear();
901 }
902
862 inline void BreakingContext::commitAndUpdateLineBreakIfNeeded() 903 inline void BreakingContext::commitAndUpdateLineBreakIfNeeded()
863 { 904 {
864 bool checkForBreak = m_autoWrap; 905 bool checkForBreak = m_autoWrap;
865 if (m_width.committedWidth() && !m_width.fitsOnLine() && m_lineBreak.object( ) && m_currWS == NOWRAP) { 906 if (m_width.committedWidth() && !m_width.fitsOnLine() && m_lineBreak.object( ) && m_currWS == NOWRAP) {
866 checkForBreak = true; 907 checkForBreak = true;
867 } else if (m_nextObject && m_current.object().isText() && m_nextObject.isTex t() && !m_nextObject.isBR() && (m_autoWrap || m_nextObject.style()->autoWrap())) { 908 } else if (m_nextObject && m_current.object().isText() && m_nextObject.isTex t() && !m_nextObject.isBR() && (m_autoWrap || m_nextObject.style()->autoWrap())) {
868 if (m_autoWrap && m_currentCharacterIsSpace) { 909 if (m_autoWrap && m_currentCharacterIsSpace) {
869 checkForBreak = true; 910 checkForBreak = true;
870 } else { 911 } else {
871 LineLayoutText nextText(m_nextObject); 912 LineLayoutText nextText(m_nextObject);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
934 975
935 if (style.textIndentType() == TextIndentHanging) 976 if (style.textIndentType() == TextIndentHanging)
936 shouldIndentText = shouldIndentText == IndentText ? DoNotIndentText : In dentText; 977 shouldIndentText = shouldIndentText == IndentText ? DoNotIndentText : In dentText;
937 978
938 return shouldIndentText; 979 return shouldIndentText;
939 } 980 }
940 981
941 } 982 }
942 983
943 #endif // BreakingContextInlineHeaders_h 984 #endif // BreakingContextInlineHeaders_h
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698