1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef nsILineIterator_h___
7 #define nsILineIterator_h___
8 
9 #include "nscore.h"
10 #include "nsPoint.h"
11 #include "mozilla/Attributes.h"
12 
13 class nsIFrame;
14 struct nsRect;
15 
16 /**
17  * Line iterator API.
18  *
19  * Lines are numbered from 0 to N, where 0 is the top line and N is
20  * the bottom line.
21  *
22  * Obtain this interface from frames via nsIFrame::GetLineIterator.
23  * When you are finished using the iterator, call DisposeLineIterator()
24  * to destroy the iterator if appropriate.
25  */
26 class nsILineIterator {
27  protected:
28   ~nsILineIterator() = default;
29 
30  public:
31   virtual void DisposeLineIterator() = 0;
32 
33   /**
34    * The number of lines in the block
35    */
36   virtual int32_t GetNumLines() const = 0;
37 
38   /**
39    * The prevailing direction of lines.
40    *
41    * @return true if the CSS direction property for the block is
42    *         "rtl", otherwise false
43    *
44    *XXX after bug 924851 change this to return a UBiDiDirection
45    */
46   virtual bool GetDirection() = 0;
47 
48   // Return structural information about a line. aFirstFrameOnLine is
49   // the first frame on the line and aNumFramesOnLine is the number of
50   // frames that are on the line. If the line-number is invalid then
51   // aFirstFrameOnLine will be nullptr and aNumFramesOnLine will be
52   // zero.
53   //
54   // For valid line numbers, aLineBounds is set to the bounding box of
55   // the line (which is based on the in-flow position of the frames on
56   // the line; if a frame was moved because of relative positioning
57   // then its coordinates may be outside the line bounds).
58   NS_IMETHOD GetLine(int32_t aLineNumber, nsIFrame** aFirstFrameOnLine,
59                      int32_t* aNumFramesOnLine, nsRect& aLineBounds) const = 0;
60 
61   /**
62    * Given a frame that's a child of the block, find which line its on
63    * and return that line index, as long as it's at least as big as
64    * aStartLine.  Returns -1 if the frame cannot be found on lines
65    * starting with aStartLine.
66    */
67   virtual int32_t FindLineContaining(nsIFrame* aFrame,
68                                      int32_t aStartLine = 0) = 0;
69 
70   // Given a line number and a coordinate, find the frame on the line
71   // that is nearest to aPos along the inline axis. (The block-axis coord
72   // of aPos is irrelevant.)
73   // The aPosIsBeforeFirstFrame and aPosIsAfterLastFrame flags are updated
74   // appropriately.
75   NS_IMETHOD FindFrameAt(int32_t aLineNumber, nsPoint aPos,
76                          nsIFrame** aFrameFound, bool* aPosIsBeforeFirstFrame,
77                          bool* aPosIsAfterLastFrame) const = 0;
78 
79   // Give the line iterator implementor a chance todo something more complicated
80   // than nsIFrame::GetNextSibling()
81   NS_IMETHOD GetNextSiblingOnLine(nsIFrame*& aFrame,
82                                   int32_t aLineNumber) const = 0;
83 
84   // Check whether visual and logical order of frames within a line are
85   // identical.
86   //  If not, return the first and last visual frames
87   NS_IMETHOD CheckLineOrder(int32_t aLine, bool* aIsReordered,
88                             nsIFrame** aFirstVisual,
89                             nsIFrame** aLastVisual) = 0;
90 };
91 
92 class nsAutoLineIterator {
93  public:
nsAutoLineIterator()94   nsAutoLineIterator() : mRawPtr(nullptr) {}
nsAutoLineIterator(nsILineIterator * i)95   MOZ_IMPLICIT nsAutoLineIterator(nsILineIterator* i) : mRawPtr(i) {}
96 
~nsAutoLineIterator()97   ~nsAutoLineIterator() {
98     if (mRawPtr) mRawPtr->DisposeLineIterator();
99   }
100 
101   operator const nsILineIterator*() const { return mRawPtr; }
102   operator nsILineIterator*() { return mRawPtr; }
103   const nsILineIterator* operator->() const { return mRawPtr; }
104   nsILineIterator* operator->() { return mRawPtr; }
105 
106   nsILineIterator* operator=(nsILineIterator* i) {
107     if (i == mRawPtr) return i;
108 
109     if (mRawPtr) mRawPtr->DisposeLineIterator();
110 
111     mRawPtr = i;
112     return i;
113   }
114 
115  private:
116   nsILineIterator* mRawPtr;
117 };
118 
119 #endif /* nsILineIterator_h___ */
120