OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2000 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 2000 Lars Knoll (knoll@kde.org) |
3 * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r
ight reserved. | 3 * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r
ight reserved. |
4 * Copyright (C) 2010 Google Inc. All rights reserved. | 4 * Copyright (C) 2010 Google Inc. All rights reserved. |
5 * Copyright (C) 2013 Adobe Systems Incorporated. | 5 * Copyright (C) 2013 Adobe Systems Incorporated. |
6 * | 6 * |
7 * This library is free software; you can redistribute it and/or | 7 * This library is free software; you can redistribute it and/or |
8 * modify it under the terms of the GNU Library General Public | 8 * modify it under the terms of the GNU Library General Public |
9 * License as published by the Free Software Foundation; either | 9 * License as published by the Free Software Foundation; either |
10 * version 2 of the License, or (at your option) any later version. | 10 * version 2 of the License, or (at your option) any later version. |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 if (it.object()->isFloatingOrOutOfFlowPositioned()) | 187 if (it.object()->isFloatingOrOutOfFlowPositioned()) |
188 return false; | 188 return false; |
189 | 189 |
190 if (it.object()->isLayoutInline() && !alwaysRequiresLineBox(it.object()) &&
!requiresLineBoxForContent(toLayoutInline(it.object()), lineInfo)) | 190 if (it.object()->isLayoutInline() && !alwaysRequiresLineBox(it.object()) &&
!requiresLineBoxForContent(toLayoutInline(it.object()), lineInfo)) |
191 return false; | 191 return false; |
192 | 192 |
193 if (!shouldCollapseWhiteSpace(it.object()->styleRef(), lineInfo, whitespaceP
osition) || it.object()->isBR()) | 193 if (!shouldCollapseWhiteSpace(it.object()->styleRef(), lineInfo, whitespaceP
osition) || it.object()->isBR()) |
194 return true; | 194 return true; |
195 | 195 |
196 UChar current = it.current(); | 196 UChar current = it.current(); |
197 bool notJustWhitespace = current != space && current != characterTabulation
&& current != softHyphen && (current != newlineCharacter || it.object()->preserv
esNewline()); | 197 bool notJustWhitespace = current != spaceCharacter && current != tabulationC
haracter && current != softHyphenCharacter && (current != newlineCharacter || it
.object()->preservesNewline()); |
198 return notJustWhitespace || isEmptyInline(it.object()); | 198 return notJustWhitespace || isEmptyInline(it.object()); |
199 } | 199 } |
200 | 200 |
201 inline void setStaticPositions(LayoutBlockFlow* block, LayoutBox* child) | 201 inline void setStaticPositions(LayoutBlockFlow* block, LayoutBox* child) |
202 { | 202 { |
203 ASSERT(child->isOutOfFlowPositioned()); | 203 ASSERT(child->isOutOfFlowPositioned()); |
204 // FIXME: The math here is actually not really right. It's a best-guess appr
oximation that | 204 // FIXME: The math here is actually not really right. It's a best-guess appr
oximation that |
205 // will work for the common cases | 205 // will work for the common cases |
206 LayoutObject* containerBlock = child->container(); | 206 LayoutObject* containerBlock = child->container(); |
207 LayoutUnit blockHeight = block->logicalHeight(); | 207 LayoutUnit blockHeight = block->logicalHeight(); |
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
572 m_layoutTextInfo.m_text = layoutText; | 572 m_layoutTextInfo.m_text = layoutText; |
573 m_layoutTextInfo.m_font = &font; | 573 m_layoutTextInfo.m_font = &font; |
574 m_layoutTextInfo.m_lineBreakIterator.resetStringAndReleaseIterator(layou
tText->text(), style.locale()); | 574 m_layoutTextInfo.m_lineBreakIterator.resetStringAndReleaseIterator(layou
tText->text(), style.locale()); |
575 } else if (m_layoutTextInfo.m_font != &font) { | 575 } else if (m_layoutTextInfo.m_font != &font) { |
576 m_layoutTextInfo.m_font = &font; | 576 m_layoutTextInfo.m_font = &font; |
577 } | 577 } |
578 | 578 |
579 // Non-zero only when kerning is enabled, in which case we measure | 579 // Non-zero only when kerning is enabled, in which case we measure |
580 // words with their trailing space, then subtract its width. | 580 // words with their trailing space, then subtract its width. |
581 float wordTrailingSpaceWidth = (font.fontDescription().typesettingFeatures()
& Kerning) ? | 581 float wordTrailingSpaceWidth = (font.fontDescription().typesettingFeatures()
& Kerning) ? |
582 font.width(constructTextRun(layoutText, font, &space, 1, style, style.di
rection())) + wordSpacing | 582 font.width(constructTextRun(layoutText, font, &spaceCharacter, 1, style,
style.direction())) + wordSpacing |
583 : 0; | 583 : 0; |
584 | 584 |
585 UChar lastCharacter = m_layoutTextInfo.m_lineBreakIterator.lastCharacter(); | 585 UChar lastCharacter = m_layoutTextInfo.m_lineBreakIterator.lastCharacter(); |
586 UChar secondToLastCharacter = m_layoutTextInfo.m_lineBreakIterator.secondToL
astCharacter(); | 586 UChar secondToLastCharacter = m_layoutTextInfo.m_lineBreakIterator.secondToL
astCharacter(); |
587 for (; m_current.offset() < layoutText->textLength(); m_current.fastIncremen
tInTextNode()) { | 587 for (; m_current.offset() < layoutText->textLength(); m_current.fastIncremen
tInTextNode()) { |
588 bool previousCharacterIsSpace = m_currentCharacterIsSpace; | 588 bool previousCharacterIsSpace = m_currentCharacterIsSpace; |
589 bool previousCharacterShouldCollapseIfPreWap = m_currentCharacterShouldC
ollapseIfPreWap; | 589 bool previousCharacterShouldCollapseIfPreWap = m_currentCharacterShouldC
ollapseIfPreWap; |
590 UChar c = m_current.current(); | 590 UChar c = m_current.current(); |
591 m_currentCharacterShouldCollapseIfPreWap = m_currentCharacterIsSpace = c
== space || c == characterTabulation || (!m_preservesNewline && (c == newlineCh
aracter)); | 591 m_currentCharacterShouldCollapseIfPreWap = m_currentCharacterIsSpace = c
== spaceCharacter || c == tabulationCharacter || (!m_preservesNewline && (c ==
newlineCharacter)); |
592 | 592 |
593 if (!m_collapseWhiteSpace || !m_currentCharacterIsSpace) | 593 if (!m_collapseWhiteSpace || !m_currentCharacterIsSpace) |
594 m_lineInfo.setEmpty(false, m_block, &m_width); | 594 m_lineInfo.setEmpty(false, m_block, &m_width); |
595 | 595 |
596 if (c == softHyphen && m_autoWrap && !hyphenWidth) { | 596 if (c == softHyphenCharacter && m_autoWrap && !hyphenWidth) { |
597 hyphenWidth = measureHyphenWidth(layoutText, font, textDirectionFrom
Unicode(m_resolver.position().direction())); | 597 hyphenWidth = measureHyphenWidth(layoutText, font, textDirectionFrom
Unicode(m_resolver.position().direction())); |
598 m_width.addUncommittedWidth(hyphenWidth); | 598 m_width.addUncommittedWidth(hyphenWidth); |
599 } | 599 } |
600 | 600 |
601 bool applyWordSpacing = false; | 601 bool applyWordSpacing = false; |
602 | 602 |
603 if (breakWords && !midWordBreak) { | 603 if (breakWords && !midWordBreak) { |
604 wrapW += charWidth; | 604 wrapW += charWidth; |
605 bool midWordBreakIsBeforeSurrogatePair = U16_IS_LEAD(c) && m_current
.offset() + 1 < layoutText->textLength() && U16_IS_TRAIL((*layoutText)[m_current
.offset() + 1]); | 605 bool midWordBreakIsBeforeSurrogatePair = U16_IS_LEAD(c) && m_current
.offset() + 1 < layoutText->textLength() && U16_IS_TRAIL((*layoutText)[m_current
.offset() + 1]); |
606 charWidth = textWidth(layoutText, m_current.offset(), midWordBreakIs
BeforeSurrogatePair ? 2 : 1, font, m_width.committedWidth() + wrapW, m_collapseW
hiteSpace); | 606 charWidth = textWidth(layoutText, m_current.offset(), midWordBreakIs
BeforeSurrogatePair ? 2 : 1, font, m_width.committedWidth() + wrapW, m_collapseW
hiteSpace); |
(...skipping 24 matching lines...) Expand all Loading... |
631 } | 631 } |
632 | 632 |
633 wordMeasurements.grow(wordMeasurements.size() + 1); | 633 wordMeasurements.grow(wordMeasurements.size() + 1); |
634 WordMeasurement& wordMeasurement = wordMeasurements.last(); | 634 WordMeasurement& wordMeasurement = wordMeasurements.last(); |
635 | 635 |
636 wordMeasurement.layoutText = layoutText; | 636 wordMeasurement.layoutText = layoutText; |
637 wordMeasurement.endOffset = m_current.offset(); | 637 wordMeasurement.endOffset = m_current.offset(); |
638 wordMeasurement.startOffset = lastSpace; | 638 wordMeasurement.startOffset = lastSpace; |
639 | 639 |
640 float additionalTempWidth; | 640 float additionalTempWidth; |
641 if (wordTrailingSpaceWidth && c == space) | 641 if (wordTrailingSpaceWidth && c == spaceCharacter) |
642 additionalTempWidth = textWidth(layoutText, lastSpace, m_current
.offset() + 1 - lastSpace, font, m_width.currentWidth(), m_collapseWhiteSpace, &
wordMeasurement.fallbackFonts) - wordTrailingSpaceWidth; | 642 additionalTempWidth = textWidth(layoutText, lastSpace, m_current
.offset() + 1 - lastSpace, font, m_width.currentWidth(), m_collapseWhiteSpace, &
wordMeasurement.fallbackFonts) - wordTrailingSpaceWidth; |
643 else | 643 else |
644 additionalTempWidth = textWidth(layoutText, lastSpace, m_current
.offset() - lastSpace, font, m_width.currentWidth(), m_collapseWhiteSpace, &word
Measurement.fallbackFonts); | 644 additionalTempWidth = textWidth(layoutText, lastSpace, m_current
.offset() - lastSpace, font, m_width.currentWidth(), m_collapseWhiteSpace, &word
Measurement.fallbackFonts); |
645 | 645 |
646 wordMeasurement.width = additionalTempWidth + wordSpacingForWordMeas
urement; | 646 wordMeasurement.width = additionalTempWidth + wordSpacingForWordMeas
urement; |
647 additionalTempWidth += lastSpaceWordSpacing; | 647 additionalTempWidth += lastSpaceWordSpacing; |
648 m_width.addUncommittedWidth(additionalTempWidth); | 648 m_width.addUncommittedWidth(additionalTempWidth); |
649 | 649 |
650 if (m_collapseWhiteSpace && previousCharacterIsSpace && m_currentCha
racterIsSpace && additionalTempWidth) | 650 if (m_collapseWhiteSpace && previousCharacterIsSpace && m_currentCha
racterIsSpace && additionalTempWidth) |
651 m_width.setTrailingWhitespaceWidth(additionalTempWidth); | 651 m_width.setTrailingWhitespaceWidth(additionalTempWidth); |
(...skipping 26 matching lines...) Expand all Loading... |
678 } | 678 } |
679 } | 679 } |
680 if (lineWasTooWide || !m_width.fitsOnLine()) { | 680 if (lineWasTooWide || !m_width.fitsOnLine()) { |
681 if (m_lineBreak.atTextParagraphSeparator()) { | 681 if (m_lineBreak.atTextParagraphSeparator()) { |
682 if (!stoppedIgnoringSpaces && m_current.offset() > 0) | 682 if (!stoppedIgnoringSpaces && m_current.offset() > 0) |
683 m_lineMidpointState.ensureCharacterGetsLineBox(m_cur
rent); | 683 m_lineMidpointState.ensureCharacterGetsLineBox(m_cur
rent); |
684 m_lineBreak.increment(); | 684 m_lineBreak.increment(); |
685 m_lineInfo.setPreviousLineBrokeCleanly(true); | 685 m_lineInfo.setPreviousLineBrokeCleanly(true); |
686 wordMeasurement.endOffset = m_lineBreak.offset(); | 686 wordMeasurement.endOffset = m_lineBreak.offset(); |
687 } | 687 } |
688 if (m_lineBreak.object() && m_lineBreak.offset() && m_lineBr
eak.object()->isText() && toLayoutText(m_lineBreak.object())->textLength() && to
LayoutText(m_lineBreak.object())->characterAt(m_lineBreak.offset() - 1) == softH
yphen) | 688 if (m_lineBreak.object() && m_lineBreak.offset() && m_lineBr
eak.object()->isText() && toLayoutText(m_lineBreak.object())->textLength() && to
LayoutText(m_lineBreak.object())->characterAt(m_lineBreak.offset() - 1) == softH
yphenCharacter) |
689 hyphenated = true; | 689 hyphenated = true; |
690 if (m_lineBreak.offset() && m_lineBreak.offset() != (unsigne
d)wordMeasurement.endOffset && !wordMeasurement.width) { | 690 if (m_lineBreak.offset() && m_lineBreak.offset() != (unsigne
d)wordMeasurement.endOffset && !wordMeasurement.width) { |
691 if (charWidth) { | 691 if (charWidth) { |
692 wordMeasurement.endOffset = m_lineBreak.offset(); | 692 wordMeasurement.endOffset = m_lineBreak.offset(); |
693 wordMeasurement.width = charWidth; | 693 wordMeasurement.width = charWidth; |
694 } | 694 } |
695 } | 695 } |
696 // Didn't fit. Jump to the end unless there's still an oppor
tunity to collapse whitespace. | 696 // Didn't fit. Jump to the end unless there's still an oppor
tunity to collapse whitespace. |
697 if (m_ignoringSpaces || !m_collapseWhiteSpace || !m_currentC
haracterIsSpace || !previousCharacterIsSpace) { | 697 if (m_ignoringSpaces || !m_collapseWhiteSpace || !m_currentC
haracterIsSpace || !previousCharacterIsSpace) { |
698 m_atEnd = true; | 698 m_atEnd = true; |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
809 | 809 |
810 LayoutUnit inlineLogicalTempWidth = inlineLogicalWidth(m_current.object(), !
m_appliedStartWidth, m_includeEndWidth); | 810 LayoutUnit inlineLogicalTempWidth = inlineLogicalWidth(m_current.object(), !
m_appliedStartWidth, m_includeEndWidth); |
811 m_width.addUncommittedWidth(additionalTempWidth + inlineLogicalTempWidth); | 811 m_width.addUncommittedWidth(additionalTempWidth + inlineLogicalTempWidth); |
812 | 812 |
813 if (m_collapseWhiteSpace && m_currentCharacterIsSpace && additionalTempWidth
) | 813 if (m_collapseWhiteSpace && m_currentCharacterIsSpace && additionalTempWidth
) |
814 m_width.setTrailingWhitespaceWidth(additionalTempWidth + inlineLogicalTe
mpWidth); | 814 m_width.setTrailingWhitespaceWidth(additionalTempWidth + inlineLogicalTe
mpWidth); |
815 | 815 |
816 m_includeEndWidth = false; | 816 m_includeEndWidth = false; |
817 | 817 |
818 if (!m_width.fitsOnLine()) { | 818 if (!m_width.fitsOnLine()) { |
819 if (!hyphenated && m_lineBreak.previousInSameNode() == softHyphen) { | 819 if (!hyphenated && m_lineBreak.previousInSameNode() == softHyphenCharact
er) { |
820 hyphenated = true; | 820 hyphenated = true; |
821 m_atEnd = true; | 821 m_atEnd = true; |
822 } | 822 } |
823 } | 823 } |
824 return false; | 824 return false; |
825 } | 825 } |
826 | 826 |
827 inline void BreakingContext::commitAndUpdateLineBreakIfNeeded() | 827 inline void BreakingContext::commitAndUpdateLineBreakIfNeeded() |
828 { | 828 { |
829 bool checkForBreak = m_autoWrap; | 829 bool checkForBreak = m_autoWrap; |
830 if (m_width.committedWidth() && !m_width.fitsOnLine() && m_lineBreak.object(
) && m_currWS == NOWRAP) { | 830 if (m_width.committedWidth() && !m_width.fitsOnLine() && m_lineBreak.object(
) && m_currWS == NOWRAP) { |
831 checkForBreak = true; | 831 checkForBreak = true; |
832 } else if (m_nextObject && m_current.object()->isText() && m_nextObject->isT
ext() && !m_nextObject->isBR() && (m_autoWrap || m_nextObject->style()->autoWrap
())) { | 832 } else if (m_nextObject && m_current.object()->isText() && m_nextObject->isT
ext() && !m_nextObject->isBR() && (m_autoWrap || m_nextObject->style()->autoWrap
())) { |
833 if (m_autoWrap && m_currentCharacterIsSpace) { | 833 if (m_autoWrap && m_currentCharacterIsSpace) { |
834 checkForBreak = true; | 834 checkForBreak = true; |
835 } else { | 835 } else { |
836 LayoutText* nextText = toLayoutText(m_nextObject); | 836 LayoutText* nextText = toLayoutText(m_nextObject); |
837 if (nextText->textLength()) { | 837 if (nextText->textLength()) { |
838 UChar c = nextText->characterAt(0); | 838 UChar c = nextText->characterAt(0); |
839 // If the next item on the line is text, and if we did not end w
ith | 839 // If the next item on the line is text, and if we did not end w
ith |
840 // a space, then the next text run continues our word (and so it
needs to | 840 // a space, then the next text run continues our word (and so it
needs to |
841 // keep adding to the uncommitted width. Just update and continu
e. | 841 // keep adding to the uncommitted width. Just update and continu
e. |
842 checkForBreak = !m_currentCharacterIsSpace && (c == space || c =
= characterTabulation || (c == newlineCharacter && !m_nextObject->preservesNewli
ne())); | 842 checkForBreak = !m_currentCharacterIsSpace && (c == spaceCharact
er || c == tabulationCharacter || (c == newlineCharacter && !m_nextObject->prese
rvesNewline())); |
843 } else if (nextText->isWordBreak()) { | 843 } else if (nextText->isWordBreak()) { |
844 checkForBreak = true; | 844 checkForBreak = true; |
845 } | 845 } |
846 | 846 |
847 if (!m_width.fitsOnLine() && !m_width.committedWidth()) | 847 if (!m_width.fitsOnLine() && !m_width.committedWidth()) |
848 m_width.fitBelowFloats(m_lineInfo.isFirstLine()); | 848 m_width.fitBelowFloats(m_lineInfo.isFirstLine()); |
849 | 849 |
850 bool canPlaceOnLine = m_width.fitsOnLine() || !m_autoWrapWasEverTrue
OnLine; | 850 bool canPlaceOnLine = m_width.fitsOnLine() || !m_autoWrapWasEverTrue
OnLine; |
851 if (canPlaceOnLine && checkForBreak) { | 851 if (canPlaceOnLine && checkForBreak) { |
852 m_width.commit(); | 852 m_width.commit(); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
898 | 898 |
899 if (style.textIndentType() == TextIndentHanging) | 899 if (style.textIndentType() == TextIndentHanging) |
900 shouldIndentText = shouldIndentText == IndentText ? DoNotIndentText : In
dentText; | 900 shouldIndentText = shouldIndentText == IndentText ? DoNotIndentText : In
dentText; |
901 | 901 |
902 return shouldIndentText; | 902 return shouldIndentText; |
903 } | 903 } |
904 | 904 |
905 } | 905 } |
906 | 906 |
907 #endif // BreakingContextInlineHeaders_h | 907 #endif // BreakingContextInlineHeaders_h |
OLD | NEW |