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

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

Issue 1536443002: Refactor and comment BreakingContext::handleText() - Part 2 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Updated 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 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 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&, unsi gned lastSpace, float& lastWidthMeasurement, float wordSpacingForWordMeasurement , const Font&, float wordTrailingSpaceWidth, UChar);
108 void stopIgnoringSpaces(unsigned& lastSpace);
105 void commitAndUpdateLineBreakIfNeeded(); 109 void commitAndUpdateLineBreakIfNeeded();
106 InlineIterator handleEndOfLine(); 110 InlineIterator handleEndOfLine();
107 111
108 void clearLineBreakIfFitsOnLine() 112 void clearLineBreakIfFitsOnLine()
109 { 113 {
110 if (m_width.fitsOnLine() || m_lastWS == NOWRAP) 114 if (m_width.fitsOnLine() || m_lastWS == NOWRAP)
111 m_lineBreak.clear(); 115 m_lineBreak.clear();
112 } 116 }
113 117
114 private: 118 private:
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after
616 if (!m_collapseWhiteSpace || !m_currentCharacterIsSpace) 620 if (!m_collapseWhiteSpace || !m_currentCharacterIsSpace)
617 m_lineInfo.setEmpty(false, m_block, &m_width); 621 m_lineInfo.setEmpty(false, m_block, &m_width);
618 622
619 if (c == softHyphenCharacter && m_autoWrap && !hyphenWidth) { 623 if (c == softHyphenCharacter && m_autoWrap && !hyphenWidth) {
620 hyphenWidth = layoutText.hyphenWidth(font, textDirectionFromUnicode( m_resolver.position().direction())); 624 hyphenWidth = layoutText.hyphenWidth(font, textDirectionFromUnicode( m_resolver.position().direction()));
621 m_width.addUncommittedWidth(hyphenWidth); 625 m_width.addUncommittedWidth(hyphenWidth);
622 } 626 }
623 627
624 bool applyWordSpacing = false; 628 bool applyWordSpacing = false;
625 629
630 // Determine if we should try breaking in the middle of a word.
626 if (breakWords && !midWordBreak) { 631 if (breakWords && !midWordBreak) {
627 widthFromLastBreakingOpportunity += charWidth; 632 widthFromLastBreakingOpportunity += charWidth;
628 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));
629 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);
630 midWordBreak = m_width.committedWidth() + widthFromLastBreakingOppor tunity + charWidth > m_width.availableWidth(); 635 midWordBreak = m_width.committedWidth() + widthFromLastBreakingOppor tunity + charWidth > m_width.availableWidth();
631 } 636 }
632 637
638 // Determine if we are in the whitespace between words.
633 int nextBreakablePosition = m_current.nextBreakablePosition(); 639 int nextBreakablePosition = m_current.nextBreakablePosition();
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)); 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));
635 m_current.setNextBreakablePosition(nextBreakablePosition); 641 m_current.setNextBreakablePosition(nextBreakablePosition);
636 642
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. 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.
638 if (!betweenWords && !midWordBreak) { 644 if (!betweenWords && !midWordBreak) {
639 if (m_ignoringSpaces) { 645 if (m_ignoringSpaces) {
640 // Stop ignoring spaces and begin at this 646 // Stop ignoring spaces and begin at this
641 // new point. 647 // new point.
642 m_ignoringSpaces = false;
643 lastSpaceWordSpacing = applyWordSpacing ? wordSpacing : 0; 648 lastSpaceWordSpacing = applyWordSpacing ? wordSpacing : 0;
644 wordSpacingForWordMeasurement = (applyWordSpacing && wordMeasure ments.last().width) ? wordSpacing : 0; 649 wordSpacingForWordMeasurement = (applyWordSpacing && wordMeasure ments.last().width) ? wordSpacing : 0;
645 lastSpace = m_current.offset(); // e.g., "Foo goo", don't add in any of the ignored spaces. 650 stopIgnoringSpaces(lastSpace);
646 m_lineMidpointState.stopIgnoringSpaces(InlineIterator(0, m_curre nt.object(), m_current.offset()));
647 } 651 }
648 652
649 prepareForNextCharacter(layoutText, prohibitBreakInside, previousCha racterIsSpace, previousCharacterShouldCollapseIfPreWap); 653 prepareForNextCharacter(layoutText, prohibitBreakInside, previousCha racterIsSpace, previousCharacterShouldCollapseIfPreWap);
650 m_atStart = false; 654 m_atStart = false;
651 nextCharacter(c, lastCharacter, secondToLastCharacter); 655 nextCharacter(c, lastCharacter, secondToLastCharacter);
652 continue; 656 continue;
653 } 657 }
654 658
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. 659 // If we're collapsing space and we're at a collapsible space such as a space or tab, continue to the next character.
660 if (m_ignoringSpaces && m_currentCharacterIsSpace) {
661 lastSpaceWordSpacing = 0;
662 // Just keep ignoring these spaces.
663 nextCharacter(c, lastCharacter, secondToLastCharacter);
664 continue;
665 }
666
667 // 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.
668
669 // If we're here and we're collapsing space then the current character i sn't a form of whitespace we can collapse. Stop ignoring spaces.
656 bool stoppedIgnoringSpaces = false; 670 bool stoppedIgnoringSpaces = false;
657 if (m_ignoringSpaces) { 671 if (m_ignoringSpaces) {
658 lastSpaceWordSpacing = 0; 672 lastSpaceWordSpacing = 0;
659 if (!m_currentCharacterIsSpace) { 673 wordSpacingForWordMeasurement = 0;
660 // Stop ignoring spaces and begin at this 674 stoppedIgnoringSpaces = true;
661 // new point. 675 stopIgnoringSpaces(lastSpace);
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 } 676 }
673 677
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. 678 // Update our tally of the width since the last breakable position with the width of the word we're now at the end of.
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; 679 float lastWidthMeasurement;
683 if (wordTrailingSpaceWidth && c == spaceCharacter) 680 WordMeasurement& wordMeasurement = calculateWordWidth(wordMeasurements, layoutText, lastSpace, lastWidthMeasurement, wordSpacingForWordMeasurement, font , wordTrailingSpaceWidth, c);
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; 681 lastWidthMeasurement += lastSpaceWordSpacing;
691 m_width.addUncommittedWidth(lastWidthMeasurement); 682 m_width.addUncommittedWidth(lastWidthMeasurement);
692 683
684 // We keep track of the total width contributed by trailing space as we often want to exclude it when determining
685 // if a run fits on a line.
693 if (m_collapseWhiteSpace && previousCharacterIsSpace && m_currentCharact erIsSpace && lastWidthMeasurement) 686 if (m_collapseWhiteSpace && previousCharacterIsSpace && m_currentCharact erIsSpace && lastWidthMeasurement)
694 m_width.setTrailingWhitespaceWidth(lastWidthMeasurement); 687 m_width.setTrailingWhitespaceWidth(lastWidthMeasurement);
695 688
689 // If this is the end of the first word in run of text then make sure we apply the width from any leading inlines.
690 // For example: '<span style="margin-left: 5px;"><span style="margin-lef t: 10px;">FirstWord</span></span>' would
691 // apply a width of 15px from the two span ancestors.
696 if (!m_appliedStartWidth) { 692 if (!m_appliedStartWidth) {
697 m_width.addUncommittedWidth(inlineLogicalWidthFromAncestorsIfNeeded( m_current.object(), true, false).toFloat()); 693 m_width.addUncommittedWidth(inlineLogicalWidthFromAncestorsIfNeeded( m_current.object(), true, false).toFloat());
698 m_appliedStartWidth = true; 694 m_appliedStartWidth = true;
699 } 695 }
700 696
701 applyWordSpacing = wordSpacing && m_currentCharacterIsSpace; 697 applyWordSpacing = wordSpacing && m_currentCharacterIsSpace;
702 698
699 // If we haven't hit a breakable position yet and already don't fit on t he line try to move below any floats.
703 if (!m_width.committedWidth() && m_autoWrap && !m_width.fitsOnLine() && !widthMeasurementAtLastBreakOpportunity) 700 if (!m_width.committedWidth() && m_autoWrap && !m_width.fitsOnLine() && !widthMeasurementAtLastBreakOpportunity)
704 m_width.fitBelowFloats(m_lineInfo.isFirstLine()); 701 m_width.fitBelowFloats(m_lineInfo.isFirstLine());
705 702
706 if (m_autoWrap || breakWords) { 703 // If there is a soft-break available at this whitespace position then t ake it.
707 // If we break only after white-space, consider the current characte r 704 applyWordSpacing = wordSpacing && m_currentCharacterIsSpace;
708 // as candidate width for this line. 705 if (canBreakAtWhitespace(breakWords, wordMeasurement, stoppedIgnoringSpa ces, hyphenated, charWidth, hyphenWidth, betweenWords, midWordBreak, breakAll, p reviousCharacterIsSpace, lastWidthMeasurement, layoutText, font, applyWordSpacin g, wordSpacing))
709 bool lineWasTooWide = false; 706 return 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);
721 }
722 }
723 if (lineWasTooWide || !m_width.fitsOnLine()) {
724 if (m_lineBreak.atTextParagraphSeparator()) {
725 if (!stoppedIgnoringSpaces && m_current.offset() > 0)
726 m_lineMidpointState.ensureCharacterGetsLineBox(m_current );
727 m_lineBreak.increment();
728 m_lineInfo.setPreviousLineBrokeCleanly(true);
729 wordMeasurement.endOffset = m_lineBreak.offset();
730 }
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)
732 hyphenated = true;
733 if (m_lineBreak.offset() && m_lineBreak.offset() != (unsigned)wo rdMeasurement.endOffset && !wordMeasurement.width) {
734 if (charWidth) {
735 wordMeasurement.endOffset = m_lineBreak.offset();
736 wordMeasurement.width = charWidth;
737 }
738 }
739 // Didn't fit. Jump to the end unless there's still an opportuni ty to collapse whitespace.
740 if (m_ignoringSpaces || !m_collapseWhiteSpace || !m_currentChara cterIsSpace || !previousCharacterIsSpace) {
741 m_atEnd = true;
742 return false;
743 }
744 } else {
745 if (!betweenWords || (midWordBreak && !m_autoWrap) || (breakAll && !m_currentCharacterIsSpace))
746 m_width.addUncommittedWidth(-lastWidthMeasurement);
747 if (hyphenWidth) {
748 // Subtract the width of the soft hyphen out since we fit on a line.
749 m_width.addUncommittedWidth(-hyphenWidth);
750 hyphenWidth = 0;
751 }
752 }
753 }
754 707
708 // If there is a hard-break available at this whitespace position then t ake it.
755 if (c == newlineCharacter && m_preservesNewline) { 709 if (c == newlineCharacter && m_preservesNewline) {
756 if (!stoppedIgnoringSpaces && m_current.offset()) 710 if (!stoppedIgnoringSpaces && m_current.offset())
757 m_lineMidpointState.ensureCharacterGetsLineBox(m_current); 711 m_lineMidpointState.ensureCharacterGetsLineBox(m_current);
758 m_lineBreak.moveTo(m_current.object(), m_current.offset(), m_current .nextBreakablePosition()); 712 m_lineBreak.moveTo(m_current.object(), m_current.offset(), m_current .nextBreakablePosition());
759 m_lineBreak.increment(); 713 m_lineBreak.increment();
760 m_lineInfo.setPreviousLineBrokeCleanly(true); 714 m_lineInfo.setPreviousLineBrokeCleanly(true);
761 return true; 715 return true;
762 } 716 }
763 717
718 // Auto-wrapping text should not wrap in the middle of a word once it ha s had an
719 // opportunity to break after a word.
764 if (m_autoWrap && betweenWords) { 720 if (m_autoWrap && betweenWords) {
765 m_width.commit(); 721 m_width.commit();
766 widthFromLastBreakingOpportunity = 0; 722 widthFromLastBreakingOpportunity = 0;
767 m_lineBreak.moveTo(m_current.object(), m_current.offset(), m_current .nextBreakablePosition()); 723 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; 724 breakWords = false;
771 widthMeasurementAtLastBreakOpportunity = lastWidthMeasurement; 725 widthMeasurementAtLastBreakOpportunity = lastWidthMeasurement;
772 } 726 }
773 727
728 // Remember this as a breakable position in case adding the end width fo rces a break.
774 if (midWordBreak && !U16_IS_TRAIL(c) && !(WTF::Unicode::category(c) & (W TF::Unicode::Mark_NonSpacing | WTF::Unicode::Mark_Enclosing | WTF::Unicode::Mark _SpacingCombining))) { 729 if (midWordBreak && !U16_IS_TRAIL(c) && !(WTF::Unicode::category(c) & (W TF::Unicode::Mark_NonSpacing | WTF::Unicode::Mark_Enclosing | WTF::Unicode::Mark _SpacingCombining))) {
775 // Remember this as a breakable position in case
776 // adding the end width forces a break.
777 m_lineBreak.moveTo(m_current.object(), m_current.offset(), m_current .nextBreakablePosition()); 730 m_lineBreak.moveTo(m_current.object(), m_current.offset(), m_current .nextBreakablePosition());
778 midWordBreak &= (breakWords || breakAll); 731 midWordBreak &= (breakWords || breakAll);
779 } 732 }
780 733
781 if (betweenWords) { 734 if (betweenWords) {
782 lastSpaceWordSpacing = applyWordSpacing ? wordSpacing : 0; 735 lastSpaceWordSpacing = applyWordSpacing ? wordSpacing : 0;
783 wordSpacingForWordMeasurement = (applyWordSpacing && wordMeasurement .width) ? wordSpacing : 0; 736 wordSpacingForWordMeasurement = (applyWordSpacing && wordMeasurement .width) ? wordSpacing : 0;
784 lastSpace = !breakAll || m_currentCharacterIsSpace ? m_current.offse t() : lastSpace; 737 lastSpace = !breakAll || m_currentCharacterIsSpace ? m_current.offse t() : lastSpace;
785 } 738 }
786 739
740 // If we encounter a newline, or if we encounter a second space, we need to go ahead and break up
741 // this run and enter a mode where we start collapsing spaces.
787 if (!m_ignoringSpaces && m_currentStyle->collapseWhiteSpace()) { 742 if (!m_ignoringSpaces && m_currentStyle->collapseWhiteSpace()) {
788 // If we encounter a newline, or if we encounter a
789 // second space, we need to go ahead and break up this
790 // run and enter a mode where we start collapsing spaces.
791 if (m_currentCharacterIsSpace && previousCharacterIsSpace) { 743 if (m_currentCharacterIsSpace && previousCharacterIsSpace) {
792 m_ignoringSpaces = true; 744 m_ignoringSpaces = true;
793 745
794 // We just entered a mode where we are ignoring 746 // We just entered a mode where we are ignoring spaces. Create a midpoint to terminate the run
795 // spaces. Create a midpoint to terminate the run
796 // before the second space. 747 // before the second space.
797 m_lineMidpointState.startIgnoringSpaces(m_startOfIgnoredSpaces); 748 m_lineMidpointState.startIgnoringSpaces(m_startOfIgnoredSpaces);
798 m_trailingObjects.updateMidpointsForTrailingObjects(m_lineMidpoi ntState, InlineIterator(), TrailingObjects::DoNotCollapseFirstSpace); 749 m_trailingObjects.updateMidpointsForTrailingObjects(m_lineMidpoi ntState, InlineIterator(), TrailingObjects::DoNotCollapseFirstSpace);
799 } 750 }
800 } 751 }
801 752
802 prepareForNextCharacter(layoutText, prohibitBreakInside, previousCharact erIsSpace, previousCharacterShouldCollapseIfPreWap); 753 prepareForNextCharacter(layoutText, prohibitBreakInside, previousCharact erIsSpace, previousCharacterShouldCollapseIfPreWap);
803 m_atStart = false; 754 m_atStart = false;
804 nextCharacter(c, lastCharacter, secondToLastCharacter); 755 nextCharacter(c, lastCharacter, secondToLastCharacter);
805 } 756 }
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
862 if (m_autoWrap && m_currentStyle->breakOnlyAfterWhiteSpace()) 813 if (m_autoWrap && m_currentStyle->breakOnlyAfterWhiteSpace())
863 m_lineBreak.moveTo(m_current.object(), m_current.offset(), m_current .nextBreakablePosition()); 814 m_lineBreak.moveTo(m_current.object(), m_current.offset(), m_current .nextBreakablePosition());
864 } 815 }
865 if (m_collapseWhiteSpace && m_currentCharacterIsSpace && !m_ignoringSpaces) 816 if (m_collapseWhiteSpace && m_currentCharacterIsSpace && !m_ignoringSpaces)
866 m_trailingObjects.setTrailingWhitespace(LineLayoutText(m_current.object( ))); 817 m_trailingObjects.setTrailingWhitespace(LineLayoutText(m_current.object( )));
867 else if (!m_currentStyle->collapseWhiteSpace() || !m_currentCharacterIsSpace ) 818 else if (!m_currentStyle->collapseWhiteSpace() || !m_currentCharacterIsSpace )
868 m_trailingObjects.clear(); 819 m_trailingObjects.clear();
869 } 820 }
870 821
871 822
823 inline void BreakingContext::stopIgnoringSpaces(unsigned& lastSpace)
824 {
825 m_ignoringSpaces = false;
826 lastSpace = m_current.offset(); // e.g., "Foo goo", don't add in any of t he ignored spaces.
827 m_lineMidpointState.stopIgnoringSpaces(InlineIterator(0, m_current.object(), m_current.offset()));
828 }
829
830 inline WordMeasurement& BreakingContext::calculateWordWidth(WordMeasurements& wo rdMeasurements, LineLayoutText& layoutText, unsigned lastSpace, float& lastWidth Measurement, float wordSpacingForWordMeasurement, const Font& font, float wordTr ailingSpaceWidth, UChar c)
831 {
832 wordMeasurements.grow(wordMeasurements.size() + 1);
833 WordMeasurement& wordMeasurement = wordMeasurements.last();
834 wordMeasurement.layoutText = layoutText;
835 wordMeasurement.endOffset = m_current.offset();
836 wordMeasurement.startOffset = lastSpace;
837
838 if (wordTrailingSpaceWidth && c == spaceCharacter)
839 lastWidthMeasurement = textWidth(layoutText, lastSpace, m_current.offset () + 1 - lastSpace, font, m_width.currentWidth(), m_collapseWhiteSpace, &wordMea surement.fallbackFonts, &wordMeasurement.glyphBounds) - wordTrailingSpaceWidth;
840 else
841 lastWidthMeasurement = textWidth(layoutText, lastSpace, m_current.offset () - lastSpace, font, m_width.currentWidth(), m_collapseWhiteSpace, &wordMeasure ment.fallbackFonts, &wordMeasurement.glyphBounds);
842
843 wordMeasurement.width = lastWidthMeasurement + wordSpacingForWordMeasurement ;
844 wordMeasurement.glyphBounds.move(wordSpacingForWordMeasurement, 0);
845 return wordMeasurement;
846 }
847
848 inline bool BreakingContext::trailingSpaceExceedsAvailableWidth(bool midWordBrea k, const LineLayoutText& layoutText, WordMeasurement& wordMeasurement, bool appl yWordSpacing, bool wordSpacing, const Font& font)
849 {
850 // If we break only after white-space, consider the current character
851 // as candidate width for this line.
852 if (m_width.fitsOnLine() && m_currentCharacterIsSpace && m_currentStyle->bre akOnlyAfterWhiteSpace() && !midWordBreak) {
853 float charWidth = textWidth(layoutText, m_current.offset(), 1, font, m_w idth.currentWidth(), m_collapseWhiteSpace, &wordMeasurement.fallbackFonts, &word Measurement.glyphBounds) + (applyWordSpacing ? wordSpacing : 0);
854 // Check if line is too big even without the extra space
855 // at the end of the line. If it is not, do nothing.
856 // If the line needs the extra whitespace to be too long,
857 // then move the line break to the space and skip all
858 // additional whitespace.
859 if (!m_width.fitsOnLine(charWidth)) {
860 m_lineBreak.moveTo(m_current.object(), m_current.offset(), m_current .nextBreakablePosition());
861 skipTrailingWhitespace(m_lineBreak, m_lineInfo);
862 return true;
863 }
864 }
865 return false;
866 }
867
868 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)
869 {
870 if (!m_autoWrap && !breakWords)
871 return false;
872
873 // If we break only after white-space, consider the current character
874 // as candidate width for this line.
875 if (trailingSpaceExceedsAvailableWidth(midWordBreak, layoutText, wordMeasure ment, applyWordSpacing, wordSpacing, font) || !m_width.fitsOnLine()) {
876 if (m_lineBreak.atTextParagraphSeparator()) {
877 if (!stoppedIgnoringSpaces && m_current.offset() > 0)
878 m_lineMidpointState.ensureCharacterGetsLineBox(m_current);
879 m_lineBreak.increment();
880 m_lineInfo.setPreviousLineBrokeCleanly(true);
881 wordMeasurement.endOffset = m_lineBreak.offset();
882 }
883 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)
884 hyphenated = true;
885 if (m_lineBreak.offset() && m_lineBreak.offset() != (unsigned)wordMeasur ement.endOffset && !wordMeasurement.width) {
886 if (charWidth) {
887 wordMeasurement.endOffset = m_lineBreak.offset();
888 wordMeasurement.width = charWidth;
889 }
890 }
891 // Didn't fit. Jump to the end unless there's still an opportunity to co llapse whitespace.
892 if (m_ignoringSpaces || !m_collapseWhiteSpace || !m_currentCharacterIsSp ace || !previousCharacterIsSpace) {
893 m_atEnd = true;
894 return true;
895 }
896 } else {
897 if (!betweenWords || (midWordBreak && !m_autoWrap) || (breakAll && !m_cu rrentCharacterIsSpace))
898 m_width.addUncommittedWidth(-lastWidthMeasurement);
899 if (hyphenWidth) {
900 // Subtract the width of the soft hyphen out since we fit on a line.
901 m_width.addUncommittedWidth(-hyphenWidth);
902 hyphenWidth = 0;
903 }
904 }
905 return false;
906 }
907
872 inline void BreakingContext::commitAndUpdateLineBreakIfNeeded() 908 inline void BreakingContext::commitAndUpdateLineBreakIfNeeded()
873 { 909 {
874 bool checkForBreak = m_autoWrap; 910 bool checkForBreak = m_autoWrap;
875 if (m_width.committedWidth() && !m_width.fitsOnLine() && m_lineBreak.object( ) && m_currWS == NOWRAP) { 911 if (m_width.committedWidth() && !m_width.fitsOnLine() && m_lineBreak.object( ) && m_currWS == NOWRAP) {
876 checkForBreak = true; 912 checkForBreak = true;
877 } else if (m_nextObject && m_current.object().isText() && m_nextObject.isTex t() && !m_nextObject.isBR() && (m_autoWrap || m_nextObject.style()->autoWrap())) { 913 } else if (m_nextObject && m_current.object().isText() && m_nextObject.isTex t() && !m_nextObject.isBR() && (m_autoWrap || m_nextObject.style()->autoWrap())) {
878 if (m_autoWrap && m_currentCharacterIsSpace) { 914 if (m_autoWrap && m_currentCharacterIsSpace) {
879 checkForBreak = true; 915 checkForBreak = true;
880 } else { 916 } else {
881 LineLayoutText nextText(m_nextObject); 917 LineLayoutText nextText(m_nextObject);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
944 980
945 if (style.textIndentType() == TextIndentHanging) 981 if (style.textIndentType() == TextIndentHanging)
946 shouldIndentText = shouldIndentText == IndentText ? DoNotIndentText : In dentText; 982 shouldIndentText = shouldIndentText == IndentText ? DoNotIndentText : In dentText;
947 983
948 return shouldIndentText; 984 return shouldIndentText;
949 } 985 }
950 986
951 } 987 }
952 988
953 #endif // BreakingContextInlineHeaders_h 989 #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