added support for front-to-back view rendering.

This commit is contained in:
michaelp 1998-05-27 02:13:28 +00:00
parent f3731166a5
commit b5140d2751
18 changed files with 452 additions and 111 deletions

View File

@ -0,0 +1,96 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsRegionUnix.h"
static NS_DEFINE_IID(kRegionIID, NS_IREGION_IID);
nsRegionUnix :: nsRegionUnix()
{
NS_INIT_REFCNT();
}
nsRegionUnix :: ~nsRegionUnix()
{
}
NS_IMPL_QUERY_INTERFACE(nsRegionUnix, kRegionIID)
NS_IMPL_ADDREF(nsRegionUnix)
NS_IMPL_RELEASE(nsRegionUnix)
nsresult nsRegionUnix :: Init(void)
{
return NS_OK;
}
void nsRegionUnix :: SetTo(const nsIRegion &aRegion)
{
}
void nsRegionUnix :: SetTo(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
{
}
void nsRegionUnix :: Intersect(const nsIRegion &aRegion)
{
}
void nsRegionUnix :: Intersect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
{
}
void nsRegionUnix :: Union(const nsIRegion &aRegion)
{
}
void nsRegionUnix :: Union(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
{
}
void nsRegionUnix :: Subtract(const nsIRegion &aRegion)
{
}
PRBool nsRegionUnix :: IsEmpty(void)
{
return PR_FALSE;
}
PRBool nsRegionUnix :: IsEqual(const nsIRegion &aRegion)
{
return PR_FALSE;
}
void nsRegionUnix :: GetBoundingBox(PRInt32 *aX, PRInt32 *aY, PRInt32 *aWidth, PRInt32 *aHeight)
{
*aX = *aY = *aWidth = *aHeight = 0;
}
void nsRegionUnix :: Offset(PRInt32 aXOffset, PRInt32 aYOffset)
{
}
PRBool nsRegionUnix :: ContainsRect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
{
return PR_TRUE;
}
PRBool nsRegionUnix :: ForEachRect(nsRectInRegionFunc *func, void *closure)
{
return PR_FALSE;
}

View File

@ -0,0 +1,51 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsRegionUnix_h___
#define nsRegionUnix_h___
#include "nsIRegion.h"
class nsRegionUnix : public nsIRegion
{
public:
nsRegionUnix();
NS_DECL_ISUPPORTS
virtual nsresult Init();
virtual void SetTo(const nsIRegion &aRegion);
virtual void SetTo(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight);
virtual void Intersect(const nsIRegion &aRegion);
virtual void Intersect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight);
virtual void Union(const nsIRegion &aRegion);
virtual void Union(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight);
virtual void Subtract(const nsIRegion &aRegion);
virtual PRBool IsEmpty(void);
virtual PRBool IsEqual(const nsIRegion &aRegion);
virtual void GetBoundingBox(PRInt32 *aX, PRInt32 *aY, PRInt32 *aWidth, PRInt32 *aHeight);
virtual void Offset(PRInt32 aXOffset, PRInt32 aYOffset);
virtual PRBool ContainsRect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight);
virtual PRBool ForEachRect(nsRectInRegionFunc *func, void *closure);
private:
~nsRegionUnix();
};
#endif // nsRegionUnix_h___

View File

@ -93,11 +93,11 @@ nsIDeviceContext * nsRenderingContextUnix :: GetDeviceContext(void)
return mContext;
}
void nsRenderingContextUnix :: PushState()
void nsRenderingContextUnix :: PushState(void)
{
}
void nsRenderingContextUnix :: PopState()
void nsRenderingContextUnix :: PopState(void)
{
}
@ -106,16 +106,42 @@ PRBool nsRenderingContextUnix :: IsVisibleRect(const nsRect& aRect)
return PR_TRUE;
}
void nsRenderingContextUnix :: SetClipRect(const nsRect& aRect, PRBool aIntersect)
void nsRenderingContextUnix :: SetClipRect(const nsRect& aRect, nsClipCombine aCombine)
{
nsRect trect = aRect;
mTMatrix->TransformCoord(&trect.x, &trect.y,
&trect.width, &trect.height);
//how we combine the new rect with the previous?
if (aCombine == nsClipCombine_kIntersect)
{
}
else if (aCombine == nsClipCombine_kUnion)
{
}
else if (aCombine == nsClipCombine_kSubtract)
{
}
else if (aCombine == nsClipCombine_kReplace)
{
}
else
NS_ASSERTION(FALSE, "illegal clip combination");
}
PRBool nsRenderingContextUnix :: GetClipRect(nsRect &aRect)
{
return PR_TRUE;
return PR_FALSE;
}
void nsRenderingContextUnix :: SetClipRegion(const nsIRegion& aRegion, PRBool aIntersect)
void nsRenderingContextUnix :: SetClipRegion(const nsIRegion& aRegion, nsClipCombine aCombine)
{
//XXX wow, needs to do something.
}
void nsRenderingContextUnix :: GetClipRegion(nsIRegion **aRegion)
{
//XXX wow, needs to do something.
}

View File

@ -34,6 +34,7 @@
#include "nsImageUnix.h"
#include "nsIDeviceContext.h"
#include "nsVoidArray.h"
#include "nsIRegion.h"
#include "Xm/Xm.h"
@ -62,15 +63,15 @@ public:
virtual nsresult SelectOffScreenDrawingSurface(nsDrawingSurface aSurface);
virtual void PushState();
virtual void PopState();
virtual void PushState(void);
virtual void PopState(void);
virtual PRBool IsVisibleRect(const nsRect& aRect);
virtual void SetClipRect(const nsRect& aRect, PRBool aIntersect);
virtual void SetClipRect(const nsRect& aRect, nsClipCombine aCombine);
virtual PRBool GetClipRect(nsRect &aRect);
virtual void SetClipRegion(const nsIRegion& aRegion, PRBool aIntersect);
virtual void SetClipRegion(const nsIRegion& aRegion, nsClipCombine aCombine);
virtual void GetClipRegion(nsIRegion **aRegion);
virtual void SetColor(nscolor aColor);
virtual nscolor GetColor() const;

View File

@ -37,6 +37,16 @@ struct nsFont;
struct nsPoint;
struct nsRect;
//cliprect/region combination methods
typedef enum
{
nsClipCombine_kIntersect = 0,
nsClipCombine_kUnion = 1,
nsClipCombine_kSubtract = 2,
nsClipCombine_kReplace = 3
} nsClipCombine;
// IID for the nsIRenderingContext interface
#define NS_IRENDERING_CONTEXT_IID \
{ 0x7fd8c0f0, 0xa265, 0x11d1, \
@ -90,12 +100,12 @@ public:
/**
* Save a graphical state onto a stack.
*/
virtual void PushState() = 0;
virtual void PushState(void) = 0;
/**
* Get and and set RenderingContext to this graphical state
*/
virtual void PopState() = 0;
virtual void PopState(void) = 0;
/**
* Tells if a given rectangle is visible within the rendering context
@ -107,26 +117,35 @@ public:
/**
* Sets the clipping for the RenderingContext to the passed in rectangle
* @param aRect The rectangle to set the clipping rectangle to
* @param aIntersect A boolean, if true will cause aRect to be
* intersected with existing clip area
* @param aCombine how to combine this rect with the current clip region.
* see the bottom of nsIRenderingContext.h
*/
virtual void SetClipRect(const nsRect& aRect, PRBool aIntersect) = 0;
virtual void SetClipRect(const nsRect& aRect, nsClipCombine aCombine) = 0;
/**
* Gets the clipping rectangle of the RenderingContext
* @param aRect out parameter to containt the clipping rectangle
* Gets the bounds of the clip region of the RenderingContext
* @param aRect out parameter to contain the clip region bounds
* for the RenderingContext
* @return PR_TRUE if the rendering context has a cliprect set
* (i.e. this is the exact clip rect, not a clip region bounds)
*/
virtual PRBool GetClipRect(nsRect &aRect) = 0;
/**
* Sets the clipping for the RenderingContext to the passed in region
* @param aRegion The region to set the clipping area to
* @param aIntersect A boolean, if true will cause aRegion to be
* intersected with existing clip area
* @param aCombine how to combine this region with the current clip region.
* see the bottom of nsIRenderingContext.h
*/
virtual void SetClipRegion(const nsIRegion& aRegion, PRBool aIntersect) = 0;
virtual void SetClipRegion(const nsIRegion& aRegion, nsClipCombine aCombine) = 0;
/**
* Gets the current clipping region for the RenderingContext
* @param aRegion out parameter representing the clip region.
* if SetClipRegion() is called, do not assume that GetClipRegion()
* will return the same object.
*/
virtual void GetClipRegion(nsIRegion **aRegion) = 0;
/**
* Sets the forground color for the RenderingContext

View File

@ -19,6 +19,9 @@
#include "nsRenderingContextWin.h"
#include <math.h>
#define FLAG_CLIP_VALID 0x0001
#define FLAG_CLIP_CHANGED 0x0002
class GraphicsState
{
public:
@ -29,7 +32,6 @@ public:
GraphicsState *mNext;
nsTransform2D mMatrix;
nsRect mLocalClip;
nsRect mGlobalClip;
HRGN mClipRegion;
nscolor mBrushColor;
HBRUSH mSolidBrush;
@ -37,6 +39,7 @@ public:
HFONT mFont;
nscolor mPenColor;
HPEN mSolidPen;
PRUint32 mFlags;
};
GraphicsState :: GraphicsState()
@ -44,7 +47,6 @@ GraphicsState :: GraphicsState()
mNext = nsnull;
mMatrix.SetToIdentity();
mLocalClip.x = mLocalClip.y = mLocalClip.width = mLocalClip.height = 0;
mGlobalClip = mLocalClip;
mClipRegion = NULL;
mBrushColor = NS_RGB(0, 0, 0);
mSolidBrush = NULL;
@ -52,12 +54,12 @@ GraphicsState :: GraphicsState()
mFont = NULL;
mPenColor = NS_RGB(0, 0, 0);
mSolidPen = NULL;
mFlags = 0;
}
GraphicsState :: GraphicsState(GraphicsState &aState) :
mMatrix(&aState.mMatrix),
mLocalClip(aState.mLocalClip),
mGlobalClip(aState.mGlobalClip)
mLocalClip(aState.mLocalClip)
{
mNext = &aState;
mClipRegion = NULL;
@ -67,6 +69,7 @@ GraphicsState :: GraphicsState(GraphicsState &aState) :
mFont = NULL;
mPenColor = aState.mPenColor;
mSolidPen = NULL;
mFlags = 0;
}
GraphicsState :: ~GraphicsState()
@ -309,7 +312,7 @@ nsIDeviceContext * nsRenderingContextWin :: GetDeviceContext(void)
return mContext;
}
void nsRenderingContextWin :: PushState()
void nsRenderingContextWin :: PushState(void)
{
PRInt32 cnt = mStateCache->Count();
@ -331,14 +334,14 @@ void nsRenderingContextWin :: PushState()
state->mMatrix = mStates->mMatrix;
state->mLocalClip = mStates->mLocalClip;
state->mGlobalClip = mStates->mGlobalClip;
state->mClipRegion = nsnull;
state->mClipRegion = NULL;
state->mBrushColor = mStates->mBrushColor;
state->mSolidBrush = nsnull;
state->mSolidBrush = NULL;
state->mFontMetrics = mStates->mFontMetrics;
state->mFont = nsnull;
state->mFont = NULL;
state->mPenColor = mStates->mPenColor;
state->mSolidPen = nsnull;
state->mSolidPen = NULL;
state->mFlags = 0;
mStates = state;
}
@ -346,7 +349,7 @@ void nsRenderingContextWin :: PushState()
mTMatrix = &mStates->mMatrix;
}
void nsRenderingContextWin :: PopState()
void nsRenderingContextWin :: PopState(void)
{
if (nsnull == mStates)
{
@ -366,27 +369,21 @@ void nsRenderingContextWin :: PopState()
GraphicsState *pstate;
if (NULL != oldstate->mClipRegion)
if (oldstate->mFlags & FLAG_CLIP_CHANGED)
{
pstate = mStates;
//the clip rect has changed from state to state, so
//install the previous clip rect
while ((nsnull != pstate) && (NULL == pstate->mClipRegion))
while ((nsnull != pstate) && !(pstate->mFlags & FLAG_CLIP_VALID))
pstate = pstate->mNext;
if ((nsnull != pstate) && (pstate->mGlobalClip != oldstate->mGlobalClip))
if (nsnull != pstate)
::SelectClipRgn(mDC, pstate->mClipRegion);
else
::SelectClipRgn(mDC, NULL);
//kill the clip region we are popping off the stack
::DeleteObject(oldstate->mClipRegion);
oldstate->mClipRegion = NULL;
}
oldstate->mFlags &= ~(FLAG_CLIP_VALID | FLAG_CLIP_CHANGED);
oldstate->mSolidBrush = NULL;
oldstate->mFont = NULL;
oldstate->mSolidPen = NULL;
@ -401,7 +398,7 @@ PRBool nsRenderingContextWin :: IsVisibleRect(const nsRect& aRect)
return PR_TRUE;
}
void nsRenderingContextWin :: SetClipRect(const nsRect& aRect, PRBool aIntersect)
void nsRenderingContextWin :: SetClipRect(const nsRect& aRect, nsClipCombine aCombine)
{
nsRect trect = aRect;
@ -410,26 +407,51 @@ void nsRenderingContextWin :: SetClipRect(const nsRect& aRect, PRBool aIntersect
mTMatrix->TransformCoord(&trect.x, &trect.y,
&trect.width, &trect.height);
//should we combine the new rect with the previous?
//how we combine the new rect with the previous?
if (aIntersect == PR_TRUE)
if (aCombine == nsClipCombine_kIntersect)
{
if (PR_FALSE == mStates->mGlobalClip.IntersectRect(mStates->mGlobalClip, trect))
{
mStates->mGlobalClip.x = mStates->mGlobalClip.y = mStates->mGlobalClip.width = mStates->mGlobalClip.height = 0;
}
PushClipState();
::IntersectClipRect(mDC, trect.x,
trect.y,
trect.XMost(),
trect.YMost());
}
else if (aCombine == nsClipCombine_kUnion)
{
PushClipState();
HRGN tregion = ::CreateRectRgn(trect.x,
trect.y,
trect.XMost(),
trect.YMost());
::ExtSelectClipRgn(mDC, tregion, RGN_OR);
::DeleteObject(tregion);
}
else if (aCombine == nsClipCombine_kSubtract)
{
PushClipState();
::ExcludeClipRect(mDC, trect.x,
trect.y,
trect.XMost(),
trect.YMost());
}
else if (aCombine == nsClipCombine_kReplace)
{
PushClipState();
HRGN tregion = ::CreateRectRgn(trect.x,
trect.y,
trect.XMost(),
trect.YMost());
::SelectClipRgn(mDC, tregion);
::DeleteObject(tregion);
}
else
mStates->mGlobalClip = trect;
if (NULL != mStates->mClipRegion)
::DeleteObject(mStates->mClipRegion);
mStates->mClipRegion = ::CreateRectRgn(mStates->mGlobalClip.x,
mStates->mGlobalClip.y,
mStates->mGlobalClip.XMost(),
mStates->mGlobalClip.YMost());
::SelectClipRgn(mDC, mStates->mClipRegion);
NS_ASSERTION(FALSE, "illegal clip combination");
}
PRBool nsRenderingContextWin :: GetClipRect(nsRect &aRect)
@ -439,7 +461,12 @@ PRBool nsRenderingContextWin :: GetClipRect(nsRect &aRect)
return PR_TRUE;
}
void nsRenderingContextWin :: SetClipRegion(const nsIRegion& aRegion, PRBool aIntersect)
void nsRenderingContextWin :: SetClipRegion(const nsIRegion& aRegion, nsClipCombine aCombine)
{
//XXX wow, needs to do something.
}
void nsRenderingContextWin :: GetClipRegion(nsIRegion **aRegion)
{
//XXX wow, needs to do something.
}
@ -877,17 +904,28 @@ nsresult nsRenderingContextWin :: CopyOffScreenBits(nsRect &aBounds)
{
if ((nsnull != mDC) && (nsnull != mMainDC))
{
HRGN tregion = ::CreateRectRgn(0, 0, 0, 0);
if (::GetClipRgn(mDC, tregion) == 1)
::SelectClipRgn(mMainDC, tregion);
// else
// ::SelectClipRgn(mMainDC, NULL);
::DeleteObject(tregion);
#if 0
GraphicsState *pstate = mStates;
//look for a cliprect somewhere in the stack...
while ((nsnull != pstate) && (NULL == pstate->mClipRegion))
while ((nsnull != pstate) && !(pstate->mFlags & FLAG_CLIP_VALID))
pstate = pstate->mNext;
if (nsnull != pstate)
::SelectClipRgn(mMainDC, pstate->mClipRegion);
else
::SelectClipRgn(mMainDC, NULL);
#endif
::BitBlt(mMainDC, 0, 0, aBounds.width, aBounds.height, mDC, 0, 0, SRCCOPY);
}
@ -952,3 +990,29 @@ HPEN nsRenderingContextWin :: SetupSolidPen(void)
return mCurrPen;
}
void nsRenderingContextWin :: PushClipState(void)
{
if (!(mStates->mFlags & FLAG_CLIP_CHANGED))
{
GraphicsState *tstate = mStates->mNext;
//we have never set a clip on this state before, so
//remember the current clip state in the next state on the
//stack. kind of wacky, but avoids selecting stuff in the DC
//all the damned time.
if (nsnull != tstate)
{
if (NULL == tstate->mClipRegion)
tstate->mClipRegion = ::CreateRectRgn(0, 0, 0, 0);
if (::GetClipRgn(mDC, tstate->mClipRegion) == 1)
tstate->mFlags |= FLAG_CLIP_VALID;
else
tstate->mFlags &= ~FLAG_CLIP_VALID;
}
mStates->mFlags |= FLAG_CLIP_CHANGED;
}
}

View File

@ -60,14 +60,15 @@ public:
virtual nsresult SelectOffScreenDrawingSurface(nsDrawingSurface aSurface);
virtual void PushState();
virtual void PopState();
virtual void PushState(void);
virtual void PopState(void);
virtual PRBool IsVisibleRect(const nsRect& aRect);
virtual void SetClipRect(const nsRect& aRect, PRBool aIntersect);
virtual void SetClipRect(const nsRect& aRect, nsClipCombine aCombine);
virtual PRBool GetClipRect(nsRect &aRect);
virtual void SetClipRegion(const nsIRegion& aRegion, PRBool aIntersect);
virtual void SetClipRegion(const nsIRegion& aRegion, nsClipCombine aCombine);
virtual void GetClipRegion(nsIRegion **aRegion);
virtual void SetColor(nscolor aColor);
virtual nscolor GetColor() const;
@ -129,6 +130,7 @@ private:
HBRUSH SetupSolidBrush(void);
HPEN SetupSolidPen(void);
void SetupFont(void);
void PushClipState(void);
protected:
nscolor mCurrentColor;
@ -142,6 +144,7 @@ protected:
nsIDeviceContext *mContext;
float mP2T;
HDC mMainDC;
HRGN mClipRegion;
//default objects
HBRUSH mOrigSolidBrush;
HBRUSH mBlackBrush;

View File

@ -851,7 +851,7 @@ void nsCSSRendering::PaintBackground(nsIPresContext& aPresContext,
PRIntn yPos = aColor.mBackgroundXPosition;
#endif
aRenderingContext.PushState();
aRenderingContext.SetClipRect(aDirtyRect, PR_TRUE);
aRenderingContext.SetClipRect(aDirtyRect, nsClipCombine_kIntersect);
PRIntn x, y;
for (y = 0; y <= ycount; ++y, ypos += tileHeight) {
for (x = 0, xpos = xpos0; x <= xcount; ++x, xpos += tileWidth) {

View File

@ -232,7 +232,7 @@ void nsContainerFrame::PaintChildren(nsIPresContext& aPresContext,
if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) {
aRenderingContext.PushState();
aRenderingContext.SetClipRect(nsRect(0, 0, mRect.width, mRect.height),
PR_TRUE);
nsClipCombine_kIntersect);
hidden = PR_TRUE;
}

View File

@ -372,17 +372,17 @@ NS_METHOD nsFrame::MoveTo(nscoord aX, nscoord aY)
if ((aX != mRect.x) || (aY != mRect.y)) {
mRect.x = aX;
mRect.y = aY;
}
// Let the view know
if (nsnull != mView) {
// Position view relative to it's parent, not relative to our
// parent frame (our parent frame may not have a view).
nsIView* parentWithView;
nsPoint origin;
GetOffsetFromView(origin, parentWithView);
mView->SetPosition(origin.x, origin.y);
NS_IF_RELEASE(parentWithView);
}
// Let the view know
if (nsnull != mView) {
// Position view relative to it's parent, not relative to our
// parent frame (our parent frame may not have a view).
nsIView* parentWithView;
nsPoint origin;
GetOffsetFromView(origin, parentWithView);
mView->SetPosition(origin.x, origin.y);
NS_IF_RELEASE(parentWithView);
}
return NS_OK;
@ -998,6 +998,7 @@ nsFrame::DidReflow(nsIPresContext& aPresContext,
{
NS_FRAME_TRACE_MSG(("nsFrame::DidReflow: aStatus=%d", aStatus));
if (NS_FRAME_REFLOW_FINISHED == aStatus) {
// MoveTo(mRect.x, mRect.y); //added and killed per kipp's instructions... MMP
mState &= ~NS_FRAME_IN_REFLOW;
}
return NS_OK;

View File

@ -37,6 +37,9 @@
#include "nsILinkHandler.h"
#include "nsIURL.h"
#include "nsCSSLayout.h"
#include "nsViewsCID.h"
#include "nsIView.h"
#include "nsIViewManager.h"
#define BROKEN_IMAGE_URL "resource:/html/broken-image.gif"
@ -292,6 +295,45 @@ nsHTMLImageLoader::GetDesiredSize(nsIPresContext* aPresContext,
ImageFrame::ImageFrame(nsIContent* aContent, nsIFrame* aParentFrame)
: nsLeafFrame(aContent, aParentFrame)
{
#if 0
//lifted from nsRootPart.cpp. if we do this very much, factor it somehow. MMP
// Create a view
nsIFrame* parent;
nsIView* view;
GetParentWithView(parent);
NS_ASSERTION(parent, "GetParentWithView failed");
nsIView* parView;
parent->GetView(parView);
NS_ASSERTION(parView, "no parent with view");
// Create a view
static NS_DEFINE_IID(kViewCID, NS_VIEW_CID);
static NS_DEFINE_IID(kIViewIID, NS_IVIEW_IID);
nsresult result = NSRepository::CreateInstance(kViewCID,
nsnull,
kIViewIID,
(void **)&view);
if (NS_OK == result) {
nsIView* rootView = parView;
nsIViewManager* viewManager = rootView->GetViewManager();
// Initialize the view
NS_ASSERTION(nsnull != viewManager, "null view manager");
view->Init(viewManager, mRect, rootView);
viewManager->InsertChild(rootView, view, 0);
NS_RELEASE(viewManager);
// Remember our view
SetView(view);
NS_RELEASE(view);
}
NS_RELEASE(parView);
#endif
}
ImageFrame::~ImageFrame()

View File

@ -62,6 +62,7 @@ nsInputFrame::nsInputFrame(nsIContent* aContent, nsIFrame* aParentFrame)
: nsInputFrameSuper(aContent, aParentFrame)
{
mLastMouseState = eMouseNone;
mDidInit = PR_FALSE;
}
nsInputFrame::~nsInputFrame()
@ -138,16 +139,21 @@ nsInputFrame::Paint(nsIPresContext& aPresContext,
nsIView* view = nsnull;
GetView(view);
if (nsnull != view) {
SetViewVisiblity(&aPresContext, PR_TRUE);
if (PR_FALSE == mDidInit) {
((nsInput*)mContent)->GetFormManager()->Init(PR_FALSE);
PostCreateWidget(&aPresContext, view);
mDidInit = PR_TRUE;
}
// SetViewVisiblity(&aPresContext, PR_TRUE);
NS_RELEASE(view);
}
// Point borders/padding if any
return nsInputFrameSuper::Paint(aPresContext, aRenderingContext, aDirtyRect);
}
return NS_OK;
}
//don't call this. MMP
void
nsInputFrame::SetViewVisiblity(nsIPresContext* aPresContext, PRBool aShow)
{
@ -261,7 +267,7 @@ nsInputFrame::Reflow(nsIPresContext* aPresContext,
// initialize the view as hidden since we don't know the (x,y) until Paint
result = view->Init(viewMan, boundBox, parView, &id, initData,
nsnull, 0, nsnull,
1.0f, nsViewVisibility_kHide);
1.0f, nsViewVisibility_kShow);
if (nsnull != initData) {
delete(initData);
}
@ -297,7 +303,7 @@ nsInputFrame::Reflow(nsIPresContext* aPresContext,
// If we are being reflowed and have a view, hide the view until
// we are told to paint (which is when our location will have
// stabilized).
SetViewVisiblity(aPresContext, PR_FALSE);
// SetViewVisiblity(aPresContext, PR_FALSE);
}
aDesiredSize.ascent = aDesiredSize.height;

View File

@ -212,6 +212,7 @@ protected:
nsMouseState mLastMouseState;
nsSize mWidgetSize;
PRBool mDidInit;
};
#endif

View File

@ -851,7 +851,7 @@ void nsCSSRendering::PaintBackground(nsIPresContext& aPresContext,
PRIntn yPos = aColor.mBackgroundXPosition;
#endif
aRenderingContext.PushState();
aRenderingContext.SetClipRect(aDirtyRect, PR_TRUE);
aRenderingContext.SetClipRect(aDirtyRect, nsClipCombine_kIntersect);
PRIntn x, y;
for (y = 0; y <= ycount; ++y, ypos += tileHeight) {
for (x = 0, xpos = xpos0; x <= xcount; ++x, xpos += tileWidth) {

View File

@ -123,8 +123,12 @@ public:
* @param rc rendering context to paint into
* @param rect damage area
* @param aPaintFlags see nsIView.h for flag definitions
* @param aBackstop if we will need to do back to front
* painting, this is the view that, once rendered
* ends the back to front pass.
*/
virtual void Paint(nsIRenderingContext& rc, const nsRect& rect, PRUint32 aPaintFlags) = 0;
virtual void Paint(nsIRenderingContext& rc, const nsRect& rect,
PRUint32 aPaintFlags, nsIView *aBackstop = nsnull) = 0;
/**
* Called to indicate that the specified region of the view
@ -367,10 +371,15 @@ public:
//visibility state is set to inherit
#define NS_VIEW_FLAG_PARENT_HIDDEN 0x0001
//when painting, if we have determined that we need to do a combination
//of front to back and back to front painting, this flag will be set
//while in the back to front pass
#define NS_VIEW_FLAG_BACK_TO_FRONT 0x0002
//during event propagation, see if parent views can handle the event
#define NS_VIEW_FLAG_CHECK_PARENT 0x0002
#define NS_VIEW_FLAG_CHECK_PARENT 0x0004
//during event propagation, see if child views can handle the event
#define NS_VIEW_FLAG_CHECK_CHILDREN 0x0004
#define NS_VIEW_FLAG_CHECK_CHILDREN 0x0008
#endif

View File

@ -365,41 +365,28 @@ nsIWidget * nsView :: GetWidget()
return mWindow;
}
void nsView :: Paint(nsIRenderingContext& rc, const nsRect& rect, PRUint32 aPaintFlags)
void nsView :: Paint(nsIRenderingContext& rc, const nsRect& rect,
PRUint32 aPaintFlags, nsIView *aBackstop)
{
nsIView *pRoot = mViewManager->GetRootView();
rc.PushState();
if ((mClip.mLeft != mClip.mRight) && (mClip.mTop != mClip.mBottom))
{
rc.Translate(mBounds.x, mBounds.y);
nsRect crect;
crect.x = mClip.mLeft;
crect.y = mClip.mTop;
crect.x = mClip.mLeft + mBounds.x;
crect.y = mClip.mTop + mBounds.y;
crect.width = mClip.mRight - mClip.mLeft;
crect.height = mClip.mBottom - mClip.mTop;
rc.SetClipRect(crect, PR_TRUE);
rc.SetClipRect(crect, nsClipCombine_kIntersect);
}
else
{
nsIView *pRoot = mViewManager->GetRootView();
else if (this != pRoot)
rc.SetClipRect(mBounds, nsClipCombine_kIntersect);
if (this != pRoot)
rc.SetClipRect(mBounds, PR_TRUE);
NS_RELEASE(pRoot);
rc.Translate(mBounds.x, mBounds.y);
}
if (nsnull != mFrame)
{
nsIPresContext *cx = mViewManager->GetPresContext();
mFrame->Paint(*cx, rc, rect);
NS_RELEASE(cx);
}
rc.Translate(mBounds.x, mBounds.y);
//XXX maybe we should set this before we set the clip? MMP
@ -432,7 +419,39 @@ void nsView :: Paint(nsIRenderingContext& rc, const nsRect& rect, PRUint32 aPain
}
}
if ((mVis == nsViewVisibility_kShow) && (nsnull != mFrame))
{
nsIPresContext *cx = mViewManager->GetPresContext();
rc.PushState();
mFrame->Paint(*cx, rc, rect);
rc.PopState();
NS_RELEASE(cx);
}
rc.PopState();
//now we need to exclude this view from the rest of the
//paint process. only do this if this view is actually
//visible and if there is no widget (like a scrollbar) here.
if ((mVis == nsViewVisibility_kShow) && (nsnull == mWindow))
{
if ((mClip.mLeft != mClip.mRight) && (mClip.mTop != mClip.mBottom))
{
nsRect crect;
crect.x = mClip.mLeft + mBounds.x;
crect.y = mClip.mTop + mBounds.y;
crect.width = mClip.mRight - mClip.mLeft;
crect.height = mClip.mBottom - mClip.mTop;
rc.SetClipRect(crect, nsClipCombine_kSubtract);
}
else if (this != pRoot)
rc.SetClipRect(mBounds, nsClipCombine_kSubtract);
}
NS_RELEASE(pRoot);
}
void nsView :: Paint(nsIRenderingContext& rc, const nsIRegion& region, PRUint32 aPaintFlags)
@ -854,7 +873,7 @@ void nsView :: List(FILE* out, PRInt32 aIndent) const
for (PRInt32 i = aIndent; --i >= 0; ) fputs(" ", out);
fprintf(out, "%p win=%p ", this, mWindow);
out << mBounds;
fputs("<\n", out);
fprintf(out, " z=%d vis=%d opc=%1.3f <\n", mZindex, mVis, mOpacity);
nsIView* kid = mFirstChild;
while (nsnull != kid) {
kid->List(out, aIndent + 1);

View File

@ -56,7 +56,8 @@ public:
virtual void Destroy();
virtual nsIViewManager * GetViewManager();
virtual nsIWidget * GetWidget();
virtual void Paint(nsIRenderingContext& rc, const nsRect& rect, PRUint32 aPaintFlags);
virtual void Paint(nsIRenderingContext& rc, const nsRect& rect,
PRUint32 aPaintFlags, nsIView *aBackstop = nsnull);
virtual void Paint(nsIRenderingContext& rc, const nsIRegion& region, PRUint32 aPaintFlags);
virtual nsEventStatus HandleEvent(nsGUIEvent *event, PRUint32 aEventFlags);
virtual void SetPosition(nscoord x, nscoord y);

View File

@ -300,7 +300,7 @@ void nsViewManager :: Refresh(nsIView *aView, nsIRenderingContext *aContext, nsR
}
if (aUpdateFlags & NS_VMREFRESH_SCREEN_RECT)
localcx->SetClipRect(*rect, PR_FALSE);
localcx->SetClipRect(*rect, nsClipCombine_kReplace);
GetWindowOffsets(&xoff, &yoff);
@ -311,9 +311,11 @@ void nsViewManager :: Refresh(nsIView *aView, nsIRenderingContext *aContext, nsR
if (aUpdateFlags & NS_VMREFRESH_SCREEN_RECT)
trect.MoveBy(xoff, yoff);
else
localcx->SetClipRect(trect, PR_FALSE);
localcx->SetClipRect(trect, nsClipCombine_kReplace);
localcx->PushState();
aView->Paint(*localcx, trect, 0);
localcx->PopState();
if (aUpdateFlags & NS_VMREFRESH_DOUBLE_BUFFER)
localcx->CopyOffScreenBits(wrect);