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

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

Issue 1538453002: Refactor and comment 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 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
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);
104 void commitAndUpdateLineBreakIfNeeded(); 105 void commitAndUpdateLineBreakIfNeeded();
105 InlineIterator handleEndOfLine(); 106 InlineIterator handleEndOfLine();
106 107
107 void clearLineBreakIfFitsOnLine() 108 void clearLineBreakIfFitsOnLine()
108 { 109 {
109 if (m_width.fitsOnLine() || m_lastWS == NOWRAP) 110 if (m_width.fitsOnLine() || m_lastWS == NOWRAP)
110 m_lineBreak.clear(); 111 m_lineBreak.clear();
111 } 112 }
112 113
113 private: 114 private:
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 return font.width(run, fallbackFonts, glyphBounds); 539 return font.width(run, fallbackFonts, glyphBounds);
539 } 540 }
540 541
541 inline bool BreakingContext::handleText(WordMeasurements& wordMeasurements, bool & hyphenated) 542 inline bool BreakingContext::handleText(WordMeasurements& wordMeasurements, bool & hyphenated)
542 { 543 {
543 if (!m_current.offset()) 544 if (!m_current.offset())
544 m_appliedStartWidth = false; 545 m_appliedStartWidth = false;
545 546
546 LineLayoutText layoutText(m_current.object()); 547 LineLayoutText layoutText(m_current.object());
547 548
548 bool isSVGText = layoutText.isSVGInlineText();
549
550 // If we have left a no-wrap inline and entered an autowrap inline while ign oring spaces 549 // 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. 550 // 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) { 551 if (m_autoWrap && !ComputedStyle::autoWrap(m_lastWS) && m_ignoringSpaces) {
553 m_width.commit(); 552 m_width.commit();
554 m_lineBreak.moveToStartOf(m_current.object()); 553 m_lineBreak.moveToStartOf(m_current.object());
555 } 554 }
556 555
557 const ComputedStyle& style = layoutText.styleRef(m_lineInfo.isFirstLine()); 556 const ComputedStyle& style = layoutText.styleRef(m_lineInfo.isFirstLine());
558 const Font& font = style.font(); 557 const Font& font = style.font();
559 558
(...skipping 13 matching lines...) Expand all
573 bool prohibitBreakInside = m_currentStyle->hasTextCombine() && layoutText.is CombineText() && LineLayoutTextCombine(layoutText).isCombined(); 572 bool prohibitBreakInside = m_currentStyle->hasTextCombine() && layoutText.is CombineText() && LineLayoutTextCombine(layoutText).isCombined();
574 573
575 // This is currently only used for word-break: break-all, specifically for t he case 574 // 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 575 // 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. 576 // 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 577 // See: fast/css3-text/css3-word-break/word-break-all-wrap-with-floats.html
579 float widthMeasurementAtLastBreakOpportunity = 0; 578 float widthMeasurementAtLastBreakOpportunity = 0;
580 579
581 float hyphenWidth = 0; 580 float hyphenWidth = 0;
582 581
583 if (isSVGText) { 582 if (layoutText.isSVGInlineText()) {
584 breakWords = false; 583 breakWords = false;
585 breakAll = false; 584 breakAll = false;
586 keepAll = false; 585 keepAll = false;
587 } 586 }
588 587
589 if (layoutText.isWordBreak()) { 588 if (layoutText.isWordBreak()) {
590 m_width.commit(); 589 m_width.commit();
591 m_lineBreak.moveToStartOf(m_current.object()); 590 m_lineBreak.moveToStartOf(m_current.object());
592 ASSERT(m_current.offset() == layoutText.textLength()); 591 ASSERT(m_current.offset() == layoutText.textLength());
593 } 592 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
628 widthFromLastBreakingOpportunity += charWidth; 627 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)); 628 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); 629 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(); 630 midWordBreak = m_width.committedWidth() + widthFromLastBreakingOppor tunity + charWidth > m_width.availableWidth();
632 } 631 }
633 632
634 int nextBreakablePosition = m_current.nextBreakablePosition(); 633 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)); 634 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); 635 m_current.setNextBreakablePosition(nextBreakablePosition);
637 636
638 if (betweenWords || midWordBreak) { 637 // 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; 638 if (!betweenWords && !midWordBreak) {
640 if (m_ignoringSpaces) { 639 if (m_ignoringSpaces) {
641 lastSpaceWordSpacing = 0; 640 // Stop ignoring spaces and begin at this
642 if (!m_currentCharacterIsSpace) { 641 // new point.
643 // Stop ignoring spaces and begin at this 642 m_ignoringSpaces = false;
644 // new point. 643 lastSpaceWordSpacing = applyWordSpacing ? wordSpacing : 0;
645 m_ignoringSpaces = false; 644 wordSpacingForWordMeasurement = (applyWordSpacing && wordMeasure ments.last().width) ? wordSpacing : 0;
646 wordSpacingForWordMeasurement = 0; 645 lastSpace = m_current.offset(); // e.g., "Foo goo", don't add in any of the ignored spaces.
647 lastSpace = m_current.offset(); // e.g., "Foo goo", don't add in any of the ignored spaces. 646 m_lineMidpointState.stopIgnoringSpaces(InlineIterator(0, m_curre nt.object(), m_current.offset()));
648 m_lineMidpointState.stopIgnoringSpaces(InlineIterator(0, m_c urrent.object(), m_current.offset())); 647 }
649 stoppedIgnoringSpaces = true; 648
650 } else { 649 prepareForNextCharacter(layoutText, prohibitBreakInside, previousCha racterIsSpace, previousCharacterShouldCollapseIfPreWap);
651 // Just keep ignoring these spaces. 650 m_atStart = false;
652 nextCharacter(c, lastCharacter, secondToLastCharacter); 651 nextCharacter(c, lastCharacter, secondToLastCharacter);
653 continue; 652 continue;
653 }
654
655 // If we're ignoring space and we're at a collapsible space such as a sp ace or tab, continue to the next character.
656 bool stoppedIgnoringSpaces = false;
657 if (m_ignoringSpaces) {
658 lastSpaceWordSpacing = 0;
659 if (!m_currentCharacterIsSpace) {
660 // Stop ignoring spaces and begin at this
661 // new point.
662 m_ignoringSpaces = false;
663 wordSpacingForWordMeasurement = 0;
664 lastSpace = m_current.offset(); // e.g., "Foo goo", don't add in any of the ignored spaces.
665 m_lineMidpointState.stopIgnoringSpaces(InlineIterator(0, m_curre nt.object(), m_current.offset()));
666 stoppedIgnoringSpaces = true;
667 } else {
668 // Just keep ignoring these spaces.
669 nextCharacter(c, lastCharacter, secondToLastCharacter);
670 continue;
671 }
672 }
673
674 // We're in the first whitespace after a word or in whitespace that we d on't collapse, which means we may have a breaking opportunity here.
675 wordMeasurements.grow(wordMeasurements.size() + 1);
676 WordMeasurement& wordMeasurement = wordMeasurements.last();
677
678 wordMeasurement.layoutText = layoutText;
679 wordMeasurement.endOffset = m_current.offset();
680 wordMeasurement.startOffset = lastSpace;
681
682 float lastWidthMeasurement;
683 if (wordTrailingSpaceWidth && c == spaceCharacter)
684 lastWidthMeasurement = textWidth(layoutText, lastSpace, m_current.of fset() + 1 - lastSpace, font, m_width.currentWidth(), m_collapseWhiteSpace, &wor dMeasurement.fallbackFonts, &wordMeasurement.glyphBounds) - wordTrailingSpaceWid th;
685 else
686 lastWidthMeasurement = textWidth(layoutText, lastSpace, m_current.of fset() - lastSpace, font, m_width.currentWidth(), m_collapseWhiteSpace, &wordMea surement.fallbackFonts, &wordMeasurement.glyphBounds);
687
688 wordMeasurement.width = lastWidthMeasurement + wordSpacingForWordMeasure ment;
689 wordMeasurement.glyphBounds.move(wordSpacingForWordMeasurement, 0);
690 lastWidthMeasurement += lastSpaceWordSpacing;
691 m_width.addUncommittedWidth(lastWidthMeasurement);
692
693 if (m_collapseWhiteSpace && previousCharacterIsSpace && m_currentCharact erIsSpace && lastWidthMeasurement)
694 m_width.setTrailingWhitespaceWidth(lastWidthMeasurement);
695
696 if (!m_appliedStartWidth) {
697 m_width.addUncommittedWidth(inlineLogicalWidthFromAncestorsIfNeeded( m_current.object(), true, false).toFloat());
698 m_appliedStartWidth = true;
699 }
700
701 applyWordSpacing = wordSpacing && m_currentCharacterIsSpace;
702
703 if (!m_width.committedWidth() && m_autoWrap && !m_width.fitsOnLine() && !widthMeasurementAtLastBreakOpportunity)
704 m_width.fitBelowFloats(m_lineInfo.isFirstLine());
705
706 if (m_autoWrap || breakWords) {
707 // If we break only after white-space, consider the current characte r
708 // as candidate width for this line.
709 bool lineWasTooWide = false;
710 if (m_width.fitsOnLine() && m_currentCharacterIsSpace && m_currentSt yle->breakOnlyAfterWhiteSpace() && !midWordBreak) {
711 float charWidth = textWidth(layoutText, m_current.offset(), 1, f ont, m_width.currentWidth(), m_collapseWhiteSpace, &wordMeasurement.fallbackFont s, &wordMeasurement.glyphBounds) + (applyWordSpacing ? wordSpacing : 0);
712 // Check if line is too big even without the extra space
713 // at the end of the line. If it is not, do nothing.
714 // If the line needs the extra whitespace to be too long,
715 // then move the line break to the space and skip all
716 // additional whitespace.
717 if (!m_width.fitsOnLine(charWidth)) {
718 lineWasTooWide = true;
719 m_lineBreak.moveTo(m_current.object(), m_current.offset(), m _current.nextBreakablePosition());
720 skipTrailingWhitespace(m_lineBreak, m_lineInfo);
654 } 721 }
655 } 722 }
656 723 if (lineWasTooWide || !m_width.fitsOnLine()) {
657 wordMeasurements.grow(wordMeasurements.size() + 1); 724 if (m_lineBreak.atTextParagraphSeparator()) {
658 WordMeasurement& wordMeasurement = wordMeasurements.last(); 725 if (!stoppedIgnoringSpaces && m_current.offset() > 0)
659 726 m_lineMidpointState.ensureCharacterGetsLineBox(m_current );
660 wordMeasurement.layoutText = layoutText; 727 m_lineBreak.increment();
661 wordMeasurement.endOffset = m_current.offset(); 728 m_lineInfo.setPreviousLineBrokeCleanly(true);
662 wordMeasurement.startOffset = lastSpace; 729 wordMeasurement.endOffset = m_lineBreak.offset();
663 730 }
664 float lastWidthMeasurement; 731 if (m_lineBreak.object() && m_lineBreak.offset() && m_lineBreak. object().isText() && LineLayoutText(m_lineBreak.object()).textLength() && LineLa youtText(m_lineBreak.object()).characterAt(m_lineBreak.offset() - 1) == softHyph enCharacter)
665 if (wordTrailingSpaceWidth && c == spaceCharacter) 732 hyphenated = true;
666 lastWidthMeasurement = textWidth(layoutText, lastSpace, m_curren t.offset() + 1 - lastSpace, font, m_width.currentWidth(), m_collapseWhiteSpace, &wordMeasurement.fallbackFonts, &wordMeasurement.glyphBounds) - wordTrailingSpac eWidth; 733 if (m_lineBreak.offset() && m_lineBreak.offset() != (unsigned)wo rdMeasurement.endOffset && !wordMeasurement.width) {
667 else 734 if (charWidth) {
668 lastWidthMeasurement = textWidth(layoutText, lastSpace, m_curren t.offset() - lastSpace, font, m_width.currentWidth(), m_collapseWhiteSpace, &wor dMeasurement.fallbackFonts, &wordMeasurement.glyphBounds); 735 wordMeasurement.endOffset = m_lineBreak.offset();
669 736 wordMeasurement.width = charWidth;
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 } 737 }
704 } 738 }
705 if (lineWasTooWide || !m_width.fitsOnLine()) { 739 // Didn't fit. Jump to the end unless there's still an opportuni ty to collapse whitespace.
706 if (m_lineBreak.atTextParagraphSeparator()) { 740 if (m_ignoringSpaces || !m_collapseWhiteSpace || !m_currentChara cterIsSpace || !previousCharacterIsSpace) {
707 if (!stoppedIgnoringSpaces && m_current.offset() > 0) 741 m_atEnd = true;
708 m_lineMidpointState.ensureCharacterGetsLineBox(m_cur rent); 742 return false;
709 m_lineBreak.increment(); 743 }
710 m_lineInfo.setPreviousLineBrokeCleanly(true); 744 } else {
711 wordMeasurement.endOffset = m_lineBreak.offset(); 745 if (!betweenWords || (midWordBreak && !m_autoWrap) || (breakAll && !m_currentCharacterIsSpace))
712 } 746 m_width.addUncommittedWidth(-lastWidthMeasurement);
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) 747 if (hyphenWidth) {
714 hyphenated = true; 748 // Subtract the width of the soft hyphen out since we fit on a line.
715 if (m_lineBreak.offset() && m_lineBreak.offset() != (unsigne d)wordMeasurement.endOffset && !wordMeasurement.width) { 749 m_width.addUncommittedWidth(-hyphenWidth);
716 if (charWidth) { 750 hyphenWidth = 0;
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 } 751 }
735 } 752 }
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 } 753 }
792 754
793 if (isSVGText && m_current.offset()) { 755 if (c == newlineCharacter && m_preservesNewline) {
794 // Force creation of new InlineBoxes for each absolute positioned ch aracter (those that start new text chunks). 756 if (!stoppedIgnoringSpaces && m_current.offset())
795 if (LineLayoutSVGInlineText(layoutText).characterStartsNewTextChunk( m_current.offset()))
796 m_lineMidpointState.ensureCharacterGetsLineBox(m_current); 757 m_lineMidpointState.ensureCharacterGetsLineBox(m_current);
758 m_lineBreak.moveTo(m_current.object(), m_current.offset(), m_current .nextBreakablePosition());
759 m_lineBreak.increment();
760 m_lineInfo.setPreviousLineBrokeCleanly(true);
761 return true;
797 } 762 }
798 763
799 if (prohibitBreakInside) { 764 if (m_autoWrap && betweenWords) {
800 m_current.setNextBreakablePosition(layoutText.textLength()); 765 m_width.commit();
801 prohibitBreakInside = false; 766 widthFromLastBreakingOpportunity = 0;
767 m_lineBreak.moveTo(m_current.object(), m_current.offset(), m_current .nextBreakablePosition());
768 // Auto-wrapping text should not wrap in the middle of a word once i t has had an
769 // opportunity to break after a word.
770 breakWords = false;
771 widthMeasurementAtLastBreakOpportunity = lastWidthMeasurement;
802 } 772 }
803 773
804 if (m_currentCharacterIsSpace && !previousCharacterIsSpace) { 774 if (midWordBreak && !U16_IS_TRAIL(c) && !(WTF::Unicode::category(c) & (W TF::Unicode::Mark_NonSpacing | WTF::Unicode::Mark_Enclosing | WTF::Unicode::Mark _SpacingCombining))) {
805 m_startOfIgnoredSpaces.setObject(m_current.object()); 775 // Remember this as a breakable position in case
806 m_startOfIgnoredSpaces.setOffset(m_current.offset()); 776 // adding the end width forces a break.
777 m_lineBreak.moveTo(m_current.object(), m_current.offset(), m_current .nextBreakablePosition());
778 midWordBreak &= (breakWords || breakAll);
807 } 779 }
808 780
809 if (!m_currentCharacterIsSpace && previousCharacterShouldCollapseIfPreWa p) { 781 if (betweenWords) {
810 if (m_autoWrap && m_currentStyle->breakOnlyAfterWhiteSpace()) 782 lastSpaceWordSpacing = applyWordSpacing ? wordSpacing : 0;
811 m_lineBreak.moveTo(m_current.object(), m_current.offset(), m_cur rent.nextBreakablePosition()); 783 wordSpacingForWordMeasurement = (applyWordSpacing && wordMeasurement .width) ? wordSpacing : 0;
784 lastSpace = !breakAll || m_currentCharacterIsSpace ? m_current.offse t() : lastSpace;
812 } 785 }
813 786
814 if (m_collapseWhiteSpace && m_currentCharacterIsSpace && !m_ignoringSpac es) 787 if (!m_ignoringSpaces && m_currentStyle->collapseWhiteSpace()) {
815 m_trailingObjects.setTrailingWhitespace(LineLayoutText(m_current.obj ect())); 788 // If we encounter a newline, or if we encounter a
816 else if (!m_currentStyle->collapseWhiteSpace() || !m_currentCharacterIsS pace) 789 // second space, we need to go ahead and break up this
817 m_trailingObjects.clear(); 790 // run and enter a mode where we start collapsing spaces.
791 if (m_currentCharacterIsSpace && previousCharacterIsSpace) {
792 m_ignoringSpaces = true;
818 793
794 // We just entered a mode where we are ignoring
795 // spaces. Create a midpoint to terminate the run
796 // before the second space.
797 m_lineMidpointState.startIgnoringSpaces(m_startOfIgnoredSpaces);
798 m_trailingObjects.updateMidpointsForTrailingObjects(m_lineMidpoi ntState, InlineIterator(), TrailingObjects::DoNotCollapseFirstSpace);
799 }
800 }
801
802 prepareForNextCharacter(layoutText, prohibitBreakInside, previousCharact erIsSpace, previousCharacterShouldCollapseIfPreWap);
819 m_atStart = false; 803 m_atStart = false;
820 nextCharacter(c, lastCharacter, secondToLastCharacter); 804 nextCharacter(c, lastCharacter, secondToLastCharacter);
821 } 805 }
822 806
823 m_layoutTextInfo.m_lineBreakIterator.setPriorContext(lastCharacter, secondTo LastCharacter); 807 m_layoutTextInfo.m_lineBreakIterator.setPriorContext(lastCharacter, secondTo LastCharacter);
824 808
825 wordMeasurements.grow(wordMeasurements.size() + 1); 809 wordMeasurements.grow(wordMeasurements.size() + 1);
826 WordMeasurement& wordMeasurement = wordMeasurements.last(); 810 WordMeasurement& wordMeasurement = wordMeasurements.last();
827 wordMeasurement.layoutText = layoutText; 811 wordMeasurement.layoutText = layoutText;
828 812
(...skipping 23 matching lines...) Expand all
852 return true; 836 return true;
853 } 837 }
854 if (!hyphenated && m_lineBreak.previousInSameNode() == softHyphenCharact er) { 838 if (!hyphenated && m_lineBreak.previousInSameNode() == softHyphenCharact er) {
855 hyphenated = true; 839 hyphenated = true;
856 m_atEnd = true; 840 m_atEnd = true;
857 } 841 }
858 } 842 }
859 return false; 843 return false;
860 } 844 }
861 845
846 inline void BreakingContext::prepareForNextCharacter(const LineLayoutText& layou tText, bool& prohibitBreakInside, bool previousCharacterIsSpace, bool previousCh aracterShouldCollapseIfPreWap)
847 {
848 if (layoutText.isSVGInlineText() && m_current.offset()) {
849 // Force creation of new InlineBoxes for each absolute positioned charac ter (those that start new text chunks).
850 if (LineLayoutSVGInlineText(layoutText).characterStartsNewTextChunk(m_cu rrent.offset()))
851 m_lineMidpointState.ensureCharacterGetsLineBox(m_current);
852 }
853 if (prohibitBreakInside) {
854 m_current.setNextBreakablePosition(layoutText.textLength());
855 prohibitBreakInside = false;
856 }
857 if (m_currentCharacterIsSpace && !previousCharacterIsSpace) {
858 m_startOfIgnoredSpaces.setObject(m_current.object());
859 m_startOfIgnoredSpaces.setOffset(m_current.offset());
860 }
861 if (!m_currentCharacterIsSpace && previousCharacterShouldCollapseIfPreWap) {
862 if (m_autoWrap && m_currentStyle->breakOnlyAfterWhiteSpace())
863 m_lineBreak.moveTo(m_current.object(), m_current.offset(), m_current .nextBreakablePosition());
864 }
865 if (m_collapseWhiteSpace && m_currentCharacterIsSpace && !m_ignoringSpaces)
866 m_trailingObjects.setTrailingWhitespace(LineLayoutText(m_current.object( )));
867 else if (!m_currentStyle->collapseWhiteSpace() || !m_currentCharacterIsSpace )
868 m_trailingObjects.clear();
869 }
870
871
862 inline void BreakingContext::commitAndUpdateLineBreakIfNeeded() 872 inline void BreakingContext::commitAndUpdateLineBreakIfNeeded()
863 { 873 {
864 bool checkForBreak = m_autoWrap; 874 bool checkForBreak = m_autoWrap;
865 if (m_width.committedWidth() && !m_width.fitsOnLine() && m_lineBreak.object( ) && m_currWS == NOWRAP) { 875 if (m_width.committedWidth() && !m_width.fitsOnLine() && m_lineBreak.object( ) && m_currWS == NOWRAP) {
866 checkForBreak = true; 876 checkForBreak = true;
867 } else if (m_nextObject && m_current.object().isText() && m_nextObject.isTex t() && !m_nextObject.isBR() && (m_autoWrap || m_nextObject.style()->autoWrap())) { 877 } 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) { 878 if (m_autoWrap && m_currentCharacterIsSpace) {
869 checkForBreak = true; 879 checkForBreak = true;
870 } else { 880 } else {
871 LineLayoutText nextText(m_nextObject); 881 LineLayoutText nextText(m_nextObject);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
934 944
935 if (style.textIndentType() == TextIndentHanging) 945 if (style.textIndentType() == TextIndentHanging)
936 shouldIndentText = shouldIndentText == IndentText ? DoNotIndentText : In dentText; 946 shouldIndentText = shouldIndentText == IndentText ? DoNotIndentText : In dentText;
937 947
938 return shouldIndentText; 948 return shouldIndentText;
939 } 949 }
940 950
941 } 951 }
942 952
943 #endif // BreakingContextInlineHeaders_h 953 #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