mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 14:22:01 +00:00
added Get/SetScrollableRoot() to nsIViewManager. fixed bug where maximizing
window would cause junk to be shown below/to the right of the real content if the document was scrolled towards bottom/right. fixed flashing scrollbar problem. made quality control work again.
This commit is contained in:
parent
6992018f6f
commit
f8b4bc0d49
@ -28,6 +28,7 @@ class nsIRegion;
|
||||
class nsIEvent;
|
||||
class nsIPresContext;
|
||||
class nsIView;
|
||||
class nsIScrollableView;
|
||||
class nsIWidget;
|
||||
struct nsRect;
|
||||
|
||||
@ -355,6 +356,22 @@ public:
|
||||
*/
|
||||
NS_IMETHOD EnableRefresh(void) = 0;
|
||||
|
||||
/**
|
||||
* set the view that is is considered to be the root scrollable
|
||||
* view for the document.
|
||||
* @param aScrollable root scrollable view
|
||||
* @return error status
|
||||
*/
|
||||
NS_IMETHOD SetRootScrollableView(nsIScrollableView *aScrollable) = 0;
|
||||
|
||||
/**
|
||||
* get the view that is is considered to be the root scrollable
|
||||
* view for the document.
|
||||
* @param aScrollable out parameter for root scrollable view
|
||||
* @return error status
|
||||
*/
|
||||
NS_IMETHOD GetRootScrollableView(nsIScrollableView **aScrollable) = 0;
|
||||
|
||||
/**
|
||||
* Display the specified view. Used when printing.
|
||||
*/
|
||||
|
@ -152,7 +152,7 @@ public:
|
||||
NS_IMETHOD Paint(nsIRenderingContext& rc, const nsRect& rect,
|
||||
PRUint32 aPaintFlags, PRBool &Result);
|
||||
|
||||
void Show(PRBool aShow);
|
||||
void Show(PRBool aShow, PRBool aRethink);
|
||||
|
||||
PRBool mShowQuality;
|
||||
nsContentQuality mQuality;
|
||||
@ -181,17 +181,15 @@ NS_IMETHODIMP CornerView :: ShowQuality(PRBool aShow)
|
||||
|
||||
if (mShow == PR_FALSE)
|
||||
{
|
||||
if (mVis == nsViewVisibility_kShow)
|
||||
if (mShowQuality == PR_FALSE)
|
||||
mViewManager->SetViewVisibility(this, nsViewVisibility_kHide);
|
||||
else
|
||||
mViewManager->SetViewVisibility(this, nsViewVisibility_kShow);
|
||||
|
||||
nscoord dimx, dimy;
|
||||
nsIScrollableView *par;
|
||||
|
||||
//this will force the scrolling view to recalc the scrollbar sizes... MMP
|
||||
|
||||
mParent->GetDimensions(&dimx, &dimy);
|
||||
mParent->SetDimensions(dimx, dimy);
|
||||
if (NS_OK == mParent->QueryInterface(kIScrollableViewIID, (void **)&par))
|
||||
par->ComputeContainerSize();
|
||||
}
|
||||
|
||||
mViewManager->UpdateView(this, nsnull, NS_VMREFRESH_IMMEDIATE);
|
||||
@ -211,7 +209,7 @@ NS_IMETHODIMP CornerView :: SetQuality(nsContentQuality aQuality)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void CornerView :: Show(PRBool aShow)
|
||||
void CornerView :: Show(PRBool aShow, PRBool aRethink)
|
||||
{
|
||||
if (mShow != aShow)
|
||||
{
|
||||
@ -222,12 +220,13 @@ void CornerView :: Show(PRBool aShow)
|
||||
else if (mShowQuality == PR_FALSE)
|
||||
mViewManager->SetViewVisibility(this, nsViewVisibility_kHide);
|
||||
|
||||
nscoord dimx, dimy;
|
||||
if (PR_TRUE == aRethink)
|
||||
{
|
||||
nsIScrollableView *par;
|
||||
|
||||
//this will force the scrolling view to recalc the scrollbar sizes... MMP
|
||||
|
||||
mParent->GetDimensions(&dimx, &dimy);
|
||||
mParent->SetDimensions(dimx, dimy);
|
||||
if (NS_OK == mParent->QueryInterface(kIScrollableViewIID, (void **)&par))
|
||||
par->ComputeContainerSize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -403,9 +402,19 @@ NS_IMETHODIMP nsScrollingView :: SetDimensions(nscoord width, nscoord height, PR
|
||||
// Set our bounds and size our widget if we have one
|
||||
nsView::SetDimensions(width, height, aPaint);
|
||||
|
||||
#if 0
|
||||
//this will fix the size of the thumb when we resize the root window,
|
||||
//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();
|
||||
#endif
|
||||
|
||||
// Determine how much space is actually taken up by the scrollbars
|
||||
if (mHScrollBarView && ViewIsShowing(mHScrollBarView))
|
||||
showHorz = NSToCoordRound(scrollHeight);
|
||||
|
||||
if (mVScrollBarView && ViewIsShowing(mVScrollBarView))
|
||||
showVert = NSToCoordRound(scrollWidth);
|
||||
|
||||
@ -413,12 +422,6 @@ NS_IMETHODIMP nsScrollingView :: SetDimensions(nscoord width, nscoord height, PR
|
||||
clipRect.SetRect(0, 0, width - showVert, height - showHorz);
|
||||
clipRect.Deflate(mInsets);
|
||||
|
||||
//this will fix the size of the thumb when we resize the root window,
|
||||
//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();
|
||||
|
||||
// Size and position the clip view
|
||||
if (nsnull != mClipView)
|
||||
mClipView->SetBounds(clipRect, aPaint);
|
||||
@ -929,6 +932,7 @@ NS_IMETHODIMP nsScrollingView :: ComputeContainerSize()
|
||||
nscoord offx, offy;
|
||||
float scale;
|
||||
nsRect controlRect(0, 0, mBounds.width, mBounds.height);
|
||||
|
||||
controlRect.Deflate(mInsets);
|
||||
|
||||
mViewManager->GetDeviceContext(px);
|
||||
@ -978,23 +982,34 @@ NS_IMETHODIMP nsScrollingView :: ComputeContainerSize()
|
||||
//now update the scroller position for the new size
|
||||
|
||||
PRUint32 oldpos = 0;
|
||||
scrollv->GetPosition(oldpos);
|
||||
float p2t;
|
||||
PRInt32 availheight;
|
||||
|
||||
scrollv->GetPosition(oldpos);
|
||||
px->GetDevUnitsToAppUnits(p2t);
|
||||
|
||||
availheight = controlRect.height - ((nsnull != scrollh) ? hheight : 0);
|
||||
|
||||
// XXX Check for 0 initial size. This is really indicative
|
||||
// of a problem.
|
||||
if (0 == oldsizey) {
|
||||
if (0 == oldsizey)
|
||||
mOffsetY = 0;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
mOffsetY = NSIntPixelsToTwips(NSTwipsToIntPixels(nscoord(((float)oldpos * mSizeY) / oldsizey), scale), p2t);
|
||||
|
||||
if ((mSizeY - mOffsetY) < availheight)
|
||||
{
|
||||
mOffsetY = mSizeY - availheight;
|
||||
|
||||
if (mOffsetY < 0)
|
||||
mOffsetY = 0;
|
||||
}
|
||||
}
|
||||
|
||||
dy = NSTwipsToIntPixels((offy - mOffsetY), scale);
|
||||
|
||||
scrollv->SetParameters(mSizeY, controlRect.height - ((nsnull != scrollh) ? hheight : 0),
|
||||
scrollv->SetParameters(mSizeY, availheight,
|
||||
mOffsetY, NSIntPointsToTwips(12));
|
||||
}
|
||||
else
|
||||
@ -1005,6 +1020,7 @@ NS_IMETHODIMP nsScrollingView :: ComputeContainerSize()
|
||||
dy = NSTwipsToIntPixels(offy, scale);
|
||||
|
||||
scrollv->SetPosition(0); // make sure thumb is at the top
|
||||
|
||||
if (mScrollPref == nsScrollPreference_kAlwaysScroll)
|
||||
{
|
||||
mVScrollBarView->SetVisibility(nsViewVisibility_kShow);
|
||||
@ -1045,29 +1061,35 @@ NS_IMETHODIMP nsScrollingView :: ComputeContainerSize()
|
||||
//now update the scroller position for the new size
|
||||
|
||||
PRUint32 oldpos = 0;
|
||||
scrollh->GetPosition(oldpos);
|
||||
float p2t;
|
||||
PRInt32 availwidth;
|
||||
|
||||
scrollh->GetPosition(oldpos);
|
||||
px->GetDevUnitsToAppUnits(p2t);
|
||||
|
||||
availwidth = controlRect.width - ((nsnull != scrollv) ? vwidth : 0);
|
||||
|
||||
// XXX Check for 0 initial size. This is really indicative
|
||||
// of a problem.
|
||||
if (0 == oldsizex) {
|
||||
if (0 == oldsizex)
|
||||
mOffsetX = 0;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
mOffsetX = NSIntPixelsToTwips(NSTwipsToIntPixels(nscoord(((float)oldpos * mSizeX) / oldsizex), scale), p2t);
|
||||
|
||||
if ((mSizeX - mOffsetX) < availwidth)
|
||||
{
|
||||
mOffsetX = mSizeX - availwidth;
|
||||
|
||||
if (mOffsetX < 0)
|
||||
mOffsetX = 0;
|
||||
}
|
||||
}
|
||||
|
||||
dx = NSTwipsToIntPixels((offx - mOffsetX), scale);
|
||||
|
||||
scrollh->SetParameters(mSizeX, controlRect.width - ((nsnull != scrollv) ? vwidth : 0),
|
||||
scrollh->SetParameters(mSizeX, availwidth,
|
||||
mOffsetX, NSIntPointsToTwips(12));
|
||||
|
||||
// //now make the vertical scroll region account for this scrollbar
|
||||
//
|
||||
// if (nsnull != scrollv)
|
||||
// scrollv->SetParameters(mSizeY, mBounds.height - hheight, mOffsetY, NSIntPointsToTwips(12));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1077,6 +1099,7 @@ NS_IMETHODIMP nsScrollingView :: ComputeContainerSize()
|
||||
dx = NSTwipsToIntPixels(offx, scale);
|
||||
|
||||
scrollh->SetPosition(0); // make sure thumb is all the way to the left
|
||||
|
||||
if (mScrollPref == nsScrollPreference_kAlwaysScroll)
|
||||
{
|
||||
mHScrollBarView->SetVisibility(nsViewVisibility_kShow);
|
||||
@ -1112,9 +1135,9 @@ NS_IMETHODIMP nsScrollingView :: ComputeContainerSize()
|
||||
{
|
||||
if (mHScrollBarView && ViewIsShowing(mHScrollBarView) &&
|
||||
mVScrollBarView && ViewIsShowing(mVScrollBarView))
|
||||
((CornerView *)mCornerView)->Show(PR_TRUE);
|
||||
((CornerView *)mCornerView)->Show(PR_TRUE, PR_FALSE);
|
||||
else
|
||||
((CornerView *)mCornerView)->Show(PR_FALSE);
|
||||
((CornerView *)mCornerView)->Show(PR_FALSE, PR_FALSE);
|
||||
}
|
||||
|
||||
// now we can release the vertical scroller if there was one...
|
||||
@ -1156,7 +1179,7 @@ NS_IMETHODIMP nsScrollingView :: ComputeContainerSize()
|
||||
}
|
||||
|
||||
if (nsnull != mCornerView)
|
||||
((CornerView *)mCornerView)->Show(PR_FALSE);
|
||||
((CornerView *)mCornerView)->Show(PR_FALSE, PR_FALSE);
|
||||
|
||||
mOffsetX = mOffsetY = 0;
|
||||
mSizeX = mSizeY = 0;
|
||||
@ -1367,40 +1390,72 @@ void nsScrollingView :: AdjustChildWidgets(nsScrollingView *aScrolling, nsIView
|
||||
void nsScrollingView :: UpdateScrollControls(PRBool aPaint)
|
||||
{
|
||||
nsRect clipRect;
|
||||
nsSize cornerSize = nsSize(0, 0);
|
||||
nsSize visCornerSize = nsSize(0, 0);
|
||||
nsPoint cornerPos = nsPoint(0, 0);
|
||||
nsViewVisibility vertVis = nsViewVisibility_kHide;
|
||||
nsViewVisibility horzVis = nsViewVisibility_kHide;
|
||||
|
||||
if (nsnull != mClipView)
|
||||
{
|
||||
mClipView->GetBounds(clipRect);
|
||||
|
||||
// Position the corner view
|
||||
if (nsnull != mVScrollBarView)
|
||||
mVScrollBarView->GetVisibility(vertVis);
|
||||
|
||||
if (nsnull != mHScrollBarView)
|
||||
mHScrollBarView->GetVisibility(horzVis);
|
||||
|
||||
if (nsnull != mCornerView)
|
||||
{
|
||||
nsSize cornerSize;
|
||||
nsViewVisibility cornerVis;
|
||||
|
||||
mCornerView->GetDimensions(&cornerSize.width, &cornerSize.height);
|
||||
mCornerView->SetBounds(clipRect.XMost(), clipRect.YMost(), cornerSize.width,
|
||||
cornerSize.height, aPaint);
|
||||
mCornerView->GetVisibility(cornerVis);
|
||||
|
||||
if (cornerVis == nsViewVisibility_kShow)
|
||||
visCornerSize = cornerSize;
|
||||
|
||||
if (vertVis == nsViewVisibility_kShow)
|
||||
visCornerSize.width = 0;
|
||||
|
||||
if (horzVis == nsViewVisibility_kShow)
|
||||
visCornerSize.height = 0;
|
||||
}
|
||||
|
||||
// Size and position the vertical scrollbar
|
||||
if (nsnull != mVScrollBarView)
|
||||
{
|
||||
nsSize sbSize;
|
||||
nsSize vertSize;
|
||||
|
||||
mVScrollBarView->GetDimensions(&sbSize.width, &sbSize.height);
|
||||
mVScrollBarView->SetBounds(clipRect.XMost(), clipRect.y, sbSize.width,
|
||||
clipRect.height, aPaint);
|
||||
mVScrollBarView->GetDimensions(&vertSize.width, &vertSize.height);
|
||||
mVScrollBarView->SetBounds(clipRect.XMost(), clipRect.y, vertSize.width,
|
||||
clipRect.height - visCornerSize.height, aPaint);
|
||||
|
||||
if (vertVis == nsViewVisibility_kShow)
|
||||
cornerPos.x = clipRect.XMost();
|
||||
else
|
||||
cornerPos.x = clipRect.XMost() - cornerSize.width;
|
||||
}
|
||||
|
||||
// Size and position the horizontal scrollbar
|
||||
if (nsnull != mHScrollBarView)
|
||||
{
|
||||
nsSize sbSize;
|
||||
|
||||
mHScrollBarView->GetDimensions(&sbSize.width, &sbSize.height);
|
||||
mHScrollBarView->SetBounds(clipRect.x, clipRect.YMost(), clipRect.width,
|
||||
sbSize.height, aPaint);
|
||||
nsSize horzSize;
|
||||
|
||||
mHScrollBarView->GetDimensions(&horzSize.width, &horzSize.height);
|
||||
mHScrollBarView->SetBounds(clipRect.x, clipRect.YMost(), clipRect.width - visCornerSize.width,
|
||||
horzSize.height, aPaint);
|
||||
|
||||
if (horzVis == nsViewVisibility_kShow)
|
||||
cornerPos.y = clipRect.YMost();
|
||||
else
|
||||
cornerPos.y = clipRect.YMost() - cornerSize.height;
|
||||
}
|
||||
|
||||
// Position the corner view
|
||||
if (nsnull != mCornerView)
|
||||
mCornerView->SetPosition(cornerPos.x, cornerPos.y);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -875,6 +875,7 @@ NS_IMETHODIMP nsView :: SetDimensions(nscoord width, nscoord height, PRBool aPai
|
||||
{
|
||||
mBounds.SizeTo(width, height);
|
||||
|
||||
#if 0
|
||||
if (nsnull != mParent)
|
||||
{
|
||||
nsIScrollableView *scroller;
|
||||
@ -892,6 +893,7 @@ NS_IMETHODIMP nsView :: SetDimensions(nscoord width, nscoord height, PRBool aPai
|
||||
scroller->ComputeContainerSize();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (nsnull != mWindow)
|
||||
{
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "nsIRegion.h"
|
||||
#include "nsView.h"
|
||||
#include "nsIScrollbar.h"
|
||||
#include "nsIBlender.h"
|
||||
|
||||
static NS_DEFINE_IID(kIScrollableViewIID, NS_ISCROLLABLEVIEW_IID);
|
||||
static NS_DEFINE_IID(kIScrollbarIID, NS_ISCROLLBAR_IID);
|
||||
@ -37,6 +38,8 @@ static const PRBool gsDebug = PR_FALSE;
|
||||
//#define NO_DOUBLE_BUFFER
|
||||
//#define NEW_COMPOSITOR
|
||||
|
||||
#define FLATVIEW_INC 3
|
||||
|
||||
static void vm_timer_callback(nsITimer *aTimer, void *aClosure)
|
||||
{
|
||||
nsViewManager *vm = (nsViewManager *)aClosure;
|
||||
@ -81,11 +84,15 @@ nsViewManager :: ~nsViewManager()
|
||||
|
||||
NS_IF_RELEASE(mRootWindow);
|
||||
|
||||
mRootScrollable = nsnull;
|
||||
|
||||
--mVMCount;
|
||||
|
||||
NS_ASSERTION(!(mVMCount < 0), "underflow of viewmanagers");
|
||||
|
||||
if ((0 == mVMCount) && (nsnull != mDrawingSurface))
|
||||
if ((0 == mVMCount) &&
|
||||
((nsnull != mDrawingSurface) || (nsnull != gOffScreen) ||
|
||||
(nsnull != gRed) || (nsnull != gBlue)))
|
||||
{
|
||||
nsIRenderingContext *rc;
|
||||
|
||||
@ -99,11 +106,25 @@ nsViewManager :: ~nsViewManager()
|
||||
|
||||
if (NS_OK == rv)
|
||||
{
|
||||
rc->DestroyDrawingSurface(mDrawingSurface);
|
||||
if (nsnull != mDrawingSurface)
|
||||
rc->DestroyDrawingSurface(mDrawingSurface);
|
||||
|
||||
if (nsnull != gOffScreen)
|
||||
rc->DestroyDrawingSurface(gOffScreen);
|
||||
|
||||
if (nsnull != gRed)
|
||||
rc->DestroyDrawingSurface(gRed);
|
||||
|
||||
if (nsnull != gBlue)
|
||||
rc->DestroyDrawingSurface(gBlue);
|
||||
|
||||
NS_RELEASE(rc);
|
||||
}
|
||||
|
||||
mDrawingSurface = nsnull;
|
||||
gOffScreen = nsnull;
|
||||
gRed = nsnull;
|
||||
gBlue = nsnull;
|
||||
}
|
||||
|
||||
mObserver = nsnull;
|
||||
@ -113,7 +134,7 @@ nsViewManager :: ~nsViewManager()
|
||||
{
|
||||
PRInt32 cnt = mFlatViews->Count(), idx;
|
||||
|
||||
for (idx = 1; idx < cnt; idx += 2)
|
||||
for (idx = 1; idx < cnt; idx += FLATVIEW_INC)
|
||||
{
|
||||
nsRect *rect = (nsRect *)mFlatViews->ElementAt(idx);
|
||||
|
||||
@ -452,19 +473,51 @@ void nsViewManager :: Refresh(nsIView *aView, nsIRenderingContext *aContext, con
|
||||
mPainting = PR_FALSE;
|
||||
}
|
||||
|
||||
//states
|
||||
#define FRONT_TO_BACK_RENDER 1
|
||||
#define FRONT_TO_BACK_ACCUMULATE 2
|
||||
#define BACK_TO_FRONT_TRANS 3
|
||||
#define BACK_TO_FRONT_OPACITY 4
|
||||
#define COMPOSITION_DONE 5
|
||||
|
||||
//bit shifts
|
||||
#define TRANS_PROPERTY_TRANS 0
|
||||
#define TRANS_PROPERTY_OPACITY 1
|
||||
|
||||
//flat view flags
|
||||
#define VIEW_INCLUDED 0x0001
|
||||
|
||||
void nsViewManager :: RenderViews(nsIView *aRootView, nsIRenderingContext& aRC, const nsRect& aRect, PRBool &aResult)
|
||||
{
|
||||
#ifdef NEW_COMPOSITOR
|
||||
|
||||
PRInt32 flatlen = 0, cnt;
|
||||
PRInt32 flatlen = 0, cnt;
|
||||
PRInt32 state = FRONT_TO_BACK_RENDER;
|
||||
PRInt32 transprop;
|
||||
nsRect backfrontrect;
|
||||
nsRect accumrect;
|
||||
PRInt32 increment = FLATVIEW_INC;
|
||||
PRInt32 loopstart = 0;
|
||||
PRInt32 loopend;
|
||||
PRInt32 accumstart;
|
||||
float t2p;
|
||||
nsDrawingSurface origsurf;
|
||||
nsIRegion *transrgn = nsnull;
|
||||
nsIRegion *temprgn = nsnull;
|
||||
nsIRegion *rcrgn = nsnull;
|
||||
|
||||
if (nsnull != aRootView)
|
||||
FlattenViewTree(aRootView, &flatlen);
|
||||
FlattenViewTree(aRootView, &flatlen, &aRect);
|
||||
|
||||
loopend = flatlen;
|
||||
|
||||
mContext->GetAppUnitsToDevUnits(t2p);
|
||||
aRC.GetDrawingSurface(&origsurf);
|
||||
|
||||
#if 0
|
||||
printf("flatlen %d\n", flatlen);
|
||||
|
||||
for (cnt = 0; cnt < flatlen; cnt += 2)
|
||||
for (cnt = 0; cnt < flatlen; cnt += FLATVIEW_INC)
|
||||
{
|
||||
nsRect *rect;
|
||||
printf("view: %x\n", mFlatViews->ElementAt(cnt));
|
||||
@ -478,57 +531,229 @@ for (cnt = 0; cnt < flatlen; cnt += 2)
|
||||
}
|
||||
#endif
|
||||
|
||||
for (cnt = 0; cnt < flatlen; cnt += 2)
|
||||
while (state != COMPOSITION_DONE)
|
||||
{
|
||||
nsIView *curview = (nsIView *)mFlatViews->ElementAt(cnt);
|
||||
nsRect *currect = (nsRect *)mFlatViews->ElementAt(cnt + 1);
|
||||
|
||||
if ((nsnull != curview) && (nsnull != currect))
|
||||
for (cnt = loopstart; (increment > 0) ? (cnt < loopend) : (cnt > loopend); cnt += increment)
|
||||
{
|
||||
nsIWidget *widget;
|
||||
PRBool hasWidget = PR_FALSE;
|
||||
|
||||
curview->GetWidget(widget);
|
||||
|
||||
if (nsnull != widget)
|
||||
nsIView *curview = (nsIView *)mFlatViews->ElementAt(cnt);
|
||||
nsRect *currect = (nsRect *)mFlatViews->ElementAt(cnt + 1);
|
||||
PRUint32 curflags = (PRUint32)mFlatViews->ElementAt(cnt + 2);
|
||||
|
||||
if ((nsnull != curview) && (nsnull != currect))
|
||||
{
|
||||
void *nativewidget;
|
||||
PRBool hasWidget = DoesViewHaveNativeWidget(*curview);
|
||||
|
||||
nativewidget = widget->GetNativeData(NS_NATIVE_WIDGET);
|
||||
if ((PR_FALSE == hasWidget) || ((PR_TRUE == hasWidget) && (cnt == (flatlen - FLATVIEW_INC))))
|
||||
{
|
||||
PRBool trans;
|
||||
float opacity;
|
||||
|
||||
NS_RELEASE(widget);
|
||||
curview->HasTransparency(trans);
|
||||
curview->GetOpacity(opacity);
|
||||
|
||||
if (nsnull != nativewidget)
|
||||
hasWidget = PR_TRUE;
|
||||
switch (state)
|
||||
{
|
||||
default:
|
||||
case FRONT_TO_BACK_RENDER:
|
||||
if ((PR_TRUE == trans) || (opacity < 1.0f))
|
||||
{
|
||||
//need to finish using back to front till this point
|
||||
transprop = (trans << TRANS_PROPERTY_TRANS) | ((opacity < 1.0f) << TRANS_PROPERTY_OPACITY);
|
||||
backfrontrect = accumrect = *currect;
|
||||
state = FRONT_TO_BACK_ACCUMULATE;
|
||||
accumstart = cnt;
|
||||
mFlatViews->ReplaceElementAt((void *)VIEW_INCLUDED, cnt + 2);
|
||||
|
||||
//get a snapshot of the current clip so that we can exclude areas
|
||||
//already excluded in it from the transparency region
|
||||
aRC.GetClipRegion(&rcrgn);
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
RenderView(curview, aRC, aRect, *currect, aResult);
|
||||
|
||||
if (aResult == PR_FALSE)
|
||||
aRC.SetClipRect(*currect, nsClipCombine_kSubtract, aResult);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case FRONT_TO_BACK_ACCUMULATE:
|
||||
if ((PR_TRUE == backfrontrect.Intersects(*currect)) &&
|
||||
((PR_TRUE == trans) || (opacity < 1.0f)))
|
||||
{
|
||||
transprop |= (trans << TRANS_PROPERTY_TRANS) | ((opacity < 1.0f) << TRANS_PROPERTY_OPACITY);
|
||||
accumrect.UnionRect(*currect, accumrect);
|
||||
mFlatViews->ReplaceElementAt((void *)VIEW_INCLUDED, cnt + 2);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case BACK_TO_FRONT_TRANS:
|
||||
if (PR_TRUE == accumrect.Intersects(*currect))
|
||||
{
|
||||
PRBool clipstate;
|
||||
|
||||
RenderView(curview, aRC, aRect, *currect, clipstate);
|
||||
|
||||
//if this view is transparent, it has been accounted
|
||||
//for, so we never have to look at it again.
|
||||
if ((PR_TRUE == trans) && (curflags & VIEW_INCLUDED))
|
||||
{
|
||||
mFlatViews->ReplaceElementAt(nsnull, cnt);
|
||||
mFlatViews->ReplaceElementAt(nsnull, cnt + 2);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case BACK_TO_FRONT_OPACITY:
|
||||
if (PR_TRUE == accumrect.Intersects(*currect))
|
||||
{
|
||||
PRBool clipstate;
|
||||
|
||||
if (opacity == 1.0f)
|
||||
RenderView(curview, aRC, aRect, *currect, clipstate);
|
||||
else
|
||||
{
|
||||
aRC.SelectOffScreenDrawingSurface(gRed);
|
||||
|
||||
RenderView(curview, aRC, aRect, *currect, clipstate);
|
||||
|
||||
nsRect brect;
|
||||
|
||||
brect.x = brect.y = 0;
|
||||
brect.width = accumrect.width;
|
||||
brect.height = accumrect.height;
|
||||
|
||||
static NS_DEFINE_IID(kBlenderCID, NS_BLENDER_CID);
|
||||
static NS_DEFINE_IID(kIBlenderIID, NS_IBLENDER_IID);
|
||||
|
||||
nsIBlender *blender = nsnull;
|
||||
nsresult rv;
|
||||
|
||||
rv = nsRepository::CreateInstance(kBlenderCID, nsnull, kIBlenderIID, (void **)&blender);
|
||||
|
||||
if (NS_OK == rv)
|
||||
{
|
||||
nscoord width, height;
|
||||
|
||||
width = NSToCoordRound(currect->width * t2p);
|
||||
height = NSToCoordRound(currect->height * t2p);
|
||||
|
||||
blender->Init(mContext);
|
||||
blender->Blend(0, 0, width, height, gRed, gOffScreen, 0, 0, opacity);
|
||||
|
||||
NS_RELEASE(blender);
|
||||
}
|
||||
|
||||
aRC.SelectOffScreenDrawingSurface(gOffScreen);
|
||||
}
|
||||
|
||||
//if this view is transparent or non-opaque, it has
|
||||
//been accounted for, so we never have to look at it again.
|
||||
if (((PR_TRUE == trans) || (opacity < 1.0f)) && (curflags & VIEW_INCLUDED))
|
||||
{
|
||||
mFlatViews->ReplaceElementAt(nsnull, cnt);
|
||||
mFlatViews->ReplaceElementAt(nsnull, cnt + 2);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
aRC.SetClipRect(*currect, nsClipCombine_kSubtract, aResult);
|
||||
|
||||
if (aResult == PR_TRUE)
|
||||
{
|
||||
state = COMPOSITION_DONE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((PR_FALSE == hasWidget) || ((PR_TRUE == hasWidget) && (cnt == (flatlen - 2))))
|
||||
{
|
||||
nsRect lrect, drect, grect;
|
||||
switch (state)
|
||||
{
|
||||
case FRONT_TO_BACK_ACCUMULATE:
|
||||
loopstart = cnt - FLATVIEW_INC;
|
||||
loopend = accumstart - FLATVIEW_INC;
|
||||
increment = -FLATVIEW_INC;
|
||||
state = (transprop & (1 << TRANS_PROPERTY_OPACITY)) ? BACK_TO_FRONT_OPACITY : BACK_TO_FRONT_TRANS;
|
||||
|
||||
grect = *currect;
|
||||
curview->GetBounds(lrect);
|
||||
if (state == BACK_TO_FRONT_OPACITY)
|
||||
{
|
||||
PRInt32 w, h;
|
||||
nsRect bitrect;
|
||||
|
||||
aRC.PushState();
|
||||
//prepare offscreen buffers
|
||||
|
||||
aRC.Translate(grect.x, grect.y);
|
||||
w = NSToCoordRound(accumrect.width * t2p);
|
||||
h = NSToCoordRound(accumrect.height * t2p);
|
||||
|
||||
drect.IntersectRect(aRect, grect);
|
||||
if ((w > gBlendWidth) || (h > gBlendHeight))
|
||||
{
|
||||
bitrect.x = bitrect.y = 0;
|
||||
bitrect.width = w;
|
||||
bitrect.height = h;
|
||||
|
||||
drect.x -= grect.x;
|
||||
drect.y -= grect.y;
|
||||
if (nsnull != gOffScreen)
|
||||
{
|
||||
aRC.DestroyDrawingSurface(gOffScreen);
|
||||
gOffScreen = nsnull;
|
||||
}
|
||||
|
||||
curview->Paint(aRC, drect, NS_VIEW_FLAG_JUST_PAINT, aResult);
|
||||
aRC.CreateDrawingSurface(&bitrect, NS_CREATEDRAWINGSURFACE_FOR_PIXEL_ACCESS, gOffScreen);
|
||||
|
||||
aRC.PopState(aResult);
|
||||
if (nsnull != gRed)
|
||||
{
|
||||
aRC.DestroyDrawingSurface(gRed);
|
||||
gRed = nsnull;
|
||||
}
|
||||
|
||||
if (aResult == PR_FALSE)
|
||||
aRC.SetClipRect(grect, nsClipCombine_kSubtract, aResult);
|
||||
}
|
||||
else
|
||||
aRC.SetClipRect(*currect, nsClipCombine_kSubtract, aResult);
|
||||
aRC.CreateDrawingSurface(&bitrect, NS_CREATEDRAWINGSURFACE_FOR_PIXEL_ACCESS, gRed);
|
||||
|
||||
if (aResult == PR_TRUE)
|
||||
gBlendWidth = w;
|
||||
gBlendHeight = h;
|
||||
printf("offscr: %d, %d (%d, %d)\n", w, h, accumrect.width, accumrect.height);
|
||||
}
|
||||
|
||||
if ((nsnull == gOffScreen) || (nsnull == gRed))
|
||||
state = BACK_TO_FRONT_TRANS;
|
||||
else
|
||||
{
|
||||
aRC.Translate(-accumrect.x, -accumrect.y);
|
||||
aRC.SelectOffScreenDrawingSurface(gOffScreen);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case BACK_TO_FRONT_OPACITY:
|
||||
aRC.SelectOffScreenDrawingSurface(origsurf);
|
||||
aRC.Translate(accumrect.x, accumrect.y);
|
||||
aRC.CopyOffScreenBits(gOffScreen, 0, 0, accumrect, NS_COPYBITS_XFORM_DEST_VALUES | NS_COPYBITS_TO_BACK_BUFFER);
|
||||
//falls through
|
||||
|
||||
case BACK_TO_FRONT_TRANS:
|
||||
loopstart = accumstart + FLATVIEW_INC;
|
||||
loopend = flatlen;
|
||||
increment = FLATVIEW_INC;
|
||||
state = FRONT_TO_BACK_RENDER;
|
||||
|
||||
//clip out what we just rendered
|
||||
aRC.SetClipRect(accumrect, nsClipCombine_kSubtract, aResult);
|
||||
|
||||
//did that finish everything?
|
||||
if (aResult == PR_TRUE)
|
||||
state = COMPOSITION_DONE;
|
||||
|
||||
break;
|
||||
|
||||
case FRONT_TO_BACK_RENDER:
|
||||
state = COMPOSITION_DONE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -541,6 +766,26 @@ for (cnt = 0; cnt < flatlen; cnt += 2)
|
||||
#endif
|
||||
}
|
||||
|
||||
void nsViewManager :: RenderView(nsIView *aView, nsIRenderingContext &aRC, const nsRect &aDamageRect, nsRect &aGlobalRect, PRBool &aResult)
|
||||
{
|
||||
nsRect drect;
|
||||
|
||||
NS_ASSERTION(!(nsnull == aView), "no view");
|
||||
|
||||
aRC.PushState();
|
||||
|
||||
aRC.Translate(aGlobalRect.x, aGlobalRect.y);
|
||||
|
||||
drect.IntersectRect(aDamageRect, aGlobalRect);
|
||||
|
||||
drect.x -= aGlobalRect.x;
|
||||
drect.y -= aGlobalRect.y;
|
||||
|
||||
aView->Paint(aRC, drect, NS_VIEW_FLAG_JUST_PAINT, aResult);
|
||||
|
||||
aRC.PopState(aResult);
|
||||
}
|
||||
|
||||
void nsViewManager :: UpdateDirtyViews(nsIView *aView, nsRect *aParentRect) const
|
||||
{
|
||||
nsRect pardamage;
|
||||
@ -776,18 +1021,19 @@ NS_IMETHODIMP nsViewManager :: UpdateView(nsIView *aView, const nsRect &aRect, P
|
||||
// Convert damage rect to coordinate space of containing view with
|
||||
// a widget
|
||||
// XXX Consolidate this code with the code above...
|
||||
if (aView != widgetView)
|
||||
{
|
||||
// if (aView != widgetView)
|
||||
// {
|
||||
do
|
||||
{
|
||||
par->GetPosition(&x, &y);
|
||||
trect.x += x;
|
||||
trect.y += y;
|
||||
|
||||
par->GetParent(par);
|
||||
if (par != widgetView)
|
||||
par->GetParent(par);
|
||||
}
|
||||
while ((nsnull != par) && (par != widgetView));
|
||||
}
|
||||
// }
|
||||
|
||||
// Add this rect to the widgetView's dirty region.
|
||||
|
||||
@ -1447,11 +1693,21 @@ nsDrawingSurface nsViewManager :: GetDrawingSurface(nsIRenderingContext &aContex
|
||||
NS_IMETHODIMP nsViewManager :: ShowQuality(PRBool aShow)
|
||||
{
|
||||
nsIScrollableView *scroller;
|
||||
nsresult retval;
|
||||
nsresult retval = NS_ERROR_FAILURE;
|
||||
|
||||
retval = mRootView->QueryInterface(kIScrollableViewIID, (void **)&scroller);
|
||||
if (NS_SUCCEEDED(retval)) {
|
||||
scroller->ShowQuality(aShow);
|
||||
if (nsnull != mRootView)
|
||||
{
|
||||
nsIView *child;
|
||||
|
||||
mRootView->GetChild(0, child);
|
||||
|
||||
if (nsnull != child)
|
||||
{
|
||||
retval = child->QueryInterface(kIScrollableViewIID, (void **)&scroller);
|
||||
|
||||
if (NS_SUCCEEDED(retval))
|
||||
scroller->ShowQuality(aShow);
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
@ -1460,11 +1716,21 @@ NS_IMETHODIMP nsViewManager :: ShowQuality(PRBool aShow)
|
||||
NS_IMETHODIMP nsViewManager :: GetShowQuality(PRBool &aResult)
|
||||
{
|
||||
nsIScrollableView *scroller;
|
||||
nsresult retval;
|
||||
nsresult retval = NS_ERROR_FAILURE;
|
||||
|
||||
retval = mRootView->QueryInterface(kIScrollableViewIID, (void **)&scroller);
|
||||
if (NS_SUCCEEDED(retval)) {
|
||||
scroller->GetShowQuality(aResult);
|
||||
if (nsnull != mRootView)
|
||||
{
|
||||
nsIView *child;
|
||||
|
||||
mRootView->GetChild(0, child);
|
||||
|
||||
if (nsnull != child)
|
||||
{
|
||||
retval = child->QueryInterface(kIScrollableViewIID, (void **)&scroller);
|
||||
|
||||
if (NS_SUCCEEDED(retval))
|
||||
scroller->GetShowQuality(aResult);
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
@ -1473,12 +1739,21 @@ NS_IMETHODIMP nsViewManager :: GetShowQuality(PRBool &aResult)
|
||||
NS_IMETHODIMP nsViewManager :: SetQuality(nsContentQuality aQuality)
|
||||
{
|
||||
nsIScrollableView *scroller;
|
||||
nsresult retval;
|
||||
nsresult retval = NS_ERROR_FAILURE;
|
||||
|
||||
retval = mRootView->QueryInterface(kIScrollableViewIID, (void **)&scroller);
|
||||
if (NS_SUCCEEDED(retval))
|
||||
if (nsnull != mRootView)
|
||||
{
|
||||
scroller->SetQuality(aQuality);
|
||||
nsIView *child;
|
||||
|
||||
mRootView->GetChild(0, child);
|
||||
|
||||
if (nsnull != child)
|
||||
{
|
||||
retval = child->QueryInterface(kIScrollableViewIID, (void **)&scroller);
|
||||
|
||||
if (NS_SUCCEEDED(retval))
|
||||
scroller->SetQuality(aQuality);
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
@ -1611,6 +1886,18 @@ NS_IMETHODIMP nsViewManager :: EnableRefresh(void)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsViewManager :: SetRootScrollableView(nsIScrollableView *aScrollable)
|
||||
{
|
||||
mRootScrollable = aScrollable;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsViewManager :: GetRootScrollableView(nsIScrollableView **aScrollable)
|
||||
{
|
||||
*aScrollable = mRootScrollable;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsViewManager :: Display(nsIView* aView)
|
||||
{
|
||||
nsRect wrect;
|
||||
@ -1658,7 +1945,7 @@ NS_IMETHODIMP nsViewManager :: Display(nsIView* aView)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsViewManager :: FlattenViewTree(nsIView *aView, PRInt32 *aIndex, nsIView *aTopView, nsVoidArray *aArray, nscoord aX, nscoord aY)
|
||||
void nsViewManager :: FlattenViewTree(nsIView *aView, PRInt32 *aIndex, const nsRect *aDamageRect, nsIView *aTopView, nsVoidArray *aArray, nscoord aX, nscoord aY)
|
||||
{
|
||||
PRInt32 numkids, cnt;
|
||||
|
||||
@ -1696,22 +1983,7 @@ void nsViewManager :: FlattenViewTree(nsIView *aView, PRInt32 *aIndex, nsIView *
|
||||
|
||||
if (numkids > 0)
|
||||
{
|
||||
nsIWidget *widget;
|
||||
PRBool hasWidget = PR_FALSE;
|
||||
|
||||
aView->GetWidget(widget);
|
||||
|
||||
if (nsnull != widget)
|
||||
{
|
||||
void *nativewidget;
|
||||
|
||||
nativewidget = widget->GetNativeData(NS_NATIVE_WIDGET);
|
||||
|
||||
NS_RELEASE(widget);
|
||||
|
||||
if (nsnull != nativewidget)
|
||||
hasWidget = PR_TRUE;
|
||||
}
|
||||
PRBool hasWidget = DoesViewHaveNativeWidget(*aView);
|
||||
|
||||
if ((PR_FALSE == hasWidget) || ((PR_TRUE == hasWidget) && (aView == aTopView)))
|
||||
{
|
||||
@ -1720,29 +1992,68 @@ void nsViewManager :: FlattenViewTree(nsIView *aView, PRInt32 *aIndex, nsIView *
|
||||
nsIView *child;
|
||||
|
||||
aView->GetChild(cnt, child);
|
||||
FlattenViewTree(child, aIndex, aTopView, aArray, lrect.x, lrect.y);
|
||||
FlattenViewTree(child, aIndex, aDamageRect, aTopView, aArray, lrect.x, lrect.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aArray->ReplaceElementAt(aView, (*aIndex)++);
|
||||
nsViewVisibility vis;
|
||||
float opacity;
|
||||
PRBool overlap;
|
||||
|
||||
nsRect *grect = (nsRect *)aArray->ElementAt(*aIndex);
|
||||
aView->GetVisibility(vis);
|
||||
aView->GetOpacity(opacity);
|
||||
|
||||
if (nsnull == grect)
|
||||
if (nsnull != aDamageRect)
|
||||
overlap = lrect.Intersects(*aDamageRect);
|
||||
else
|
||||
overlap = PR_TRUE;
|
||||
|
||||
if ((nsViewVisibility_kShow == vis) && (opacity > 0.0f) && (PR_TRUE == overlap))
|
||||
{
|
||||
grect = new nsRect(lrect.x, lrect.y, lrect.width, lrect.height);
|
||||
aArray->ReplaceElementAt(aView, (*aIndex)++);
|
||||
|
||||
nsRect *grect = (nsRect *)aArray->ElementAt(*aIndex);
|
||||
|
||||
if (nsnull == grect)
|
||||
{
|
||||
(*aIndex)--;
|
||||
return;
|
||||
grect = new nsRect(lrect.x, lrect.y, lrect.width, lrect.height);
|
||||
|
||||
if (nsnull == grect)
|
||||
{
|
||||
(*aIndex)--;
|
||||
return;
|
||||
}
|
||||
|
||||
aArray->ReplaceElementAt(grect, *aIndex);
|
||||
}
|
||||
else
|
||||
*grect = lrect;
|
||||
|
||||
aArray->ReplaceElementAt(grect, *aIndex);
|
||||
(*aIndex)++;
|
||||
|
||||
aArray->ReplaceElementAt(nsnull, (*aIndex)++);
|
||||
}
|
||||
else
|
||||
*grect = lrect;
|
||||
|
||||
(*aIndex)++;
|
||||
}
|
||||
|
||||
PRBool nsViewManager :: DoesViewHaveNativeWidget(nsIView &aView)
|
||||
{
|
||||
nsIWidget *widget;
|
||||
PRBool retval = PR_FALSE;
|
||||
|
||||
aView.GetWidget(widget);
|
||||
|
||||
if (nsnull != widget)
|
||||
{
|
||||
void *nativewidget;
|
||||
|
||||
nativewidget = widget->GetNativeData(NS_NATIVE_WIDGET);
|
||||
|
||||
NS_RELEASE(widget);
|
||||
|
||||
if (nsnull != nativewidget)
|
||||
retval = PR_TRUE;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "nsITimer.h"
|
||||
#include "prtime.h"
|
||||
#include "nsVoidArray.h"
|
||||
#include "nsIScrollableView.h"
|
||||
|
||||
class nsViewManager : public nsIViewManager
|
||||
{
|
||||
@ -109,6 +110,9 @@ public:
|
||||
NS_IMETHOD DisableRefresh(void);
|
||||
NS_IMETHOD EnableRefresh(void);
|
||||
|
||||
NS_IMETHOD SetRootScrollableView(nsIScrollableView *aScrollable);
|
||||
NS_IMETHOD GetRootScrollableView(nsIScrollableView **aScrollable);
|
||||
|
||||
nsDrawingSurface GetDrawingSurface(nsIRenderingContext &aContext, nsRect& aBounds);
|
||||
|
||||
NS_IMETHOD Display(nsIView *aView);
|
||||
@ -126,11 +130,14 @@ private:
|
||||
nsIRegion *region, PRUint32 aUpdateFlags);
|
||||
void Refresh(nsIView* aView, nsIRenderingContext *aContext,
|
||||
const nsRect *rect, PRUint32 aUpdateFlags);
|
||||
void FlattenViewTree(nsIView *aView, PRInt32 *aIndex,
|
||||
nsIView *aTopView = nsnull, nsVoidArray *aArray = nsnull,
|
||||
nscoord aX = 0, nscoord aY = 0);
|
||||
void RenderViews(nsIView *aRootView, nsIRenderingContext& aRC, const nsRect& aRect,
|
||||
PRBool &aResult);
|
||||
void RenderView(nsIView *aView, nsIRenderingContext &aRC,
|
||||
const nsRect &aDamageRect, nsRect &aGlobalRect, PRBool &aResult);
|
||||
void FlattenViewTree(nsIView *aView, PRInt32 *aIndex, const nsRect *aDamageRect = nsnull,
|
||||
nsIView *aTopView = nsnull, nsVoidArray *aArray = nsnull,
|
||||
nscoord aX = 0, nscoord aY = 0);
|
||||
PRBool DoesViewHaveNativeWidget(nsIView &aView);
|
||||
|
||||
|
||||
nsIDeviceContext *mContext;
|
||||
@ -144,11 +151,19 @@ private:
|
||||
nsIView *mKeyGrabber;
|
||||
PRInt32 mUpdateCnt;
|
||||
nsVoidArray *mFlatViews;
|
||||
nsIScrollableView *mRootScrollable;
|
||||
|
||||
static PRUint32 mVMCount; //number of viewmanagers
|
||||
static nsDrawingSurface mDrawingSurface; //single drawing surface
|
||||
static nsRect mDSBounds; //for all VMs
|
||||
|
||||
//blending buffers
|
||||
nsDrawingSurface gOffScreen;
|
||||
nsDrawingSurface gRed;
|
||||
nsDrawingSurface gBlue;
|
||||
PRInt32 gBlendWidth;
|
||||
PRInt32 gBlendHeight;
|
||||
|
||||
public:
|
||||
//these are public so that our timer callback can poke them.
|
||||
nsITimer *mTimer;
|
||||
|
Loading…
Reference in New Issue
Block a user