nsILineIterator.cpp (2447B)
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 7 #include "nsILineIterator.h" 8 9 #include "nsIFrame.h" 10 11 namespace mozilla { 12 13 void LineFrameFinder::Scan(nsIFrame* aFrame) { 14 if (mDone) { 15 return; 16 } 17 18 if (!mFirstFrame) { 19 mFirstFrame = aFrame; 20 } 21 22 const LogicalRect rect = aFrame->GetLogicalRect(mWM, mContainerSize); 23 if (rect.ISize(mWM) == 0) { 24 return; 25 } 26 // If pos.I() is inside this frame - this is it 27 if (rect.IStart(mWM) <= mPos.I(mWM) && rect.IEnd(mWM) > mPos.I(mWM)) { 28 mClosestFromStart = mClosestFromEnd = aFrame; 29 mDone = true; 30 return; 31 } 32 if (rect.IStart(mWM) < mPos.I(mWM)) { 33 if (!mClosestFromStart || 34 rect.IEnd(mWM) > 35 mClosestFromStart->GetLogicalRect(mWM, mContainerSize).IEnd(mWM)) { 36 mClosestFromStart = aFrame; 37 } 38 } else { 39 if (!mClosestFromEnd || 40 rect.IStart(mWM) < 41 mClosestFromEnd->GetLogicalRect(mWM, mContainerSize).IStart(mWM)) { 42 mClosestFromEnd = aFrame; 43 } 44 } 45 } 46 47 void LineFrameFinder::Finish(nsIFrame** aFrameFound, 48 bool* aPosIsBeforeFirstFrame, 49 bool* aPosIsAfterLastFrame) { 50 if (!mClosestFromStart && !mClosestFromEnd) { 51 // All frames were zero-width. Just take the first one. 52 mClosestFromStart = mClosestFromEnd = mFirstFrame; 53 } 54 *aPosIsBeforeFirstFrame = mIsReversed ? !mClosestFromEnd : !mClosestFromStart; 55 *aPosIsAfterLastFrame = mIsReversed ? !mClosestFromStart : !mClosestFromEnd; 56 if (mClosestFromStart == mClosestFromEnd) { 57 *aFrameFound = mClosestFromStart; 58 } else if (!mClosestFromStart) { 59 *aFrameFound = mClosestFromEnd; 60 } else if (!mClosestFromEnd) { 61 *aFrameFound = mClosestFromStart; 62 } else { // we're between two frames 63 nscoord delta = 64 mClosestFromEnd->GetLogicalRect(mWM, mContainerSize).IStart(mWM) - 65 mClosestFromStart->GetLogicalRect(mWM, mContainerSize).IEnd(mWM); 66 if (mPos.I(mWM) < 67 mClosestFromStart->GetLogicalRect(mWM, mContainerSize).IEnd(mWM) + 68 delta / 2) { 69 *aFrameFound = mClosestFromStart; 70 } else { 71 *aFrameFound = mClosestFromEnd; 72 } 73 } 74 } 75 76 } // namespace mozilla