Changeset 44649 in webkit


Ignore:
Timestamp:
Jun 12, 2009 11:04:40 PM (15 years ago)
Author:
hyatt@apple.com
Message:

2009-06-12 David Hyatt <hyatt@apple.com>

Reviewed by Dan Bernstein.

https://bugs.webkit.org/show_bug.cgi?id=26367

Remove the global variables in bidi.cpp. Make a new struct, MidpointState, that holds all of the
midpoint information. Add the remaining global variables as arguments passed down through functions
as needed.

  • platform/text/BidiResolver.h: (WebCore::MidpointState::MidpointState): (WebCore::MidpointState::reset): (WebCore::BidiResolver::midpointState):
  • rendering/RenderBlock.h:
  • rendering/bidi.cpp: (WebCore::BidiRun::operator delete): (WebCore::chopMidpointsAt): (WebCore::checkMidpoints): (WebCore::addMidpoint): (WebCore::appendRunsForObject): (WebCore::RenderBlock::bidiReorderLine): (WebCore::RenderBlock::layoutInlineChildren): (WebCore::RenderBlock::determineStartPosition): (WebCore::skipNonBreakingSpace): (WebCore::shouldCollapseWhiteSpace): (WebCore::requiresLineBox): (WebCore::RenderBlock::generatesLineBoxesForInlineChild): (WebCore::RenderBlock::skipTrailingWhitespace): (WebCore::RenderBlock::skipLeadingWhitespace): (WebCore::shouldSkipWhitespaceAfterStartObject): (WebCore::RenderBlock::findNextLineBreak):
Location:
trunk/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r44648 r44649  
     12009-06-12  David Hyatt  <hyatt@apple.com>
     2
     3        Reviewed by Dan Bernstein.
     4
     5        https://bugs.webkit.org/show_bug.cgi?id=26367
     6
     7        Remove the global variables in bidi.cpp.  Make a new struct, MidpointState, that holds all of the
     8        midpoint information.  Add the remaining global variables as arguments passed down through functions
     9        as needed.
     10
     11        * platform/text/BidiResolver.h:
     12        (WebCore::MidpointState::MidpointState):
     13        (WebCore::MidpointState::reset):
     14        (WebCore::BidiResolver::midpointState):
     15        * rendering/RenderBlock.h:
     16        * rendering/bidi.cpp:
     17        (WebCore::BidiRun::operator delete):
     18        (WebCore::chopMidpointsAt):
     19        (WebCore::checkMidpoints):
     20        (WebCore::addMidpoint):
     21        (WebCore::appendRunsForObject):
     22        (WebCore::RenderBlock::bidiReorderLine):
     23        (WebCore::RenderBlock::layoutInlineChildren):
     24        (WebCore::RenderBlock::determineStartPosition):
     25        (WebCore::skipNonBreakingSpace):
     26        (WebCore::shouldCollapseWhiteSpace):
     27        (WebCore::requiresLineBox):
     28        (WebCore::RenderBlock::generatesLineBoxesForInlineChild):
     29        (WebCore::RenderBlock::skipTrailingWhitespace):
     30        (WebCore::RenderBlock::skipLeadingWhitespace):
     31        (WebCore::shouldSkipWhitespaceAfterStartObject):
     32        (WebCore::RenderBlock::findNextLineBreak):
     33
    1342009-06-12  Holger Hans Peter Freyther  <zecke@selfish.org>
    235
  • trunk/WebCore/platform/text/BidiResolver.h

    r42895 r44649  
    3030namespace WebCore {
    3131
     32template <class Iterator> class MidpointState
     33{
     34public:
     35    MidpointState()
     36    {
     37        reset();
     38    }
     39   
     40    void reset()
     41    {
     42        m_numMidpoints = 0;
     43        m_currentMidpoint = 0;
     44        m_betweenMidpoints = false;
     45    }
     46   
     47    // The goal is to reuse the line state across multiple
     48    // lines so we just keep an array around for midpoints and never clear it across multiple
     49    // lines.  We track the number of items and position using the two other variables.
     50    Vector<Iterator> m_midpoints;
     51    unsigned m_numMidpoints;
     52    unsigned m_currentMidpoint;
     53    bool m_betweenMidpoints;
     54};
     55
    3256// The BidiStatus at a given position (typically the end of a line) can
    3357// be cached and then used to restart bidi resolution at that position.
     
    136160    void setStatus(const BidiStatus s) { m_status = s; }
    137161
     162    MidpointState<Iterator>& midpointState() { return m_midpointState; }
     163
    138164    void embed(WTF::Unicode::Direction);
    139165    void commitExplicitEmbedding();
     
    173199    Run* m_logicallyLastRun;
    174200    unsigned m_runCount;
     201    MidpointState<Iterator> m_midpointState;
    175202
    176203private:
  • trunk/WebCore/rendering/RenderBlock.h

    r44446 r44649  
    2525#ifndef RenderBlock_h
    2626#define RenderBlock_h
    27 
    2827#include "DeprecatedPtrList.h"
    2928#include "GapRects.h"
     
    4342
    4443template <class Iterator, class Run> class BidiResolver;
     44template <class Iterator> class MidpointState;
    4545typedef BidiResolver<InlineIterator, BidiRun> InlineBidiResolver;
     46typedef MidpointState<InlineIterator> LineMidpointState;
    4647
    4748enum CaretType { CursorCaret, DragCaret };
     
    158159    };
    159160
    160     void bidiReorderLine(InlineBidiResolver&, const InlineIterator& end);
    161     RootInlineBox* determineStartPosition(bool& firstLine, bool& fullLayout, InlineBidiResolver&, Vector<FloatWithRect>& floats, unsigned& numCleanFloats);
     161    void bidiReorderLine(InlineBidiResolver&, const InlineIterator& end, bool previousLineBrokeCleanly);
     162    RootInlineBox* determineStartPosition(bool& firstLine, bool& fullLayout, bool& previousLineBrokeCleanly,
     163                                          InlineBidiResolver&, Vector<FloatWithRect>& floats, unsigned& numCleanFloats);
    162164    RootInlineBox* determineEndPosition(RootInlineBox* startBox, InlineIterator& cleanLineStart,
    163165                                        BidiStatus& cleanLineBidiStatus,
     
    165167    bool matchedEndLine(const InlineBidiResolver&, const InlineIterator& endLineStart, const BidiStatus& endLineStatus,
    166168                        RootInlineBox*& endLine, int& endYPos, int& repaintBottom, int& repaintTop);
    167     bool generatesLineBoxesForInlineChild(RenderObject*);
    168     void skipTrailingWhitespace(InlineIterator&);
    169     int skipLeadingWhitespace(InlineBidiResolver&, bool firstLine);
     169    bool generatesLineBoxesForInlineChild(RenderObject*, bool isLineEmpty = true, bool previousLineBrokeCleanly = true);
     170    void skipTrailingWhitespace(InlineIterator&, bool isLineEmpty, bool previousLineBrokeCleanly);
     171    int skipLeadingWhitespace(InlineBidiResolver&, bool firstLine, bool isLineEmpty, bool previousLineBrokeCleanly);
    170172    void fitBelowFloats(int widthToFit, bool firstLine, int& availableWidth);
    171     InlineIterator findNextLineBreak(InlineBidiResolver&, bool firstLine, EClear* clear = 0);
     173    InlineIterator findNextLineBreak(InlineBidiResolver&, bool firstLine, bool& isLineEmpty, bool& previousLineBrokeCleanly, EClear* clear = 0);
    172174    RootInlineBox* constructLine(unsigned runCount, BidiRun* firstRun, BidiRun* lastRun, bool firstLine, bool lastLine, RenderObject* endObject);
    173175    InlineFlowBox* createLineBoxes(RenderObject*, bool firstLine);
  • trunk/WebCore/rendering/bidi.cpp

    r43664 r44649  
    7979};
    8080
    81 // Midpoint globals.  The goal is not to do any allocation when dealing with
    82 // these midpoints, so we just keep an array around and never clear it.  We track
    83 // the number of items and position using the two other variables.
    84 static Vector<InlineIterator>* smidpoints;
    85 static unsigned sNumMidpoints;
    86 static unsigned sCurrMidpoint;
    87 static bool betweenMidpoints;
    88 
    89 static bool isLineEmpty = true;
    90 static bool previousLineBrokeCleanly = true;
    91 
    9281static int getBorderPaddingMargin(RenderBoxModelObject* child, bool endOfInline)
    9382{
     
    148137    bidiRunCounter.decrement();
    149138#endif
    150     ASSERT(inBidiRunDestroy);
     139    //ASSERT(inBidiRunDestroy);
    151140
    152141    // Stash size where destroy() can find it.
     
    328317// -------------------------------------------------------------------------------------------------
    329318
    330 static void chopMidpointsAt(RenderObject* obj, unsigned pos)
    331 {
    332     if (!sNumMidpoints)
     319static void chopMidpointsAt(LineMidpointState& lineMidpointState, RenderObject* obj, unsigned pos)
     320{
     321    if (!lineMidpointState.m_numMidpoints)
    333322        return;
    334     InlineIterator* midpoints = smidpoints->data();
    335     for (int i = sNumMidpoints - 1; i >= 0; i--) {
     323    InlineIterator* midpoints = lineMidpointState.m_midpoints.data();
     324    for (int i = lineMidpointState.m_numMidpoints - 1; i >= 0; i--) {
    336325        const InlineIterator& point = midpoints[i];
    337326        if (point.obj == obj && point.pos == pos) {
    338             sNumMidpoints = i;
     327            lineMidpointState.m_numMidpoints = i;
    339328            break;
    340329        }
     
    342331}
    343332
    344 static void checkMidpoints(InlineIterator& lBreak)
     333static void checkMidpoints(LineMidpointState& lineMidpointState, InlineIterator& lBreak)
    345334{
    346335    // Check to see if our last midpoint is a start point beyond the line break.  If so,
    347336    // shave it off the list, and shave off a trailing space if the previous end point doesn't
    348337    // preserve whitespace.
    349     if (lBreak.obj && sNumMidpoints && sNumMidpoints % 2 == 0) {
    350         InlineIterator* midpoints = smidpoints->data();
    351         InlineIterator& endpoint = midpoints[sNumMidpoints-2];
    352         const InlineIterator& startpoint = midpoints[sNumMidpoints-1];
     338    if (lBreak.obj && lineMidpointState.m_numMidpoints && !(lineMidpointState.m_numMidpoints % 2)) {
     339        InlineIterator* midpoints = lineMidpointState.m_midpoints.data();
     340        InlineIterator& endpoint = midpoints[lineMidpointState.m_numMidpoints - 2];
     341        const InlineIterator& startpoint = midpoints[lineMidpointState.m_numMidpoints - 1];
    353342        InlineIterator currpoint = endpoint;
    354343        while (!currpoint.atEnd() && currpoint != startpoint && currpoint != lBreak)
     
    356345        if (currpoint == lBreak) {
    357346            // We hit the line break before the start point.  Shave off the start point.
    358             sNumMidpoints--;
     347            lineMidpointState.m_numMidpoints--;
    359348            if (endpoint.obj->style()->collapseWhiteSpace()) {
    360349                if (endpoint.obj->isText()) {
     
    376365}
    377366
    378 static void addMidpoint(const InlineIterator& midpoint)
    379 {
    380     if (smidpoints->size() <= sNumMidpoints)
    381         smidpoints->grow(sNumMidpoints + 10);
    382 
    383     InlineIterator* midpoints = smidpoints->data();
    384     midpoints[sNumMidpoints++] = midpoint;
     367static void addMidpoint(LineMidpointState& lineMidpointState, const InlineIterator& midpoint)
     368{
     369    if (lineMidpointState.m_midpoints.size() <= lineMidpointState.m_numMidpoints)
     370        lineMidpointState.m_midpoints.grow(lineMidpointState.m_numMidpoints + 10);
     371
     372    InlineIterator* midpoints = lineMidpointState.m_midpoints.data();
     373    midpoints[lineMidpointState.m_numMidpoints++] = midpoint;
    385374}
    386375
     
    391380        return;
    392381
    393     bool haveNextMidpoint = (sCurrMidpoint < sNumMidpoints);
     382    LineMidpointState& lineMidpointState = resolver.midpointState();
     383    bool haveNextMidpoint = (lineMidpointState.m_currentMidpoint < lineMidpointState.m_numMidpoints);
    394384    InlineIterator nextMidpoint;
    395385    if (haveNextMidpoint)
    396         nextMidpoint = smidpoints->at(sCurrMidpoint);
    397     if (betweenMidpoints) {
     386        nextMidpoint = lineMidpointState.m_midpoints[lineMidpointState.m_currentMidpoint];
     387    if (lineMidpointState.m_betweenMidpoints) {
    398388        if (!(haveNextMidpoint && nextMidpoint.obj == obj))
    399389            return;
    400390        // This is a new start point. Stop ignoring objects and
    401391        // adjust our start.
    402         betweenMidpoints = false;
     392        lineMidpointState.m_betweenMidpoints = false;
    403393        start = nextMidpoint.pos;
    404         sCurrMidpoint++;
     394        lineMidpointState.m_currentMidpoint++;
    405395        if (start < end)
    406396            return appendRunsForObject(start, end, obj, resolver);
     
    414404        // need to go ahead and append a run with our endpoint.
    415405        if (static_cast<int>(nextMidpoint.pos + 1) <= end) {
    416             betweenMidpoints = true;
    417             sCurrMidpoint++;
     406            lineMidpointState.m_betweenMidpoints = true;
     407            lineMidpointState.m_currentMidpoint++;
    418408            if (nextMidpoint.pos != UINT_MAX) { // UINT_MAX means stop at the object and don't include any of it.
    419409                if (static_cast<int>(nextMidpoint.pos + 1) > start)
     
    792782
    793783// collects one line of the paragraph and transforms it to visual order
    794 void RenderBlock::bidiReorderLine(InlineBidiResolver& resolver, const InlineIterator& end)
     784void RenderBlock::bidiReorderLine(InlineBidiResolver& resolver, const InlineIterator& end, bool previousLineBrokeCleanly)
    795785{
    796786    resolver.createBidiRunsForLine(end, style()->visuallyOrdered(), previousLineBrokeCleanly);
     
    875865        unsigned floatIndex;
    876866        bool firstLine = true;
    877         RootInlineBox* startLine = determineStartPosition(firstLine, fullLayout, resolver, floats, floatIndex);
     867        bool previousLineBrokeCleanly = true;
     868        RootInlineBox* startLine = determineStartPosition(firstLine, fullLayout, previousLineBrokeCleanly, resolver, floats, floatIndex);
    878869
    879870        if (fullLayout && !selfNeedsLayout()) {
     
    892883        FloatingObject* lastFloat = m_floatingObjects ? m_floatingObjects->last() : 0;
    893884
    894         if (!smidpoints)
    895             smidpoints = new Vector<InlineIterator>();
    896 
    897         sNumMidpoints = 0;
    898         sCurrMidpoint = 0;
     885        LineMidpointState& lineMidpointState = resolver.midpointState();
    899886
    900887        // We also find the first clean line and extract these lines.  We will add them back
     
    944931        int lastHeight = height();
    945932
     933        bool isLineEmpty = true;
     934
    946935        while (!end.atEnd()) {
    947936            // FIXME: Is this check necessary before the first iteration or can it be moved to the end?
     
    949938                break;
    950939
    951             betweenMidpoints = false;
     940            lineMidpointState.reset();
     941           
    952942            isLineEmpty = true;
    953943           
    954944            EClear clear = CNONE;
    955             end = findNextLineBreak(resolver, firstLine, &clear);
     945            end = findNextLineBreak(resolver, firstLine, isLineEmpty, previousLineBrokeCleanly, &clear);
    956946            if (resolver.position().atEnd()) {
    957947                resolver.deleteRuns();
     
    962952
    963953            if (!isLineEmpty) {
    964                 bidiReorderLine(resolver, end);
     954                bidiReorderLine(resolver, end, previousLineBrokeCleanly);
    965955                ASSERT(resolver.position() == end);
    966956
     
    10761066
    10771067            lastHeight = height();
    1078             sNumMidpoints = 0;
    1079             sCurrMidpoint = 0;
     1068            lineMidpointState.reset();
    10801069            resolver.setPosition(end);
    10811070        }
     
    11341123    }
    11351124
    1136     sNumMidpoints = 0;
    1137     sCurrMidpoint = 0;
    1138 
    11391125    // Now add in the bottom border/padding.
    11401126    setHeight(height() + toAdd);
     
    11551141}
    11561142
    1157 RootInlineBox* RenderBlock::determineStartPosition(bool& firstLine, bool& fullLayout, InlineBidiResolver& resolver, Vector<FloatWithRect>& floats, unsigned& numCleanFloats)
     1143RootInlineBox* RenderBlock::determineStartPosition(bool& firstLine, bool& fullLayout, bool& previousLineBrokeCleanly,
     1144                                                   InlineBidiResolver& resolver, Vector<FloatWithRect>& floats, unsigned& numCleanFloats)
    11581145{
    11591146    RootInlineBox* curr = 0;
     
    13861373}
    13871374
    1388 static inline bool skipNonBreakingSpace(const InlineIterator& it)
     1375static inline bool skipNonBreakingSpace(const InlineIterator& it, bool isLineEmpty, bool previousLineBrokeCleanly)
    13891376{
    13901377    if (it.obj->style()->nbspMode() != SPACE || it.current() != noBreakSpace)
     
    14021389}
    14031390
    1404 static inline bool shouldCollapseWhiteSpace(const RenderStyle* style)
     1391static inline bool shouldCollapseWhiteSpace(const RenderStyle* style, bool isLineEmpty, bool previousLineBrokeCleanly)
    14051392{
    14061393    return style->collapseWhiteSpace() || (style->whiteSpace() == PRE_WRAP && (!isLineEmpty || !previousLineBrokeCleanly));
     
    14251412}
    14261413
    1427 static inline bool requiresLineBox(const InlineIterator& it)
     1414static inline bool requiresLineBox(const InlineIterator& it, bool isLineEmpty, bool previousLineBrokeCleanly)
    14281415{
    14291416    if (it.obj->isFloatingOrPositioned())
     
    14331420        return false;
    14341421
    1435     if (!shouldCollapseWhiteSpace(it.obj->style()) || it.obj->isBR())
     1422    if (!shouldCollapseWhiteSpace(it.obj->style(), isLineEmpty, previousLineBrokeCleanly) || it.obj->isBR())
    14361423        return true;
    14371424
    14381425    UChar current = it.current();
    1439     return current != ' ' && current != '\t' && current != softHyphen && (current != '\n' || shouldPreserveNewline(it.obj)) && !skipNonBreakingSpace(it);
    1440 }
    1441 
    1442 bool RenderBlock::generatesLineBoxesForInlineChild(RenderObject* inlineObj)
     1426    return current != ' ' && current != '\t' && current != softHyphen && (current != '\n' || shouldPreserveNewline(it.obj))
     1427            && !skipNonBreakingSpace(it, isLineEmpty, previousLineBrokeCleanly);
     1428}
     1429
     1430bool RenderBlock::generatesLineBoxesForInlineChild(RenderObject* inlineObj, bool isLineEmpty, bool previousLineBrokeCleanly)
    14431431{
    14441432    ASSERT(inlineObj->parent() == this);
    14451433
    14461434    InlineIterator it(this, inlineObj, 0);
    1447     while (!it.atEnd() && !requiresLineBox(it))
     1435    while (!it.atEnd() && !requiresLineBox(it, isLineEmpty, previousLineBrokeCleanly))
    14481436        it.increment();
    14491437
     
    14571445// NB. this function will insert any floating elements that would otherwise
    14581446// be skipped but it will not position them.
    1459 void RenderBlock::skipTrailingWhitespace(InlineIterator& iterator)
    1460 {
    1461     while (!iterator.atEnd() && !requiresLineBox(iterator)) {
     1447void RenderBlock::skipTrailingWhitespace(InlineIterator& iterator, bool isLineEmpty, bool previousLineBrokeCleanly)
     1448{
     1449    while (!iterator.atEnd() && !requiresLineBox(iterator, isLineEmpty, previousLineBrokeCleanly)) {
    14621450        RenderObject* object = iterator.obj;
    14631451        if (object->isFloating()) {
     
    14901478}
    14911479
    1492 int RenderBlock::skipLeadingWhitespace(InlineBidiResolver& resolver, bool firstLine)
     1480int RenderBlock::skipLeadingWhitespace(InlineBidiResolver& resolver, bool firstLine, bool isLineEmpty, bool previousLineBrokeCleanly)
    14931481{
    14941482    int availableWidth = lineWidth(height(), firstLine);
    1495     while (!resolver.position().atEnd() && !requiresLineBox(resolver.position())) {
     1483    while (!resolver.position().atEnd() && !requiresLineBox(resolver.position(), isLineEmpty, previousLineBrokeCleanly)) {
    14961484        RenderObject* object = resolver.position().obj;
    14971485        if (object->isFloating()) {
     
    15301518// This is currently just used for list markers and inline flows that have line boxes. Neither should
    15311519// have an effect on whitespace at the start of the line.
    1532 static bool shouldSkipWhitespaceAfterStartObject(RenderBlock* block, RenderObject* o)
     1520static bool shouldSkipWhitespaceAfterStartObject(RenderBlock* block, RenderObject* o, LineMidpointState& lineMidpointState)
    15331521{
    15341522    RenderObject* next = bidiNext(block, o);
     
    15371525        UChar nextChar = nextText->characters()[0];
    15381526        if (nextText->style()->isCollapsibleWhiteSpace(nextChar)) {
    1539             addMidpoint(InlineIterator(0, o, 0));
     1527            addMidpoint(lineMidpointState, InlineIterator(0, o, 0));
    15401528            return true;
    15411529        }
     
    15761564}
    15771565
    1578 InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool firstLine, EClear* clear)
     1566InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool firstLine,  bool& isLineEmpty, bool& previousLineBrokeCleanly,
     1567                                              EClear* clear)
    15791568{
    15801569    ASSERT(resolver.position().block == this);
    15811570
    15821571    bool appliedStartWidth = resolver.position().pos > 0;
    1583 
    1584     int width = skipLeadingWhitespace(resolver, firstLine);
     1572    LineMidpointState& lineMidpointState = resolver.midpointState();
     1573   
     1574    int width = skipLeadingWhitespace(resolver, firstLine, isLineEmpty, previousLineBrokeCleanly);
    15851575
    15861576    int w = 0;
     
    17071697                    ignoreStart.pos = 0;
    17081698                    if (ignoringSpaces) {
    1709                         addMidpoint(ignoreStart); // Stop ignoring spaces.
    1710                         addMidpoint(ignoreStart); // Start ignoring again.
     1699                        addMidpoint(lineMidpointState, ignoreStart); // Stop ignoring spaces.
     1700                        addMidpoint(lineMidpointState, ignoreStart); // Start ignoring again.
    17111701                    }
    17121702                   
     
    17271717                if (ignoringSpaces) {
    17281718                    trailingSpaceObject = 0;
    1729                     addMidpoint(InlineIterator(0, o, 0)); // Stop ignoring spaces.
    1730                     addMidpoint(InlineIterator(0, o, 0)); // Start ignoring again.
     1719                    addMidpoint(lineMidpointState, InlineIterator(0, o, 0)); // Stop ignoring spaces.
     1720                    addMidpoint(lineMidpointState, InlineIterator(0, o, 0)); // Start ignoring again.
    17311721                } else if (style()->collapseWhiteSpace() && resolver.position().obj == o
    1732                     && shouldSkipWhitespaceAfterStartObject(this, o)) {
     1722                    && shouldSkipWhitespaceAfterStartObject(this, o, lineMidpointState)) {
    17331723                    // Like with list markers, we start ignoring spaces to make sure that any
    17341724                    // additional spaces we see will be discarded.
     
    17541744
    17551745            if (ignoringSpaces)
    1756                 addMidpoint(InlineIterator(0, o, 0));
     1746                addMidpoint(lineMidpointState, InlineIterator(0, o, 0));
    17571747
    17581748            isLineEmpty = false;
     
    17651755            // item, then this is all moot. -dwh
    17661756            if (o->isListMarker() && !static_cast<RenderListMarker*>(o)->isInside()) {
    1767                 if (style()->collapseWhiteSpace() && shouldSkipWhitespaceAfterStartObject(this, o)) {
     1757                if (style()->collapseWhiteSpace() && shouldSkipWhitespaceAfterStartObject(this, o, lineMidpointState)) {
    17681758                    // Like with inline flows, we start ignoring spaces to make sure that any
    17691759                    // additional spaces we see will be discarded.
     
    18281818                            beforeSoftHyphen = InlineIterator(0, last, last->isText() ? toRenderText(last)->textLength() - 1 : 0);
    18291819                        // Two consecutive soft hyphens. Avoid overlapping midpoints.
    1830                         if (sNumMidpoints && smidpoints->at(sNumMidpoints - 1).obj == o && smidpoints->at(sNumMidpoints - 1).pos == pos)
    1831                             sNumMidpoints--;
     1820                        if (lineMidpointState.m_numMidpoints && lineMidpointState.m_midpoints[lineMidpointState.m_numMidpoints - 1].obj == o &&
     1821                            lineMidpointState.m_midpoints[lineMidpointState.m_numMidpoints - 1].pos == pos)
     1822                            lineMidpointState.m_numMidpoints--;
    18321823                        else
    1833                             addMidpoint(beforeSoftHyphen);
     1824                            addMidpoint(lineMidpointState, beforeSoftHyphen);
    18341825
    18351826                        // Add the width up to but not including the hyphen.
     
    18431834                        InlineIterator afterSoftHyphen(0, o, pos);
    18441835                        afterSoftHyphen.increment();
    1845                         addMidpoint(afterSoftHyphen);
     1836                        addMidpoint(lineMidpointState, afterSoftHyphen);
    18461837                    }
    18471838
     
    18741865                            lastSpaceWordSpacing = 0;
    18751866                            lastSpace = pos; // e.g., "Foo    goo", don't add in any of the ignored spaces.
    1876                             addMidpoint(InlineIterator(0, o, pos));
     1867                            addMidpoint(lineMidpointState, InlineIterator(0, o, pos));
    18771868                            stoppedIgnoringSpaces = true;
    18781869                        } else {
     
    19121903                                lBreak.pos = pos;
    19131904                                lBreak.nextBreakablePosition = nextBreakable;
    1914                                 skipTrailingWhitespace(lBreak);
     1905                                skipTrailingWhitespace(lBreak, isLineEmpty, previousLineBrokeCleanly);
    19151906                            }
    19161907                        }
     
    19191910                                if (!stoppedIgnoringSpaces && pos > 0) {
    19201911                                    // We need to stop right before the newline and then start up again.
    1921                                     addMidpoint(InlineIterator(0, o, pos - 1)); // Stop
    1922                                     addMidpoint(InlineIterator(0, o, pos)); // Start
     1912                                    addMidpoint(lineMidpointState, InlineIterator(0, o, pos - 1)); // Stop
     1913                                    addMidpoint(lineMidpointState, InlineIterator(0, o, pos)); // Start
    19231914                                }
    19241915                                lBreak.increment();
     
    19381929                        if (!stoppedIgnoringSpaces && pos > 0) {
    19391930                            // We need to stop right before the newline and then start up again.
    1940                             addMidpoint(InlineIterator(0, o, pos - 1)); // Stop
    1941                             addMidpoint(InlineIterator(0, o, pos)); // Start
     1931                            addMidpoint(lineMidpointState, InlineIterator(0, o, pos - 1)); // Stop
     1932                            addMidpoint(lineMidpointState, InlineIterator(0, o, pos)); // Start
    19421933                        }
    19431934                        lBreak.obj = o;
     
    19851976                            // spaces. Create a midpoint to terminate the run
    19861977                            // before the second space.
    1987                             addMidpoint(ignoreStart);
     1978                            addMidpoint(lineMidpointState, ignoreStart);
    19881979                        }
    19891980                    }
     
    19941985                    lastSpaceWordSpacing = applyWordSpacing ? wordSpacing : 0;
    19951986                    lastSpace = pos; // e.g., "Foo    goo", don't add in any of the ignored spaces.
    1996                     addMidpoint(InlineIterator(0, o, pos));
     1987                    addMidpoint(lineMidpointState, InlineIterator(0, o, pos));
    19971988                }
    19981989
     
    21462137
    21472138    // Sanity check our midpoints.
    2148     checkMidpoints(lBreak);
     2139    checkMidpoints(lineMidpointState, lBreak);
    21492140       
    21502141    if (trailingSpaceObject) {
     
    21522143        // to be the actual endpoint.  In both cases we just decrease our pos by 1 level to
    21532144        // exclude the space, allowing it to - in effect - collapse into the newline.
    2154         if (sNumMidpoints%2==1) {
    2155             InlineIterator* midpoints = smidpoints->data();
    2156             midpoints[sNumMidpoints-1].pos--;
     2145        if (lineMidpointState.m_numMidpoints % 2) {
     2146            InlineIterator* midpoints = lineMidpointState.m_midpoints.data();
     2147            midpoints[lineMidpointState.m_numMidpoints - 1].pos--;
    21572148        }
    21582149        //else if (lBreak.pos > 0)
     
    21642155            unsigned pos = length >= 2 ? length - 2 : UINT_MAX;
    21652156            InlineIterator endMid(0, trailingSpaceObject, pos);
    2166             addMidpoint(endMid);
     2157            addMidpoint(lineMidpointState, endMid);
    21672158        }
    21682159    }
     
    21802171        // For soft hyphens on line breaks, we have to chop out the midpoints that made us
    21812172        // ignore the hyphen so that it will render at the end of the line.
    2182         UChar c = toRenderText(lBreak.obj)->characters()[lBreak.pos-1];
     2173        UChar c = toRenderText(lBreak.obj)->characters()[lBreak.pos - 1];
    21832174        if (c == softHyphen)
    2184             chopMidpointsAt(lBreak.obj, lBreak.pos-2);
     2175            chopMidpointsAt(lineMidpointState, lBreak.obj, lBreak.pos - 2);
    21852176    }
    21862177   
Note: See TracChangeset for help on using the changeset viewer.