int nextBreakablePosition(LazyLineBreakIterator& lazyBreakIterator, int pos, bool treatNoBreakSpaceAsBreak) { const UChar* str = lazyBreakIterator.string(); int len = lazyBreakIterator.length(); int nextBreak = -1; UChar lastCh = pos > 0 ? str[pos - 1] : 0; for (int i = pos; i < len; i++) { UChar ch = str[i]; if (isBreakableSpace(ch, treatNoBreakSpaceAsBreak) || shouldBreakAfter(lastCh, ch)) return i; if (needsLineBreakIterator(ch) || needsLineBreakIterator(lastCh)) { if (nextBreak < i && i) { TextBreakIterator* breakIterator = lazyBreakIterator.get(); if (breakIterator) nextBreak = textBreakFollowing(breakIterator, i - 1); } // These characters are not kinsoku characters according to Unicode 6.0, // However, they are in JLreq (http://www.w3.org/TR/jlreq/). We need // special treatment here. if (i == nextBreak && !isBreakableSpace(lastCh, treatNoBreakSpaceAsBreak) && !Font::isUnbreakableCharactersPair(lastCh, ch)) return i; } lastCh = ch; } return len; }
int nextBreakablePosition(LazyLineBreakIterator& lazyBreakIterator, int pos, bool treatNoBreakSpaceAsBreak) { const UChar* str = lazyBreakIterator.string(); int len = lazyBreakIterator.length(); int nextBreak = -1; UChar lastLastCh = pos > 1 ? str[pos - 2] : 0; UChar lastCh = pos > 0 ? str[pos - 1] : 0; for (int i = pos; i < len; i++) { UChar ch = str[i]; if (isBreakableSpace(ch, treatNoBreakSpaceAsBreak) || shouldBreakAfter(lastLastCh, lastCh, ch)) return i; if (needsLineBreakIterator(ch) || needsLineBreakIterator(lastCh)) { if (nextBreak < i && i) { TextBreakIterator* breakIterator = lazyBreakIterator.get(); if (breakIterator) nextBreak = textBreakFollowing(breakIterator, i - 1); } if (i == nextBreak && !isBreakableSpace(lastCh, treatNoBreakSpaceAsBreak)) return i; } lastLastCh = lastCh; lastCh = ch; } return len; }
int nextBreakablePositionIgnoringNBSP(LazyLineBreakIterator& lazyBreakIterator, int pos) { String string = lazyBreakIterator.string(); if (string.is8Bit()) return nextBreakablePosition<LChar, false>(lazyBreakIterator, string.characters8(), string.length(), pos); return nextBreakablePosition<UChar, false>(lazyBreakIterator, string.characters16(), string.length(), pos); }
bool RenderRubyText::canBreakBefore(const LazyLineBreakIterator& iterator) const { // FIXME: It would be nice to improve this so that it isn't just hard-coded, but lookahead in this // case is particularly problematic. if (!iterator.priorContextLength()) return true; UChar ch = iterator.lastCharacter(); ULineBreak lineBreak = (ULineBreak)u_getIntPropertyValue(ch, UCHAR_LINE_BREAK); // UNICODE LINE BREAKING ALGORITHM // http://www.unicode.org/reports/tr14/ // And Requirements for Japanese Text Layout, 3.1.7 Characters Not Starting a Line // http://www.w3.org/TR/2012/NOTE-jlreq-20120403/#characters_not_starting_a_line switch (lineBreak) { case U_LB_NONSTARTER: case U_LB_CLOSE_PARENTHESIS: case U_LB_CLOSE_PUNCTUATION: case U_LB_EXCLAMATION: case U_LB_BREAK_SYMBOLS: case U_LB_INFIX_NUMERIC: case U_LB_ZWSPACE: case U_LB_WORD_JOINER: return false; default: break; } // Special care for Requirements for Japanese Text Layout switch (ch) { case 0x2019: // RIGHT SINGLE QUOTATION MARK case 0x201D: // RIGHT DOUBLE QUOTATION MARK case 0x00BB: // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK case 0x2010: // HYPHEN case 0x2013: // EN DASH case 0x300C: // LEFT CORNER BRACKET return false; default: break; } return true; }
static inline int nextBreakablePositionKeepAllInternal(LazyLineBreakIterator& lazyBreakIterator, const UChar* str, unsigned length, int pos) { int len = static_cast<int>(length); int nextBreak = -1; UChar lastLastCh = pos > 1 ? str[pos - 2] : static_cast<UChar>(lazyBreakIterator.secondToLastCharacter()); UChar lastCh = pos > 0 ? str[pos - 1] : static_cast<UChar>(lazyBreakIterator.lastCharacter()); unsigned priorContextLength = lazyBreakIterator.priorContextLength(); for (int i = pos; i < len; i++) { UChar ch = str[i]; if (isBreakableSpace(ch) || shouldBreakAfter(lastLastCh, lastCh, ch)) return i; if (!shouldKeepAfter(lastLastCh, lastCh, ch) && (needsLineBreakIterator(ch) || needsLineBreakIterator(lastCh))) { if (nextBreak < i) { // Don't break if positioned at start of primary context and there is no prior context. if (i || priorContextLength) { TextBreakIterator* breakIterator = lazyBreakIterator.get(priorContextLength); if (breakIterator) { nextBreak = breakIterator->following(i - 1 + priorContextLength); if (nextBreak >= 0) { nextBreak -= priorContextLength; } } } } if (i == nextBreak && !isBreakableSpace(lastCh)) return i; } lastLastCh = lastCh; lastCh = ch; } return len; }
static inline int nextBreakablePosition(LazyLineBreakIterator& lazyBreakIterator, const CharacterType* str, unsigned length, int pos) { int len = static_cast<int>(length); int nextBreak = -1; CharacterType lastLastCh = pos > 1 ? str[pos - 2] : static_cast<CharacterType>(lazyBreakIterator.secondToLastCharacter()); CharacterType lastCh = pos > 0 ? str[pos - 1] : static_cast<CharacterType>(lazyBreakIterator.lastCharacter()); unsigned priorContextLength = lazyBreakIterator.priorContextLength(); for (int i = pos; i < len; i++) { CharacterType ch = str[i]; if (isBreakableSpace<treatNoBreakSpaceAsBreak>(ch) || shouldBreakAfter(lastLastCh, lastCh, ch)) return i; if (needsLineBreakIterator<treatNoBreakSpaceAsBreak, wordBreakSwitch>(ch) || needsLineBreakIterator<treatNoBreakSpaceAsBreak, wordBreakSwitch>(lastCh)) { if (nextBreak < i) { // Don't break if positioned at start of primary context and there is no prior context. if (i || priorContextLength) { TextBreakIterator* breakIterator = lazyBreakIterator.get(priorContextLength); if (breakIterator) { nextBreak = textBreakFollowing(breakIterator, i - 1 + priorContextLength); if (nextBreak >= 0) { nextBreak -= priorContextLength; } } } } if (i == nextBreak && !isBreakableSpace<treatNoBreakSpaceAsBreak>(lastCh)) return i; } lastLastCh = lastCh; lastCh = ch; } return len; }
int nextBreakablePosition(LazyLineBreakIterator& lazyBreakIterator, int pos, bool treatNoBreakSpaceAsBreak) { const UChar* str = lazyBreakIterator.string(); int len = lazyBreakIterator.length(); int nextBreak = -1; UChar lastCh = pos > 0 ? str[pos - 1] : 0; for (int i = pos; i < len; i++) { UChar ch = str[i]; if (isBreakableSpace(ch, treatNoBreakSpaceAsBreak) || shouldBreakAfter(lastCh, ch)) return i; if (needsLineBreakIterator(ch) || needsLineBreakIterator(lastCh)) { if (nextBreak < i && i) { #if !PLATFORM(MAC) || !defined(BUILDING_ON_TIGER) TextBreakIterator* breakIterator = lazyBreakIterator.get(); if (breakIterator) nextBreak = textBreakFollowing(breakIterator, i - 1); #else static TextBreakLocatorRef breakLocator = lineBreakLocator(); if (breakLocator) { UniCharArrayOffset nextUCBreak; if (UCFindTextBreak(breakLocator, kUCTextBreakLineMask, 0, str, len, i, &nextUCBreak) == 0) nextBreak = nextUCBreak; } #endif } if (i == nextBreak && !isBreakableSpace(lastCh, treatNoBreakSpaceAsBreak)) return i; } lastCh = ch; } return len; }
static inline int nextBreakablePositionBreakAllInternal(LazyLineBreakIterator& lazyBreakIterator, const CharacterType* str, unsigned length, int pos) { int len = static_cast<int>(length); CharacterType lastLastCh = pos > 1 ? str[pos - 2] : static_cast<CharacterType>(lazyBreakIterator.secondToLastCharacter()); CharacterType lastCh = pos > 0 ? str[pos - 1] : static_cast<CharacterType>(lazyBreakIterator.lastCharacter()); bool lastIsLetterOrNumber = isUnicodeCategoryLetterOrNumber(lastLastCh, lastCh); for (int i = pos; i < len; ++i) { CharacterType ch = str[i]; if (isBreakableSpace(ch) || shouldBreakAfter(lastLastCh, lastCh, ch)) return i; if (!U16_IS_LEAD(ch)) { bool isLetterOrNumber = isUnicodeCategoryLetterOrNumber(lastCh, ch); if (isLetterOrNumber && lastIsLetterOrNumber) return i > pos && U16_IS_TRAIL(ch) ? i - 1 : i; lastIsLetterOrNumber = isLetterOrNumber; } lastLastCh = lastCh; lastCh = ch; } return len; }
bool LayoutRubyRun::canBreakBefore(const LazyLineBreakIterator& iterator) const { // TODO(kojii): It would be nice to improve this so that it isn't just // hard-coded, but lookahead in this case is particularly problematic. // See crbug.com/522826. if (!iterator.priorContextLength()) return true; UChar ch = iterator.lastCharacter(); ULineBreak lineBreak = static_cast<ULineBreak>(u_getIntPropertyValue(ch, UCHAR_LINE_BREAK)); // UNICODE LINE BREAKING ALGORITHM // http://www.unicode.org/reports/tr14/ // And Requirements for Japanese Text Layout, 3.1.7 Characters Not Starting a Line // http://www.w3.org/TR/2012/NOTE-jlreq-20120403/#characters_not_starting_a_line switch (lineBreak) { case U_LB_WORD_JOINER: case U_LB_GLUE: case U_LB_OPEN_PUNCTUATION: return false; default: break; } return true; }
static unsigned nextBreakablePositionInSegment(LazyLineBreakIterator& lineBreakIterator, unsigned startPosition, bool breakNBSP, bool keepAllWordsForCJK) { if (keepAllWordsForCJK) { if (breakNBSP) return nextBreakablePositionKeepingAllWords(lineBreakIterator, startPosition); return nextBreakablePositionKeepingAllWordsIgnoringNBSP(lineBreakIterator, startPosition); } if (lineBreakIterator.isLooseCJKMode()) { if (breakNBSP) return nextBreakablePositionLoose(lineBreakIterator, startPosition); return nextBreakablePositionIgnoringNBSPLoose(lineBreakIterator, startPosition); } if (breakNBSP) return WebCore::nextBreakablePosition(lineBreakIterator, startPosition); return nextBreakablePositionIgnoringNBSP(lineBreakIterator, startPosition); }
int nextBreakablePositionIgnoringNBSP(LazyLineBreakIterator& lazyBreakIterator, int pos, EWordBreak wordBreak) { String string = lazyBreakIterator.string(); switch (wordBreak) { case KeepAllWordBreak: if (string.is8Bit()) return nextBreakablePosition<LChar, false, KeepAll>(lazyBreakIterator, string.characters8(), string.length(), pos); return nextBreakablePosition<UChar, false, KeepAll>(lazyBreakIterator, string.characters16(), string.length(), pos); case KeepAllIfKoreanWordBreak: if (string.is8Bit()) return nextBreakablePosition<LChar, false, KeepAllIfKorean>(lazyBreakIterator, string.characters8(), string.length(), pos); return nextBreakablePosition<UChar, false, KeepAllIfKorean>(lazyBreakIterator, string.characters16(), string.length(), pos); default: if (string.is8Bit()) return nextBreakablePosition<LChar, false, Default>(lazyBreakIterator, string.characters8(), string.length(), pos); return nextBreakablePosition<UChar, false, Default>(lazyBreakIterator, string.characters16(), string.length(), pos); } }
void RenderRubyBase::cachePriorCharactersIfNeeded(const LazyLineBreakIterator& lineBreakIterator) { auto* run = rubyRun(); if (run) run->setCachedPriorCharacters(lineBreakIterator.lastCharacter(), lineBreakIterator.secondToLastCharacter()); }