This commit is contained in:
kipp 1998-06-18 16:25:41 +00:00
parent 5cb81ae627
commit 88d50c8d17
14 changed files with 4810 additions and 0 deletions

24
layout/css/Makefile Normal file
View File

@ -0,0 +1,24 @@
#!gmake
#
# 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 = ../..
DIRS = layout
include $(DEPTH)/config/config.mk
include $(DEPTH)/config/rules.mk

View File

@ -0,0 +1,24 @@
#!gmake
#
# 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 = ../../..
DIRS = src
include $(DEPTH)/config/config.mk
include $(DEPTH)/config/rules.mk

View File

@ -0,0 +1,22 @@
#!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=..\..\..
DIRS=src
include <$(DEPTH)\layout\config\rules.mak>

View File

@ -0,0 +1,43 @@
#!gmake
#
# 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 = raptorhtmlline_s
# Note the sophisticated alphabetical ordering :-|
CPPSRCS = \
nsBlockFrame.cpp \
nsHTMLLineLayout.cpp \
nsInlineFrame.cpp \
nsLineData.cpp \
$(NULL)
MODULE = raptor
REQUIRES = xpcom raptor dom netlib
include $(DEPTH)/config/config.mk
LCFLAGS += -D_IMPL_NS_HTML
INCLUDES += -I../../style/src -I../../../base/src
include $(DEPTH)/config/rules.mk
install::
$(INSTALL) broken-image.gif $(DIST)/bin/res/html

View File

@ -0,0 +1,55 @@
#!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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,176 @@
/* -*- 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 nsCSSBlockFrame_h___
#define nsCSSBlockFrame_h___
#include "nsCSSContainerFrame.h"
#include "nsIFloaterContainer.h"
#include "nsIRunaround.h"
#include "nsISpaceManager.h"
#include "nsVoidArray.h"
struct nsCSSInlineLayout;
class nsPlaceholderFrame;
struct FrameData;
struct nsBlockBandData : public nsBandData {
// Trapezoids used during band processing
nsBandTrapezoid data[12];
// Bounding rect of available space between any left and right floaters
nsRect availSpace;
nsBlockBandData() {
size = 12;
trapezoids = data;
}
/**
* Computes the bounding rect of the available space, i.e. space
* between any left and right floaters Uses the current trapezoid
* data, see nsISpaceManager::GetBandData(). Also updates member
* data "availSpace".
*/
void ComputeAvailSpaceRect();
};
//----------------------------------------------------------------------
struct nsCSSBlockReflowState : public nsReflowState {
nsCSSBlockReflowState(nsIPresContext* aPresContext,
nsISpaceManager* aSpaceManager,
nsCSSContainerFrame* aBlock,
const nsReflowState& aReflowState,
nsSize* aMaxElementSize);
~nsCSSBlockReflowState();
/**
* Update the mCurrentBand data based on the current mY position.
*/
void GetAvailableSpace();
void PlaceCurrentLineFloater(nsIFrame* aFloater);
void PlaceBelowCurrentLineFloaters(nsVoidArray* aFloaterList);
void ClearFloaters(PRUint8 aBreakType);
nsIPresContext* mPresContext;
nsISpaceManager* mSpaceManager;
nsBlockBandData mCurrentBand;
nsCSSContainerFrame* mBlock;
PRBool mBlockIsPseudo;
nsIStyleContext* mBlockSC;
nsMargin mBorderPadding;
nsSize mAvailSize;
nsSize mStyleSize;
PRIntn mStyleSizeFlags;
nscoord mDeltaWidth;
PRPackedBool mUnconstrainedWidth, mUnconstrainedHeight;
PRPackedBool mNoWrap;
nscoord mX, mY;
nscoord mPrevPosBottomMargin;
nscoord mPrevNegBottomMargin;
nscoord mKidXMost;
nsSize* mMaxElementSize;
nsVoidArray mPendingFloaters;
nsCSSInlineLayout* mCurrentLine;
// XXX The next list ordinal for counting list bullets
PRInt32 mNextListOrdinal;
};
//----------------------------------------------------------------------
class nsCSSBlockFrame : public nsCSSContainerFrame,
public nsIRunaround,
public nsIFloaterContainer
{
public:
static nsresult NewFrame(nsIFrame** aInstancePtrResult,
nsIContent* aContent,
nsIFrame* aParent);
// nsISupports
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
// nsIFrame
NS_IMETHOD IsSplittable(nsSplittableType& aIsSplittable) const;
NS_IMETHOD CreateContinuingFrame(nsIPresContext* aPresContext,
nsIFrame* aParent,
nsIStyleContext* aStyleContext,
nsIFrame*& aContinuingFrame);
NS_IMETHOD List(FILE* out, PRInt32 aIndent) const;
NS_IMETHOD ListTag(FILE* out) const;
// XXX implement regular reflow method too!
// nsIRunaround
NS_IMETHOD Reflow(nsIPresContext* aPresContext,
nsISpaceManager* aSpaceManager,
nsReflowMetrics& aDesiredSize,
const nsReflowState& aReflowState,
nsRect& aDesiredRect,
nsReflowStatus& aStatus);
// nsIFloaterContainer
virtual PRBool AddFloater(nsIPresContext* aPresContext,
const nsReflowState& aPlaceholderReflowState,
nsIFrame* aFloater,
nsPlaceholderFrame* aPlaceholder);
protected:
nsCSSBlockFrame(nsIContent* aContent, nsIFrame* aParent);
~nsCSSBlockFrame();
virtual void WillDeleteNextInFlowFrame(nsIFrame* aNextInFlow);
virtual PRIntn GetSkipSides() const;
void RecoverState(nsCSSBlockReflowState& aStatus, FrameData* fp);
nsresult FrameAppendedReflow(nsCSSBlockReflowState& aState);
nsresult ChildIncrementalReflow(nsCSSBlockReflowState& aState);
nsresult ResizeReflow(nsCSSBlockReflowState& aState);
void ComputeFinalSize(nsCSSBlockReflowState& aState,
nsReflowMetrics& aMetrics,
nsRect& aDesiredRect);
void ReflowFloater(nsIPresContext* aPresContext,
nsCSSBlockReflowState& aState,
nsIFrame* aFloaterFrame);
PRBool IsLeftMostChild(nsIFrame* aFrame);
FrameData* mFrames;
// placeholder frames for floaters to display at the top line
nsVoidArray* mRunInFloaters;
};
#define IS_REFLOW_ERROR(_status) (PRInt32(_status) < 0)
#endif /* nsCSSBlockFrame_h___ */

View File

@ -0,0 +1,50 @@
/* -*- 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 "nsCSSContainerFrame.h"
nsCSSContainerFrame::nsCSSContainerFrame(nsIContent* aContent,
nsIFrame* aParent)
: nsHTMLContainerFrame(aContent, aParent)
{
}
nsCSSContainerFrame::~nsCSSContainerFrame()
{
}
#if 0
NS_IMETHODIMP
nsCSSContainerFrame::ContentAppended(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer)
{
// Get to the last-in-flow of our frame (that is where appends occur)
nsCSSContainerFrame* lastInFlow = (nsCSSContainerFrame*) GetLastInFlow();
// Now generate a reflow command targetted at our last-in-flow frame
nsIReflowCommand* cmd;
nsresult rv = NS_NewHTMLReflowCommand(&cmd, lastInFlow,
nsIReflowCommand::FrameAppended);
if (NS_OK == rv) {
aShell->AppendReflowCommand(cmd);
NS_RELEASE(cmd);
}
return rv;
}
#endif

View File

@ -0,0 +1,47 @@
/* -*- 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 nsCSSContainerFrame_h___
#define nsCSSContainerFrame_h___
#include "nsHTMLContainerFrame.h"
class nsCSSContainerFrame : public nsHTMLContainerFrame {
public:
#if 0
NS_IMETHOD ContentAppended(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer);
#endif
protected:
nsCSSContainerFrame(nsIContent* aContent, nsIFrame* aParent);
~nsCSSContainerFrame();
#if 0
PRInt32 NextChildOffset() const {
return mLastContentOffset + (mLastContentIsComplete ? 1 : 0);
}
PRInt32 mFirstContentOffset;
PRInt32 mLastContentOffset;
PRBool mLastContentIsComplete; // XXX move into frame-state
#endif
};
#endif /* nsCSSContainerFrame_h___ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,114 @@
/* -*- 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 "nsCSSLineLayout.h"
class nsInlineState;
// Inline container class. Does not support being used as a pseudo frame
class nsInlineFrame : public nsHTMLContainerFrame, public nsIInlineReflow {
public:
static nsresult NewFrame(nsIFrame** aInstancePtrResult,
nsIContent* aContent,
nsIFrame* aParent);
// nsISupports
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
// nsIFrame
NS_IMETHOD Reflow(nsIPresContext* aPresContext,
nsReflowMetrics& aDesiredSize,
const nsReflowState& aReflowState,
nsReflowStatus& aStatus);
// nsIInlineReflow
NS_IMETHOD FindTextRuns(nsCSSLineLayout& aLineLayout);
NS_IMETHOD InlineReflow(nsCSSLineLayout& aLineLayout,
nsReflowMetrics& aDesiredSize,
const nsReflowState& aReflowState);
protected:
nsInlineFrame(nsIContent* aContent, nsIFrame* aParent);
virtual ~nsInlineFrame();
virtual PRIntn GetSkipSides() const;
void InitializeState(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
nsInlineState& aState);
PRBool DidFitChild(nsIPresContext* aPresContext,
nsInlineState& aState,
nsIFrame* aChildFrame,
nsReflowMetrics& aChildMetrics);
PRBool CanFitChild(nsIPresContext* aPresContext,
nsInlineState& aState,
nsIFrame* aChildFrame);
void ComputeFinalSize(nsIPresContext* aPresContext,
nsInlineState& aState,
nsReflowMetrics& aSize);
PRBool ReflowMappedChildrenFrom(nsIPresContext* aPresContext,
nsInlineState& aState,
nsIFrame* aChildFrame,
PRInt32 aChildIndex);
PRBool PullUpChildren(nsIPresContext* aPresContext,
nsInlineState& aState);
nsReflowStatus ReflowUnmappedChildren(nsIPresContext* aPresContext,
nsInlineState& aState);
void PlaceChild(nsIFrame* aChild,
PRInt32 aIndex, // in the child frame list
nsInlineState& aState,
const nsReflowMetrics& aChildSize,
const nsSize* aChildMaxElementSize);
PRInt32 RecoverState(nsIPresContext* aCX,
nsInlineState& aState,
nsIFrame* aSkipChild);
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___ */

View File

@ -0,0 +1,470 @@
/* -*- 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 "nsCSSLineLayout.h"
#include "nsCSSLayout.h"
#include "nsIFontMetrics.h"
#include "nsIPresContext.h"
#include "nsIRunaround.h"
#include "nsIStyleContext.h"
// XXX nsCSSIIDs.[h,cpp]
static NS_DEFINE_IID(kIInlineReflowIID, NS_IINLINE_REFLOW_IID);
static NS_DEFINE_IID(kIRunaroundIID, NS_IRUNAROUND_IID);
void
nsCSSTextRun::List(FILE* out, PRInt32 aIndent)
{
PRInt32 i;
for (i = aIndent; --i >= 0; ) fputs(" ", out);
PRInt32 n = mArray.Count();
fprintf(out, "count=%d <\n", n);
for (i = 0; i < n; i++) {
nsIFrame* text = (nsIFrame*) mArray.ElementAt(i);
text->List(out, aIndent + 1);
}
for (i = aIndent; --i >= 0; ) fputs(" ", out);
fputs(">\n", out);
}
//----------------------------------------------------------------------
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,
nsISpaceManager* aSpaceManager)
{
mPresContext = aPresContext;
mSpaceManager = aSpaceManager;
mTextRuns = nsnull;
mTextRunP = &mTextRuns;
mCurrentTextRun = nsnull;
mListPositionOutside = PR_FALSE;
mLineNumber = 0;
mLeftEdge = 0;
mColumn = 0;
}
nsCSSLineLayout::~nsCSSLineLayout()
{
if (nsnull != mTextRuns) {
delete mTextRuns;
}
}
void
nsCSSLineLayout::EndTextRun()
{
if (nsnull != mCurrentTextRun) {
// Keep the text-run if it's not empty
if (mCurrentTextRun->mArray.Count() > 0) {
*mTextRunP = mCurrentTextRun;
mTextRunP = &mCurrentTextRun->mNext;
}
else {
delete mCurrentTextRun;
}
mCurrentTextRun = nsnull;
}
}
nsresult
nsCSSLineLayout::AddText(nsIFrame* aTextFrame)
{
if (nsnull == mCurrentTextRun) {
mCurrentTextRun = new nsCSSTextRun();
}
mCurrentTextRun->mArray.AppendElement(aTextFrame);
return NS_OK;/* XXX */
}

View File

@ -0,0 +1,255 @@
/* -*- 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 nsCSSLineLayout_h___
#define nsCSSLineLayout_h___
#include "nsCSSBlockFrame.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
// nsIFrame's that are considered text frames.
struct nsCSSTextRun {
nsCSSTextRun() {
mNext = nsnull;
}
~nsCSSTextRun() {
nsCSSTextRun* run = mNext;
while (nsnull != run) {
nsCSSTextRun* next = run->mNext;
delete run;
run = next;
}
}
void List(FILE* out, PRInt32 aIndent);
nsVoidArray mArray;
nsCSSTextRun* mNext;
};
//----------------------------------------------------------------------
/**
* 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
// 2) horizontal layout of frames for block
// 3) horizontal layout of frames for inline
// 4) state storage for text-reflow
class nsCSSLineLayout {
public:
nsCSSLineLayout(nsIPresContext* aPresContext,
nsISpaceManager* aSpaceManager);
~nsCSSLineLayout();
void EndTextRun();
// Note: continuation frames must NOT add themselves; just the
// first-in-flow
nsresult AddText(nsIFrame* aTextFrame);
nsCSSTextRun* TakeTextRuns() {
nsCSSTextRun* result = mTextRuns;
mTextRuns = nsnull;
return result;
}
void Prepare(nscoord aLeftEdge) {
mLeftEdge = aLeftEdge;
mColumn = 0;
}
PRInt32 GetColumn() {
return mColumn;
}
void SetColumn(PRInt32 aNewColumn) {
mColumn = aNewColumn;
}
nsIPresContext* mPresContext;
nsISpaceManager* mSpaceManager;
PRBool mListPositionOutside;
PRInt32 mLineNumber;
nscoord mLeftEdge;
PRInt32 mColumn;
nsCSSTextRun* mTextRuns;
nsCSSTextRun** mTextRunP;
nsCSSTextRun* mCurrentTextRun;
};
#endif /* nsCSSLineLayout_h___ */

22
layout/css/makefile.win Normal file
View File

@ -0,0 +1,22 @@
#!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=..\..
DIRS = layout
include <$(DEPTH)\layout\config\rules.mak>