floating views. bug=21966, r=troy, rods, a=brendan

git-svn-id: svn://10.0.0.236/trunk@58504 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
beard%netscape.com
2000-01-25 01:53:34 +00:00
parent 71ae94a086
commit c956c22a62
9 changed files with 705 additions and 680 deletions

View File

@@ -2181,11 +2181,11 @@ nsListControlFrame::CreateScrollingViewWidget(nsIView* aView, const nsStylePosit
{
if (IsInDropDownMode() == PR_TRUE) {
nsWidgetInitData widgetData;
aView->SetZIndex(kMaxZ);
// aView->SetZIndex(kMaxZ);
aView->SetFloating(PR_TRUE);
widgetData.mWindowType = eWindowType_popup;
widgetData.mBorderStyle = eBorderStyle_default;
#ifdef XP_MAC
static NS_DEFINE_IID(kCPopUpCID, NS_POPUP_CID);
aView->CreateWidget(kCPopUpCID, &widgetData, nsnull);

View File

@@ -2181,11 +2181,11 @@ nsListControlFrame::CreateScrollingViewWidget(nsIView* aView, const nsStylePosit
{
if (IsInDropDownMode() == PR_TRUE) {
nsWidgetInitData widgetData;
aView->SetZIndex(kMaxZ);
// aView->SetZIndex(kMaxZ);
aView->SetFloating(PR_TRUE);
widgetData.mWindowType = eWindowType_popup;
widgetData.mBorderStyle = eBorderStyle_default;
#ifdef XP_MAC
static NS_DEFINE_IID(kCPopUpCID, NS_POPUP_CID);
aView->CreateWidget(kCPopUpCID, &widgetData, nsnull);

View File

@@ -148,6 +148,11 @@ nsMenuPopupFrame::Init(nsIPresContext* aPresContext,
viewManager->GetRootView(rootView);
viewManager->InsertChild(rootView, ourView, kMaxZ);
// XXX Hack. The menu's view should float above all other views,
// so we use the nsIView::SetFloating() to tell the view manager
// about that constraint.
ourView->SetFloating(PR_TRUE);
// XXX Hack. Change our transparency to be non-transparent
// until the bug related to update of transparency on show/hide
// is fixed.

View File

@@ -263,6 +263,17 @@ public:
*/
NS_IMETHOD GetAutoZIndex(PRBool &aAutoZIndex) const = 0;
/**
* Set/Get whether the view "floats" above all other views,
* which tells the compositor not to consider higher views in
* the view hierarchy that would geometrically intersect with
* this view. This is a hack, but it fixes some problems with
* views that need to be drawn in front of all other views.
* @result PR_TRUE if the view floats, PR_FALSE otherwise.
*/
NS_IMETHOD SetFloating(PRBool aFloatingView) = 0;
NS_IMETHOD GetFloating(PRBool &aFloatingView) const = 0;
/**
* Called to set the parent of the view.
* @param aParent new parent
@@ -539,5 +550,7 @@ private:
#define NS_VIEW_PUBLIC_FLAG_DONT_BITBLT 0x0010
// indicates that the view is using auto z-indexing
#define NS_VIEW_PUBLIC_FLAG_AUTO_ZINDEX 0x0020
// indicatest hat the view is a floating view.
#define NS_VIEW_PUBLIC_FLAG_FLOATING 0x0040
#endif

View File

@@ -72,6 +72,11 @@ nsresult nsScrollPortView::QueryInterface(const nsIID& aIID, void** aInstancePtr
return NS_OK;
}
if (aIID.Equals(NS_GET_IID(nsIClipView))) {
*aInstancePtr = (void*)(nsIClipView*)this;
return NS_OK;
}
return nsView::QueryInterface(aIID, aInstancePtr);
}
@@ -531,6 +536,15 @@ void nsScrollPortView::Scroll(nsIView *aScrolledView, PRInt32 aDx, PRInt32 aDy,
NS_IMETHODIMP nsScrollPortView::Paint(nsIRenderingContext& rc, const nsRect& rect,
PRUint32 aPaintFlags, PRBool &aResult)
{
PRBool clipEmpty;
rc.PushState();
nsRect bounds = mBounds;
bounds.x = bounds.y = 0;
rc.SetClipRect(bounds, nsClipCombine_kIntersect, clipEmpty);
nsresult rv = nsView::Paint(rc, rect, aPaintFlags, aResult);
rc.PopState(clipEmpty);
return rv;
}

View File

@@ -267,495 +267,451 @@ NS_IMETHODIMP nsView :: GetViewManager(nsIViewManager *&aViewMgr) const
NS_IMETHODIMP nsView :: Paint(nsIRenderingContext& rc, const nsRect& rect,
PRUint32 aPaintFlags, PRBool &aResult)
{
if (aPaintFlags & NS_VIEW_FLAG_JUST_PAINT)
{
//new compositor
if (nsnull != mClientData)
{
nsIViewObserver *obs;
if (NS_OK == mViewManager->GetViewObserver(obs))
{
if ((mClip.mLeft != mClip.mRight) && (mClip.mTop != mClip.mBottom))
{
nsRect crect;
crect.x = mClip.mLeft;
crect.y = mClip.mTop;
crect.width = mClip.mRight - mClip.mLeft;
crect.height = mClip.mBottom - mClip.mTop;
rc.SetClipRect(crect, nsClipCombine_kIntersect, aResult);
}
obs->Paint((nsIView *)this, rc, rect);
NS_RELEASE(obs);
}
}
}
else
{
nsIView *pRoot;
PRBool clipres = PR_FALSE;
PRBool clipwasset = PR_FALSE;
float opacity;
mViewManager->GetRootView(pRoot);
rc.PushState();
GetOpacity(opacity);
if (aPaintFlags & NS_VIEW_FLAG_CLIP_SET)
{
clipwasset = PR_TRUE;
aPaintFlags &= ~NS_VIEW_FLAG_CLIP_SET;
}
else if (mVis == nsViewVisibility_kShow)
{
if (opacity == 1.0f)
{
nsRect brect;
GetBounds(brect);
if ((mClip.mLeft == mClip.mRight) || (mClip.mTop == mClip.mBottom) &&
(this != pRoot))
{
rc.SetClipRect(brect, nsClipCombine_kIntersect, clipres);
}
}
}
if (clipres == PR_FALSE)
{
nscoord posx, posy;
if (nsnull == mWindow)
{
GetPosition(&posx, &posy);
rc.Translate(posx, posy);
}
if (nsnull != mXForm)
{
nsTransform2D *pXForm;
rc.GetCurrentTransform(pXForm);
pXForm->Concatenate(mXForm);
}
//if we are not doing a two pass render,
//render the kids...
if (!(aPaintFlags & (NS_VIEW_FLAG_FRONT_TO_BACK | NS_VIEW_FLAG_BACK_TO_FRONT)))
{
PRInt32 numkids;
GetChildCount(numkids);
for (PRInt32 cnt = 0; cnt < numkids; cnt++)
{
nsIView *kid;
GetChild(cnt, kid);
if (nsnull != kid)
{
// Don't paint child views that have widgets. They'll get their own
// native paint requests
nsIWidget *widget;
PRBool hasWidget;
kid->GetWidget(widget);
hasWidget = (widget != nsnull);
if (nsnull != widget)
{
void *thing;
thing = widget->GetNativeData(NS_NATIVE_WIDGET);
NS_RELEASE(widget);
if (nsnull == thing)
hasWidget = PR_FALSE;
}
if (!hasWidget)
{
nsRect kidRect;
kid->GetBounds(kidRect);
nsRect damageArea;
PRBool overlap = damageArea.IntersectRect(rect, kidRect);
if (overlap == PR_TRUE)
{
// Translate damage area into kid's coordinate system
nsRect kidDamageArea(damageArea.x - kidRect.x, damageArea.y - kidRect.y,
damageArea.width, damageArea.height);
kid->Paint(rc, kidDamageArea, aPaintFlags, clipres);
if (clipres == PR_TRUE)
break;
}
}
}
}
}
if ((clipres == PR_FALSE) && (mVis == nsViewVisibility_kShow))
{
//don't render things that can't be seen...
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
rc.PushState();
HasTransparency(hasTransparency);
if (opacity < 1.0f)
{
nsIDeviceContext *dx = nsnull;
nsIView *rootview = nsnull;
//create offscreen bitmap to render view into
mViewManager->GetDeviceContext(dx);
mViewManager->GetRootView(rootview);
if ((nsnull != dx) && (nsnull != rootview))
{
dx->CreateRenderingContext(rootview, localcx);
if (nsnull != localcx)
{
float t2p;
nscoord width, height;
//create offscreen buffer for blending...
dx->GetAppUnitsToDevUnits(t2p);
width = NSToCoordRound(mBounds.width * t2p);
height = NSToCoordRound(mBounds.height * t2p);
nsRect bitrect = nsRect(0, 0, width, height);
localcx->CreateDrawingSurface(&bitrect, NS_CREATEDRAWINGSURFACE_FOR_PIXEL_ACCESS, surf);
localcx->CreateDrawingSurface(&bitrect, NS_CREATEDRAWINGSURFACE_FOR_PIXEL_ACCESS, redsurf);
if (nsnull != surf)
localcx->SelectOffScreenDrawingSurface(surf);
}
NS_RELEASE(dx);
}
}
if (nsnull == localcx)
localcx = &rc;
if (hasTransparency || (opacity < 1.0f))
{
//overview of algorithm:
//1. clip is set to intersection of this view and whatever is
// left of the damage region in the rc.
//2. walk tree from this point down through the view list,
// rendering and clipping out opaque views encountered until
// there is nothing left in the clip area or the bottommost
// view is reached.
//3. walk back up through view list restoring clips and painting
// or blending any non-opaque views encountered until we reach the
// view that started the whole process
//walk down rendering only views within this clip
//clip is already set to this view in rendering context...
nsIView *curview, *preview = this;
nsVoidArray *views = (nsVoidArray *)new nsVoidArray();
nsVoidArray *rects = (nsVoidArray *)new nsVoidArray();
// nscoord posx, posy;
nsRect damRect = rect;
localcx->PushState();
GetPosition(&posx, &posy);
//we need to go back to the coordinate system that was there
//before we came along... XXX xform not accounted for. MMP
damRect.x += posx;
damRect.y += posy;
if (aPaintFlags & NS_VIEW_FLAG_JUST_PAINT)
{
//new compositor
if (nsnull != mClientData) {
nsCOMPtr<nsIViewObserver> observer;
if (NS_OK == mViewManager->GetViewObserver(*getter_AddRefs(observer))) {
if ((mClip.mLeft != mClip.mRight) && (mClip.mTop != mClip.mBottom)) {
nsRect crect;
crect.x = mClip.mLeft;
crect.y = mClip.mTop;
crect.width = mClip.mRight - mClip.mLeft;
crect.height = mClip.mBottom - mClip.mTop;
rc.SetClipRect(crect, nsClipCombine_kIntersect, aResult);
}
observer->Paint((nsIView *)this, rc, rect);
}
}
} else {
nsIView *pRoot;
PRBool clipres = PR_FALSE;
PRBool clipwasset = PR_FALSE;
float opacity;
mViewManager->GetRootView(pRoot);
rc.PushState();
GetOpacity(opacity);
if (aPaintFlags & NS_VIEW_FLAG_CLIP_SET)
{
clipwasset = PR_TRUE;
aPaintFlags &= ~NS_VIEW_FLAG_CLIP_SET;
} else if (mVis == nsViewVisibility_kShow) {
if (opacity == 1.0f)
{
nsRect brect;
GetBounds(brect);
// what does this test mean?
if ((mClip.mLeft == mClip.mRight) || (mClip.mTop == mClip.mBottom) && (this != pRoot)) {
rc.SetClipRect(brect, nsClipCombine_kIntersect, clipres);
}
}
}
if (clipres == PR_FALSE)
{
nscoord posx, posy;
if (nsnull == mWindow)
{
GetPosition(&posx, &posy);
rc.Translate(posx, posy);
}
if (nsnull != mXForm)
{
nsTransform2D *pXForm;
rc.GetCurrentTransform(pXForm);
pXForm->Concatenate(mXForm);
}
//if we are not doing a two pass render,
//render the kids...
if (!(aPaintFlags & (NS_VIEW_FLAG_FRONT_TO_BACK | NS_VIEW_FLAG_BACK_TO_FRONT))) {
PRInt32 numkids;
GetChildCount(numkids);
for (PRInt32 cnt = 0; cnt < numkids; cnt++) {
nsIView *kid;
GetChild(cnt, kid);
if (nsnull != kid) {
// Don't paint child views that have widgets. They'll get their own
// native paint requests
nsIWidget *widget;
PRBool hasWidget;
kid->GetWidget(widget);
hasWidget = (widget != nsnull);
if (nsnull != widget) {
void *thing;
thing = widget->GetNativeData(NS_NATIVE_WIDGET);
NS_RELEASE(widget);
if (nsnull == thing)
hasWidget = PR_FALSE;
}
if (!hasWidget) {
nsRect kidRect;
kid->GetBounds(kidRect);
nsRect damageArea;
PRBool overlap = damageArea.IntersectRect(rect, kidRect);
if (overlap == PR_TRUE) {
// Translate damage area into kid's coordinate system
nsRect kidDamageArea(damageArea.x - kidRect.x, damageArea.y - kidRect.y,
damageArea.width, damageArea.height);
kid->Paint(rc, kidDamageArea, aPaintFlags, clipres);
if (clipres == PR_TRUE)
break;
}
}
}
}
}
if ((clipres == PR_FALSE) && (mVis == nsViewVisibility_kShow)) {
//don't render things that can't be seen...
if ((opacity > 0.0f) && (mBounds.width > 1) && (mBounds.height > 1)) {
nsCOMPtr<nsIRenderingContext> localcx;
nsDrawingSurface surf = nsnull;
nsDrawingSurface redsurf = nsnull;
PRBool hasTransparency;
PRBool clipState; //for when we want to throw away the clip state
rc.PushState();
HasTransparency(hasTransparency);
if (opacity < 1.0f)
{
nsIDeviceContext *dx = nsnull;
nsIView *rootview = nsnull;
//create offscreen bitmap to render view into
mViewManager->GetDeviceContext(dx);
mViewManager->GetRootView(rootview);
if ((nsnull != dx) && (nsnull != rootview))
{
dx->CreateRenderingContext(rootview, *getter_AddRefs(localcx));
if (nsnull != localcx) {
float t2p;
nscoord width, height;
//create offscreen buffer for blending...
dx->GetAppUnitsToDevUnits(t2p);
width = NSToCoordRound(mBounds.width * t2p);
height = NSToCoordRound(mBounds.height * t2p);
nsRect bitrect = nsRect(0, 0, width, height);
localcx->CreateDrawingSurface(&bitrect, NS_CREATEDRAWINGSURFACE_FOR_PIXEL_ACCESS, surf);
localcx->CreateDrawingSurface(&bitrect, NS_CREATEDRAWINGSURFACE_FOR_PIXEL_ACCESS, redsurf);
if (nsnull != surf)
localcx->SelectOffScreenDrawingSurface(surf);
}
NS_RELEASE(dx);
}
}
localcx->Translate(-posx, -posy);
if (nsnull == localcx)
localcx = &rc;
GetNextSibling(curview);
if (hasTransparency || (opacity < 1.0f)) {
//overview of algorithm:
//1. clip is set to intersection of this view and whatever is
// left of the damage region in the rc.
//2. walk tree from this point down through the view list,
// rendering and clipping out opaque views encountered until
// there is nothing left in the clip area or the bottommost
// view is reached.
//3. walk back up through view list restoring clips and painting
// or blending any non-opaque views encountered until we reach the
// view that started the whole process
if (nsnull == curview)
{
preview->GetParent(curview);
//walk down rendering only views within this clip
//clip is already set to this view in rendering context...
if (nsnull != curview)
{
nsRect prect;
nsIView *curview, *preview = this;
nsVoidArray *views = (nsVoidArray *)new nsVoidArray();
nsVoidArray *rects = (nsVoidArray *)new nsVoidArray();
// nscoord posx, posy;
nsRect damRect = rect;
curview->GetBounds(prect);
localcx->PushState();
damRect.x += prect.x;
damRect.y += prect.y;
GetPosition(&posx, &posy);
localcx->Translate(-prect.x, -prect.y);
}
}
//we need to go back to the coordinate system that was there
//before we came along... XXX xform not accounted for. MMP
damRect.x += posx;
damRect.y += posy;
while (nsnull != curview)
{
nsRect kidRect;
curview->GetBounds(kidRect);
nsRect damageArea;
PRBool overlap = damageArea.IntersectRect(damRect, kidRect);
localcx->Translate(-posx, -posy);
if (overlap == PR_TRUE)
{
// Translate damage area into kid's coordinate system
// nsRect kidDamageArea(damageArea.x - kidRect.x, damageArea.y - kidRect.y,
// damageArea.width, damageArea.height);
nsRect kidDamageArea(damRect.x - kidRect.x, damRect.y - kidRect.y,
damRect.width, damRect.height);
GetNextSibling(curview);
//we will pop the states on the back to front pass...
localcx->PushState();
if (nsnull == curview)
{
preview->GetParent(curview);
if (nsnull != views)
views->AppendElement(curview);
if (nsnull != curview)
{
nsRect prect;
rects->AppendElement(new nsRect(kidDamageArea));
curview->GetBounds(prect);
curview->Paint(*localcx, kidDamageArea, aPaintFlags | NS_VIEW_FLAG_FRONT_TO_BACK, clipres);
}
damRect.x += prect.x;
damRect.y += prect.y;
if (clipres == PR_TRUE)
break;
localcx->Translate(-prect.x, -prect.y);
}
}
preview = curview;
while (nsnull != curview)
{
nsRect kidRect;
curview->GetBounds(kidRect);
nsRect damageArea;
PRBool overlap = damageArea.IntersectRect(damRect, kidRect);
curview->GetNextSibling(curview);
if (overlap == PR_TRUE)
{
// Translate damage area into kid's coordinate system
// nsRect kidDamageArea(damageArea.x - kidRect.x, damageArea.y - kidRect.y,
// damageArea.width, damageArea.height);
nsRect kidDamageArea(damRect.x - kidRect.x, damRect.y - kidRect.y,
damRect.width, damRect.height);
if (nsnull == curview)
{
preview->GetParent(curview);
//we will pop the states on the back to front pass...
localcx->PushState();
if (nsnull != curview)
{
nsRect prect;
if (nsnull != views)
views->AppendElement(curview);
curview->GetBounds(prect);
rects->AppendElement(new nsRect(kidDamageArea));
damRect.x += prect.x;
damRect.y += prect.y;
curview->Paint(*localcx, kidDamageArea, aPaintFlags | NS_VIEW_FLAG_FRONT_TO_BACK, clipres);
}
localcx->Translate(-prect.x, -prect.y);
}
}
}
if (clipres == PR_TRUE)
break;
//walk backwards, rendering views
preview = curview;
if (nsnull != views)
{
PRInt32 idx = views->Count();
PRBool isfirst = PR_TRUE;
curview->GetNextSibling(curview);
while (idx > 0)
{
if (PR_TRUE == isfirst)
{
//we just rendered the last view at the
//end of the first pass, so there is no need
//to do so again.
if (nsnull == curview)
{
preview->GetParent(curview);
nsRect *trect = (nsRect *)rects->ElementAt(--idx);
delete trect;
if (nsnull != curview)
{
nsRect prect;
localcx->PopState(clipState);
isfirst = PR_FALSE;
}
else
{
curview = (nsIView *)views->ElementAt(--idx);
nsRect *trect = (nsRect *)rects->ElementAt(idx);
curview->GetBounds(prect);
curview->Paint(*localcx, *trect, aPaintFlags | NS_VIEW_FLAG_BACK_TO_FRONT, clipres);
damRect.x += prect.x;
damRect.y += prect.y;
delete trect;
localcx->Translate(-prect.x, -prect.y);
}
}
}
//pop the state pushed on the front to back pass...
localcx->PopState(clipState);
}
}
//walk backwards, rendering views
delete rects;
delete views;
}
if (nsnull != views) {
PRInt32 idx = views->Count();
PRBool isfirst = PR_TRUE;
localcx->PopState(clipState);
}
while (idx > 0) {
if (PR_TRUE == isfirst) {
//we just rendered the last view at the
//end of the first pass, so there is no need
//to do so again.
if (nsnull != redsurf)
localcx->SelectOffScreenDrawingSurface(redsurf);
nsRect *trect = (nsRect *)rects->ElementAt(--idx);
delete trect;
//now draw ourself...
localcx->PopState(clipState);
isfirst = PR_FALSE;
} else {
curview = (nsIView *)views->ElementAt(--idx);
nsRect *trect = (nsRect *)rects->ElementAt(idx);
if (nsnull != mClientData)
{
nsIViewObserver *obs;
curview->Paint(*localcx, *trect, aPaintFlags | NS_VIEW_FLAG_BACK_TO_FRONT, clipres);
if (NS_OK == mViewManager->GetViewObserver(obs))
{
if ((mClip.mLeft != mClip.mRight) && (mClip.mTop != mClip.mBottom))
{
nsRect crect, brect;
delete trect;
GetBounds(brect);
//pop the state pushed on the front to back pass...
localcx->PopState(clipState);
}
}
crect.x = mClip.mLeft + brect.x;
crect.y = mClip.mTop + brect.y;
crect.width = mClip.mRight - mClip.mLeft;
crect.height = mClip.mBottom - mClip.mTop;
delete rects;
delete views;
}
localcx->SetClipRect(crect, nsClipCombine_kIntersect, clipres);
}
localcx->PopState(clipState);
}
obs->Paint((nsIView *)this, *localcx, rect);
NS_RELEASE(obs);
}
}
if (nsnull != redsurf)
localcx->SelectOffScreenDrawingSurface(redsurf);
if (localcx != &rc)
{
// localcx->SelectOffScreenDrawingSurface(nsnull);
NS_RELEASE(localcx);
}
else
localcx = nsnull;
//now draw ourself...
//kill offscreen buffer
if (nsnull != mClientData) {
nsCOMPtr<nsIViewObserver> observer;
if (NS_OK == mViewManager->GetViewObserver(*getter_AddRefs(observer))) {
if ((mClip.mLeft != mClip.mRight) && (mClip.mTop != mClip.mBottom)) {
nsRect crect(mClip.mLeft, mClip.mTop,
mClip.mRight - mClip.mLeft,
mClip.mBottom - mClip.mTop);
localcx->SetClipRect(crect, nsClipCombine_kIntersect, clipres);
}
observer->Paint((nsIView *)this, *localcx, rect);
}
}
if ((nsnull != surf) && (nsnull != redsurf))
{
nsRect brect;
#if 1
// release whatever hold we had on the context.
localcx = nsnull;
#else
if (localcx != &rc) {
// localcx->SelectOffScreenDrawingSurface(nsnull);
NS_RELEASE(localcx);
} else
localcx = nsnull;
#endif
brect.x = brect.y = 0;
brect.width = mBounds.width;
brect.height = mBounds.height;
//kill offscreen buffer
static NS_DEFINE_IID(kBlenderCID, NS_BLENDER_CID);
static NS_DEFINE_IID(kIBlenderIID, NS_IBLENDER_IID);
if ((nsnull != surf) && (nsnull != redsurf))
{
nsRect brect;
nsIBlender *blender = nsnull;
nsresult rv;
brect.x = brect.y = 0;
brect.width = mBounds.width;
brect.height = mBounds.height;
rv = nsComponentManager::CreateInstance(kBlenderCID, nsnull, kIBlenderIID, (void **)&blender);
static NS_DEFINE_IID(kBlenderCID, NS_BLENDER_CID);
static NS_DEFINE_IID(kIBlenderIID, NS_IBLENDER_IID);
if (NS_OK == rv)
{
nsIDeviceContext *dx;
nsIBlender *blender = nsnull;
nsresult rv;
mViewManager->GetDeviceContext(dx);
rv = nsComponentManager::CreateInstance(kBlenderCID, nsnull, kIBlenderIID, (void **)&blender);
float t2p;
nscoord width, height;
if (NS_OK == rv)
{
nsIDeviceContext *dx;
dx->GetAppUnitsToDevUnits(t2p);
mViewManager->GetDeviceContext(dx);
width = NSToCoordRound(mBounds.width * t2p);
height = NSToCoordRound(mBounds.height * t2p);
float t2p;
nscoord width, height;
blender->Init(dx);
blender->Blend(0, 0, width, height,redsurf,surf, 0, 0, opacity);
dx->GetAppUnitsToDevUnits(t2p);
NS_RELEASE(blender);
NS_RELEASE(dx);
width = NSToCoordRound(mBounds.width * t2p);
height = NSToCoordRound(mBounds.height * t2p);
rc.CopyOffScreenBits(surf, 0, 0, brect, NS_COPYBITS_XFORM_DEST_VALUES);
}
blender->Init(dx);
blender->Blend(0, 0, width, height,redsurf,surf, 0, 0, opacity);
rc.DestroyDrawingSurface(surf);
rc.DestroyDrawingSurface(redsurf);
NS_RELEASE(blender);
NS_RELEASE(dx);
rc.CopyOffScreenBits(surf, 0, 0, brect, NS_COPYBITS_XFORM_DEST_VALUES);
}
rc.DestroyDrawingSurface(surf);
rc.DestroyDrawingSurface(redsurf);
surf = nsnull;
redsurf = nsnull;
}
surf = nsnull;
redsurf = nsnull;
}
#ifdef SHOW_VIEW_BORDERS
{
nscoord x, y, w, h;
#ifdef SHOW_VIEW_BORDERS
{
nscoord x, y, w, h;
if ((mClip.mLeft != mClip.mRight) && (mClip.mTop != mClip.mBottom))
{
x = mClip.mLeft;
y = mClip.mTop;
w = mClip.mRight - mClip.mLeft;
h = mClip.mBottom - mClip.mTop;
if ((mClip.mLeft != mClip.mRight) && (mClip.mTop != mClip.mBottom))
{
x = mClip.mLeft;
y = mClip.mTop;
w = mClip.mRight - mClip.mLeft;
h = mClip.mBottom - mClip.mTop;
rc.SetColor(NS_RGB(255, 255, 0));
}
else
{
x = y = 0;
rc.SetColor(NS_RGB(255, 255, 0));
}
else
{
x = y = 0;
GetDimensions(&w, &h);
GetDimensions(&w, &h);
if (nsnull != mWindow)
rc.SetColor(NS_RGB(0, 255, 0));
else
rc.SetColor(NS_RGB(0, 0, 255));
}
rc.DrawRect(x, y, w, h);
}
#endif
rc.PopState(clipState);
}
}
}
rc.PopState(clipres);
if (nsnull != mWindow)
rc.SetColor(NS_RGB(0, 255, 0));
else
rc.SetColor(NS_RGB(0, 0, 255));
}
//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.
rc.DrawRect(x, y, w, h);
}
#endif
if (!clipwasset && (clipres == PR_FALSE) &&
(mVis == nsViewVisibility_kShow) && (nsnull == mWindow) &&
(opacity > 0.0f))
{
nsRect brect;
GetBounds(brect);
rc.PopState(clipState);
}
}
}
if ((mClip.mLeft != mClip.mRight) && (mClip.mTop != mClip.mBottom))
{
nsRect crect;
rc.PopState(clipres);
crect.x = mClip.mLeft + brect.x;
crect.y = mClip.mTop + brect.y;
crect.width = mClip.mRight - mClip.mLeft;
crect.height = mClip.mBottom - mClip.mTop;
//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.
rc.SetClipRect(crect, nsClipCombine_kSubtract, clipres);
} else if (this != pRoot)
rc.SetClipRect(brect, nsClipCombine_kSubtract, clipres);
}
if (!clipwasset && (clipres == PR_FALSE) &&
(mVis == nsViewVisibility_kShow) && (nsnull == mWindow) &&
(opacity > 0.0f))
{
nsRect brect;
aResult = clipres;
}
GetBounds(brect);
if ((mClip.mLeft != mClip.mRight) && (mClip.mTop != mClip.mBottom))
{
nsRect crect;
crect.x = mClip.mLeft + brect.x;
crect.y = mClip.mTop + brect.y;
crect.width = mClip.mRight - mClip.mLeft;
crect.height = mClip.mBottom - mClip.mTop;
rc.SetClipRect(crect, nsClipCombine_kSubtract, clipres);
}
else if (this != pRoot)
rc.SetClipRect(brect, nsClipCombine_kSubtract, clipres);
}
aResult = clipres;
}
return NS_OK;
return NS_OK;
}
NS_IMETHODIMP nsView :: Paint(nsIRenderingContext& rc, const nsIRegion& region,
@@ -1083,6 +1039,32 @@ NS_IMETHODIMP nsView::GetAutoZIndex(PRBool &aAutoZIndex) const
return NS_OK;
}
NS_IMETHODIMP nsView::SetFloating(PRBool aFloatingView)
{
if (aFloatingView)
mVFlags |= NS_VIEW_PUBLIC_FLAG_FLOATING;
else
mVFlags &= ~NS_VIEW_PUBLIC_FLAG_FLOATING;
#if 0
// recursively make all sub-views "floating" grr.
nsIView *child = mFirstChild;
while (nsnull != child) {
child->SetFloating(aFloatingView);
child->GetNextSibling(child);
}
#endif
return NS_OK;
}
NS_IMETHODIMP nsView::GetFloating(PRBool &aFloatingView) const
{
aFloatingView = ((mVFlags & NS_VIEW_PUBLIC_FLAG_FLOATING) != 0);
return NS_OK;
}
NS_IMETHODIMP nsView :: SetParent(nsIView *aParent)
{
mParent = aParent;

View File

@@ -74,6 +74,8 @@ public:
NS_IMETHOD GetZIndex(PRInt32 &aZIndex) const;
NS_IMETHOD SetAutoZIndex(PRBool aAutoZIndex);
NS_IMETHOD GetAutoZIndex(PRBool &aAutoZIndex) const;
NS_IMETHOD SetFloating(PRBool aFloatingView);
NS_IMETHOD GetFloating(PRBool &aFloatingView) const;
NS_IMETHOD SetParent(nsIView *aParent);
NS_IMETHOD GetParent(nsIView *&aParent) const;
NS_IMETHOD GetNextSibling(nsIView *&aNextSibling) const;

View File

@@ -658,6 +658,14 @@ void nsViewManager :: RenderViews(nsIView *aRootView, nsIRenderingContext& aRC,
{
#ifdef NEW_COMPOSITOR
PRBool isFloatingView = PR_FALSE;
if (NS_SUCCEEDED(aRootView->GetFloating(isFloatingView)) && isFloatingView) {
// floating views are rendered locally (and act globally).
// Paint the view. The clipping rect was set above set don't clip again.
aRootView->Paint(aRC, aRect, NS_VIEW_FLAG_CLIP_SET, aResult);
return;
}
#define SET_STATE(x) { prevstate = state; state = (x); }
PRInt32 flatlen = 0, cnt;
@@ -1770,6 +1778,11 @@ NS_IMETHODIMP nsViewManager :: InsertChild(nsIView *parent, nsIView *child, nsIV
UpdateTransCnt(nsnull, child);
// if the parent view is marked as "floating", make the newly added view float as well.
PRBool isFloating = PR_FALSE;
parent->GetFloating(isFloating);
child->SetFloating(isFloating);
//and mark this area as dirty if the view is visible...
nsViewVisibility visibility;
@@ -1817,9 +1830,13 @@ NS_IMETHODIMP nsViewManager :: InsertChild(nsIView *parent, nsIView *child, PRIn
UpdateTransCnt(nsnull, child);
// if the parent view is marked as "floating", make the newly added view float as well.
PRBool isFloating = PR_FALSE;
parent->GetFloating(isFloating);
child->SetFloating(isFloating);
//and mark this area as dirty if the view is visible...
nsViewVisibility visibility;
child->GetVisibility(visibility);
if (nsViewVisibility_kHide != visibility)

View File

@@ -39,7 +39,7 @@ static NS_DEFINE_IID(kRenderingContextCID, NS_RENDERING_CONTEXT_CID);
#define UPDATE_QUANTUM 1000 / 40
//#define NO_DOUBLE_BUFFER
#define NO_DOUBLE_BUFFER
//display list flags
#define RENDER_VIEW 0x0000
@@ -129,12 +129,11 @@ nsViewManager2::~nsViewManager2()
((nsnull != mDrawingSurface) || (nsnull != gOffScreen) ||
(nsnull != gRed) || (nsnull != gBlue)))
{
nsIRenderingContext *rc;
nsCOMPtr<nsIRenderingContext> rc;
nsresult rv = nsComponentManager::CreateInstance(kRenderingContextCID,
nsnull,
NS_GET_IID(nsIRenderingContext),
(void **)&rc);
getter_AddRefs(rc));
if (NS_OK == rv)
{
@@ -149,8 +148,6 @@ nsViewManager2::~nsViewManager2()
if (nsnull != gBlue)
rc->DestroyDrawingSurface(gBlue);
NS_RELEASE(rc);
}
mDrawingSurface = nsnull;
@@ -381,7 +378,7 @@ NS_IMETHODIMP nsViewManager2::ResetScrolling(void)
void nsViewManager2::Refresh(nsIView *aView, nsIRenderingContext *aContext, nsIRegion *region, PRUint32 aUpdateFlags)
{
nsRect wrect;
nsIRenderingContext *localcx = nsnull;
nsCOMPtr<nsIRenderingContext> localcx;
nsDrawingSurface ds = nsnull;
if (PR_FALSE == mRefreshEnabled)
@@ -403,24 +400,24 @@ void nsViewManager2::Refresh(nsIView *aView, nsIRenderingContext *aContext, nsIR
if (nsnull == aContext)
{
localcx = CreateRenderingContext(*aView);
localcx = getter_AddRefs(CreateRenderingContext(*aView));
//couldn't get rendering context. this is ok at init time atleast
if (nsnull == localcx)
return;
}
else
} else {
// plain assignment grabs another reference.
localcx = aContext;
}
// notify the listeners.
if (nsnull != mCompositeListeners) {
PRUint32 listenerCount;
if (NS_SUCCEEDED(mCompositeListeners->Count(&listenerCount))) {
nsICompositeListener* listener;
nsCOMPtr<nsICompositeListener> listener;
for (PRUint32 i = 0; i < listenerCount; i++) {
if (NS_SUCCEEDED(mCompositeListeners->QueryElementAt(i, NS_GET_IID(nsICompositeListener), (void**)&listener))) {
if (NS_SUCCEEDED(mCompositeListeners->QueryElementAt(i, NS_GET_IID(nsICompositeListener), getter_AddRefs(listener)))) {
listener->WillRefreshRegion(this, aView, aContext, region, aUpdateFlags);
NS_RELEASE(listener);
}
}
}
@@ -428,15 +425,10 @@ void nsViewManager2::Refresh(nsIView *aView, nsIRenderingContext *aContext, nsIR
if (aUpdateFlags & NS_VMREFRESH_DOUBLE_BUFFER)
{
nsIWidget* widget;
aView->GetWidget(widget);
nsCOMPtr<nsIWidget> widget;
aView->GetWidget(*getter_AddRefs(widget));
widget->GetClientBounds(wrect);
wrect.x = wrect.y = 0;
NS_RELEASE(widget);
ds = GetDrawingSurface(*localcx, wrect);
}
@@ -455,9 +447,6 @@ void nsViewManager2::Refresh(nsIView *aView, nsIRenderingContext *aContext, nsIR
if ((aUpdateFlags & NS_VMREFRESH_DOUBLE_BUFFER) && ds)
localcx->CopyOffScreenBits(ds, wrect.x, wrect.y, wrect, NS_COPYBITS_USE_SOURCE_CLIP_REGION);
if (localcx != aContext)
NS_RELEASE(localcx);
// Subtract the area we just painted from the dirty region
if ((nsnull != region) && !region->IsEmpty())
{
@@ -478,11 +467,10 @@ void nsViewManager2::Refresh(nsIView *aView, nsIRenderingContext *aContext, nsIR
if (nsnull != mCompositeListeners) {
PRUint32 listenerCount;
if (NS_SUCCEEDED(mCompositeListeners->Count(&listenerCount))) {
nsICompositeListener* listener;
nsCOMPtr<nsICompositeListener> listener;
for (PRUint32 i = 0; i < listenerCount; i++) {
if (NS_SUCCEEDED(mCompositeListeners->QueryElementAt(i, NS_GET_IID(nsICompositeListener), (void**)&listener))) {
if (NS_SUCCEEDED(mCompositeListeners->QueryElementAt(i, NS_GET_IID(nsICompositeListener), getter_AddRefs(listener)))) {
listener->DidRefreshRegion(this, aView, aContext, region, aUpdateFlags);
NS_RELEASE(listener);
}
}
}
@@ -492,7 +480,7 @@ void nsViewManager2::Refresh(nsIView *aView, nsIRenderingContext *aContext, nsIR
void nsViewManager2::Refresh(nsIView *aView, nsIRenderingContext *aContext, const nsRect *rect, PRUint32 aUpdateFlags)
{
nsRect wrect, brect;
nsIRenderingContext *localcx = nsnull;
nsCOMPtr<nsIRenderingContext> localcx;
nsDrawingSurface ds = nsnull;
if (PR_FALSE == mRefreshEnabled)
@@ -516,24 +504,24 @@ void nsViewManager2::Refresh(nsIView *aView, nsIRenderingContext *aContext, cons
if (nsnull == aContext)
{
localcx = CreateRenderingContext(*aView);
localcx = getter_AddRefs(CreateRenderingContext(*aView));
//couldn't get rendering context. this is ok if at startup
if (nsnull == localcx)
return;
}
else
} else {
// plain assignment adds a ref
localcx = aContext;
}
// notify the listeners.
if (nsnull != mCompositeListeners) {
PRUint32 listenerCount;
if (NS_SUCCEEDED(mCompositeListeners->Count(&listenerCount))) {
nsICompositeListener* listener;
nsCOMPtr<nsICompositeListener> listener;
for (PRUint32 i = 0; i < listenerCount; i++) {
if (NS_SUCCEEDED(mCompositeListeners->QueryElementAt(i, NS_GET_IID(nsICompositeListener), (void**)&listener))) {
if (NS_SUCCEEDED(mCompositeListeners->QueryElementAt(i, NS_GET_IID(nsICompositeListener), getter_AddRefs(listener)))) {
listener->WillRefreshRect(this, aView, aContext, rect, aUpdateFlags);
NS_RELEASE(listener);
}
}
}
@@ -541,16 +529,11 @@ void nsViewManager2::Refresh(nsIView *aView, nsIRenderingContext *aContext, cons
if (aUpdateFlags & NS_VMREFRESH_DOUBLE_BUFFER)
{
nsIWidget* widget;
aView->GetWidget(widget);
nsCOMPtr<nsIWidget> widget;
aView->GetWidget(*getter_AddRefs(widget));
widget->GetClientBounds(wrect);
brect = wrect;
wrect.x = wrect.y = 0;
NS_RELEASE(widget);
ds = GetDrawingSurface(*localcx, wrect);
}
@@ -565,13 +548,9 @@ void nsViewManager2::Refresh(nsIView *aView, nsIRenderingContext *aContext, cons
if ((aUpdateFlags & NS_VMREFRESH_DOUBLE_BUFFER) && ds)
localcx->CopyOffScreenBits(ds, wrect.x, wrect.y, wrect, NS_COPYBITS_USE_SOURCE_CLIP_REGION);
if (localcx != aContext)
NS_RELEASE(localcx);
#if 0
// Subtract the area we just painted from the dirty region
nsIRegion *dirtyRegion;
nsIRegion* dirtyRegion;
aView->GetDirtyRegion(dirtyRegion);
if ((nsnull != dirtyRegion) && !dirtyRegion->IsEmpty())
@@ -595,11 +574,10 @@ void nsViewManager2::Refresh(nsIView *aView, nsIRenderingContext *aContext, cons
if (nsnull != mCompositeListeners) {
PRUint32 listenerCount;
if (NS_SUCCEEDED(mCompositeListeners->Count(&listenerCount))) {
nsICompositeListener* listener;
nsCOMPtr<nsICompositeListener> listener;
for (PRUint32 i = 0; i < listenerCount; i++) {
if (NS_SUCCEEDED(mCompositeListeners->QueryElementAt(i, NS_GET_IID(nsICompositeListener), (void**)&listener))) {
if (NS_SUCCEEDED(mCompositeListeners->QueryElementAt(i, NS_GET_IID(nsICompositeListener), getter_AddRefs(listener)))) {
listener->DidRefreshRect(this, aView, aContext, rect, aUpdateFlags);
NS_RELEASE(listener);
}
}
}
@@ -619,76 +597,108 @@ typedef enum
COMPOSITION_DONE
} nsCompState;
//bit shifts
#define TRANS_PROPERTY_TRANS 0
#define TRANS_PROPERTY_OPACITY 1
#ifdef XP_MAC
#include <Events.h>
static Boolean caps_lock()
{
EventRecord event;
::OSEventAvail(0, &event);
return ((event.modifiers & alphaLock) != 0);
}
#else
#define caps_lock() (0)
#endif
void nsViewManager2::RenderViews(nsIView *aRootView, nsIRenderingContext& aRC, const nsRect& aRect, PRBool &aResult)
{
// Paint the view. The clipping rect was set above set don't clip again.
aRootView->Paint(aRC, aRect, NS_VIEW_FLAG_CLIP_SET, aResult);
PRBool isFloatingView = PR_FALSE;
if (NS_SUCCEEDED(aRootView->GetFloating(isFloatingView)) && isFloatingView) {
// floating views are rendered locally (and act globally).
// Paint the view. The clipping rect was set above set don't clip again.
aRootView->Paint(aRC, aRect, NS_VIEW_FLAG_CLIP_SET, aResult);
} else {
// otherwise, use display list to render non-floating views.
PRBool clipEmpty;
// create the display list. shouldn't we be able to just create this once?
nsPoint origin(0, 0);
ComputeViewOffset(aRootView, &origin.x, &origin.y, 1);
PRInt32 count = 0;
CreateDisplayList(mRootView, &count, origin.x, origin.y, aRootView, &aRect);
// draw all views in the display list, from back to front.
for (PRInt32 i = count - 1; i>= 0; --i) {
DisplayListElement* element = static_cast<DisplayListElement*>(mDisplayList->ElementAt(i));
if (element->mFlags & PUSH_CLIP) {
aRC.PushState();
aRC.SetClipRect(element->mClip, nsClipCombine_kIntersect, clipEmpty);
} else
if (element->mFlags & POP_CLIP) {
aRC.PopState(clipEmpty);
} else {
RenderView(element->mView, aRC, aRect, element->mClip, aResult);
}
}
}
}
void nsViewManager2::RenderView(nsIView *aView, nsIRenderingContext &aRC, const nsRect &aDamageRect, nsRect &aGlobalRect, PRBool &aResult)
{
nsRect drect;
nsRect drect;
NS_ASSERTION(!(nsnull == aView), "no view");
NS_ASSERTION(!(nsnull == aView), "no view");
aRC.PushState();
aRC.PushState();
aRC.Translate(aGlobalRect.x, aGlobalRect.y);
aRC.Translate(aGlobalRect.x, aGlobalRect.y);
drect.IntersectRect(aDamageRect, aGlobalRect);
drect.IntersectRect(aDamageRect, aGlobalRect);
drect.x -= aGlobalRect.x;
drect.y -= aGlobalRect.y;
drect.x -= aGlobalRect.x;
drect.y -= aGlobalRect.y;
aView->Paint(aRC, drect, NS_VIEW_FLAG_JUST_PAINT, aResult);
aView->Paint(aRC, drect, NS_VIEW_FLAG_JUST_PAINT, aResult);
aRC.PopState(aResult);
aRC.PopState(aResult);
}
void nsViewManager2::UpdateDirtyViews(nsIView *aView, nsRect *aParentRect) const
{
nsRect bounds;
aView->GetBounds(bounds);
nsRect bounds;
aView->GetBounds(bounds);
// translate parent rect into child coords.
nsRect parDamage;
if (nsnull != aParentRect) {
parDamage = *aParentRect;
parDamage.IntersectRect(bounds, parDamage);
parDamage.MoveBy(-bounds.x, -bounds.y);
} else
parDamage = bounds;
// translate parent rect into child coords.
nsRect parDamage;
if (nsnull != aParentRect) {
parDamage = *aParentRect;
parDamage.IntersectRect(bounds, parDamage);
parDamage.MoveBy(-bounds.x, -bounds.y);
} else
parDamage = bounds;
if (PR_FALSE == parDamage.IsEmpty()) {
nsIWidget *widget;
aView->GetWidget(widget);
if (nsnull != widget) {
float scale;
nsRect pixrect = parDamage;
if (PR_FALSE == parDamage.IsEmpty()) {
nsCOMPtr<nsIWidget> widget;
aView->GetWidget(*getter_AddRefs(widget));
if (nsnull != widget) {
nsRect pixrect = parDamage;
mContext->GetAppUnitsToDevUnits(scale);
pixrect.ScaleRoundOut(scale);
float scale;
mContext->GetAppUnitsToDevUnits(scale);
pixrect.ScaleRoundOut(scale);
//printf("invalidating: view %x (pix) %d, %d\n", aView, pixrect.width, pixrect.height);
widget->Invalidate(pixrect, PR_FALSE);
//printf("invalidating: view %x (pix) %d, %d\n", aView, pixrect.width, pixrect.height);
widget->Invalidate(pixrect, PR_FALSE);
}
}
NS_RELEASE(widget);
}
}
// Check our child views
nsIView *child;
aView->GetChild(0, child);
while (nsnull != child) {
UpdateDirtyViews(child, &parDamage);
child->GetNextSibling(child);
}
// Check our child views
nsIView *child;
aView->GetChild(0, child);
while (nsnull != child) {
UpdateDirtyViews(child, &parDamage);
child->GetNextSibling(child);
}
}
void nsViewManager2::ProcessPendingUpdates(nsIView* aView)
@@ -1094,6 +1104,12 @@ NS_IMETHODIMP nsViewManager2::InsertChild(nsIView *parent, nsIView *child, nsIVi
UpdateTransCnt(nsnull, child);
// if the parent view is marked as "floating", make the newly added view float as well.
PRBool isFloating = PR_FALSE;
parent->GetFloating(isFloating);
if (isFloating)
child->SetFloating(isFloating);
//and mark this area as dirty if the view is visible...
nsViewVisibility visibility;
@@ -1141,9 +1157,14 @@ NS_IMETHODIMP nsViewManager2::InsertChild(nsIView *parent, nsIView *child, PRInt
UpdateTransCnt(nsnull, child);
// if the parent view is marked as "floating", make the newly added view float as well.
PRBool isFloating = PR_FALSE;
parent->GetFloating(isFloating);
if (isFloating)
child->SetFloating(isFloating);
//and mark this area as dirty if the view is visible...
nsViewVisibility visibility;
child->GetVisibility(visibility);
if (nsViewVisibility_kHide != visibility)
@@ -1429,27 +1450,25 @@ NS_IMETHODIMP nsViewManager2::SetViewOpacity(nsIView *aView, float aOpacity)
NS_IMETHODIMP nsViewManager2::SetViewObserver(nsIViewObserver *aObserver)
{
mObserver = aObserver;
return NS_OK;
mObserver = aObserver;
return NS_OK;
}
NS_IMETHODIMP nsViewManager2::GetViewObserver(nsIViewObserver *&aObserver)
{
if (nsnull != mObserver)
{
aObserver = mObserver;
NS_ADDREF(mObserver);
return NS_OK;
}
else
return NS_ERROR_NO_INTERFACE;
if (nsnull != mObserver) {
aObserver = mObserver;
NS_ADDREF(mObserver);
return NS_OK;
} else
return NS_ERROR_NO_INTERFACE;
}
NS_IMETHODIMP nsViewManager2::GetDeviceContext(nsIDeviceContext *&aContext)
{
NS_IF_ADDREF(mContext);
aContext = mContext;
return NS_OK;
NS_IF_ADDREF(mContext);
aContext = mContext;
return NS_OK;
}
#ifndef max
@@ -1458,39 +1477,37 @@ NS_IMETHODIMP nsViewManager2::GetDeviceContext(nsIDeviceContext *&aContext)
nsDrawingSurface nsViewManager2::GetDrawingSurface(nsIRenderingContext &aContext, nsRect& aBounds)
{
if ((nsnull == mDrawingSurface)
|| (mDSBounds.width < aBounds.width)
|| (mDSBounds.height < aBounds.height))
{
if ((nsnull == mDrawingSurface)
|| (mDSBounds.width < aBounds.width)
|| (mDSBounds.height < aBounds.height))
{
nsRect newBounds;
newBounds.MoveTo(aBounds.x, aBounds.y);
newBounds.width = max(aBounds.width, mDSBounds.width);
newBounds.height = max(aBounds.height, mDSBounds.height);
if (mDrawingSurface) {
//destroy existing DS
aContext.DestroyDrawingSurface(mDrawingSurface);
mDrawingSurface = nsnull;
}
if (mDrawingSurface) {
//destroy existing DS
aContext.DestroyDrawingSurface(mDrawingSurface);
mDrawingSurface = nsnull;
}
nsresult rv = aContext.CreateDrawingSurface(&newBounds, 0, mDrawingSurface);
nsresult rv = aContext.CreateDrawingSurface(&newBounds, 0, mDrawingSurface);
if (NS_SUCCEEDED(rv)) {
mDSBounds = newBounds;
mDSBounds = newBounds;
aContext.SelectOffScreenDrawingSurface(mDrawingSurface);
}
else {
mDSBounds.SetRect(0,0,0,0);
mDrawingSurface = nsnull;
}
}
else {
} else {
mDSBounds.SetRect(0,0,0,0);
mDrawingSurface = nsnull;
}
} else {
aContext.SelectOffScreenDrawingSurface(mDrawingSurface);
float p2t;
mContext->GetDevUnitsToAppUnits(p2t);
nsRect bounds = aBounds;
bounds *= p2t;
mContext->GetDevUnitsToAppUnits(p2t);
nsRect bounds = aBounds;
bounds *= p2t;
PRBool clipEmpty;
aContext.SetClipRect(bounds, nsClipCombine_kReplace, clipEmpty);
@@ -1498,9 +1515,9 @@ nsDrawingSurface nsViewManager2::GetDrawingSurface(nsIRenderingContext &aContext
nscolor col = NS_RGB(255,255,255);
aContext.SetColor(col);
//aContext.FillRect(bounds);
}
}
return mDrawingSurface;
return mDrawingSurface;
}
NS_IMETHODIMP nsViewManager2::ShowQuality(PRBool aShow)
@@ -1530,14 +1547,13 @@ NS_IMETHODIMP nsViewManager2::SetQuality(nsContentQuality aQuality)
nsIRenderingContext * nsViewManager2::CreateRenderingContext(nsIView &aView)
{
nsIView *par = &aView;
nsIWidget *win;
nsCOMPtr<nsIWidget> win;
nsIRenderingContext *cx = nsnull;
nscoord x, y, ax = 0, ay = 0;
do
{
par->GetWidget(win);
par->GetWidget(*getter_AddRefs(win));
if (nsnull != win)
break;
@@ -1565,8 +1581,6 @@ nsIRenderingContext * nsViewManager2::CreateRenderingContext(nsIView &aView)
if (nsnull != cx)
cx->Translate(ax, ay);
NS_RELEASE(win);
}
return cx;
@@ -1766,128 +1780,118 @@ PRBool nsViewManager2::CreateDisplayList(nsIView *aView, PRInt32 *aIndex,
const nsRect *aDamageRect, nsIView *aTopView,
nsVoidArray *aArray, nscoord aX, nscoord aY)
{
PRInt32 numkids, zindex;
PRBool hasWidget, retval = PR_FALSE;
nsIClipView *clipper = nsnull;
nsPoint *point;
nsIView *child = nsnull;
PRInt32 numkids, zindex;
PRBool retval = PR_FALSE;
nsIClipView *clipper = nsnull;
nsPoint *point;
nsIView *child = nsnull;
NS_ASSERTION(!(!aView), "no view");
NS_ASSERTION(!(!aIndex), "no index");
NS_ASSERTION(!(!aView), "no view");
NS_ASSERTION(!(!aIndex), "no index");
if (!aArray)
{
if (!mDisplayList)
mDisplayList = new nsVoidArray(8);
if (!aArray) {
if (!mDisplayList)
mDisplayList = new nsVoidArray(8);
aArray = mDisplayList;
aArray = mDisplayList;
if (!aArray)
return PR_TRUE;
}
if (!aArray)
return PR_TRUE;
}
if (!aTopView)
aTopView = aView;
if (!aTopView)
aTopView = aView;
nsRect lrect;
aView->GetBounds(lrect);
nsRect lrect;
if (aView == aTopView) {
lrect.x = 0;
lrect.y = 0;
}
aView->GetBounds(lrect);
lrect.x += aX;
lrect.y += aY;
if (aView == aTopView)
{
lrect.x = 0;
lrect.y = 0;
}
aView->QueryInterface(NS_GET_IID(nsIClipView), (void **)&clipper);
aView->GetChildCount(numkids);
aView->GetScratchPoint(&point);
lrect.x += aX;
lrect.y += aY;
PRBool hasWidget = DoesViewHaveNativeWidget(*aView);
aView->QueryInterface(NS_GET_IID(nsIClipView), (void **)&clipper);
aView->GetChildCount(numkids);
aView->GetScratchPoint(&point);
if (numkids > 0) {
if (clipper && (!hasWidget || (hasWidget && point->x))) {
lrect.x -= aOriginX;
lrect.y -= aOriginY;
hasWidget = DoesViewHaveNativeWidget(*aView);
retval = AddToDisplayList(aArray, aIndex, aView, lrect, POP_CLIP);
if (numkids > 0)
{
if (clipper && (!hasWidget || (hasWidget && point->x)))
{
lrect.x -= aOriginX;
lrect.y -= aOriginY;
if (retval)
return retval;
retval = AddToDisplayList(aArray, aIndex, aView, lrect, PUSH_CLIP);
lrect.x += aOriginX;
lrect.y += aOriginY;
}
if (retval)
return retval;
if (!hasWidget || (hasWidget && point->x))
// if ((aView == aTopView) || (aView == aRealView))
// if ((aView == aTopView) || !hasWidget || (aView == aRealView))
// if ((aView == aTopView) || !(hasWidget && clipper) || (aView == aRealView))
{
for (aView->GetChild(0, child); nsnull != child; child->GetNextSibling(child)) {
child->GetZIndex(zindex);
if (zindex < 0)
break;
retval = CreateDisplayList(child, aIndex, aOriginX, aOriginY, aRealView, aDamageRect, aTopView, aArray, lrect.x, lrect.y);
if (retval)
break;
}
}
}
lrect.x += aOriginX;
lrect.y += aOriginY;
}
lrect.x -= aOriginX;
lrect.y -= aOriginY;
if (!hasWidget || (hasWidget && point->x))
// if ((aView == aTopView) || (aView == aRealView))
// if ((aView == aTopView) || !hasWidget || (aView == aRealView))
// if ((aView == aTopView) || !(hasWidget && clipper) || (aView == aRealView))
{
for (aView->GetChild(0, child); nsnull != child; child->GetNextSibling(child))
{
child->GetZIndex(zindex);
if (zindex < 0)
break;
retval = CreateDisplayList(child, aIndex, aOriginX, aOriginY, aRealView, aDamageRect, aTopView, aArray, lrect.x, lrect.y);
if (retval)
break;
}
}
}
// if (clipper)
if (clipper && (!hasWidget || (hasWidget && point->x))) {
if (numkids > 0)
retval = AddToDisplayList(aArray, aIndex, aView, lrect, PUSH_CLIP);
} else if (!retval) {
nsViewVisibility vis;
float opacity;
PRBool overlap;
PRBool trans;
nsRect irect;
lrect.x -= aOriginX;
lrect.y -= aOriginY;
aView->GetVisibility(vis);
aView->GetOpacity(opacity);
aView->HasTransparency(trans);
// if (clipper)
if (clipper && (!hasWidget || (hasWidget && point->x)))
{
if (numkids > 0)
retval = AddToDisplayList(aArray, aIndex, aView, lrect, POP_CLIP);
}
else if (!retval)
{
nsViewVisibility vis;
float opacity;
PRBool overlap;
PRBool trans;
nsRect irect;
if (aDamageRect)
overlap = irect.IntersectRect(lrect, *aDamageRect);
else
overlap = PR_TRUE;
aView->GetVisibility(vis);
aView->GetOpacity(opacity);
aView->HasTransparency(trans);
if ((nsViewVisibility_kShow == vis) && (opacity > 0.0f) && overlap)
{
retval = AddToDisplayList(aArray, aIndex, aView, lrect, 0);
if (aDamageRect)
overlap = irect.IntersectRect(lrect, *aDamageRect);
else
overlap = PR_TRUE;
if (retval || !trans && (opacity == 1.0f) && (irect == *aDamageRect))
retval = PR_TRUE;
}
if ((nsViewVisibility_kShow == vis) && (opacity > 0.0f) && overlap)
{
retval = AddToDisplayList(aArray, aIndex, aView, lrect, 0);
// any children with negative z-indices?
if (!retval && nsnull != child) {
lrect.x += aOriginX;
lrect.y += aOriginY;
for (; nsnull != child; child->GetNextSibling(child)) {
retval = CreateDisplayList(child, aIndex, aOriginX, aOriginY, aRealView, aDamageRect, aTopView, aArray, lrect.x, lrect.y);
if (retval)
break;
}
}
}
if (retval || !trans && (opacity == 1.0f) && (irect == *aDamageRect))
retval = PR_TRUE;
}
// any children with negative z-indices?
if (!retval && nsnull != child) {
lrect.x += aOriginX;
lrect.y += aOriginY;
for (; nsnull != child; child->GetNextSibling(child)) {
retval = CreateDisplayList(child, aIndex, aOriginX, aOriginY, aRealView, aDamageRect, aTopView, aArray, lrect.x, lrect.y);
if (retval)
break;
}
}
}
return retval;
return retval;
}
PRBool nsViewManager2::AddToDisplayList(nsVoidArray *aArray, PRInt32 *aIndex, nsIView *aView, nsRect &aRect, PRUint32 aFlags)
@@ -1998,23 +2002,11 @@ void nsViewManager2::ComputeViewOffset(nsIView *aView, nscoord *aX, nscoord *aY,
PRBool nsViewManager2::DoesViewHaveNativeWidget(nsIView &aView)
{
nsIWidget *widget;
PRBool retval = PR_FALSE;
aView.GetWidget(widget);
nsCOMPtr<nsIWidget> widget;
aView.GetWidget(*getter_AddRefs(widget));
if (nsnull != widget)
{
void *nativewidget;
nativewidget = widget->GetNativeData(NS_NATIVE_WIDGET);
NS_RELEASE(widget);
if (nsnull != nativewidget)
retval = PR_TRUE;
}
return retval;
return (nsnull != widget->GetNativeData(NS_NATIVE_WIDGET));
return PR_FALSE;
}
void nsViewManager2::PauseTimer(void)