mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-21 01:37:16 +00:00
nuked
This commit is contained in:
parent
bfc5f6a627
commit
c60547b531
@ -1,131 +0,0 @@
|
||||
/* -*- 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 "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
#ifndef nsInlineFrame_h___
|
||||
#define nsInlineFrame_h___
|
||||
|
||||
#include "nsHTMLContainerFrame.h"
|
||||
#include "nsInlineLayout.h"
|
||||
#include "nsLineLayout.h"
|
||||
|
||||
class nsInlineFrame;
|
||||
class nsPlaceholderFrame;
|
||||
|
||||
/**
|
||||
* Reflow state object for managing css inline layout. Most of the state
|
||||
* is managed by the nsInlineLayout object.
|
||||
*/
|
||||
struct nsInlineReflowState : public nsReflowState {
|
||||
nsInlineReflowState(nsLineLayout& aLineLayout,
|
||||
nsInlineFrame* aInlineFrame,
|
||||
nsIStyleContext* aInlineSC,
|
||||
const nsReflowState& aReflowState,
|
||||
PRBool aComputeMaxElementSize);
|
||||
~nsInlineReflowState();
|
||||
|
||||
nsIPresContext* mPresContext;
|
||||
nsInlineLayout mInlineLayout;
|
||||
|
||||
nsIFrame* mLastChild; // last child we have reflowed (so far)
|
||||
|
||||
nsMargin mBorderPadding;
|
||||
PRBool mNoWrap;
|
||||
PRIntn mStyleSizeFlags;
|
||||
nsSize mStyleSize;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* CSS "inline" layout class.
|
||||
*
|
||||
* Note: This class does not support being used as a pseudo frame.
|
||||
*/
|
||||
class nsInlineFrame : public nsHTMLContainerFrame,
|
||||
public nsIInlineReflow
|
||||
{
|
||||
public:
|
||||
// nsISupports
|
||||
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
|
||||
|
||||
// nsIFrame
|
||||
NS_IMETHOD Init(nsIPresContext& aPresContext, nsIFrame* aChildList);
|
||||
NS_IMETHOD CreateContinuingFrame(nsIPresContext& aCX,
|
||||
nsIFrame* aParent,
|
||||
nsIStyleContext* aStyleContext,
|
||||
nsIFrame*& aContinuingFrame);
|
||||
#if XXX_not_yet
|
||||
NS_IMETHOD Reflow(nsIPresContext& aPresContext,
|
||||
nsReflowMetrics& aDesiredSize,
|
||||
const nsReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
#endif
|
||||
|
||||
// nsIInlineReflow
|
||||
NS_IMETHOD FindTextRuns(nsLineLayout& aLineLayout,
|
||||
nsIReflowCommand* aReflowCommand);
|
||||
NS_IMETHOD InlineReflow(nsLineLayout& aLineLayout,
|
||||
nsReflowMetrics& aDesiredSize,
|
||||
const nsReflowState& aReflowState);
|
||||
|
||||
// nsContainerFrame
|
||||
virtual PRBool DeleteNextInFlowsFor(nsIPresContext& aPresContext, nsIFrame* aChild);
|
||||
|
||||
protected:
|
||||
nsInlineFrame(nsIContent* aContent, nsIFrame* aParent);
|
||||
|
||||
virtual ~nsInlineFrame();
|
||||
|
||||
virtual PRIntn GetSkipSides() const;
|
||||
|
||||
nsresult InitialReflow(nsInlineReflowState& aState);
|
||||
|
||||
nsresult FrameAppendedReflow(nsInlineReflowState& aState);
|
||||
|
||||
nsresult ChildIncrementalReflow(nsInlineReflowState& aState);
|
||||
|
||||
nsresult ResizeReflow(nsInlineReflowState& aState);
|
||||
|
||||
void ComputeFinalSize(nsInlineReflowState& aState,
|
||||
nsReflowMetrics& aMetrics);
|
||||
|
||||
PRBool ReflowMapped(nsInlineReflowState& aState,
|
||||
nsInlineReflowStatus& aReflowStatus);
|
||||
|
||||
PRBool PullUpChildren(nsInlineReflowState& aState,
|
||||
nsInlineReflowStatus& aReflowStatus);
|
||||
|
||||
nsIFrame* PullOneChild(nsInlineFrame* aNextInFlow,
|
||||
nsIFrame* aLastChild);
|
||||
|
||||
nsresult MaybeCreateNextInFlow(nsInlineReflowState& aState,
|
||||
nsIFrame* aFrame);
|
||||
|
||||
void PushKids(nsInlineReflowState& aState,
|
||||
nsIFrame* aPrevChild, nsIFrame* aPushedChild);
|
||||
|
||||
void DrainOverflowLists();
|
||||
|
||||
nsresult AppendNewFrames(nsIPresContext* aPresContext, nsIFrame*);
|
||||
|
||||
void InsertNewFrame(nsIFrame* aNewFrame, nsIFrame* aPrevSibling);
|
||||
|
||||
friend nsresult NS_NewInlineFrame(nsIContent* aContent, nsIFrame* aParentFrame,
|
||||
nsIFrame*& aNewFrame);
|
||||
};
|
||||
|
||||
#endif /* nsInlineFrame_h___ */
|
@ -1,126 +0,0 @@
|
||||
/* -*- 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 "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
#include "nsAbsoluteFrame.h"
|
||||
#include "nsFrame.h"
|
||||
#include "nsHTMLBase.h"
|
||||
#include "nsPlaceholderFrame.h"
|
||||
#include "nsScrollFrame.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsViewsCID.h"
|
||||
|
||||
#include "nsIPresContext.h"
|
||||
#include "nsIStyleContext.h"
|
||||
#include "nsIView.h"
|
||||
#include "nsIViewManager.h"
|
||||
#include "nsHTMLAtoms.h"
|
||||
|
||||
nsresult
|
||||
nsHTMLBase::CreateViewForFrame(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
nsIStyleContext* aStyleContext,
|
||||
PRBool aForce)
|
||||
{
|
||||
nsIView* view;
|
||||
aFrame->GetView(view);
|
||||
if (nsnull == view) {
|
||||
// We don't yet have a view; see if we need a view
|
||||
|
||||
// See if the opacity is not the same as the geometric parent
|
||||
// frames opacity.
|
||||
if (!aForce) {
|
||||
nsIFrame* parent;
|
||||
aFrame->GetGeometricParent(parent);
|
||||
if (nsnull != parent) {
|
||||
// Get my nsStyleColor
|
||||
const nsStyleColor* myColor = (const nsStyleColor*)
|
||||
aStyleContext->GetStyleData(eStyleStruct_Color);
|
||||
|
||||
// Get parent's nsStyleColor
|
||||
const nsStyleColor* parentColor;
|
||||
parent->GetStyleData(eStyleStruct_Color, (const nsStyleStruct*&)parentColor);
|
||||
|
||||
// If the opacities are different then I need a view
|
||||
if (myColor->mOpacity != parentColor->mOpacity) {
|
||||
NS_FRAME_LOG(NS_FRAME_TRACE_CALLS,
|
||||
("nsHTMLBase::CreateViewForFrame: frame=%p opacity=%g parentOpacity=%g",
|
||||
aFrame, myColor->mOpacity, parentColor->mOpacity));
|
||||
aForce = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// See if the frame is being relatively positioned
|
||||
if (!aForce) {
|
||||
const nsStylePosition* position = (const nsStylePosition*)
|
||||
aStyleContext->GetStyleData(eStyleStruct_Position);
|
||||
if (NS_STYLE_POSITION_RELATIVE == position->mPosition) {
|
||||
NS_FRAME_LOG(NS_FRAME_TRACE_CALLS,
|
||||
("nsHTMLBase::CreateViewForFrame: frame=%p relatively positioned",
|
||||
aFrame));
|
||||
aForce = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (aForce) {
|
||||
// Create a view
|
||||
nsIFrame* parent;
|
||||
nsIView* view;
|
||||
|
||||
aFrame->GetParentWithView(parent);
|
||||
NS_ASSERTION(parent, "GetParentWithView failed");
|
||||
nsIView* parView;
|
||||
|
||||
parent->GetView(parView);
|
||||
NS_ASSERTION(parView, "no parent with view");
|
||||
|
||||
// Create a view
|
||||
static NS_DEFINE_IID(kViewCID, NS_VIEW_CID);
|
||||
static NS_DEFINE_IID(kIViewIID, NS_IVIEW_IID);
|
||||
|
||||
nsresult result = nsRepository::CreateInstance(kViewCID,
|
||||
nsnull,
|
||||
kIViewIID,
|
||||
(void **)&view);
|
||||
if (NS_OK == result) {
|
||||
nsIView* rootView = parView;
|
||||
nsIViewManager* viewManager;
|
||||
rootView->GetViewManager(viewManager);
|
||||
|
||||
// Initialize the view
|
||||
NS_ASSERTION(nsnull != viewManager, "null view manager");
|
||||
|
||||
nsRect bounds;
|
||||
aFrame->GetRect(bounds);
|
||||
view->Init(viewManager, bounds, rootView);
|
||||
viewManager->InsertChild(rootView, view, 0);
|
||||
|
||||
NS_RELEASE(viewManager);
|
||||
}
|
||||
|
||||
// Remember our view
|
||||
aFrame->SetView(view);
|
||||
|
||||
NS_FRAME_LOG(NS_FRAME_TRACE_CALLS,
|
||||
("nsHTMLBase::CreateViewForFrame: frame=%p view=%p",
|
||||
aFrame));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1,38 +0,0 @@
|
||||
/* -*- 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 "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
#ifndef nsHTMLBase_h___
|
||||
#define nsHTMLBase_h___
|
||||
|
||||
#include "nsIFrame.h"
|
||||
|
||||
// This is a class whose purpose is to provide shared code that is
|
||||
// common to all html frames, including containers and leaf frames.
|
||||
class nsHTMLBase {
|
||||
public:
|
||||
/**
|
||||
* Create a view for a frame if it needs one. A frame needs a view
|
||||
* if it requires a scrollbar, is relatively positioned or has a
|
||||
* non opaque opacity.
|
||||
*/
|
||||
static nsresult CreateViewForFrame(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
nsIStyleContext* aStyleContext,
|
||||
PRBool aForce);
|
||||
};
|
||||
|
||||
#endif /* nsHTMLBase_h___ */
|
@ -1,500 +0,0 @@
|
||||
/* -*- 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.
|
||||
*/
|
||||
#include "nsInlineLayout.h"
|
||||
#include "nsLineLayout.h"
|
||||
#include "nsCSSLayout.h"
|
||||
#include "nsHTMLIIDs.h"
|
||||
#include "nsContainerFrame.h"
|
||||
|
||||
#include "nsIFontMetrics.h"
|
||||
#include "nsIStyleContext.h"
|
||||
#include "nsIPresContext.h"
|
||||
#include "nsIReflowCommand.h"
|
||||
#include "nsIRunaround.h"
|
||||
#include "nsISpaceManager.h"
|
||||
|
||||
nsInlineLayout::nsInlineLayout(nsLineLayout& aLineLayout,
|
||||
nsContainerFrame* aContainerFrame,
|
||||
nsIStyleContext* aContainerStyle)
|
||||
: mLineLayout(aLineLayout)
|
||||
{
|
||||
mContainerFrame = aContainerFrame;
|
||||
mAscents = mAscentBuf;
|
||||
mMaxAscents = sizeof(mAscentBuf) / sizeof(mAscentBuf[0]);
|
||||
|
||||
mContainerFont = (const nsStyleFont*)
|
||||
aContainerStyle->GetStyleData(eStyleStruct_Font);
|
||||
mContainerText = (const nsStyleText*)
|
||||
aContainerStyle->GetStyleData(eStyleStruct_Text);
|
||||
mContainerDisplay = (const nsStyleDisplay*)
|
||||
aContainerStyle->GetStyleData(eStyleStruct_Display);
|
||||
mDirection = mContainerDisplay->mDirection;
|
||||
mIsBullet = PR_FALSE;
|
||||
mHaveBullet = PR_FALSE;
|
||||
mNextRCFrame = nsnull;
|
||||
}
|
||||
|
||||
nsInlineLayout::~nsInlineLayout()
|
||||
{
|
||||
if (mAscents != mAscentBuf) {
|
||||
delete [] mAscents;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsInlineLayout::Init(const nsReflowState* aContainerReflowState)
|
||||
{
|
||||
mContainerReflowState = aContainerReflowState;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsInlineLayout::SetAscent(nscoord aAscent)
|
||||
{
|
||||
PRInt32 frameNum = mFrameNum;
|
||||
if (frameNum == mMaxAscents) {
|
||||
mMaxAscents *= 2;
|
||||
nscoord* newAscents = new nscoord[mMaxAscents];
|
||||
if (nsnull == newAscents) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
nsCRT::memcpy(newAscents, mAscents, sizeof(nscoord) * frameNum);
|
||||
if (mAscents != mAscentBuf) {
|
||||
delete [] mAscents;
|
||||
}
|
||||
mAscents = newAscents;
|
||||
}
|
||||
mAscents[frameNum] = aAscent;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsInlineLayout::Prepare(PRBool aUnconstrainedWidth,
|
||||
PRBool aNoWrap,
|
||||
PRBool aComputeMaxElementSize)
|
||||
{
|
||||
mIsBullet = PR_FALSE;
|
||||
mHaveBullet = PR_FALSE;
|
||||
mFrameNum = 0;
|
||||
mUnconstrainedWidth = aUnconstrainedWidth;
|
||||
mNoWrap = aNoWrap;
|
||||
mComputeMaxElementSize = aComputeMaxElementSize;
|
||||
if (aComputeMaxElementSize) {
|
||||
mMaxElementSize.width = 0;
|
||||
mMaxElementSize.height = 0;
|
||||
}
|
||||
mMaxAscent = 0;
|
||||
mMaxDescent = 0;
|
||||
}
|
||||
|
||||
void
|
||||
nsInlineLayout::SetReflowSpace(nscoord aX, nscoord aY,
|
||||
nscoord aAvailWidth, nscoord aAvailHeight)
|
||||
{
|
||||
mAvailWidth = aAvailWidth;
|
||||
mAvailHeight = aAvailHeight;
|
||||
mX = aX;
|
||||
mY = aY;
|
||||
mLeftEdge = aX;
|
||||
mRightEdge = aX + aAvailWidth;
|
||||
}
|
||||
|
||||
//XXX block children of inline frames needs handling *here*
|
||||
|
||||
nsInlineReflowStatus
|
||||
nsInlineLayout::ReflowAndPlaceFrame(nsIFrame* aFrame)
|
||||
{
|
||||
NS_FRAME_LOG(NS_FRAME_TRACE_CHILD_REFLOW,
|
||||
("nsInlineLayout::ReflowAndPlaceFrame: frame=%p x=%d",
|
||||
aFrame, mX));
|
||||
|
||||
// If the frame is a block frame and this is not the first frame on
|
||||
// the line, we need to break before the block frame.
|
||||
const nsStyleDisplay* kidDisplay;
|
||||
aFrame->GetStyleData(eStyleStruct_Display,
|
||||
(const nsStyleStruct*&) kidDisplay);
|
||||
const nsStylePosition* kidPosition;
|
||||
aFrame->GetStyleData(eStyleStruct_Position,
|
||||
(const nsStyleStruct*&) kidPosition);
|
||||
PRBool isBlock = nsLineLayout::TreatFrameAsBlock(kidDisplay, kidPosition);
|
||||
if (isBlock && !IsFirstChild()) {
|
||||
return NS_INLINE_LINE_BREAK_BEFORE(0);/* XXX indicate never-reflowed? */
|
||||
}
|
||||
|
||||
// Compute the maximum size of the frame. If there is no room at all
|
||||
// for it, then trigger a line-break before the frame.
|
||||
nsSize maxSize;
|
||||
nsMargin margin;
|
||||
if (!ComputeMaxSize(aFrame, margin, maxSize)) {
|
||||
NS_FRAME_LOG(NS_FRAME_TRACE_CHILD_REFLOW,
|
||||
("nsInlineLayout::ReflowAndPlaceFrame: break-before"));
|
||||
return NS_INLINE_LINE_BREAK_BEFORE(0);/* XXX indicate never-reflowed? */
|
||||
}
|
||||
|
||||
// Get reflow reason set correctly. It's possible that we created a
|
||||
// child and then decided that we cannot reflow it (for example, a
|
||||
// block frame that isn't at the start of a line). In this case the
|
||||
// reason will be wrong so we need to check the frame state.
|
||||
nsReflowReason reason = eReflowReason_Resize;
|
||||
nsFrameState state;
|
||||
aFrame->GetFrameState(state);
|
||||
if (NS_FRAME_FIRST_REFLOW & state) {
|
||||
reason = eReflowReason_Initial;
|
||||
}
|
||||
else if (mNextRCFrame == aFrame) {
|
||||
reason = eReflowReason_Incremental;
|
||||
// Make sure we only incrementally reflow once
|
||||
mNextRCFrame = nsnull;
|
||||
}
|
||||
|
||||
// Setup reflow state for reflowing the frame
|
||||
nsReflowState reflowState(aFrame, *mContainerReflowState, maxSize);
|
||||
reflowState.reason = reason;
|
||||
nsInlineReflowStatus rs;
|
||||
nsSize frameMaxElementSize;
|
||||
nsReflowMetrics metrics(mComputeMaxElementSize
|
||||
? &frameMaxElementSize
|
||||
: nsnull);
|
||||
PRBool isAware;
|
||||
aFrame->WillReflow(*mLineLayout.mPresContext);
|
||||
rs = ReflowFrame(aFrame, metrics, reflowState, isAware);
|
||||
if (NS_IS_REFLOW_ERROR(rs)) {
|
||||
return rs;
|
||||
}
|
||||
if (NS_INLINE_IS_BREAK_BEFORE(rs)) {
|
||||
return rs;
|
||||
}
|
||||
|
||||
// XXX we need to do this because blocks depend on it; we shouldn't expect
|
||||
// the child frame to deal with it.
|
||||
if (eReflowReason_Initial == reason) {
|
||||
aFrame->GetFrameState(state);
|
||||
aFrame->SetFrameState(state & ~NS_FRAME_FIRST_REFLOW);
|
||||
}
|
||||
|
||||
// XXX the 0,0 part of this is hack: get rid of it
|
||||
if (!isAware && ((0 != metrics.width) || (0 != metrics.height))) {
|
||||
mLineLayout.SetSkipLeadingWhiteSpace(PR_FALSE);
|
||||
}
|
||||
|
||||
// It's possible the frame didn't fit
|
||||
if (metrics.width > maxSize.width) {
|
||||
if (!IsFirstChild()) {
|
||||
// We are out of room.
|
||||
// XXX mKidPrevInFlow
|
||||
NS_FRAME_LOG(NS_FRAME_TRACE_CHILD_REFLOW,
|
||||
("nsInlineLayout::ReflowAndPlaceFrame: !fit size=%d,%d",
|
||||
metrics.width, metrics.height));
|
||||
|
||||
// XXX if the child requested a break and we need to break too...
|
||||
|
||||
return NS_INLINE_LINE_BREAK_BEFORE(0);
|
||||
}
|
||||
}
|
||||
|
||||
nsRect frameRect(mX, mY, metrics.width, metrics.height);
|
||||
return PlaceFrame(aFrame, frameRect, metrics, margin, rs, isBlock);
|
||||
}
|
||||
|
||||
// XXX RTL
|
||||
PRBool
|
||||
nsInlineLayout::IsFirstChild()
|
||||
{
|
||||
if (mHaveBullet) {
|
||||
return mFrameNum < 2;
|
||||
}
|
||||
return mFrameNum < 1;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsInlineLayout::ComputeMaxSize(nsIFrame* aFrame,
|
||||
nsMargin& aKidMargin,
|
||||
nsSize& aResult)
|
||||
{
|
||||
const nsStyleSpacing* kidSpacing;
|
||||
aFrame->GetStyleData(eStyleStruct_Spacing,
|
||||
(const nsStyleStruct*&)kidSpacing);
|
||||
kidSpacing->CalcMarginFor(aFrame, aKidMargin);
|
||||
if (mUnconstrainedWidth || mNoWrap) {
|
||||
aResult.width = NS_UNCONSTRAINEDSIZE;
|
||||
}
|
||||
else {
|
||||
aResult.width = mRightEdge - mX;
|
||||
aResult.width -= aKidMargin.left + aKidMargin.right;
|
||||
// Note: We let zero sneak through here in case the next child is
|
||||
// either something that gets compressed into zero or is a BR
|
||||
// (which is zero width)
|
||||
if (!IsFirstChild() && (aResult.width < 0)) {
|
||||
// XXX Make sure child is dirty for next time
|
||||
aFrame->WillReflow(*mLineLayout.mPresContext);
|
||||
NS_FRAME_LOG(NS_FRAME_TRACE_CHILD_REFLOW,
|
||||
("nsInlineLayout::ComputeMaxSize: !fit"));
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// Give the child a limited height in case it's a block child and
|
||||
// our height was limited.
|
||||
aResult.height = mAvailHeight;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
nsInlineReflowStatus
|
||||
nsInlineLayout::ReflowFrame(nsIFrame* aKidFrame,
|
||||
nsReflowMetrics& aMetrics,
|
||||
const nsReflowState& aReflowState,
|
||||
PRBool& aInlineAware)
|
||||
{
|
||||
// There are 3 ways to reflow the child frame: using the nsIRunaround
|
||||
// interface, using the nsIInlineReflow interface or using the default
|
||||
// Reflow method in nsIFrame. The order of precedence is nsIRunaround,
|
||||
// nsIInlineReflow, nsIFrame. For all three API's we map the reflow status
|
||||
// into an nsInlineReflowStatus.
|
||||
|
||||
NS_ASSERTION(nsnull != mLineLayout.mSpaceManager, "yikes");
|
||||
nsresult rv;
|
||||
nsIRunaround* runAround;
|
||||
nsIInlineReflow* inlineReflow;
|
||||
|
||||
// Make local copies of x,y in case what we are reflowing is a
|
||||
// floater and the floater ends up being a left aligned
|
||||
// current-line-floater (which means it will adjust our mX value)
|
||||
nscoord x = mX;
|
||||
nscoord y = mY;
|
||||
|
||||
if ((nsnull != mLineLayout.mSpaceManager) &&
|
||||
(NS_OK == aKidFrame->QueryInterface(kIRunaroundIID,
|
||||
(void**)&runAround))) {
|
||||
nsRect r;
|
||||
mLineLayout.mSpaceManager->Translate(x, y);
|
||||
runAround->ReflowAround(*mLineLayout.mPresContext,
|
||||
mLineLayout.mSpaceManager,
|
||||
aMetrics, aReflowState, r, rv);
|
||||
mLineLayout.mSpaceManager->Translate(-x, -y);
|
||||
|
||||
aMetrics.width = r.width;
|
||||
aMetrics.height = r.height;
|
||||
aMetrics.ascent = r.height;
|
||||
aMetrics.descent = 0;
|
||||
aInlineAware = PR_FALSE;
|
||||
}
|
||||
else if (NS_OK == aKidFrame->QueryInterface(kIInlineReflowIID,
|
||||
(void**)&inlineReflow)) {
|
||||
mLineLayout.mSpaceManager->Translate(x, y);
|
||||
rv = inlineReflow->InlineReflow(mLineLayout, aMetrics, aReflowState);
|
||||
mLineLayout.mSpaceManager->Translate(-x, -y);
|
||||
aInlineAware = PR_TRUE;
|
||||
}
|
||||
else {
|
||||
mLineLayout.mSpaceManager->Translate(x, y);
|
||||
aKidFrame->Reflow(*mLineLayout.mPresContext, aMetrics, aReflowState, rv);
|
||||
mLineLayout.mSpaceManager->Translate(-x, -y);
|
||||
aInlineAware = PR_FALSE;
|
||||
}
|
||||
|
||||
if (NS_FRAME_IS_COMPLETE(rv)) {
|
||||
nsIFrame* kidNextInFlow;
|
||||
aKidFrame->GetNextInFlow(kidNextInFlow);
|
||||
if (nsnull != kidNextInFlow) {
|
||||
// Remove all of the childs next-in-flows. Make sure that we ask
|
||||
// the right parent to do the removal (it's possible that the
|
||||
// parent is not this because we are executing pullup code)
|
||||
nsIFrame* parent;
|
||||
aKidFrame->GetGeometricParent(parent);
|
||||
((nsHTMLContainerFrame*)parent)->DeleteNextInFlowsFor(*mLineLayout.mPresContext,
|
||||
aKidFrame);
|
||||
}
|
||||
}
|
||||
|
||||
NS_FRAME_LOG(NS_FRAME_TRACE_CHILD_REFLOW,
|
||||
("nsInlineLayout::ReflowFrame: frame=%p reflowStatus=%x %saware",
|
||||
aKidFrame, rv, aInlineAware ? "" :"not "));
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsInlineReflowStatus
|
||||
nsInlineLayout::PlaceFrame(nsIFrame* aFrame,
|
||||
nsRect& aFrameRect,
|
||||
const nsReflowMetrics& aFrameMetrics,
|
||||
const nsMargin& aFrameMargin,
|
||||
nsInlineReflowStatus aFrameReflowStatus,
|
||||
PRBool aIsBlock)
|
||||
{
|
||||
nscoord horizontalMargins = 0;
|
||||
|
||||
// XXX RTL
|
||||
// Special case to position outside list bullets.
|
||||
if (mIsBullet) {
|
||||
// We are placing the first child of the container and we have
|
||||
// list-style-position of "outside" therefore this is the
|
||||
// bullet that is being reflowed. The bullet is placed in the
|
||||
// padding area of this block. Don't worry about getting the Y
|
||||
// coordinate of the bullet right (vertical alignment will
|
||||
// take care of that).
|
||||
nsIFontMetrics* fm =
|
||||
mLineLayout.mPresContext->GetMetricsFor(mContainerFont->mFont);
|
||||
nscoord height;
|
||||
fm->GetHeight(height);
|
||||
nscoord dx = height / 2; // from old layout engine
|
||||
NS_RELEASE(fm);
|
||||
aFrameRect.x = mX - aFrameRect.width - dx;
|
||||
if (aFrameRect.x < 0) aFrameRect.x = 0;
|
||||
aFrame->SetRect(aFrameRect);
|
||||
}
|
||||
else {
|
||||
// Place normal in-flow child
|
||||
aFrame->SetRect(aFrameRect);
|
||||
|
||||
// Advance
|
||||
const nsStyleDisplay* frameDisplay;
|
||||
aFrame->GetStyleData(eStyleStruct_Display,
|
||||
(const nsStyleStruct*&) frameDisplay);
|
||||
switch (frameDisplay->mFloats) {
|
||||
default:
|
||||
NS_NOTYETIMPLEMENTED("Unsupported floater type");
|
||||
// FALL THROUGH
|
||||
|
||||
case NS_STYLE_FLOAT_LEFT:
|
||||
case NS_STYLE_FLOAT_RIGHT:
|
||||
// When something is floated, its margins are applied there
|
||||
// not here.
|
||||
break;
|
||||
|
||||
case NS_STYLE_FLOAT_NONE:
|
||||
horizontalMargins = aFrameMargin.left + aFrameMargin.right;
|
||||
break;
|
||||
}
|
||||
mX += aFrameMetrics.width + horizontalMargins;
|
||||
}
|
||||
|
||||
NS_FRAME_LOG(NS_FRAME_TRACE_CHILD_REFLOW,
|
||||
("nsInlineLayout::PlaceFrame: frame=%p {%d, %d, %d, %d}",
|
||||
aFrame,
|
||||
aFrameRect.x, aFrameRect.y,
|
||||
aFrameRect.width, aFrameRect.height));
|
||||
|
||||
// XXX this is not right; the max-element-size of a child depends on
|
||||
// its margins which it doesn't know how to add in
|
||||
|
||||
// Fold in child's max-element-size information into our own
|
||||
if (mComputeMaxElementSize) {
|
||||
if (aFrameMetrics.maxElementSize->width > mMaxElementSize.width) {
|
||||
mMaxElementSize.width = aFrameMetrics.maxElementSize->width;
|
||||
}
|
||||
if (aFrameMetrics.maxElementSize->height > mMaxElementSize.height) {
|
||||
mMaxElementSize.height = aFrameMetrics.maxElementSize->height;
|
||||
}
|
||||
}
|
||||
|
||||
if (aFrameMetrics.ascent > mMaxAscent) {
|
||||
mMaxAscent = aFrameMetrics.ascent;
|
||||
}
|
||||
if (aFrameMetrics.descent > mMaxDescent) {
|
||||
mMaxDescent = aFrameMetrics.descent;
|
||||
}
|
||||
nsresult rv = SetAscent(aFrameMetrics.ascent);
|
||||
if (NS_OK != rv) {
|
||||
return nsInlineReflowStatus(rv);
|
||||
}
|
||||
mFrameNum++;
|
||||
|
||||
if (aIsBlock) {
|
||||
if (!NS_INLINE_IS_BREAK(aFrameReflowStatus)) {
|
||||
aFrameReflowStatus =
|
||||
NS_INLINE_LINE_BREAK_AFTER(aFrameReflowStatus & NS_FRAME_NOT_COMPLETE);
|
||||
}
|
||||
}
|
||||
|
||||
return aFrameReflowStatus;
|
||||
}
|
||||
|
||||
void
|
||||
nsInlineLayout::AlignFrames(nsIFrame* aFrame, PRInt32 aFrameCount,
|
||||
nsRect& aBounds)
|
||||
{
|
||||
NS_PRECONDITION(aFrameCount == mFrameNum, "bogus reflow");
|
||||
|
||||
// Vertically align the children on the line; this will compute
|
||||
// the actual line height for us.
|
||||
|
||||
// XXX Fold in vertical alignment code here and make it update the
|
||||
// max ascent and max descent values properly. When line-height is
|
||||
// involved, give half of it to ascent and half to descent
|
||||
|
||||
nscoord lineHeight =
|
||||
nsCSSLayout::VerticallyAlignChildren(mLineLayout.mPresContext,
|
||||
mContainerFrame, mContainerFont,
|
||||
mY, aFrame, aFrameCount,
|
||||
mAscents, mMaxAscent/* XXX maxDescent */);
|
||||
nscoord lineWidth = mX - mLeftEdge;
|
||||
|
||||
// Save away line bounds before other adjustments
|
||||
aBounds.x = mLeftEdge;
|
||||
aBounds.y = mY;
|
||||
aBounds.width = lineWidth;
|
||||
aBounds.height = lineHeight;
|
||||
|
||||
// Now horizontally place the children
|
||||
if (!mUnconstrainedWidth && (mAvailWidth > lineWidth)) {
|
||||
nsCSSLayout::HorizontallyPlaceChildren(mLineLayout.mPresContext,
|
||||
mContainerFrame,
|
||||
mContainerText->mTextAlign,
|
||||
mDirection,
|
||||
aFrame, aFrameCount,
|
||||
lineWidth,
|
||||
mAvailWidth);
|
||||
}
|
||||
|
||||
// Last, apply relative positioning
|
||||
nsCSSLayout::RelativePositionChildren(mLineLayout.mPresContext,
|
||||
mContainerFrame,
|
||||
aFrame, aFrameCount);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsInlineLayout::MaybeCreateNextInFlow(nsIFrame* aFrame,
|
||||
nsIFrame*& aNextInFlowResult)
|
||||
{
|
||||
aNextInFlowResult = nsnull;
|
||||
|
||||
nsIFrame* nextInFlow;
|
||||
aFrame->GetNextInFlow(nextInFlow);
|
||||
if (nsnull == nextInFlow) {
|
||||
// Create a continuation frame for the child frame and insert it
|
||||
// into our lines child list.
|
||||
nsIFrame* nextFrame;
|
||||
aFrame->GetNextSibling(nextFrame);
|
||||
nsIStyleContext* kidSC;
|
||||
aFrame->GetStyleContext(mLineLayout.mPresContext, kidSC);
|
||||
aFrame->CreateContinuingFrame(*mLineLayout.mPresContext, mContainerFrame,
|
||||
kidSC, nextInFlow);
|
||||
NS_RELEASE(kidSC);
|
||||
if (nsnull == nextInFlow) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
aFrame->SetNextSibling(nextInFlow);
|
||||
nextInFlow->SetNextSibling(nextFrame);
|
||||
|
||||
NS_FRAME_LOG(NS_FRAME_TRACE_NEW_FRAMES,
|
||||
("nsInlineLayout::MaybeCreateNextInFlow: frame=%p nextInFlow=%p",
|
||||
aFrame, nextInFlow));
|
||||
|
||||
aNextInFlowResult = nextInFlow;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
@ -1,112 +0,0 @@
|
||||
/* -*- 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 nsInlineLayout_h___
|
||||
#define nsInlineLayout_h___
|
||||
|
||||
#include "nsHTMLContainerFrame.h"
|
||||
#include "nsIInlineReflow.h"
|
||||
class nsLineLayout;
|
||||
struct nsStyleDisplay;
|
||||
struct nsStyleFont;
|
||||
struct nsStyleText;
|
||||
|
||||
/**
|
||||
* This structure contains the horizontal layout state for line
|
||||
* layout frame placement. This is factored out of nsLineLayout so
|
||||
* that the block layout code and the inline layout code can use
|
||||
* nsLineLayout to reflow and place frames.
|
||||
*/
|
||||
struct nsInlineLayout {
|
||||
nsInlineLayout(nsLineLayout& aLineLayout,
|
||||
nsContainerFrame* aContainerFrame,
|
||||
nsIStyleContext* aContainerStyle);
|
||||
~nsInlineLayout();
|
||||
|
||||
void Init(const nsReflowState* aContainerReflowState);
|
||||
|
||||
void Prepare(PRBool aUnconstrainedWidth,
|
||||
PRBool aNoWrap,
|
||||
PRBool aComputeMaxElementSize);
|
||||
|
||||
void SetReflowSpace(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight);
|
||||
|
||||
nsInlineReflowStatus ReflowAndPlaceFrame(nsIFrame* aFrame);
|
||||
|
||||
/**
|
||||
* Align the frames that have been reflowed by this object.
|
||||
* aBounds is filled in with the size of the "line" before any
|
||||
* horziontal alignment or relative positioning. aBounds.width will
|
||||
* be the line width, aBounds.height will be the line height.
|
||||
*/
|
||||
void AlignFrames(nsIFrame* aFrame, PRInt32 aFrameCount, nsRect& aBounds);
|
||||
|
||||
PRBool IsFirstChild();
|
||||
|
||||
nsresult SetAscent(nscoord aAscent);
|
||||
|
||||
PRBool ComputeMaxSize(nsIFrame* aFrame,
|
||||
nsMargin& aKidMargin,
|
||||
nsSize& aResult);
|
||||
|
||||
nsInlineReflowStatus ReflowFrame(nsIFrame* aFrame,
|
||||
nsReflowMetrics& aDesiredSize,
|
||||
const nsReflowState& aReflowState,
|
||||
PRBool& aInlineAware);
|
||||
|
||||
nsInlineReflowStatus PlaceFrame(nsIFrame* aFrame,
|
||||
nsRect& kidRect,
|
||||
const nsReflowMetrics& kidMetrics,
|
||||
const nsMargin& kidMargin,
|
||||
nsInlineReflowStatus kidReflowStatus,
|
||||
PRBool aIsBlock);
|
||||
|
||||
nsresult MaybeCreateNextInFlow(nsIFrame* aFrame,
|
||||
nsIFrame*& aNextInFlowResult);
|
||||
|
||||
nsLineLayout& mLineLayout;
|
||||
nsContainerFrame* mContainerFrame;
|
||||
const nsStyleFont* mContainerFont;
|
||||
const nsStyleText* mContainerText;
|
||||
const nsStyleDisplay* mContainerDisplay;
|
||||
const nsReflowState* mContainerReflowState;
|
||||
PRUint8 mDirection;
|
||||
|
||||
PRPackedBool mUnconstrainedWidth;
|
||||
PRPackedBool mNoWrap;
|
||||
PRPackedBool mComputeMaxElementSize;
|
||||
PRPackedBool mIsBullet;
|
||||
PRPackedBool mHaveBullet;
|
||||
nscoord mAvailWidth;
|
||||
nscoord mAvailHeight;
|
||||
nscoord mX, mY;
|
||||
nscoord mLeftEdge, mRightEdge;
|
||||
|
||||
PRInt32 mFrameNum;
|
||||
nscoord* mAscents;
|
||||
nscoord mAscentBuf[20];
|
||||
nscoord mMaxAscents;
|
||||
|
||||
nscoord mMaxAscent;
|
||||
nscoord mMaxDescent;
|
||||
nsSize mMaxElementSize;
|
||||
|
||||
nsIFrame* mNextRCFrame;
|
||||
};
|
||||
|
||||
#endif /* nsInlineLayout_h___ */
|
Loading…
x
Reference in New Issue
Block a user