InDesign SDK  20.5
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ITextParcelList.h
1 //========================================================================================
2 //
3 // $File$
4 //
5 // Owner: dwaterfa
6 //
7 // $Author$
8 //
9 // $DateTime$
10 //
11 // $Revision$
12 //
13 // $Change$
14 //
15 // Copyright 1997-2010 Adobe Systems Incorporated. All rights reserved.
16 //
17 // NOTICE: Adobe permits you to use, modify, and distribute this file in accordance
18 // with the terms of the Adobe license agreement accompanying it. If you have received
19 // this file from a source other than Adobe, then your use, modification, or
20 // distribution of it requires the prior written permission of Adobe.
21 //
22 //========================================================================================
23 
24 #ifndef __ITextParcelList__
25 #define __ITextParcelList__
26 
27 #include "IPMUnknown.h"
28 #include "IParcelList.h"
29 #include "ITextParcelListData.h"
30 
31 #include "CTextEnum.h"
32 #include "DrawPassInfo.h"
33 #include "OwnedItemDataList.h"
34 #include "PMMatrix.h"
35 #include "PMRect.h"
36 #include "TextID.h"
37 #include "UIDList.h"
38 
39 class ICallback;
40 class IComposeScanner;
41 class IDocumentLayer;
42 class IFrameList;
43 class IGraphicsContext;
44 class IParcelContainer;
45 class IInlineData;
46 class IStandOffData;
47 class ISpread;
48 class ITextSelectionDrawer;
49 class ITextStoryThread;
50 class ITextModel;
51 class IWaxAnchoredElement;
52 class IWaxLine;
53 class IWaxStrand;
54 
55 class GraphicsData;
56 class IdleTimer;
57 class RangeData;
58 class TabStopTable;
59 class ContainerComposer;
60 
65 {
66  public:
67  enum { kDefaultIID = IID_ITEXTPARCELLIST };
68 
69  //
70  // Composed state of the Text Parcel List
71  //
72  virtual UIDRef GetTextModelRef() const = 0;
73  virtual UIDRef GetWaxStrandRef() const = 0;
74 
75  virtual ITextStoryThread * QueryStoryThread() const = 0;
76  virtual RangeData GetThreadRange() const = 0;
77  virtual TextIndex GetThreadStart(int32* pSpan = nil) const = 0;
78  virtual int32 GetThreadSpan(TextIndex* pStart = nil) const = 0;
79 
80  virtual TextIndex GetTextStart(ParcelKey key) const = 0;
81  virtual int32 GetTextSpan(ParcelKey key) const = 0;
82  virtual RangeData GetTextRange(ParcelKey key) const = 0;
83  virtual void SetTextSpan(ParcelKey key, int32 span) = 0;
84 
85  //
86  // These methods return the ParcelKey of the Parcel which contains the
87  // specified TextIndex (or start of RangeData). If the TextIndex is
88  // in overset an invalid ParcelKey will be returned.
89  //
90  // The LeanLeft variant behaves the same as the other variant except
91  // that it treats the first TextIndex in the Parcel as being mapped to
92  // the previous Parcel. Most casual users should use the non-LeanLeft
93  // variant.
94  //
95  // NOTE It is important that the client check for invalid ParcelKeys
96  // before proceeding to use them in the methods of this interface.
97  // The only exception to this is IParcelList::begin(key)/end(key)/
98  // rbegin(key)/rend(key). See that file for more information.
99  //
100  virtual ParcelKey GetParcelContaining(TextIndex at) const = 0;
101  virtual ParcelKey GetParcelContainingLeanLeft(TextIndex at) const = 0;
102  virtual ParcelKey GetParcelContaining(const RangeData& location) const = 0;
103  virtual void GetParcelsContaining(const RangeData& r,
104  ParcelKey* firstParcel,
105  ParcelKey* lastParcel) const = 0;
106 
115  virtual bool16 GetIsOverset(TextIndex* pFirstOversetTextIndex = nil) const = 0;
116 
128  virtual TextIndex GetFirstOversetTextIndex(TextIndex* pThreadLast = nil) const = 0;
129 
130  //
131  // These methods help navigate through the ParcelList since some
132  // ParcelLists may have Parcels that are not to be composed into, such
133  // as in Table Headers/Footers.
134  //
135  virtual ParcelKey GetFirstLogicalParcelKey() const = 0;
136 
137  virtual ParcelKey GetNextLogicalParcelKey(ParcelKey key) const = 0;
138 
139  virtual ParcelKey GetLastLogicalParcelKey() const = 0;
140 
141  virtual ParcelKey GetLastLogicalNonOversetParcelKey() const = 0;
142 
143  //
144  // Iterators
145  //
146  // It is acceptable to pass in an invalid ParcelKey to begin()/end()/
147  // rbegin()/rend(). The resulting iterator will be the same as if the
148  // caller had called the end()/rend() methods with no key argument.
149  //
150  class const_iterator;
152  virtual const_iterator begin() const = 0;
153  virtual const_iterator begin(ParcelKey key) const = 0;
154  virtual const_iterator end() const = 0;
155  virtual const_iterator end(ParcelKey key) const = 0;
156  virtual const_reverse_iterator rbegin() const = 0;
157  virtual const_reverse_iterator rbegin(ParcelKey key) const = 0;
158  virtual const_reverse_iterator rend() const = 0;
159  virtual const_reverse_iterator rend(ParcelKey key) const = 0;
160 
161  //
162  // Text Parcel List Properties
163  //
164  virtual Text::FirstLineOffsetMetric GetFirstLineOffsetMetric(ParcelKey key) const = 0;
165  virtual PMReal GetMinFirstLineOffset(ParcelKey key) const = 0;
166  virtual bool16 GetIsVertical() const = 0;
167  virtual bool16 GetIsRightToLeft() const = 0;
168 
169  virtual bool16 GetParcelHasBeenVJed(ParcelKey key) const = 0;
170 
171  //
172  // These methods simply call the ITextTiler methods of the same
173  // name. If you already have a Parcel you should call directly rather
174  // than using these interfaces.
175  //
176  virtual PMRect GetParcelContentBounds(ParcelKey key) const = 0;
177  virtual PMMatrix GetParcelToContentMatrix(ParcelKey key) const = 0;
178 
179  //
180  // SoftBottom
181  //
182  // A Parcel which allows Text Tiling to go past the bottom of the
183  // Parcel and still be part of the same Parcel (but not visible) is
184  // considered to have a SoftBottom. All WaxLines that are tiled off
185  // the end of the Parcel but still less than the Max height are
186  // considered part of the Parcel but are marked not visible and will
187  // not draw.
188  //
189  virtual PMReal GetMaxSoftBottomHeight(ParcelKey key) const = 0;
190 
191  //
192  // Composition is a delicate thing...
193  //
194  // When an undamaged WaxLine is damaged the InkBound rectangle of the
195  // WaxLine (in Parcel coordinates) is given to the SetPendingInval()
196  // method and the Parcel is marked damaged through SetDamage().
197  //
198  // The Recompose() method is eventually called by the owning container
199  // (TextFrame, Table, etc).
200  //
201  // When a WaxLine is applied into a Parcel by the WaxStrand the
202  // following occurs:
203  // 1) The SetRecomposing() method is called.
204  // 2) If the owning container is in view the InkBound rectangle of
205  // the new WaxLine is given to the SetPendingInval() method.
206  //
207  // This process then repeats itself until the composition of the
208  // original Parcel(s) is complete.
209  //
210  // Note that starting composition in one Parcel may in fact lead to
211  // new WaxLines being applied in other Parcels due to either the
212  // ParagraphComposer backing up out of the starting Parcel or simply
213  // running off of the starting Parcel into the next one.
214  //
215  virtual bool16 GetIsDamaged(ParcelKey key) const = 0;
216  virtual void SetDamaged(ParcelKey key) = 0;
217 
220  virtual ParcelKey GetFirstDamagedParcel() const = 0;
221 
232  virtual ParcelKey GetFirstParcelNeedingComposition() const = 0;
233 
238  {
245 
250 
256 
265 
270 
271  };
272 
292  virtual RecomposeResult Recompose(IParcelContainer* container,
293  int32 firstContainerPI,
294  bool16 noDamageBackPrevContainers,
295  Text::VerticalJustification vj,
296  PMReal vjMaxInterParaSpace,
297  bool16 vjBalanceColumns,
298  int32 firstDamagedPI,
299  int32 firstNeedWrapCheckPI,
300  TextIndex composeUpToTextIndex = kInvalidTextIndex,
301  IdleTimer* interruptCheck = nil,
302  PMReal* tileableHeightRemaining = nil) = 0;
303 
304  //
305  // The text content can become damaged in various ways other than
306  // direct changes to the content.
307  //
308 
317  virtual bool16 MarkDamage(TextIndex at,
318  int32 amt,
319  int32 limitLeanLeftParcelIndex) = 0;
320 
324  virtual void AdjustSpans(TextIndex at, int32 amt) = 0;
325 
326  // These methods provide support for specific common operations that
327  // affect the text content. The will compute the span of text that
328  // needs to be damaged for that operation.
329  //
330  // MarkParcelInsertDamage The parcel list has changed.
331  // MarkParcelRemoveDamage ""
332  // ComputeResizeDamage The parcel has changed it's size.
333  // ComputeMoveDamage The parcel has been moved relative to
334  // underlying pasteboard. It may or may
335  // not have been moved relative to the
336  // underlying Frame.
337  //
338  // These methods are provided out of convenience to functions that wish
339  // to change the composition environment of the Text such as changing
340  // FirstLineOffset, rotating text, etc. It is left upto to the specific
341  // function to determine what extent of damage is appropriate.
342  //
343  // ComputeFirstLineDamage Compute damage for the first line of
344  // text that COULD compose in the Parcel.
345  // Note this line might not actually be in
346  // the Parcel.
347  // ComputeEntireParcelDamage Compute damage for all text in the
348  // Parcel including the first line of text
349  // in the next Parcel.
350  // ComputeFirstLineInNextParcelDamage Compute damage for the first
351  // line that is in the next Parcel.
352  // This is used to "pull up" lines
353  // into the Parcel.
354  //
355  // Note: All PMRects are expressed in Parcel coordinates.
356  //
357  virtual void MarkParcelInsertDamage(ParcelKey key) = 0;
358 
359  virtual void MarkParcelRemoveDamage(ParcelKey key) = 0;
360 
361  virtual void MarkResizeDamage(ParcelKey key,
362  const PMRect &boundsBefore,
363  const PMRect &boundsAfter) = 0;
364 
365  virtual void MarkMoveDamage(ParcelKey key) = 0;
366 
367  virtual void MarkGridDamage(ParcelKey key) = 0;
368 
380  virtual void MarkCompositionDamageNoLean(ParcelKey limitFirstParcelKey,
381  TextIndex threadStart,
382  TextIndex damageStart,
383  int32 limitFirstParcelIndex,
384  TextIndex damageEnd,
385  int32 lastParcelIndex) = 0;
386 
387  virtual void DamageFirstLine(ParcelKey key) = 0;
388  virtual void DamageEntireParcel(ParcelKey key, int32 limitLeanLeftParcelIndex = kInvalidParcelIndex) = 0;
389  virtual void DamageEntireParcelP1(ParcelKey key, int32 limitLeanLeftParcelIndex = kInvalidParcelIndex) = 0;
390  virtual void DamageFirstLineInNextParcel(ParcelKey key) = 0;
391  virtual void DamageYRange(ParcelKey key, const PMReal& waxYTop,
392  const PMReal& waxYBottom) = 0;
393  /*
394  This method damages the Wax Anchored Elements(containing foonotes as of now) found in a parcel given that they intersect/lie between with waxYTop & waxYBottom.
395  @param key - key of the parcel whose WAE needs to be damaged
396  @param waxYTop - top Y position of wax line
397  @param waxYBottom - bottom Y position of wax line
398  */
399  virtual void DamageWaxAnchoredElementYRange(ParcelKey key, const PMReal& waxYTop,
400  const PMReal& waxYBottom) = 0;
401 
402  typedef void (ITextParcelList::*ComputeMethod1)(ParcelKey,
403  TextIndex*, int32*) const;
404  typedef void (ITextParcelList::*ComputeMethod2)(ParcelKey,
405  const PMRect&, const PMRect&,
406  TextIndex*, int32*) const;
407 
408  virtual void Damage(ComputeMethod1, ParcelKey key, int32 limitLeanLeftParcelIndex = kInvalidParcelIndex) = 0;
409 
410  virtual void Damage(ComputeMethod2, ParcelKey key,
411  const PMRect& b1, const PMRect& b2) = 0;
412 
413  virtual void ComputeResizeDamage(ParcelKey key,
414  const PMRect &boundsBefore,
415  const PMRect &boundsAfter,
416  TextIndex *pStart, int32 *pLen) const = 0;
417 
418  virtual void ComputeFirstLineDamage(ParcelKey key,
419  TextIndex *pStart, int32 *pLen) const = 0;
420  virtual void ComputeEntireParcelDamage(ParcelKey key,
421  TextIndex *pStart, int32 *pLen) const = 0;
422  virtual void ComputeEntireParcelP1Damage(ParcelKey key,
423  TextIndex *pStart, int32 *pLen) const = 0;
424  virtual void ComputeFirstLineInNextParcelDamage(ParcelKey key,
425  TextIndex *pStart, int32 *pLen) const = 0;
426 
427  //
428  // Inval the WaxLines for the specified range.
429  //
430  virtual void Inval(TextIndex start, int32 span) const = 0;
431 
432  //
433  // Not all break values are supported by all implementations. If the
434  // implementation does not support the particular break mode for the
435  // particular Parcel then it should return kFalse which will ensure
436  // that no adjustment to the Paragraph starting position will occur.
437  //
438  // If the implementation does not support ANY break modes then it
439  // should return kFalse for the second method.
440  //
441  virtual bool16 GetIsValidStartBreakLocation(ParcelKey key,
442  Text::StartBreakLocation mode) const = 0;
443  virtual bool16 GetHasAnyValidStartBreakLocation() const = 0;
444 
445  //
446  // Return information needed by IParcelShape.
447  //
448  virtual void GetShapeData(ParcelKey key,
449  PMRect *inkBounds, // parcel coord.
450  int32 *passCount,
451  Text::DrawPassInfo **passList) = 0;
452 
453  //
454  // Draw a parcel.
455  //
456  virtual void DrawParcel(ParcelKey key,
457  GraphicsData* gd,
458  int32 iShapeFlags,
459  const PMRect* areaToDraw,
460  const int32 passCount,
461  const Text::DrawPassInfo* passList,
462  void (*btdFunc)(void *),
463  void (*btfdFunc)(void *),
464  void* funcPrv,
465  bool16* pInkBoundsChanged) = 0;
466 
467  //
468  // Composed Bounds.
469  //
470  // The composed bounds represent the smallest amount of space the
471  // composed text fit in so it does NOT including any amounts due to
472  // Vertical Justification. The bounds are returned in Content
473  // coordinates. This information is valuable for computing autogrow.
474  //
475  // See GetParcelContentBounds() to get the bounds used by the
476  // Tiler to tile within the Parcel. Most users will want to use that
477  // interface instead of this one.
478  //
479  virtual PMRect GetParcelComposedBounds(ParcelKey key) const = 0;
480 
493  virtual PMReal HitTestParcel(ParcelKey key,
494  const PMPoint &pasteboardPt,
495  TextIndex *nextLine = nil) = 0;
496 
501  virtual void IterateTextParcelListDrawOrder( const PMMatrix *xform,
502  ICallback *callbackInfo,
503  int32 iShapeFlags,
504  ParcelKey key) const = 0;
505 
511  virtual bool16 ShouldFakeTabAlignToChar() const = 0;
512 
518  virtual void CollectParcelChildren(ParcelKey key, UIDList* list) const = 0;
519 
524  virtual void InsertWaxAnchoredElement(IWaxAnchoredElement* wae,
525  ParcelKey toKey) = 0;
526 
529  virtual void RemoveWaxAnchoredElement(IWaxAnchoredElement*wae) = 0;
530 
533  virtual void MoveWaxAnchoredElement(IWaxAnchoredElement* wae,
534  ParcelKey toKey) = 0;
535 
545  virtual void NotifyInkBoundsChangedAt(TextIndex at,
546  bool16 fromRebuild) = 0;
547 
552  virtual void NotifyParcelInkBoundsChanged(ParcelKey key) = 0;
553 
560 
573  virtual PMReal HitTestParcel(ParcelKey key,
574  const PMPoint &waxPt,
575  bool16 withinSTOnly,
576  TextIndex *nextLine) const = 0;
577 
578 
588  virtual void CollectParcelOwnedItems(ParcelKey key,
589  OwnedItemDataList* rList) const = 0;
590 
597  virtual bool16 GetParcelIsEmpty(ParcelKey key,
598  bool16* optionalIsOnlyLastCR = nil) const = 0;
599 
604  virtual void NotifyParcelLayerChanged(ParcelKey key,
605  const IDocumentLayer* newDocLayer) = 0;
606 
610  virtual void NotifyParcelVisibilityChanged(ParcelKey key) = 0;
611 
615  virtual void NotifyParcelZOrderChanged(ParcelKey key) = 0;
616 
620  virtual void NotifyParcelIgnoreWrapChanged(ParcelKey key) = 0;
621 
630  virtual void AddParcelInlineWraps(ParcelKey key,
631  const IInlineData* id,
632  const UIDRef& spreadRef,
633  const TextWrapRefList& sodList) = 0;
634 
650  virtual void NotifyParcelWrapZOrderChanged(ParcelKey key,
651  const TextWrapRef& sodRef,
652  bool16 zOrderBasedWrap,
653  const IDocumentLayer* sodDocLayer) = 0;
654 
663  const TextWrapRef& sodRef) = 0;
664 
676  const TextWrapRef& sodRef) = 0;
677 
688  virtual void RemoveParcelWrap(ParcelKey key,
689  const TextWrapRef& sodRef) = 0;
690 
700  virtual bool16 RebuildWaxLine(const ITextStoryThread* thread,
701  const IParcelList* pl,
702  IWaxLine* waxLine) const = 0;
703 
712  virtual bool16 GetParcelContainsOversetContent(ParcelKey key) const = 0;
713 
718  virtual void NotifyStoryDirectionChanged() = 0;
719 
725  virtual ParcelKey GetParcelComposing() const = 0;
726 
729  virtual Text::VerticalJustification GetComposingVerticalJustification() const = 0;
730 
733  virtual bool16 CanBackDamageContainer() const = 0;
734 
739  {
740  public:
741  typedef ParcelKey value_type;
742  typedef std::ptrdiff_t difference_type;
743  typedef const ParcelKey* pointer;
744  typedef const ParcelKey& reference;
745  typedef std::bidirectional_iterator_tag iterator_category;
746 
747  friend class TextParcelList;
748  friend class const_reverse_iterator;
749 
750  const_iterator(const const_iterator& copy)
751  {
752  ASSERT(copy.fData);
753  fData.reset(copy.fData);
754  fData->AddRef();
755  fKey = copy.fKey;
756  fKeyState = copy.fKeyState;
757  }
758 
759  ~const_iterator()
760  { }
761 
762  const ParcelKey& operator*() const
763  { return fKey; }
764 
765  const ParcelKey* operator->() const
766  { return &fKey; }
767 
768  const_iterator& operator=(const const_iterator& rhs)
769  {
770  if (this != &rhs)
771  {
772  ASSERT(rhs.fData);
773  fData.reset(rhs.fData);
774  fData->AddRef();
775  fKey = rhs.fKey;
776  fKeyState = rhs.fKeyState;
777  }
778  return *this;
779  }
780 
781  const_iterator& operator++()
782  {
783  if (fKeyState == -1)
784  {
785  fKey = fData->GetFirstLogicalParcelKey();
786 
787  if(!fKey.IsValid())
788  {
789  fKeyState = 1;
790  } else {
791  fKeyState = 0;
792  }
793  }
794  else if (fKeyState == 0)
795  {
796  fKey = fData->GetNextLogicalParcelKey(fKey);
797 
798  if(!fKey.IsValid())
799  {
800  fKeyState = 1;
801  }
802  }
803  else
804  {
805  ASSERT(fKeyState == 1);
806  ASSERT_FAIL("ITextParcelList::const_iterator ++ past end");
807  }
808  return *this;
809  }
810 
811  const_iterator operator++(int)
812  {
813  const_iterator tmp = *this;
814  if (fKeyState == -1)
815  {
816  fKey = fData->GetFirstLogicalParcelKey();
817 
818  if(!fKey.IsValid())
819  {
820  fKeyState = 1;
821  } else {
822  fKeyState = 0;
823  }
824  }
825  else if (fKeyState == 0)
826  {
827  fKey = fData->GetNextLogicalParcelKey(fKey);
828 
829  if(!fKey.IsValid())
830  {
831  fKeyState = 1;
832  }
833  }
834  else
835  {
836  ASSERT(fKeyState == 1);
837  ASSERT_FAIL("ITextParcelList::const_iterator ++ past end");
838  }
839  return tmp;
840  }
841 
842  const_iterator& operator--()
843  {
844  if (fKeyState == -1)
845  {
846  ASSERT_FAIL("ITextParcelList::const_iterator -- before begin");
847  }
848  else if (fKeyState == 0)
849  {
850  fKey = fData->GetPreviousLogicalParcelKey(fKey);
851 
852  if(!fKey.IsValid())
853  {
854  fKeyState = -1;
855  }
856  }
857  else
858  {
859  ASSERT(fKeyState == 1);
860  fKey = fData->GetLastLogicalParcelKey();
861 
862  if(!fKey.IsValid())
863  {
864  fKeyState = -1;
865  } else {
866  fKeyState = 0;
867  }
868  }
869  return *this;
870  }
871 
872  const_iterator operator--(int)
873  {
874  const_iterator tmp = *this;
875  if (fKeyState == -1)
876  {
877  ASSERT_FAIL("ITextParcelList::const_iterator -- before begin");
878  }
879  else if (fKeyState == 0)
880  {
881  fKey = fData->GetPreviousLogicalParcelKey(fKey);
882 
883  if(!fKey.IsValid())
884  {
885  fKeyState = -1;
886  }
887  }
888  else
889  {
890  ASSERT(fKeyState == 1);
891  fKey = fData->GetLastLogicalParcelKey();
892 
893  if(!fKey.IsValid())
894  {
895  fKeyState = -1;
896  } else {
897  fKeyState = 0;
898  }
899  }
900  return tmp;
901  }
902 
903  bool16 operator==(const const_iterator& rhs) const
904  {
905  return ((fData == rhs.fData) &&
906  (fKey == rhs.fKey) &&
907  (fKeyState == rhs.fKeyState));
908  }
909 
910  bool16 operator!=(const const_iterator& rhs) const
911  { return !(*this == rhs); }
912 
913  protected:
915  ParcelKey key,
916  int32 keyState) : // -1 key invalid, before begin
917  // 0 key valid, within range
918  // 1 key invalid, after end
919  fData(data), fKey(key), fKeyState(keyState)
920  {
921  // Force the ref count to be increased, the initializer
922  // is calling the InterfacePtr(IFace*) constructor which
923  // doesn't AddRef(). I guess the compiler considers it the
924  // best match even though the constness is gone.
925  if(fData)
926  {
927  fData->AddRef();
928  }
929  ASSERT(((keyState == -1) && (!key.IsValid())) ||
930  ((keyState == 0) && (key.IsValid())) ||
931  ((keyState == 1) && (!key.IsValid())));
932  }
933 
935  ParcelKey fKey;
936  int32 fKeyState;
937  };
938 
940  {
941  public:
942  typedef ParcelKey value_type;
943  typedef std::ptrdiff_t difference_type;
944  typedef const ParcelKey* pointer;
945  typedef const ParcelKey& reference;
946  typedef std::bidirectional_iterator_tag iterator_category;
947 
948  friend class TextParcelList;
949 
951  fIter(copy.fIter)
952  { }
953 
954  const ParcelKey& operator*() const
955  { return fIter.operator*(); }
956 
957  const ParcelKey* operator->() const
958  { return fIter.operator->(); }
959 
960  const_reverse_iterator& operator=(const const_reverse_iterator& rhs)
961  { this->fIter = rhs.fIter; return *this; }
962 
963  const_reverse_iterator& operator++()
964  { --fIter; return *this; }
965 
966  const_reverse_iterator operator++(int)
967  {
968  const_reverse_iterator tmp = *this;
969  ++fIter;
970  return tmp;
971  }
972 
973  const_reverse_iterator& operator--()
974  { ++fIter; return *this; }
975 
976  const_reverse_iterator operator--(int)
977  {
978  const_reverse_iterator tmp = *this;
979  --fIter;
980  return tmp;
981  }
982 
983  bool16 operator==(const const_reverse_iterator& rhs) const
984  { return (this->fIter == rhs.fIter); }
985 
986  bool16 operator!=(const const_reverse_iterator& rhs)
987  { return !(*this == rhs); }
988 
989  protected:
991  ParcelKey key, int32 keyState) :
992  fIter(data, key, keyState)
993  { }
994 
995  const_iterator fIter;
996  };
997 
998  virtual ContainerComposer* GetCompositionContext() const = 0;
999 
1007  virtual void NotifyParcelWrapModifyIndentsAroundTextWrapChanged(ParcelKey key, const TextWrapRef& sodRef) = 0;
1008 };
1009 
1010 #endif // __ITextParcelList__
1011