зеркало из https://github.com/mozilla/pjs.git
snapshot
This commit is contained in:
Родитель
3626bfa96d
Коммит
f7d5a13f2b
|
@ -1,55 +0,0 @@
|
||||||
#!nmake
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
DEPTH=..\..\..\..
|
|
||||||
|
|
||||||
LIBRARY_NAME=nglcsslay_s
|
|
||||||
MODULE=raptor
|
|
||||||
REQUIRES=xpcom raptor
|
|
||||||
DEFINES=-D_IMPL_NS_HTML -DWIN32_LEAN_AND_MEAN
|
|
||||||
|
|
||||||
CPPSRCS= \
|
|
||||||
nsCSSBlockFrame.cpp \
|
|
||||||
nsCSSContainerFrame.cpp \
|
|
||||||
nsCSSInlineFrame.cpp \
|
|
||||||
nsCSSLineLayout.cpp \
|
|
||||||
$(NULL)
|
|
||||||
|
|
||||||
CPP_OBJS= \
|
|
||||||
.\$(OBJDIR)\nsCSSBlockFrame.obj \
|
|
||||||
.\$(OBJDIR)\nsCSSContainerFrame.obj \
|
|
||||||
.\$(OBJDIR)\nsCSSInlineFrame.obj \
|
|
||||||
.\$(OBJDIR)\nsCSSLineLayout.obj \
|
|
||||||
$(NULL)
|
|
||||||
|
|
||||||
LINCS = \
|
|
||||||
-I$(PUBLIC)\xpcom -I$(PUBLIC)\raptor -I$(PUBLIC)\dom -I$(PUBLIC)\netlib \
|
|
||||||
-I..\..\..\base\src \
|
|
||||||
-I..\..\..\html\style\src -I..\..\..\html\base\src
|
|
||||||
|
|
||||||
LCFLAGS = \
|
|
||||||
$(LCFLAGS) \
|
|
||||||
$(DEFINES) \
|
|
||||||
$(NULL)
|
|
||||||
|
|
||||||
include <$(DEPTH)\layout\config\rules.mak>
|
|
||||||
|
|
||||||
libs:: $(LIBRARY)
|
|
||||||
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
|
|
||||||
|
|
||||||
clobber::
|
|
||||||
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib
|
|
|
@ -18,9 +18,11 @@
|
||||||
*/
|
*/
|
||||||
#include "nsCSSBlockFrame.h"
|
#include "nsCSSBlockFrame.h"
|
||||||
#include "nsCSSLineLayout.h"
|
#include "nsCSSLineLayout.h"
|
||||||
|
#include "nsCSSInlineLayout.h"
|
||||||
#include "nsCSSLayout.h"
|
#include "nsCSSLayout.h"
|
||||||
#include "nsPlaceholderFrame.h"
|
#include "nsPlaceholderFrame.h"
|
||||||
#include "nsStyleConsts.h"
|
#include "nsStyleConsts.h"
|
||||||
|
#include "nsHTMLIIDs.h"
|
||||||
|
|
||||||
#include "nsIAnchoredItems.h"
|
#include "nsIAnchoredItems.h"
|
||||||
#include "nsIPresContext.h"
|
#include "nsIPresContext.h"
|
||||||
|
@ -35,11 +37,6 @@
|
||||||
#include "nsHTMLValue.h"// XXX list ordinal hack
|
#include "nsHTMLValue.h"// XXX list ordinal hack
|
||||||
#include "nsIHTMLContent.h"// XXX list ordinal hack
|
#include "nsIHTMLContent.h"// XXX list ordinal hack
|
||||||
|
|
||||||
static NS_DEFINE_IID(kIAnchoredItemsIID, NS_IANCHOREDITEMS_IID);
|
|
||||||
static NS_DEFINE_IID(kIFloaterContainerIID, NS_IFLOATERCONTAINER_IID);
|
|
||||||
static NS_DEFINE_IID(kIInlineReflowIID, NS_IINLINE_REFLOW_IID);
|
|
||||||
static NS_DEFINE_IID(kIRunaroundIID, NS_IRUNAROUND_IID);
|
|
||||||
|
|
||||||
// XXX mLastContentOffset, mFirstContentOffset, mLastContentIsComplete
|
// XXX mLastContentOffset, mFirstContentOffset, mLastContentIsComplete
|
||||||
// XXX inline span frames
|
// XXX inline span frames
|
||||||
// XXX IsFirstChild
|
// XXX IsFirstChild
|
||||||
|
@ -178,8 +175,6 @@ nsCSSBlockReflowState::nsCSSBlockReflowState(nsIPresContext* aPresContext,
|
||||||
if (!mBlockIsPseudo) {
|
if (!mBlockIsPseudo) {
|
||||||
const nsStyleSpacing* blockSpacing = (const nsStyleSpacing*)
|
const nsStyleSpacing* blockSpacing = (const nsStyleSpacing*)
|
||||||
mBlockSC->GetStyleData(eStyleStruct_Spacing);
|
mBlockSC->GetStyleData(eStyleStruct_Spacing);
|
||||||
const nsStylePosition* blockPosition = (const nsStylePosition*)
|
|
||||||
mBlockSC->GetStyleData(eStyleStruct_Position);
|
|
||||||
|
|
||||||
blockSpacing->CalcBorderPaddingFor(mBlock, mBorderPadding);
|
blockSpacing->CalcBorderPaddingFor(mBlock, mBorderPadding);
|
||||||
mY = mBorderPadding.top;
|
mY = mBorderPadding.top;
|
||||||
|
@ -1145,8 +1140,8 @@ InlineFrameData::ReflowLine(nsCSSBlockReflowState& aState,
|
||||||
|
|
||||||
// Prepare for reflowing this line
|
// Prepare for reflowing this line
|
||||||
aLineLayout.Prepare(aState.mX);
|
aLineLayout.Prepare(aState.mX);
|
||||||
nsCSSInlineLayout inlineLayout(aLineLayout, aState.mBlock, aState.mBlockSC,
|
nsCSSInlineLayout inlineLayout(aLineLayout, aState.mBlock, aState.mBlockSC);
|
||||||
aState);
|
inlineLayout.Init(&aState);
|
||||||
inlineLayout.Prepare(aState.mUnconstrainedWidth, aState.mNoWrap,
|
inlineLayout.Prepare(aState.mUnconstrainedWidth, aState.mNoWrap,
|
||||||
aState.mMaxElementSize);
|
aState.mMaxElementSize);
|
||||||
inlineLayout.SetReflowSpace(aState.mCurrentBand.availSpace.x,
|
inlineLayout.SetReflowSpace(aState.mCurrentBand.availSpace.x,
|
||||||
|
@ -1291,7 +1286,7 @@ InlineFrameData::ReflowLine(nsCSSBlockReflowState& aState,
|
||||||
|
|
||||||
// See if speculative application of the margin should stick
|
// See if speculative application of the margin should stick
|
||||||
if (ild == &mLines) {
|
if (ild == &mLines) {
|
||||||
if (0 == inlineLayout.GetLineHeight()) {
|
if (0 == inlineLayout.mMaxAscent + inlineLayout.mMaxDescent) {
|
||||||
// No, undo margin application when we get a zero height child.
|
// No, undo margin application when we get a zero height child.
|
||||||
aState.mY -= bottomMargin;
|
aState.mY -= bottomMargin;
|
||||||
if (aState.mY + bottomMargin >= aState.mCurrentBand.availSpace.YMost()) {
|
if (aState.mY + bottomMargin >= aState.mCurrentBand.availSpace.YMost()) {
|
||||||
|
@ -1351,7 +1346,7 @@ InlineFrameData::SplitLine(nsCSSBlockReflowState& aState,
|
||||||
InlineLineData* ild,
|
InlineLineData* ild,
|
||||||
nsIFrame* aFrame)
|
nsIFrame* aFrame)
|
||||||
{
|
{
|
||||||
PRInt32 pushCount = ild->mChildCount - aInlineLayout.GetFrameNum();
|
PRInt32 pushCount = ild->mChildCount - aInlineLayout.mFrameNum;
|
||||||
NS_FRAME_LOG(NS_FRAME_TRACE_CHILD_REFLOW,
|
NS_FRAME_LOG(NS_FRAME_TRACE_CHILD_REFLOW,
|
||||||
("LineLayout::SplitLine: pushing %d frames",
|
("LineLayout::SplitLine: pushing %d frames",
|
||||||
pushCount));
|
pushCount));
|
||||||
|
|
|
@ -171,6 +171,4 @@ protected:
|
||||||
nsVoidArray* mRunInFloaters;
|
nsVoidArray* mRunInFloaters;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define IS_REFLOW_ERROR(_status) (PRInt32(_status) < 0)
|
|
||||||
|
|
||||||
#endif /* nsCSSBlockFrame_h___ */
|
#endif /* nsCSSBlockFrame_h___ */
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -15,28 +15,61 @@
|
||||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||||
* Reserved.
|
* Reserved.
|
||||||
*/
|
*/
|
||||||
#ifndef nsInlineFrame_h___
|
#ifndef nsCSSInlineFrame_h___
|
||||||
#define nsInlineFrame_h___
|
#define nsCSSInlineFrame_h___
|
||||||
|
|
||||||
#include "nsHTMLContainerFrame.h"
|
#include "nsCSSContainerFrame.h"
|
||||||
|
#include "nsCSSInlineLayout.h"
|
||||||
#include "nsCSSLineLayout.h"
|
#include "nsCSSLineLayout.h"
|
||||||
class nsInlineState;
|
|
||||||
|
|
||||||
// Inline container class. Does not support being used as a pseudo frame
|
class nsCSSInlineFrame;
|
||||||
class nsInlineFrame : public nsHTMLContainerFrame, public nsIInlineReflow {
|
|
||||||
|
/**
|
||||||
|
* Reflow state object for managing css inline layout. Most of the state
|
||||||
|
* is managed by the nsCSSInlineLayout object.
|
||||||
|
*/
|
||||||
|
struct nsCSSInlineReflowState : public nsReflowState {
|
||||||
|
nsCSSInlineReflowState(nsCSSLineLayout& aLineLayout,
|
||||||
|
nsCSSInlineFrame* aInlineFrame,
|
||||||
|
nsIStyleContext* aInlineSC,
|
||||||
|
const nsReflowState& aReflowState,
|
||||||
|
nsSize* aMaxElementSize);
|
||||||
|
~nsCSSInlineReflowState();
|
||||||
|
|
||||||
|
nsIPresContext* mPresContext;
|
||||||
|
nsCSSInlineLayout mInlineLayout;
|
||||||
|
|
||||||
|
nsIFrame* mLastChild; // last child we have reflowed (so far)
|
||||||
|
|
||||||
|
PRInt32 mKidContentIndex; // content index of last child reflowed
|
||||||
|
|
||||||
|
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 nsCSSInlineFrame : public nsCSSContainerFrame,
|
||||||
|
public nsIInlineReflow
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
static nsresult NewFrame(nsIFrame** aInstancePtrResult,
|
|
||||||
nsIContent* aContent,
|
|
||||||
nsIFrame* aParent);
|
|
||||||
|
|
||||||
// nsISupports
|
// nsISupports
|
||||||
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
|
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
|
||||||
|
|
||||||
// nsIFrame
|
// nsIFrame
|
||||||
|
#if XXX_not_yet
|
||||||
NS_IMETHOD Reflow(nsIPresContext* aPresContext,
|
NS_IMETHOD Reflow(nsIPresContext* aPresContext,
|
||||||
nsReflowMetrics& aDesiredSize,
|
nsReflowMetrics& aDesiredSize,
|
||||||
const nsReflowState& aReflowState,
|
const nsReflowState& aReflowState,
|
||||||
nsReflowStatus& aStatus);
|
nsReflowStatus& aStatus);
|
||||||
|
#endif
|
||||||
|
|
||||||
// nsIInlineReflow
|
// nsIInlineReflow
|
||||||
NS_IMETHOD FindTextRuns(nsCSSLineLayout& aLineLayout);
|
NS_IMETHOD FindTextRuns(nsCSSLineLayout& aLineLayout);
|
||||||
|
@ -45,70 +78,38 @@ public:
|
||||||
const nsReflowState& aReflowState);
|
const nsReflowState& aReflowState);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsInlineFrame(nsIContent* aContent, nsIFrame* aParent);
|
nsCSSInlineFrame(nsIContent* aContent, nsIFrame* aParent);
|
||||||
|
|
||||||
virtual ~nsInlineFrame();
|
virtual ~nsCSSInlineFrame();
|
||||||
|
|
||||||
virtual PRIntn GetSkipSides() const;
|
virtual PRIntn GetSkipSides() const;
|
||||||
|
|
||||||
void InitializeState(nsIPresContext* aPresContext,
|
nsresult FrameAppendedReflow(nsCSSInlineReflowState& aState);
|
||||||
const nsReflowState& aReflowState,
|
|
||||||
nsInlineState& aState);
|
|
||||||
|
|
||||||
PRBool DidFitChild(nsIPresContext* aPresContext,
|
nsresult ChildIncrementalReflow(nsCSSInlineReflowState& aState);
|
||||||
nsInlineState& aState,
|
|
||||||
nsIFrame* aChildFrame,
|
|
||||||
nsReflowMetrics& aChildMetrics);
|
|
||||||
|
|
||||||
PRBool CanFitChild(nsIPresContext* aPresContext,
|
nsresult ResizeReflow(nsCSSInlineReflowState& aState);
|
||||||
nsInlineState& aState,
|
|
||||||
nsIFrame* aChildFrame);
|
|
||||||
|
|
||||||
void ComputeFinalSize(nsIPresContext* aPresContext,
|
void ComputeFinalSize(nsCSSInlineReflowState& aState,
|
||||||
nsInlineState& aState,
|
nsReflowMetrics& aMetrics);
|
||||||
nsReflowMetrics& aSize);
|
|
||||||
|
|
||||||
PRBool ReflowMappedChildrenFrom(nsIPresContext* aPresContext,
|
nsInlineReflowStatus ReflowMapped(nsCSSInlineReflowState& aState);
|
||||||
nsInlineState& aState,
|
|
||||||
nsIFrame* aChildFrame,
|
|
||||||
PRInt32 aChildIndex);
|
|
||||||
|
|
||||||
PRBool PullUpChildren(nsIPresContext* aPresContext,
|
nsInlineReflowStatus ReflowUnmapped(nsCSSInlineReflowState& aState);
|
||||||
nsInlineState& aState);
|
|
||||||
|
|
||||||
nsReflowStatus ReflowUnmappedChildren(nsIPresContext* aPresContext,
|
nsInlineReflowStatus PullUpChildren(nsCSSInlineReflowState& aState);
|
||||||
nsInlineState& aState);
|
|
||||||
|
|
||||||
void PlaceChild(nsIFrame* aChild,
|
void PushKids(nsCSSInlineReflowState& aState,
|
||||||
PRInt32 aIndex, // in the child frame list
|
nsIFrame* aPrevChild, nsIFrame* aPushedChild);
|
||||||
nsInlineState& aState,
|
|
||||||
const nsReflowMetrics& aChildSize,
|
|
||||||
const nsSize* aChildMaxElementSize);
|
|
||||||
|
|
||||||
PRInt32 RecoverState(nsIPresContext* aCX,
|
friend nsresult NS_NewCSSInlineFrame(nsIFrame** aInstancePtrResult,
|
||||||
nsInlineState& aState,
|
nsIContent* aContent,
|
||||||
nsIFrame* aSkipChild);
|
nsIFrame* aParent);
|
||||||
|
|
||||||
nsresult Reflow2(nsIPresContext* aPresContext,
|
|
||||||
nsCSSLineLayout* aLineLayout,
|
|
||||||
nsReflowMetrics& aDesiredSize,
|
|
||||||
const nsReflowState& aReflowState);
|
|
||||||
|
|
||||||
nsReflowStatus IncrementalReflowFrom(nsIPresContext* aPresContext,
|
|
||||||
nsInlineState& aState,
|
|
||||||
nsIFrame* aChildFrame,
|
|
||||||
PRInt32 aChildIndex);
|
|
||||||
|
|
||||||
nsReflowStatus IncrementalReflowAfter(nsIPresContext* aPresContext,
|
|
||||||
nsInlineState& aState,
|
|
||||||
nsIFrame* aChildFrame,
|
|
||||||
PRInt32 aChildIndex);
|
|
||||||
|
|
||||||
nsInlineReflowStatus ReflowChild(nsInlineState& aState,
|
|
||||||
nsIFrame* aKidFrame,
|
|
||||||
nsIPresContext* aPresContext,
|
|
||||||
nsReflowMetrics& aDesiredSize,
|
|
||||||
const nsReflowState& aReflowState);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* nsInlineFrame_h___ */
|
extern nsresult NS_NewCSSInlineFrame(nsIFrame** aInstancePtrResult,
|
||||||
|
nsIContent* aContent,
|
||||||
|
nsIFrame* aParent);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* nsCSSInlineFrame_h___ */
|
||||||
|
|
|
@ -0,0 +1,422 @@
|
||||||
|
/* -*- 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 "nsCSSInlineLayout.h"
|
||||||
|
#include "nsCSSLineLayout.h"
|
||||||
|
#include "nsCSSLayout.h"
|
||||||
|
#include "nsHTMLIIDs.h"
|
||||||
|
#include "nsCSSContainerFrame.h"
|
||||||
|
|
||||||
|
#include "nsIFontMetrics.h"
|
||||||
|
#include "nsIStyleContext.h"
|
||||||
|
#include "nsIPresContext.h"
|
||||||
|
#include "nsIRunaround.h"
|
||||||
|
|
||||||
|
nsCSSInlineLayout::nsCSSInlineLayout(nsCSSLineLayout& aLineLayout,
|
||||||
|
nsIFrame* aContainerFrame,
|
||||||
|
nsIStyleContext* aContainerStyle)
|
||||||
|
: mLineLayout(aLineLayout)
|
||||||
|
{
|
||||||
|
mContainerFrame = aContainerFrame;
|
||||||
|
mAscents = mAscentBuf;
|
||||||
|
mMaxAscents = sizeof(mAscentBuf) / sizeof(mAscentBuf[0]);
|
||||||
|
mMaxElementSize = nsnull;
|
||||||
|
|
||||||
|
mContainerFont = (const nsStyleFont*)
|
||||||
|
aContainerStyle->GetStyleData(eStyleStruct_Font);
|
||||||
|
mContainerText = (const nsStyleText*)
|
||||||
|
aContainerStyle->GetStyleData(eStyleStruct_Text);
|
||||||
|
mContainerDisplay = (const nsStyleDisplay*)
|
||||||
|
aContainerStyle->GetStyleData(eStyleStruct_Display);
|
||||||
|
mDirection = mContainerDisplay->mDirection;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCSSInlineLayout::~nsCSSInlineLayout()
|
||||||
|
{
|
||||||
|
if (mAscents != mAscentBuf) {
|
||||||
|
delete [] mAscents;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsCSSInlineLayout::Init(const nsReflowState* aContainerReflowState)
|
||||||
|
{
|
||||||
|
mContainerReflowState = aContainerReflowState;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsCSSInlineLayout::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
|
||||||
|
nsCSSInlineLayout::Prepare(PRBool aUnconstrainedWidth, PRBool aNoWrap,
|
||||||
|
nsSize* aMaxElementSize)
|
||||||
|
{
|
||||||
|
mFrameNum = 0;
|
||||||
|
mUnconstrainedWidth = aUnconstrainedWidth;
|
||||||
|
mNoWrap = aNoWrap;
|
||||||
|
mMaxElementSize = aMaxElementSize;
|
||||||
|
mMaxAscent = 0;
|
||||||
|
mMaxDescent = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsCSSInlineLayout::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
|
||||||
|
nsCSSInlineLayout::ReflowAndPlaceFrame(nsIFrame* aFrame)
|
||||||
|
{
|
||||||
|
// 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)) {
|
||||||
|
return NS_INLINE_REFLOW_LINE_BREAK_BEFORE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
if (nsnull != mContainerReflowState->reflowCommand) {
|
||||||
|
reason = eReflowReason_Incremental;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
nsFrameState state;
|
||||||
|
aFrame->GetFrameState(state);
|
||||||
|
if (NS_FRAME_FIRST_REFLOW & state) {
|
||||||
|
reason = eReflowReason_Initial;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup reflow state for reflowing the frame
|
||||||
|
nsReflowState reflowState(aFrame, *mContainerReflowState, maxSize, reason);
|
||||||
|
nsInlineReflowStatus rs;
|
||||||
|
nsReflowMetrics metrics(mMaxElementSize);
|
||||||
|
PRBool isAware;
|
||||||
|
aFrame->WillReflow(*mLineLayout.mPresContext);
|
||||||
|
rs = ReflowFrame(aFrame, metrics, reflowState, isAware);
|
||||||
|
if (IS_REFLOW_ERROR(rs)) {
|
||||||
|
return rs;
|
||||||
|
}
|
||||||
|
if (NS_INLINE_REFLOW_BREAK_BEFORE == (rs & NS_INLINE_REFLOW_REFLOW_MASK)) {
|
||||||
|
return rs;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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,
|
||||||
|
("LineLayout::ReflowChild: !fit size=%d,%d",
|
||||||
|
metrics.width, metrics.height));
|
||||||
|
return NS_INLINE_REFLOW_LINE_BREAK_BEFORE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRect frameRect(mX, mY, metrics.width, metrics.height);
|
||||||
|
return PlaceFrame(aFrame, frameRect, metrics, margin, rs);
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX RTL
|
||||||
|
PRBool
|
||||||
|
nsCSSInlineLayout::IsFirstChild()
|
||||||
|
{
|
||||||
|
return 0 == mFrameNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
nsCSSInlineLayout::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;
|
||||||
|
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,
|
||||||
|
("CSSLineLayout::ComputeMaxSize: !fit"));
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
aResult.height = mAvailHeight;
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsInlineReflowStatus
|
||||||
|
nsCSSInlineLayout::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.
|
||||||
|
|
||||||
|
nsresult rv;
|
||||||
|
nsIRunaround* runAround;
|
||||||
|
nsIInlineReflow* inlineReflow;
|
||||||
|
if ((nsnull != mLineLayout.mSpaceManager) &&
|
||||||
|
(NS_OK == aKidFrame->QueryInterface(kIRunaroundIID,
|
||||||
|
(void**)&runAround))) {
|
||||||
|
nsRect r;
|
||||||
|
runAround->Reflow(mLineLayout.mPresContext, mLineLayout.mSpaceManager,
|
||||||
|
aMetrics, aReflowState, r, rv);
|
||||||
|
aMetrics.width = r.width;
|
||||||
|
aMetrics.height = r.height;
|
||||||
|
aMetrics.ascent = r.height;
|
||||||
|
aMetrics.descent = 0;
|
||||||
|
rv = NS_FRAME_REFLOW_STATUS_2_INLINE_REFLOW_STATUS(rv);
|
||||||
|
aInlineAware = PR_FALSE;
|
||||||
|
}
|
||||||
|
else if (NS_OK == aKidFrame->QueryInterface(kIInlineReflowIID,
|
||||||
|
(void**)&inlineReflow)) {
|
||||||
|
rv = inlineReflow->InlineReflow(mLineLayout, aMetrics, aReflowState);
|
||||||
|
aInlineAware = PR_TRUE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
aKidFrame->Reflow(mLineLayout.mPresContext, aMetrics, aReflowState, rv);
|
||||||
|
rv = NS_FRAME_REFLOW_STATUS_2_INLINE_REFLOW_STATUS(rv);
|
||||||
|
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)
|
||||||
|
nsCSSContainerFrame* parent;
|
||||||
|
aKidFrame->GetGeometricParent((nsIFrame*&)parent);
|
||||||
|
parent->DeleteChildsNextInFlow(aKidFrame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsInlineReflowStatus
|
||||||
|
nsCSSInlineLayout::PlaceFrame(nsIFrame* aFrame,
|
||||||
|
nsRect& aFrameRect,
|
||||||
|
const nsReflowMetrics& aFrameMetrics,
|
||||||
|
const nsMargin& aFrameMargin,
|
||||||
|
nsInlineReflowStatus aFrameReflowStatus)
|
||||||
|
{
|
||||||
|
nscoord horizontalMargins = 0;
|
||||||
|
|
||||||
|
// Special case to position outside list bullets.
|
||||||
|
// XXX RTL bullets
|
||||||
|
PRBool isBullet = PR_FALSE;
|
||||||
|
if (mLineLayout.mListPositionOutside) {
|
||||||
|
PRBool isFirstChild = IsFirstChild();
|
||||||
|
if (isFirstChild && (0 == mLineLayout.mLineNumber)) {
|
||||||
|
nsIFrame* containerPrevInFlow;
|
||||||
|
mContainerFrame->GetPrevInFlow(containerPrevInFlow);
|
||||||
|
if (nsnull == containerPrevInFlow) {
|
||||||
|
isBullet = PR_TRUE;
|
||||||
|
// 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).
|
||||||
|
|
||||||
|
// Compute gap between bullet and inner rect left edge
|
||||||
|
nsIFontMetrics* fm =
|
||||||
|
mLineLayout.mPresContext->GetMetricsFor(mContainerFont->mFont);
|
||||||
|
nscoord kidAscent = fm->GetMaxAscent();
|
||||||
|
nscoord dx = fm->GetHeight() / 2; // from old layout engine
|
||||||
|
NS_RELEASE(fm);
|
||||||
|
|
||||||
|
// XXX RTL bullets
|
||||||
|
aFrameRect.x = mX - aFrameRect.width - dx;
|
||||||
|
aFrame->SetRect(aFrameRect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isBullet) {
|
||||||
|
// Place normal in-flow child
|
||||||
|
aFrame->SetRect(aFrameRect);
|
||||||
|
|
||||||
|
// XXX RTL
|
||||||
|
// 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, it's margin's are applied there
|
||||||
|
// not here.
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NS_STYLE_FLOAT_NONE:
|
||||||
|
horizontalMargins = aFrameMargin.left + aFrameMargin.right;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
nscoord totalWidth = aFrameMetrics.width + horizontalMargins;
|
||||||
|
mX += totalWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_FRAME_LOG(NS_FRAME_TRACE_CHILD_REFLOW,
|
||||||
|
("CSSLineLayout::PlaceChild: frame=%p {%d, %d, %d, %d}",
|
||||||
|
aFrame,
|
||||||
|
aFrameRect.x, aFrameRect.y,
|
||||||
|
aFrameRect.width, aFrameRect.height));
|
||||||
|
|
||||||
|
#if XXX_fix_me
|
||||||
|
// XXX this is not right; the max-element-size of a child depends on
|
||||||
|
// it's margins which it doesn't know how to add in
|
||||||
|
|
||||||
|
if (nsnull != mMaxElementSize) {
|
||||||
|
// XXX I'm not certain that this is doing the right thing; rethink this
|
||||||
|
nscoord elementWidth = kidMaxElementSize->width + horizontalMargins;
|
||||||
|
if (elementWidth > mMaxElementSize->width) {
|
||||||
|
mMaxElementSize->width = elementWidth;
|
||||||
|
}
|
||||||
|
if (aFrameMetrics.height > mMaxElementSize->height) {
|
||||||
|
mMaxElementSize->height = aFrameMetrics.height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
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 XXX_fix_me
|
||||||
|
mLine->mLastContentOffset = mKidContentIndex;
|
||||||
|
switch (aFrameReflowStatus & NS_INLINE_REFLOW_REFLOW_MASK) {
|
||||||
|
case NS_INLINE_REFLOW_COMPLETE:
|
||||||
|
case NS_INLINE_REFLOW_BREAK_AFTER:
|
||||||
|
mLine->mLastContentIsComplete = PR_TRUE;
|
||||||
|
mKidPrevInFlow = nsnull;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NS_INLINE_REFLOW_NOT_COMPLETE:
|
||||||
|
mLine->mLastContentIsComplete = PR_FALSE;
|
||||||
|
mKidPrevInFlow = mKidFrame;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
NS_FRAME_LOG(NS_FRAME_TRACE_CHILD_REFLOW,
|
||||||
|
("CSSLineLayout::PlaceChild: aFrameReflowStatus=%x",
|
||||||
|
aFrameReflowStatus));
|
||||||
|
return aFrameReflowStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
nscoord
|
||||||
|
nsCSSInlineLayout::AlignFrames(nsIFrame* aFrame, PRInt32 aFrameCount,
|
||||||
|
nsRect& aBounds)
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(aFrameCount == mFrameNum, "bogus reflow");
|
||||||
|
|
||||||
|
nscoord lineHeight;
|
||||||
|
|
||||||
|
if (PR_TRUE /*XXX !mLine->mIsBlock*/) {
|
||||||
|
// Vertically align the children on the line; this will compute
|
||||||
|
// the actual line height for us.
|
||||||
|
lineHeight =
|
||||||
|
nsCSSLayout::VerticallyAlignChildren(mLineLayout.mPresContext,
|
||||||
|
mContainerFrame, mContainerFont,
|
||||||
|
mY, aFrame, aFrameCount,
|
||||||
|
mAscents, mMaxAscent);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// The line height of a block is just the block's height
|
||||||
|
lineHeight = mMaxAscent;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save away line bounds before other adjustments
|
||||||
|
aBounds.x = mLeftEdge;
|
||||||
|
aBounds.y = mY;
|
||||||
|
aBounds.width = mX - mLeftEdge;
|
||||||
|
aBounds.height = lineHeight;
|
||||||
|
|
||||||
|
// Now horizontally place the children
|
||||||
|
if (!mUnconstrainedWidth) {
|
||||||
|
nsCSSLayout::HorizontallyPlaceChildren(mLineLayout.mPresContext,
|
||||||
|
mContainerFrame,
|
||||||
|
mContainerText->mTextAlign,
|
||||||
|
mDirection,
|
||||||
|
aFrame, aFrameCount,
|
||||||
|
mX - mLeftEdge,
|
||||||
|
mAvailWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Last, apply relative positioning
|
||||||
|
nsCSSLayout::RelativePositionChildren(mLineLayout.mPresContext,
|
||||||
|
mContainerFrame,
|
||||||
|
aFrame, aFrameCount);
|
||||||
|
|
||||||
|
return lineHeight;
|
||||||
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
/* -*- 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 nsCSSInlineLayout_h___
|
||||||
|
#define nsCSSInlineLayout_h___
|
||||||
|
|
||||||
|
#include "nsIFrame.h"
|
||||||
|
#include "nsIInlineReflow.h"
|
||||||
|
class nsCSSLineLayout;
|
||||||
|
struct nsStyleDisplay;
|
||||||
|
struct nsStyleFont;
|
||||||
|
struct nsStyleText;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This structure contains the horizontal layout state for line
|
||||||
|
* layout frame placement. This is factored out of nsCSSLineLayout so
|
||||||
|
* that the block layout code and the inline layout code can use
|
||||||
|
* nsCSSLineLayout to reflow and place frames.
|
||||||
|
*/
|
||||||
|
struct nsCSSInlineLayout {
|
||||||
|
nsCSSInlineLayout(nsCSSLineLayout& aLineLayout,
|
||||||
|
nsIFrame* aContainerFrame,
|
||||||
|
nsIStyleContext* aContainerStyle);
|
||||||
|
~nsCSSInlineLayout();
|
||||||
|
|
||||||
|
void Init(const nsReflowState* aContainerReflowState);
|
||||||
|
|
||||||
|
void Prepare(PRBool aUnconstrainedWidth,
|
||||||
|
PRBool aNoWrap,
|
||||||
|
nsSize* aMaxElementSize);
|
||||||
|
|
||||||
|
void SetReflowSpace(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight);
|
||||||
|
|
||||||
|
nsInlineReflowStatus ReflowAndPlaceFrame(nsIFrame* aFrame);
|
||||||
|
|
||||||
|
nscoord 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);
|
||||||
|
|
||||||
|
nsCSSLineLayout& mLineLayout;
|
||||||
|
nsIFrame* mContainerFrame;
|
||||||
|
const nsStyleFont* mContainerFont;
|
||||||
|
const nsStyleText* mContainerText;
|
||||||
|
const nsStyleDisplay* mContainerDisplay;
|
||||||
|
const nsReflowState* mContainerReflowState;
|
||||||
|
PRUint8 mDirection;
|
||||||
|
|
||||||
|
PRPackedBool mUnconstrainedWidth;
|
||||||
|
PRPackedBool mNoWrap;
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* nsCSSInlineLayout_h___ */
|
|
@ -19,6 +19,7 @@
|
||||||
#include "nsCSSLineLayout.h"
|
#include "nsCSSLineLayout.h"
|
||||||
#include "nsCSSLayout.h"
|
#include "nsCSSLayout.h"
|
||||||
|
|
||||||
|
#if 0
|
||||||
#include "nsIFontMetrics.h"
|
#include "nsIFontMetrics.h"
|
||||||
#include "nsIPresContext.h"
|
#include "nsIPresContext.h"
|
||||||
#include "nsIRunaround.h"
|
#include "nsIRunaround.h"
|
||||||
|
@ -27,6 +28,7 @@
|
||||||
// XXX nsCSSIIDs.[h,cpp]
|
// XXX nsCSSIIDs.[h,cpp]
|
||||||
static NS_DEFINE_IID(kIInlineReflowIID, NS_IINLINE_REFLOW_IID);
|
static NS_DEFINE_IID(kIInlineReflowIID, NS_IINLINE_REFLOW_IID);
|
||||||
static NS_DEFINE_IID(kIRunaroundIID, NS_IRUNAROUND_IID);
|
static NS_DEFINE_IID(kIRunaroundIID, NS_IRUNAROUND_IID);
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
nsCSSTextRun::List(FILE* out, PRInt32 aIndent)
|
nsCSSTextRun::List(FILE* out, PRInt32 aIndent)
|
||||||
|
@ -45,382 +47,6 @@ nsCSSTextRun::List(FILE* out, PRInt32 aIndent)
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
nsCSSInlineLayout::nsCSSInlineLayout(nsCSSLineLayout& aLineLayout,
|
|
||||||
nsIFrame* aContainerFrame,
|
|
||||||
nsIStyleContext* aContainerStyle,
|
|
||||||
const nsReflowState& aContainerRS)
|
|
||||||
: mLineLayout(aLineLayout),
|
|
||||||
mContainerReflowState(aContainerRS)
|
|
||||||
{
|
|
||||||
mContainerFrame = aContainerFrame;
|
|
||||||
mAscents = mAscentBuf;
|
|
||||||
mMaxAscents = sizeof(mAscentBuf) / sizeof(mAscentBuf[0]);
|
|
||||||
mMaxElementSize = nsnull;
|
|
||||||
|
|
||||||
mContainerFont = (const nsStyleFont*)
|
|
||||||
aContainerStyle->GetStyleData(eStyleStruct_Font);
|
|
||||||
mContainerText = (const nsStyleText*)
|
|
||||||
aContainerStyle->GetStyleData(eStyleStruct_Text);
|
|
||||||
mContainerDisplay = (const nsStyleDisplay*)
|
|
||||||
aContainerStyle->GetStyleData(eStyleStruct_Display);
|
|
||||||
mDirection = mContainerDisplay->mDirection;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCSSInlineLayout::~nsCSSInlineLayout()
|
|
||||||
{
|
|
||||||
if (mAscents != mAscentBuf) {
|
|
||||||
delete [] mAscents;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsCSSInlineLayout::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
|
|
||||||
nsCSSInlineLayout::Prepare(PRBool aUnconstrainedWidth, PRBool aNoWrap,
|
|
||||||
nsSize* aMaxElementSize)
|
|
||||||
{
|
|
||||||
mFrameNum = 0;
|
|
||||||
mUnconstrainedWidth = aUnconstrainedWidth;
|
|
||||||
mNoWrap = aNoWrap;
|
|
||||||
mMaxElementSize = aMaxElementSize;
|
|
||||||
|
|
||||||
// mKidPrevInFlow = ???;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nsCSSInlineLayout::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
|
|
||||||
nsCSSInlineLayout::ReflowAndPlaceFrame(nsIFrame* aFrame)
|
|
||||||
{
|
|
||||||
// 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)) {
|
|
||||||
return NS_INLINE_REFLOW_LINE_BREAK_BEFORE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup reflow state for reflowing the frame
|
|
||||||
nsReflowState reflowState(aFrame, mContainerReflowState, maxSize);
|
|
||||||
nsInlineReflowStatus rs;
|
|
||||||
nsReflowMetrics metrics(mMaxElementSize);
|
|
||||||
PRBool isAware;
|
|
||||||
aFrame->WillReflow(*mLineLayout.mPresContext);
|
|
||||||
rs = ReflowFrame(aFrame, metrics, reflowState, isAware);
|
|
||||||
if (IS_REFLOW_ERROR(rs)) {
|
|
||||||
return rs;
|
|
||||||
}
|
|
||||||
if (NS_INLINE_REFLOW_BREAK_BEFORE == (rs & NS_INLINE_REFLOW_REFLOW_MASK)) {
|
|
||||||
return rs;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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,
|
|
||||||
("LineLayout::ReflowChild: !fit size=%d,%d",
|
|
||||||
metrics.width, metrics.height));
|
|
||||||
return NS_INLINE_REFLOW_LINE_BREAK_BEFORE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nsRect frameRect(mX, mY, metrics.width, metrics.height);
|
|
||||||
return PlaceFrame(aFrame, frameRect, metrics, margin, rs);
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX RTL
|
|
||||||
PRBool
|
|
||||||
nsCSSInlineLayout::IsFirstChild()
|
|
||||||
{
|
|
||||||
return 0 == mFrameNum;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRBool
|
|
||||||
nsCSSInlineLayout::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;
|
|
||||||
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,
|
|
||||||
("CSSLineLayout::ComputeMaxSize: !fit"));
|
|
||||||
return PR_FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
aResult.height = mAvailHeight;
|
|
||||||
return PR_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsInlineReflowStatus
|
|
||||||
nsCSSInlineLayout::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.
|
|
||||||
|
|
||||||
nsresult rv;
|
|
||||||
nsIRunaround* runAround;
|
|
||||||
nsIInlineReflow* inlineReflow;
|
|
||||||
if ((nsnull != mLineLayout.mSpaceManager) &&
|
|
||||||
(NS_OK == aKidFrame->QueryInterface(kIRunaroundIID,
|
|
||||||
(void**)&runAround))) {
|
|
||||||
nsRect r;
|
|
||||||
runAround->Reflow(mLineLayout.mPresContext, mLineLayout.mSpaceManager,
|
|
||||||
aMetrics, aReflowState, r, rv);
|
|
||||||
aMetrics.width = r.width;
|
|
||||||
aMetrics.height = r.height;
|
|
||||||
aMetrics.ascent = r.height;
|
|
||||||
aMetrics.descent = 0;
|
|
||||||
rv = NS_FRAME_REFLOW_STATUS_2_INLINE_REFLOW_STATUS(rv);
|
|
||||||
aInlineAware = PR_FALSE;
|
|
||||||
}
|
|
||||||
else if (NS_OK == aKidFrame->QueryInterface(kIInlineReflowIID,
|
|
||||||
(void**)&inlineReflow)) {
|
|
||||||
rv = inlineReflow->InlineReflow(mLineLayout, aMetrics, aReflowState);
|
|
||||||
aInlineAware = PR_TRUE;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
aKidFrame->Reflow(mLineLayout.mPresContext, aMetrics, aReflowState, rv);
|
|
||||||
rv = NS_FRAME_REFLOW_STATUS_2_INLINE_REFLOW_STATUS(rv);
|
|
||||||
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)
|
|
||||||
nsCSSContainerFrame* parent;
|
|
||||||
aKidFrame->GetGeometricParent((nsIFrame*&)parent);
|
|
||||||
parent->DeleteChildsNextInFlow(aKidFrame);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsInlineReflowStatus
|
|
||||||
nsCSSInlineLayout::PlaceFrame(nsIFrame* aFrame,
|
|
||||||
nsRect& aFrameRect,
|
|
||||||
const nsReflowMetrics& aFrameMetrics,
|
|
||||||
const nsMargin& aFrameMargin,
|
|
||||||
nsInlineReflowStatus aFrameReflowStatus)
|
|
||||||
{
|
|
||||||
nscoord horizontalMargins = 0;
|
|
||||||
|
|
||||||
// Special case to position outside list bullets.
|
|
||||||
// XXX RTL bullets
|
|
||||||
PRBool isBullet = PR_FALSE;
|
|
||||||
if (mLineLayout.mListPositionOutside) {
|
|
||||||
PRBool isFirstChild = IsFirstChild();
|
|
||||||
if (isFirstChild && (0 == mLineLayout.mLineNumber)) {
|
|
||||||
nsIFrame* containerPrevInFlow;
|
|
||||||
mContainerFrame->GetPrevInFlow(containerPrevInFlow);
|
|
||||||
if (nsnull == containerPrevInFlow) {
|
|
||||||
isBullet = PR_TRUE;
|
|
||||||
// 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).
|
|
||||||
|
|
||||||
// Compute gap between bullet and inner rect left edge
|
|
||||||
nsIFontMetrics* fm =
|
|
||||||
mLineLayout.mPresContext->GetMetricsFor(mContainerFont->mFont);
|
|
||||||
nscoord kidAscent = fm->GetMaxAscent();
|
|
||||||
nscoord dx = fm->GetHeight() / 2; // from old layout engine
|
|
||||||
NS_RELEASE(fm);
|
|
||||||
|
|
||||||
// XXX RTL bullets
|
|
||||||
aFrameRect.x = mX - aFrameRect.width - dx;
|
|
||||||
aFrame->SetRect(aFrameRect);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!isBullet) {
|
|
||||||
// Place normal in-flow child
|
|
||||||
aFrame->SetRect(aFrameRect);
|
|
||||||
|
|
||||||
// XXX RTL
|
|
||||||
// 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, it's margin's are applied there
|
|
||||||
// not here.
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NS_STYLE_FLOAT_NONE:
|
|
||||||
horizontalMargins = aFrameMargin.left + aFrameMargin.right;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
nscoord totalWidth = aFrameMetrics.width + horizontalMargins;
|
|
||||||
mX += totalWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_FRAME_LOG(NS_FRAME_TRACE_CHILD_REFLOW,
|
|
||||||
("CSSLineLayout::PlaceChild: frame=%p {%d, %d, %d, %d}",
|
|
||||||
aFrame,
|
|
||||||
aFrameRect.x, aFrameRect.y,
|
|
||||||
aFrameRect.width, aFrameRect.height));
|
|
||||||
|
|
||||||
#if XXX_fix_me
|
|
||||||
// XXX this is not right; the max-element-size of a child depends on
|
|
||||||
// it's margins which it doesn't know how to add in
|
|
||||||
|
|
||||||
if (nsnull != mMaxElementSize) {
|
|
||||||
// XXX I'm not certain that this is doing the right thing; rethink this
|
|
||||||
nscoord elementWidth = kidMaxElementSize->width + horizontalMargins;
|
|
||||||
if (elementWidth > mMaxElementSize->width) {
|
|
||||||
mMaxElementSize->width = elementWidth;
|
|
||||||
}
|
|
||||||
if (aFrameMetrics.height > mMaxElementSize->height) {
|
|
||||||
mMaxElementSize->height = aFrameMetrics.height;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
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 XXX_fix_me
|
|
||||||
mLine->mLastContentOffset = mKidContentIndex;
|
|
||||||
switch (aFrameReflowStatus & NS_INLINE_REFLOW_REFLOW_MASK) {
|
|
||||||
case NS_INLINE_REFLOW_COMPLETE:
|
|
||||||
case NS_INLINE_REFLOW_BREAK_AFTER:
|
|
||||||
mLine->mLastContentIsComplete = PR_TRUE;
|
|
||||||
mKidPrevInFlow = nsnull;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NS_INLINE_REFLOW_NOT_COMPLETE:
|
|
||||||
mLine->mLastContentIsComplete = PR_FALSE;
|
|
||||||
mKidPrevInFlow = mKidFrame;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
NS_FRAME_LOG(NS_FRAME_TRACE_CHILD_REFLOW,
|
|
||||||
("CSSLineLayout::PlaceChild: aFrameReflowStatus=%x",
|
|
||||||
aFrameReflowStatus));
|
|
||||||
return aFrameReflowStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
nscoord
|
|
||||||
nsCSSInlineLayout::AlignFrames(nsIFrame* aFrame, PRInt32 aFrameCount,
|
|
||||||
nsRect& aBounds)
|
|
||||||
{
|
|
||||||
NS_PRECONDITION(aFrameCount == mFrameNum, "bogus reflow");
|
|
||||||
|
|
||||||
nscoord lineHeight;
|
|
||||||
|
|
||||||
if (PR_TRUE /*XXX !mLine->mIsBlock*/) {
|
|
||||||
// Vertically align the children on the line; this will compute
|
|
||||||
// the actual line height for us.
|
|
||||||
lineHeight =
|
|
||||||
nsCSSLayout::VerticallyAlignChildren(mLineLayout.mPresContext,
|
|
||||||
mContainerFrame, mContainerFont,
|
|
||||||
mY, aFrame, aFrameCount,
|
|
||||||
mAscents, mMaxAscent);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// The line height of a block is just the block's height
|
|
||||||
lineHeight = mMaxAscent;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save away line bounds before other adjustments
|
|
||||||
aBounds.x = mLeftEdge;
|
|
||||||
aBounds.y = mY;
|
|
||||||
aBounds.width = mX - mLeftEdge;
|
|
||||||
aBounds.height = lineHeight;
|
|
||||||
|
|
||||||
// Now horizontally place the children
|
|
||||||
if (!mUnconstrainedWidth) {
|
|
||||||
nsCSSLayout::HorizontallyPlaceChildren(mLineLayout.mPresContext,
|
|
||||||
mContainerFrame,
|
|
||||||
mContainerText->mTextAlign,
|
|
||||||
mDirection,
|
|
||||||
aFrame, aFrameCount,
|
|
||||||
mX - mLeftEdge,
|
|
||||||
mAvailWidth);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Last, apply relative positioning
|
|
||||||
nsCSSLayout::RelativePositionChildren(mLineLayout.mPresContext,
|
|
||||||
mContainerFrame,
|
|
||||||
aFrame, aFrameCount);
|
|
||||||
|
|
||||||
return lineHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
|
||||||
|
|
||||||
nsCSSLineLayout::nsCSSLineLayout(nsIPresContext* aPresContext,
|
nsCSSLineLayout::nsCSSLineLayout(nsIPresContext* aPresContext,
|
||||||
nsISpaceManager* aSpaceManager)
|
nsISpaceManager* aSpaceManager)
|
||||||
{
|
{
|
||||||
|
@ -467,4 +93,3 @@ nsCSSLineLayout::AddText(nsIFrame* aTextFrame)
|
||||||
mCurrentTextRun->mArray.AppendElement(aTextFrame);
|
mCurrentTextRun->mArray.AppendElement(aTextFrame);
|
||||||
return NS_OK;/* XXX */
|
return NS_OK;/* XXX */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,84 +19,8 @@
|
||||||
#ifndef nsCSSLineLayout_h___
|
#ifndef nsCSSLineLayout_h___
|
||||||
#define nsCSSLineLayout_h___
|
#define nsCSSLineLayout_h___
|
||||||
|
|
||||||
#include "nsCSSBlockFrame.h"
|
#include "nsIFrame.h"
|
||||||
#include "nsVoidArray.h"
|
#include "nsVoidArray.h"
|
||||||
#include "nsStyleConsts.h"
|
|
||||||
|
|
||||||
class nsCSSLineLayout;
|
|
||||||
struct nsStyleDisplay;
|
|
||||||
struct nsStyleFont;
|
|
||||||
struct nsStyleText;
|
|
||||||
|
|
||||||
/* d76e29b0-ff56-11d1-89e7-006008911b81 */
|
|
||||||
#define NS_IINLINE_REFLOW_IID \
|
|
||||||
{0xd76e29b0, 0xff56, 0x11d1, {0x89, 0xe7, 0x00, 0x60, 0x08, 0x91, 0x1b, 0x81}}
|
|
||||||
|
|
||||||
class nsIInlineReflow {
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Recursively find all of the text runs contained in an outer
|
|
||||||
* block container. Inline frames implement this by recursing over
|
|
||||||
* their children; note that inlines frames may need to create
|
|
||||||
* missing child frames before proceeding (e.g. when a tree
|
|
||||||
* containing inlines is appended/inserted into a block container
|
|
||||||
*/
|
|
||||||
NS_IMETHOD FindTextRuns(nsCSSLineLayout& aLineLayout) = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* InlineReflow method. See below for how to interpret the return value.
|
|
||||||
*/
|
|
||||||
NS_IMETHOD InlineReflow(nsCSSLineLayout& aLineLayout,
|
|
||||||
nsReflowMetrics& aDesiredSize,
|
|
||||||
const nsReflowState& aReflowState) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* For InlineReflow the return value (an nsresult) indicates the
|
|
||||||
* status of the reflow operation. If the return value is negative
|
|
||||||
* then some sort of catastrophic error has occured (e.g. out of memory).
|
|
||||||
* If the return value is non-negative then the macros below can be
|
|
||||||
* used to interpret it.
|
|
||||||
*/
|
|
||||||
typedef nsresult nsInlineReflowStatus;
|
|
||||||
|
|
||||||
// The low 3 bits of the nsInlineReflowStatus indicate what happened
|
|
||||||
// to the child during it's reflow.
|
|
||||||
#define NS_INLINE_REFLOW_COMPLETE 0 // note: not a bit!
|
|
||||||
#define NS_INLINE_REFLOW_NOT_COMPLETE 1
|
|
||||||
#define NS_INLINE_REFLOW_BREAK_BEFORE 2
|
|
||||||
#define NS_INLINE_REFLOW_BREAK_AFTER 3
|
|
||||||
#define NS_INLINE_REFLOW_REFLOW_MASK 0x3
|
|
||||||
|
|
||||||
// The inline reflow status may need to indicate that the next-in-flow
|
|
||||||
// must be reflowed. This bit is or'd in in that case.
|
|
||||||
#define NS_INLINE_REFLOW_NEXT_IN_FLOW 0x4
|
|
||||||
|
|
||||||
// When a break is indicated (break-before/break-after) the type of
|
|
||||||
// break requested is indicate in bits 4-7.
|
|
||||||
#define NS_INLINE_REFLOW_BREAK_MASK 0xF0
|
|
||||||
#define NS_INLINE_REFLOW_GET_BREAK_TYPE(_status) (((_status) >> 4) & 0xF)
|
|
||||||
#define NS_INLINE_REFLOW_MAKE_BREAK_TYPE(_type) ((_type) << 4)
|
|
||||||
|
|
||||||
// This macro maps an nsIFrame nsReflowStatus value into an
|
|
||||||
// nsInlineReflowStatus value.
|
|
||||||
#define NS_FRAME_REFLOW_STATUS_2_INLINE_REFLOW_STATUS(_status) \
|
|
||||||
(((_status) & 0x1) | (((_status) & NS_FRAME_REFLOW_NEXTINFLOW) << 2))
|
|
||||||
|
|
||||||
// Convenience macro's
|
|
||||||
#define NS_INLINE_REFLOW_LINE_BREAK_BEFORE \
|
|
||||||
(NS_INLINE_REFLOW_BREAK_BEFORE | \
|
|
||||||
NS_INLINE_REFLOW_MAKE_BREAK_TYPE(NS_STYLE_CLEAR_LINE))
|
|
||||||
|
|
||||||
#define NS_INLINE_REFLOW_LINE_BREAK_AFTER \
|
|
||||||
(NS_INLINE_REFLOW_BREAK_AFTER | \
|
|
||||||
NS_INLINE_REFLOW_MAKE_BREAK_TYPE(NS_STYLE_CLEAR_LINE))
|
|
||||||
|
|
||||||
// This macro tests to see if an nsInlineReflowStatus is an error value
|
|
||||||
// or just a regular return value
|
|
||||||
#define NS_INLINE_REFLOW_ERROR(_status) (PRInt32(_status) < 0)
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
|
||||||
|
|
||||||
// This structure represents a run of text. In mText are the
|
// This structure represents a run of text. In mText are the
|
||||||
// nsIFrame's that are considered text frames.
|
// nsIFrame's that are considered text frames.
|
||||||
|
@ -122,87 +46,6 @@ struct nsCSSTextRun {
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
|
||||||
* This structure contains the horizontal layout state for line
|
|
||||||
* layout frame placement. This is factored out of nsCSSLineLayout so
|
|
||||||
* that the block layout code and the inline layout code can use
|
|
||||||
* nsCSSLineLayout to reflow and place frames.
|
|
||||||
*/
|
|
||||||
struct nsCSSInlineLayout {
|
|
||||||
nsCSSInlineLayout(nsCSSLineLayout& aLineLayout,
|
|
||||||
nsIFrame* aContainerFrame,
|
|
||||||
nsIStyleContext* aContainerStyle,
|
|
||||||
const nsReflowState& aContainerReflowState);
|
|
||||||
~nsCSSInlineLayout();
|
|
||||||
|
|
||||||
void Prepare(PRBool aUnconstrainedWidth,
|
|
||||||
PRBool aNoWrap,
|
|
||||||
nsSize* aMaxElementSize);
|
|
||||||
|
|
||||||
void SetReflowSpace(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight);
|
|
||||||
|
|
||||||
nsInlineReflowStatus ReflowAndPlaceFrame(nsIFrame* aFrame);
|
|
||||||
|
|
||||||
nscoord AlignFrames(nsIFrame* aFrame, PRInt32 aFrameCount,
|
|
||||||
nsRect& aBounds);
|
|
||||||
|
|
||||||
PRInt32 GetFrameNum() { return mFrameNum; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return an approximation of the line height for the line as
|
|
||||||
* reflowed so far. Note that this value doesn't take into account
|
|
||||||
* any vertical alignment properties on the frames in the line so
|
|
||||||
* it may be smaller than it should be.
|
|
||||||
*/
|
|
||||||
nscoord GetLineHeight() { return mMaxAscent + mMaxDescent; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
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);
|
|
||||||
|
|
||||||
nsCSSLineLayout& mLineLayout;
|
|
||||||
nsIFrame* mContainerFrame;
|
|
||||||
const nsStyleFont* mContainerFont;
|
|
||||||
const nsStyleText* mContainerText;
|
|
||||||
const nsStyleDisplay* mContainerDisplay;
|
|
||||||
const nsReflowState& mContainerReflowState;
|
|
||||||
PRUint8 mDirection;
|
|
||||||
|
|
||||||
PRPackedBool mUnconstrainedWidth;
|
|
||||||
PRPackedBool mNoWrap;
|
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
|
||||||
|
|
||||||
// 1) collecting frames for text-runs
|
// 1) collecting frames for text-runs
|
||||||
// 2) horizontal layout of frames for block
|
// 2) horizontal layout of frames for block
|
||||||
// 3) horizontal layout of frames for inline
|
// 3) horizontal layout of frames for inline
|
||||||
|
|
Загрузка…
Ссылка в новой задаче