PageRenderTime 50ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/webview/native/Source/WebCore/platform/text/BidiRunList.h

https://bitbucket.org/rbair/rbair-controls-8
C++ Header | 253 lines | 182 code | 42 blank | 29 comment | 27 complexity | 41d1e4a9fffc5355b520a0b6cd9cc2a0 MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-2.1, GPL-2.0, LGPL-2.0
  1. /*
  2. * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
  3. * Copyright (C) 2003, 2004, 2006, 2007, 2008 Apple Inc. All right reserved.
  4. * Copyright (C) 2011 Google, Inc. All rights reserved.
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Library General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Library General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Library General Public License
  17. * along with this library; see the file COPYING.LIB. If not, write to
  18. * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  19. * Boston, MA 02110-1301, USA.
  20. *
  21. */
  22. #ifndef BidiRunList_h
  23. #define BidiRunList_h
  24. #include <wtf/Noncopyable.h>
  25. namespace WebCore {
  26. template <class Run>
  27. class BidiRunList {
  28. WTF_MAKE_NONCOPYABLE(BidiRunList);
  29. public:
  30. BidiRunList()
  31. : m_firstRun(0)
  32. , m_lastRun(0)
  33. , m_logicallyLastRun(0)
  34. , m_runCount(0)
  35. {
  36. }
  37. // FIXME: Once BidiResolver no longer owns the BidiRunList,
  38. // then ~BidiRunList should call deleteRuns() automatically.
  39. Run* firstRun() const { return m_firstRun; }
  40. Run* lastRun() const { return m_lastRun; }
  41. Run* logicallyLastRun() const { return m_logicallyLastRun; }
  42. unsigned runCount() const { return m_runCount; }
  43. void addRun(Run*);
  44. void prependRun(Run*);
  45. void moveRunToEnd(Run*);
  46. void moveRunToBeginning(Run*);
  47. void deleteRuns();
  48. void reverseRuns(unsigned start, unsigned end);
  49. void reorderRunsFromLevels();
  50. void setLogicallyLastRun(Run* run) { m_logicallyLastRun = run; }
  51. void replaceRunWithRuns(Run* toReplace, BidiRunList<Run>& newRuns);
  52. private:
  53. void clearWithoutDestroyingRuns();
  54. Run* m_firstRun;
  55. Run* m_lastRun;
  56. Run* m_logicallyLastRun;
  57. unsigned m_runCount;
  58. };
  59. template <class Run>
  60. inline void BidiRunList<Run>::addRun(Run* run)
  61. {
  62. if (!m_firstRun)
  63. m_firstRun = run;
  64. else
  65. m_lastRun->m_next = run;
  66. m_lastRun = run;
  67. m_runCount++;
  68. }
  69. template <class Run>
  70. inline void BidiRunList<Run>::prependRun(Run* run)
  71. {
  72. ASSERT(!run->m_next);
  73. if (!m_lastRun)
  74. m_lastRun = run;
  75. else
  76. run->m_next = m_firstRun;
  77. m_firstRun = run;
  78. m_runCount++;
  79. }
  80. template <class Run>
  81. inline void BidiRunList<Run>::moveRunToEnd(Run* run)
  82. {
  83. ASSERT(m_firstRun);
  84. ASSERT(m_lastRun);
  85. ASSERT(run->m_next);
  86. Run* current = 0;
  87. Run* next = m_firstRun;
  88. while (next != run) {
  89. current = next;
  90. next = current->next();
  91. }
  92. if (!current)
  93. m_firstRun = run->next();
  94. else
  95. current->m_next = run->m_next;
  96. run->m_next = 0;
  97. m_lastRun->m_next = run;
  98. m_lastRun = run;
  99. }
  100. template <class Run>
  101. inline void BidiRunList<Run>::moveRunToBeginning(Run* run)
  102. {
  103. ASSERT(m_firstRun);
  104. ASSERT(m_lastRun);
  105. ASSERT(run != m_firstRun);
  106. Run* current = m_firstRun;
  107. Run* next = current->next();
  108. while (next != run) {
  109. current = next;
  110. next = current->next();
  111. }
  112. current->m_next = run->m_next;
  113. if (run == m_lastRun)
  114. m_lastRun = current;
  115. run->m_next = m_firstRun;
  116. m_firstRun = run;
  117. }
  118. template <class Run>
  119. void BidiRunList<Run>::replaceRunWithRuns(Run* toReplace, BidiRunList<Run>& newRuns)
  120. {
  121. ASSERT(newRuns.runCount());
  122. ASSERT(m_firstRun);
  123. ASSERT(toReplace);
  124. if (m_firstRun == toReplace)
  125. m_firstRun = newRuns.firstRun();
  126. else {
  127. // Find the run just before "toReplace" in the list of runs.
  128. Run* previousRun = m_firstRun;
  129. while (previousRun->next() != toReplace)
  130. previousRun = previousRun->next();
  131. ASSERT(previousRun);
  132. previousRun->setNext(newRuns.firstRun());
  133. }
  134. newRuns.lastRun()->setNext(toReplace->next());
  135. // Fix up any of other pointers which may now be stale.
  136. if (m_lastRun == toReplace)
  137. m_lastRun = newRuns.lastRun();
  138. if (m_logicallyLastRun == toReplace)
  139. m_logicallyLastRun = newRuns.logicallyLastRun();
  140. m_runCount += newRuns.runCount() - 1; // We added the new runs and removed toReplace.
  141. toReplace->destroy();
  142. newRuns.clearWithoutDestroyingRuns();
  143. }
  144. template <class Run>
  145. void BidiRunList<Run>::clearWithoutDestroyingRuns()
  146. {
  147. m_firstRun = 0;
  148. m_lastRun = 0;
  149. m_logicallyLastRun = 0;
  150. m_runCount = 0;
  151. }
  152. template <class Run>
  153. void BidiRunList<Run>::deleteRuns()
  154. {
  155. if (!m_firstRun)
  156. return;
  157. Run* curr = m_firstRun;
  158. while (curr) {
  159. Run* s = curr->next();
  160. curr->destroy();
  161. curr = s;
  162. }
  163. m_firstRun = 0;
  164. m_lastRun = 0;
  165. m_runCount = 0;
  166. }
  167. template <class Run>
  168. void BidiRunList<Run>::reverseRuns(unsigned start, unsigned end)
  169. {
  170. if (start >= end)
  171. return;
  172. ASSERT(end < m_runCount);
  173. // Get the item before the start of the runs to reverse and put it in
  174. // |beforeStart|. |curr| should point to the first run to reverse.
  175. Run* curr = m_firstRun;
  176. Run* beforeStart = 0;
  177. unsigned i = 0;
  178. while (i < start) {
  179. i++;
  180. beforeStart = curr;
  181. curr = curr->next();
  182. }
  183. Run* startRun = curr;
  184. while (i < end) {
  185. i++;
  186. curr = curr->next();
  187. }
  188. Run* endRun = curr;
  189. Run* afterEnd = curr->next();
  190. i = start;
  191. curr = startRun;
  192. Run* newNext = afterEnd;
  193. while (i <= end) {
  194. // Do the reversal.
  195. Run* next = curr->next();
  196. curr->m_next = newNext;
  197. newNext = curr;
  198. curr = next;
  199. i++;
  200. }
  201. // Now hook up beforeStart and afterEnd to the startRun and endRun.
  202. if (beforeStart)
  203. beforeStart->m_next = endRun;
  204. else
  205. m_firstRun = endRun;
  206. startRun->m_next = afterEnd;
  207. if (!afterEnd)
  208. m_lastRun = startRun;
  209. }
  210. } // namespace WebCore
  211. #endif // BidiRunList