Files
Mozilla/mozilla/layout/html/base/src/nsInlineReflow.h
kipp%netscape.com 25b61d53b3 Support for display: compact
git-svn-id: svn://10.0.0.236/trunk@14506 18797224-902f-48f8-a5cc-f745e15eee43
1998-11-12 16:32:19 +00:00

256 lines
7.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 nsInlineReflow_h___
#define nsInlineReflow_h___
#include "nsIFrame.h"
#include "nsIHTMLReflow.h"
class nsFrameReflowState;
class nsHTMLContainerFrame;
class nsLineLayout;
struct nsStyleDisplay;
struct nsStylePosition;
struct nsStyleSpacing;
// XXX Make this class handle x,y offsets from the outer state's
// borderpadding value.
/** A class that implements a css compatible horizontal reflow
* algorithm. Frames are stacked left to right (or right to left)
* until the horizontal space runs out. Then the 1 or more frames are
* vertically aligned, horizontally positioned and relatively
* positioned. */
class nsInlineReflow {
public:
nsInlineReflow(nsLineLayout& aLineLayout,
nsFrameReflowState& aOuterReflowState,
nsHTMLContainerFrame* aOuter,
PRBool aOuterIsBlock);
~nsInlineReflow();
void Init(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight);
void SetIsFirstChild(PRBool aValue) {
mIsFirstChild = aValue;
}
void SetRunInFrame(nsBlockFrame* aBlockFrame) {
mRunInFrame = aBlockFrame;
}
void SetCompactMarginWidth(nscoord aWidth) {
mCompactMarginWidth = aWidth;
}
void UpdateBand(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight,
PRBool aPlacedLeftFloater);
nsReflowStatus ReflowFrame(nsIFrame* aFrame);
void VerticalAlignFrames(nsRect& aLineBox,
nscoord& aMaxAscent,
nscoord& aMaxDescent);
void HorizontalAlignFrames(nsRect& aLineBox,
PRBool aIsLastLine = PR_FALSE);
void RelativePositionFrames(nsRect& aCombinedArea);
PRInt32 GetCurrentFrameNum() const { return mFrameNum; }
void ChangeFrameCount(PRInt32 aCount) {
NS_ASSERTION(aCount <= mFrameNum, "bad change frame count");
mFrameNum = aCount;
}
PRBool GetIsBlock() const { return mIsBlock; }
const nsSize& GetMaxElementSize() const { return mMaxElementSize; }
nscoord GetCarriedOutTopMargin() const { return mCarriedOutTopMargin; }
nscoord GetCarriedOutBottomMargin() const { return mCarriedOutBottomMargin; }
nscoord GetCarriedOutMarginFlags() const { return mCarriedOutMarginFlags; }
nscoord GetTopMargin() const {
return mFrameData->mMargin.top;
}
nscoord GetBottomMargin() const {
return mFrameData->mMargin.bottom;
}
PRUintn GetMarginFlags() const {
return mFrameData->mMarginFlags;
}
nscoord GetAvailWidth() const {
return mRightEdge - mX;
}
static PRUintn CalculateBlockMarginsFor(nsIPresContext& aPresContext,
nsIFrame* aFrame,
const nsStyleSpacing* aSpacing,
nsMargin& aMargin);
// Return value from CalculateBlockMarginsFor
#define NS_TOP_MARGIN_IS_AUTO 0x1
#define NS_BOTTOM_MARGIN_IS_AUTO 0x2
static nscoord MaxMargin(nscoord a, nscoord b);
/**
* Calculate the line-height value for a given frame.
*/
static nscoord CalcLineHeightFor(nsIPresContext& aPresContext,
nsIFrame* aFrame,
nscoord aBaseLineHeight);
protected:
nsresult SetFrame(nsIFrame* aFrame);
PRBool TreatFrameAsBlockFrame();
const nsStyleDisplay* GetDisplay();
const nsStylePosition* GetPosition();
const nsStyleSpacing* GetSpacing();
void CalculateMargins();
void ApplyTopLeftMargins();
PRBool ComputeAvailableSize();
PRBool ReflowFrame(nsHTMLReflowMetrics& aMetrics,
nsReflowStatus& aStatus);
PRBool CanPlaceFrame(nsHTMLReflowMetrics& aMetrics,
nsReflowStatus& aStatus);
void PlaceFrame(nsHTMLReflowMetrics& aMetrics);
void UpdateFrames();
void JustifyFrames(nscoord aMaxWidth, nsRect& aLineBox);
// The outer frame that contains the frames that we reflow.
nsHTMLContainerFrame* mOuterFrame;
nsISpaceManager* mSpaceManager;
nsLineLayout& mLineLayout;
nsFrameReflowState& mOuterReflowState;
nsIPresContext& mPresContext;
PRBool mOuterIsBlock;
nsBlockFrame* mRunInFrame;
nscoord mCompactMarginWidth;
PRIntn mFrameNum;
/*
* For each frame reflowed, we keep this state around
*/
struct PerFrameData {
nsIFrame* mFrame;
nscoord mAscent; // computed ascent value
nscoord mDescent; // computed descent value
nsMargin mMargin; // computed margin value
PRUintn mMarginFlags;
// Location and size of frame after its reflowed but before it is
// positioned finally by VerticalAlignFrames
nsRect mBounds;
// Combined area value from nsHTMLReflowMetrics
nsRect mCombinedArea;
nsSize mMaxElementSize;
PRBool mSplittable;
};
PerFrameData* mFrameData;
PerFrameData* mFrameDataBase;
PerFrameData mFrameDataBuf[20];
PRIntn mNumFrameData;
// Current frame state
const nsStyleSpacing* mSpacing;
const nsStylePosition* mPosition;
const nsStyleDisplay* mDisplay;
PRBool mTreatFrameAsBlock; // treat the frame as a block frame
// Entire reflow should act like a block; this means that somewhere
// during reflow we encountered a block frame. There can be more one
// than one frame in the reflow group (because of empty frames), so
// this flag keeps us honest regarding the state of this reflow.
PRBool mIsBlock;
PRBool mCanBreakBeforeFrame; // we can break before the frame
PRBool mIsFirstChild;
PRBool mComputeMaxElementSize;
nsSize mMaxElementSize;
// The frame's computed margin values (includes auto value
// computation)
nscoord mRightMargin;/* XXX */
nscoord mCarriedOutTopMargin;
nscoord mCarriedOutBottomMargin;
PRUintn mCarriedOutMarginFlags;
// The computed available size and location for the frame
nsSize mFrameAvailSize;
nscoord mLeftEdge;
nscoord mX;
nscoord mRightEdge;
nscoord mTopEdge;
nscoord mBottomEdge;
PRBool mUpdatedBand;
PRBool mPlacedLeftFloater;
PRBool mInWord;
};
inline nscoord
nsInlineReflow::MaxMargin(nscoord a, nscoord b)
{
if (a < 0) {
if (b < 0) {
if (a < b) return a;
return b;
}
return b + a;
}
else if (b < 0) {
return a + b;
}
if (a > b) return a;
return b;
}
#endif /* nsInlineReflow_h___ */