summaryrefslogtreecommitdiffstats
path: root/vcl
diff options
context:
space:
mode:
authorKurt Zenker <kz@openoffice.org>2006-10-06 09:05:28 +0000
committerKurt Zenker <kz@openoffice.org>2006-10-06 09:05:28 +0000
commitaaddf88a730026f9a3f9a1806dece388c24b8e3f (patch)
tree6d12d2445c321e50f4901dee1c137c04f60e2986 /vcl
parentINTEGRATION: CWS impresshydra (1.61.48); FILE MERGED (diff)
downloadcore-aaddf88a730026f9a3f9a1806dece388c24b8e3f.tar.gz
core-aaddf88a730026f9a3f9a1806dece388c24b8e3f.zip
INTEGRATION: CWS impresshydra (1.42.48); FILE MERGED
2006/10/05 13:19:04 pl 1.42.48.14: #i68546# force MultiScreenGlyph usage when pixmap from non-default screen is involved 2006/10/04 13:32:31 pl 1.42.48.13: #i67721# fix a copy and paste error (hdu) 2006/09/27 09:43:58 hdu 1.42.48.12: #i67721# do not copy but reference ExtDataRef 2006/09/20 13:50:50 cl 1.42.48.11: RESYNC: (1.42-1.43); FILE MERGED 2006/09/04 11:20:06 hdu 1.42.48.10: #i68546# add wrongly deleted line again to initialize render glyph for multi-screen 2006/09/04 07:09:38 hdu 1.42.48.9: #i68546# optimization for default screen use in multi-screen scenario 2006/09/01 14:25:01 hdu 1.42.48.8: #i68546# fix initialization of multi-screen glyph pixmaps 2006/09/01 13:56:53 hdu 1.42.48.7: #i68546# optimization for single-screen use in multi-screen scenario 2006/09/01 10:59:53 hdu 1.42.48.6: #i68546# fix typo 2006/09/01 10:52:08 hdu 1.42.48.5: #i68546# handle wild mixture of multi-screen scenarios 2006/09/01 10:27:42 hdu 1.42.48.4: #i68546# extend glyphcache to handle multi-screen scenarios 2006/08/29 14:49:29 cl 1.42.48.3: fixed merge conflicts 2006/08/10 09:37:59 pl 1.42.48.2: #i67721# clean up glyph peer caching and final cleanup 2006/08/09 15:35:46 pl 1.42.48.1: #i67721# first step of making glyph rnedering multiscreen capable
Diffstat (limited to 'vcl')
-rw-r--r--vcl/unx/source/gdi/gcach_xpeer.cxx419
1 files changed, 330 insertions, 89 deletions
diff --git a/vcl/unx/source/gdi/gcach_xpeer.cxx b/vcl/unx/source/gdi/gcach_xpeer.cxx
index 4dc22651de98..1d509bfe6b1d 100644
--- a/vcl/unx/source/gdi/gcach_xpeer.cxx
+++ b/vcl/unx/source/gdi/gcach_xpeer.cxx
@@ -4,9 +4,9 @@
*
* $RCSfile: gcach_xpeer.cxx,v $
*
- * $Revision: 1.43 $
+ * $Revision: 1.44 $
*
- * last change: $Author: obo $ $Date: 2006-09-17 12:37:36 $
+ * last change: $Author: kz $ $Date: 2006-10-06 10:05:28 $
*
* The Contents of this file are made available subject to
* the terms of GNU Lesser General Public License Version 2.1.
@@ -44,15 +44,31 @@ using namespace rtl;
#include <gcach_xpeer.hxx>
#include <stdio.h>
#include <stdlib.h>
+#include <saldisp.hxx>
+#include <saldata.hxx>
-// ---------------------------------------------------------------------------
+// ===========================================================================
+
+// all glyph specific data needed by the XGlyphPeer is quite trivial
+// with one exception: if multiple screens are involved and non-antialiased
+// glyph rendering is active, then we need screen specific pixmaps
+struct MultiScreenGlyph
+{
+ const RawBitmap* mpRawBitmap;
+ Glyph maXRGlyphId;
+ Pixmap maPixmaps[1]; // [mnMaxScreens]
+};
-static int nRenderVersion = 0x00;
+// ===========================================================================
X11GlyphPeer::X11GlyphPeer()
: mpDisplay(NULL)
-, mbForcedAA(false)
-, mbUsingXRender(false)
+, mnMaxScreens(0)
+, mnDefaultScreen(0)
+, mnExtByteCount(0)
+, mnForcedAA(0)
+, mnUsingXRender(0)
+, mnRenderVersion(0x00)
, mpGlyphFormat(NULL)
{
maRawBitmap.mnAllocated = 0;
@@ -61,12 +77,46 @@ X11GlyphPeer::X11GlyphPeer()
// ---------------------------------------------------------------------------
-void X11GlyphPeer::SetDisplay( Display* _pDisplay, Visual* _pVisual )
+X11GlyphPeer::~X11GlyphPeer()
{
- if( mpDisplay == _pDisplay )
+ SalDisplay* pSalDisp = GetX11SalData()->GetDisplay();
+ Display* const pX11Disp = pSalDisp->GetDisplay();
+ for( int i = 0; i < mnMaxScreens; i++ )
+ {
+ SalDisplay::RenderEntryMap& rMap = pSalDisp->GetRenderEntries( i );
+ for( SalDisplay::RenderEntryMap::iterator it = rMap.begin(); it != rMap.end(); ++it )
+ {
+ if( it->second.m_aPixmap )
+ XFreePixmap( pX11Disp, it->second.m_aPixmap );
+ if( it->second.m_aPicture )
+ {
+ #ifdef XRENDER_LINK
+ XRenderFreePicture ( pX11Disp, it->second.m_aPicture );
+ #else
+ (*pXRenderFreePicture)( pX11Disp, it->second.m_aPicture );
+ #endif
+ }
+ }
+ rMap.clear();
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+void X11GlyphPeer::SetDisplay( const SalDisplay& rSalDisplay )
+{
+ if( mpDisplay != NULL )
return;
- mpDisplay = _pDisplay;
+ mpDisplay = rSalDisplay.GetDisplay();
+ mnMaxScreens = rSalDisplay.GetScreenCount();
+ if( mnMaxScreens > MAX_GCACH_SCREENS )
+ mnMaxScreens = MAX_GCACH_SCREENS;
+ // if specific glyph data has to be kept for many screens
+ // then prepare the allocation of MultiScreenGlyph objects
+ if( mnMaxScreens > 1 )
+ mnExtByteCount = sizeof(MultiScreenGlyph) + sizeof(Pixmap) * (mnMaxScreens - 1);
+ mnDefaultScreen = rSalDisplay.GetDefaultScreenNumber();
int nEnvAntiAlias = 0;
const char* pEnvAntiAlias = getenv( "SAL_ANTIALIAS_DISABLE" );
@@ -79,25 +129,29 @@ void X11GlyphPeer::SetDisplay( Display* _pDisplay, Visual* _pVisual )
// we can do anti aliasing on the client side
// when the display's visuals are suitable
- mbForcedAA = true;
- XVisualInfo aXVisualInfo;
- aXVisualInfo.visualid = _pVisual->visualid;
- int nVisuals = 0;
- XVisualInfo* pXVisualInfo = XGetVisualInfo( mpDisplay, VisualIDMask, &aXVisualInfo, &nVisuals );
+ mnForcedAA = ~0U;
+ // unless the feature is explicitly disabled by an environment variable
+ if( (nEnvAntiAlias & 1) != 0 )
+ mnForcedAA = 0;
int nMaxDepth = 0;
- for( int i = nVisuals; --i >= 0; )
+ for( int nScreen = 0; nScreen < mnMaxScreens; ++nScreen)
{
- if( nMaxDepth < pXVisualInfo[i].depth )
- nMaxDepth = pXVisualInfo[i].depth;
- if( ((pXVisualInfo[i].c_class==PseudoColor) || (pXVisualInfo[i].depth<24))
- && ((pXVisualInfo[i].c_class>GrayScale) || (pXVisualInfo[i].depth!=8) ) )
- mbForcedAA = false;
+ Visual* pVisual = rSalDisplay.GetVisual( nScreen ).GetVisual();
+ XVisualInfo aXVisualInfo;
+ aXVisualInfo.visualid = pVisual->visualid;
+ int nVisuals = 0;
+ XVisualInfo* pXVisualInfo = XGetVisualInfo( mpDisplay, VisualIDMask, &aXVisualInfo, &nVisuals );
+ for( int i = nVisuals; --i >= 0; )
+ {
+ if( nMaxDepth < pXVisualInfo[i].depth )
+ nMaxDepth = pXVisualInfo[i].depth;
+ if( ((pXVisualInfo[i].c_class==PseudoColor) || (pXVisualInfo[i].depth<24))
+ && ((pXVisualInfo[i].c_class>GrayScale) || (pXVisualInfo[i].depth!=8) ) )
+ mnForcedAA &= ~(1U << nScreen);
+ }
+ if( pXVisualInfo != NULL )
+ XFree( pXVisualInfo );
}
- if( pXVisualInfo != NULL )
- XFree( pXVisualInfo );
-
- if( (nEnvAntiAlias & 1) != 0 )
- mbForcedAA = false;
// but we prefer the hardware accelerated solution
int nDummy;
@@ -202,7 +256,7 @@ void X11GlyphPeer::SetDisplay( Display* _pDisplay, Visual* _pVisual )
#else
(*pXRenderQueryVersion)( mpDisplay, &nMajor, &nMinor );
#endif
- nRenderVersion = 16*nMajor + nMinor;
+ mnRenderVersion = 16*nMajor + nMinor;
// TODO: enable/disable things depending on version
// the 8bit alpha mask format must be there
@@ -217,69 +271,224 @@ void X11GlyphPeer::SetDisplay( Display* _pDisplay, Visual* _pVisual )
if( mpGlyphFormat != NULL )
{
- // and the visual must be supported too
+ for( int nScreen = 0; nScreen < mnMaxScreens; ++nScreen)
+ {
+ Visual* pVisual = rSalDisplay.GetVisual( nScreen ).GetVisual();
+
+ // and the visual must be supported too on the screen
#ifdef XRENDER_LINK
- XRenderPictFormat* pVisualFormat = XRenderFindVisualFormat ( mpDisplay, _pVisual);
+ XRenderPictFormat* pVisualFormat = XRenderFindVisualFormat( mpDisplay, pVisual );
#else
- XRenderPictFormat* pVisualFormat = (*pXRenderFindVisualFormat)( mpDisplay, _pVisual );
+ XRenderPictFormat* pVisualFormat = (*pXRenderFindVisualFormat)( mpDisplay, pVisual );
#endif
- if( pVisualFormat != NULL )
- mbUsingXRender = true;
+ if( pVisualFormat != NULL )
+ mnUsingXRender = ~0U;
+ }
}
// #97763# disable XRENDER on <15bit displays for XFree<=4.2.0
- if( (nMaxDepth < 15) && (nRenderVersion <= 0x02) )
- mbUsingXRender = false;
+ if( (nMaxDepth < 15) && (mnRenderVersion <= 0x02) )
+ mnUsingXRender = 0;
// #93033# disable XRENDER for old RENDER versions if XINERAMA is present
- if( (nRenderVersion < 0x02)
+ if( (mnRenderVersion < 0x02)
&& XQueryExtension( mpDisplay, "XINERAMA", &nDummy, &nDummy, &nDummy ) )
- mbUsingXRender = false;
+ mnUsingXRender = 0;
+ // disable XRENDER if requested by an environment variable
if( (nEnvAntiAlias & 2) != 0 )
- mbUsingXRender = false;
+ mnUsingXRender = 0;
+}
+
+// ===========================================================================
+
+enum { INFO_EMPTY=0, INFO_PIXMAP, INFO_XRENDER, INFO_RAWBMP, INFO_MULTISCREEN };
+static const Glyph NO_GLYPHID = 0;
+static RawBitmap* const NO_RAWBMP = NULL;
+static const Pixmap NO_PIXMAP = 0;
+
+// ---------------------------------------------------------------------------
+
+MultiScreenGlyph* X11GlyphPeer::PrepareForMultiscreen( ExtGlyphData& rEGD ) const
+{
+ // prepare to store screen specific pixmaps
+ MultiScreenGlyph* pMSGlyph = (MultiScreenGlyph*)new char[ mnExtByteCount ];
+ pMSGlyph->mpRawBitmap = NO_RAWBMP;
+ pMSGlyph->maXRGlyphId = NO_GLYPHID;
+ for( int i = 0; i < mnMaxScreens; ++i )
+ pMSGlyph->maPixmaps[i] = NO_PIXMAP;
+ if( rEGD.meInfo == INFO_XRENDER )
+ pMSGlyph->maXRGlyphId = reinterpret_cast<Glyph>(rEGD.mpData);
+ else if( rEGD.meInfo == INFO_RAWBMP )
+ pMSGlyph->mpRawBitmap = reinterpret_cast<RawBitmap*>(rEGD.mpData);
+ else if( rEGD.meInfo == INFO_PIXMAP )
+ pMSGlyph->maPixmaps[ mnDefaultScreen ] = reinterpret_cast<Pixmap>(rEGD.mpData);
+ rEGD.mpData = (void*)pMSGlyph;
+ rEGD.meInfo = INFO_MULTISCREEN;
+ return pMSGlyph;
+ }
+
+// ---------------------------------------------------------------------------
+
+Glyph X11GlyphPeer::GetRenderGlyph( const GlyphData& rGD ) const
+{
+ Glyph aGlyphId = NO_GLYPHID;
+ const ExtGlyphData& rEGD = rGD.ExtDataRef();
+ if( rEGD.meInfo == INFO_XRENDER )
+ aGlyphId = reinterpret_cast<Glyph>(rEGD.mpData);
+ else if( rEGD.meInfo == INFO_MULTISCREEN )
+ aGlyphId = reinterpret_cast<MultiScreenGlyph*>(rEGD.mpData)->maXRGlyphId;
+ return aGlyphId;
+}
+
+// ---------------------------------------------------------------------------
+
+void X11GlyphPeer::SetRenderGlyph( GlyphData& rGD, Glyph aGlyphId ) const
+{
+ ExtGlyphData& rEGD = rGD.ExtDataRef();
+ switch( rEGD.meInfo )
+ {
+ case INFO_EMPTY:
+ rEGD.meInfo = INFO_XRENDER;
+ // fall through
+ case INFO_XRENDER:
+ rEGD.mpData = reinterpret_cast<void*>(aGlyphId);
+ break;
+ case INFO_PIXMAP:
+ case INFO_RAWBMP:
+ PrepareForMultiscreen( rEGD );
+ // fall through
+ case INFO_MULTISCREEN:
+ reinterpret_cast<MultiScreenGlyph*>(rEGD.mpData)->maXRGlyphId = aGlyphId;
+ break;
+ default:
+ break; // cannot happen...
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+const RawBitmap* X11GlyphPeer::GetRawBitmap( const GlyphData& rGD ) const
+{
+ const RawBitmap* pRawBitmap = NO_RAWBMP;
+ const ExtGlyphData& rEGD = rGD.ExtDataRef();
+ if( rEGD.meInfo == INFO_RAWBMP )
+ pRawBitmap = reinterpret_cast<RawBitmap*>(rEGD.mpData);
+ else if( rEGD.meInfo == INFO_MULTISCREEN )
+ pRawBitmap = reinterpret_cast<MultiScreenGlyph*>(rEGD.mpData)->mpRawBitmap;
+ return pRawBitmap;
+}
+
+// ---------------------------------------------------------------------------
+
+void X11GlyphPeer::SetRawBitmap( GlyphData& rGD, const RawBitmap* pRawBitmap ) const
+{
+ ExtGlyphData& rEGD = rGD.ExtDataRef();
+ switch( rEGD.meInfo )
+ {
+ case INFO_EMPTY:
+ rEGD.meInfo = INFO_RAWBMP;
+ // fall through
+ case INFO_RAWBMP:
+ rEGD.mpData = (void*)pRawBitmap;
+ break;
+ case INFO_PIXMAP:
+ case INFO_XRENDER:
+ PrepareForMultiscreen( rEGD );
+ // fall through
+ case INFO_MULTISCREEN:
+ reinterpret_cast<MultiScreenGlyph*>(rEGD.mpData)->mpRawBitmap = pRawBitmap;
+ break;
+ default:
+ // cannot happen...
+ break;
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+Pixmap X11GlyphPeer::GetPixmap( const GlyphData& rGD, int nScreen ) const
+{
+ Pixmap aPixmap = NO_PIXMAP;
+ const ExtGlyphData& rEGD = rGD.ExtDataRef();
+ if( (rEGD.meInfo == INFO_PIXMAP) && (nScreen == mnDefaultScreen) )
+ aPixmap = (Pixmap)rEGD.mpData;
+ else if( rEGD.meInfo == INFO_MULTISCREEN )
+ aPixmap = (Pixmap)(reinterpret_cast<MultiScreenGlyph*>(rEGD.mpData)->maPixmaps[nScreen]);
+ return aPixmap;
+}
+
+// ---------------------------------------------------------------------------
+
+void X11GlyphPeer::SetPixmap( GlyphData& rGD, Pixmap aPixmap, int nScreen ) const
+{
+ if( aPixmap == NO_PIXMAP )
+ aPixmap = None;
+
+ ExtGlyphData& rEGD = rGD.ExtDataRef();
+ if( (rEGD.meInfo == INFO_EMPTY) && (nScreen == mnDefaultScreen) )
+ {
+ rEGD.meInfo = INFO_PIXMAP;
+ rEGD.mpData = (void*)aPixmap;
+ }
+ else
+ {
+ MultiScreenGlyph* pMSGlyph;
+ if( rEGD.meInfo == INFO_MULTISCREEN )
+ pMSGlyph = reinterpret_cast<MultiScreenGlyph*>(rEGD.mpData);
+ else
+ pMSGlyph = PrepareForMultiscreen( rEGD );
+
+ pMSGlyph->maPixmaps[ nScreen ] = aPixmap;
+ }
}
// ---------------------------------------------------------------------------
void X11GlyphPeer::RemovingFont( ServerFont& rServerFont )
{
+ void* pFontExt = rServerFont.GetExtPointer();
switch( rServerFont.GetExtInfo() )
{
- case PIXMAP_KIND:
- case AAFORCED_KIND:
+ case INFO_PIXMAP:
+ case INFO_RAWBMP:
+ // nothing to do
+ break;
+ case INFO_MULTISCREEN:
+ // cannot happen...
break;
- case XRENDER_KIND:
+ case INFO_XRENDER:
#ifdef XRENDER_LINK
- XRenderFreeGlyphSet( mpDisplay,(GlyphSet)rServerFont.GetExtPointer() );
+ XRenderFreeGlyphSet( mpDisplay, (GlyphSet)pFontExt );
#else
- (*pXRenderFreeGlyphSet)( mpDisplay,(GlyphSet)rServerFont.GetExtPointer() );
+ (*pXRenderFreeGlyphSet)( mpDisplay, (GlyphSet)pFontExt );
#endif
break;
}
- rServerFont.SetExtended( EMPTY_KIND, NULL );
+ rServerFont.SetExtended( INFO_EMPTY, NULL );
}
// ---------------------------------------------------------------------------
// notification to clean up GlyphPeer resources for this glyph
-void X11GlyphPeer::RemovingGlyph( ServerFont& rServerFont, GlyphData& rGlyphData, int /*nGlyphIndex*/ )
+void X11GlyphPeer::RemovingGlyph( ServerFont& /*rServerFont*/, GlyphData& rGlyphData, int /*nGlyphIndex*/ )
{
// nothing to do if the GlyphPeer hasn't allocated resources for the glyph
- if( rGlyphData.GetExtInfo() == EMPTY_KIND )
+ if( rGlyphData.ExtDataRef().meInfo == INFO_EMPTY )
return;
const GlyphMetric& rGM = rGlyphData.GetMetric();
- const int nWidth = rGM.GetSize().Width();
+ const int nWidth = rGM.GetSize().Width();
const int nHeight = rGM.GetSize().Height();
- switch( rServerFont.GetExtInfo() )
+ void* pGlyphExt = rGlyphData.ExtDataRef().mpData;
+ switch( rGlyphData.ExtDataRef().meInfo )
{
- case PIXMAP_KIND:
+ case INFO_PIXMAP:
{
- Pixmap aPixmap = (Pixmap)rServerFont.GetExtPointer();
+ Pixmap aPixmap = (Pixmap)pGlyphExt;
if( aPixmap != None )
{
XFreePixmap( mpDisplay, aPixmap );
@@ -288,9 +497,25 @@ void X11GlyphPeer::RemovingGlyph( ServerFont& rServerFont, GlyphData& rGlyphData
}
break;
- case AAFORCED_KIND:
+ case INFO_MULTISCREEN:
+ {
+ MultiScreenGlyph* pMSGlyph = reinterpret_cast<MultiScreenGlyph*>(pGlyphExt);
+ for( int i = 0; i < mnMaxScreens; ++i)
+ {
+ if( pMSGlyph->maPixmaps[i] == NO_PIXMAP )
+ continue;
+ XFreePixmap( mpDisplay, pMSGlyph->maPixmaps[i] );
+ mnBytesUsed -= nHeight * ((nWidth + 7) >> 3);
+ }
+ delete pMSGlyph->mpRawBitmap;
+ // (*pXRenderFreeGlyphs)( mpDisplay, aGlyphSet, &nGlyphId, 1 );
+ delete[] pMSGlyph; // it was allocated with new char[]
+ }
+ break;
+
+ case INFO_RAWBMP:
{
- RawBitmap* pRawBitmap = (RawBitmap*)rGlyphData.GetExtPointer();
+ RawBitmap* pRawBitmap = (RawBitmap*)pGlyphExt;
if( pRawBitmap != NULL )
{
mnBytesUsed -= pRawBitmap->mnScanlineSize * pRawBitmap->mnHeight;
@@ -300,16 +525,16 @@ void X11GlyphPeer::RemovingGlyph( ServerFont& rServerFont, GlyphData& rGlyphData
}
break;
- case XRENDER_KIND:
+ case INFO_XRENDER:
{
/*
// TODO: reenable when it works without problems
- Glyph nGlyphId = (Glyph)rGlyphData.GetExtPointer();
+ Glyph nGlyphId = (Glyph)rGlyphData.ExtDataRef().mpData;
// XRenderFreeGlyphs not implemented yet for version<=0.2
// #108209# disabled because of crash potential,
// the glyph leak is not too bad because they will
// be cleaned up when the glyphset is released
- if( nRenderVersion >= 0x05 )
+ if( mnRenderVersion >= 0x05 )
(*pXRenderFreeGlyphs)( mpDisplay, aGlyphSet, &nGlyphId, 1 );
*/
mnBytesUsed -= nHeight * ((nWidth + 3) & ~3);
@@ -320,35 +545,35 @@ void X11GlyphPeer::RemovingGlyph( ServerFont& rServerFont, GlyphData& rGlyphData
if( mnBytesUsed < 0 ) // TODO: eliminate nBytesUsed calc mismatch
mnBytesUsed = 0;
- rGlyphData.SetExtended( EMPTY_KIND, NULL );
+ rGlyphData.ExtDataRef() = ExtGlyphData();
}
// ---------------------------------------------------------------------------
-bool X11GlyphPeer::ForcedAntialiasing( const ServerFont& rServerFont ) const
+bool X11GlyphPeer::ForcedAntialiasing( const ServerFont& rServerFont, int nScreen ) const
{
bool bForceOk = rServerFont.GetAntialiasAdvice();
// maximum size for antialiasing is 250 pixels
bForceOk &= (rServerFont.GetFontSelData().mnHeight < 250);
- return (bForceOk && mbForcedAA);
+ return (bForceOk && ((mnForcedAA >> nScreen) & 1));
}
// ---------------------------------------------------------------------------
-GlyphSet X11GlyphPeer::GetGlyphSet( ServerFont& rServerFont )
+GlyphSet X11GlyphPeer::GetGlyphSet( ServerFont& rServerFont, int nScreen )
{
- if( !mbUsingXRender )
+ if( (nScreen >= 0) && ((mnUsingXRender >> nScreen) & 1) == 0 )
return 0;
GlyphSet aGlyphSet;
switch( rServerFont.GetExtInfo() )
{
- case XRENDER_KIND:
+ case INFO_XRENDER:
aGlyphSet = (GlyphSet)rServerFont.GetExtPointer();
break;
- case EMPTY_KIND:
+ case INFO_EMPTY:
{
// antialiasing for reasonable font heights only
// => prevents crashes caused by X11 requests >= 256k
@@ -358,11 +583,11 @@ GlyphSet X11GlyphPeer::GetGlyphSet( ServerFont& rServerFont )
if( nHeight<250 && rServerFont.GetAntialiasAdvice() )
{
#ifdef XRENDER_LINK
- aGlyphSet = XRenderCreateGlyphSet ( mpDisplay, mpGlyphFormat );
+ aGlyphSet = XRenderCreateGlyphSet ( mpDisplay, mpGlyphFormat );
#else
aGlyphSet = (*pXRenderCreateGlyphSet)( mpDisplay, mpGlyphFormat );
#endif
- rServerFont.SetExtended( XRENDER_KIND, (void*)aGlyphSet );
+ rServerFont.SetExtended( INFO_XRENDER, (void*)aGlyphSet );
}
else
aGlyphSet = 0;
@@ -379,14 +604,11 @@ GlyphSet X11GlyphPeer::GetGlyphSet( ServerFont& rServerFont )
// ---------------------------------------------------------------------------
-Pixmap X11GlyphPeer::GetPixmap( ServerFont& rServerFont, int nGlyphIndex )
+Pixmap X11GlyphPeer::GetPixmap( ServerFont& rServerFont, int nGlyphIndex, int nReqScreen )
{
- Pixmap aPixmap = None;
GlyphData& rGlyphData = rServerFont.GetGlyphData( nGlyphIndex );
-
- if( rGlyphData.GetExtInfo() == PIXMAP_KIND )
- aPixmap = (Pixmap)rGlyphData.GetExtPointer();
- else
+ Pixmap aPixmap = GetPixmap( rGlyphData, nReqScreen );
+ if( aPixmap == NO_PIXMAP )
{
if( rServerFont.GetGlyphBitmap1( nGlyphIndex, maRawBitmap ) )
{
@@ -441,20 +663,43 @@ Pixmap X11GlyphPeer::GetPixmap( ServerFont& rServerFont, int nGlyphIndex )
for( int i = nBytes; --i >= 0; ++pTemp )
*pTemp = lsb2msb[ *pTemp ];
- aPixmap = XCreatePixmapFromBitmapData( mpDisplay,
- DefaultRootWindow( mpDisplay ), (char*)maRawBitmap.mpBits,
- nPixmapWidth, maRawBitmap.mnHeight, 1, 0, 1 );
- mnBytesUsed += nBytes;
+ // often a glyph pixmap is only needed on the default screen
+ // => optimize for this common case
+ int nMinScreen = 0;
+ int nEndScreen = mnMaxScreens;
+ if( nReqScreen == mnDefaultScreen ) {
+ nMinScreen = mnDefaultScreen;
+ nEndScreen = mnDefaultScreen + 1;
+ }
+ // prepare glyph pixmaps for the different screens
+ for( int i = nMinScreen; i < nEndScreen; ++i )
+ {
+ // don't bother if the pixmap is already there
+ if( GetPixmap( rGlyphData, i ) != NO_PIXMAP )
+ continue;
+ // create the glyph pixmap
+ Pixmap aScreenPixmap = XCreatePixmapFromBitmapData( mpDisplay,
+ RootWindow( mpDisplay, i ), (char*)maRawBitmap.mpBits,
+ nPixmapWidth, maRawBitmap.mnHeight, 1, 0, 1 );
+ // and cache it as glyph specific data
+ SetPixmap( rGlyphData, aScreenPixmap, i );
+ mnBytesUsed += nBytes;
+ if( i == nReqScreen )
+ aPixmap = aScreenPixmap;
+ }
}
}
else
{
// fall back to .notdef glyph
if( nGlyphIndex != 0 ) // recurse only once
- aPixmap = GetPixmap( rServerFont, 0 );
- }
+ aPixmap = GetPixmap( rServerFont, 0, nReqScreen );
+
+ if( aPixmap == NO_PIXMAP )
+ aPixmap = None;
- rGlyphData.SetExtended( PIXMAP_KIND, (void*)aPixmap );
+ SetPixmap( rGlyphData, aPixmap, nReqScreen );
+ }
}
return aPixmap;
@@ -465,19 +710,17 @@ Pixmap X11GlyphPeer::GetPixmap( ServerFont& rServerFont, int nGlyphIndex )
const RawBitmap* X11GlyphPeer::GetRawBitmap( ServerFont& rServerFont,
int nGlyphIndex )
{
- const RawBitmap* pRawBitmap = NULL;
GlyphData& rGlyphData = rServerFont.GetGlyphData( nGlyphIndex );
- if( rGlyphData.GetExtInfo() == AAFORCED_KIND )
- pRawBitmap = (RawBitmap*)rGlyphData.GetExtPointer();
- else
+ const RawBitmap* pRawBitmap = GetRawBitmap( rGlyphData );
+ if( pRawBitmap == NO_RAWBMP )
{
RawBitmap* pNewBitmap = new RawBitmap;
if( rServerFont.GetGlyphBitmap8( nGlyphIndex, *pNewBitmap ) )
{
pRawBitmap = pNewBitmap;
- mnBytesUsed += pRawBitmap->mnScanlineSize * pRawBitmap->mnHeight;
- mnBytesUsed += sizeof(RawBitmap);
+ mnBytesUsed += pNewBitmap->mnScanlineSize * pNewBitmap->mnHeight;
+ mnBytesUsed += sizeof(pNewBitmap);
}
else
{
@@ -487,7 +730,7 @@ const RawBitmap* X11GlyphPeer::GetRawBitmap( ServerFont& rServerFont,
pRawBitmap = GetRawBitmap( rServerFont, 0 );
}
- rGlyphData.SetExtended( AAFORCED_KIND, (void*)pRawBitmap );
+ SetRawBitmap( rGlyphData, pRawBitmap );
}
return pRawBitmap;
@@ -497,12 +740,10 @@ const RawBitmap* X11GlyphPeer::GetRawBitmap( ServerFont& rServerFont,
Glyph X11GlyphPeer::GetGlyphId( ServerFont& rServerFont, int nGlyphIndex )
{
- Glyph aGlyphId = 0;
GlyphData& rGlyphData = rServerFont.GetGlyphData( nGlyphIndex );
- if( rGlyphData.GetExtInfo() == XRENDER_KIND )
- aGlyphId = (Glyph)rGlyphData.GetExtPointer();
- else
+ Glyph aGlyphId = GetRenderGlyph( rGlyphData );
+ if( aGlyphId == NO_GLYPHID )
{
// prepare GlyphInfo and Bitmap
if( rServerFont.GetGlyphBitmap8( nGlyphIndex, maRawBitmap ) )
@@ -521,12 +762,12 @@ Glyph X11GlyphPeer::GetGlyphId( ServerFont& rServerFont, int nGlyphIndex )
aGlyphInfo.yOff = +rGM.GetDelta().Y();
// upload glyph bitmap to server
- GlyphSet aGlyphSet = GetGlyphSet( rServerFont );
+ GlyphSet aGlyphSet = GetGlyphSet( rServerFont, -1 );
aGlyphId = nGlyphIndex & 0x00FFFFFF;
const ULONG nBytes = maRawBitmap.mnScanlineSize * maRawBitmap.mnHeight;
#ifdef XRENDER_LINK
- XRenderAddGlyphs ( mpDisplay, aGlyphSet, &aGlyphId, &aGlyphInfo, 1,
+ XRenderAddGlyphs ( mpDisplay, aGlyphSet, &aGlyphId, &aGlyphInfo, 1,
(char*)maRawBitmap.mpBits, nBytes );
#else
(*pXRenderAddGlyphs)( mpDisplay, aGlyphSet, &aGlyphId, &aGlyphInfo, 1,
@@ -541,7 +782,7 @@ Glyph X11GlyphPeer::GetGlyphId( ServerFont& rServerFont, int nGlyphIndex )
aGlyphId = GetGlyphId( rServerFont, 0 );
}
- rGlyphData.SetExtended( XRENDER_KIND, (void*)aGlyphId );
+ SetRenderGlyph( rGlyphData, aGlyphId );
}
return aGlyphId;