Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

226 lines
7.1 KiB

  1. /*
  2. * @doc INTERNAL
  3. *
  4. * @module _RUNPTR.H -- Text run and run pointer class defintion |
  5. *
  6. * Original Author: <nl>
  7. * Christian Fortini
  8. *
  9. * History: <nl>
  10. * 6/25/95 alexgo Commenting and Cleanup
  11. *
  12. * Copyright (c) 1995-1997 Microsoft Corporation. All rights reserved.
  13. */
  14. #ifndef _RUNPTR_H
  15. #define _RUNPTR_H
  16. #include "_array.h"
  17. #include "_doc.h"
  18. typedef CArray<CTxtRun> CRunArray;
  19. /*
  20. * CRunPtrBase
  21. *
  22. * @class Base run pointer functionality. Keeps a position within an array
  23. * of text runs.
  24. *
  25. * @devnote Run pointers go through three different possible states :
  26. *
  27. * NULL: there is no data and no array (frequently a startup condition) <nl>
  28. * <mf CRunPtrBase::SetRunArray> will transition from this state to
  29. * the Empty state. It is typically up to the derived class to
  30. * define when that method should be called. IsValid() fails. <nl>
  31. *
  32. * <md CRunPtrBase::_pRuns> == NULL <nl>
  33. * <md CRunPtrBase::_iRun> == 0 <nl>
  34. * <md CRunPtrBase::_ich> == 0 <nl>
  35. *
  36. * Empty: an array class exists, but there is no data (can happen if all
  37. * of the elements in the array are deleted). IsValid() fails.<nl>
  38. * <md CRunPtrBase::_pRuns> != NULL <nl>
  39. * <md CRunPtrBase::_iRun> == 0 <nl>
  40. * <md CRunPtrBase::_ich> <gt>= 0 <nl>
  41. * <md CRunPtrBase::_pRuns-<gt>Count()> == 0 <nl>
  42. *
  43. * Normal: the array class exists and has data; IsValid() succeeds and
  44. * <md CRunPtrBase::_pRuns-<gt>Elem[] is defined <nl>
  45. * <md CRunPtrBase::_pRuns> != NULL <nl>
  46. * <md CRunPtrBase::_iRun> >= 0 <nl>
  47. * <md CRunPtrBase::_ich> >= 0 <nl>
  48. * <md _pRuns>-<gt>Count() > 0 <nl>
  49. *
  50. * Note that in order to support the empty and normal states, the actual
  51. * array element at <md CRunPtrBase::_iRun> must be explicitly fetched in
  52. * any method that may need it.
  53. *
  54. * Currently, there is no way to transition to the NULL state from any of
  55. * the other states. If we needed to, we could support that by explicitly
  56. * fetching the array from the document on demand.
  57. *
  58. * Note that only <md CRunPtrBase::_iRun> is kept. We could also keep
  59. * a pointer to the actual run (i.e. _pRun). Earlier versions of this
  60. * engine did in fact do this. I've opted to not do this for several
  61. * reasons: <nl>
  62. * 1. If IsValid(), _pRun is *always* available by calling Elem(_iRun).
  63. * Therefore, there is nominally no need to keep both _iRun and _pRun.<nl>
  64. * 2. Run pointers are typically used to either just move around
  65. * and then fetch data or move and fetch data every time (like during
  66. * a measuring loop). In the former case, there is no need to always
  67. * bind _pRun; you can just do it on demand. In the latter case, the
  68. * two models are equivalent.
  69. */
  70. class CRunPtrBase
  71. {
  72. friend class CDisplayML;
  73. friend class CDisplaySL;
  74. //@access Public methods
  75. public:
  76. #ifdef DEBUG
  77. BOOL Invariant() const; //@cmember Invariant tests
  78. void ValidatePtr(void *pRun) const; //@cmember Validate <p pRun>
  79. LONG CalcTextLength() const; //@cmember Get total cch in runs
  80. #define VALIDATE_PTR(pRun) ValidatePtr(pRun)
  81. #else
  82. #define VALIDATE_PTR(pRun)
  83. #endif // DEBUG
  84. CRunPtrBase(CRunArray *pRuns); //@cmember Constructor
  85. CRunPtrBase(CRunPtrBase& rp); //@cmember Constructor
  86. // Run Control
  87. void SetRunArray(CRunArray *pRuns) //@cmember Set run array for this
  88. { // run ptr
  89. _pRuns = pRuns;
  90. }
  91. BOOL SetRun(LONG iRun, LONG ich); //@cmember Set this runptr to run
  92. // <p iRun> & char offset <p ich>
  93. BOOL NextRun(); //@cmember Advance to next run
  94. BOOL PrevRun(); //@cmember Go back to prev run
  95. BOOL ChgRun(LONG cRun) //@cmember Move <p cRun> runs
  96. { // returning TRUE if successful
  97. return SetRun(_iRun + cRun, 0);
  98. }
  99. //@cmember Count <p cRun> runs
  100. LONG CountRuns(LONG &cRun, // returning cch counted and
  101. LONG cchMax, // updating <p cRun>
  102. LONG cp,
  103. LONG cchText) const;
  104. //@cmember Find run range limits
  105. void FindRun (LONG *pcpMin,
  106. LONG *pcpMost, LONG cpMin, LONG cch, LONG cchText) const;
  107. CTxtRun * GetRun(LONG cRun) const; //@cmember Retrieve run element at
  108. // offset <p cRun> from this run
  109. LONG Count() const //@cmember Get count of runs
  110. {
  111. return _pRuns->Count();
  112. }
  113. BOOL SameRuns(CRunPtrBase *prp) //@cmember Return TRUE iff same runs
  114. {
  115. return _pRuns == prp->_pRuns;
  116. }
  117. BOOL SameRun(CRunPtrBase *prp)
  118. {
  119. return SameRuns(prp) && _iRun == prp->_iRun;
  120. }
  121. // Character position control
  122. LONG BindToCp(LONG cp); //@cmember Set cp for this run ptr = <p cp>
  123. LONG CalculateCp() const;//@cmember Add _cch's up to _iRun, _ich
  124. LONG AdvanceCp(LONG cch);//@cmember Advance cp by <p cch> chars
  125. void AdjustBackward(); //@cmember If on the edge of two runs,
  126. // adjust to end of left (previous) run
  127. void AdjustForward(); //@cmember If at the edge of two runs,
  128. // adjust to start of right (next) run
  129. LONG GetIch() const //@cmember Return <md CRunPtrBase::_ich>
  130. {Assert(IsValid()); return _ich;}
  131. LONG GetCchLeft() const; //@cmember Return GetRun(0)->_cch - GetIch()
  132. BOOL IsValid() const; //@cmember Return FALSE if run ptr is in
  133. // empty or NULL states. TRUE otherwise
  134. void SetToNull(); //@cmember Clears data from run pointer
  135. //@access Protected Data
  136. protected:
  137. CRunArray * _pRuns; //@cmember Pointer to CTxtRun array
  138. LONG _iRun; //@cmember Index of current run in array
  139. LONG _ich; //@cmember Char offset inside current run
  140. };
  141. /*
  142. * CRunPtr (template)
  143. *
  144. * @class a template over CRunPtrBase allowing for type-safe versions of
  145. * run pointers
  146. *
  147. * @tcarg class | CElem | run array class to be used
  148. *
  149. * @base public | CRunPtrBase
  150. */
  151. template <class CElem>
  152. class CRunPtr : public CRunPtrBase
  153. {
  154. public:
  155. CRunPtr (void) //@cmember Constructor
  156. : CRunPtrBase (0) {}
  157. CRunPtr (CRunArray *pRuns) //@cmember Constructor
  158. : CRunPtrBase (pRuns) {}
  159. CRunPtr (CRunPtrBase& rp) //@cmember Constructor
  160. : CRunPtrBase (rp) {}
  161. // Array management
  162. CElem * Add (LONG cRun, LONG *pielIns) //@cmember Add <p cRun>
  163. { // elements at end of array
  164. return (CElem *)_pRuns->Add(cRun, pielIns);
  165. }
  166. CElem * Insert (LONG cRun) //@cmember Insert <p cRun>
  167. { // elements at current pos
  168. return (CElem *)_pRuns->Insert(_iRun, cRun);
  169. }
  170. void Remove (LONG cRun) //@cmember Remove <p cRun>
  171. { // elements at current pos
  172. _pRuns->Remove (_iRun, cRun);
  173. }
  174. //@cmember Replace <p cRun> elements
  175. // at current position with those
  176. // from <p parRun>
  177. BOOL Replace (LONG cRun, CArrayBase *parRun)
  178. {
  179. return _pRuns->Replace(_iRun, cRun, parRun);
  180. }
  181. CElem * Elem(LONG iRun) const //@cmember Get ptr to run <p iRun>
  182. {
  183. return (CElem *)_pRuns->Elem(iRun);
  184. }
  185. CElem * GetRun(LONG cRun) const //@cmember Get ptr <p cRun> runs
  186. { // away from current run
  187. return Elem(_iRun + cRun);
  188. }
  189. void IncPtr(CElem *&pRun) const //@cmember Increment ptr <p pRun>
  190. {
  191. VALIDATE_PTR(pRun); // Allow invalid ptr after ++ for
  192. pRun++; // for loops
  193. }
  194. CElem * GetPtr(CElem *pRun, LONG cRun) const//@cmember Get ptr <p cRun>
  195. { // runs away from ptr <p pRun>
  196. VALIDATE_PTR(pRun + cRun);
  197. return pRun + cRun;
  198. }
  199. };
  200. #endif