fixed display of black or garbage when resizing scrolled scrollingviews.
git-svn-id: svn://10.0.0.236/trunk@15194 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
6f3d289878
commit
ddee55a0ed
@ -427,7 +427,7 @@ NS_IMETHODIMP nsScrollingView :: SetDimensions(nscoord width, nscoord height, PR
|
||||
//but unfortunately it will also cause scrollbar flashing. so long as
|
||||
//all resize operations happen through the viewmanager, this is not
|
||||
//an issue. we'll see. MMP
|
||||
// ComputeContainerSize();
|
||||
ComputeContainerSize();
|
||||
|
||||
NS_RELEASE(dx);
|
||||
return NS_OK;
|
||||
|
||||
@ -65,8 +65,17 @@ nsEventStatus PR_CALLBACK HandleEvent(nsGUIEvent *aEvent)
|
||||
return result;
|
||||
}
|
||||
|
||||
PRInt32 nsView::gNumViews = 0;
|
||||
PRInt32 nsView::gOffScreenWidth = 0;
|
||||
PRInt32 nsView::gOffScreenHeight = 0;
|
||||
nsDrawingSurface nsView::gOffScreen = nsnull;
|
||||
nsDrawingSurface nsView::gRedSurf = nsnull;
|
||||
nsDrawingSurface nsView::gBlueSurf = nsnull;
|
||||
|
||||
nsView :: nsView()
|
||||
{
|
||||
gNumViews++;
|
||||
|
||||
mVis = nsViewVisibility_kShow;
|
||||
mXForm = nsnull;
|
||||
mVFlags = ~ALL_VIEW_FLAGS;
|
||||
@ -137,7 +146,43 @@ nsView :: ~nsView()
|
||||
mWindow->Destroy();
|
||||
NS_RELEASE(mWindow);
|
||||
}
|
||||
|
||||
NS_IF_RELEASE(mDirtyRegion);
|
||||
|
||||
--gNumViews;
|
||||
|
||||
NS_ASSERTION(!(gNumViews < 0), "underflow of views");
|
||||
|
||||
if (0 == gNumViews)
|
||||
{
|
||||
nsIRenderingContext *rc;
|
||||
|
||||
static NS_DEFINE_IID(kRenderingContextCID, NS_RENDERING_CONTEXT_CID);
|
||||
static NS_DEFINE_IID(kIRenderingContextIID, NS_IRENDERING_CONTEXT_IID);
|
||||
|
||||
nsresult rv = nsRepository::CreateInstance(kRenderingContextCID,
|
||||
nsnull,
|
||||
kIRenderingContextIID,
|
||||
(void **)&rc);
|
||||
|
||||
if (NS_OK == rv)
|
||||
{
|
||||
if (nsnull != gOffScreen)
|
||||
rc->DestroyDrawingSurface(gOffScreen);
|
||||
|
||||
if (nsnull != gRedSurf)
|
||||
rc->DestroyDrawingSurface(gRedSurf);
|
||||
|
||||
if (nsnull != gBlueSurf)
|
||||
rc->DestroyDrawingSurface(gBlueSurf);
|
||||
|
||||
NS_RELEASE(rc);
|
||||
}
|
||||
|
||||
gOffScreen = nsnull;
|
||||
gRedSurf = nsnull;
|
||||
gBlueSurf = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult nsView :: QueryInterface(const nsIID& aIID, void** aInstancePtr)
|
||||
@ -255,12 +300,14 @@ NS_IMETHODIMP nsView :: Paint(nsIRenderingContext& rc, const nsRect& rect,
|
||||
PRBool clipres = PR_FALSE;
|
||||
PRBool clipwasset = PR_FALSE;
|
||||
float opacity;
|
||||
PRBool hasTransparency;
|
||||
|
||||
mViewManager->GetRootView(pRoot);
|
||||
|
||||
rc.PushState();
|
||||
|
||||
GetOpacity(opacity);
|
||||
HasTransparency(hasTransparency);
|
||||
|
||||
if (aPaintFlags & NS_VIEW_FLAG_CLIP_SET)
|
||||
{
|
||||
@ -269,8 +316,8 @@ NS_IMETHODIMP nsView :: Paint(nsIRenderingContext& rc, const nsRect& rect,
|
||||
}
|
||||
else if (mVis == nsViewVisibility_kShow)
|
||||
{
|
||||
if (opacity == 1.0f)
|
||||
{
|
||||
// if (!(aPaintFlags & (NS_VIEW_FLAG_FRONT_TO_BACK | NS_VIEW_FLAG_BACK_TO_FRONT)))
|
||||
// {
|
||||
nsRect brect;
|
||||
|
||||
GetBounds(brect);
|
||||
@ -288,7 +335,7 @@ NS_IMETHODIMP nsView :: Paint(nsIRenderingContext& rc, const nsRect& rect,
|
||||
}
|
||||
else if (this != pRoot)
|
||||
rc.SetClipRect(brect, nsClipCombine_kIntersect, clipres);
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
if (clipres == PR_FALSE)
|
||||
@ -370,15 +417,13 @@ NS_IMETHODIMP nsView :: Paint(nsIRenderingContext& rc, const nsRect& rect,
|
||||
if ((opacity > 0.0f) && (mBounds.width > 1) && (mBounds.height > 1))
|
||||
{
|
||||
nsIRenderingContext *localcx = nsnull;
|
||||
nsDrawingSurface surf = nsnull;
|
||||
nsDrawingSurface redsurf = nsnull;
|
||||
PRBool hasTransparency;
|
||||
PRBool clipState; //for when we want to throw away the clip state
|
||||
nsRect offscrRect = nsRect(0, 0, 0, 0);
|
||||
PRBool useBlueSurf = PR_FALSE;
|
||||
PRBool useBlendingSurfs = PR_FALSE;
|
||||
|
||||
rc.PushState();
|
||||
|
||||
HasTransparency(hasTransparency);
|
||||
|
||||
if (opacity < 1.0f)
|
||||
{
|
||||
nsIDeviceContext *dx = nsnull;
|
||||
@ -405,13 +450,20 @@ NS_IMETHODIMP nsView :: Paint(nsIRenderingContext& rc, const nsRect& rect,
|
||||
width = NSToCoordRound(mBounds.width * t2p);
|
||||
height = NSToCoordRound(mBounds.height * t2p);
|
||||
|
||||
nsRect bitrect = nsRect(0, 0, width, height);
|
||||
offscrRect = nsRect(0, 0, width, height);
|
||||
|
||||
localcx->CreateDrawingSurface(&bitrect, NS_CREATEDRAWINGSURFACE_FOR_PIXEL_ACCESS, surf);
|
||||
localcx->CreateDrawingSurface(&bitrect, NS_CREATEDRAWINGSURFACE_FOR_PIXEL_ACCESS, redsurf);
|
||||
CreateOffscreenSurfaces(*localcx, width, height);
|
||||
|
||||
if (nsnull != surf)
|
||||
localcx->SelectOffScreenDrawingSurface(surf);
|
||||
if ((PR_TRUE == hasTransparency) && (nsnull != gBlueSurf))
|
||||
useBlueSurf = PR_TRUE;
|
||||
|
||||
if (nsnull != gOffScreen)
|
||||
{
|
||||
localcx->SelectOffScreenDrawingSurface(gOffScreen);
|
||||
|
||||
if (nsnull != gRedSurf)
|
||||
useBlendingSurfs = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
NS_RELEASE(dx);
|
||||
@ -421,7 +473,8 @@ NS_IMETHODIMP nsView :: Paint(nsIRenderingContext& rc, const nsRect& rect,
|
||||
if (nsnull == localcx)
|
||||
localcx = &rc;
|
||||
|
||||
if (hasTransparency || (opacity < 1.0f))
|
||||
if (((PR_TRUE == hasTransparency) || (opacity < 1.0f)) &&
|
||||
!(aPaintFlags & (NS_VIEW_FLAG_FRONT_TO_BACK | NS_VIEW_FLAG_BACK_TO_FRONT)))
|
||||
{
|
||||
//overview of algorithm:
|
||||
//1. clip is set to intersection of this view and whatever is
|
||||
@ -566,9 +619,6 @@ NS_IMETHODIMP nsView :: Paint(nsIRenderingContext& rc, const nsRect& rect,
|
||||
localcx->PopState(clipState);
|
||||
}
|
||||
|
||||
if (nsnull != redsurf)
|
||||
localcx->SelectOffScreenDrawingSurface(redsurf);
|
||||
|
||||
//now draw ourself...
|
||||
|
||||
if (nsnull != mClientData)
|
||||
@ -577,14 +627,35 @@ NS_IMETHODIMP nsView :: Paint(nsIRenderingContext& rc, const nsRect& rect,
|
||||
|
||||
if (NS_OK == mViewManager->GetViewObserver(obs))
|
||||
{
|
||||
if (nsnull != gRedSurf)
|
||||
{
|
||||
localcx->SelectOffScreenDrawingSurface(gRedSurf);
|
||||
|
||||
if (PR_TRUE == useBlueSurf)
|
||||
{
|
||||
localcx->SetColor(NS_RGB(255, 0, 0));
|
||||
localcx->FillRect(0, 0, mBounds.width, mBounds.height);
|
||||
}
|
||||
}
|
||||
|
||||
obs->Paint((nsIView *)this, *localcx, rect);
|
||||
|
||||
if (PR_TRUE == useBlueSurf)
|
||||
{
|
||||
localcx->SelectOffScreenDrawingSurface(gBlueSurf);
|
||||
|
||||
localcx->SetColor(NS_RGB(0, 0, 255));
|
||||
localcx->FillRect(0, 0, mBounds.width, mBounds.height);
|
||||
|
||||
obs->Paint((nsIView *)this, *localcx, rect);
|
||||
}
|
||||
|
||||
NS_RELEASE(obs);
|
||||
}
|
||||
}
|
||||
|
||||
if (localcx != &rc)
|
||||
{
|
||||
// localcx->SelectOffScreenDrawingSurface(nsnull);
|
||||
NS_RELEASE(localcx);
|
||||
}
|
||||
else
|
||||
@ -592,7 +663,7 @@ NS_IMETHODIMP nsView :: Paint(nsIRenderingContext& rc, const nsRect& rect,
|
||||
|
||||
//kill offscreen buffer
|
||||
|
||||
if ((nsnull != surf) && (nsnull != redsurf))
|
||||
if (PR_TRUE == useBlendingSurfs)
|
||||
{
|
||||
nsRect brect;
|
||||
|
||||
@ -614,29 +685,17 @@ NS_IMETHODIMP nsView :: Paint(nsIRenderingContext& rc, const nsRect& rect,
|
||||
|
||||
mViewManager->GetDeviceContext(dx);
|
||||
|
||||
float t2p;
|
||||
nscoord width, height;
|
||||
|
||||
dx->GetAppUnitsToDevUnits(t2p);
|
||||
|
||||
width = NSToCoordRound(mBounds.width * t2p);
|
||||
height = NSToCoordRound(mBounds.height * t2p);
|
||||
|
||||
blender->Init(dx);
|
||||
blender->Blend(0, 0, width, height,surf,redsurf, 0, 0, opacity, PR_FALSE);
|
||||
blender->Blend(0, 0, offscrRect.width, offscrRect.height, gRedSurf,
|
||||
gOffScreen, 0, 0, opacity, PR_FALSE,
|
||||
(PR_TRUE == useBlueSurf) ? gBlueSurf : nsnull,
|
||||
NS_RGB(255, 0, 0), NS_RGB(0, 0, 255));
|
||||
|
||||
NS_RELEASE(blender);
|
||||
NS_RELEASE(dx);
|
||||
|
||||
// rc.CopyOffScreenBits(surf, 0, 0, brect, NS_COPYBITS_XFORM_DEST_VALUES | NS_COPYBITS_TO_BACK_BUFFER);
|
||||
rc.CopyOffScreenBits(redsurf, 0, 0, brect, NS_COPYBITS_XFORM_DEST_VALUES | NS_COPYBITS_TO_BACK_BUFFER);
|
||||
rc.CopyOffScreenBits(gOffScreen, 0, 0, brect, NS_COPYBITS_XFORM_DEST_VALUES | NS_COPYBITS_TO_BACK_BUFFER);
|
||||
}
|
||||
|
||||
rc.DestroyDrawingSurface(surf);
|
||||
rc.DestroyDrawingSurface(redsurf);
|
||||
|
||||
surf = nsnull;
|
||||
redsurf = nsnull;
|
||||
}
|
||||
|
||||
#ifdef SHOW_VIEW_BORDERS
|
||||
@ -679,9 +738,10 @@ NS_IMETHODIMP nsView :: Paint(nsIRenderingContext& rc, const nsRect& rect,
|
||||
//paint process. only do this if this view is actually
|
||||
//visible and if there is no widget (like a scrollbar) here.
|
||||
|
||||
if (!clipwasset && (clipres == PR_FALSE) &&
|
||||
if ((PR_FALSE == clipwasset) && (PR_FALSE == clipres) &&
|
||||
(mVis == nsViewVisibility_kShow) && (nsnull == mWindow) &&
|
||||
(opacity > 0.0f))
|
||||
(((opacity == 1.0f) && (PR_FALSE == hasTransparency)) ||
|
||||
!(aPaintFlags & (NS_VIEW_FLAG_BACK_TO_FRONT | NS_VIEW_FLAG_BACK_TO_FRONT))))
|
||||
{
|
||||
nsRect brect;
|
||||
|
||||
@ -1288,3 +1348,43 @@ NS_IMETHODIMP nsView :: SetDirtyRegion(nsIRegion *aRegion)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifndef NS_MAX
|
||||
#define NS_MAX(x, y) (((x) > (y)) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
nsresult nsView ::CreateOffscreenSurfaces(nsIRenderingContext &aRC, PRInt32 aWidth, PRInt32 aHeight)
|
||||
{
|
||||
nsresult res = NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
if ((aWidth > gOffScreenWidth) || (aHeight > gOffScreenHeight))
|
||||
{
|
||||
if (nsnull != gOffScreen)
|
||||
aRC.DestroyDrawingSurface(gOffScreen);
|
||||
|
||||
if (nsnull != gRedSurf)
|
||||
aRC.DestroyDrawingSurface(gRedSurf);
|
||||
|
||||
if (nsnull != gBlueSurf)
|
||||
aRC.DestroyDrawingSurface(gBlueSurf);
|
||||
|
||||
gOffScreen = nsnull;
|
||||
gRedSurf = nsnull;
|
||||
gBlueSurf = nsnull;
|
||||
|
||||
gOffScreenWidth = NS_MAX(aWidth, gOffScreenWidth);
|
||||
gOffScreenHeight = NS_MAX(aHeight, gOffScreenHeight);
|
||||
|
||||
nsRect trect = nsRect(0, 0, gOffScreenWidth, gOffScreenHeight);
|
||||
|
||||
aRC.CreateDrawingSurface(&trect, NS_CREATEDRAWINGSURFACE_FOR_PIXEL_ACCESS, gOffScreen);
|
||||
aRC.CreateDrawingSurface(&trect, NS_CREATEDRAWINGSURFACE_FOR_PIXEL_ACCESS, gRedSurf);
|
||||
aRC.CreateDrawingSurface(&trect, NS_CREATEDRAWINGSURFACE_FOR_PIXEL_ACCESS, gBlueSurf);
|
||||
|
||||
if ((nsnull != gOffScreen) && (nsnull != gRedSurf) && (nsnull != gBlueSurf))
|
||||
res = NS_OK;
|
||||
}
|
||||
else
|
||||
res = NS_OK;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -102,8 +102,8 @@ public:
|
||||
|
||||
protected:
|
||||
virtual ~nsView();
|
||||
//
|
||||
virtual nsresult LoadWidget(const nsCID &aClassIID);
|
||||
nsresult CreateOffscreenSurfaces(nsIRenderingContext &aRC, PRInt32 aWidth, PRInt32 aHeight);
|
||||
|
||||
protected:
|
||||
nsIViewManager *mViewManager;
|
||||
@ -124,6 +124,16 @@ protected:
|
||||
PRInt32 mVFlags;
|
||||
nsIRegion* mDirtyRegion;
|
||||
|
||||
public:
|
||||
//globals
|
||||
|
||||
static PRInt32 gNumViews;
|
||||
static PRInt32 gOffScreenWidth;
|
||||
static PRInt32 gOffScreenHeight;
|
||||
static nsDrawingSurface gOffScreen;
|
||||
static nsDrawingSurface gRedSurf;
|
||||
static nsDrawingSurface gBlueSurf;
|
||||
|
||||
private:
|
||||
NS_IMETHOD_(nsrefcnt) AddRef(void);
|
||||
NS_IMETHOD_(nsrefcnt) Release(void);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user