gecko-dev/layout/generic/nsLineBox.h

336 lines
8.0 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
#ifndef nsLineBox_h___
#define nsLineBox_h___
#include "nsVoidArray.h"
#include "nsPlaceholderFrame.h"
#include "nsILineIterator.h"
// bits in nsLineBox.mState
#define LINE_IS_DIRTY 0x1
#define LINE_IS_BLOCK 0x2
#define LINE_IS_IMPACTED_BY_FLOATER 0x4
#ifdef BLOCK_DOES_FIRST_LINE
#define LINE_IS_FIRST_LINE 0x8
#endif
#define LINE_WAS_DIRTY 0x10
class nsISpaceManager;
class nsLineBox;
//----------------------------------------------------------------------
class nsFloaterCache;
class nsFloaterCacheList;
class nsFloaterCacheFreeList;
// State cached after reflowing a floater. This state is used during
// incremental reflow when we avoid reflowing a floater.
class nsFloaterCache {
public:
nsFloaterCache();
~nsFloaterCache() { }
nsFloaterCache* Next() const { return mNext; }
nsPlaceholderFrame* mPlaceholder; // nsPlaceholderFrame
// This will be true if the floater was placed on the current line
// instead of below the current line.
PRBool mIsCurrentLineFloater;
nsMargin mMargins; // computed margins
nsMargin mOffsets; // computed offsets (relative pos)
// Region in the spacemanager impacted by this floater; the
// coordinates are relative to the containing block frame. The
// region includes the margins around the floater, but doesn't
// include the relative offsets.
nsRect mRegion;
// Combined area for the floater. This will not include the margins
// for the floater. Like mRegion, the coordinates are relative to
// the containing block frame.
nsRect mCombinedArea;
protected:
nsFloaterCache* mNext;
friend class nsFloaterCacheList;
friend class nsFloaterCacheFreeList;
};
//----------------------------------------
class nsFloaterCacheList {
public:
nsFloaterCacheList() : mHead(nsnull) { }
~nsFloaterCacheList();
PRBool IsEmpty() const {
return nsnull == mHead;
}
PRBool NotEmpty() const {
return nsnull != mHead;
}
nsFloaterCache* Head() const {
return mHead;
}
nsFloaterCache* Tail() const;
nsFloaterCache* Find(nsIFrame* aOutOfFlowFrame);
void Remove(nsFloaterCache* aElement);
void Append(nsFloaterCacheFreeList& aList);
protected:
nsFloaterCache* mHead;
friend class nsFloaterCacheFreeList;
};
//---------------------------------------
class nsFloaterCacheFreeList : public nsFloaterCacheList {
public:
nsFloaterCacheFreeList() : mTail(nsnull) { }
~nsFloaterCacheFreeList() { }
// Steal away aList's nsFloaterCache objects and put them on this
// free-list.
void Append(nsFloaterCacheList& aList);
void Append(nsFloaterCache* aFloaterCache);
// Allocate a new nsFloaterCache object
nsFloaterCache* Alloc();
protected:
nsFloaterCache* mTail;
friend class nsFloaterCacheList;
};
//----------------------------------------------------------------------
/**
* The nsLineBox class represents a horizontal line of frames. It contains
* enough state to support incremental reflow of the frames, event handling
* for the frames, and rendering of the frames.
*/
class nsLineBox {
public:
nscoord GetCarriedOutBottomMargin() const {
return mCarriedOutBottomMargin;
}
nscoord GetHeight() const { return mBounds.height; }
//----------------------------------------------------------------------
// XXX old junk
nsLineBox(nsIFrame* aFrame, PRInt32 aCount, PRUint16 flags);
~nsLineBox();
static void DeleteLineList(nsIPresContext& aPresContext, nsLineBox* aLine);
static nsLineBox* LastLine(nsLineBox* aLine);
static nsLineBox* FindLineContaining(nsLineBox* aLine, nsIFrame* aFrame,
PRInt32* aFrameIndexInLine);
void List(FILE* out, PRInt32 aIndent) const;
PRInt32 ChildCount() const {
return PRInt32(mChildCount);
}
nsIFrame* LastChild() const;
PRBool IsLastChild(nsIFrame* aFrame) const;
PRBool IsBlock() const {
return 0 != (LINE_IS_BLOCK & mState);
}
void SetIsBlock() {
mState |= LINE_IS_BLOCK;
}
void ClearIsBlock() {
mState &= ~LINE_IS_BLOCK;
}
void SetIsBlock(PRBool aValue) {
if (aValue) {
SetIsBlock();
}
else {
ClearIsBlock();
}
}
void SetLineIsImpactedByFloater(PRBool aValue) {
if (aValue) {
mState |= LINE_IS_IMPACTED_BY_FLOATER;
}
else {
mState &= ~LINE_IS_IMPACTED_BY_FLOATER;
}
}
PRBool IsImpactedByFloater() const {
return 0 != (LINE_IS_IMPACTED_BY_FLOATER & mState);
}
#ifdef BLOCK_DOES_FIRST_LINE
PRBool IsFirstLine() const {
return 0 != (LINE_IS_FIRST_LINE & mState);
}
void SetIsFirstLine(PRBool aValue) {
if (aValue) {
mState |= LINE_IS_FIRST_LINE;
}
else {
mState &= ~LINE_IS_FIRST_LINE;
}
}
#endif
void MarkDirty() {
mState |= LINE_IS_DIRTY;
}
void ClearDirty() {
mState &= ~LINE_IS_DIRTY;
}
PRBool IsDirty() const {
return 0 != (LINE_IS_DIRTY & mState);
}
void ClearWasDirty() {
mState &= ~LINE_WAS_DIRTY;
}
void MarkWasDirty() {
mState |= LINE_WAS_DIRTY;
}
PRBool WasDirty() const {
return 0 != (LINE_WAS_DIRTY & mState);
}
char* StateToString(char* aBuf, PRInt32 aBufSize) const;
PRInt32 IndexOf(nsIFrame* aFrame) const;
PRBool Contains(nsIFrame* aFrame) const {
return IndexOf(aFrame) >= 0;
}
#ifdef NS_DEBUG
PRBool CheckIsBlock() const;
#endif
nsIFrame* mFirstChild;
PRUint16 mChildCount;
PRUint8 mState;
PRUint8 mBreakType;
nsRect mBounds;
nsRect mCombinedArea;
nscoord mCarriedOutBottomMargin;/* XXX switch to 16 bits */
nsFloaterCacheList mFloaters;
nsLineBox* mNext;
nscoord mMaxElementWidth; // width part of max-element-size
};
//----------------------------------------------------------------------
class nsLineIterator : public nsILineIterator {
public:
nsLineIterator();
virtual ~nsLineIterator();
NS_DECL_ISUPPORTS
NS_IMETHOD GetNumLines(PRInt32* aResult);
NS_IMETHOD GetDirection(PRBool* aIsRightToLeft);
NS_IMETHOD GetLine(PRInt32 aLineNumber,
nsIFrame** aFirstFrameOnLine,
PRInt32* aNumFramesOnLine,
nsRect& aLineBounds);
NS_IMETHOD FindLineContaining(nsIFrame* aFrame,
PRInt32* aLineNumberResult);
NS_IMETHOD FindLineAt(nscoord aY,
PRInt32* aLineNumberResult);
NS_IMETHOD FindFrameAt(PRInt32 aLineNumber,
nscoord aX,
nsIFrame** aFrameFound,
PRBool* aXIsBeforeFirstFrame,
PRBool* aXIsAfterLastFrame);
nsresult Init(nsLineBox* aLines, PRBool aRightToLeft);
protected:
PRInt32 NumLines() const {
return mNumLines;
}
nsLineBox* CurrentLine() {
return mLines[mIndex];
}
nsLineBox* PrevLine() {
if (0 == mIndex) {
return nsnull;
}
return mLines[--mIndex];
}
nsLineBox* NextLine() {
if (mIndex >= mNumLines - 1) {
return nsnull;
}
return mLines[++mIndex];
}
nsLineBox* LineAt(PRInt32 aIndex) {
if ((aIndex < 0) || (aIndex >= mNumLines)) {
return nsnull;
}
return mLines[aIndex];
}
nsLineBox** mLines;
PRInt32 mIndex;
PRInt32 mNumLines;
PRBool mRightToLeft;
};
#endif /* nsLineBox_h___ */