зеркало из https://github.com/mozilla/pjs.git
Changed nsHTMLReflowState to compute 'offsets' for relatively positioned
elements
This commit is contained in:
Родитель
0675aa20ad
Коммит
3a6b91ec12
|
@ -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,
|
||||
|
|
Загрузка…
Ссылка в новой задаче