summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform/text/BidiRunList.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/platform/text/BidiRunList.h')
-rw-r--r--Source/WebCore/platform/text/BidiRunList.h209
1 files changed, 209 insertions, 0 deletions
diff --git a/Source/WebCore/platform/text/BidiRunList.h b/Source/WebCore/platform/text/BidiRunList.h
new file mode 100644
index 0000000..a4aa3c2
--- /dev/null
+++ b/Source/WebCore/platform/text/BidiRunList.h
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2003, 2004, 2006, 2007, 2008 Apple Inc. All right reserved.
+ * Copyright (C) 2011 Google, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BidiRunList_h
+#define BidiRunList_h
+
+#include <wtf/Noncopyable.h>
+
+namespace WebCore {
+
+template <class Run>
+class BidiRunList {
+ WTF_MAKE_NONCOPYABLE(BidiRunList);
+public:
+ BidiRunList()
+ : m_firstRun(0)
+ , m_lastRun(0)
+ , m_logicallyLastRun(0)
+ , m_runCount(0)
+ {
+ }
+
+ // FIXME: Once BidiResolver no longer owns the BidiRunList,
+ // then ~BidiRunList should call deleteRuns() automatically.
+
+ Run* firstRun() const { return m_firstRun; }
+ Run* lastRun() const { return m_lastRun; }
+ Run* logicallyLastRun() const { return m_logicallyLastRun; }
+ unsigned runCount() const { return m_runCount; }
+
+ void addRun(Run*);
+ void prependRun(Run*);
+
+ void moveRunToEnd(Run*);
+ void moveRunToBeginning(Run*);
+
+ void deleteRuns();
+ void reverseRuns(unsigned start, unsigned end);
+ void reorderRunsFromLevels();
+
+ void setLogicallyLastRun(Run* run) { m_logicallyLastRun = run; }
+
+private:
+ Run* m_firstRun;
+ Run* m_lastRun;
+ Run* m_logicallyLastRun;
+ unsigned m_runCount;
+};
+
+template <class Run>
+inline void BidiRunList<Run>::addRun(Run* run)
+{
+ if (!m_firstRun)
+ m_firstRun = run;
+ else
+ m_lastRun->m_next = run;
+ m_lastRun = run;
+ m_runCount++;
+}
+
+template <class Run>
+inline void BidiRunList<Run>::prependRun(Run* run)
+{
+ ASSERT(!run->m_next);
+
+ if (!m_lastRun)
+ m_lastRun = run;
+ else
+ run->m_next = m_firstRun;
+ m_firstRun = run;
+ m_runCount++;
+}
+
+template <class Run>
+inline void BidiRunList<Run>::moveRunToEnd(Run* run)
+{
+ ASSERT(m_firstRun);
+ ASSERT(m_lastRun);
+ ASSERT(run->m_next);
+
+ Run* current = 0;
+ Run* next = m_firstRun;
+ while (next != run) {
+ current = next;
+ next = current->next();
+ }
+
+ if (!current)
+ m_firstRun = run->next();
+ else
+ current->m_next = run->m_next;
+
+ run->m_next = 0;
+ m_lastRun->m_next = run;
+ m_lastRun = run;
+}
+
+template <class Run>
+inline void BidiRunList<Run>::moveRunToBeginning(Run* run)
+{
+ ASSERT(m_firstRun);
+ ASSERT(m_lastRun);
+ ASSERT(run != m_firstRun);
+
+ Run* current = m_firstRun;
+ Run* next = current->next();
+ while (next != run) {
+ current = next;
+ next = current->next();
+ }
+
+ current->m_next = run->m_next;
+ if (run == m_lastRun)
+ m_lastRun = current;
+
+ run->m_next = m_firstRun;
+ m_firstRun = run;
+}
+
+template <class Run>
+void BidiRunList<Run>::deleteRuns()
+{
+ if (!m_firstRun)
+ return;
+
+ Run* curr = m_firstRun;
+ while (curr) {
+ Run* s = curr->next();
+ curr->destroy();
+ curr = s;
+ }
+
+ m_firstRun = 0;
+ m_lastRun = 0;
+ m_runCount = 0;
+}
+
+template <class Run>
+void BidiRunList<Run>::reverseRuns(unsigned start, unsigned end)
+{
+ if (start >= end)
+ return;
+
+ ASSERT(end < m_runCount);
+
+ // Get the item before the start of the runs to reverse and put it in
+ // |beforeStart|. |curr| should point to the first run to reverse.
+ Run* curr = m_firstRun;
+ Run* beforeStart = 0;
+ unsigned i = 0;
+ while (i < start) {
+ i++;
+ beforeStart = curr;
+ curr = curr->next();
+ }
+
+ Run* startRun = curr;
+ while (i < end) {
+ i++;
+ curr = curr->next();
+ }
+ Run* endRun = curr;
+ Run* afterEnd = curr->next();
+
+ i = start;
+ curr = startRun;
+ Run* newNext = afterEnd;
+ while (i <= end) {
+ // Do the reversal.
+ Run* next = curr->next();
+ curr->m_next = newNext;
+ newNext = curr;
+ curr = next;
+ i++;
+ }
+
+ // Now hook up beforeStart and afterEnd to the startRun and endRun.
+ if (beforeStart)
+ beforeStart->m_next = endRun;
+ else
+ m_firstRun = endRun;
+
+ startRun->m_next = afterEnd;
+ if (!afterEnd)
+ m_lastRun = startRun;
+}
+
+} // namespace WebCore
+
+#endif // BidiRunList