зеркало из https://github.com/mozilla/gecko-dev.git
bug 28811
r=karnaze The problem was we were over-eager in optimizing away a resize reflow for lines that contain %-aware children. We were only looking at the first-level children of a line, not all the children. Now, we compute a bit for each inline container based on it's children, true if any of them are %-aware wrt any width measurement. We propogate this bit upwards to a bit on the line itself, and check this bit during reflow.
This commit is contained in:
Родитель
a7d77f33f2
Коммит
37e900a62c
|
@ -158,6 +158,7 @@ InitDebugFlags()
|
||||||
#undef REFLOW_STATUS_COVERAGE // I think this is most useful for printing, to see which frames return "incomplete"
|
#undef REFLOW_STATUS_COVERAGE // I think this is most useful for printing, to see which frames return "incomplete"
|
||||||
#undef NOISY_SPACEMANAGER // enables debug output for space manager use, useful for analysing reflow of floaters and positioned elements
|
#undef NOISY_SPACEMANAGER // enables debug output for space manager use, useful for analysing reflow of floaters and positioned elements
|
||||||
#undef NOISY_BLOCK_INVALIDATE // enables debug output for all calls to invalidate
|
#undef NOISY_BLOCK_INVALIDATE // enables debug output for all calls to invalidate
|
||||||
|
#undef REALLY_NOISY_REFLOW // some extra debug info
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -781,7 +782,8 @@ nsBlockReflowState::ComputeBlockAvailSpace(nsIFrame* aFrame,
|
||||||
|
|
||||||
const nsMargin& borderPadding = BorderPadding();
|
const nsMargin& borderPadding = BorderPadding();
|
||||||
|
|
||||||
if (NS_FRAME_SPLITTABLE_NON_RECTANGULAR == aSplitType) {
|
if (NS_FRAME_SPLITTABLE_NON_RECTANGULAR == aSplitType)
|
||||||
|
{
|
||||||
if (mBand.GetFloaterCount()) {
|
if (mBand.GetFloaterCount()) {
|
||||||
// Use the float-edge property to determine how the child block
|
// Use the float-edge property to determine how the child block
|
||||||
// will interact with the floater.
|
// will interact with the floater.
|
||||||
|
@ -2006,15 +2008,6 @@ HaveAutoWidth(const nsHTMLReflowState& aReflowState)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static PRBool
|
|
||||||
IsPercentageUnitSides(const nsStyleSides* aSides)
|
|
||||||
{
|
|
||||||
return eStyleUnit_Percent == aSides->GetLeftUnit()
|
|
||||||
|| eStyleUnit_Percent == aSides->GetRightUnit()
|
|
||||||
|| eStyleUnit_Percent == aSides->GetTopUnit()
|
|
||||||
|| eStyleUnit_Percent == aSides->GetBottomUnit();
|
|
||||||
}
|
|
||||||
|
|
||||||
static PRBool
|
static PRBool
|
||||||
IsPercentageAwareChild(const nsIFrame* aFrame)
|
IsPercentageAwareChild(const nsIFrame* aFrame)
|
||||||
{
|
{
|
||||||
|
@ -2024,9 +2017,9 @@ IsPercentageAwareChild(const nsIFrame* aFrame)
|
||||||
return PR_TRUE; // just to be on the safe side
|
return PR_TRUE; // just to be on the safe side
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsPercentageUnitSides(&space->mMargin)
|
if (nsLineLayout::IsPercentageUnitSides(&space->mMargin)
|
||||||
|| IsPercentageUnitSides(&space->mPadding)
|
|| nsLineLayout::IsPercentageUnitSides(&space->mPadding)
|
||||||
|| IsPercentageUnitSides(&space->mBorderRadius)) {
|
|| nsLineLayout::IsPercentageUnitSides(&space->mBorderRadius)) {
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2042,7 +2035,7 @@ IsPercentageAwareChild(const nsIFrame* aFrame)
|
||||||
|| eStyleUnit_Percent == pos->mHeight.GetUnit()
|
|| eStyleUnit_Percent == pos->mHeight.GetUnit()
|
||||||
|| eStyleUnit_Percent == pos->mMinHeight.GetUnit()
|
|| eStyleUnit_Percent == pos->mMinHeight.GetUnit()
|
||||||
|| eStyleUnit_Percent == pos->mMaxHeight.GetUnit()
|
|| eStyleUnit_Percent == pos->mMaxHeight.GetUnit()
|
||||||
|| IsPercentageUnitSides(&pos->mOffset)) { // XXX need more here!!!
|
|| nsLineLayout::IsPercentageUnitSides(&pos->mOffset)) { // XXX need more here!!!
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2600,6 +2593,7 @@ nsBlockFrame::PrepareResizeReflow(nsBlockReflowState& aState)
|
||||||
// newlines. Therefore, we don't need to reflow the line.
|
// newlines. Therefore, we don't need to reflow the line.
|
||||||
}
|
}
|
||||||
else if ((line->mNext && !line->HasBreak()) ||
|
else if ((line->mNext && !line->HasBreak()) ||
|
||||||
|
line->ResizeReflowOptimizationDisabled() ||
|
||||||
line->HasFloaters() || line->IsImpactedByFloater() ||
|
line->HasFloaters() || line->IsImpactedByFloater() ||
|
||||||
line->HasPercentageChild() ||
|
line->HasPercentageChild() ||
|
||||||
(line->mBounds.XMost() > newAvailWidth)) {
|
(line->mBounds.XMost() > newAvailWidth)) {
|
||||||
|
|
|
@ -158,6 +158,7 @@ InitDebugFlags()
|
||||||
#undef REFLOW_STATUS_COVERAGE // I think this is most useful for printing, to see which frames return "incomplete"
|
#undef REFLOW_STATUS_COVERAGE // I think this is most useful for printing, to see which frames return "incomplete"
|
||||||
#undef NOISY_SPACEMANAGER // enables debug output for space manager use, useful for analysing reflow of floaters and positioned elements
|
#undef NOISY_SPACEMANAGER // enables debug output for space manager use, useful for analysing reflow of floaters and positioned elements
|
||||||
#undef NOISY_BLOCK_INVALIDATE // enables debug output for all calls to invalidate
|
#undef NOISY_BLOCK_INVALIDATE // enables debug output for all calls to invalidate
|
||||||
|
#undef REALLY_NOISY_REFLOW // some extra debug info
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -781,7 +782,8 @@ nsBlockReflowState::ComputeBlockAvailSpace(nsIFrame* aFrame,
|
||||||
|
|
||||||
const nsMargin& borderPadding = BorderPadding();
|
const nsMargin& borderPadding = BorderPadding();
|
||||||
|
|
||||||
if (NS_FRAME_SPLITTABLE_NON_RECTANGULAR == aSplitType) {
|
if (NS_FRAME_SPLITTABLE_NON_RECTANGULAR == aSplitType)
|
||||||
|
{
|
||||||
if (mBand.GetFloaterCount()) {
|
if (mBand.GetFloaterCount()) {
|
||||||
// Use the float-edge property to determine how the child block
|
// Use the float-edge property to determine how the child block
|
||||||
// will interact with the floater.
|
// will interact with the floater.
|
||||||
|
@ -2006,15 +2008,6 @@ HaveAutoWidth(const nsHTMLReflowState& aReflowState)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static PRBool
|
|
||||||
IsPercentageUnitSides(const nsStyleSides* aSides)
|
|
||||||
{
|
|
||||||
return eStyleUnit_Percent == aSides->GetLeftUnit()
|
|
||||||
|| eStyleUnit_Percent == aSides->GetRightUnit()
|
|
||||||
|| eStyleUnit_Percent == aSides->GetTopUnit()
|
|
||||||
|| eStyleUnit_Percent == aSides->GetBottomUnit();
|
|
||||||
}
|
|
||||||
|
|
||||||
static PRBool
|
static PRBool
|
||||||
IsPercentageAwareChild(const nsIFrame* aFrame)
|
IsPercentageAwareChild(const nsIFrame* aFrame)
|
||||||
{
|
{
|
||||||
|
@ -2024,9 +2017,9 @@ IsPercentageAwareChild(const nsIFrame* aFrame)
|
||||||
return PR_TRUE; // just to be on the safe side
|
return PR_TRUE; // just to be on the safe side
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsPercentageUnitSides(&space->mMargin)
|
if (nsLineLayout::IsPercentageUnitSides(&space->mMargin)
|
||||||
|| IsPercentageUnitSides(&space->mPadding)
|
|| nsLineLayout::IsPercentageUnitSides(&space->mPadding)
|
||||||
|| IsPercentageUnitSides(&space->mBorderRadius)) {
|
|| nsLineLayout::IsPercentageUnitSides(&space->mBorderRadius)) {
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2042,7 +2035,7 @@ IsPercentageAwareChild(const nsIFrame* aFrame)
|
||||||
|| eStyleUnit_Percent == pos->mHeight.GetUnit()
|
|| eStyleUnit_Percent == pos->mHeight.GetUnit()
|
||||||
|| eStyleUnit_Percent == pos->mMinHeight.GetUnit()
|
|| eStyleUnit_Percent == pos->mMinHeight.GetUnit()
|
||||||
|| eStyleUnit_Percent == pos->mMaxHeight.GetUnit()
|
|| eStyleUnit_Percent == pos->mMaxHeight.GetUnit()
|
||||||
|| IsPercentageUnitSides(&pos->mOffset)) { // XXX need more here!!!
|
|| nsLineLayout::IsPercentageUnitSides(&pos->mOffset)) { // XXX need more here!!!
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2600,6 +2593,7 @@ nsBlockFrame::PrepareResizeReflow(nsBlockReflowState& aState)
|
||||||
// newlines. Therefore, we don't need to reflow the line.
|
// newlines. Therefore, we don't need to reflow the line.
|
||||||
}
|
}
|
||||||
else if ((line->mNext && !line->HasBreak()) ||
|
else if ((line->mNext && !line->HasBreak()) ||
|
||||||
|
line->ResizeReflowOptimizationDisabled() ||
|
||||||
line->HasFloaters() || line->IsImpactedByFloater() ||
|
line->HasFloaters() || line->IsImpactedByFloater() ||
|
||||||
line->HasPercentageChild() ||
|
line->HasPercentageChild() ||
|
||||||
(line->mBounds.XMost() > newAvailWidth)) {
|
(line->mBounds.XMost() > newAvailWidth)) {
|
||||||
|
|
|
@ -158,6 +158,7 @@ InitDebugFlags()
|
||||||
#undef REFLOW_STATUS_COVERAGE // I think this is most useful for printing, to see which frames return "incomplete"
|
#undef REFLOW_STATUS_COVERAGE // I think this is most useful for printing, to see which frames return "incomplete"
|
||||||
#undef NOISY_SPACEMANAGER // enables debug output for space manager use, useful for analysing reflow of floaters and positioned elements
|
#undef NOISY_SPACEMANAGER // enables debug output for space manager use, useful for analysing reflow of floaters and positioned elements
|
||||||
#undef NOISY_BLOCK_INVALIDATE // enables debug output for all calls to invalidate
|
#undef NOISY_BLOCK_INVALIDATE // enables debug output for all calls to invalidate
|
||||||
|
#undef REALLY_NOISY_REFLOW // some extra debug info
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -781,7 +782,8 @@ nsBlockReflowState::ComputeBlockAvailSpace(nsIFrame* aFrame,
|
||||||
|
|
||||||
const nsMargin& borderPadding = BorderPadding();
|
const nsMargin& borderPadding = BorderPadding();
|
||||||
|
|
||||||
if (NS_FRAME_SPLITTABLE_NON_RECTANGULAR == aSplitType) {
|
if (NS_FRAME_SPLITTABLE_NON_RECTANGULAR == aSplitType)
|
||||||
|
{
|
||||||
if (mBand.GetFloaterCount()) {
|
if (mBand.GetFloaterCount()) {
|
||||||
// Use the float-edge property to determine how the child block
|
// Use the float-edge property to determine how the child block
|
||||||
// will interact with the floater.
|
// will interact with the floater.
|
||||||
|
@ -2006,15 +2008,6 @@ HaveAutoWidth(const nsHTMLReflowState& aReflowState)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static PRBool
|
|
||||||
IsPercentageUnitSides(const nsStyleSides* aSides)
|
|
||||||
{
|
|
||||||
return eStyleUnit_Percent == aSides->GetLeftUnit()
|
|
||||||
|| eStyleUnit_Percent == aSides->GetRightUnit()
|
|
||||||
|| eStyleUnit_Percent == aSides->GetTopUnit()
|
|
||||||
|| eStyleUnit_Percent == aSides->GetBottomUnit();
|
|
||||||
}
|
|
||||||
|
|
||||||
static PRBool
|
static PRBool
|
||||||
IsPercentageAwareChild(const nsIFrame* aFrame)
|
IsPercentageAwareChild(const nsIFrame* aFrame)
|
||||||
{
|
{
|
||||||
|
@ -2024,9 +2017,9 @@ IsPercentageAwareChild(const nsIFrame* aFrame)
|
||||||
return PR_TRUE; // just to be on the safe side
|
return PR_TRUE; // just to be on the safe side
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsPercentageUnitSides(&space->mMargin)
|
if (nsLineLayout::IsPercentageUnitSides(&space->mMargin)
|
||||||
|| IsPercentageUnitSides(&space->mPadding)
|
|| nsLineLayout::IsPercentageUnitSides(&space->mPadding)
|
||||||
|| IsPercentageUnitSides(&space->mBorderRadius)) {
|
|| nsLineLayout::IsPercentageUnitSides(&space->mBorderRadius)) {
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2042,7 +2035,7 @@ IsPercentageAwareChild(const nsIFrame* aFrame)
|
||||||
|| eStyleUnit_Percent == pos->mHeight.GetUnit()
|
|| eStyleUnit_Percent == pos->mHeight.GetUnit()
|
||||||
|| eStyleUnit_Percent == pos->mMinHeight.GetUnit()
|
|| eStyleUnit_Percent == pos->mMinHeight.GetUnit()
|
||||||
|| eStyleUnit_Percent == pos->mMaxHeight.GetUnit()
|
|| eStyleUnit_Percent == pos->mMaxHeight.GetUnit()
|
||||||
|| IsPercentageUnitSides(&pos->mOffset)) { // XXX need more here!!!
|
|| nsLineLayout::IsPercentageUnitSides(&pos->mOffset)) { // XXX need more here!!!
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2600,6 +2593,7 @@ nsBlockFrame::PrepareResizeReflow(nsBlockReflowState& aState)
|
||||||
// newlines. Therefore, we don't need to reflow the line.
|
// newlines. Therefore, we don't need to reflow the line.
|
||||||
}
|
}
|
||||||
else if ((line->mNext && !line->HasBreak()) ||
|
else if ((line->mNext && !line->HasBreak()) ||
|
||||||
|
line->ResizeReflowOptimizationDisabled() ||
|
||||||
line->HasFloaters() || line->IsImpactedByFloater() ||
|
line->HasFloaters() || line->IsImpactedByFloater() ||
|
||||||
line->HasPercentageChild() ||
|
line->HasPercentageChild() ||
|
||||||
(line->mBounds.XMost() > newAvailWidth)) {
|
(line->mBounds.XMost() > newAvailWidth)) {
|
||||||
|
|
|
@ -549,6 +549,41 @@ nsInlineFrame::ReflowFrames(nsIPresContext* aPresContext,
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void SetContainsPercentAwareChild(nsIFrame *aFrame)
|
||||||
|
{
|
||||||
|
nsFrameState myFrameState;
|
||||||
|
aFrame->GetFrameState(&myFrameState);
|
||||||
|
aFrame->SetFrameState(myFrameState | NS_INLINE_FRAME_CONTAINS_PERCENT_AWARE_CHILD);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void MarkPercentAwareFrame(nsIPresContext *aPresContext,
|
||||||
|
nsInlineFrame *aInline,
|
||||||
|
nsIFrame *aFrame)
|
||||||
|
{
|
||||||
|
nsFrameState childFrameState;
|
||||||
|
aFrame->GetFrameState(&childFrameState);
|
||||||
|
if (childFrameState & NS_FRAME_REPLACED_ELEMENT)
|
||||||
|
{ // aFrame is a replaced element, check it's style
|
||||||
|
if (nsLineLayout::IsPercentageAwareReplacedElement(aPresContext, aFrame)) {
|
||||||
|
SetContainsPercentAwareChild(aInline);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nsIFrame *child;
|
||||||
|
aFrame->FirstChild(aPresContext, nsnull, &child);
|
||||||
|
if (child)
|
||||||
|
{ // aFrame is an inline container frame, check my frame state
|
||||||
|
if (childFrameState & NS_INLINE_FRAME_CONTAINS_PERCENT_AWARE_CHILD) {
|
||||||
|
SetContainsPercentAwareChild(aInline); // if a child container is effected, so am I
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// else frame is a leaf that we don't care about
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsInlineFrame::ReflowInlineFrame(nsIPresContext* aPresContext,
|
nsInlineFrame::ReflowInlineFrame(nsIPresContext* aPresContext,
|
||||||
const nsHTMLReflowState& aReflowState,
|
const nsHTMLReflowState& aReflowState,
|
||||||
|
@ -561,6 +596,15 @@ nsInlineFrame::ReflowInlineFrame(nsIPresContext* aPresContext,
|
||||||
PRBool pushedFrame;
|
PRBool pushedFrame;
|
||||||
nsresult rv = lineLayout->ReflowFrame(aFrame, &irs.mNextRCFrame, aStatus,
|
nsresult rv = lineLayout->ReflowFrame(aFrame, &irs.mNextRCFrame, aStatus,
|
||||||
nsnull, pushedFrame);
|
nsnull, pushedFrame);
|
||||||
|
/* This next block is for bug 28811
|
||||||
|
Test the child frame for %-awareness,
|
||||||
|
and mark this frame with a bit if it is %-aware.
|
||||||
|
Don't bother if this frame is already marked
|
||||||
|
*/
|
||||||
|
if (!(mState & NS_INLINE_FRAME_CONTAINS_PERCENT_AWARE_CHILD)) {
|
||||||
|
MarkPercentAwareFrame(aPresContext, this, aFrame);
|
||||||
|
}
|
||||||
|
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,8 @@ class nsAnonymousBlockFrame;
|
||||||
|
|
||||||
#define nsInlineFrameSuper nsHTMLContainerFrame
|
#define nsInlineFrameSuper nsHTMLContainerFrame
|
||||||
|
|
||||||
|
#define NS_INLINE_FRAME_CONTAINS_PERCENT_AWARE_CHILD 0X00010000
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inline frame class.
|
* Inline frame class.
|
||||||
*
|
*
|
||||||
|
@ -95,7 +97,7 @@ protected:
|
||||||
nsIFrame* mNextRCFrame;
|
nsIFrame* mNextRCFrame;
|
||||||
nsIFrame* mPrevFrame;
|
nsIFrame* mPrevFrame;
|
||||||
nsInlineFrame* mNextInFlow;
|
nsInlineFrame* mNextInFlow;
|
||||||
PRBool mSetParentPointer; // when reflowing child frame first set its
|
PRPackedBool mSetParentPointer; // when reflowing child frame first set its
|
||||||
// parent frame pointer
|
// parent frame pointer
|
||||||
|
|
||||||
InlineReflowState() {
|
InlineReflowState() {
|
||||||
|
@ -129,6 +131,7 @@ protected:
|
||||||
virtual void PushFrames(nsIPresContext* aPresContext,
|
virtual void PushFrames(nsIPresContext* aPresContext,
|
||||||
nsIFrame* aFromChild,
|
nsIFrame* aFromChild,
|
||||||
nsIFrame* aPrevSibling);
|
nsIFrame* aPrevSibling);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
|
@ -136,7 +136,7 @@ protected:
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
#define LINE_MAX_BREAK_TYPE ((1 << 4) - 1)
|
#define LINE_MAX_BREAK_TYPE ((1 << 4) - 1)
|
||||||
#define LINE_MAX_CHILD_COUNT ((1 << 21) - 1)
|
#define LINE_MAX_CHILD_COUNT ((1 << 20) - 1)
|
||||||
|
|
||||||
#if NS_STYLE_CLEAR_LAST_VALUE > 15
|
#if NS_STYLE_CLEAR_LAST_VALUE > 15
|
||||||
need to rearrange the mBits bitfield;
|
need to rearrange the mBits bitfield;
|
||||||
|
@ -232,6 +232,17 @@ public:
|
||||||
return mFlags.mForceInvalidate;
|
return mFlags.mForceInvalidate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mResizeReflowOptimizationDisabled bit
|
||||||
|
void DisableResizeReflowOptimization() {
|
||||||
|
mFlags.mResizeReflowOptimizationDisabled = PR_TRUE;
|
||||||
|
}
|
||||||
|
void EnableResizeReflowOptimization() {
|
||||||
|
mFlags.mResizeReflowOptimizationDisabled = PR_FALSE;
|
||||||
|
}
|
||||||
|
PRBool ResizeReflowOptimizationDisabled() const {
|
||||||
|
return mFlags.mResizeReflowOptimizationDisabled;
|
||||||
|
}
|
||||||
|
|
||||||
// mChildCount value
|
// mChildCount value
|
||||||
PRInt32 GetChildCount() const {
|
PRInt32 GetChildCount() const {
|
||||||
return (PRInt32) mFlags.mChildCount;
|
return (PRInt32) mFlags.mChildCount;
|
||||||
|
@ -337,11 +348,11 @@ public:
|
||||||
PRUint32 mTrimmed : 1;
|
PRUint32 mTrimmed : 1;
|
||||||
PRUint32 mHasPercentageChild : 1;
|
PRUint32 mHasPercentageChild : 1;
|
||||||
PRUint32 mLineWrapped: 1;
|
PRUint32 mLineWrapped: 1;
|
||||||
PRUint32 mForceInvalidate: 1;
|
PRUint32 mForceInvalidate: 1; // default 0 = means this line handles it's own invalidation. 1 = always invalidate this entire line
|
||||||
|
PRUint32 mResizeReflowOptimizationDisabled: 1; // default 0 = means that the opt potentially applies to this line. 1 = never skip reflowing this line for a resize reflow
|
||||||
PRUint32 mBreakType : 4;
|
PRUint32 mBreakType : 4;
|
||||||
|
|
||||||
PRUint32 mChildCount : 21;
|
PRUint32 mChildCount : 20;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ExtraData {
|
struct ExtraData {
|
||||||
|
@ -442,7 +453,7 @@ protected:
|
||||||
nsLineBox** mLines;
|
nsLineBox** mLines;
|
||||||
PRInt32 mIndex;
|
PRInt32 mIndex;
|
||||||
PRInt32 mNumLines;
|
PRInt32 mNumLines;
|
||||||
PRBool mRightToLeft;
|
PRPackedBool mRightToLeft;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* nsLineBox_h___ */
|
#endif /* nsLineBox_h___ */
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsLineLayout.h"
|
#include "nsLineLayout.h"
|
||||||
#include "nsBlockFrame.h"
|
#include "nsBlockFrame.h"
|
||||||
|
#include "nsInlineFrame.h"
|
||||||
#include "nsStyleConsts.h"
|
#include "nsStyleConsts.h"
|
||||||
#include "nsHTMLContainerFrame.h"
|
#include "nsHTMLContainerFrame.h"
|
||||||
#include "nsHTMLIIDs.h"
|
#include "nsHTMLIIDs.h"
|
||||||
|
@ -1548,6 +1549,86 @@ nsLineLayout::DumpPerSpanData(PerSpanData* psd, PRInt32 aIndent)
|
||||||
#define VALIGN_TOP 1
|
#define VALIGN_TOP 1
|
||||||
#define VALIGN_BOTTOM 2
|
#define VALIGN_BOTTOM 2
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
nsLineLayout::IsPercentageUnitSides(const nsStyleSides* aSides)
|
||||||
|
{
|
||||||
|
return eStyleUnit_Percent == aSides->GetLeftUnit()
|
||||||
|
|| eStyleUnit_Percent == aSides->GetRightUnit()
|
||||||
|
|| eStyleUnit_Percent == aSides->GetTopUnit()
|
||||||
|
|| eStyleUnit_Percent == aSides->GetBottomUnit();
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
nsLineLayout::IsPercentageAwareReplacedElement(nsIPresContext *aPresContext,
|
||||||
|
nsIFrame* aFrame)
|
||||||
|
{
|
||||||
|
nsFrameState frameState;
|
||||||
|
aFrame->GetFrameState(&frameState);
|
||||||
|
if (frameState & NS_FRAME_REPLACED_ELEMENT)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIAtom> frameType;
|
||||||
|
aFrame->GetFrameType(getter_AddRefs(frameType));
|
||||||
|
if (nsLayoutAtoms::brFrame != frameType &&
|
||||||
|
nsLayoutAtoms::textFrame != frameType)
|
||||||
|
{
|
||||||
|
const nsStyleSpacing* space;
|
||||||
|
nsresult rv = aFrame->GetStyleData(eStyleStruct_Spacing,(const nsStyleStruct*&) space);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
return PR_TRUE; // just to be on the safe side
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsPercentageUnitSides(&space->mMargin)
|
||||||
|
|| IsPercentageUnitSides(&space->mPadding)
|
||||||
|
|| IsPercentageUnitSides(&space->mBorderRadius)) {
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nsStylePosition* pos;
|
||||||
|
rv = aFrame->GetStyleData(eStyleStruct_Position,(const nsStyleStruct*&) pos);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
return PR_TRUE; // just to be on the safe side
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eStyleUnit_Percent == pos->mWidth.GetUnit()
|
||||||
|
|| eStyleUnit_Percent == pos->mMaxWidth.GetUnit()
|
||||||
|
|| eStyleUnit_Percent == pos->mMinWidth.GetUnit()
|
||||||
|
|| eStyleUnit_Percent == pos->mHeight.GetUnit()
|
||||||
|
|| eStyleUnit_Percent == pos->mMinHeight.GetUnit()
|
||||||
|
|| eStyleUnit_Percent == pos->mMaxHeight.GetUnit()
|
||||||
|
|| IsPercentageUnitSides(&pos->mOffset)) { // XXX need more here!!!
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool IsPercentageAwareFrame(nsIPresContext *aPresContext, nsIFrame *aFrame)
|
||||||
|
{
|
||||||
|
nsFrameState childFrameState;
|
||||||
|
aFrame->GetFrameState(&childFrameState);
|
||||||
|
if (childFrameState & NS_FRAME_REPLACED_ELEMENT) {
|
||||||
|
if (nsLineLayout::IsPercentageAwareReplacedElement(aPresContext, aFrame)) {
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nsIFrame *child;
|
||||||
|
aFrame->FirstChild(aPresContext, nsnull, &child);
|
||||||
|
if (child)
|
||||||
|
{ // aFrame is an inline container frame, check my frame state
|
||||||
|
if (childFrameState & NS_INLINE_FRAME_CONTAINS_PERCENT_AWARE_CHILD) {
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// else it's a frame we just don't care about
|
||||||
|
}
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
nsLineLayout::VerticalAlignFrames(nsLineBox* aLineBox,
|
nsLineLayout::VerticalAlignFrames(nsLineBox* aLineBox,
|
||||||
nsSize& aMaxElementSizeResult,
|
nsSize& aMaxElementSizeResult,
|
||||||
|
@ -1684,6 +1765,14 @@ nsLineLayout::VerticalAlignFrames(nsLineBox* aLineBox,
|
||||||
nscoord distanceFromTop = pfd->mBounds.y - mTopEdge;
|
nscoord distanceFromTop = pfd->mBounds.y - mTopEdge;
|
||||||
PlaceTopBottomFrames(span, distanceFromTop, lineHeight);
|
PlaceTopBottomFrames(span, distanceFromTop, lineHeight);
|
||||||
}
|
}
|
||||||
|
// check to see if the frame is an inline replace element
|
||||||
|
// and if it is percent-aware. If so, mark the line.
|
||||||
|
if ((PR_FALSE==aLineBox->ResizeReflowOptimizationDisabled()) &&
|
||||||
|
pfd->mFrameType & NS_CSS_FRAME_TYPE_INLINE)
|
||||||
|
{
|
||||||
|
if (IsPercentageAwareFrame(mPresContext, pfd->mFrame))
|
||||||
|
aLineBox->DisableResizeReflowOptimization();
|
||||||
|
}
|
||||||
pfd = pfd->mNext;
|
pfd = pfd->mNext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -251,6 +251,12 @@ public:
|
||||||
|
|
||||||
static PRBool TreatFrameAsBlock(nsIFrame* aFrame);
|
static PRBool TreatFrameAsBlock(nsIFrame* aFrame);
|
||||||
|
|
||||||
|
static PRBool IsPercentageUnitSides(const nsStyleSides* aSides);
|
||||||
|
|
||||||
|
static PRBool IsPercentageAwareReplacedElement(nsIPresContext *aPresContext,
|
||||||
|
nsIFrame *aFrame);
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------
|
//----------------------------------------
|
||||||
|
|
||||||
nsIPresContext* mPresContext;
|
nsIPresContext* mPresContext;
|
||||||
|
|
|
@ -158,6 +158,7 @@ InitDebugFlags()
|
||||||
#undef REFLOW_STATUS_COVERAGE // I think this is most useful for printing, to see which frames return "incomplete"
|
#undef REFLOW_STATUS_COVERAGE // I think this is most useful for printing, to see which frames return "incomplete"
|
||||||
#undef NOISY_SPACEMANAGER // enables debug output for space manager use, useful for analysing reflow of floaters and positioned elements
|
#undef NOISY_SPACEMANAGER // enables debug output for space manager use, useful for analysing reflow of floaters and positioned elements
|
||||||
#undef NOISY_BLOCK_INVALIDATE // enables debug output for all calls to invalidate
|
#undef NOISY_BLOCK_INVALIDATE // enables debug output for all calls to invalidate
|
||||||
|
#undef REALLY_NOISY_REFLOW // some extra debug info
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -781,7 +782,8 @@ nsBlockReflowState::ComputeBlockAvailSpace(nsIFrame* aFrame,
|
||||||
|
|
||||||
const nsMargin& borderPadding = BorderPadding();
|
const nsMargin& borderPadding = BorderPadding();
|
||||||
|
|
||||||
if (NS_FRAME_SPLITTABLE_NON_RECTANGULAR == aSplitType) {
|
if (NS_FRAME_SPLITTABLE_NON_RECTANGULAR == aSplitType)
|
||||||
|
{
|
||||||
if (mBand.GetFloaterCount()) {
|
if (mBand.GetFloaterCount()) {
|
||||||
// Use the float-edge property to determine how the child block
|
// Use the float-edge property to determine how the child block
|
||||||
// will interact with the floater.
|
// will interact with the floater.
|
||||||
|
@ -2006,15 +2008,6 @@ HaveAutoWidth(const nsHTMLReflowState& aReflowState)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static PRBool
|
|
||||||
IsPercentageUnitSides(const nsStyleSides* aSides)
|
|
||||||
{
|
|
||||||
return eStyleUnit_Percent == aSides->GetLeftUnit()
|
|
||||||
|| eStyleUnit_Percent == aSides->GetRightUnit()
|
|
||||||
|| eStyleUnit_Percent == aSides->GetTopUnit()
|
|
||||||
|| eStyleUnit_Percent == aSides->GetBottomUnit();
|
|
||||||
}
|
|
||||||
|
|
||||||
static PRBool
|
static PRBool
|
||||||
IsPercentageAwareChild(const nsIFrame* aFrame)
|
IsPercentageAwareChild(const nsIFrame* aFrame)
|
||||||
{
|
{
|
||||||
|
@ -2024,9 +2017,9 @@ IsPercentageAwareChild(const nsIFrame* aFrame)
|
||||||
return PR_TRUE; // just to be on the safe side
|
return PR_TRUE; // just to be on the safe side
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsPercentageUnitSides(&space->mMargin)
|
if (nsLineLayout::IsPercentageUnitSides(&space->mMargin)
|
||||||
|| IsPercentageUnitSides(&space->mPadding)
|
|| nsLineLayout::IsPercentageUnitSides(&space->mPadding)
|
||||||
|| IsPercentageUnitSides(&space->mBorderRadius)) {
|
|| nsLineLayout::IsPercentageUnitSides(&space->mBorderRadius)) {
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2042,7 +2035,7 @@ IsPercentageAwareChild(const nsIFrame* aFrame)
|
||||||
|| eStyleUnit_Percent == pos->mHeight.GetUnit()
|
|| eStyleUnit_Percent == pos->mHeight.GetUnit()
|
||||||
|| eStyleUnit_Percent == pos->mMinHeight.GetUnit()
|
|| eStyleUnit_Percent == pos->mMinHeight.GetUnit()
|
||||||
|| eStyleUnit_Percent == pos->mMaxHeight.GetUnit()
|
|| eStyleUnit_Percent == pos->mMaxHeight.GetUnit()
|
||||||
|| IsPercentageUnitSides(&pos->mOffset)) { // XXX need more here!!!
|
|| nsLineLayout::IsPercentageUnitSides(&pos->mOffset)) { // XXX need more here!!!
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2600,6 +2593,7 @@ nsBlockFrame::PrepareResizeReflow(nsBlockReflowState& aState)
|
||||||
// newlines. Therefore, we don't need to reflow the line.
|
// newlines. Therefore, we don't need to reflow the line.
|
||||||
}
|
}
|
||||||
else if ((line->mNext && !line->HasBreak()) ||
|
else if ((line->mNext && !line->HasBreak()) ||
|
||||||
|
line->ResizeReflowOptimizationDisabled() ||
|
||||||
line->HasFloaters() || line->IsImpactedByFloater() ||
|
line->HasFloaters() || line->IsImpactedByFloater() ||
|
||||||
line->HasPercentageChild() ||
|
line->HasPercentageChild() ||
|
||||||
(line->mBounds.XMost() > newAvailWidth)) {
|
(line->mBounds.XMost() > newAvailWidth)) {
|
||||||
|
|
|
@ -158,6 +158,7 @@ InitDebugFlags()
|
||||||
#undef REFLOW_STATUS_COVERAGE // I think this is most useful for printing, to see which frames return "incomplete"
|
#undef REFLOW_STATUS_COVERAGE // I think this is most useful for printing, to see which frames return "incomplete"
|
||||||
#undef NOISY_SPACEMANAGER // enables debug output for space manager use, useful for analysing reflow of floaters and positioned elements
|
#undef NOISY_SPACEMANAGER // enables debug output for space manager use, useful for analysing reflow of floaters and positioned elements
|
||||||
#undef NOISY_BLOCK_INVALIDATE // enables debug output for all calls to invalidate
|
#undef NOISY_BLOCK_INVALIDATE // enables debug output for all calls to invalidate
|
||||||
|
#undef REALLY_NOISY_REFLOW // some extra debug info
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -781,7 +782,8 @@ nsBlockReflowState::ComputeBlockAvailSpace(nsIFrame* aFrame,
|
||||||
|
|
||||||
const nsMargin& borderPadding = BorderPadding();
|
const nsMargin& borderPadding = BorderPadding();
|
||||||
|
|
||||||
if (NS_FRAME_SPLITTABLE_NON_RECTANGULAR == aSplitType) {
|
if (NS_FRAME_SPLITTABLE_NON_RECTANGULAR == aSplitType)
|
||||||
|
{
|
||||||
if (mBand.GetFloaterCount()) {
|
if (mBand.GetFloaterCount()) {
|
||||||
// Use the float-edge property to determine how the child block
|
// Use the float-edge property to determine how the child block
|
||||||
// will interact with the floater.
|
// will interact with the floater.
|
||||||
|
@ -2006,15 +2008,6 @@ HaveAutoWidth(const nsHTMLReflowState& aReflowState)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static PRBool
|
|
||||||
IsPercentageUnitSides(const nsStyleSides* aSides)
|
|
||||||
{
|
|
||||||
return eStyleUnit_Percent == aSides->GetLeftUnit()
|
|
||||||
|| eStyleUnit_Percent == aSides->GetRightUnit()
|
|
||||||
|| eStyleUnit_Percent == aSides->GetTopUnit()
|
|
||||||
|| eStyleUnit_Percent == aSides->GetBottomUnit();
|
|
||||||
}
|
|
||||||
|
|
||||||
static PRBool
|
static PRBool
|
||||||
IsPercentageAwareChild(const nsIFrame* aFrame)
|
IsPercentageAwareChild(const nsIFrame* aFrame)
|
||||||
{
|
{
|
||||||
|
@ -2024,9 +2017,9 @@ IsPercentageAwareChild(const nsIFrame* aFrame)
|
||||||
return PR_TRUE; // just to be on the safe side
|
return PR_TRUE; // just to be on the safe side
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsPercentageUnitSides(&space->mMargin)
|
if (nsLineLayout::IsPercentageUnitSides(&space->mMargin)
|
||||||
|| IsPercentageUnitSides(&space->mPadding)
|
|| nsLineLayout::IsPercentageUnitSides(&space->mPadding)
|
||||||
|| IsPercentageUnitSides(&space->mBorderRadius)) {
|
|| nsLineLayout::IsPercentageUnitSides(&space->mBorderRadius)) {
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2042,7 +2035,7 @@ IsPercentageAwareChild(const nsIFrame* aFrame)
|
||||||
|| eStyleUnit_Percent == pos->mHeight.GetUnit()
|
|| eStyleUnit_Percent == pos->mHeight.GetUnit()
|
||||||
|| eStyleUnit_Percent == pos->mMinHeight.GetUnit()
|
|| eStyleUnit_Percent == pos->mMinHeight.GetUnit()
|
||||||
|| eStyleUnit_Percent == pos->mMaxHeight.GetUnit()
|
|| eStyleUnit_Percent == pos->mMaxHeight.GetUnit()
|
||||||
|| IsPercentageUnitSides(&pos->mOffset)) { // XXX need more here!!!
|
|| nsLineLayout::IsPercentageUnitSides(&pos->mOffset)) { // XXX need more here!!!
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2600,6 +2593,7 @@ nsBlockFrame::PrepareResizeReflow(nsBlockReflowState& aState)
|
||||||
// newlines. Therefore, we don't need to reflow the line.
|
// newlines. Therefore, we don't need to reflow the line.
|
||||||
}
|
}
|
||||||
else if ((line->mNext && !line->HasBreak()) ||
|
else if ((line->mNext && !line->HasBreak()) ||
|
||||||
|
line->ResizeReflowOptimizationDisabled() ||
|
||||||
line->HasFloaters() || line->IsImpactedByFloater() ||
|
line->HasFloaters() || line->IsImpactedByFloater() ||
|
||||||
line->HasPercentageChild() ||
|
line->HasPercentageChild() ||
|
||||||
(line->mBounds.XMost() > newAvailWidth)) {
|
(line->mBounds.XMost() > newAvailWidth)) {
|
||||||
|
|
|
@ -158,6 +158,7 @@ InitDebugFlags()
|
||||||
#undef REFLOW_STATUS_COVERAGE // I think this is most useful for printing, to see which frames return "incomplete"
|
#undef REFLOW_STATUS_COVERAGE // I think this is most useful for printing, to see which frames return "incomplete"
|
||||||
#undef NOISY_SPACEMANAGER // enables debug output for space manager use, useful for analysing reflow of floaters and positioned elements
|
#undef NOISY_SPACEMANAGER // enables debug output for space manager use, useful for analysing reflow of floaters and positioned elements
|
||||||
#undef NOISY_BLOCK_INVALIDATE // enables debug output for all calls to invalidate
|
#undef NOISY_BLOCK_INVALIDATE // enables debug output for all calls to invalidate
|
||||||
|
#undef REALLY_NOISY_REFLOW // some extra debug info
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -781,7 +782,8 @@ nsBlockReflowState::ComputeBlockAvailSpace(nsIFrame* aFrame,
|
||||||
|
|
||||||
const nsMargin& borderPadding = BorderPadding();
|
const nsMargin& borderPadding = BorderPadding();
|
||||||
|
|
||||||
if (NS_FRAME_SPLITTABLE_NON_RECTANGULAR == aSplitType) {
|
if (NS_FRAME_SPLITTABLE_NON_RECTANGULAR == aSplitType)
|
||||||
|
{
|
||||||
if (mBand.GetFloaterCount()) {
|
if (mBand.GetFloaterCount()) {
|
||||||
// Use the float-edge property to determine how the child block
|
// Use the float-edge property to determine how the child block
|
||||||
// will interact with the floater.
|
// will interact with the floater.
|
||||||
|
@ -2006,15 +2008,6 @@ HaveAutoWidth(const nsHTMLReflowState& aReflowState)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static PRBool
|
|
||||||
IsPercentageUnitSides(const nsStyleSides* aSides)
|
|
||||||
{
|
|
||||||
return eStyleUnit_Percent == aSides->GetLeftUnit()
|
|
||||||
|| eStyleUnit_Percent == aSides->GetRightUnit()
|
|
||||||
|| eStyleUnit_Percent == aSides->GetTopUnit()
|
|
||||||
|| eStyleUnit_Percent == aSides->GetBottomUnit();
|
|
||||||
}
|
|
||||||
|
|
||||||
static PRBool
|
static PRBool
|
||||||
IsPercentageAwareChild(const nsIFrame* aFrame)
|
IsPercentageAwareChild(const nsIFrame* aFrame)
|
||||||
{
|
{
|
||||||
|
@ -2024,9 +2017,9 @@ IsPercentageAwareChild(const nsIFrame* aFrame)
|
||||||
return PR_TRUE; // just to be on the safe side
|
return PR_TRUE; // just to be on the safe side
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsPercentageUnitSides(&space->mMargin)
|
if (nsLineLayout::IsPercentageUnitSides(&space->mMargin)
|
||||||
|| IsPercentageUnitSides(&space->mPadding)
|
|| nsLineLayout::IsPercentageUnitSides(&space->mPadding)
|
||||||
|| IsPercentageUnitSides(&space->mBorderRadius)) {
|
|| nsLineLayout::IsPercentageUnitSides(&space->mBorderRadius)) {
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2042,7 +2035,7 @@ IsPercentageAwareChild(const nsIFrame* aFrame)
|
||||||
|| eStyleUnit_Percent == pos->mHeight.GetUnit()
|
|| eStyleUnit_Percent == pos->mHeight.GetUnit()
|
||||||
|| eStyleUnit_Percent == pos->mMinHeight.GetUnit()
|
|| eStyleUnit_Percent == pos->mMinHeight.GetUnit()
|
||||||
|| eStyleUnit_Percent == pos->mMaxHeight.GetUnit()
|
|| eStyleUnit_Percent == pos->mMaxHeight.GetUnit()
|
||||||
|| IsPercentageUnitSides(&pos->mOffset)) { // XXX need more here!!!
|
|| nsLineLayout::IsPercentageUnitSides(&pos->mOffset)) { // XXX need more here!!!
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2600,6 +2593,7 @@ nsBlockFrame::PrepareResizeReflow(nsBlockReflowState& aState)
|
||||||
// newlines. Therefore, we don't need to reflow the line.
|
// newlines. Therefore, we don't need to reflow the line.
|
||||||
}
|
}
|
||||||
else if ((line->mNext && !line->HasBreak()) ||
|
else if ((line->mNext && !line->HasBreak()) ||
|
||||||
|
line->ResizeReflowOptimizationDisabled() ||
|
||||||
line->HasFloaters() || line->IsImpactedByFloater() ||
|
line->HasFloaters() || line->IsImpactedByFloater() ||
|
||||||
line->HasPercentageChild() ||
|
line->HasPercentageChild() ||
|
||||||
(line->mBounds.XMost() > newAvailWidth)) {
|
(line->mBounds.XMost() > newAvailWidth)) {
|
||||||
|
|
|
@ -549,6 +549,41 @@ nsInlineFrame::ReflowFrames(nsIPresContext* aPresContext,
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void SetContainsPercentAwareChild(nsIFrame *aFrame)
|
||||||
|
{
|
||||||
|
nsFrameState myFrameState;
|
||||||
|
aFrame->GetFrameState(&myFrameState);
|
||||||
|
aFrame->SetFrameState(myFrameState | NS_INLINE_FRAME_CONTAINS_PERCENT_AWARE_CHILD);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void MarkPercentAwareFrame(nsIPresContext *aPresContext,
|
||||||
|
nsInlineFrame *aInline,
|
||||||
|
nsIFrame *aFrame)
|
||||||
|
{
|
||||||
|
nsFrameState childFrameState;
|
||||||
|
aFrame->GetFrameState(&childFrameState);
|
||||||
|
if (childFrameState & NS_FRAME_REPLACED_ELEMENT)
|
||||||
|
{ // aFrame is a replaced element, check it's style
|
||||||
|
if (nsLineLayout::IsPercentageAwareReplacedElement(aPresContext, aFrame)) {
|
||||||
|
SetContainsPercentAwareChild(aInline);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nsIFrame *child;
|
||||||
|
aFrame->FirstChild(aPresContext, nsnull, &child);
|
||||||
|
if (child)
|
||||||
|
{ // aFrame is an inline container frame, check my frame state
|
||||||
|
if (childFrameState & NS_INLINE_FRAME_CONTAINS_PERCENT_AWARE_CHILD) {
|
||||||
|
SetContainsPercentAwareChild(aInline); // if a child container is effected, so am I
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// else frame is a leaf that we don't care about
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsInlineFrame::ReflowInlineFrame(nsIPresContext* aPresContext,
|
nsInlineFrame::ReflowInlineFrame(nsIPresContext* aPresContext,
|
||||||
const nsHTMLReflowState& aReflowState,
|
const nsHTMLReflowState& aReflowState,
|
||||||
|
@ -561,6 +596,15 @@ nsInlineFrame::ReflowInlineFrame(nsIPresContext* aPresContext,
|
||||||
PRBool pushedFrame;
|
PRBool pushedFrame;
|
||||||
nsresult rv = lineLayout->ReflowFrame(aFrame, &irs.mNextRCFrame, aStatus,
|
nsresult rv = lineLayout->ReflowFrame(aFrame, &irs.mNextRCFrame, aStatus,
|
||||||
nsnull, pushedFrame);
|
nsnull, pushedFrame);
|
||||||
|
/* This next block is for bug 28811
|
||||||
|
Test the child frame for %-awareness,
|
||||||
|
and mark this frame with a bit if it is %-aware.
|
||||||
|
Don't bother if this frame is already marked
|
||||||
|
*/
|
||||||
|
if (!(mState & NS_INLINE_FRAME_CONTAINS_PERCENT_AWARE_CHILD)) {
|
||||||
|
MarkPercentAwareFrame(aPresContext, this, aFrame);
|
||||||
|
}
|
||||||
|
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,8 @@ class nsAnonymousBlockFrame;
|
||||||
|
|
||||||
#define nsInlineFrameSuper nsHTMLContainerFrame
|
#define nsInlineFrameSuper nsHTMLContainerFrame
|
||||||
|
|
||||||
|
#define NS_INLINE_FRAME_CONTAINS_PERCENT_AWARE_CHILD 0X00010000
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inline frame class.
|
* Inline frame class.
|
||||||
*
|
*
|
||||||
|
@ -95,7 +97,7 @@ protected:
|
||||||
nsIFrame* mNextRCFrame;
|
nsIFrame* mNextRCFrame;
|
||||||
nsIFrame* mPrevFrame;
|
nsIFrame* mPrevFrame;
|
||||||
nsInlineFrame* mNextInFlow;
|
nsInlineFrame* mNextInFlow;
|
||||||
PRBool mSetParentPointer; // when reflowing child frame first set its
|
PRPackedBool mSetParentPointer; // when reflowing child frame first set its
|
||||||
// parent frame pointer
|
// parent frame pointer
|
||||||
|
|
||||||
InlineReflowState() {
|
InlineReflowState() {
|
||||||
|
@ -129,6 +131,7 @@ protected:
|
||||||
virtual void PushFrames(nsIPresContext* aPresContext,
|
virtual void PushFrames(nsIPresContext* aPresContext,
|
||||||
nsIFrame* aFromChild,
|
nsIFrame* aFromChild,
|
||||||
nsIFrame* aPrevSibling);
|
nsIFrame* aPrevSibling);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
|
@ -136,7 +136,7 @@ protected:
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
#define LINE_MAX_BREAK_TYPE ((1 << 4) - 1)
|
#define LINE_MAX_BREAK_TYPE ((1 << 4) - 1)
|
||||||
#define LINE_MAX_CHILD_COUNT ((1 << 21) - 1)
|
#define LINE_MAX_CHILD_COUNT ((1 << 20) - 1)
|
||||||
|
|
||||||
#if NS_STYLE_CLEAR_LAST_VALUE > 15
|
#if NS_STYLE_CLEAR_LAST_VALUE > 15
|
||||||
need to rearrange the mBits bitfield;
|
need to rearrange the mBits bitfield;
|
||||||
|
@ -232,6 +232,17 @@ public:
|
||||||
return mFlags.mForceInvalidate;
|
return mFlags.mForceInvalidate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mResizeReflowOptimizationDisabled bit
|
||||||
|
void DisableResizeReflowOptimization() {
|
||||||
|
mFlags.mResizeReflowOptimizationDisabled = PR_TRUE;
|
||||||
|
}
|
||||||
|
void EnableResizeReflowOptimization() {
|
||||||
|
mFlags.mResizeReflowOptimizationDisabled = PR_FALSE;
|
||||||
|
}
|
||||||
|
PRBool ResizeReflowOptimizationDisabled() const {
|
||||||
|
return mFlags.mResizeReflowOptimizationDisabled;
|
||||||
|
}
|
||||||
|
|
||||||
// mChildCount value
|
// mChildCount value
|
||||||
PRInt32 GetChildCount() const {
|
PRInt32 GetChildCount() const {
|
||||||
return (PRInt32) mFlags.mChildCount;
|
return (PRInt32) mFlags.mChildCount;
|
||||||
|
@ -337,11 +348,11 @@ public:
|
||||||
PRUint32 mTrimmed : 1;
|
PRUint32 mTrimmed : 1;
|
||||||
PRUint32 mHasPercentageChild : 1;
|
PRUint32 mHasPercentageChild : 1;
|
||||||
PRUint32 mLineWrapped: 1;
|
PRUint32 mLineWrapped: 1;
|
||||||
PRUint32 mForceInvalidate: 1;
|
PRUint32 mForceInvalidate: 1; // default 0 = means this line handles it's own invalidation. 1 = always invalidate this entire line
|
||||||
|
PRUint32 mResizeReflowOptimizationDisabled: 1; // default 0 = means that the opt potentially applies to this line. 1 = never skip reflowing this line for a resize reflow
|
||||||
PRUint32 mBreakType : 4;
|
PRUint32 mBreakType : 4;
|
||||||
|
|
||||||
PRUint32 mChildCount : 21;
|
PRUint32 mChildCount : 20;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ExtraData {
|
struct ExtraData {
|
||||||
|
@ -442,7 +453,7 @@ protected:
|
||||||
nsLineBox** mLines;
|
nsLineBox** mLines;
|
||||||
PRInt32 mIndex;
|
PRInt32 mIndex;
|
||||||
PRInt32 mNumLines;
|
PRInt32 mNumLines;
|
||||||
PRBool mRightToLeft;
|
PRPackedBool mRightToLeft;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* nsLineBox_h___ */
|
#endif /* nsLineBox_h___ */
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsLineLayout.h"
|
#include "nsLineLayout.h"
|
||||||
#include "nsBlockFrame.h"
|
#include "nsBlockFrame.h"
|
||||||
|
#include "nsInlineFrame.h"
|
||||||
#include "nsStyleConsts.h"
|
#include "nsStyleConsts.h"
|
||||||
#include "nsHTMLContainerFrame.h"
|
#include "nsHTMLContainerFrame.h"
|
||||||
#include "nsHTMLIIDs.h"
|
#include "nsHTMLIIDs.h"
|
||||||
|
@ -1548,6 +1549,86 @@ nsLineLayout::DumpPerSpanData(PerSpanData* psd, PRInt32 aIndent)
|
||||||
#define VALIGN_TOP 1
|
#define VALIGN_TOP 1
|
||||||
#define VALIGN_BOTTOM 2
|
#define VALIGN_BOTTOM 2
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
nsLineLayout::IsPercentageUnitSides(const nsStyleSides* aSides)
|
||||||
|
{
|
||||||
|
return eStyleUnit_Percent == aSides->GetLeftUnit()
|
||||||
|
|| eStyleUnit_Percent == aSides->GetRightUnit()
|
||||||
|
|| eStyleUnit_Percent == aSides->GetTopUnit()
|
||||||
|
|| eStyleUnit_Percent == aSides->GetBottomUnit();
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
nsLineLayout::IsPercentageAwareReplacedElement(nsIPresContext *aPresContext,
|
||||||
|
nsIFrame* aFrame)
|
||||||
|
{
|
||||||
|
nsFrameState frameState;
|
||||||
|
aFrame->GetFrameState(&frameState);
|
||||||
|
if (frameState & NS_FRAME_REPLACED_ELEMENT)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIAtom> frameType;
|
||||||
|
aFrame->GetFrameType(getter_AddRefs(frameType));
|
||||||
|
if (nsLayoutAtoms::brFrame != frameType &&
|
||||||
|
nsLayoutAtoms::textFrame != frameType)
|
||||||
|
{
|
||||||
|
const nsStyleSpacing* space;
|
||||||
|
nsresult rv = aFrame->GetStyleData(eStyleStruct_Spacing,(const nsStyleStruct*&) space);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
return PR_TRUE; // just to be on the safe side
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsPercentageUnitSides(&space->mMargin)
|
||||||
|
|| IsPercentageUnitSides(&space->mPadding)
|
||||||
|
|| IsPercentageUnitSides(&space->mBorderRadius)) {
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nsStylePosition* pos;
|
||||||
|
rv = aFrame->GetStyleData(eStyleStruct_Position,(const nsStyleStruct*&) pos);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
return PR_TRUE; // just to be on the safe side
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eStyleUnit_Percent == pos->mWidth.GetUnit()
|
||||||
|
|| eStyleUnit_Percent == pos->mMaxWidth.GetUnit()
|
||||||
|
|| eStyleUnit_Percent == pos->mMinWidth.GetUnit()
|
||||||
|
|| eStyleUnit_Percent == pos->mHeight.GetUnit()
|
||||||
|
|| eStyleUnit_Percent == pos->mMinHeight.GetUnit()
|
||||||
|
|| eStyleUnit_Percent == pos->mMaxHeight.GetUnit()
|
||||||
|
|| IsPercentageUnitSides(&pos->mOffset)) { // XXX need more here!!!
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRBool IsPercentageAwareFrame(nsIPresContext *aPresContext, nsIFrame *aFrame)
|
||||||
|
{
|
||||||
|
nsFrameState childFrameState;
|
||||||
|
aFrame->GetFrameState(&childFrameState);
|
||||||
|
if (childFrameState & NS_FRAME_REPLACED_ELEMENT) {
|
||||||
|
if (nsLineLayout::IsPercentageAwareReplacedElement(aPresContext, aFrame)) {
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nsIFrame *child;
|
||||||
|
aFrame->FirstChild(aPresContext, nsnull, &child);
|
||||||
|
if (child)
|
||||||
|
{ // aFrame is an inline container frame, check my frame state
|
||||||
|
if (childFrameState & NS_INLINE_FRAME_CONTAINS_PERCENT_AWARE_CHILD) {
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// else it's a frame we just don't care about
|
||||||
|
}
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
nsLineLayout::VerticalAlignFrames(nsLineBox* aLineBox,
|
nsLineLayout::VerticalAlignFrames(nsLineBox* aLineBox,
|
||||||
nsSize& aMaxElementSizeResult,
|
nsSize& aMaxElementSizeResult,
|
||||||
|
@ -1684,6 +1765,14 @@ nsLineLayout::VerticalAlignFrames(nsLineBox* aLineBox,
|
||||||
nscoord distanceFromTop = pfd->mBounds.y - mTopEdge;
|
nscoord distanceFromTop = pfd->mBounds.y - mTopEdge;
|
||||||
PlaceTopBottomFrames(span, distanceFromTop, lineHeight);
|
PlaceTopBottomFrames(span, distanceFromTop, lineHeight);
|
||||||
}
|
}
|
||||||
|
// check to see if the frame is an inline replace element
|
||||||
|
// and if it is percent-aware. If so, mark the line.
|
||||||
|
if ((PR_FALSE==aLineBox->ResizeReflowOptimizationDisabled()) &&
|
||||||
|
pfd->mFrameType & NS_CSS_FRAME_TYPE_INLINE)
|
||||||
|
{
|
||||||
|
if (IsPercentageAwareFrame(mPresContext, pfd->mFrame))
|
||||||
|
aLineBox->DisableResizeReflowOptimization();
|
||||||
|
}
|
||||||
pfd = pfd->mNext;
|
pfd = pfd->mNext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -251,6 +251,12 @@ public:
|
||||||
|
|
||||||
static PRBool TreatFrameAsBlock(nsIFrame* aFrame);
|
static PRBool TreatFrameAsBlock(nsIFrame* aFrame);
|
||||||
|
|
||||||
|
static PRBool IsPercentageUnitSides(const nsStyleSides* aSides);
|
||||||
|
|
||||||
|
static PRBool IsPercentageAwareReplacedElement(nsIPresContext *aPresContext,
|
||||||
|
nsIFrame *aFrame);
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------
|
//----------------------------------------
|
||||||
|
|
||||||
nsIPresContext* mPresContext;
|
nsIPresContext* mPresContext;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче