Changed nsHTMLReflowState to compute 'offsets' for relatively positioned

elements
This commit is contained in:
troy%netscape.com 1999-01-16 20:58:17 +00:00
Родитель 0675aa20ad
Коммит 3a6b91ec12
13 изменённых файлов: 281 добавлений и 142 удалений

Просмотреть файл

@ -2121,8 +2121,9 @@ nsBaseIBFrame::ReflowBlockFrame(nsBlockReflowState& aState,
nsRect availSpace(availX, aState.mY, availWidth, availHeight);
WillReflowFrame(aState, aLine, frame);
nsReflowStatus frameReflowStatus;
nsMargin computedOffsets;
rv = brc.ReflowBlock(frame, availSpace, aState.IsAdjacentWithTop(),
frameReflowStatus);
computedOffsets, frameReflowStatus);
if (NS_FAILED(rv)) {
return rv;
}
@ -2147,7 +2148,7 @@ nsBaseIBFrame::ReflowBlockFrame(nsBlockReflowState& aState,
PRBool isAdjacentWithTop = aState.IsAdjacentWithTop();
PRBool applyTopMargin = aState.ShouldApplyTopMargin();
aKeepReflowGoing = brc.PlaceBlock(isAdjacentWithTop, applyTopMargin,
aState.mPrevBottomMargin,
aState.mPrevBottomMargin, computedOffsets,
aLine->mBounds, aLine->mCombinedArea);
if (aKeepReflowGoing) {
// Some of the child block fit

Просмотреть файл

@ -74,6 +74,7 @@ nsresult
nsBlockReflowContext::ReflowBlock(nsIFrame* aFrame,
const nsRect& aSpace,
PRBool aIsAdjacentWithTop,
nsMargin& aComputedOffsets,
nsReflowStatus& aFrameReflowStatus)
{
nsresult rv = NS_OK;
@ -121,6 +122,7 @@ nsBlockReflowContext::ReflowBlock(nsIFrame* aFrame,
// Setup reflow state for reflowing the frame
nsHTMLReflowState reflowState(mPresContext, aFrame, mOuterReflowState,
availSize);
aComputedOffsets = reflowState.computedOffsets;
reflowState.lineLayout = nsnull;
reflowState.mRunInFrame = mRunInFrame;
reflowState.mCompactMarginWidth = mCompactMarginWidth;
@ -247,6 +249,7 @@ nsBlockReflowContext::CollapseMargins(const nsMargin& aMargin,
PRBool
nsBlockReflowContext::PlaceBlock(PRBool aForceFit, PRBool aApplyTopMargin,
nscoord aPrevBottomMargin,
const nsMargin& aComputedOffsets,
nsRect& aInFlowBounds,
nsRect& aCombinedRect)
{
@ -341,7 +344,8 @@ nsBlockReflowContext::PlaceBlock(PRBool aForceFit, PRBool aApplyTopMargin,
mFrame->GetStyleData(eStyleStruct_Position,
(const nsStyleStruct*&)stylePos);
if (NS_STYLE_POSITION_RELATIVE == stylePos->mPosition) {
ComputeRelativePosition(mFrame, stylePos, x, y);
x += aComputedOffsets.left - aComputedOffsets.right;
y += aComputedOffsets.top - aComputedOffsets.bottom;
}
// Compute combined-rect in callers coordinate system. The value
@ -391,34 +395,3 @@ nsBlockReflowContext::PlaceBlock(PRBool aForceFit, PRBool aApplyTopMargin,
return fits;
}
void
nsBlockReflowContext::ComputeRelativePosition(nsIFrame* aFrame,
const nsStylePosition* aStylePos,
nscoord& aX, nscoord& aY)
{
nsStyleCoord coord;
nscoord dx = 0;
switch (aStylePos->mOffset.GetLeftUnit()) {
case eStyleUnit_Percent:
printf("XXX: not yet implemented: % relative position\n");
case eStyleUnit_Auto:
break;
case eStyleUnit_Coord:
dx = aStylePos->mOffset.GetLeft(coord).GetCoordValue();
break;
}
aX += dx;
nscoord dy = 0;
switch (aStylePos->mOffset.GetTopUnit()) {
case eStyleUnit_Percent:
printf("XXX: not yet implemented: % relative position\n");
case eStyleUnit_Auto:
break;
case eStyleUnit_Coord:
dy = aStylePos->mOffset.GetTop(coord).GetCoordValue();
break;
}
aY += dy;
}

Просмотреть файл

@ -50,10 +50,12 @@ public:
nsresult ReflowBlock(nsIFrame* aFrame,
const nsRect& aSpace,
PRBool aIsAdjacentWithTop,
nsMargin& aComputedOffsets,
nsReflowStatus& aReflowStatus);
PRBool PlaceBlock(PRBool aForceFit, PRBool aApplyTopMargin,
nscoord aPrevBottomMargin,
const nsMargin& aComputedOffsets,
nsRect& aInFlowBounds,
nsRect& aCombinedRect);
@ -106,10 +108,6 @@ public:
return b;
}
static void ComputeRelativePosition(nsIFrame* aFrame,
const nsStylePosition* aStylePos,
nscoord& aX, nscoord& aY);
protected:
nsIPresContext& mPresContext;
nsLineLayout& mLineLayout;

Просмотреть файл

@ -2121,8 +2121,9 @@ nsBaseIBFrame::ReflowBlockFrame(nsBlockReflowState& aState,
nsRect availSpace(availX, aState.mY, availWidth, availHeight);
WillReflowFrame(aState, aLine, frame);
nsReflowStatus frameReflowStatus;
nsMargin computedOffsets;
rv = brc.ReflowBlock(frame, availSpace, aState.IsAdjacentWithTop(),
frameReflowStatus);
computedOffsets, frameReflowStatus);
if (NS_FAILED(rv)) {
return rv;
}
@ -2147,7 +2148,7 @@ nsBaseIBFrame::ReflowBlockFrame(nsBlockReflowState& aState,
PRBool isAdjacentWithTop = aState.IsAdjacentWithTop();
PRBool applyTopMargin = aState.ShouldApplyTopMargin();
aKeepReflowGoing = brc.PlaceBlock(isAdjacentWithTop, applyTopMargin,
aState.mPrevBottomMargin,
aState.mPrevBottomMargin, computedOffsets,
aLine->mBounds, aLine->mCombinedArea);
if (aKeepReflowGoing) {
// Some of the child block fit

Просмотреть файл

@ -2121,8 +2121,9 @@ nsBaseIBFrame::ReflowBlockFrame(nsBlockReflowState& aState,
nsRect availSpace(availX, aState.mY, availWidth, availHeight);
WillReflowFrame(aState, aLine, frame);
nsReflowStatus frameReflowStatus;
nsMargin computedOffsets;
rv = brc.ReflowBlock(frame, availSpace, aState.IsAdjacentWithTop(),
frameReflowStatus);
computedOffsets, frameReflowStatus);
if (NS_FAILED(rv)) {
return rv;
}
@ -2147,7 +2148,7 @@ nsBaseIBFrame::ReflowBlockFrame(nsBlockReflowState& aState,
PRBool isAdjacentWithTop = aState.IsAdjacentWithTop();
PRBool applyTopMargin = aState.ShouldApplyTopMargin();
aKeepReflowGoing = brc.PlaceBlock(isAdjacentWithTop, applyTopMargin,
aState.mPrevBottomMargin,
aState.mPrevBottomMargin, computedOffsets,
aLine->mBounds, aLine->mCombinedArea);
if (aKeepReflowGoing) {
// Some of the child block fit

Просмотреть файл

@ -213,6 +213,81 @@ nsHTMLReflowState::CalculateLeftRightMargin(const nsHTMLReflowState* aContaining
}
}
void
nsHTMLReflowState::ComputeRelativeOffsets(const nsHTMLReflowState* cbrs,
const nsStylePosition* aPosition)
{
nsStyleCoord coord;
const nsHTMLReflowState* pcbrs = nsnull;
// If any of the offsets are 'inherit' we need to find the positioned
// containing block
if ((eStyleUnit_Inherit == aPosition->mOffset.GetLeftUnit()) ||
(eStyleUnit_Inherit == aPosition->mOffset.GetTopUnit()) ||
(eStyleUnit_Inherit == aPosition->mOffset.GetRightUnit()) ||
(eStyleUnit_Inherit == aPosition->mOffset.GetBottomUnit())) {
pcbrs = cbrs;
while (nsnull != pcbrs) {
const nsStylePosition* position;
pcbrs->frame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)position);
if ((NS_STYLE_POSITION_ABSOLUTE == position->mPosition) ||
(NS_STYLE_POSITION_RELATIVE == position->mPosition)) {
break;
}
pcbrs = (const nsHTMLReflowState*)pcbrs->parentReflowState; // XXX cast
}
}
// For relatively positioned elements 'auto' becomes 0
if (eStyleUnit_Inherit == aPosition->mOffset.GetLeftUnit()) {
computedOffsets.left = pcbrs ? pcbrs->computedOffsets.left : 0;
} else if (eStyleUnit_Auto == aPosition->mOffset.GetLeftUnit()) {
computedOffsets.left = 0;
} else {
ComputeHorizontalValue(cbrs->computedWidth, aPosition->mOffset.GetLeftUnit(),
aPosition->mOffset.GetLeft(coord),
computedOffsets.left);
}
if (eStyleUnit_Inherit == aPosition->mOffset.GetTopUnit()) {
computedOffsets.top = pcbrs ? pcbrs->computedOffsets.top : 0;
} else if ((eStyleUnit_Auto == aPosition->mOffset.GetTopUnit()) ||
((NS_AUTOHEIGHT == cbrs->computedHeight) &&
(eStyleUnit_Percent == aPosition->mOffset.GetTopUnit()))) {
computedOffsets.top = 0;
} else {
ComputeVerticalValue(cbrs->computedHeight, aPosition->mOffset.GetTopUnit(),
aPosition->mOffset.GetTop(coord),
computedOffsets.top);
}
if (eStyleUnit_Inherit == aPosition->mOffset.GetRightUnit()) {
computedOffsets.right = pcbrs ? pcbrs->computedOffsets.right : 0;
} else if (eStyleUnit_Auto == aPosition->mOffset.GetRightUnit()) {
computedOffsets.right = 0;
} else {
ComputeHorizontalValue(cbrs->computedWidth, aPosition->mOffset.GetRightUnit(),
aPosition->mOffset.GetRight(coord),
computedOffsets.right);
}
if (eStyleUnit_Inherit == aPosition->mOffset.GetBottomUnit()) {
computedOffsets.bottom = pcbrs ? pcbrs->computedOffsets.bottom : 0;
} else if ((eStyleUnit_Auto == aPosition->mOffset.GetBottomUnit()) ||
((NS_AUTOHEIGHT == cbrs->computedHeight) &&
(eStyleUnit_Percent == aPosition->mOffset.GetBottomUnit()))) {
computedOffsets.bottom = 0;
} else {
ComputeVerticalValue(cbrs->computedHeight, aPosition->mOffset.GetBottomUnit(),
aPosition->mOffset.GetBottom(coord),
computedOffsets.bottom);
}
}
void
nsHTMLReflowState::InitAbsoluteConstraints(nsIPresContext& aPresContext,
const nsHTMLReflowState* cbrs,
@ -265,7 +340,9 @@ nsHTMLReflowState::InitAbsoluteConstraints(nsIPresContext& aPresContext,
// Initialize the 'left' and 'right' computed offsets
PRBool leftIsAuto = PR_FALSE, rightIsAuto = PR_FALSE;
nsStyleCoord coord;
if (eStyleUnit_Auto == aPosition->mOffset.GetLeftUnit()) {
if (eStyleUnit_Inherit == aPosition->mOffset.GetLeftUnit()) {
computedOffsets.left = cbrs->computedOffsets.left;
} else if (eStyleUnit_Auto == aPosition->mOffset.GetLeftUnit()) {
if (NS_STYLE_DIRECTION_LTR == display->mDirection) {
computedOffsets.left = placeholderOffset.x;
} else {
@ -277,7 +354,9 @@ nsHTMLReflowState::InitAbsoluteConstraints(nsIPresContext& aPresContext,
aPosition->mOffset.GetLeft(coord),
computedOffsets.left);
}
if (eStyleUnit_Auto == aPosition->mOffset.GetRightUnit()) {
if (eStyleUnit_Inherit == aPosition->mOffset.GetRightUnit()) {
computedOffsets.right = cbrs->computedOffsets.right;
} else if (eStyleUnit_Auto == aPosition->mOffset.GetRightUnit()) {
if (NS_STYLE_DIRECTION_RTL == display->mDirection) {
computedOffsets.right = placeholderOffset.x;
} else {
@ -347,7 +426,9 @@ nsHTMLReflowState::InitAbsoluteConstraints(nsIPresContext& aPresContext,
// Initialize the 'top' and 'bottom' computed offsets
PRBool bottomIsAuto = PR_FALSE;
if ((eStyleUnit_Auto == aPosition->mOffset.GetTopUnit()) ||
if (eStyleUnit_Inherit == aPosition->mOffset.GetTopUnit()) {
computedOffsets.top = cbrs->computedOffsets.top;
} else if ((eStyleUnit_Auto == aPosition->mOffset.GetTopUnit()) ||
((NS_AUTOHEIGHT == containingBlockHeight) &&
(eStyleUnit_Percent == aPosition->mOffset.GetTopUnit()))) {
// Use the placeholder position
@ -357,7 +438,9 @@ nsHTMLReflowState::InitAbsoluteConstraints(nsIPresContext& aPresContext,
ComputeVerticalValue(containingBlockHeight, aPosition->mOffset.GetTopUnit(),
aPosition->mOffset.GetTop(coord), computedOffsets.top);
}
if ((eStyleUnit_Auto == aPosition->mOffset.GetBottomUnit()) ||
if (eStyleUnit_Inherit == aPosition->mOffset.GetBottomUnit()) {
computedOffsets.bottom = cbrs->computedOffsets.bottom;
} else if ((eStyleUnit_Auto == aPosition->mOffset.GetBottomUnit()) ||
((NS_AUTOHEIGHT == containingBlockHeight) &&
(eStyleUnit_Percent == aPosition->mOffset.GetBottomUnit()))) {
if (eStyleUnit_Auto == heightUnit) {
@ -447,36 +530,12 @@ nsHTMLReflowState::InitConstraints(nsIPresContext& aPresContext)
nsresult result = frame->GetStyleData(eStyleStruct_Position,
(const nsStyleStruct*&)pos);
// Compute margins from the specified margin style information
nsMargin margin;
ComputeMarginFor(frame, parentReflowState, margin);
// These become the default computed values, and may be adjusted below
computedLeftMargin = margin.left;
computedRightMargin = margin.right;
computedTopMargin = margin.top;
computedBottomMargin = margin.bottom;
// Calculate the line height.
// XXX Do we need to do this for all elements or just inline non-replaced
// elements?
mLineHeight = CalcLineHeight(aPresContext, frame);
// See if it's an inline non-replaced element
if (NS_CSS_FRAME_TYPE_INLINE == frameType) {
// 'width' property doesn't apply to inline non-replaced elements. The
// 'height' is given by the element's 'line-height' value
if (mLineHeight >= 0) {
computedHeight = mLineHeight;
}
return; // nothing else to compute
}
// If this is the root frame then set the computed width and
// height equal to the available space
if (nsnull == parentReflowState) {
computedWidth = availableWidth;
computedHeight = availableHeight;
computedLeftMargin = computedRightMargin = computedTopMargin = computedBottomMargin = 0;
} else {
// Get the containing block reflow state
@ -484,6 +543,39 @@ nsHTMLReflowState::InitConstraints(nsIPresContext& aPresContext)
GetContainingBlockReflowState(parentReflowState);
NS_ASSERTION(nsnull != cbrs, "no containing block");
// See if the element is relatively positioned
if (NS_STYLE_POSITION_RELATIVE == pos->mPosition) {
ComputeRelativeOffsets(cbrs, pos);
} else {
// Initialize offsets to 0
computedOffsets.SizeTo(0, 0, 0, 0);
}
// Compute margins from the specified margin style information
nsMargin margin;
ComputeMarginFor(frame, parentReflowState, margin);
// These become the default computed values, and may be adjusted below
computedLeftMargin = margin.left;
computedRightMargin = margin.right;
computedTopMargin = margin.top;
computedBottomMargin = margin.bottom;
// Calculate the line height.
// XXX Do we need to do this for all elements or just inline non-replaced
// elements?
mLineHeight = CalcLineHeight(aPresContext, frame);
// See if it's an inline non-replaced element
if (NS_CSS_FRAME_TYPE_INLINE == frameType) {
// 'width' property doesn't apply to inline non-replaced elements. The
// 'height' is given by the element's 'line-height' value
if (mLineHeight >= 0) {
computedHeight = mLineHeight;
}
return; // nothing else to compute
}
// Get the containing block width and height. We'll need them when
// calculating the computed width and height. For all elements other
// than absolutely positioned elements, the containing block is formed
@ -729,6 +821,7 @@ nsHTMLReflowState::ComputeHorizontalValue(nscoord aContainingBlockWidth,
const nsStyleCoord& aCoord,
nscoord& aResult)
{
NS_PRECONDITION(eStyleUnit_Inherit != aUnit, "unexpected unit");
aResult = 0;
if (eStyleUnit_Percent == aUnit) {
float pct = aCoord.GetPercentValue();
@ -745,6 +838,7 @@ nsHTMLReflowState::ComputeVerticalValue(nscoord aContainingBlockHeight,
const nsStyleCoord& aCoord,
nscoord& aResult)
{
NS_PRECONDITION(eStyleUnit_Inherit != aUnit, "unexpected unit");
aResult = 0;
if (eStyleUnit_Percent == aUnit) {
// Verify no one is trying to calculate a percentage based height against

Просмотреть файл

@ -2121,8 +2121,9 @@ nsBaseIBFrame::ReflowBlockFrame(nsBlockReflowState& aState,
nsRect availSpace(availX, aState.mY, availWidth, availHeight);
WillReflowFrame(aState, aLine, frame);
nsReflowStatus frameReflowStatus;
nsMargin computedOffsets;
rv = brc.ReflowBlock(frame, availSpace, aState.IsAdjacentWithTop(),
frameReflowStatus);
computedOffsets, frameReflowStatus);
if (NS_FAILED(rv)) {
return rv;
}
@ -2147,7 +2148,7 @@ nsBaseIBFrame::ReflowBlockFrame(nsBlockReflowState& aState,
PRBool isAdjacentWithTop = aState.IsAdjacentWithTop();
PRBool applyTopMargin = aState.ShouldApplyTopMargin();
aKeepReflowGoing = brc.PlaceBlock(isAdjacentWithTop, applyTopMargin,
aState.mPrevBottomMargin,
aState.mPrevBottomMargin, computedOffsets,
aLine->mBounds, aLine->mCombinedArea);
if (aKeepReflowGoing) {
// Some of the child block fit

Просмотреть файл

@ -74,6 +74,7 @@ nsresult
nsBlockReflowContext::ReflowBlock(nsIFrame* aFrame,
const nsRect& aSpace,
PRBool aIsAdjacentWithTop,
nsMargin& aComputedOffsets,
nsReflowStatus& aFrameReflowStatus)
{
nsresult rv = NS_OK;
@ -121,6 +122,7 @@ nsBlockReflowContext::ReflowBlock(nsIFrame* aFrame,
// Setup reflow state for reflowing the frame
nsHTMLReflowState reflowState(mPresContext, aFrame, mOuterReflowState,
availSize);
aComputedOffsets = reflowState.computedOffsets;
reflowState.lineLayout = nsnull;
reflowState.mRunInFrame = mRunInFrame;
reflowState.mCompactMarginWidth = mCompactMarginWidth;
@ -247,6 +249,7 @@ nsBlockReflowContext::CollapseMargins(const nsMargin& aMargin,
PRBool
nsBlockReflowContext::PlaceBlock(PRBool aForceFit, PRBool aApplyTopMargin,
nscoord aPrevBottomMargin,
const nsMargin& aComputedOffsets,
nsRect& aInFlowBounds,
nsRect& aCombinedRect)
{
@ -341,7 +344,8 @@ nsBlockReflowContext::PlaceBlock(PRBool aForceFit, PRBool aApplyTopMargin,
mFrame->GetStyleData(eStyleStruct_Position,
(const nsStyleStruct*&)stylePos);
if (NS_STYLE_POSITION_RELATIVE == stylePos->mPosition) {
ComputeRelativePosition(mFrame, stylePos, x, y);
x += aComputedOffsets.left - aComputedOffsets.right;
y += aComputedOffsets.top - aComputedOffsets.bottom;
}
// Compute combined-rect in callers coordinate system. The value
@ -391,34 +395,3 @@ nsBlockReflowContext::PlaceBlock(PRBool aForceFit, PRBool aApplyTopMargin,
return fits;
}
void
nsBlockReflowContext::ComputeRelativePosition(nsIFrame* aFrame,
const nsStylePosition* aStylePos,
nscoord& aX, nscoord& aY)
{
nsStyleCoord coord;
nscoord dx = 0;
switch (aStylePos->mOffset.GetLeftUnit()) {
case eStyleUnit_Percent:
printf("XXX: not yet implemented: % relative position\n");
case eStyleUnit_Auto:
break;
case eStyleUnit_Coord:
dx = aStylePos->mOffset.GetLeft(coord).GetCoordValue();
break;
}
aX += dx;
nscoord dy = 0;
switch (aStylePos->mOffset.GetTopUnit()) {
case eStyleUnit_Percent:
printf("XXX: not yet implemented: % relative position\n");
case eStyleUnit_Auto:
break;
case eStyleUnit_Coord:
dy = aStylePos->mOffset.GetTop(coord).GetCoordValue();
break;
}
aY += dy;
}

Просмотреть файл

@ -50,10 +50,12 @@ public:
nsresult ReflowBlock(nsIFrame* aFrame,
const nsRect& aSpace,
PRBool aIsAdjacentWithTop,
nsMargin& aComputedOffsets,
nsReflowStatus& aReflowStatus);
PRBool PlaceBlock(PRBool aForceFit, PRBool aApplyTopMargin,
nscoord aPrevBottomMargin,
const nsMargin& aComputedOffsets,
nsRect& aInFlowBounds,
nsRect& aCombinedRect);
@ -106,10 +108,6 @@ public:
return b;
}
static void ComputeRelativePosition(nsIFrame* aFrame,
const nsStylePosition* aStylePos,
nscoord& aX, nscoord& aY);
protected:
nsIPresContext& mPresContext;
nsLineLayout& mLineLayout;

Просмотреть файл

@ -2121,8 +2121,9 @@ nsBaseIBFrame::ReflowBlockFrame(nsBlockReflowState& aState,
nsRect availSpace(availX, aState.mY, availWidth, availHeight);
WillReflowFrame(aState, aLine, frame);
nsReflowStatus frameReflowStatus;
nsMargin computedOffsets;
rv = brc.ReflowBlock(frame, availSpace, aState.IsAdjacentWithTop(),
frameReflowStatus);
computedOffsets, frameReflowStatus);
if (NS_FAILED(rv)) {
return rv;
}
@ -2147,7 +2148,7 @@ nsBaseIBFrame::ReflowBlockFrame(nsBlockReflowState& aState,
PRBool isAdjacentWithTop = aState.IsAdjacentWithTop();
PRBool applyTopMargin = aState.ShouldApplyTopMargin();
aKeepReflowGoing = brc.PlaceBlock(isAdjacentWithTop, applyTopMargin,
aState.mPrevBottomMargin,
aState.mPrevBottomMargin, computedOffsets,
aLine->mBounds, aLine->mCombinedArea);
if (aKeepReflowGoing) {
// Some of the child block fit

Просмотреть файл

@ -2121,8 +2121,9 @@ nsBaseIBFrame::ReflowBlockFrame(nsBlockReflowState& aState,
nsRect availSpace(availX, aState.mY, availWidth, availHeight);
WillReflowFrame(aState, aLine, frame);
nsReflowStatus frameReflowStatus;
nsMargin computedOffsets;
rv = brc.ReflowBlock(frame, availSpace, aState.IsAdjacentWithTop(),
frameReflowStatus);
computedOffsets, frameReflowStatus);
if (NS_FAILED(rv)) {
return rv;
}
@ -2147,7 +2148,7 @@ nsBaseIBFrame::ReflowBlockFrame(nsBlockReflowState& aState,
PRBool isAdjacentWithTop = aState.IsAdjacentWithTop();
PRBool applyTopMargin = aState.ShouldApplyTopMargin();
aKeepReflowGoing = brc.PlaceBlock(isAdjacentWithTop, applyTopMargin,
aState.mPrevBottomMargin,
aState.mPrevBottomMargin, computedOffsets,
aLine->mBounds, aLine->mCombinedArea);
if (aKeepReflowGoing) {
// Some of the child block fit

Просмотреть файл

@ -213,6 +213,81 @@ nsHTMLReflowState::CalculateLeftRightMargin(const nsHTMLReflowState* aContaining
}
}
void
nsHTMLReflowState::ComputeRelativeOffsets(const nsHTMLReflowState* cbrs,
const nsStylePosition* aPosition)
{
nsStyleCoord coord;
const nsHTMLReflowState* pcbrs = nsnull;
// If any of the offsets are 'inherit' we need to find the positioned
// containing block
if ((eStyleUnit_Inherit == aPosition->mOffset.GetLeftUnit()) ||
(eStyleUnit_Inherit == aPosition->mOffset.GetTopUnit()) ||
(eStyleUnit_Inherit == aPosition->mOffset.GetRightUnit()) ||
(eStyleUnit_Inherit == aPosition->mOffset.GetBottomUnit())) {
pcbrs = cbrs;
while (nsnull != pcbrs) {
const nsStylePosition* position;
pcbrs->frame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)position);
if ((NS_STYLE_POSITION_ABSOLUTE == position->mPosition) ||
(NS_STYLE_POSITION_RELATIVE == position->mPosition)) {
break;
}
pcbrs = (const nsHTMLReflowState*)pcbrs->parentReflowState; // XXX cast
}
}
// For relatively positioned elements 'auto' becomes 0
if (eStyleUnit_Inherit == aPosition->mOffset.GetLeftUnit()) {
computedOffsets.left = pcbrs ? pcbrs->computedOffsets.left : 0;
} else if (eStyleUnit_Auto == aPosition->mOffset.GetLeftUnit()) {
computedOffsets.left = 0;
} else {
ComputeHorizontalValue(cbrs->computedWidth, aPosition->mOffset.GetLeftUnit(),
aPosition->mOffset.GetLeft(coord),
computedOffsets.left);
}
if (eStyleUnit_Inherit == aPosition->mOffset.GetTopUnit()) {
computedOffsets.top = pcbrs ? pcbrs->computedOffsets.top : 0;
} else if ((eStyleUnit_Auto == aPosition->mOffset.GetTopUnit()) ||
((NS_AUTOHEIGHT == cbrs->computedHeight) &&
(eStyleUnit_Percent == aPosition->mOffset.GetTopUnit()))) {
computedOffsets.top = 0;
} else {
ComputeVerticalValue(cbrs->computedHeight, aPosition->mOffset.GetTopUnit(),
aPosition->mOffset.GetTop(coord),
computedOffsets.top);
}
if (eStyleUnit_Inherit == aPosition->mOffset.GetRightUnit()) {
computedOffsets.right = pcbrs ? pcbrs->computedOffsets.right : 0;
} else if (eStyleUnit_Auto == aPosition->mOffset.GetRightUnit()) {
computedOffsets.right = 0;
} else {
ComputeHorizontalValue(cbrs->computedWidth, aPosition->mOffset.GetRightUnit(),
aPosition->mOffset.GetRight(coord),
computedOffsets.right);
}
if (eStyleUnit_Inherit == aPosition->mOffset.GetBottomUnit()) {
computedOffsets.bottom = pcbrs ? pcbrs->computedOffsets.bottom : 0;
} else if ((eStyleUnit_Auto == aPosition->mOffset.GetBottomUnit()) ||
((NS_AUTOHEIGHT == cbrs->computedHeight) &&
(eStyleUnit_Percent == aPosition->mOffset.GetBottomUnit()))) {
computedOffsets.bottom = 0;
} else {
ComputeVerticalValue(cbrs->computedHeight, aPosition->mOffset.GetBottomUnit(),
aPosition->mOffset.GetBottom(coord),
computedOffsets.bottom);
}
}
void
nsHTMLReflowState::InitAbsoluteConstraints(nsIPresContext& aPresContext,
const nsHTMLReflowState* cbrs,
@ -265,7 +340,9 @@ nsHTMLReflowState::InitAbsoluteConstraints(nsIPresContext& aPresContext,
// Initialize the 'left' and 'right' computed offsets
PRBool leftIsAuto = PR_FALSE, rightIsAuto = PR_FALSE;
nsStyleCoord coord;
if (eStyleUnit_Auto == aPosition->mOffset.GetLeftUnit()) {
if (eStyleUnit_Inherit == aPosition->mOffset.GetLeftUnit()) {
computedOffsets.left = cbrs->computedOffsets.left;
} else if (eStyleUnit_Auto == aPosition->mOffset.GetLeftUnit()) {
if (NS_STYLE_DIRECTION_LTR == display->mDirection) {
computedOffsets.left = placeholderOffset.x;
} else {
@ -277,7 +354,9 @@ nsHTMLReflowState::InitAbsoluteConstraints(nsIPresContext& aPresContext,
aPosition->mOffset.GetLeft(coord),
computedOffsets.left);
}
if (eStyleUnit_Auto == aPosition->mOffset.GetRightUnit()) {
if (eStyleUnit_Inherit == aPosition->mOffset.GetRightUnit()) {
computedOffsets.right = cbrs->computedOffsets.right;
} else if (eStyleUnit_Auto == aPosition->mOffset.GetRightUnit()) {
if (NS_STYLE_DIRECTION_RTL == display->mDirection) {
computedOffsets.right = placeholderOffset.x;
} else {
@ -347,7 +426,9 @@ nsHTMLReflowState::InitAbsoluteConstraints(nsIPresContext& aPresContext,
// Initialize the 'top' and 'bottom' computed offsets
PRBool bottomIsAuto = PR_FALSE;
if ((eStyleUnit_Auto == aPosition->mOffset.GetTopUnit()) ||
if (eStyleUnit_Inherit == aPosition->mOffset.GetTopUnit()) {
computedOffsets.top = cbrs->computedOffsets.top;
} else if ((eStyleUnit_Auto == aPosition->mOffset.GetTopUnit()) ||
((NS_AUTOHEIGHT == containingBlockHeight) &&
(eStyleUnit_Percent == aPosition->mOffset.GetTopUnit()))) {
// Use the placeholder position
@ -357,7 +438,9 @@ nsHTMLReflowState::InitAbsoluteConstraints(nsIPresContext& aPresContext,
ComputeVerticalValue(containingBlockHeight, aPosition->mOffset.GetTopUnit(),
aPosition->mOffset.GetTop(coord), computedOffsets.top);
}
if ((eStyleUnit_Auto == aPosition->mOffset.GetBottomUnit()) ||
if (eStyleUnit_Inherit == aPosition->mOffset.GetBottomUnit()) {
computedOffsets.bottom = cbrs->computedOffsets.bottom;
} else if ((eStyleUnit_Auto == aPosition->mOffset.GetBottomUnit()) ||
((NS_AUTOHEIGHT == containingBlockHeight) &&
(eStyleUnit_Percent == aPosition->mOffset.GetBottomUnit()))) {
if (eStyleUnit_Auto == heightUnit) {
@ -447,36 +530,12 @@ nsHTMLReflowState::InitConstraints(nsIPresContext& aPresContext)
nsresult result = frame->GetStyleData(eStyleStruct_Position,
(const nsStyleStruct*&)pos);
// Compute margins from the specified margin style information
nsMargin margin;
ComputeMarginFor(frame, parentReflowState, margin);
// These become the default computed values, and may be adjusted below
computedLeftMargin = margin.left;
computedRightMargin = margin.right;
computedTopMargin = margin.top;
computedBottomMargin = margin.bottom;
// Calculate the line height.
// XXX Do we need to do this for all elements or just inline non-replaced
// elements?
mLineHeight = CalcLineHeight(aPresContext, frame);
// See if it's an inline non-replaced element
if (NS_CSS_FRAME_TYPE_INLINE == frameType) {
// 'width' property doesn't apply to inline non-replaced elements. The
// 'height' is given by the element's 'line-height' value
if (mLineHeight >= 0) {
computedHeight = mLineHeight;
}
return; // nothing else to compute
}
// If this is the root frame then set the computed width and
// height equal to the available space
if (nsnull == parentReflowState) {
computedWidth = availableWidth;
computedHeight = availableHeight;
computedLeftMargin = computedRightMargin = computedTopMargin = computedBottomMargin = 0;
} else {
// Get the containing block reflow state
@ -484,6 +543,39 @@ nsHTMLReflowState::InitConstraints(nsIPresContext& aPresContext)
GetContainingBlockReflowState(parentReflowState);
NS_ASSERTION(nsnull != cbrs, "no containing block");
// See if the element is relatively positioned
if (NS_STYLE_POSITION_RELATIVE == pos->mPosition) {
ComputeRelativeOffsets(cbrs, pos);
} else {
// Initialize offsets to 0
computedOffsets.SizeTo(0, 0, 0, 0);
}
// Compute margins from the specified margin style information
nsMargin margin;
ComputeMarginFor(frame, parentReflowState, margin);
// These become the default computed values, and may be adjusted below
computedLeftMargin = margin.left;
computedRightMargin = margin.right;
computedTopMargin = margin.top;
computedBottomMargin = margin.bottom;
// Calculate the line height.
// XXX Do we need to do this for all elements or just inline non-replaced
// elements?
mLineHeight = CalcLineHeight(aPresContext, frame);
// See if it's an inline non-replaced element
if (NS_CSS_FRAME_TYPE_INLINE == frameType) {
// 'width' property doesn't apply to inline non-replaced elements. The
// 'height' is given by the element's 'line-height' value
if (mLineHeight >= 0) {
computedHeight = mLineHeight;
}
return; // nothing else to compute
}
// Get the containing block width and height. We'll need them when
// calculating the computed width and height. For all elements other
// than absolutely positioned elements, the containing block is formed
@ -729,6 +821,7 @@ nsHTMLReflowState::ComputeHorizontalValue(nscoord aContainingBlockWidth,
const nsStyleCoord& aCoord,
nscoord& aResult)
{
NS_PRECONDITION(eStyleUnit_Inherit != aUnit, "unexpected unit");
aResult = 0;
if (eStyleUnit_Percent == aUnit) {
float pct = aCoord.GetPercentValue();
@ -745,6 +838,7 @@ nsHTMLReflowState::ComputeVerticalValue(nscoord aContainingBlockHeight,
const nsStyleCoord& aCoord,
nscoord& aResult)
{
NS_PRECONDITION(eStyleUnit_Inherit != aUnit, "unexpected unit");
aResult = 0;
if (eStyleUnit_Percent == aUnit) {
// Verify no one is trying to calculate a percentage based height against

Просмотреть файл

@ -322,6 +322,9 @@ protected:
nscoord containingBlockWidth,
nscoord containingBlockHeight);
void ComputeRelativeOffsets(const nsHTMLReflowState* cbrs,
const nsStylePosition* aPosition);
void CalculateLeftRightMargin(const nsHTMLReflowState* aContainingBlockRS,
const nsStyleSpacing* aSpacing,
nscoord aComputedWidth,