nsILineIterator.h (4557B)
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 "mozilla/Attributes.h" 10 #include "mozilla/Result.h" 11 #include "mozilla/WritingModes.h" 12 #include "nsINode.h" 13 #include "nsRect.h" 14 #include "nscore.h" 15 16 class nsIFrame; 17 18 /** 19 * Line iterator API. 20 * 21 * Lines are numbered from 0 to N, where 0 is the top line and N is 22 * the bottom line. 23 * 24 * Obtain this interface from frames via nsIFrame::GetLineIterator. 25 * This iterator belongs to the frame from which it was obtained, and should 26 * not be deleted by the caller. 27 * Note that any modification of the frame will invalidate the iterator! 28 * Users must get a new iterator any time the target may have been touched. 29 */ 30 class nsILineIterator { 31 protected: 32 ~nsILineIterator() = default; 33 34 public: 35 /** 36 * The number of lines in the block 37 */ 38 virtual int32_t GetNumLines() const = 0; 39 40 /** 41 * Returns whether our lines are rtl. 42 */ 43 virtual bool IsLineIteratorFlowRTL() = 0; 44 45 struct LineInfo { 46 /** The first frame on the line. */ 47 nsIFrame* mFirstFrameOnLine = nullptr; 48 /** The numbers of frames on the line. */ 49 int32_t mNumFramesOnLine = 0; 50 /** 51 * The bounding box of the line (which is based on the in-flow position of 52 * the frames on the line; if a frame was moved because of relative 53 * positioning then its coordinates may be outside the line bounds) 54 */ 55 nsRect mLineBounds; 56 /** Whether the line is wrapped at the end */ 57 bool mIsWrapped = false; 58 59 /** 60 * Return last frame of the line if there is no enough siblings of 61 * mFirstFrameOnLine. 62 * Otherwise, nullptr including in the unexpected error cases. 63 */ 64 nsIFrame* GetLastFrameOnLine() const; 65 }; 66 67 // Return miscellaneous information about a line. 68 virtual mozilla::Result<LineInfo, nsresult> GetLine(int32_t aLineNumber) = 0; 69 70 /** 71 * Given a frame that's a child of the block, find which line its on 72 * and return that line index, as long as it's at least as big as 73 * aStartLine. Returns -1 if the frame cannot be found on lines 74 * starting with aStartLine. 75 */ 76 virtual int32_t FindLineContaining(const nsIFrame* aFrame, 77 int32_t aStartLine = 0) = 0; 78 79 // Given a line number and a coordinate, find the frame on the line 80 // that is nearest to aPos along the inline axis. (The block-axis coord 81 // of aPos is irrelevant.) 82 // The aPosIsBeforeFirstFrame and aPosIsAfterLastFrame flags are updated 83 // appropriately. 84 NS_IMETHOD FindFrameAt(int32_t aLineNumber, nsPoint aPos, 85 nsIFrame** aFrameFound, bool* aPosIsBeforeFirstFrame, 86 bool* aPosIsAfterLastFrame) = 0; 87 88 // Check whether visual and logical order of frames within a line are 89 // identical. 90 // If not, return the first and last visual frames 91 NS_IMETHOD CheckLineOrder(int32_t aLine, bool* aIsReordered, 92 nsIFrame** aFirstVisual, 93 nsIFrame** aLastVisual) = 0; 94 }; 95 96 namespace mozilla { 97 98 // Helper struct for FindFrameAt. 99 struct LineFrameFinder { 100 LineFrameFinder(const nsPoint& aPos, const nsSize& aContainerSize, 101 WritingMode aWM, bool aIsReversed) 102 : mPos(aWM, aPos, aContainerSize), 103 mContainerSize(aContainerSize), 104 mWM(aWM), 105 mIsReversed(aIsReversed) {} 106 107 void Scan(nsIFrame*); 108 void Finish(nsIFrame**, bool* aPosIsBeforeFirstFrame, 109 bool* aPosIsAfterLastFrame); 110 111 const LogicalPoint mPos; 112 const nsSize mContainerSize; 113 const WritingMode mWM; 114 const bool mIsReversed; 115 116 bool IsDone() const { return mDone; } 117 118 private: 119 bool mDone = false; 120 nsIFrame* mFirstFrame = nullptr; 121 nsIFrame* mClosestFromStart = nullptr; 122 nsIFrame* mClosestFromEnd = nullptr; 123 }; 124 125 } // namespace mozilla 126 127 /** 128 * Helper intended to be used in a scope where we're using an nsILineIterator 129 * and want to verify that no DOM mutations (which would invalidate the 130 * iterator) occur while we're using it. 131 */ 132 class MOZ_RAII AutoAssertNoDomMutations final { 133 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED 134 nsMutationGuard mGuard; 135 #endif 136 public: 137 ~AutoAssertNoDomMutations() { MOZ_DIAGNOSTIC_ASSERT(!mGuard.Mutated(0)); } 138 }; 139 140 #endif /* nsILineIterator_h___ */