зеркало из https://github.com/mozilla/pjs.git
Bug 164625. Native regions on Linux (and probably some other platforms) are limited to 16bit signed coordinates, so we have to use our own region implementation to manipulate regions in twips space. Using our own regions should also improve performance. r=kmcclusk,sr=kin
This commit is contained in:
Родитель
3824278a64
Коммит
beff719ea7
|
@ -958,6 +958,13 @@
|
|||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS>Debug</FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>nsRegion.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS>Debug</FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>nsTransform2D.cpp</PATH>
|
||||
|
|
|
@ -27,7 +27,8 @@ VPATH = @srcdir@
|
|||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = gfx
|
||||
EXPORTS = nsFontList.h
|
||||
EXPORTS = nsFontList.h \
|
||||
nsRegion.h
|
||||
LIBRARY_NAME = gkgfx
|
||||
EXPORT_LIBRARY = 1
|
||||
REQUIRES = xpcom \
|
||||
|
@ -93,6 +94,7 @@ CPPSRCS = \
|
|||
nsNameValuePairDB.cpp \
|
||||
nsRenderingContextImpl.cpp \
|
||||
nsRect.cpp \
|
||||
nsRegion.cpp \
|
||||
nsTransform2D.cpp \
|
||||
nsScriptableRegion.cpp \
|
||||
nsGraphicsImpl.cpp \
|
||||
|
@ -108,7 +110,6 @@ endif
|
|||
|
||||
ifneq (,$(filter gtk gtk2 xlib os2,$(MOZ_WIDGET_TOOLKIT)))
|
||||
CPPSRCS += \
|
||||
nsRegion.cpp \
|
||||
nsRegionImpl.cpp \
|
||||
$(NULL)
|
||||
endif
|
||||
|
|
|
@ -56,11 +56,11 @@
|
|||
#include "nsLayoutAtoms.h"
|
||||
#include "nsIViewManager.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsIRegion.h"
|
||||
#include "nsGfxCIID.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsCSSRendering.h"
|
||||
#include "nsTransform2D.h"
|
||||
#include "nsRegion.h"
|
||||
|
||||
static NS_DEFINE_CID(kRegionCID, NS_REGION_CID);
|
||||
|
||||
|
@ -497,20 +497,6 @@ nsContainerFrame::PositionFrameView(nsIPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
static nsIRegion* CreateRegion()
|
||||
{
|
||||
nsIRegion* region;
|
||||
nsresult rv = nsComponentManager::CreateInstance(kRegionCID, nsnull, NS_GET_IID(nsIRegion), (void**)®ion);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (NS_SUCCEEDED(region->Init())) {
|
||||
return region;
|
||||
} else {
|
||||
NS_RELEASE(region);
|
||||
}
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
void
|
||||
nsContainerFrame::SyncFrameViewAfterReflow(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
|
@ -741,12 +727,9 @@ nsContainerFrame::SyncFrameViewAfterReflow(nsIPresContext* aPresContext,
|
|||
}
|
||||
|
||||
// Set clipping of child views.
|
||||
nsIRegion *region = CreateRegion();
|
||||
if (region != nsnull) {
|
||||
region->SetTo(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
|
||||
vm->SetViewChildClipRegion(aView, region);
|
||||
NS_RELEASE(region);
|
||||
}
|
||||
nsRegion region;
|
||||
region.Copy(nsRectFast(clipRect));
|
||||
vm->SetViewChildClipRegion(aView, ®ion);
|
||||
} else {
|
||||
// Remove clipping of child views.
|
||||
vm->SetViewChildClipRegion(aView, nsnull);
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
#include "nsHTMLContainerFrame.h" // view creation
|
||||
|
||||
#include "nsSimplePageSequence.h" // for nsSharedPageData
|
||||
#include "nsIRegion.h"
|
||||
#include "nsRegion.h"
|
||||
#include "nsIViewManager.h"
|
||||
|
||||
// for page number localization formatting
|
||||
|
@ -232,9 +232,9 @@ NS_IMETHODIMP nsPageFrame::Reflow(nsIPresContext* aPresContext,
|
|||
if (view) {
|
||||
nsCOMPtr<nsIViewManager> vm;
|
||||
view->GetViewManager(*getter_AddRefs(vm));
|
||||
nsCOMPtr<nsIRegion> region = dont_AddRef(nsSimplePageSequenceFrame::CreateRegion());
|
||||
region->SetTo(0,0, aDesiredSize.width, aDesiredSize.height);
|
||||
vm->SetViewChildClipRegion(view, region);
|
||||
nsRegion region;
|
||||
region.Copy(nsRectFast(0, 0, aDesiredSize.width, aDesiredSize.height));
|
||||
vm->SetViewChildClipRegion(view, ®ion);
|
||||
}
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
#include "nsIPrintPreviewContext.h"
|
||||
#include "nsIPrintContext.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsIRegion.h"
|
||||
#include "nsRegion.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
|
||||
#include "nsIPref.h" // for header/footer gap & ExtraMargin for Print Preview
|
||||
|
@ -636,20 +636,6 @@ nsSimplePageSequenceFrame::SetPageNumberFormat(const char* aPropName, const char
|
|||
|
||||
}
|
||||
|
||||
nsIRegion* nsSimplePageSequenceFrame::CreateRegion()
|
||||
{
|
||||
nsIRegion* region;
|
||||
nsresult rv = nsComponentManager::CreateInstance(kRegionCID, nsnull, NS_GET_IID(nsIRegion), (void**)®ion);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (NS_SUCCEEDED(region->Init())) {
|
||||
return region;
|
||||
} else {
|
||||
NS_RELEASE(region);
|
||||
}
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSimplePageSequenceFrame::StartPrint(nsIPresContext* aPresContext,
|
||||
nsIPrintSettings* aPrintSettings,
|
||||
|
@ -740,7 +726,6 @@ nsSimplePageSequenceFrame::StartPrint(nsIPresContext* aPresContext,
|
|||
PRInt32 pageNum = 1;
|
||||
nscoord y = 0;//mMargin.top;
|
||||
|
||||
nsCOMPtr<nsIRegion> emptyRegion = getter_AddRefs(CreateRegion());
|
||||
for (nsIFrame* page = mFrames.FirstChild(); nsnull != page; page->GetNextSibling(&page)) {
|
||||
nsIView* view = nsnull;
|
||||
page->GetView(aPresContext, &view);
|
||||
|
@ -756,7 +741,8 @@ nsSimplePageSequenceFrame::StartPrint(nsIPresContext* aPresContext,
|
|||
// sure the child views don't get asked to print
|
||||
// but my guess is that there won't be any
|
||||
vm->SetViewVisibility(view, nsViewVisibility_kHide);
|
||||
vm->SetViewChildClipRegion(view, emptyRegion);
|
||||
nsRegion emptyRegion;
|
||||
vm->SetViewChildClipRegion(view, &emptyRegion);
|
||||
} else {
|
||||
nsRect rect;
|
||||
page->GetRect(rect);
|
||||
|
|
|
@ -121,8 +121,6 @@ public:
|
|||
nscoord aWidth,
|
||||
nscoord aHeight);
|
||||
|
||||
static nsIRegion* CreateRegion();
|
||||
|
||||
/**
|
||||
* Get the "type" of the frame
|
||||
*
|
||||
|
|
|
@ -56,11 +56,11 @@
|
|||
#include "nsLayoutAtoms.h"
|
||||
#include "nsIViewManager.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsIRegion.h"
|
||||
#include "nsGfxCIID.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsCSSRendering.h"
|
||||
#include "nsTransform2D.h"
|
||||
#include "nsRegion.h"
|
||||
|
||||
static NS_DEFINE_CID(kRegionCID, NS_REGION_CID);
|
||||
|
||||
|
@ -497,20 +497,6 @@ nsContainerFrame::PositionFrameView(nsIPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
static nsIRegion* CreateRegion()
|
||||
{
|
||||
nsIRegion* region;
|
||||
nsresult rv = nsComponentManager::CreateInstance(kRegionCID, nsnull, NS_GET_IID(nsIRegion), (void**)®ion);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (NS_SUCCEEDED(region->Init())) {
|
||||
return region;
|
||||
} else {
|
||||
NS_RELEASE(region);
|
||||
}
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
void
|
||||
nsContainerFrame::SyncFrameViewAfterReflow(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
|
@ -741,12 +727,9 @@ nsContainerFrame::SyncFrameViewAfterReflow(nsIPresContext* aPresContext,
|
|||
}
|
||||
|
||||
// Set clipping of child views.
|
||||
nsIRegion *region = CreateRegion();
|
||||
if (region != nsnull) {
|
||||
region->SetTo(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
|
||||
vm->SetViewChildClipRegion(aView, region);
|
||||
NS_RELEASE(region);
|
||||
}
|
||||
nsRegion region;
|
||||
region.Copy(nsRectFast(clipRect));
|
||||
vm->SetViewChildClipRegion(aView, ®ion);
|
||||
} else {
|
||||
// Remove clipping of child views.
|
||||
vm->SetViewChildClipRegion(aView, nsnull);
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
#include "nsHTMLContainerFrame.h" // view creation
|
||||
|
||||
#include "nsSimplePageSequence.h" // for nsSharedPageData
|
||||
#include "nsIRegion.h"
|
||||
#include "nsRegion.h"
|
||||
#include "nsIViewManager.h"
|
||||
|
||||
// for page number localization formatting
|
||||
|
@ -232,9 +232,9 @@ NS_IMETHODIMP nsPageFrame::Reflow(nsIPresContext* aPresContext,
|
|||
if (view) {
|
||||
nsCOMPtr<nsIViewManager> vm;
|
||||
view->GetViewManager(*getter_AddRefs(vm));
|
||||
nsCOMPtr<nsIRegion> region = dont_AddRef(nsSimplePageSequenceFrame::CreateRegion());
|
||||
region->SetTo(0,0, aDesiredSize.width, aDesiredSize.height);
|
||||
vm->SetViewChildClipRegion(view, region);
|
||||
nsRegion region;
|
||||
region.Copy(nsRectFast(0, 0, aDesiredSize.width, aDesiredSize.height));
|
||||
vm->SetViewChildClipRegion(view, ®ion);
|
||||
}
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
#include "nsIPrintPreviewContext.h"
|
||||
#include "nsIPrintContext.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsIRegion.h"
|
||||
#include "nsRegion.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
|
||||
#include "nsIPref.h" // for header/footer gap & ExtraMargin for Print Preview
|
||||
|
@ -636,20 +636,6 @@ nsSimplePageSequenceFrame::SetPageNumberFormat(const char* aPropName, const char
|
|||
|
||||
}
|
||||
|
||||
nsIRegion* nsSimplePageSequenceFrame::CreateRegion()
|
||||
{
|
||||
nsIRegion* region;
|
||||
nsresult rv = nsComponentManager::CreateInstance(kRegionCID, nsnull, NS_GET_IID(nsIRegion), (void**)®ion);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (NS_SUCCEEDED(region->Init())) {
|
||||
return region;
|
||||
} else {
|
||||
NS_RELEASE(region);
|
||||
}
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSimplePageSequenceFrame::StartPrint(nsIPresContext* aPresContext,
|
||||
nsIPrintSettings* aPrintSettings,
|
||||
|
@ -740,7 +726,6 @@ nsSimplePageSequenceFrame::StartPrint(nsIPresContext* aPresContext,
|
|||
PRInt32 pageNum = 1;
|
||||
nscoord y = 0;//mMargin.top;
|
||||
|
||||
nsCOMPtr<nsIRegion> emptyRegion = getter_AddRefs(CreateRegion());
|
||||
for (nsIFrame* page = mFrames.FirstChild(); nsnull != page; page->GetNextSibling(&page)) {
|
||||
nsIView* view = nsnull;
|
||||
page->GetView(aPresContext, &view);
|
||||
|
@ -756,7 +741,8 @@ nsSimplePageSequenceFrame::StartPrint(nsIPresContext* aPresContext,
|
|||
// sure the child views don't get asked to print
|
||||
// but my guess is that there won't be any
|
||||
vm->SetViewVisibility(view, nsViewVisibility_kHide);
|
||||
vm->SetViewChildClipRegion(view, emptyRegion);
|
||||
nsRegion emptyRegion;
|
||||
vm->SetViewChildClipRegion(view, &emptyRegion);
|
||||
} else {
|
||||
nsRect rect;
|
||||
page->GetRect(rect);
|
||||
|
|
|
@ -121,8 +121,6 @@ public:
|
|||
nscoord aWidth,
|
||||
nscoord aHeight);
|
||||
|
||||
static nsIRegion* CreateRegion();
|
||||
|
||||
/**
|
||||
* Get the "type" of the frame
|
||||
*
|
||||
|
|
|
@ -47,9 +47,9 @@ class nsIScrollableView;
|
|||
class nsIWidget;
|
||||
class nsICompositeListener;
|
||||
struct nsRect;
|
||||
class nsRegion;
|
||||
class nsIDeviceContext;
|
||||
class nsIViewObserver;
|
||||
class nsIRegion;
|
||||
|
||||
enum nsContentQuality {
|
||||
nsContentQuality_kGood = 0,
|
||||
|
@ -278,7 +278,7 @@ public:
|
|||
*
|
||||
* XXX Currently we only support regions consisting of a single rectangle.
|
||||
*/
|
||||
NS_IMETHOD SetViewChildClipRegion(nsIView *aView, nsIRegion *aRegion) = 0;
|
||||
NS_IMETHOD SetViewChildClipRegion(nsIView *aView, const nsRegion *aRegion) = 0;
|
||||
|
||||
/**
|
||||
* Set the visibility of a view.
|
||||
|
|
|
@ -931,30 +931,19 @@ NS_IMETHODIMP nsView::GetOffsetFromWidget(nscoord *aDx, nscoord *aDy, nsIWidget
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsView::GetDirtyRegion(nsIRegion *&aRegion) const
|
||||
nsresult nsView::GetDirtyRegion(nsIRegion*& aRegion)
|
||||
{
|
||||
if (nsnull == mDirtyRegion) {
|
||||
// The view doesn't have a dirty region so create one
|
||||
nsresult rv = nsComponentManager::CreateInstance(kRegionCID,
|
||||
nsnull,
|
||||
NS_GET_IID(nsIRegion),
|
||||
(void**) &mDirtyRegion);
|
||||
if (nsnull == mDirtyRegion) {
|
||||
nsresult rv = GetViewManager()->CreateRegion(&mDirtyRegion);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = mDirtyRegion->Init();
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
|
||||
aRegion = mDirtyRegion;
|
||||
NS_ADDREF(aRegion);
|
||||
|
||||
return NS_OK;
|
||||
aRegion = mDirtyRegion;
|
||||
NS_ADDREF(aRegion);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsView::SetCompositorFlags(PRUint32 aFlags)
|
||||
{
|
||||
mCompositorFlags = aFlags;
|
||||
|
|
|
@ -240,7 +240,7 @@ public:
|
|||
* Gets the dirty region associated with this view. Used by the view
|
||||
* manager.
|
||||
*/
|
||||
NS_IMETHOD GetDirtyRegion(nsIRegion*& aRegion) const;
|
||||
nsresult GetDirtyRegion(nsIRegion*& aRegion);
|
||||
/**
|
||||
* Set the widget associated with this view.
|
||||
* @param aWidget widget to associate with view. It is an error
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
#include "nsIServiceManager.h"
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsIPref.h"
|
||||
#include "nsRegion.h"
|
||||
|
||||
static NS_DEFINE_IID(kBlenderCID, NS_BLENDER_CID);
|
||||
static NS_DEFINE_IID(kRegionCID, NS_REGION_CID);
|
||||
|
@ -395,8 +396,6 @@ nsViewManager::~nsViewManager()
|
|||
mContext = nsnull;
|
||||
|
||||
NS_IF_RELEASE(mBlender);
|
||||
NS_IF_RELEASE(mOpaqueRgn);
|
||||
NS_IF_RELEASE(mTmpRgn);
|
||||
|
||||
NS_IF_RELEASE(mOffScreenCX);
|
||||
NS_IF_RELEASE(mBlackCX);
|
||||
|
@ -436,27 +435,26 @@ nsrefcnt nsViewManager::Release(void)
|
|||
return mRefCnt;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsresult
|
||||
nsViewManager::CreateRegion(nsIRegion* *result)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
|
||||
if (!mRegionFactory) {
|
||||
nsCOMPtr<nsIComponentManager> compMgr;
|
||||
rv = NS_GetComponentManager(getter_AddRefs(compMgr));
|
||||
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = compMgr->GetClassObject(kRegionCID,
|
||||
NS_GET_IID(nsIFactory),
|
||||
rv = compMgr->GetClassObject(kRegionCID,
|
||||
NS_GET_IID(nsIFactory),
|
||||
getter_AddRefs(mRegionFactory));
|
||||
|
||||
|
||||
if (!mRegionFactory) {
|
||||
*result = nsnull;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
nsIRegion* region = nsnull;
|
||||
rv = mRegionFactory->CreateInstance(nsnull, NS_GET_IID(nsIRegion), (void**)®ion);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
|
@ -491,13 +489,6 @@ NS_IMETHODIMP nsViewManager::Init(nsIDeviceContext* aContext)
|
|||
mMouseGrabber = nsnull;
|
||||
mKeyGrabber = nsnull;
|
||||
|
||||
// create regions
|
||||
mOpaqueRgn = nsnull;
|
||||
mTmpRgn = nsnull;
|
||||
|
||||
CreateRegion(&mOpaqueRgn);
|
||||
CreateRegion(&mTmpRgn);
|
||||
|
||||
if (nsnull == mEventQueueService) {
|
||||
mEventQueueService = do_GetService(kEventQueueServiceCID);
|
||||
NS_ASSERTION(mEventQueueService, "couldn't get event queue service");
|
||||
|
@ -694,7 +685,8 @@ void nsViewManager::Refresh(nsView *aView, nsIRenderingContext *aContext, nsIReg
|
|||
}
|
||||
|
||||
nsRect damageRectInPixels;
|
||||
aRegion->GetBoundingBox(&damageRectInPixels.x, &damageRectInPixels.y, &damageRectInPixels.width, &damageRectInPixels.height);
|
||||
aRegion->GetBoundingBox(&damageRectInPixels.x, &damageRectInPixels.y,
|
||||
&damageRectInPixels.width, &damageRectInPixels.height);
|
||||
|
||||
if (aUpdateFlags & NS_VMREFRESH_DOUBLE_BUFFER)
|
||||
{
|
||||
|
@ -1005,9 +997,9 @@ static void PopState(nsIRenderingContext **aRCs, PRInt32 aRCCount) {
|
|||
}
|
||||
}
|
||||
|
||||
void nsViewManager::AddCoveringWidgetsToOpaqueRegion(nsIRegion* aRgn, nsIDeviceContext* aContext,
|
||||
void nsViewManager::AddCoveringWidgetsToOpaqueRegion(nsRegion &aRgn, nsIDeviceContext* aContext,
|
||||
nsView* aRootView) {
|
||||
// We accumulate the bounds of widgets obscuring aRootView's widget into mOpaqueRgn.
|
||||
// We accumulate the bounds of widgets obscuring aRootView's widget into opaqueRgn.
|
||||
// In OptimizeDisplayList, display list elements which lie behind obscuring native
|
||||
// widgets are dropped.
|
||||
// This shouldn't really be necessary, since the GFX/Widget toolkit should remove these
|
||||
|
@ -1019,53 +1011,58 @@ void nsViewManager::AddCoveringWidgetsToOpaqueRegion(nsIRegion* aRgn, nsIDeviceC
|
|||
//
|
||||
// NB: we must NOT add widgets that correspond to floating views!
|
||||
// We may be required to paint behind them
|
||||
if (aRgn) {
|
||||
aRgn->SetTo(0, 0, 0, 0);
|
||||
nsCOMPtr<nsIWidget> widget;
|
||||
GetWidgetForView(aRootView, getter_AddRefs(widget));
|
||||
if (widget) {
|
||||
nsCOMPtr<nsIEnumerator> children(dont_AddRef(widget->GetChildren()));
|
||||
if (children) {
|
||||
children->First();
|
||||
do {
|
||||
nsCOMPtr<nsISupports> child;
|
||||
if (NS_SUCCEEDED(children->CurrentItem(getter_AddRefs(child)))) {
|
||||
nsCOMPtr<nsIWidget> childWidget = do_QueryInterface(child);
|
||||
if (childWidget) {
|
||||
nsView* view = nsView::GetViewFor(childWidget);
|
||||
if (view) {
|
||||
nsViewVisibility visible = nsViewVisibility_kHide;
|
||||
view->GetVisibility(visible);
|
||||
if (visible == nsViewVisibility_kShow) {
|
||||
PRBool floating = PR_FALSE;
|
||||
view->GetFloating(floating);
|
||||
if (!floating) {
|
||||
nsRect bounds;
|
||||
view->GetBounds(bounds);
|
||||
if (bounds.width > 0 && bounds.height > 0) {
|
||||
nsView* viewParent = view->GetParent();
|
||||
aRgn.Empty();
|
||||
|
||||
while (viewParent && viewParent != aRootView) {
|
||||
viewParent->ConvertToParentCoords(&bounds.x, &bounds.y);
|
||||
viewParent = viewParent->GetParent();
|
||||
}
|
||||
nsCOMPtr<nsIWidget> widget;
|
||||
GetWidgetForView(aRootView, getter_AddRefs(widget));
|
||||
if (!widget) {
|
||||
return;
|
||||
}
|
||||
|
||||
// maybe we couldn't get the view into the coordinate
|
||||
// system of aRootView (maybe it's not a descendant
|
||||
// view of aRootView?); if so, don't use it
|
||||
if (viewParent) {
|
||||
aRgn->Union(bounds.x, bounds.y, bounds.width, bounds.height);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
nsCOMPtr<nsIEnumerator> children(dont_AddRef(widget->GetChildren()));
|
||||
if (!children) {
|
||||
return;
|
||||
}
|
||||
|
||||
children->First();
|
||||
do {
|
||||
nsCOMPtr<nsISupports> child;
|
||||
if (!NS_SUCCEEDED(children->CurrentItem(getter_AddRefs(child)))) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIWidget> childWidget = do_QueryInterface(child);
|
||||
if (childWidget) {
|
||||
nsView* view = nsView::GetViewFor(childWidget);
|
||||
if (view) {
|
||||
nsViewVisibility visible = nsViewVisibility_kHide;
|
||||
view->GetVisibility(visible);
|
||||
if (visible == nsViewVisibility_kShow) {
|
||||
PRBool floating = PR_FALSE;
|
||||
view->GetFloating(floating);
|
||||
if (!floating) {
|
||||
nsRect bounds;
|
||||
view->GetBounds(bounds);
|
||||
if (bounds.width > 0 && bounds.height > 0) {
|
||||
nsView* viewParent = view->GetParent();
|
||||
|
||||
while (viewParent && viewParent != aRootView) {
|
||||
viewParent->ConvertToParentCoords(&bounds.x, &bounds.y);
|
||||
viewParent = viewParent->GetParent();
|
||||
}
|
||||
|
||||
// maybe we couldn't get the view into the coordinate
|
||||
// system of aRootView (maybe it's not a descendant
|
||||
// view of aRootView?); if so, don't use it
|
||||
if (viewParent) {
|
||||
aRgn.Or(aRgn, nsRectFast(bounds));
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (NS_SUCCEEDED(children->Next()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (NS_SUCCEEDED(children->Next()));
|
||||
}
|
||||
|
||||
void nsViewManager::RenderViews(nsView *aRootView, nsIRenderingContext& aRC, const nsRect& aRect, PRBool &aResult)
|
||||
|
@ -1079,11 +1076,9 @@ void nsViewManager::RenderViews(nsView *aRootView, nsIRenderingContext& aRC, con
|
|||
|
||||
ReapplyClipInstructions(PR_FALSE, fakeClipRect, index);
|
||||
|
||||
if (nsnull != mOpaqueRgn) {
|
||||
mOpaqueRgn->SetTo(0, 0, 0, 0);
|
||||
AddCoveringWidgetsToOpaqueRegion(mOpaqueRgn, mContext, aRootView);
|
||||
OptimizeDisplayList(aRect, finalTransparentRect);
|
||||
}
|
||||
nsRegion opaqueRgn;
|
||||
AddCoveringWidgetsToOpaqueRegion(opaqueRgn, mContext, aRootView);
|
||||
OptimizeDisplayList(aRect, finalTransparentRect, opaqueRgn);
|
||||
|
||||
// ShowDisplayList(mDisplayListCount);
|
||||
|
||||
|
@ -1744,7 +1739,6 @@ NS_IMETHODIMP nsViewManager::DispatchEvent(nsGUIEvent *aEvent, nsEventStatus *aS
|
|||
doDefault = PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// since we got an NS_PAINT event, we need to
|
||||
// draw something so we don't get blank areas.
|
||||
|
@ -2457,7 +2451,7 @@ NS_IMETHODIMP nsViewManager::ResizeView(nsIView *aView, const nsRect &aRect, PRB
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsViewManager::SetViewChildClipRegion(nsIView *aView, nsIRegion *aRegion)
|
||||
NS_IMETHODIMP nsViewManager::SetViewChildClipRegion(nsIView *aView, const nsRegion *aRegion)
|
||||
{
|
||||
nsView* view = NS_STATIC_CAST(nsView*, aView);
|
||||
|
||||
|
@ -2478,7 +2472,7 @@ NS_IMETHODIMP nsViewManager::SetViewChildClipRegion(nsIView *aView, nsIRegion *a
|
|||
// and it is set to no more than the bounds of the view.
|
||||
if (aRegion != nsnull) {
|
||||
newClipFlag = PR_TRUE;
|
||||
aRegion->GetBoundingBox(&newClipRect.x, &newClipRect.y, &newClipRect.width, &newClipRect.height);
|
||||
aRegion->GetBoundRect(newClipRect);
|
||||
if (IsClipView(view)) {
|
||||
nsRect dims;
|
||||
view->GetDimensions(dims);
|
||||
|
@ -2626,23 +2620,21 @@ PRBool nsViewManager::CanScrollWithBitBlt(nsView* aView)
|
|||
}
|
||||
}
|
||||
|
||||
if (nsnull != mOpaqueRgn) {
|
||||
nsRect finalTransparentRect;
|
||||
nsRect finalTransparentRect;
|
||||
|
||||
mOpaqueRgn->SetTo(0, 0, 0, 0);
|
||||
// We DON'T use AddCoveringWidgetsToOpaqueRegion here. Our child widgets are going to be moved
|
||||
// as if they were scrolled, so we need to examine the display list elements that might be covered by
|
||||
// child widgets.
|
||||
|
||||
// We DO need to use OptimizeDisplayList here to eliminate views that are covered by views we know
|
||||
// are opaque. Typically aView itself is opaque and we want to eliminate views behind aView, such as
|
||||
// aView's parent, that aren't being scrolled and would otherwise cause us to decide not to blit.
|
||||
|
||||
// (Of course it's possible that aView's parent is actually in front of aView (if aView has a negative
|
||||
// z-index) but if so, this code still does the right thing. Yay for the display list based approach!)
|
||||
OptimizeDisplayList(r, finalTransparentRect);
|
||||
}
|
||||
// We DON'T use AddCoveringWidgetsToOpaqueRegion here. Our child widgets are going to be moved
|
||||
// as if they were scrolled, so we need to examine the display list elements that might be covered by
|
||||
// child widgets.
|
||||
|
||||
// We DO need to use OptimizeDisplayList here to eliminate views that are covered by views we know
|
||||
// are opaque. Typically aView itself is opaque and we want to eliminate views behind aView, such as
|
||||
// aView's parent, that aren't being scrolled and would otherwise cause us to decide not to blit.
|
||||
|
||||
// (Of course it's possible that aView's parent is actually in front of aView (if aView has a negative
|
||||
// z-index) but if so, this code still does the right thing. Yay for the display list based approach!)
|
||||
nsRegion opaqueRegion; // empty; no opaque overlay
|
||||
OptimizeDisplayList(r, finalTransparentRect, opaqueRegion);
|
||||
|
||||
PRBool anyUnscrolledViews = PR_FALSE;
|
||||
PRBool anyUnblittableViews = PR_FALSE;
|
||||
|
||||
|
@ -3550,9 +3542,6 @@ void nsViewManager::ReapplyClipInstructions(PRBool aHaveClip, nsRect& aClipRect,
|
|||
/**
|
||||
Walk the display list, looking for opaque views, and remove any views that are behind them
|
||||
and totally occluded.
|
||||
We rely on a good region implementation. If nsIRegion doesn't cut it, we can disable this
|
||||
optimization ... or better still, fix nsIRegion on that platform.
|
||||
It seems to be good on Windows.
|
||||
|
||||
@param aFinalTransparentRect
|
||||
Receives a rectangle enclosing all pixels in the damage rectangle
|
||||
|
@ -3560,40 +3549,37 @@ void nsViewManager::ReapplyClipInstructions(PRBool aHaveClip, nsRect& aClipRect,
|
|||
Usually this will be empty, but nothing really prevents someone
|
||||
from creating a set of views that are (for example) all transparent.
|
||||
*/
|
||||
nsresult nsViewManager::OptimizeDisplayList(const nsRect& aDamageRect, nsRect& aFinalTransparentRect)
|
||||
nsresult nsViewManager::OptimizeDisplayList(const nsRect& aDamageRect, nsRect& aFinalTransparentRect,
|
||||
nsRegion &aOpaqueRegion)
|
||||
{
|
||||
aFinalTransparentRect = aDamageRect;
|
||||
|
||||
if (nsnull == mOpaqueRgn || nsnull == mTmpRgn) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRInt32 count = mDisplayListCount;
|
||||
for (PRInt32 i = count - 1; i >= 0; i--) {
|
||||
DisplayListElement2* element = NS_STATIC_CAST(DisplayListElement2*, mDisplayList.ElementAt(i));
|
||||
if (element->mFlags & VIEW_RENDERED) {
|
||||
mTmpRgn->SetTo(element->mBounds.x, element->mBounds.y, element->mBounds.width, element->mBounds.height);
|
||||
mTmpRgn->Subtract(*mOpaqueRgn);
|
||||
nsRegion tmpRgn;
|
||||
tmpRgn.Copy(nsRectFast(element->mBounds));
|
||||
tmpRgn.Sub(tmpRgn, aOpaqueRegion);
|
||||
|
||||
if (mTmpRgn->IsEmpty()) {
|
||||
if (tmpRgn.IsEmpty()) {
|
||||
element->mFlags &= ~VIEW_RENDERED;
|
||||
} else {
|
||||
mTmpRgn->GetBoundingBox(&element->mBounds.x, &element->mBounds.y,
|
||||
&element->mBounds.width, &element->mBounds.height);
|
||||
tmpRgn.GetBoundRect(element->mBounds);
|
||||
|
||||
// a view is opaque if it is neither transparent nor transluscent
|
||||
if (!(element->mFlags & (VIEW_TRANSPARENT | VIEW_TRANSLUCENT))) {
|
||||
mOpaqueRgn->Union(element->mBounds.x, element->mBounds.y, element->mBounds.width, element->mBounds.height);
|
||||
aOpaqueRegion.Or(aOpaqueRegion, nsRectFast(element->mBounds));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mTmpRgn->SetTo(aDamageRect.x, aDamageRect.y, aDamageRect.width, aDamageRect.height);
|
||||
mTmpRgn->Subtract(*mOpaqueRgn);
|
||||
mTmpRgn->GetBoundingBox(&aFinalTransparentRect.x, &aFinalTransparentRect.y,
|
||||
&aFinalTransparentRect.width, &aFinalTransparentRect.height);
|
||||
|
||||
nsRegion tmpRgn;
|
||||
tmpRgn.Copy(nsRectFast(aDamageRect));
|
||||
tmpRgn.Sub(tmpRgn, aOpaqueRegion);
|
||||
tmpRgn.GetBoundRect(aFinalTransparentRect);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -171,7 +171,7 @@ public:
|
|||
|
||||
NS_IMETHOD ResizeView(nsIView *aView, const nsRect &aRect, PRBool aRepaintExposedAreaOnly = PR_FALSE);
|
||||
|
||||
NS_IMETHOD SetViewChildClipRegion(nsIView *aView, nsIRegion *aRegion);
|
||||
NS_IMETHOD SetViewChildClipRegion(nsIView *aView, const nsRegion *aRegion);
|
||||
|
||||
NS_IMETHOD SetViewBitBltEnabled(nsIView *aView, PRBool aEnable);
|
||||
|
||||
|
@ -278,11 +278,11 @@ private:
|
|||
PRBool AddToDisplayList(nsView *aView, DisplayZTreeNode* &aParent, nsRect &aClipRect,
|
||||
nsRect& aDirtyRect, PRUint32 aFlags, nscoord aAbsX, nscoord aAbsY, PRBool aAssumeIntersection);
|
||||
void ReapplyClipInstructions(PRBool aHaveClip, nsRect& aClipRect, PRInt32& aIndex);
|
||||
nsresult OptimizeDisplayList(const nsRect& aDamageRect, nsRect& aFinalTransparentRect);
|
||||
nsresult OptimizeDisplayList(const nsRect& aDamageRect, nsRect& aFinalTransparentRect, nsRegion& aOpaqueRgn);
|
||||
// Remove redundant PUSH/POP_CLIP pairs.
|
||||
void ComputeViewOffset(nsView *aView, nsPoint *aOrigin);
|
||||
|
||||
void AddCoveringWidgetsToOpaqueRegion(nsIRegion* aRgn, nsIDeviceContext* aContext,
|
||||
void AddCoveringWidgetsToOpaqueRegion(nsRegion &aRgn, nsIDeviceContext* aContext,
|
||||
nsView* aRootView);
|
||||
|
||||
// Predicates
|
||||
|
@ -364,6 +364,8 @@ public: // NOT in nsIViewManager, so private to the view module
|
|||
|
||||
PRBool CanScrollWithBitBlt(nsView* aView);
|
||||
|
||||
nsresult CreateRegion(nsIRegion* *result);
|
||||
|
||||
private:
|
||||
nsIDeviceContext *mContext;
|
||||
float mTwipsToPixels;
|
||||
|
@ -404,10 +406,6 @@ private:
|
|||
//list of view managers
|
||||
static nsVoidArray *gViewManagers;
|
||||
|
||||
//compositor regions
|
||||
nsIRegion *mOpaqueRgn;
|
||||
nsIRegion *mTmpRgn;
|
||||
|
||||
nsIBlender *mBlender;
|
||||
|
||||
nsIRenderingContext *mOffScreenCX;
|
||||
|
@ -417,7 +415,6 @@ private:
|
|||
nsISupportsArray *mCompositeListeners;
|
||||
void DestroyZTreeNode(DisplayZTreeNode* aNode);
|
||||
|
||||
nsresult CreateRegion(nsIRegion* *result);
|
||||
nsCOMPtr<nsIFactory> mRegionFactory;
|
||||
protected:
|
||||
nsView *mRootView;
|
||||
|
|
Загрузка…
Ссылка в новой задаче