Support for TrueColor display, add nsNativeDeviceContext to Init method of nsIDeviceContext, fix FontMetrics crash if no RenderingContext is available.

This commit is contained in:
spider 1998-06-11 21:26:21 +00:00
Родитель 96d3622b93
Коммит 5cc1ba3443
15 изменённых файлов: 284 добавлений и 131 удалений

Просмотреть файл

@ -27,6 +27,12 @@ static NS_DEFINE_IID(kDeviceContextIID, NS_IDEVICE_CONTEXT_IID);
#define NS_TO_X_COMPONENT(a) ((a << 8) | (a))
#define NS_TO_X_RED(a) (((NS_GET_R(a) >> (8 - mRedBits)) << mRedOffset) & mRedMask)
#define NS_TO_X_GREEN(a) (((NS_GET_G(a) >> (8 - mGreenBits)) << mGreenOffset) & mGreenMask)
#define NS_TO_X_BLUE(a) (((NS_GET_B(a) >> (8 - mBlueBits)) << mBlueOffset) & mBlueMask)
#define NS_TO_X(a) (NS_TO_X_RED(a) | NS_TO_X_GREEN(a) | NS_TO_X_BLUE(a))
nsDeviceContextUnix :: nsDeviceContextUnix()
{
NS_INIT_REFCNT();
@ -45,6 +51,22 @@ nsDeviceContextUnix :: nsDeviceContextUnix()
mZoom = 1.0f;
mVisual = nsnull;
mRedMask = 0;
mGreenMask = 0;
mBlueMask = 0;
mRedBits = 0;
mGreenBits = 0;
mBlueBits = 0;
mRedOffset = 0;
mGreenOffset = 0;
mBlueOffset = 0;
mNativeDisplay = nsnull;
}
nsDeviceContextUnix :: ~nsDeviceContextUnix()
@ -59,13 +81,17 @@ nsDeviceContextUnix :: ~nsDeviceContextUnix()
NS_IF_RELEASE(mFontCache);
if (mSurface) delete mSurface;
if (mNativeDisplay)
::XCloseDisplay((Display *)mNativeDisplay);
}
NS_IMPL_QUERY_INTERFACE(nsDeviceContextUnix, kDeviceContextIID)
NS_IMPL_ADDREF(nsDeviceContextUnix)
NS_IMPL_RELEASE(nsDeviceContextUnix)
nsresult nsDeviceContextUnix :: Init()
nsresult nsDeviceContextUnix :: Init(nsNativeDeviceContext aNativeDeviceContext)
{
for (PRInt32 cnt = 0; cnt < 256; cnt++)
mGammaTable[cnt] = cnt;
@ -73,20 +99,15 @@ nsresult nsDeviceContextUnix :: Init()
// XXX We really need to have Display passed to us since it could be specified
// not from the environment, which is the one we use here.
Display * display = ::XOpenDisplay(nsnull);
if (aNativeDeviceContext == nsnull)
mNativeDisplay = ::XOpenDisplay(nsnull);
if (display) {
mTwipsToPixels = (((float)::XDisplayWidth(display, DefaultScreen(display))) /
((float)::XDisplayWidthMM(display,DefaultScreen(display) )) * 25.4) /
NS_POINTS_TO_TWIPS_FLOAT(72.0f);
mTwipsToPixels = (((float)::XDisplayWidth((Display *)mNativeDisplay, DefaultScreen((Display *)mNativeDisplay))) /
((float)::XDisplayWidthMM((Display *)mNativeDisplay,DefaultScreen((Display *)mNativeDisplay) )) * 25.4) /
NS_POINTS_TO_TWIPS_FLOAT(72.0f);
mPixelsToTwips = 1.0f / mTwipsToPixels;
::XCloseDisplay(display);
}
mPixelsToTwips = 1.0f / mTwipsToPixels;
return NS_OK;
}
@ -161,95 +182,133 @@ PRUint32 nsDeviceContextUnix :: ConvertPixel(nscolor aColor)
{
PRUint32 newcolor = 0;
if (mDepth == 8) {
/*
For now, we assume anything in 12 planes or more is a TrueColor visual.
If it is not (like older IRIS GL graphics boards, we'll look stupid for now.
*/
if (mWriteable == PR_FALSE) {
Status rc ;
XColor colorcell;
switch (mDepth) {
case 8:
{
colorcell.red = NS_TO_X_COMPONENT(NS_GET_R(aColor));
colorcell.green = NS_TO_X_COMPONENT(NS_GET_G(aColor));
colorcell.blue = NS_TO_X_COMPONENT(NS_GET_B(aColor));
colorcell.pixel = 0;
colorcell.flags = 0;
colorcell.pad = 0;
// On static displays, this will return closest match
rc = ::XAllocColor(mSurface->display,
mColormap,
&colorcell);
if (rc == 0) {
// Punt ... this cannot happen!
fprintf(stderr,"WHOA! IT FAILED!\n");
} else {
newcolor = colorcell.pixel;
}
} else {
// Check to see if this exact color is present. If not, add it ourselves.
// If there are no unallocated cells left, do our own closest match lookup
//since X doesn't provide us with one.
Status rc ;
XColor colorcell;
colorcell.red = NS_TO_X_COMPONENT(NS_GET_R(aColor));
colorcell.green = NS_TO_X_COMPONENT(NS_GET_G(aColor));
colorcell.blue = NS_TO_X_COMPONENT(NS_GET_B(aColor));
colorcell.pixel = 0;
colorcell.flags = 0;
colorcell.pad = 0;
// On non-static displays, this may fail
rc = ::XAllocColor(mSurface->display,
mColormap,
&colorcell);
if (rc == 0) {
if (mWriteable == PR_FALSE) {
// The color does not already exist AND we do not have any unallocated colorcells left
// At his point we need to implement our own lookup matching algorithm.
unsigned long pixel;
rc = ::XAllocColorCells(mSurface->display,
mColormap,
False,0,0,
&pixel,
1);
Status rc ;
XColor colorcell;
if (rc == 0){
fprintf(stderr, "Failed to allocate Color cells...this sux\n");
colorcell.red = NS_TO_X_COMPONENT(NS_GET_R(aColor));
colorcell.green = NS_TO_X_COMPONENT(NS_GET_G(aColor));
colorcell.blue = NS_TO_X_COMPONENT(NS_GET_B(aColor));
colorcell.pixel = 0;
colorcell.flags = 0;
colorcell.pad = 0;
// On static displays, this will return closest match
rc = ::XAllocColor(mSurface->display,
mColormap,
&colorcell);
if (rc == 0) {
// Punt ... this cannot happen!
fprintf(stderr,"WHOA! IT FAILED!\n");
} else {
colorcell.pixel = pixel;
colorcell.pad = 0 ;
colorcell.flags = DoRed | DoGreen | DoBlue ;
colorcell.red = NS_TO_X_COMPONENT(NS_GET_R(aColor));
colorcell.green = NS_TO_X_COMPONENT(NS_GET_G(aColor));
colorcell.blue = NS_TO_X_COMPONENT(NS_GET_B(aColor));
::XStoreColor(mSurface->display, mColormap, &colorcell);
newcolor = colorcell.pixel;
}
} // rc == 0
} else {
newcolor = colorcell.pixel;
}
}
// Check to see if this exact color is present. If not, add it ourselves.
// If there are no unallocated cells left, do our own closest match lookup
//since X doesn't provide us with one.
Status rc ;
XColor colorcell;
colorcell.red = NS_TO_X_COMPONENT(NS_GET_R(aColor));
colorcell.green = NS_TO_X_COMPONENT(NS_GET_G(aColor));
colorcell.blue = NS_TO_X_COMPONENT(NS_GET_B(aColor));
colorcell.pixel = 0;
colorcell.flags = 0;
colorcell.pad = 0;
}
// On non-static displays, this may fail
rc = ::XAllocColor(mSurface->display,
mColormap,
&colorcell);
if (mDepth == 24) {
newcolor = (PRUint32)aColor & 0x00ffffff;
}
if (rc == 0) {
// The color does not already exist AND we do not have any unallocated colorcells left
// At his point we need to implement our own lookup matching algorithm.
unsigned long pixel;
rc = ::XAllocColorCells(mSurface->display,
mColormap,
False,0,0,
&pixel,
1);
if (rc == 0){
fprintf(stderr, "Failed to allocate Color cells...this sux\n");
} else {
colorcell.pixel = pixel;
colorcell.pad = 0 ;
colorcell.flags = DoRed | DoGreen | DoBlue ;
colorcell.red = NS_TO_X_COMPONENT(NS_GET_R(aColor));
colorcell.green = NS_TO_X_COMPONENT(NS_GET_G(aColor));
colorcell.blue = NS_TO_X_COMPONENT(NS_GET_B(aColor));
::XStoreColor(mSurface->display, mColormap, &colorcell);
newcolor = colorcell.pixel;
} // rc == 0
} else {
newcolor = colorcell.pixel;
} // rc == 0
} // mWriteable == FALSE
} // 8
break;
case 12:
{
newcolor = (PRUint32)NS_TO_X(aColor);
} // 12
break;
case 15:
{
newcolor = (PRUint32)NS_TO_X(aColor);
} // 15
break;
case 16:
{
newcolor = (PRUint32)NS_TO_X(aColor);
} // 16
break;
case 24:
{
newcolor = (PRUint32)NS_TO_X(aColor);
//newcolor = (PRUint32)NS_TO_X24(aColor);
} // 24
break;
default:
{
newcolor = (PRUint32)NS_TO_X(aColor);
// newcolor = (PRUint32) aColor;
} // default
break;
} // switch(mDepth)
return (newcolor);
}
@ -297,6 +356,52 @@ void nsDeviceContextUnix :: InstallColormap()
}
}
// Compute rgb masks and number of bits for each
mRedMask = mVisual->red_mask;
mGreenMask = mVisual->green_mask;
mBlueMask = mVisual->blue_mask;
PRUint32 i = mRedMask;
while (i) {
if ((i & 0x1) != 0) {
mRedBits++;
} else {
mRedOffset++;
}
i = i >> 1;
}
i = mGreenMask;
while (i) {
if ((i & 0x1) != 0)
mGreenBits++;
else
mGreenOffset++;
i = i >> 1;
}
i = mBlueMask;
while (i) {
if ((i & 0x1) != 0)
mBlueBits++;
else
mBlueOffset++;
i = i >> 1;
}
}
nsIFontCache* nsDeviceContextUnix::GetFontCache()
@ -391,7 +496,10 @@ void nsDeviceContextUnix :: SetGammaTable(PRUint8 * aTable, float aCurrentGamma,
aTable[cnt] = (PRUint8)(pow((double)cnt * (1. / 256.), fgval) * 255.99999999);
}
nsNativeDeviceContext nsDeviceContextUnix :: GetNativeDeviceContext()
{
return ((nsNativeDeviceContext)mNativeDisplay);
}

Просмотреть файл

@ -42,7 +42,7 @@ public:
NS_DECL_ISUPPORTS
virtual nsresult Init();
virtual nsresult Init(nsNativeDeviceContext aNativeDeviceContext);
virtual nsIRenderingContext * CreateRenderingContext(nsIView *aView);
virtual void InitRenderingContext(nsIRenderingContext *aContext, nsIWidget *aWidget);
@ -105,6 +105,21 @@ public:
void InstallColormap(void);
void SetDrawingSurface(nsDrawingSurfaceUnix * aSurface) { mSurface = aSurface; }
void SetGammaTable(PRUint8 * aTable, float aCurrentGamma, float aNewGamma);
nsNativeDeviceContext GetNativeDeviceContext();
private:
PRUint32 mRedMask;
PRUint32 mGreenMask;
PRUint32 mBlueMask;
PRUint32 mRedBits;
PRUint32 mGreenBits;
PRUint32 mBlueBits;
PRUint32 mRedOffset;
PRUint32 mGreenOffset;
PRUint32 mBlueOffset;
nsNativeDeviceContext mNativeDisplay;
};
#endif /* nsDeviceContextUnix_h___ */

Просмотреть файл

@ -28,6 +28,7 @@ nsFontMetricsUnix :: nsFontMetricsUnix()
{
NS_INIT_REFCNT();
mFont = nsnull;
mFontHandle = nsnull;
}
nsFontMetricsUnix :: ~nsFontMetricsUnix()
@ -53,25 +54,17 @@ nsresult nsFontMetricsUnix :: Init(const nsFont& aFont, nsIDeviceContext* aCX)
void nsFontMetricsUnix::RealizeFont()
{
//mFontHandle = ::CreateFontIndirect(&logFont);
//mHeight = nscoord(metrics.tmHeight * p2t);
//mLeading = nscoord(metrics.tmInternalLeading * p2t);
//mMaxAdvance = nscoord(metrics.tmMaxCharWidth * p2t);
nsDrawingSurfaceUnix * aRenderingSurface = (nsDrawingSurfaceUnix *) ((nsDeviceContextUnix *)mContext)->GetDrawingSurface();
mFontHandle = ::XLoadFont(aRenderingSurface->display, "fixed");
XFontStruct * fs = ::XQueryFont(aRenderingSurface->display, mFontHandle);
mFontHandle = ::XLoadFont((Display *)mContext->GetNativeDeviceContext(), "fixed");
XFontStruct * fs = ::XQueryFont((Display *)mContext->GetNativeDeviceContext(), mFontHandle);
mAscent = fs->ascent ;
mDescent = fs->descent ;
mMaxAscent = fs->ascent ;
mMaxDescent = fs->descent ;
::XSetFont(aRenderingSurface->display, aRenderingSurface->gc, mFontHandle);
// ::XSetFont(aRenderingSurface->display, aRenderingSurface->gc, mFontHandle);
// XXX Temp hardcodes
mHeight = 15 ;
@ -106,10 +99,15 @@ nscoord nsFontMetricsUnix :: GetWidth(const nsString& aString)
nscoord nsFontMetricsUnix :: GetWidth(const char *aString)
{
nsDrawingSurfaceUnix * aRenderingSurface = (nsDrawingSurfaceUnix *) ((nsDeviceContextUnix *)mContext)->GetDrawingSurface();
XFontStruct * fs = ::XQueryFont(aRenderingSurface->display, mFontHandle);
nscoord rc = 0 ;
mFontHandle = ::XLoadFont((Display *)mContext->GetNativeDeviceContext(), "fixed");
return (::XTextWidth(fs, aString, nsCRT::strlen(aString)));
XFontStruct * fs = ::XQueryFont((Display *)mContext->GetNativeDeviceContext(), mFontHandle);
rc = (nscoord) ::XTextWidth(fs, aString, nsCRT::strlen(aString));
return (rc);
}
@ -131,8 +129,9 @@ nscoord nsFontMetricsUnix :: GetWidth(const PRUnichar *aString, PRUint32 aLength
thischar->byte2 = (aunichar & 0xff) >> 8;
}
nsDrawingSurfaceUnix * aRenderingSurface = (nsDrawingSurfaceUnix *) ((nsDeviceContextUnix *)mContext)->GetDrawingSurface();
XFontStruct * fs = ::XQueryFont(aRenderingSurface->display, mFontHandle);
mFontHandle = ::XLoadFont((Display *)mContext->GetNativeDeviceContext(), "fixed");
XFontStruct * fs = ::XQueryFont((Display *)mContext->GetNativeDeviceContext(), mFontHandle);
width = ::XTextWidth16(fs, xstring, aLength);

Просмотреть файл

@ -395,17 +395,22 @@ nscolor nsRenderingContextUnix :: GetColor() const
void nsRenderingContextUnix :: SetFont(const nsFont& aFont)
{
/*
Font id = ::XLoadFont(mRenderingSurface->display, "fixed");
XFontStruct * fs = ::XQueryFont(mRenderingSurface->display, id);
::XSetFont(mRenderingSurface->display, mRenderingSurface->gc, id);
*/
NS_IF_RELEASE(mFontMetrics);
mFontMetrics = mFontCache->GetMetricsFor(aFont);
if (mFontMetrics) {
Font handle;
handle = ::XLoadFont(mRenderingSurface->display, "fixed");
::XSetFont(mRenderingSurface->display,
mRenderingSurface->gc,
(Font)handle);
::XFlushGC(mRenderingSurface->display,
mRenderingSurface->gc);
}
}
const nsFont& nsRenderingContextUnix :: GetFont()

Просмотреть файл

@ -31,6 +31,9 @@ class nsIFontMetrics;
class nsIWidget;
struct nsFont;
//a cross platform way of specifying a navite device context
typedef void * nsNativeDeviceContext;
#define NS_IDEVICE_CONTEXT_IID \
{ 0x5931c580, 0xb917, 0x11d1, \
{ 0xa8, 0x24, 0x00, 0x40, 0x95, 0x9a, 0x28, 0xc9 } }
@ -38,7 +41,7 @@ struct nsFont;
class nsIDeviceContext : public nsISupports
{
public:
virtual nsresult Init() = 0;
virtual nsresult Init(nsNativeDeviceContext aNativeDeviceContext) = 0;
virtual nsIRenderingContext * CreateRenderingContext(nsIView *aView) = 0;
virtual void InitRenderingContext(nsIRenderingContext *aContext, nsIWidget *aWindow) = 0;
@ -87,6 +90,8 @@ public:
//XXX the return from this really needs to be ref counted somehow. MMP
virtual PRUint8 * GetGammaTable(void) = 0;
virtual nsNativeDeviceContext GetNativeDeviceContext(void) = 0;
};
#endif /* nsIDeviceContext_h___ */

Просмотреть файл

@ -68,7 +68,7 @@ NS_IMPL_QUERY_INTERFACE(nsDeviceContextWin, kDeviceContextIID)
NS_IMPL_ADDREF(nsDeviceContextWin)
NS_IMPL_RELEASE(nsDeviceContextWin)
nsresult nsDeviceContextWin :: Init()
nsresult nsDeviceContextWin :: Init(nsNativeDeviceContext aNativeDeviceContext)
{
for (PRInt32 cnt = 0; cnt < 256; cnt++)
mGammaTable[cnt] = cnt;
@ -193,6 +193,11 @@ nsDrawingSurface nsDeviceContextWin :: GetDrawingSurface(nsIRenderingContext &aC
return mSurface;
}
nsNativeDeviceContext nsDeviceContextWin :: GetNativeDeviceContext()
{
return ((nsNativeDeviceContext)nsnull);
}
float nsDeviceContextWin :: GetGamma(void)
{
return mGammaValue;

Просмотреть файл

@ -34,7 +34,7 @@ public:
NS_DECL_ISUPPORTS
virtual nsresult Init();
virtual nsresult Init(nsNativeDeviceContext aNativeDeviceContext);
virtual nsIRenderingContext * CreateRenderingContext(nsIView *aView);
virtual void InitRenderingContext(nsIRenderingContext *aContext, nsIWidget *aWidget);
@ -65,6 +65,7 @@ public:
virtual void SetGamma(float aGamma);
virtual PRUint8 * GetGammaTable(void);
virtual nsNativeDeviceContext GetNativeDeviceContext(void) ;
protected:
~nsDeviceContextWin();

Просмотреть файл

@ -41,7 +41,7 @@ GalleyContext::GalleyContext()
kDeviceContextIID,
(void **)&mDeviceContext);
if (NS_OK == res) {
mDeviceContext->Init();
mDeviceContext->Init(nsnull);
mDeviceContext->SetDevUnitsToAppUnits(mDeviceContext->GetDevUnitsToTwips());
mDeviceContext->SetAppUnitsToDevUnits(mDeviceContext->GetTwipsToDevUnits());
mDeviceContext->SetGamma(1.7f);

Просмотреть файл

@ -45,7 +45,7 @@ PrintPreviewContext::PrintPreviewContext()
if (NS_OK == res)
{
mDeviceContext->Init();
mDeviceContext->Init(nsnull);
mDeviceContext->SetDevUnitsToAppUnits(mDeviceContext->GetDevUnitsToTwips());
mDeviceContext->SetAppUnitsToDevUnits(mDeviceContext->GetTwipsToDevUnits());

Просмотреть файл

@ -65,7 +65,7 @@ void MenuProc(PRUint32 aId)
//--------------------------------------------------------
void nsMotifViewer::AddMenu(nsIWidget* aMainWindow)
{
CreateViewerMenus(XtParent(aMainWindow->GetNativeData(NS_NATIVE_WIDGET)), MenuProc);
CreateViewerMenus(XtParent((Widget)aMainWindow->GetNativeData(NS_NATIVE_WIDGET)), MenuProc);
}
char* nsMotifViewer::GetBaseURL()

Просмотреть файл

@ -19,9 +19,12 @@
#include <Xm/CascadeBG.h>
#include <Xm/PushBG.h>
#include <Xm/SeparatoG.h>
#include <Xm/RowColumn.h>
#include "resources.h"
#include "nsMotifMenu.h"
#include "stdio.h"
//==============================================================
typedef struct _callBackInfo {
MenuCallbackProc mCallback;

Просмотреть файл

@ -36,6 +36,8 @@
#include "Xm/XmStrDefs.h"
#include "Xm/DrawingA.h"
#include "X11/Intrinsic.h"
#include "stdio.h"
#define DBG 0
@ -196,7 +198,7 @@ void nsWindow::CreateWindow(nsNativeWindow aNativeParent,
kDeviceContextIID,
(void **)&mContext);
if (NS_OK == res) {
mContext->Init();
mContext->Init(nsnull);
}
}
@ -904,6 +906,16 @@ void nsWindow::OnDestroy()
PRBool nsWindow::OnResize(nsSizeEvent &aEvent)
{
if (mWidget) {
Arg arg[3];
XtSetArg(arg[0], XtNwidth, 600);
XtSetArg(arg[1], XtNheight,800);
XtSetValues(mWidget, arg, 2);
}
if (mEventCallback) {
return(DispatchEvent(&aEvent));
}

Просмотреть файл

@ -473,7 +473,7 @@ void nsWindow::Create(nsIWidget *aParent,
res = NSRepository::CreateInstance(kDeviceContextCID, nsnull, kDeviceContextIID, (void **)&mContext);
if (NS_OK == res)
mContext->Init();
mContext->Init(nsnull);
}
if (nsnull != aInitData) {
@ -570,7 +570,7 @@ void nsWindow::Create(nsNativeWindow aParent,
res = NSRepository::CreateInstance(kDeviceContextCID, nsnull, kDeviceContextIID, (void **)&mContext);
if (NS_OK == res)
mContext->Init();
mContext->Init(nsnull);
}
if (nsnull != aInitData) {

Просмотреть файл

@ -411,7 +411,7 @@ nsresult CreateApplication()
res = NSRepository::CreateInstance(kDeviceContextCID, nsnull, kDeviceContextIID, (void **)&scribbleData.mContext);
if (NS_OK == res)
scribbleData.mContext->Init();
scribbleData.mContext->Init(nsnull);
// Create an application shell

Просмотреть файл

@ -1075,7 +1075,7 @@ nsresult WidgetTest()
if (NS_OK == res)
{
deviceContext->Init();
deviceContext->Init(nsnull);
NS_ADDREF(deviceContext);
}