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 "nsRect.h"
11 #include "mozilla/Attributes.h"
12 #include "mozilla/Result.h"
13 
14 class nsIFrame;
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   struct LineInfo {
49     /** The first frame on the line. */
50     nsIFrame* mFirstFrameOnLine = nullptr;
51     /** The numbers of frames on the line. */
52     int32_t mNumFramesOnLine = 0;
53     /**
54      * The bounding box of the line (which is based on the in-flow position of
55      * the frames on the line; if a frame was moved because of relative
56      * positioning then its coordinates may be outside the line bounds)
57      */
58     nsRect mLineBounds;
59     /** Whether the line is wrapped at the end */
60     bool mIsWrapped;
61   };
62 
63   // Return miscellaneous information about a line.
64   virtual mozilla::Result<LineInfo, nsresult> GetLine(
65       int32_t aLineNumber) const = 0;
66 
67   /**
68    * Given a frame that's a child of the block, find which line its on
69    * and return that line index, as long as it's at least as big as
70    * aStartLine.  Returns -1 if the frame cannot be found on lines
71    * starting with aStartLine.
72    */
73   virtual int32_t FindLineContaining(nsIFrame* aFrame,
74                                      int32_t aStartLine = 0) = 0;
75 
76   // Given a line number and a coordinate, find the frame on the line
77   // that is nearest to aPos along the inline axis. (The block-axis coord
78   // of aPos is irrelevant.)
79   // The aPosIsBeforeFirstFrame and aPosIsAfterLastFrame flags are updated
80   // appropriately.
81   NS_IMETHOD FindFrameAt(int32_t aLineNumber, nsPoint aPos,
82                          nsIFrame** aFrameFound, bool* aPosIsBeforeFirstFrame,
83                          bool* aPosIsAfterLastFrame) const = 0;
84 
85   // Give the line iterator implementor a chance todo something more complicated
86   // than nsIFrame::GetNextSibling()
87   NS_IMETHOD GetNextSiblingOnLine(nsIFrame*& aFrame,
88                                   int32_t aLineNumber) const = 0;
89 
90   // Check whether visual and logical order of frames within a line are
91   // identical.
92   //  If not, return the first and last visual frames
93   NS_IMETHOD CheckLineOrder(int32_t aLine, bool* aIsReordered,
94                             nsIFrame** aFirstVisual,
95                             nsIFrame** aLastVisual) = 0;
96 };
97 
98 class nsAutoLineIterator {
99  public:
nsAutoLineIterator()100   nsAutoLineIterator() : mRawPtr(nullptr) {}
nsAutoLineIterator(nsILineIterator * i)101   MOZ_IMPLICIT nsAutoLineIterator(nsILineIterator* i) : mRawPtr(i) {}
102 
~nsAutoLineIterator()103   ~nsAutoLineIterator() {
104     if (mRawPtr) mRawPtr->DisposeLineIterator();
105   }
106 
107   operator const nsILineIterator*() const { return mRawPtr; }
108   operator nsILineIterator*() { return mRawPtr; }
109   const nsILineIterator* operator->() const { return mRawPtr; }
110   nsILineIterator* operator->() { return mRawPtr; }
111 
112   nsILineIterator* operator=(nsILineIterator* i) {
113     if (i == mRawPtr) return i;
114 
115     if (mRawPtr) mRawPtr->DisposeLineIterator();
116 
117     mRawPtr = i;
118     return i;
119   }
120 
121  private:
122   nsILineIterator* mRawPtr;
123 };
124 
125 #endif /* nsILineIterator_h___ */
126