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 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 | 116 |
117 private: | 117 private: |
118 void skipTrailingWhitespace(InlineIterator&, const LineInfo&); | 118 void skipTrailingWhitespace(InlineIterator&, const LineInfo&); |
119 bool shouldMidWordBreak(UChar, LineLayoutText, const Font&, | 119 bool shouldMidWordBreak(UChar, LineLayoutText, const Font&, |
120 float& charWidth, float& widthFromLastBreakingOpportunity, | 120 float& charWidth, float& widthFromLastBreakingOpportunity, |
121 bool breakAll, int& nextBreakablePositionForBreakAll); | 121 bool breakAll, int& nextBreakablePositionForBreakAll); |
122 bool rewindToMidWordBreak(WordMeasurement&, int end, float width); | 122 bool rewindToMidWordBreak(WordMeasurement&, int end, float width); |
123 bool rewindToFirstMidWordBreak(LineLayoutText, const ComputedStyle&, const F
ont&, bool breakAll, WordMeasurement&); | 123 bool rewindToFirstMidWordBreak(LineLayoutText, const ComputedStyle&, const F
ont&, bool breakAll, WordMeasurement&); |
124 bool rewindToMidWordBreak(LineLayoutText, const ComputedStyle&, const Font&,
bool breakAll, WordMeasurement&); | 124 bool rewindToMidWordBreak(LineLayoutText, const ComputedStyle&, const Font&,
bool breakAll, WordMeasurement&); |
125 bool hyphenate(LineLayoutText, const ComputedStyle&, const Font&, const Hyph
enation&, float lastSpaceWordSpacing, WordMeasurement&); | 125 bool hyphenate(LineLayoutText, const ComputedStyle&, const Font&, const Hyph
enation&, float lastSpaceWordSpacing, WordMeasurement&); |
| 126 bool isBreakAtSoftHyphen() const; |
126 | 127 |
127 InlineBidiResolver& m_resolver; | 128 InlineBidiResolver& m_resolver; |
128 | 129 |
129 InlineIterator m_current; | 130 InlineIterator m_current; |
130 InlineIterator m_lineBreak; | 131 InlineIterator m_lineBreak; |
131 InlineIterator m_startOfIgnoredSpaces; | 132 InlineIterator m_startOfIgnoredSpaces; |
132 | 133 |
133 LineLayoutBlockFlow m_block; | 134 LineLayoutBlockFlow m_block; |
134 LineLayoutItem m_lastObject; | 135 LineLayoutItem m_lastObject; |
135 LineLayoutItem m_nextObject; | 136 LineLayoutItem m_nextObject; |
(...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
690 if (!prefixLength || prefixLength < Hyphenation::minimumPrefixLength) | 691 if (!prefixLength || prefixLength < Hyphenation::minimumPrefixLength) |
691 return false; | 692 return false; |
692 | 693 |
693 // TODO(kojii): getCharacterRange() measures as if the word were not broken | 694 // TODO(kojii): getCharacterRange() measures as if the word were not broken |
694 // as defined in the spec, and is faster than measuring each fragment, but | 695 // as defined in the spec, and is faster than measuring each fragment, but |
695 // ignores the kerning between the last letter and the hyphen. | 696 // ignores the kerning between the last letter and the hyphen. |
696 return rewindToMidWordBreak(wordMeasurement, start + prefixLength, | 697 return rewindToMidWordBreak(wordMeasurement, start + prefixLength, |
697 font.getCharacterRange(run, 0, prefixLength).width() + hyphenWidth); | 698 font.getCharacterRange(run, 0, prefixLength).width() + hyphenWidth); |
698 } | 699 } |
699 | 700 |
| 701 ALWAYS_INLINE bool BreakingContext::isBreakAtSoftHyphen() const |
| 702 { |
| 703 return m_lineBreak != m_resolver.position() |
| 704 ? m_lineBreak.previousInSameNode() == softHyphenCharacter |
| 705 : m_current.previousInSameNode() == softHyphenCharacter; |
| 706 } |
| 707 |
700 inline bool BreakingContext::handleText(WordMeasurements& wordMeasurements, bool
& hyphenated) | 708 inline bool BreakingContext::handleText(WordMeasurements& wordMeasurements, bool
& hyphenated) |
701 { | 709 { |
702 if (!m_current.offset()) | 710 if (!m_current.offset()) |
703 m_appliedStartWidth = false; | 711 m_appliedStartWidth = false; |
704 | 712 |
705 LineLayoutText layoutText(m_current.getLineLayoutItem()); | 713 LineLayoutText layoutText(m_current.getLineLayoutItem()); |
706 | 714 |
707 // If we have left a no-wrap inline and entered an autowrap inline while ign
oring spaces | 715 // If we have left a no-wrap inline and entered an autowrap inline while ign
oring spaces |
708 // then we need to mark the start of the autowrap inline as a potential line
break now. | 716 // then we need to mark the start of the autowrap inline as a potential line
break now. |
709 if (m_autoWrap && !ComputedStyle::autoWrap(m_lastWS) && m_ignoringSpaces) { | 717 if (m_autoWrap && !ComputedStyle::autoWrap(m_lastWS) && m_ignoringSpaces) { |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
976 if (hyphenation && (m_nextObject || m_lineInfo.isEmpty())) { | 984 if (hyphenation && (m_nextObject || m_lineInfo.isEmpty())) { |
977 m_width.addUncommittedWidth(-wordMeasurement.width); | 985 m_width.addUncommittedWidth(-wordMeasurement.width); |
978 DCHECK(lastSpace == static_cast<unsigned>(wordMeasurement.startOffse
t)); | 986 DCHECK(lastSpace == static_cast<unsigned>(wordMeasurement.startOffse
t)); |
979 DCHECK(m_current.offset() == static_cast<unsigned>(wordMeasurement.e
ndOffset)); | 987 DCHECK(m_current.offset() == static_cast<unsigned>(wordMeasurement.e
ndOffset)); |
980 if (hyphenate(layoutText, style, font, *hyphenation, lastSpaceWordSp
acing, wordMeasurement)) { | 988 if (hyphenate(layoutText, style, font, *hyphenation, lastSpaceWordSp
acing, wordMeasurement)) { |
981 hyphenated = true; | 989 hyphenated = true; |
982 m_atEnd = true; | 990 m_atEnd = true; |
983 } | 991 } |
984 m_width.addUncommittedWidth(wordMeasurement.width); | 992 m_width.addUncommittedWidth(wordMeasurement.width); |
985 } | 993 } |
986 if (!hyphenated | 994 if (!hyphenated && isBreakAtSoftHyphen() && !disableSoftHyphen) { |
987 && m_lineBreak.previousInSameNode() == softHyphenCharacter | |
988 && !disableSoftHyphen) { | |
989 hyphenated = true; | 995 hyphenated = true; |
990 m_atEnd = true; | 996 m_atEnd = true; |
991 } | 997 } |
992 } | 998 } |
993 return false; | 999 return false; |
994 } | 1000 } |
995 | 1001 |
996 inline void BreakingContext::prepareForNextCharacter(const LineLayoutText& layou
tText, bool& prohibitBreakInside, bool previousCharacterIsSpace) | 1002 inline void BreakingContext::prepareForNextCharacter(const LineLayoutText& layou
tText, bool& prohibitBreakInside, bool previousCharacterIsSpace) |
997 { | 1003 { |
998 if (layoutText.isSVGInlineText() && m_current.offset()) { | 1004 if (layoutText.isSVGInlineText() && m_current.offset()) { |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1074 if (midWordBreak | 1080 if (midWordBreak |
1075 || trailingSpaceExceedsAvailableWidth(canBreakMidWord, layoutText, wordM
easurement, applyWordSpacing, wordSpacing, font) | 1081 || trailingSpaceExceedsAvailableWidth(canBreakMidWord, layoutText, wordM
easurement, applyWordSpacing, wordSpacing, font) |
1076 || !m_width.fitsOnLine()) { | 1082 || !m_width.fitsOnLine()) { |
1077 if (m_lineBreak.atTextParagraphSeparator()) { | 1083 if (m_lineBreak.atTextParagraphSeparator()) { |
1078 if (!stoppedIgnoringSpaces && m_current.offset() > 0) | 1084 if (!stoppedIgnoringSpaces && m_current.offset() > 0) |
1079 m_lineMidpointState.ensureCharacterGetsLineBox(m_current); | 1085 m_lineMidpointState.ensureCharacterGetsLineBox(m_current); |
1080 m_lineBreak.increment(); | 1086 m_lineBreak.increment(); |
1081 m_lineInfo.setPreviousLineBrokeCleanly(true); | 1087 m_lineInfo.setPreviousLineBrokeCleanly(true); |
1082 wordMeasurement.endOffset = m_lineBreak.offset(); | 1088 wordMeasurement.endOffset = m_lineBreak.offset(); |
1083 } | 1089 } |
1084 if (m_lineBreak.getLineLayoutItem() && m_lineBreak.offset() && m_lineBre
ak.getLineLayoutItem().isText() && LineLayoutText(m_lineBreak.getLineLayoutItem(
)).textLength() && LineLayoutText(m_lineBreak.getLineLayoutItem()).characterAt(m
_lineBreak.offset() - 1) == softHyphenCharacter && !disableSoftHyphen) | 1090 if (isBreakAtSoftHyphen() && !disableSoftHyphen) |
1085 hyphenated = true; | 1091 hyphenated = true; |
1086 if (m_lineBreak.offset() && m_lineBreak.offset() != (unsigned)wordMeasur
ement.endOffset && !wordMeasurement.width) { | 1092 if (m_lineBreak.offset() && m_lineBreak.offset() != (unsigned)wordMeasur
ement.endOffset && !wordMeasurement.width) { |
1087 if (charWidth) { | 1093 if (charWidth) { |
1088 wordMeasurement.endOffset = m_lineBreak.offset(); | 1094 wordMeasurement.endOffset = m_lineBreak.offset(); |
1089 wordMeasurement.width = charWidth; | 1095 wordMeasurement.width = charWidth; |
1090 } | 1096 } |
1091 } | 1097 } |
1092 // Didn't fit. Jump to the end unless there's still an opportunity to co
llapse whitespace. | 1098 // Didn't fit. Jump to the end unless there's still an opportunity to co
llapse whitespace. |
1093 if (m_ignoringSpaces || !m_collapseWhiteSpace || !m_currentCharacterIsSp
ace || !previousCharacterIsSpace) { | 1099 if (m_ignoringSpaces || !m_collapseWhiteSpace || !m_currentCharacterIsSp
ace || !previousCharacterIsSpace) { |
1094 m_atEnd = true; | 1100 m_atEnd = true; |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1185 | 1191 |
1186 if (style.getTextIndentType() == TextIndentHanging) | 1192 if (style.getTextIndentType() == TextIndentHanging) |
1187 indentText = indentText == IndentText ? DoNotIndentText : IndentText; | 1193 indentText = indentText == IndentText ? DoNotIndentText : IndentText; |
1188 | 1194 |
1189 return indentText; | 1195 return indentText; |
1190 } | 1196 } |
1191 | 1197 |
1192 } // namespace blink | 1198 } // namespace blink |
1193 | 1199 |
1194 #endif // BreakingContextInlineHeaders_h | 1200 #endif // BreakingContextInlineHeaders_h |
OLD | NEW |