Changeset 158918 in webkit


Ignore:
Timestamp:
Nov 8, 2013 4:53:19 AM (10 years ago)
Author:
Antti Koivisto
Message:

Templated LChar/UChar paths for simple line layout
https://bugs.webkit.org/show_bug.cgi?id=124035

Reviewed by Andreas Kling.

  • rendering/SimpleLineLayout.cpp:

(WebCore::SimpleLineLayout::canUseForText):
(WebCore::SimpleLineLayout::canUseFor):

Use a templated function to check for illegal characters.

(WebCore::SimpleLineLayout::skipWhitespaces):

Make a template function.

(WebCore::SimpleLineLayout::textWidth):

Make a template function plus some argument changes.

(WebCore::SimpleLineLayout::createTextRuns):

Template function for creating runs while operating with either LChars or UChar.
Also simplified line breaking and text width measuring logic.

(WebCore::SimpleLineLayout::create):

Pick the template.

  • rendering/break_lines.cpp:
  • rendering/break_lines.h:


Move the implementation to the header (except for the table) so we can use the template
versions directly.

(WebCore::isBreakableSpace):
(WebCore::shouldBreakAfter):
(WebCore::needsLineBreakIterator):
(WebCore::nextBreakablePosition):
(WebCore::nextBreakablePositionIgnoringNBSP):

Location:
trunk/Source/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r158914 r158918  
     12013-11-08  Antti Koivisto  <antti@apple.com>
     2
     3        Templated LChar/UChar paths for simple line layout
     4        https://bugs.webkit.org/show_bug.cgi?id=124035
     5
     6        Reviewed by Andreas Kling.
     7
     8        * rendering/SimpleLineLayout.cpp:
     9        (WebCore::SimpleLineLayout::canUseForText):
     10        (WebCore::SimpleLineLayout::canUseFor):
     11       
     12            Use a templated function to check for illegal characters.
     13
     14        (WebCore::SimpleLineLayout::skipWhitespaces):
     15       
     16            Make a template function.
     17
     18        (WebCore::SimpleLineLayout::textWidth):
     19       
     20            Make a template function plus some argument changes.
     21
     22        (WebCore::SimpleLineLayout::createTextRuns):
     23       
     24            Template function for creating runs while operating with either LChars or UChar.
     25            Also simplified line breaking and text width measuring logic.
     26
     27        (WebCore::SimpleLineLayout::create):
     28       
     29            Pick the template.
     30
     31        * rendering/break_lines.cpp:
     32        * rendering/break_lines.h:
     33       
     34            Move the implementation to the header (except for the table) so we can use the template
     35            versions directly.
     36
     37        (WebCore::isBreakableSpace):
     38        (WebCore::shouldBreakAfter):
     39        (WebCore::needsLineBreakIterator):
     40        (WebCore::nextBreakablePosition):
     41        (WebCore::nextBreakablePositionIgnoringNBSP):
     42
    1432013-11-08  Mario Sanchez Prada  <mario.prada@samsung.com>
    244
  • trunk/Source/WebCore/rendering/SimpleLineLayout.cpp

    r158860 r158918  
    5050namespace SimpleLineLayout {
    5151
    52 static inline bool isWhitespace(UChar character)
    53 {
    54     return character == ' ' || character == '\t' || character == '\n';
     52template <typename CharacterType>
     53static bool canUseForText(const CharacterType* text, unsigned length, const SimpleFontData& fontData)
     54{
     55    for (unsigned i = 0; i < length; ++i) {
     56        UChar character = text[i];
     57        if (character == ' ')
     58            continue;
     59
     60        // These would be easy to support.
     61        if (character == noBreakSpace)
     62            return false;
     63        if (character == softHyphen)
     64            return false;
     65
     66        UCharDirection direction = u_charDirection(character);
     67        if (direction == U_RIGHT_TO_LEFT || direction == U_RIGHT_TO_LEFT_ARABIC
     68            || direction == U_RIGHT_TO_LEFT_EMBEDDING || direction == U_RIGHT_TO_LEFT_OVERRIDE
     69            || direction == U_LEFT_TO_RIGHT_EMBEDDING || direction == U_LEFT_TO_RIGHT_OVERRIDE
     70            || direction == U_POP_DIRECTIONAL_FORMAT || direction == U_BOUNDARY_NEUTRAL)
     71            return false;
     72
     73        if (!fontData.glyphForCharacter(character))
     74            return false;
     75    }
     76    return true;
     77}
     78
     79static bool canUseForText(const RenderText& textRenderer, const SimpleFontData& fontData)
     80{
     81    if (textRenderer.is8Bit())
     82        return canUseForText(textRenderer.characters8(), textRenderer.textLength(), fontData);
     83    return canUseForText(textRenderer.characters16(), textRenderer.textLength(), fontData);
    5584}
    5685
     
    163192    if (primaryFontData.isLoading())
    164193        return false;
    165 
    166     unsigned length = textRenderer.textLength();
    167     for (unsigned i = 0; i < length; ++i) {
    168         UChar character = textRenderer.characterAt(i);
    169         if (character == ' ')
    170             continue;
    171 
    172         // These would be easy to support.
    173         if (character == noBreakSpace)
    174             return false;
    175         if (character == softHyphen)
    176             return false;
    177 
    178         UCharDirection direction = u_charDirection(character);
    179         if (direction == U_RIGHT_TO_LEFT || direction == U_RIGHT_TO_LEFT_ARABIC
    180             || direction == U_RIGHT_TO_LEFT_EMBEDDING || direction == U_RIGHT_TO_LEFT_OVERRIDE
    181             || direction == U_LEFT_TO_RIGHT_EMBEDDING || direction == U_LEFT_TO_RIGHT_OVERRIDE
    182             || direction == U_POP_DIRECTIONAL_FORMAT || direction == U_BOUNDARY_NEUTRAL)
    183             return false;
    184 
    185         if (!primaryFontData.glyphForCharacter(character))
    186             return false;
    187     }
     194    if (!canUseForText(textRenderer, primaryFontData))
     195        return false;
     196
    188197    return true;
    189198}
    190199
    191 static inline unsigned skipWhitespaces(const RenderText& textRenderer, unsigned offset, unsigned length)
     200static inline bool isWhitespace(UChar character)
     201{
     202    return character == ' ' || character == '\t' || character == '\n';
     203}
     204
     205template <typename CharacterType>
     206static inline unsigned skipWhitespaces(const CharacterType* text, unsigned offset, unsigned length)
    192207{
    193208    for (; offset < length; ++offset) {
    194         if (!isWhitespace(textRenderer.characterAt(offset)))
    195             break;
    196     }
    197     return offset;
    198 }
    199 
    200 static float textWidth(const RenderText& text, unsigned from, unsigned length, float xPosition, const RenderStyle& style)
    201 {
    202     if (style.font().isFixedPitch() || (!from && length == text.textLength()))
    203         return text.width(from, length, style.font(), xPosition, nullptr, nullptr);
     209        if (!isWhitespace(text[offset]))
     210            return offset;
     211    }
     212    return length;
     213}
     214
     215template <typename CharacterType>
     216static float textWidth(const RenderText& renderText, const CharacterType* text, unsigned textLength, unsigned from, unsigned to, float xPosition, const RenderStyle& style)
     217{
     218    if (style.font().isFixedPitch() || (!from && to == textLength))
     219        return renderText.width(from, to - from, style.font(), xPosition, nullptr, nullptr);
    204220    // FIXME: Add templated UChar/LChar paths.
    205     TextRun run = text.is8Bit() ? TextRun(text.characters8() + from, length) : TextRun(text.characters16() + from, length);
    206     run.setCharactersLength(text.textLength() - from);
     221    TextRun run(text + from, to - from);
     222    run.setXPos(xPosition);
     223    run.setCharactersLength(textLength - from);
    207224    ASSERT(run.charactersLength() >= run.length());
    208225
    209     run.setXPos(xPosition);
    210226    return style.font().width(run);
    211227}
     
    241257}
    242258
    243 std::unique_ptr<Layout> create(RenderBlockFlow& flow)
    244 {
    245     RenderText& textRenderer = toRenderText(*flow.firstChild());
    246     ASSERT(!textRenderer.firstTextBox());
    247 
     259template <typename CharacterType>
     260void createTextRuns(Layout::RunVector& runs, unsigned& lineCount, RenderBlockFlow& flow, RenderText& textRenderer)
     261{
    248262    const RenderStyle& style = flow.style();
    249     const unsigned textLength = textRenderer.textLength();
    250263
    251264    ETextAlign textAlign = style.textAlign();
    252265    float wordTrailingSpaceWidth = style.font().width(TextRun(&space, 1));
    253266
     267    const CharacterType* text = textRenderer.text()->getCharacters<CharacterType>();
     268    const unsigned textLength = textRenderer.textLength();
     269
    254270    LazyLineBreakIterator lineBreakIterator(textRenderer.text(), style.locale());
    255     int nextBreakable = -1;
    256 
    257     Layout::RunVector runs;
    258     unsigned lineCount = 0;
    259 
    260     unsigned lineEndOffset = 0;
    261     while (lineEndOffset < textLength) {
    262         lineEndOffset = skipWhitespaces(textRenderer, lineEndOffset, textLength);
    263         unsigned lineStartOffset = lineEndOffset;
    264         unsigned wordEndOffset = lineEndOffset;
     271
     272    unsigned lineEnd = 0;
     273    while (lineEnd < textLength) {
     274        lineEnd = skipWhitespaces(text, lineEnd, textLength);
     275        unsigned lineStart = lineEnd;
     276        unsigned wordEnd = lineEnd;
    265277        LineWidth lineWidth(flow, false, DoNotIndentText);
    266278
    267279        Vector<Run, 4> lineRuns;
    268         lineRuns.uncheckedAppend(Run(lineStartOffset, 0));
    269 
    270         while (wordEndOffset < textLength) {
    271             ASSERT(!isWhitespace(textRenderer.characterAt(wordEndOffset)));
    272 
    273             bool previousWasSpaceBetweenWords = wordEndOffset > lineStartOffset && isWhitespace(textRenderer.characterAt(wordEndOffset - 1));
    274             unsigned wordStartOffset = previousWasSpaceBetweenWords ? wordEndOffset - 1 : wordEndOffset;
    275 
    276             ++wordEndOffset;
    277             while (wordEndOffset < textLength) {
    278                 if (wordEndOffset > lineStartOffset && isBreakable(lineBreakIterator, wordEndOffset, nextBreakable, false))
    279                     break;
    280                 ++wordEndOffset;
    281             }
    282 
    283             unsigned wordLength = wordEndOffset - wordStartOffset;
    284             bool includeEndSpace = wordEndOffset < textLength && textRenderer.characterAt(wordEndOffset) == ' ';
    285             float wordWidth;
    286             if (includeEndSpace)
    287                 wordWidth = textWidth(textRenderer, wordStartOffset, wordLength + 1, lineWidth.committedWidth(), style) - wordTrailingSpaceWidth;
    288             else
    289                 wordWidth = textWidth(textRenderer, wordStartOffset, wordLength, lineWidth.committedWidth(), style);
     280        lineRuns.uncheckedAppend(Run(lineStart, 0));
     281
     282        while (wordEnd < textLength) {
     283            ASSERT(!isWhitespace(text[wordEnd]));
     284
     285            bool wordIsPrecededByWhitespace = wordEnd > lineStart && isWhitespace(text[wordEnd - 1]);
     286            unsigned wordStart = wordIsPrecededByWhitespace ? wordEnd - 1 : wordEnd;
     287
     288            wordEnd = nextBreakablePosition<CharacterType, false>(lineBreakIterator, text, textLength, wordEnd + 1);
     289
     290            bool measureWithEndSpace = wordEnd < textLength && text[wordEnd] == ' ';
     291            unsigned wordMeasureEnd = measureWithEndSpace ? wordEnd + 1 : wordEnd;
     292
     293            float wordWidth = textWidth(textRenderer, text, textLength, wordStart, wordMeasureEnd, lineWidth.committedWidth(), style);
     294
     295            if (measureWithEndSpace)
     296                wordWidth -= wordTrailingSpaceWidth;
    290297
    291298            lineWidth.addUncommittedWidth(wordWidth);
     
    295302                break;
    296303
    297             if (wordStartOffset > lineEndOffset) {
     304            if (wordStart > lineEnd) {
    298305                // There were more than one consecutive whitespace.
    299                 ASSERT(previousWasSpaceBetweenWords);
     306                ASSERT(wordIsPrecededByWhitespace);
    300307                // Include space to the end of the previous run.
    301308                lineRuns.last().textLength++;
    302309                lineRuns.last().right += wordTrailingSpaceWidth;
    303310                // Start a new run on the same line.
    304                 lineRuns.append(Run(wordStartOffset + 1, lineRuns.last().right));
     311                lineRuns.append(Run(wordStart + 1, lineRuns.last().right));
    305312            }
    306313
     
    308315
    309316            lineRuns.last().right = lineWidth.committedWidth();
    310             lineRuns.last().textLength = wordEndOffset - lineRuns.last().textOffset;
    311 
    312             lineEndOffset = wordEndOffset;
    313             wordEndOffset = skipWhitespaces(textRenderer, wordEndOffset, textLength);
     317            lineRuns.last().textLength = wordEnd - lineRuns.last().textOffset;
     318
     319            lineEnd = wordEnd;
     320            wordEnd = skipWhitespaces(text, wordEnd, textLength);
    314321
    315322            if (!lineWidth.fitsOnLine()) {
     
    319326            }
    320327        }
    321         if (lineStartOffset == lineEndOffset)
     328        if (lineStart == lineEnd)
    322329            continue;
    323330
     
    330337        ++lineCount;
    331338    }
     339}
     340
     341std::unique_ptr<Layout> create(RenderBlockFlow& flow)
     342{
     343    Layout::RunVector runs;
     344    unsigned lineCount = 0;
     345
     346    RenderText& textRenderer = toRenderText(*flow.firstChild());
     347    ASSERT(!textRenderer.firstTextBox());
     348
     349    if (textRenderer.is8Bit())
     350        createTextRuns<LChar>(runs, lineCount, flow, textRenderer);
     351    else
     352        createTextRuns<UChar>(runs, lineCount, flow, textRenderer);
    332353
    333354    textRenderer.clearNeedsLayout();
  • trunk/Source/WebCore/rendering/break_lines.cpp

    r147588 r158918  
    3939namespace WebCore {
    4040
    41 template<bool treatNoBreakSpaceAsBreak>
    42 static inline bool isBreakableSpace(UChar ch)
    43 {
    44     switch (ch) {
    45     case ' ':
    46     case '\n':
    47     case '\t':
    48         return true;
    49     case noBreakSpace:
    50         return treatNoBreakSpaceAsBreak;
    51     default:
    52         return false;
    53     }
    54 }
    55 
    56 static const UChar asciiLineBreakTableFirstChar = '!';
    57 static const UChar asciiLineBreakTableLastChar = 127;
    58 
    5941// Pack 8 bits into one byte
    6042#define B(a, b, c, d, e, f, g, h) \
     
    7456// Please refer to <https://bugs.webkit.org/show_bug.cgi?id=37698> for line breaking matrixes of different browsers
    7557// and the ICU standard.
    76 static const unsigned char asciiLineBreakTable[][(asciiLineBreakTableLastChar - asciiLineBreakTableFirstChar) / 8 + 1] = {
     58const unsigned char asciiLineBreakTable[][asciiLineBreakTableColumnCount] = {
    7759    //  !  "  #  $  %  &  '  (     )  *  +  ,  -  .  /  0  1-8   9  :  ;  <  =  >  ?  @     A-X      Y  Z  [  \  ]  ^  _  `     a-x      y  z  {  |  }  ~  DEL
    7860    { B(0, 0, 0, 0, 0, 0, 0, 1), B(0, 0, 0, 0, 0, 0, 0, 0), 0, B(0, 0, 0, 1, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0), 0, 0, 0, B(0, 0, 1, 0, 0, 0, 0, 0) }, // !
     
    121103COMPILE_ASSERT(WTF_ARRAY_LENGTH(asciiLineBreakTable) == asciiLineBreakTableLastChar - asciiLineBreakTableFirstChar + 1, TestLineBreakTableConsistency);
    122104
    123 static inline bool shouldBreakAfter(UChar lastCh, UChar ch, UChar nextCh)
    124 {
    125     // Don't allow line breaking between '-' and a digit if the '-' may mean a minus sign in the context,
    126     // while allow breaking in 'ABCD-1234' and '1234-5678' which may be in long URLs.
    127     if (ch == '-' && isASCIIDigit(nextCh))
    128         return isASCIIAlphanumeric(lastCh);
    129 
    130     // If both ch and nextCh are ASCII characters, use a lookup table for enhanced speed and for compatibility
    131     // with other browsers (see comments for asciiLineBreakTable for details).
    132     if (ch >= asciiLineBreakTableFirstChar && ch <= asciiLineBreakTableLastChar
    133             && nextCh >= asciiLineBreakTableFirstChar && nextCh <= asciiLineBreakTableLastChar) {
    134         const unsigned char* tableRow = asciiLineBreakTable[ch - asciiLineBreakTableFirstChar];
    135         int nextChIndex = nextCh - asciiLineBreakTableFirstChar;
    136         return tableRow[nextChIndex / 8] & (1 << (nextChIndex % 8));
    137     }
    138     // Otherwise defer to the Unicode algorithm by returning false.
    139     return false;
    140 }
    141 
    142 template<bool treatNoBreakSpaceAsBreak>
    143 inline bool needsLineBreakIterator(UChar ch)
    144 {
    145     if (treatNoBreakSpaceAsBreak)
    146         return ch > asciiLineBreakTableLastChar;
    147     return ch > asciiLineBreakTableLastChar && ch != noBreakSpace;
    148 }
    149 
    150 template<typename CharacterType, bool treatNoBreakSpaceAsBreak>
    151 static inline int nextBreakablePosition(LazyLineBreakIterator& lazyBreakIterator, const CharacterType* str, unsigned length, int pos)
    152 {
    153     int len = static_cast<int>(length);
    154     int nextBreak = -1;
    155 
    156     CharacterType lastLastCh = pos > 1 ? str[pos - 2] : static_cast<CharacterType>(lazyBreakIterator.secondToLastCharacter());
    157     CharacterType lastCh = pos > 0 ? str[pos - 1] : static_cast<CharacterType>(lazyBreakIterator.lastCharacter());
    158     unsigned priorContextLength = lazyBreakIterator.priorContextLength();
    159     for (int i = pos; i < len; i++) {
    160         CharacterType ch = str[i];
    161 
    162         if (isBreakableSpace<treatNoBreakSpaceAsBreak>(ch) || shouldBreakAfter(lastLastCh, lastCh, ch))
    163             return i;
    164 
    165         if (needsLineBreakIterator<treatNoBreakSpaceAsBreak>(ch) || needsLineBreakIterator<treatNoBreakSpaceAsBreak>(lastCh)) {
    166             if (nextBreak < i) {
    167                 // Don't break if positioned at start of primary context and there is no prior context.
    168                 if (i || priorContextLength) {
    169                     TextBreakIterator* breakIterator = lazyBreakIterator.get(priorContextLength);
    170                     if (breakIterator) {
    171                         nextBreak = textBreakFollowing(breakIterator, i - 1 + priorContextLength);
    172                         if (nextBreak >= 0)
    173                             nextBreak -= priorContextLength;
    174                     }
    175                 }
    176             }
    177             if (i == nextBreak && !isBreakableSpace<treatNoBreakSpaceAsBreak>(lastCh))
    178                 return i;
    179         }
    180 
    181         lastLastCh = lastCh;
    182         lastCh = ch;
    183     }
    184 
    185     return len;
    186 }
    187 
    188 int nextBreakablePositionIgnoringNBSP(LazyLineBreakIterator& lazyBreakIterator, int pos)
    189 {
    190     String string = lazyBreakIterator.string();
    191     if (string.is8Bit())
    192         return nextBreakablePosition<LChar, false>(lazyBreakIterator, string.characters8(), string.length(), pos);
    193     return nextBreakablePosition<UChar, false>(lazyBreakIterator, string.characters16(), string.length(), pos);
    194 }
    195 
    196 int nextBreakablePosition(LazyLineBreakIterator& lazyBreakIterator, int pos)
    197 {
    198     String string = lazyBreakIterator.string();
    199     if (string.is8Bit())
    200         return nextBreakablePosition<LChar, true>(lazyBreakIterator, string.characters8(), string.length(), pos);
    201     return nextBreakablePosition<UChar, true>(lazyBreakIterator, string.characters16(), string.length(), pos);
    202 }
    203 
    204105} // namespace WebCore
  • trunk/Source/WebCore/rendering/break_lines.h

    r144073 r158918  
    11/*
    2  * Copyright (C) 2005 Apple Computer, Inc.
     2 * Copyright (C) 2005, 2007, 2010, 2013 Apple Inc. All rights reserved.
     3 * Copyright (C) 2011 Google Inc. All rights reserved.
    34 *
    45 * This library is free software; you can redistribute it and/or
     
    2223#define break_lines_h
    2324
     25#include "TextBreakIterator.h"
     26#include <wtf/ASCIICType.h>
     27#include <wtf/StdLibExtras.h>
     28#include <wtf/unicode/CharacterNames.h>
    2429#include <wtf/unicode/Unicode.h>
    2530
    2631namespace WebCore {
    2732
    28 class LazyLineBreakIterator;
     33static const UChar asciiLineBreakTableFirstChar = '!';
     34static const UChar asciiLineBreakTableLastChar = 127;
     35static const unsigned asciiLineBreakTableColumnCount = (asciiLineBreakTableLastChar - asciiLineBreakTableFirstChar) / 8 + 1;
     36
     37extern const unsigned char asciiLineBreakTable[][asciiLineBreakTableColumnCount];
    2938
    3039int nextBreakablePositionIgnoringNBSP(LazyLineBreakIterator&, int pos);
    3140int nextBreakablePosition(LazyLineBreakIterator&, int pos);
     41
     42template<bool treatNoBreakSpaceAsBreak>
     43static inline bool isBreakableSpace(UChar ch)
     44{
     45    switch (ch) {
     46    case ' ':
     47    case '\n':
     48    case '\t':
     49        return true;
     50    case noBreakSpace:
     51        return treatNoBreakSpaceAsBreak;
     52    default:
     53        return false;
     54    }
     55}
     56
     57inline bool shouldBreakAfter(UChar lastCh, UChar ch, UChar nextCh)
     58{
     59    // Don't allow line breaking between '-' and a digit if the '-' may mean a minus sign in the context,
     60    // while allow breaking in 'ABCD-1234' and '1234-5678' which may be in long URLs.
     61    if (ch == '-' && isASCIIDigit(nextCh))
     62        return isASCIIAlphanumeric(lastCh);
     63
     64    // If both ch and nextCh are ASCII characters, use a lookup table for enhanced speed and for compatibility
     65    // with other browsers (see comments for asciiLineBreakTable for details).
     66    if (ch >= asciiLineBreakTableFirstChar && ch <= asciiLineBreakTableLastChar && nextCh >= asciiLineBreakTableFirstChar && nextCh <= asciiLineBreakTableLastChar) {
     67        const unsigned char* tableRow = asciiLineBreakTable[ch - asciiLineBreakTableFirstChar];
     68        int nextChIndex = nextCh - asciiLineBreakTableFirstChar;
     69        return tableRow[nextChIndex / 8] & (1 << (nextChIndex % 8));
     70    }
     71    // Otherwise defer to the Unicode algorithm by returning false.
     72    return false;
     73}
     74
     75template<bool treatNoBreakSpaceAsBreak>
     76inline bool needsLineBreakIterator(UChar ch)
     77{
     78    if (treatNoBreakSpaceAsBreak)
     79        return ch > asciiLineBreakTableLastChar;
     80    return ch > asciiLineBreakTableLastChar && ch != noBreakSpace;
     81}
     82
     83template<typename CharacterType, bool treatNoBreakSpaceAsBreak>
     84inline int nextBreakablePosition(LazyLineBreakIterator& lazyBreakIterator, const CharacterType* str, unsigned length, int pos)
     85{
     86    int len = static_cast<int>(length);
     87    int nextBreak = -1;
     88
     89    CharacterType lastLastCh = pos > 1 ? str[pos - 2] : static_cast<CharacterType>(lazyBreakIterator.secondToLastCharacter());
     90    CharacterType lastCh = pos > 0 ? str[pos - 1] : static_cast<CharacterType>(lazyBreakIterator.lastCharacter());
     91    unsigned priorContextLength = lazyBreakIterator.priorContextLength();
     92    for (int i = pos; i < len; i++) {
     93        CharacterType ch = str[i];
     94
     95        if (isBreakableSpace<treatNoBreakSpaceAsBreak>(ch) || shouldBreakAfter(lastLastCh, lastCh, ch))
     96            return i;
     97
     98        if (needsLineBreakIterator<treatNoBreakSpaceAsBreak>(ch) || needsLineBreakIterator<treatNoBreakSpaceAsBreak>(lastCh)) {
     99            if (nextBreak < i) {
     100                // Don't break if positioned at start of primary context and there is no prior context.
     101                if (i || priorContextLength) {
     102                    TextBreakIterator* breakIterator = lazyBreakIterator.get(priorContextLength);
     103                    if (breakIterator) {
     104                        nextBreak = textBreakFollowing(breakIterator, i - 1 + priorContextLength);
     105                        if (nextBreak >= 0)
     106                            nextBreak -= priorContextLength;
     107                    }
     108                }
     109            }
     110            if (i == nextBreak && !isBreakableSpace<treatNoBreakSpaceAsBreak>(lastCh))
     111                return i;
     112        }
     113
     114        lastLastCh = lastCh;
     115        lastCh = ch;
     116    }
     117
     118    return len;
     119}
     120
     121inline int nextBreakablePositionIgnoringNBSP(LazyLineBreakIterator& lazyBreakIterator, int pos)
     122{
     123    String string = lazyBreakIterator.string();
     124    if (string.is8Bit())
     125        return nextBreakablePosition<LChar, false>(lazyBreakIterator, string.characters8(), string.length(), pos);
     126    return nextBreakablePosition<UChar, false>(lazyBreakIterator, string.characters16(), string.length(), pos);
     127}
     128
     129inline int nextBreakablePosition(LazyLineBreakIterator& lazyBreakIterator, int pos)
     130{
     131    String string = lazyBreakIterator.string();
     132    if (string.is8Bit())
     133        return nextBreakablePosition<LChar, true>(lazyBreakIterator, string.characters8(), string.length(), pos);
     134    return nextBreakablePosition<UChar, true>(lazyBreakIterator, string.characters16(), string.length(), pos);
     135}
    32136
    33137inline bool isBreakable(LazyLineBreakIterator& lazyBreakIterator, int pos, int& nextBreakable, bool breakNBSP)
Note: See TracChangeset for help on using the changeset viewer.