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:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -67,4 +67,12 @@ void nsToolkit::Init(PRThread *aThread)
|
||||
{
|
||||
}
|
||||
|
||||
void nsToolkit::SetSharedGC(GC aGC)
|
||||
{
|
||||
mSharedGC = aGC;
|
||||
}
|
||||
|
||||
GC nsToolkit::GetSharedGC()
|
||||
{
|
||||
return (mSharedGC);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -181,6 +181,8 @@ protected:
|
||||
} mInner;
|
||||
friend InnerSupport;
|
||||
|
||||
private:
|
||||
GC mGC;
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user