15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2003, 2004, 2006, 2007, 2008 Apple Inc.  All right reserved.
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2011 Google, Inc.  All rights reserved.
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version.
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful,
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details.
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB.  If not, write to
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA.
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef BidiRunList_h
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define BidiRunList_h
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
267757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "wtf/Noncopyable.h"
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore {
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <class Run>
315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class BidiRunList {
325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    WTF_MAKE_NONCOPYABLE(BidiRunList);
335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    BidiRunList()
355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        : m_firstRun(0)
365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_lastRun(0)
375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_logicallyLastRun(0)
385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_runCount(0)
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: Once BidiResolver no longer owns the BidiRunList,
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // then ~BidiRunList should call deleteRuns() automatically.
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Run* firstRun() const { return m_firstRun; }
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Run* lastRun() const { return m_lastRun; }
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Run* logicallyLastRun() const { return m_logicallyLastRun; }
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned runCount() const { return m_runCount; }
495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void addRun(Run*);
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void prependRun(Run*);
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void moveRunToEnd(Run*);
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void moveRunToBeginning(Run*);
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void deleteRuns();
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void reverseRuns(unsigned start, unsigned end);
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void reorderRunsFromLevels();
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setLogicallyLastRun(Run* run) { m_logicallyLastRun = run; }
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void replaceRunWithRuns(Run* toReplace, BidiRunList<Run>& newRuns);
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private:
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void clearWithoutDestroyingRuns();
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Run* m_firstRun;
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Run* m_lastRun;
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Run* m_logicallyLastRun;
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned m_runCount;
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <class Run>
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline void BidiRunList<Run>::addRun(Run* run)
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_firstRun)
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_firstRun = run;
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_lastRun->m_next = run;
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_lastRun = run;
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_runCount++;
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <class Run>
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline void BidiRunList<Run>::prependRun(Run* run)
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!run->m_next);
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_lastRun)
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_lastRun = run;
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        run->m_next = m_firstRun;
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_firstRun = run;
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_runCount++;
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <class Run>
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline void BidiRunList<Run>::moveRunToEnd(Run* run)
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(m_firstRun);
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(m_lastRun);
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(run->m_next);
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Run* current = 0;
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Run* next = m_firstRun;
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (next != run) {
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        current = next;
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        next = current->next();
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!current)
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_firstRun = run->next();
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        current->m_next = run->m_next;
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    run->m_next = 0;
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_lastRun->m_next = run;
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_lastRun = run;
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <class Run>
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline void BidiRunList<Run>::moveRunToBeginning(Run* run)
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(m_firstRun);
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(m_lastRun);
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(run != m_firstRun);
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Run* current = m_firstRun;
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Run* next = current->next();
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (next != run) {
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        current = next;
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        next = current->next();
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    current->m_next = run->m_next;
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (run == m_lastRun)
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_lastRun = current;
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    run->m_next = m_firstRun;
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_firstRun = run;
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <class Run>
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void BidiRunList<Run>::replaceRunWithRuns(Run* toReplace, BidiRunList<Run>& newRuns)
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(newRuns.runCount());
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(m_firstRun);
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(toReplace);
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_firstRun == toReplace)
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_firstRun = newRuns.firstRun();
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else {
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Find the run just before "toReplace" in the list of runs.
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Run* previousRun = m_firstRun;
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        while (previousRun->next() != toReplace)
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            previousRun = previousRun->next();
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(previousRun);
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        previousRun->setNext(newRuns.firstRun());
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    newRuns.lastRun()->setNext(toReplace->next());
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Fix up any of other pointers which may now be stale.
1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_lastRun == toReplace)
1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_lastRun = newRuns.lastRun();
1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_logicallyLastRun == toReplace)
1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_logicallyLastRun = newRuns.logicallyLastRun();
1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_runCount += newRuns.runCount() - 1; // We added the new runs and removed toReplace.
1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
170f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    delete toReplace;
1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    newRuns.clearWithoutDestroyingRuns();
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <class Run>
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void BidiRunList<Run>::clearWithoutDestroyingRuns()
1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_firstRun = 0;
1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_lastRun = 0;
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_logicallyLastRun = 0;
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_runCount = 0;
1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <class Run>
1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void BidiRunList<Run>::deleteRuns()
1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_firstRun)
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Run* curr = m_firstRun;
1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (curr) {
1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Run* s = curr->next();
192f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        delete curr;
1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        curr = s;
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_firstRun = 0;
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_lastRun = 0;
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_runCount = 0;
1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <class Run>
2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void BidiRunList<Run>::reverseRuns(unsigned start, unsigned end)
2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (start >= end)
2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(end < m_runCount);
2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Get the item before the start of the runs to reverse and put it in
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // |beforeStart|. |curr| should point to the first run to reverse.
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Run* curr = m_firstRun;
2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Run* beforeStart = 0;
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned i = 0;
2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (i < start) {
2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        i++;
2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        beforeStart = curr;
2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        curr = curr->next();
2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Run* startRun = curr;
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (i < end) {
2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        i++;
2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        curr = curr->next();
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Run* endRun = curr;
2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Run* afterEnd = curr->next();
2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    i = start;
2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    curr = startRun;
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Run* newNext = afterEnd;
2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (i <= end) {
2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Do the reversal.
2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Run* next = curr->next();
2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        curr->m_next = newNext;
2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        newNext = curr;
2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        curr = next;
2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        i++;
2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Now hook up beforeStart and afterEnd to the startRun and endRun.
2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (beforeStart)
2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        beforeStart->m_next = endRun;
2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else
2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_firstRun = endRun;
2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    startRun->m_next = afterEnd;
2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!afterEnd)
2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_lastRun = startRun;
2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WebCore
2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif // BidiRunList
254