Fixed for ender-lite painting problems. bug #34896

-r mjudge
This commit is contained in:
evaughan%netscape.com 2000-06-06 01:25:03 +00:00
parent ddd7c8acbf
commit d43e56932a
10 changed files with 205 additions and 76 deletions

View File

@ -2062,7 +2062,7 @@ nsGfxTextControlFrame::CalculateSizeNavQuirks (nsIPresContext* aPresContex
// If COLS was not set then check to see if CSS has the width set
//if (NS_CONTENT_ATTR_HAS_VALUE != colStatus) { // col attr will provide width
if (CSS_NOTSET != aCSSSize.width) { // css provides width
NS_ASSERTION(aCSSSize.width >= 0, "form control's computed width is < 0");
//NS_ASSERTION(aCSSSize.width >= 0, "form control's computed width is < 0");
if (NS_INTRINSICSIZE != aCSSSize.width) {
aDesiredSize.width = aCSSSize.width;
aWidthExplicit = PR_TRUE;
@ -2271,7 +2271,7 @@ nsGfxTextControlFrame::CalculateSizeStandard (nsIPresContext* aPresContext
charWidth = nsFormControlHelper::GetTextSize(aPresContext, aFrame, aSpec.mColDefaultSize, aDesiredSize, aRendContext);
aMinSize.width = aDesiredSize.width;
if (CSS_NOTSET != aCSSSize.width) { // css provides width
NS_ASSERTION(aCSSSize.width >= 0, "form control's computed width is < 0");
//NS_ASSERTION(aCSSSize.width >= 0, "form control's computed width is < 0");
if (NS_INTRINSICSIZE != aCSSSize.width) {
aDesiredSize.width = aCSSSize.width;
aWidthExplicit = PR_TRUE;

View File

@ -71,6 +71,9 @@
#include "nsIPresShell.h"
#include "nsIComponentManager.h"
#include "nsBoxLayoutState.h"
#include "nsINameSpaceManager.h"
#define DEFAULT_COLUMN_WIDTH 20
@ -501,7 +504,7 @@ NS_NewGfxTextControlFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
if (nsnull == aNewFrame) {
return NS_ERROR_NULL_POINTER;
}
nsGfxTextControlFrame2* it = new (aPresShell) nsGfxTextControlFrame2();
nsGfxTextControlFrame2* it = new (aPresShell) nsGfxTextControlFrame2(aPresShell);
if (!it) {
return NS_ERROR_OUT_OF_MEMORY;
}
@ -509,8 +512,8 @@ NS_NewGfxTextControlFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
return NS_OK;
}
NS_IMPL_ADDREF_INHERITED(nsGfxTextControlFrame2, nsHTMLContainerFrame);
NS_IMPL_RELEASE_INHERITED(nsGfxTextControlFrame2, nsHTMLContainerFrame);
NS_IMPL_ADDREF_INHERITED(nsGfxTextControlFrame2, nsBoxFrame);
NS_IMPL_RELEASE_INHERITED(nsGfxTextControlFrame2, nsBoxFrame);
NS_IMETHODIMP
@ -535,10 +538,10 @@ nsGfxTextControlFrame2::QueryInterface(const nsIID& aIID, void** aInstancePtr)
*aInstancePtr = (void*)(nsIStatefulFrame*) this;
return NS_OK;
}
return nsHTMLContainerFrame::QueryInterface(aIID, aInstancePtr);
return nsBoxFrame::QueryInterface(aIID, aInstancePtr);
}
nsGfxTextControlFrame2::nsGfxTextControlFrame2()
nsGfxTextControlFrame2::nsGfxTextControlFrame2(nsIPresShell* aShell):nsStackFrame(aShell)
{
mIsProcessing=PR_FALSE;
mFormFrame = nsnull;
@ -567,7 +570,7 @@ nsGfxTextControlFrame2::Destroy(nsIPresContext* aPresContext)
mFormFrame->RemoveFormControlFrame(*this);
mFormFrame = nsnull;
}
return nsHTMLContainerFrame::Destroy(aPresContext);
return nsBoxFrame::Destroy(aPresContext);
}
// XXX: wouldn't it be nice to get this from the style context!
@ -805,7 +808,7 @@ nsGfxTextControlFrame2::CalculateSizeStandard (nsIPresContext* aPresContex
} else {
aDesiredSize.height = aDesiredSize.height * aSpec.mRowDefaultSize;
if (CSS_NOTSET != aCSSSize.height) { // css provides height
NS_ASSERTION(aCSSSize.height > 0, "form control's computed height is <= 0");
//NS_ASSERTION(aCSSSize.height > 0, "form control's computed height is <= 0");
if (NS_INTRINSICSIZE != aCSSSize.height) {
aDesiredSize.height = aCSSSize.height;
aHeightExplicit = PR_TRUE;
@ -1202,9 +1205,116 @@ nsGfxTextControlFrame2::CreateAnonymousContent(nsIPresContext* aPresContext,
return NS_OK;
}
NS_IMETHODIMP
nsGfxTextControlFrame2::GetPrefSize(nsBoxLayoutState& aState, nsSize& aSize)
{
if (!DoesNeedRecalc(mPrefSize)) {
aSize = mPrefSize;
return NS_OK;
}
PropagateDebug(aState);
// navquirk can only happen if we are in the HTML namespace. It does not apply in XUL.
PRInt32 nameSpaceID;
mContent->GetNameSpaceID(nameSpaceID);
aSize.width = 0;
aSize.height = 0;
PRBool collapsed = PR_FALSE;
IsCollapsed(aState, collapsed);
if (collapsed)
return NS_OK;
nsSize styleSize(CSS_NOTSET,CSS_NOTSET);
nsIPresContext* aPresContext = aState.GetPresContext();
const nsHTMLReflowState* aReflowState = aState.GetReflowState();
if (!aReflowState)
return NS_OK;
nsCompatibility mode;
aPresContext->GetCompatibilityMode(&mode);
nsSize desiredSize;
nsSize minSize;
nsMargin aBorder, aPadding;
PRBool widthExplicit, heightExplicit;
PRInt32 ignore;
PRInt32 type;
GetType(&type);
if ((NS_FORM_INPUT_TEXT == type) || (NS_FORM_INPUT_PASSWORD == type)) {
PRInt32 width = 0;
if (NS_CONTENT_ATTR_HAS_VALUE != GetSizeFromContent(&width)) {
width = GetDefaultColumnWidth();
}
nsInputDimensionSpec textSpec(nsnull, PR_FALSE, nsnull,
nsnull, width,
PR_FALSE, nsnull, 1);
if (PR_FALSE) { //eCompatibility_NavQuirks == mode && nameSpaceID == kNameSpaceID_HTML) {
CalculateSizeNavQuirks(aPresContext, aReflowState->rendContext, this, styleSize,
textSpec, desiredSize, minSize, widthExplicit,
heightExplicit, ignore, aBorder, aPadding);
} else {
CalculateSizeStandard(aPresContext, aReflowState->rendContext, this, styleSize,
textSpec, desiredSize, minSize, widthExplicit,
heightExplicit, ignore, aBorder, aPadding);
}
} else {
nsInputDimensionSpec areaSpec(nsHTMLAtoms::cols, PR_FALSE, nsnull,
nsnull, GetDefaultColumnWidth(),
PR_FALSE, nsHTMLAtoms::rows, 1);
if (PR_FALSE) {//eCompatibility_NavQuirks == mode && nameSpaceID == kNameSpaceID_HTML) {
CalculateSizeNavQuirks(aPresContext, aReflowState->rendContext, this, styleSize,
areaSpec, desiredSize, minSize, widthExplicit,
heightExplicit, ignore, aBorder, aPadding);
} else {
CalculateSizeStandard(aPresContext, aReflowState->rendContext, this, styleSize,
areaSpec, desiredSize, minSize, widthExplicit,
heightExplicit, ignore, aBorder, aPadding);
}
}
aSize = desiredSize;
AddBorderAndPadding(aSize);
AddInset(aSize);
nsIBox::AddCSSPrefSize(aState, this, aSize);
mPrefSize = aSize;
return NS_OK;
}
NS_IMETHODIMP
nsGfxTextControlFrame2::GetMinSize(nsBoxLayoutState& aState, nsSize& aSize)
{
return nsBox::GetMinSize(aState, aSize);
}
NS_IMETHODIMP
nsGfxTextControlFrame2::GetMaxSize(nsBoxLayoutState& aState, nsSize& aSize)
{
return nsBox::GetMaxSize(aState, aSize);
}
NS_IMETHODIMP
nsGfxTextControlFrame2::GetAscent(nsBoxLayoutState& aState, nscoord& aAscent)
{
nsSize size;
nsresult rv = GetPrefSize(aState, size);
aAscent = size.height;
return rv;
}
/*
NS_IMETHODIMP nsGfxTextControlFrame2::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
@ -1365,11 +1475,12 @@ NS_IMETHODIMP nsGfxTextControlFrame2::Reflow(nsIPresContext* aPresConte
aStatus = NS_FRAME_COMPLETE;
// printf("width=%d, height=%d, ascent=%d\n", aDesiredSize.width, aDesiredSize.height, aDesiredSize.ascent);
printf("width=%d, height=%d, ascent=%d\n", aDesiredSize.width, aDesiredSize.height, aDesiredSize.ascent);
return rv;
}
//#endif
*/
PRIntn
nsGfxTextControlFrame2::GetSkipSides() const
@ -1726,7 +1837,7 @@ nsGfxTextControlFrame2::AttributeChanged(nsIPresContext* aPresContext,
// Allow the base class to handle common attributes supported
// by all form elements...
else {
rv = nsHTMLContainerFrame::AttributeChanged(aPresContext, aChild, aNameSpaceID, aAttribute, aHint);
rv = nsBoxFrame::AttributeChanged(aPresContext, aChild, aNameSpaceID, aAttribute, aHint);
}
return rv;
@ -1924,7 +2035,7 @@ nsGfxTextControlFrame2::SetInitialChildList(nsIPresContext* aPresContext,
list->GetNextSibling(&list);
}
*/
nsresult rv = nsHTMLContainerFrame::SetInitialChildList(aPresContext, aListName, aChildList);
nsresult rv = nsBoxFrame::SetInitialChildList(aPresContext, aListName, aChildList);
if (mEditor)
mEditor->PostCreate();
//look for scroll view below this frame go along first child list

View File

@ -23,6 +23,7 @@
#ifndef nsGfxTextControlFrame2_h___
#define nsGfxTextControlFrame2_h___
#include "nsStackFrame.h"
#include "nsAreaFrame.h"
#include "nsIFormControlFrame.h"
#include "nsIDOMMouseListener.h"
@ -46,7 +47,7 @@ class nsTextAreaSelectionImpl;
class nsGfxTextControlFrame2 : public nsHTMLContainerFrame,
class nsGfxTextControlFrame2 : public nsStackFrame,
public nsIAnonymousContentCreator,
public nsIFormControlFrame,
public nsIGfxTextControlFrame2,
@ -54,15 +55,15 @@ class nsGfxTextControlFrame2 : public nsHTMLContainerFrame,
{
public:
nsGfxTextControlFrame2();
nsGfxTextControlFrame2(nsIPresShell* aShell);
virtual ~nsGfxTextControlFrame2();
NS_IMETHOD Destroy(nsIPresContext* aPresContext);//remove yourself as a form control
NS_IMETHOD Reflow(nsIPresContext* aCX,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD GetPrefSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD GetMinSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD GetMaxSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD GetAscent(nsBoxLayoutState& aBoxLayoutState, nscoord& aAscent);
#ifdef NS_DEBUG
NS_IMETHOD GetFrameName(nsString& aResult) const

View File

@ -17,17 +17,12 @@
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Author: Eric D Vaughan <evaughan@netscape.com>
*
* Contributor(s):
* Pierre Phaneuf <pp@ludusdesign.com>
*/
//
// Eric Vaughan
// Netscape Communications
//
// See documentation in associated header file
//
#include "nsBoxLayoutState.h"
#include "nsBox.h"
#include "nsBoxFrame.h"
@ -48,7 +43,7 @@
#include "nsIDOMAttr.h"
//#define DEBUG_REFLOW
//#define DEBUG_LAYOUT
#ifdef DEBUG_COELESCED
static PRInt32 coelesced = 0;
@ -57,7 +52,7 @@ static PRInt32 coelesced = 0;
PRInt32 gIndent = 0;
PRInt32 gLayout = 0;
#ifdef DEBUG_REFLOW
#ifdef DEBUG_LAYOUT
void
nsBoxAddIndents()
{
@ -139,7 +134,7 @@ nsBox::GetBoxName(nsAutoString& aName)
void
nsBox::EnterLayout(nsBoxLayoutState& aState)
{
#ifdef DEBUG_REFLOW
#ifdef DEBUG_LAYOUT
nsBoxAddIndents();
@ -169,7 +164,7 @@ nsBox::EnterLayout(nsBoxLayoutState& aState)
void
nsBox::ExitLayout(nsBoxLayoutState& aState)
{
#ifdef DEBUG_REFLOW
#ifdef DEBUG_LAYOUT
--gIndent;
#endif
}

View File

@ -168,11 +168,6 @@ public:
nsBoxFrame::Valignment mValign;
nsBoxFrame::Halignment mHalign;
nsSize mPrefSize;
nsSize mMinSize;
nsSize mMaxSize;
nscoord mFlex;
nscoord mAscent;
nsIPresContext* mPresContext;
static PRBool gDebug;
@ -688,17 +683,17 @@ nsBoxFrame::Reflow(nsIPresContext* aPresContext,
NS_IMETHODIMP
nsBoxFrame::GetPrefSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)
{
if (!DoesNeedRecalc(mInner->mPrefSize)) {
aSize = mInner->mPrefSize;
if (!DoesNeedRecalc(mPrefSize)) {
aSize = mPrefSize;
return NS_OK;
}
PropagateDebug(aBoxLayoutState);
nsresult rv = NS_OK;
rv = nsContainerBox::GetPrefSize(aBoxLayoutState, mInner->mPrefSize);
rv = nsContainerBox::GetPrefSize(aBoxLayoutState, mPrefSize);
aSize = mInner->mPrefSize;
aSize = mPrefSize;
return rv;
}
@ -706,17 +701,17 @@ nsBoxFrame::GetPrefSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)
NS_IMETHODIMP
nsBoxFrame::GetAscent(nsBoxLayoutState& aBoxLayoutState, nscoord& aAscent)
{
if (!DoesNeedRecalc(mInner->mAscent)) {
aAscent = mInner->mAscent;
if (!DoesNeedRecalc(mAscent)) {
aAscent = mAscent;
return NS_OK;
}
PropagateDebug(aBoxLayoutState);
nsresult rv = NS_OK;
rv = nsContainerBox::GetAscent(aBoxLayoutState, mInner->mAscent);
rv = nsContainerBox::GetAscent(aBoxLayoutState, mAscent);
aAscent = mInner->mAscent;
aAscent = mAscent;
return rv;
}
@ -724,8 +719,8 @@ nsBoxFrame::GetAscent(nsBoxLayoutState& aBoxLayoutState, nscoord& aAscent)
NS_IMETHODIMP
nsBoxFrame::GetMinSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)
{
if (!DoesNeedRecalc(mInner->mMinSize)) {
aSize = mInner->mMinSize;
if (!DoesNeedRecalc(mMinSize)) {
aSize = mMinSize;
return NS_OK;
}
@ -733,10 +728,10 @@ nsBoxFrame::GetMinSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)
nsresult rv = NS_OK;
mInner->mMinSize.SizeTo(0,0);
rv = nsContainerBox::GetMinSize(aBoxLayoutState, mInner->mMinSize);
mMinSize.SizeTo(0,0);
rv = nsContainerBox::GetMinSize(aBoxLayoutState, mMinSize);
aSize = mInner->mMinSize;
aSize = mMinSize;
return rv;
}
@ -744,8 +739,8 @@ nsBoxFrame::GetMinSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)
NS_IMETHODIMP
nsBoxFrame::GetMaxSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)
{
if (!DoesNeedRecalc(mInner->mMaxSize)) {
aSize = mInner->mMaxSize;
if (!DoesNeedRecalc(mMaxSize)) {
aSize = mMaxSize;
return NS_OK;
}
@ -753,10 +748,10 @@ nsBoxFrame::GetMaxSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)
nsresult rv = NS_OK;
mInner->mMaxSize.SizeTo(0,0);
nsContainerBox::GetMaxSize(aBoxLayoutState, mInner->mMaxSize);
mMaxSize.SizeTo(0,0);
nsContainerBox::GetMaxSize(aBoxLayoutState, mMaxSize);
aSize = mInner->mMaxSize;
aSize = mMaxSize;
return rv;
}
@ -764,16 +759,16 @@ nsBoxFrame::GetMaxSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize)
NS_IMETHODIMP
nsBoxFrame::GetFlex(nsBoxLayoutState& aBoxLayoutState, nscoord& aFlex)
{
if (!DoesNeedRecalc(mInner->mFlex)) {
aFlex = mInner->mFlex;
if (!DoesNeedRecalc(mFlex)) {
aFlex = mFlex;
return NS_OK;
}
nsresult rv = NS_OK;
mInner->mFlex = 0;
rv = nsContainerBox::GetFlex(aBoxLayoutState, mInner->mFlex);
aFlex = mInner->mFlex;
mFlex = 0;
rv = nsContainerBox::GetFlex(aBoxLayoutState, mFlex);
aFlex = mFlex;
return rv;
}
@ -862,11 +857,11 @@ NS_IMETHODIMP
nsBoxFrame::NeedsRecalc()
{
if (mInner) {
SizeNeedsRecalc(mInner->mPrefSize);
SizeNeedsRecalc(mInner->mMinSize);
SizeNeedsRecalc(mInner->mMaxSize);
CoordNeedsRecalc(mInner->mFlex);
CoordNeedsRecalc(mInner->mAscent);
SizeNeedsRecalc(mPrefSize);
SizeNeedsRecalc(mMinSize);
SizeNeedsRecalc(mMaxSize);
CoordNeedsRecalc(mFlex);
CoordNeedsRecalc(mAscent);
}
return NS_OK;
}

View File

@ -203,6 +203,12 @@ protected:
virtual void GetInsertionPoint(nsIPresShell* aShell, nsIFrame* aChild, nsIFrame** aResult);
nsSize mPrefSize;
nsSize mMinSize;
nsSize mMaxSize;
nscoord mFlex;
nscoord mAscent;
private:
friend class nsBoxFrameInner;

View File

@ -194,7 +194,6 @@ nsBoxToBlockAdaptor::~nsBoxToBlockAdaptor()
NS_IMETHODIMP
nsBoxToBlockAdaptor::NeedsRecalc()
{
mSizeSet = PR_FALSE;
mMinWidth = -1;
mPrefNeedsRecalc = PR_TRUE;
SizeNeedsRecalc(mMinSize);
@ -380,11 +379,16 @@ nsBoxToBlockAdaptor::GetAscent(nsBoxLayoutState& aState, nscoord& aAscent)
return NS_OK;
}
aAscent = 0;
return NS_OK;
/*
nsSize size;
GetPrefSize(aState, size);
aAscent = mAscent;
*/
return NS_OK;
}
@ -444,6 +448,9 @@ nsBoxToBlockAdaptor::Layout(nsBoxLayoutState& aState)
mFrame->SizeTo(presContext, 0, 0);
} else {
mAscent = desiredSize.ascent;
// if our child needs to be bigger. This might happend with wrapping text. There is no way to predict its
// height until we reflow it. Now that we know the height reshuffle upward.
if (desiredSize.width > ourRect.width || desiredSize.height > ourRect.height) {
#ifdef DEBUG_GROW
@ -456,9 +463,11 @@ nsBoxToBlockAdaptor::Layout(nsBoxLayoutState& aState)
if (desiredSize.height > ourRect.height)
ourRect.height = desiredSize.height;
mFrame->SizeTo(presContext, ourRect.width, ourRect.height);
}
// ensure our size is what we think is should be. Someone could have
// reset the frame to be smaller or something dumb like that.
mFrame->SizeTo(presContext, ourRect.width, ourRect.height);
}
}
@ -710,12 +719,13 @@ nsBoxToBlockAdaptor::Reflow(nsBoxLayoutState& aState,
// PlaceChild(aPresContext, mFrame, aX + margin.left, aY + margin.top);
// }
/*
// html doesn't like 0 sizes.
if (reflowState.mComputedWidth == 0)
reflowState.mComputedWidth = 1;
if (reflowState.mComputedHeight == 0)
reflowState.mComputedHeight = 1;
*/
// if we were marked for style change.
// 1) see if we are just supposed to do a resize if so convert to a style change. Kill 2 birds

View File

@ -327,7 +327,7 @@ nsObeliskLayout::Desecrated(nsIBox* aBox, nsBoxLayoutState& aState, nsBoxSizeLi
nsCOMPtr<nsIBoxLayout> layout;
aBox->GetLayoutManager(getter_AddRefs(layout));
aBox->SetLayoutManager(nsnull);
aBox->MarkDirty(aState);
aBox->MarkDirtyChildren(aState);
aBox->SetLayoutManager(layout);
}
}

View File

@ -367,6 +367,8 @@ nsSprocketLayout::Layout(nsIBox* aBox, nsBoxLayoutState& aState)
sizeChanged = (childRect.width != oldRect.width || childRect.height != oldRect.height);
// }
PRBool possibleRedraw = PR_FALSE;
if (sizeChanged) {
nsSize maxSize;
child->GetMaxSize(aState, maxSize);
@ -381,12 +383,13 @@ nsSprocketLayout::Layout(nsIBox* aBox, nsBoxLayoutState& aState)
// set it again
child->SetBounds(aState, childRect);
needsRedraw = PR_TRUE;
// ok a child changed size so we should redraw the whole box. But it still has the possibility of
// redeeming itself. If it happens to get bigger during layout like
// wrapping text might. It may still end up the same size as it was. Then
// we don't need to redraw ourselves.
possibleRedraw = PR_TRUE;
}
// if (childBoxSize)
// if(!childBoxSize->collapsed)
// child->UnCollapse(aState);
if (layout || sizeChanged) {
child->Layout(aState);
@ -461,6 +464,10 @@ nsSprocketLayout::Layout(nsIBox* aBox, nsBoxLayoutState& aState)
child->SetBounds(aState, newChildRect);
// if the child resized but was the exact size it was. Don't redraw.
if (oldRect.width == newChildRect.width || oldRect.height == newChildRect.height)
possibleRedraw = PR_FALSE;
// if we are the first we don't need to do a second pass
if (count == 0)
finished = PR_TRUE;
@ -470,6 +477,9 @@ nsSprocketLayout::Layout(nsIBox* aBox, nsBoxLayoutState& aState)
y = nextY;
}
if (possibleRedraw)
needsRedraw = PR_TRUE;
childComputedBoxSize = childComputedBoxSize->next;
childBoxSize = childBoxSize->next;

View File

@ -71,11 +71,12 @@ private:
const nsPoint& aPoint,
nsIFrame** aFrame);
nsStackFrame(nsIPresShell* aPresShell, nsIBoxLayout* aLayout = nsnull);
protected:
nsStackFrame(nsIPresShell* aPresShell);
nsStackFrame(nsIPresShell* aPresShell, nsIBoxLayout* aLayout = nsnull);
//nsStackFrame(nsIPresShell* aPresShell);
private: