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 = false;
61   };
62 
63   // Return miscellaneous information about a line.
64   virtual mozilla::Result<LineInfo, nsresult> GetLine(int32_t aLineNumber) = 0;
65 
66   /**
67    * Given a frame that's a child of the block, find which line its on
68    * and return that line index, as long as it's at least as big as
69    * aStartLine.  Returns -1 if the frame cannot be found on lines
70    * starting with aStartLine.
71    */
72   virtual int32_t FindLineContaining(nsIFrame* aFrame,
73                                      int32_t aStartLine = 0) = 0;
74 
75   // Given a line number and a coordinate, find the frame on the line
76   // that is nearest to aPos along the inline axis. (The block-axis coord
77   // of aPos is irrelevant.)
78   // The aPosIsBeforeFirstFrame and aPosIsAfterLastFrame flags are updated
79   // appropriately.
80   NS_IMETHOD FindFrameAt(int32_t aLineNumber, nsPoint aPos,
81                          nsIFrame** aFrameFound, bool* aPosIsBeforeFirstFrame,
82                          bool* aPosIsAfterLastFrame) = 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