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)
261e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "wtf/Assertions.h"
277757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "wtf/Noncopyable.h"
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
29c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <class Run>
325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class BidiRunList {
335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    WTF_MAKE_NONCOPYABLE(BidiRunList);
345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    BidiRunList()
365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        : m_firstRun(0)
375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_lastRun(0)
385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_logicallyLastRun(0)
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_runCount(0)
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: Once BidiResolver no longer owns the BidiRunList,
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // then ~BidiRunList should call deleteRuns() automatically.
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Run* firstRun() const { return m_firstRun; }
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Run* lastRun() const { return m_lastRun; }
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Run* logicallyLastRun() const { return m_logicallyLastRun; }
495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned runCount() const { return m_runCount; }
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void addRun(Run*);
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void prependRun(Run*);
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void moveRunToEnd(Run*);
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void moveRunToBeginning(Run*);
565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void deleteRuns();
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void reverseRuns(unsigned start, unsigned end);
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void reorderRunsFromLevels();
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setLogicallyLastRun(Run* run) { m_logicallyLastRun = run; }
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void replaceRunWithRuns(Run* toReplace, BidiRunList<Run>& newRuns);
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private:
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void clearWithoutDestroyingRuns();
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Run* m_firstRun;
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Run* m_lastRun;
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Run* m_logicallyLastRun;
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned m_runCount;
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <class Run>
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline void BidiRunList<Run>::addRun(Run* run)
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_firstRun)
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_firstRun = run;
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_lastRun->m_next = run;
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_lastRun = run;
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_runCount++;
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <class Run>
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline void BidiRunList<Run>::prependRun(Run* run)
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!run->m_next);
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_lastRun)
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_lastRun = run;
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        run->m_next = m_firstRun;
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_firstRun = run;
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_runCount++;
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <class Run>
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline void BidiRunList<Run>::moveRunToEnd(Run* run)
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(m_firstRun);
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(m_lastRun);
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(run->m_next);
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Run* current = 0;
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Run* next = m_firstRun;
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (next != run) {
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        current = next;
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        next = current->next();
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!current)
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_firstRun = run->next();
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        current->m_next = run->m_next;
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    run->m_next = 0;
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_lastRun->m_next = run;
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_lastRun = run;
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <class Run>
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline void BidiRunList<Run>::moveRunToBeginning(Run* run)
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(m_firstRun);
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(m_lastRun);
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(run != m_firstRun);
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Run* current = m_firstRun;
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Run* next = current->next();
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (next != run) {
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        current = next;
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        next = current->next();
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    current->m_next = run->m_next;
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (run == m_lastRun)
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_lastRun = current;
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    run->m_next = m_firstRun;
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_firstRun = run;
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <class Run>
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void BidiRunList<Run>::replaceRunWithRuns(Run* toReplace, BidiRunList<Run>& newRuns)
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(newRuns.runCount());
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(m_firstRun);
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(toReplace);
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1511e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (m_firstRun == toReplace) {
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_firstRun = newRuns.firstRun();
1531e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    } else {
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Find the run just before "toReplace" in the list of runs.
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Run* previousRun = m_firstRun;
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        while (previousRun->next() != toReplace)
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            previousRun = previousRun->next();
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(previousRun);
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        previousRun->setNext(newRuns.firstRun());
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    newRuns.lastRun()->setNext(toReplace->next());
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Fix up any of other pointers which may now be stale.
1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_lastRun == toReplace)
1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_lastRun = newRuns.lastRun();
1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_logicallyLastRun == toReplace)
1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_logicallyLastRun = newRuns.logicallyLastRun();
1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_runCount += newRuns.runCount() - 1; // We added the new runs and removed toReplace.
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
171f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    delete toReplace;
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    newRuns.clearWithoutDestroyingRuns();
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <class Run>
1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void BidiRunList<Run>::clearWithoutDestroyingRuns()
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_firstRun = 0;
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_lastRun = 0;
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_logicallyLastRun = 0;
1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_runCount = 0;
1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <class Run>
1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void BidiRunList<Run>::deleteRuns()
1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_firstRun)
1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Run* curr = m_firstRun;
1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (curr) {
1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Run* s = curr->next();
193f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        delete curr;
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        curr = s;
1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
197d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    clearWithoutDestroyingRuns();
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <class Run>
2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void BidiRunList<Run>::reverseRuns(unsigned start, unsigned end)
2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
20351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ASSERT(m_runCount);
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)
251c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif // BidiRunList
254