Support for Optimized GC and Regions in Rendering

git-svn-id: svn://10.0.0.236/trunk@4211 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
spider
1998-06-21 07:02:44 +00:00
parent 084c69d9c7
commit 81d3b16346
9 changed files with 342 additions and 198 deletions

View File

@@ -51,23 +51,28 @@ void nsRegionUnix :: SetTo(const nsIRegion &aRegion)
{
nsRegionUnix * pRegion = (nsRegionUnix *)&aRegion;
::XDestroyRegion(mRegion);
mRegion = ::XCreateRegion();
SetRegionEmpty();
::XUnionRegion(mRegion, pRegion->mRegion, mRegion);
mRegionType = eRegionType_rect ; // XXX: Should probably set to complex
SetRegionType();
}
void nsRegionUnix :: SetTo(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
{
::XDestroyRegion(mRegion);
mRegion = ::XCreateRegion();
::XOffsetRegion(mRegion, aX, aY);
::XShrinkRegion(mRegion, -aWidth, -aHeight);
SetRegionEmpty();
mRegionType = eRegionType_rect ;
XRectangle xrect;
xrect.x = aX;
xrect.y = aY;
xrect.width = aWidth;
xrect.height = aHeight;
::XUnionRectWithRegion(&xrect, mRegion, mRegion);
SetRegionType();
}
void nsRegionUnix :: Intersect(const nsIRegion &aRegion)
@@ -76,23 +81,19 @@ void nsRegionUnix :: Intersect(const nsIRegion &aRegion)
::XIntersectRegion(mRegion, pRegion->mRegion, mRegion);
mRegionType = eRegionType_rect ;
SetRegionType();
}
void nsRegionUnix :: Intersect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
{
Region tRegion;
Region tRegion = CreateRectRegion(aX, aY, aWidth, aHeight);
tRegion = ::XCreateRegion();
::XOffsetRegion(tRegion, aX, aY);
::XShrinkRegion(tRegion, -aWidth, -aHeight);
::XIntersectRegion(mRegion, tRegion, mRegion);
::XDestroyRegion(tRegion);
mRegionType = eRegionType_rect ;
SetRegionType();
}
void nsRegionUnix :: Union(const nsIRegion &aRegion)
@@ -101,23 +102,21 @@ void nsRegionUnix :: Union(const nsIRegion &aRegion)
::XUnionRegion(mRegion, pRegion->mRegion, mRegion);
mRegionType = eRegionType_rect ;
SetRegionType();
}
void nsRegionUnix :: Union(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
{
Region tRegion;
tRegion = ::XCreateRegion();
Region tRegion = CreateRectRegion(aX, aY, aWidth, aHeight);
::XOffsetRegion(tRegion, aX, aY);
::XShrinkRegion(tRegion, -aWidth, -aHeight);
::XUnionRegion(mRegion, tRegion, mRegion);
::XDestroyRegion(tRegion);
mRegionType = eRegionType_rect ;
SetRegionType();
}
void nsRegionUnix :: Subtract(const nsIRegion &aRegion)
@@ -126,27 +125,28 @@ void nsRegionUnix :: Subtract(const nsIRegion &aRegion)
::XSubtractRegion(mRegion, pRegion->mRegion, mRegion);
mRegionType = eRegionType_rect ;
SetRegionType();
}
void nsRegionUnix :: Subtract(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
{
Region tRegion;
tRegion = ::XCreateRegion();
::XOffsetRegion(tRegion, aX, aY);
::XShrinkRegion(tRegion, -aWidth, -aHeight);
Region tRegion = CreateRectRegion(aX, aY, aWidth, aHeight);
::XSubtractRegion(mRegion, tRegion, mRegion);
::XDestroyRegion(tRegion);
mRegionType = eRegionType_rect ;
SetRegionType();
}
PRBool nsRegionUnix :: IsEmpty(void)
{
return (::XEmptyRegion(mRegion));
if (mRegionType == eRegionType_empty)
return PR_TRUE;
return PR_FALSE;
}
PRBool nsRegionUnix :: IsEqual(const nsIRegion &aRegion)
@@ -197,3 +197,41 @@ Region nsRegionUnix :: GetXRegion(void)
{
return (mRegion);
}
void nsRegionUnix :: SetRegionType()
{
if (::XEmptyRegion(mRegion) == True)
mRegionType = eRegionType_empty;
else
mRegionType = eRegionType_rect ;
}
void nsRegionUnix :: SetRegionEmpty()
{
::XDestroyRegion(mRegion);
mRegion = ::XCreateRegion();
}
Region nsRegionUnix :: CreateRectRegion(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
{
Region r = ::XCreateRegion();
XRectangle xrect;
xrect.x = aX;
xrect.y = aY;
xrect.width = aWidth;
xrect.height = aHeight;
::XUnionRectWithRegion(&xrect, r, r);
return (r);
}

View File

@@ -63,6 +63,10 @@ private:
Region mRegion;
nsRegionType mRegionType;
private:
virtual void SetRegionType();
virtual void SetRegionEmpty();
virtual Region CreateRectRegion(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight);
};

View File

@@ -28,7 +28,18 @@
#include "X11/Xlib.h"
#include "X11/Xutil.h"
#define CLIPPING_NOT_FUNCTIONAL 1
//#define NO_CLIP
/*
Some Implementation Notes
REGIONS: Regions are clipping rects associated with a GC. Since
multiple Drawable's can and do share GC's (they are hardware cached)
In order to select clip rect's into GC's, they must be writeable. Thus,
any consumer of the 'gfx' library must assume that GC's created by them
will be modified in gfx.
*/
class GraphicsState
{
@@ -56,21 +67,9 @@ GraphicsState :: GraphicsState()
GraphicsState :: ~GraphicsState()
{
if (nsnull != mClipRegion)
{
::XDestroyRegion(mClipRegion);
mClipRegion = NULL;
}
mFont = nsnull;
}
typedef unsigned char BYTE;
#define RGB(r,g,b) ((unsigned long) (((BYTE) (r) | ((unsigned long) ((BYTE) (g)) <<8)) | (((unsigned long)(BYTE)(b)) << 16)))
static NS_DEFINE_IID(kRenderingContextIID, NS_IRENDERING_CONTEXT_IID);
nsRenderingContextUnix :: nsRenderingContextUnix()
@@ -103,8 +102,10 @@ nsRenderingContextUnix :: ~nsRenderingContextUnix()
}
mTMatrix = nsnull;
PopState();
// Destroy the State Machine
if (nsnull != mStateCache)
{
PRInt32 cnt = mStateCache->Count();
@@ -122,7 +123,14 @@ nsRenderingContextUnix :: ~nsRenderingContextUnix()
mStateCache = nsnull;
}
delete mFrontBuffer;
// Destroy the front buffer and it's GC if one was allocated for it
if (nsnull != mFrontBuffer) {
if (mFrontBuffer != mRenderingSurface) {
::XFreeGC(mFrontBuffer->display,
mFrontBuffer->gc);
}
delete mFrontBuffer;
}
}
NS_IMPL_QUERY_INTERFACE(nsRenderingContextUnix, kRenderingContextIID)
@@ -156,17 +164,7 @@ nsresult nsRenderingContextUnix :: Init(nsIDeviceContext* aContext,
mFrontBuffer = mRenderingSurface;
((nsDeviceContextUnix *)aContext)->SetDrawingSurface(mRenderingSurface);
((nsDeviceContextUnix *)aContext)->InstallColormap();
mFontCache = mContext->GetFontCache();
mP2T = mContext->GetDevUnitsToAppUnits();
mTMatrix->AddScale(mContext->GetAppUnitsToDevUnits(),
mContext->GetAppUnitsToDevUnits());
mRegion = ::XCreateRegion();
// Select a default font here?
return NS_OK;
return (CommonInit());
}
nsresult nsRenderingContextUnix :: Init(nsIDeviceContext* aContext,
@@ -177,20 +175,33 @@ nsresult nsRenderingContextUnix :: Init(nsIDeviceContext* aContext,
NS_IF_ADDREF(mContext);
mRenderingSurface = (nsDrawingSurfaceUnix *) aSurface;
((nsDeviceContextUnix *)aContext)->SetDrawingSurface(mRenderingSurface);
((nsDeviceContextUnix *)aContext)->InstallColormap();
return (CommonInit());
}
nsresult nsRenderingContextUnix :: CommonInit()
{
((nsDeviceContextUnix *)mContext)->SetDrawingSurface(mRenderingSurface);
((nsDeviceContextUnix *)mContext)->InstallColormap();
mFontCache = mContext->GetFontCache();
mP2T = mContext->GetDevUnitsToAppUnits();
mTMatrix->AddScale(mContext->GetAppUnitsToDevUnits(),
mContext->GetAppUnitsToDevUnits());
mRegion = ::XCreateRegion();
return NS_OK;
}
nsresult nsRenderingContextUnix :: SelectOffScreenDrawingSurface(nsDrawingSurface aSurface)
{
mRenderingSurface = (nsDrawingSurfaceUnix *) aSurface;
if (mFrontBuffer == mRenderingSurface) {
XGCValues values;
mFrontBuffer->gc = ::XCreateGC(mRenderingSurface->display,
mRenderingSurface->drawable,
nsnull, &values);
}
mRenderingSurface = (nsDrawingSurfaceUnix *) aSurface;
return NS_OK;
}
@@ -206,6 +217,9 @@ nsIDeviceContext * nsRenderingContextUnix :: GetDeviceContext(void)
void nsRenderingContextUnix :: PushState(void)
{
nsRect rect;
GraphicsState * state = new GraphicsState();
// Push into this state object, add to vector
@@ -218,11 +232,32 @@ void nsRenderingContextUnix :: PushState(void)
else
mTMatrix = new nsTransform2D(mTMatrix);
GetClipRect(state->mLocalClip);
state->mClipRegion = mRegion;
if (nsnull != state->mClipRegion) {
mRegion = ::XCreateRegion();
XRectangle xrect;
xrect.x = state->mLocalClip.x;
xrect.y = state->mLocalClip.y;
xrect.width = state->mLocalClip.width;
xrect.height = state->mLocalClip.height;
::XUnionRectWithRegion(&xrect, mRegion, mRegion);
}
state->mColor = mCurrentColor;
}
PRBool nsRenderingContextUnix :: PopState(void)
{
PRBool bEmpty = PR_FALSE;
PRUint32 cnt = mStateCache->Count();
GraphicsState * state;
@@ -235,12 +270,34 @@ PRBool nsRenderingContextUnix :: PopState(void)
delete mTMatrix;
mTMatrix = state->mMatrix;
if (nsnull != mRegion)
::XDestroyRegion(mRegion);
mRegion = state->mClipRegion;
if (nsnull != mRegion && ::XEmptyRegion(mRegion) == True){
bEmpty = PR_TRUE;
}else{
// Select in the old region. We probably want to set a dirty flag and only
// do this IFF we need to draw before the next Pop. We'd need to check the
// state flag on every draw operation.
if (nsnull != mRegion)
::XSetRegion(mRenderingSurface->display,
mRenderingSurface->gc,
mRegion);
}
if (state->mColor != mCurrentColor)
SetColor(state->mColor);
// Delete this graphics state object
delete state;
}
//XXX need to return if clip region is empty after pop. see nsirendering....h MMP
return PR_FALSE;
return bEmpty;
}
PRBool nsRenderingContextUnix :: IsVisibleRect(const nsRect& aRect)
@@ -248,75 +305,71 @@ PRBool nsRenderingContextUnix :: IsVisibleRect(const nsRect& aRect)
return PR_TRUE;
}
PRBool nsRenderingContextUnix :: SetClipRect(const nsRect& aRect, nsClipCombine aCombine)
PRBool nsRenderingContextUnix :: SetClipRectInPixels(const nsRect& aRect, nsClipCombine aCombine)
{
#ifdef CLIPPING_NOT_FUNCTIONAL
return PR_FALSE;
#endif
// Essentially, create the rect and select it into the GC. Get the current
// ClipRegion first
PRBool bEmpty = PR_FALSE;
nsRect trect = aRect;
mTMatrix->TransformCoord(&trect.x, &trect.y,
&trect.width, &trect.height);
XRectangle xrect;
xrect.x = trect.x;
xrect.y = trect.y;
xrect.width = trect.width;
xrect.height = trect.height;
Region a = ::XCreateRegion();
::XUnionRectWithRegion(&xrect, a, a);
//how we combine the new rect with the previous?
if (aCombine == nsClipCombine_kIntersect)
{
Region a = ::XCreateRegion();
Region tRegion = ::XCreateRegion();
::XOffsetRegion(a, trect.x, trect.y);
::XShrinkRegion(a, -trect.width, -trect.height);
::XIntersectRegion(a, mRegion, tRegion);
::XDestroyRegion(mRegion);
::XDestroyRegion(a);
mRegion = tRegion;
if (nsnull != mRegion) {
::XIntersectRegion(a, mRegion, tRegion);
::XDestroyRegion(mRegion);
::XDestroyRegion(a);
mRegion = tRegion;
} else {
::XDestroyRegion(tRegion);
mRegion = a;
}
}
else if (aCombine == nsClipCombine_kUnion)
{
Region a = ::XCreateRegion();
Region tRegion = ::XCreateRegion();
if (nsnull != mRegion) {
Region tRegion = ::XCreateRegion();
::XUnionRegion(a, mRegion, tRegion);
::XDestroyRegion(mRegion);
::XDestroyRegion(a);
mRegion = tRegion;
} else {
mRegion = a;
}
::XOffsetRegion(a, trect.x, trect.y);
::XShrinkRegion(a, -trect.width, -trect.height);
::XUnionRegion(a, mRegion, tRegion);
::XDestroyRegion(mRegion);
::XDestroyRegion(a);
mRegion = tRegion;
}
else if (aCombine == nsClipCombine_kSubtract)
{
Region a = ::XCreateRegion();
Region tRegion = ::XCreateRegion();
::XOffsetRegion(a, trect.x, trect.y);
::XShrinkRegion(a, -trect.width, -trect.height);
if (nsnull != mRegion) {
::XSubtractRegion(a, mRegion, tRegion);
Region tRegion = ::XCreateRegion();
::XSubtractRegion(mRegion, a, tRegion);
::XDestroyRegion(mRegion);
::XDestroyRegion(a);
mRegion = tRegion;
::XDestroyRegion(mRegion);
::XDestroyRegion(a);
} else {
mRegion = a;
}
mRegion = tRegion;
}
else if (aCombine == nsClipCombine_kReplace)
{
Region a = ::XCreateRegion();
::XOffsetRegion(a, trect.x, trect.y);
::XShrinkRegion(a, -trect.width, -trect.height);
::XDestroyRegion(mRegion);
if (nsnull != mRegion)
::XDestroyRegion(mRegion);
mRegion = a;
@@ -324,18 +377,35 @@ PRBool nsRenderingContextUnix :: SetClipRect(const nsRect& aRect, nsClipCombine
else
NS_ASSERTION(PR_FALSE, "illegal clip combination");
::XSetRegion(mRenderingSurface->display,
mRenderingSurface->gc,
mRegion);
if (::XEmptyRegion(mRegion) == True) {
return PR_TRUE;
bEmpty = PR_TRUE;
::XSetClipMask(mRenderingSurface->display,
mRenderingSurface->gc,
None);
} else {
::XSetRegion(mRenderingSurface->display,
mRenderingSurface->gc,
mRegion);
}
return bEmpty;
}
PRBool nsRenderingContextUnix :: SetClipRect(const nsRect& aRect, nsClipCombine aCombine)
{
nsRect trect = aRect;
mTMatrix->TransformCoord(&trect.x, &trect.y,
&trect.width, &trect.height);
return(SetClipRectInPixels(trect,aCombine));
}
PRBool nsRenderingContextUnix :: GetClipRect(nsRect &aRect)
{
#ifdef CLIPPING_NOT_FUNCTIONAL
return PR_FALSE;
#endif
if (mRegion != nsnull) {
XRectangle xrect;
@@ -343,35 +413,42 @@ PRBool nsRenderingContextUnix :: GetClipRect(nsRect &aRect)
aRect.SetRect(xrect.x, xrect.y, xrect.width, xrect.height);
} else {
aRect.SetRect(0,0,0,0);
return (PR_TRUE);
}
return PR_TRUE;
if (::XEmptyRegion(mRegion) == True)
return PR_TRUE;
else
return PR_FALSE;
}
PRBool nsRenderingContextUnix :: SetClipRegion(const nsIRegion& aRegion, nsClipCombine aCombine)
{
#ifdef CLIPPING_NOT_FUNCTIONAL
return PR_FALSE;
#endif
nsRect rect;
XRectangle xrect;
nsRegionUnix *pRegion = (nsRegionUnix *)&aRegion;
Region xregion = pRegion->GetXRegion();
::XClipBox(xregion, &xrect);
::XSetRegion(mRenderingSurface->display,
mRenderingSurface->gc,
xregion);
rect.x = xrect.x;
rect.y = xrect.y;
rect.width = xrect.width;
rect.height = xrect.height;
mRegion = xregion ;
SetClipRectInPixels(rect, aCombine);
if (::XEmptyRegion(mRegion) == True)
return PR_TRUE;
else
return PR_FALSE;
return (PR_TRUE);
}
void nsRenderingContextUnix :: GetClipRegion(nsIRegion **aRegion)
{
nsIRegion * pRegion ;
static NS_DEFINE_IID(kCRegionCID, NS_REGION_CID);
@@ -398,16 +475,7 @@ void nsRenderingContextUnix :: SetColor(nscolor aColor)
{
XGCValues values ;
mCurrentColor = aColor ;
// XXX
//mCurrentColor++;
PRUint32 pixel ;
pixel = ((nsDeviceContextUnix *)mContext)->ConvertPixel(aColor);
mCurrentColor = pixel;
mCurrentColor = ((nsDeviceContextUnix *)mContext)->ConvertPixel(aColor);
values.foreground = mCurrentColor;
values.background = mCurrentColor;
@@ -416,6 +484,8 @@ void nsRenderingContextUnix :: SetColor(nscolor aColor)
mRenderingSurface->gc,
GCForeground | GCBackground,
&values);
mCurrentColor = aColor ;
}
@@ -431,7 +501,7 @@ void nsRenderingContextUnix :: SetFont(const nsFont& aFont)
if (mFontMetrics)
{
// mCurrFontHandle = (Font)mFontMetrics->GetFontHandle();
mCurrFontHandle = ::XLoadFont(mRenderingSurface->display, (char *)mFontMetrics->GetFontHandle());
::XSetFont(mRenderingSurface->display,
@@ -476,22 +546,22 @@ nsDrawingSurface nsRenderingContextUnix :: CreateDrawingSurface(nsRect *aBounds)
PRUint32 depth = DefaultDepth(mRenderingSurface->display,
DefaultScreen(mRenderingSurface->display));
Pixmap p;
if (aBounds != nsnull) {
p = ::XCreatePixmap(mRenderingSurface->display,
mRenderingSurface->drawable,
aBounds->width, aBounds->height, depth);
mRenderingSurface->drawable,
aBounds->width, aBounds->height, depth);
} else {
p = ::XCreatePixmap(mRenderingSurface->display,
mRenderingSurface->drawable,
2, 2, depth);
mRenderingSurface->drawable,
2, 2, depth);
}
nsDrawingSurfaceUnix * surface = new nsDrawingSurfaceUnix();
surface->drawable = p ;
surface->display = mRenderingSurface->display;
surface->gc = mRenderingSurface->gc;
surface->gc = mFrontBuffer->gc;
surface->visual = mRenderingSurface->visual;
surface->depth = mRenderingSurface->depth;
@@ -506,8 +576,8 @@ void nsRenderingContextUnix :: DestroyDrawingSurface(nsDrawingSurface aDS)
::XFreePixmap(surface->display, surface->drawable);
//XXX greg, this seems bad. MMP
if (mRenderingSurface == surface)
mRenderingSurface = nsnull;
if (mRenderingSurface == surface)
mRenderingSurface = nsnull;
delete aDS;
}
@@ -805,17 +875,17 @@ void nsRenderingContextUnix :: DrawString(const nsString& aString,
void nsRenderingContextUnix :: DrawImage(nsIImage *aImage, nscoord aX, nscoord aY)
{
nscoord width,height;
nscoord width,height;
width = NS_TO_INT_ROUND(mP2T * aImage->GetWidth());
height = NS_TO_INT_ROUND(mP2T * aImage->GetHeight());
this->DrawImage(aImage,aX,aY,width,height);
}
void nsRenderingContextUnix :: DrawImage(nsIImage *aImage, nscoord aX, nscoord aY,
nscoord aWidth, nscoord aHeight)
{
nsRect tr;
nsRect tr;
tr.x = aX;
tr.y = aY;
@@ -826,7 +896,7 @@ nsRect tr;
void nsRenderingContextUnix :: DrawImage(nsIImage *aImage, const nsRect& aSRect, const nsRect& aDRect)
{
nsRect sr,dr;
nsRect sr,dr;
sr = aSRect;
mTMatrix ->TransformCoord(&sr.x,&sr.y,&sr.width,&sr.height);
@@ -840,11 +910,11 @@ nsRect sr,dr;
void nsRenderingContextUnix :: DrawImage(nsIImage *aImage, const nsRect& aRect)
{
nsRect tr;
nsRect tr;
tr = aRect;
mTMatrix->TransformCoord(&tr.x,&tr.y,&tr.width,&tr.height);
if (aImage != nsnull) {
((nsImageUnix*)aImage)->Draw(*this,mRenderingSurface,tr.x,tr.y,tr.width,tr.height);
} else {
@@ -854,13 +924,24 @@ nsRect tr;
nsresult nsRenderingContextUnix :: CopyOffScreenBits(nsRect &aBounds)
{
::XSetClipMask(mFrontBuffer->display,
mFrontBuffer->gc,
None);
::XCopyArea(mRenderingSurface->display,
mRenderingSurface->drawable,
mFrontBuffer->drawable,
mFrontBuffer->gc,
aBounds.x, aBounds.y, aBounds.width, aBounds.height, 0, 0);
if (nsnull != mRegion)
::XSetRegion(mRenderingSurface->display,
mRenderingSurface->gc,
mRegion);
return NS_OK;
}

View File

@@ -58,6 +58,7 @@ public:
virtual nsresult Init(nsIDeviceContext* aContext, nsIWidget *aWindow);
virtual nsresult Init(nsIDeviceContext* aContext, nsDrawingSurface aSurface);
virtual nsresult CommonInit();
virtual void Reset();
@@ -70,6 +71,7 @@ public:
virtual PRBool IsVisibleRect(const nsRect& aRect);
virtual PRBool SetClipRectInPixels(const nsRect& aRect, nsClipCombine aCombine);
virtual PRBool SetClipRect(const nsRect& aRect, nsClipCombine aCombine);
virtual PRBool GetClipRect(nsRect &aRect);
virtual PRBool SetClipRegion(const nsIRegion& aRegion, nsClipCombine aCombine);

View File

@@ -96,24 +96,9 @@ nsEventStatus PR_CALLBACK HandleEvent(nsGUIEvent *aEvent)
//printf("damage repair...\n");
#ifdef NS_UNIX
view->GetBounds(vrect);
PRBool db = PR_FALSE;
if ((((float)trect.width * trect.height) / ((float)vrect.width * vrect.height)) > 0.75f)
db = PR_TRUE;
vm->Refresh(view, ((nsPaintEvent *)aEvent)->renderingContext, &trect,
((db == PR_TRUE) ? NS_VMREFRESH_DOUBLE_BUFFER : 0) | NS_VMREFRESH_SCREEN_RECT);
#else
vm->UpdateView(view, trect,
// ((db == PR_TRUE) ? NS_VMREFRESH_DOUBLE_BUFFER : 0) |
NS_VMREFRESH_SCREEN_RECT);
// NS_VMREFRESH_IMMEDIATE);
vm->Composite();
#endif
NS_RELEASE(dx);
NS_RELEASE(px);

View File

@@ -67,4 +67,12 @@ void nsToolkit::Init(PRThread *aThread)
{
}
void nsToolkit::SetSharedGC(GC aGC)
{
mSharedGC = aGC;
}
GC nsToolkit::GetSharedGC()
{
return (mSharedGC);
}

View File

@@ -20,6 +20,7 @@
#define TOOLKIT_H
#include "nsIToolkit.h"
#include "X11/Xlib.h"
struct MethodInfo;
@@ -32,15 +33,20 @@ struct MethodInfo;
class nsToolkit : public nsIToolkit
{
public:
nsToolkit();
virtual ~nsToolkit();
NS_DECL_ISUPPORTS
public:
nsToolkit();
virtual ~nsToolkit();
NS_DECL_ISUPPORTS
virtual void Init(PRThread *aThread);
public:
NS_IMETHOD_(GC) GetSharedGC();
NS_IMETHOD_(void) SetSharedGC(GC aGC);
private:
GC mSharedGC;
};

View File

@@ -180,6 +180,7 @@ nsWindow::nsWindow(nsISupports *aOuter):
mOuter = aOuter;
else
mOuter = &mInner;
mGC = nsnull ;
}
@@ -190,6 +191,10 @@ nsWindow::nsWindow(nsISupports *aOuter):
//-------------------------------------------------------------------------
nsWindow::~nsWindow()
{
if (nsnull != mGC) {
::XFreeGC((Display *)GetNativeData(NS_NATIVE_DISPLAY),mGC);
mGC = nsnull;
}
}
@@ -230,6 +235,9 @@ void nsWindow::CreateWindow(nsNativeWindow aNativeParent,
mToolkit = new nsToolkit();
mToolkit->AddRef();
mToolkit->Init(PR_GetCurrentThread());
// Create a shared GC for all widgets
((nsToolkit *)mToolkit)->SetSharedGC((GC)GetNativeData(NS_NATIVE_GRAPHIC));
}
}
@@ -246,25 +254,9 @@ void nsWindow::CreateWindow(nsNativeWindow aNativeParent,
else {
nsresult res;
// XXX Move this! - For some reason Registering in another DLL (shell) isn't working
#define GFXWIN_DLL "libgfxunix.so"
/*static NS_DEFINE_IID(kCRenderingContextIID, NS_RENDERING_CONTEXT_CID);
static NS_DEFINE_IID(kCDeviceContextIID, NS_DEVICE_CONTEXT_CID);
static NS_DEFINE_IID(kCFontMetricsIID, NS_FONT_METRICS_CID);
static NS_DEFINE_IID(kCImageIID, NS_IMAGE_CID);
NSRepository::RegisterFactory(kCRenderingContextIID, GFXWIN_DLL, PR_FALSE, PR_FALSE);
NSRepository::RegisterFactory(kCDeviceContextIID, GFXWIN_DLL, PR_FALSE, PR_FALSE);
NSRepository::RegisterFactory(kCFontMetricsIID, GFXWIN_DLL, PR_FALSE, PR_FALSE);
NSRepository::RegisterFactory(kCImageIID, GFXWIN_DLL, PR_FALSE, PR_FALSE);
*/
static NS_DEFINE_IID(kDeviceContextCID, NS_DEVICE_CONTEXT_CID);
static NS_DEFINE_IID(kDeviceContextIID, NS_IDEVICE_CONTEXT_IID);
//res = !NS_OK;
res = NSRepository::CreateInstance(kDeviceContextCID,
nsnull,
@@ -303,8 +295,9 @@ void nsWindow::CreateWindow(nsNativeWindow aNativeParent,
XmNmarginWidth, 0,
nsnull);
mWidget = frame ;
mWidget = frame ;
if (mainWindow) {
XmMainWindowSetAreas (mainWindow, nsnull, nsnull, nsnull, nsnull, frame);
@@ -325,12 +318,36 @@ void nsWindow::CreateWindow(nsNativeWindow aNativeParent,
nsXtWidget_Resize_Callback,
this);
/*XtAddCallback(mWidget,
XmNexposeCallback,
nsXtWidget_Expose_Callback,
this);*/
// Create a Writeable GC for this Widget. Unfortunatley,
// the Window for the Widget is not created properly at this point and
// we Need the GC prior to the Rendering Context getting created, so
// we create a small dummy window of the default depth as our dummy Drawable
// to create a compatible GC
if (nsnull == mGC) {
XGCValues values;
Window w;
Display * d = XtDisplay(mWidget);
w = ::XCreateSimpleWindow(d,
RootWindow(d,DefaultScreen(d)),
0,0,1,1,0,
BlackPixel(d,DefaultScreen(d)),
WhitePixel(d,DefaultScreen(d)));
mGC = ::XCreateGC(d, w, nsnull, &values);
::XDestroyWindow(d,w);
}
}
@@ -732,14 +749,14 @@ void* nsWindow::GetNativeData(PRUint32 aDataType)
break;
case NS_NATIVE_GRAPHIC:
{
XGCValues values;
GC aGC;
aGC= ::XtGetGC(mWidget,
nsnull,
&values);
// We Cache a Read-Only Shared GC in the Toolkit. If we don't
// have one ourselves (because it needs to be writeable) grab the
// the shared GC
if (nsnull == mGC)
return (((nsToolkit *)mToolkit)->GetSharedGC());
return (void*)aGC;
return ((void*)mGC);
}
break;
case NS_NATIVE_COLORMAP:
@@ -762,6 +779,7 @@ nsIRenderingContext* nsWindow::GetRenderingContext()
nsIRenderingContext * ctx = nsnull;
if (GetNativeData(NS_NATIVE_WIDGET)) {
nsresult res;
static NS_DEFINE_IID(kRenderingContextCID, NS_RENDERING_CONTEXT_CID);

View File

@@ -181,6 +181,8 @@ protected:
} mInner;
friend InnerSupport;
private:
GC mGC;
};
//