xref: /AOO41X/main/vcl/unx/generic/gdi/gcach_xpeer.cxx (revision 248a599f1fee5b5f8d3deeb99e238404fb7d5288)
1c82f2877SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3c82f2877SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4c82f2877SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5c82f2877SAndrew Rist  * distributed with this work for additional information
6c82f2877SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7c82f2877SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8c82f2877SAndrew Rist  * "License"); you may not use this file except in compliance
9c82f2877SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11c82f2877SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13c82f2877SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14c82f2877SAndrew Rist  * software distributed under the License is distributed on an
15c82f2877SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16c82f2877SAndrew Rist  * KIND, either express or implied.  See the License for the
17c82f2877SAndrew Rist  * specific language governing permissions and limitations
18c82f2877SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20c82f2877SAndrew Rist  *************************************************************/
21c82f2877SAndrew Rist 
22c82f2877SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_vcl.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include "rtl/ustring.hxx"
28cdf0e10cSrcweir #include "osl/module.h"
29cdf0e10cSrcweir #include "osl/thread.h"
30cdf0e10cSrcweir 
31cdf0e10cSrcweir #include "unx/saldisp.hxx"
32cdf0e10cSrcweir #include "unx/saldata.hxx"
33cdf0e10cSrcweir #include "unx/salgdi.h"
34cdf0e10cSrcweir 
35cdf0e10cSrcweir #include "gcach_xpeer.hxx"
36cdf0e10cSrcweir #include "xrender_peer.hxx"
37cdf0e10cSrcweir 
38cdf0e10cSrcweir // ===========================================================================
39cdf0e10cSrcweir 
40cdf0e10cSrcweir // all glyph specific data needed by the XGlyphPeer is quite trivial
41cdf0e10cSrcweir // with one exception: if multiple screens are involved and non-antialiased
42cdf0e10cSrcweir // glyph rendering is active, then we need screen specific pixmaps
43cdf0e10cSrcweir struct MultiScreenGlyph
44cdf0e10cSrcweir {
45cdf0e10cSrcweir     const RawBitmap*    mpRawBitmap;
46cdf0e10cSrcweir     Glyph               maXRGlyphId;
47cdf0e10cSrcweir     Pixmap              maPixmaps[1];   // [mnMaxScreens]
48cdf0e10cSrcweir };
49cdf0e10cSrcweir 
50cdf0e10cSrcweir // ===========================================================================
51cdf0e10cSrcweir 
X11GlyphPeer()52cdf0e10cSrcweir X11GlyphPeer::X11GlyphPeer()
53cdf0e10cSrcweir :   mpDisplay( GetX11SalData()->GetDisplay()->GetDisplay() )
54cdf0e10cSrcweir ,   mnMaxScreens(0)
55cdf0e10cSrcweir ,   mnDefaultScreen(0)
56cdf0e10cSrcweir ,   mnExtByteCount(0)
57cdf0e10cSrcweir ,   mnForcedAA(0)
58cdf0e10cSrcweir ,   mnUsingXRender(0)
59cdf0e10cSrcweir {
60cdf0e10cSrcweir     maRawBitmap.mnAllocated = 0;
61cdf0e10cSrcweir     maRawBitmap.mpBits = NULL;
62cdf0e10cSrcweir     if( !mpDisplay )
63cdf0e10cSrcweir         return;
64cdf0e10cSrcweir 
65cdf0e10cSrcweir     SalDisplay& rSalDisplay = *GetX11SalData()->GetDisplay();
66cdf0e10cSrcweir     mpDisplay    = rSalDisplay.GetDisplay();
67cdf0e10cSrcweir     mnMaxScreens = rSalDisplay.GetScreenCount();
68cdf0e10cSrcweir     if( mnMaxScreens > MAX_GCACH_SCREENS )
69cdf0e10cSrcweir         mnMaxScreens = MAX_GCACH_SCREENS;
70cdf0e10cSrcweir     // if specific glyph data has to be kept for many screens
71cdf0e10cSrcweir     // then prepare the allocation of MultiScreenGlyph objects
72cdf0e10cSrcweir     if( mnMaxScreens > 1 )
73cdf0e10cSrcweir         mnExtByteCount = sizeof(MultiScreenGlyph) + sizeof(Pixmap) * (mnMaxScreens - 1);
74cdf0e10cSrcweir     mnDefaultScreen = rSalDisplay.GetDefaultScreenNumber();
75cdf0e10cSrcweir 
76cdf0e10cSrcweir     InitAntialiasing();
77cdf0e10cSrcweir }
78cdf0e10cSrcweir 
79cdf0e10cSrcweir // ---------------------------------------------------------------------------
80cdf0e10cSrcweir 
~X11GlyphPeer()81cdf0e10cSrcweir X11GlyphPeer::~X11GlyphPeer()
82cdf0e10cSrcweir {
83cdf0e10cSrcweir     SalDisplay* pSalDisp = GetX11SalData()->GetDisplay();
84cdf0e10cSrcweir     Display* const pX11Disp = pSalDisp->GetDisplay();
85cdf0e10cSrcweir     XRenderPeer& rRenderPeer = XRenderPeer::GetInstance();
86cdf0e10cSrcweir     for( int i = 0; i < mnMaxScreens; i++ )
87cdf0e10cSrcweir     {
88cdf0e10cSrcweir         SalDisplay::RenderEntryMap& rMap = pSalDisp->GetRenderEntries( i );
89cdf0e10cSrcweir         for( SalDisplay::RenderEntryMap::iterator it = rMap.begin(); it != rMap.end(); ++it )
90cdf0e10cSrcweir         {
91cdf0e10cSrcweir             if( it->second.m_aPixmap )
92cdf0e10cSrcweir                 ::XFreePixmap( pX11Disp, it->second.m_aPixmap );
93cdf0e10cSrcweir             if( it->second.m_aPicture )
94cdf0e10cSrcweir                 rRenderPeer.FreePicture( it->second.m_aPicture );
95cdf0e10cSrcweir         }
96cdf0e10cSrcweir         rMap.clear();
97cdf0e10cSrcweir     }
98cdf0e10cSrcweir }
99cdf0e10cSrcweir 
100cdf0e10cSrcweir // ---------------------------------------------------------------------------
101cdf0e10cSrcweir 
InitAntialiasing()102cdf0e10cSrcweir void X11GlyphPeer::InitAntialiasing()
103cdf0e10cSrcweir {
104cdf0e10cSrcweir     int nEnvAntiAlias = 0;
105cdf0e10cSrcweir     const char* pEnvAntiAlias = getenv( "SAL_ANTIALIAS_DISABLE" );
106cdf0e10cSrcweir     if( pEnvAntiAlias )
107cdf0e10cSrcweir     {
108cdf0e10cSrcweir         nEnvAntiAlias = atoi( pEnvAntiAlias );
109cdf0e10cSrcweir         if( nEnvAntiAlias == 0 )
110cdf0e10cSrcweir             return;
111cdf0e10cSrcweir     }
112cdf0e10cSrcweir 
113cdf0e10cSrcweir     mnUsingXRender = 0;
114cdf0e10cSrcweir     mnForcedAA = 0;
115cdf0e10cSrcweir 
116cdf0e10cSrcweir     // enable XRENDER accelerated aliasing on screens that support it
117cdf0e10cSrcweir     // unless it explicitly disabled by an environment variable
118cdf0e10cSrcweir     if( (nEnvAntiAlias & 2) == 0 )
119cdf0e10cSrcweir         mnUsingXRender = XRenderPeer::GetInstance().InitRenderText();
120cdf0e10cSrcweir 
121cdf0e10cSrcweir     // else enable client side antialiasing for these screens
122cdf0e10cSrcweir     // unless it is explicitly disabled by an environment variable
123cdf0e10cSrcweir     if( (nEnvAntiAlias & 1) != 0 )
124cdf0e10cSrcweir         return;
125cdf0e10cSrcweir 
126cdf0e10cSrcweir     // enable client side antialiasing for screen visuals that are suitable
127cdf0e10cSrcweir     // mnForcedAA is a bitmask of screens enabled for client side antialiasing
128cdf0e10cSrcweir     mnForcedAA = (~(~0U << mnMaxScreens)) ^ mnUsingXRender;
129cdf0e10cSrcweir     SalDisplay& rSalDisplay = *GetX11SalData()->GetDisplay();
130cdf0e10cSrcweir     for( int nScreen = 0; nScreen < mnMaxScreens; ++nScreen)
131cdf0e10cSrcweir     {
132cdf0e10cSrcweir         Visual* pVisual = rSalDisplay.GetVisual( nScreen ).GetVisual();
133cdf0e10cSrcweir         XVisualInfo aXVisualInfo;
134cdf0e10cSrcweir         aXVisualInfo.visualid = pVisual->visualid;
135cdf0e10cSrcweir         int nVisuals = 0;
136cdf0e10cSrcweir         XVisualInfo* pXVisualInfo = XGetVisualInfo( mpDisplay, VisualIDMask, &aXVisualInfo, &nVisuals );
137cdf0e10cSrcweir         for( int i = nVisuals; --i >= 0; )
138cdf0e10cSrcweir         {
139cdf0e10cSrcweir             if( ((pXVisualInfo[i].c_class==PseudoColor) || (pXVisualInfo[i].depth<24))
140cdf0e10cSrcweir             && ((pXVisualInfo[i].c_class>GrayScale) || (pXVisualInfo[i].depth!=8) ) )
141cdf0e10cSrcweir                 mnForcedAA &= ~(1U << nScreen);
142cdf0e10cSrcweir         }
143cdf0e10cSrcweir         if( pXVisualInfo != NULL )
144cdf0e10cSrcweir             XFree( pXVisualInfo );
145cdf0e10cSrcweir     }
146cdf0e10cSrcweir }
147cdf0e10cSrcweir 
148cdf0e10cSrcweir // ===========================================================================
149cdf0e10cSrcweir 
150cdf0e10cSrcweir enum { INFO_EMPTY=0, INFO_PIXMAP, INFO_XRENDER, INFO_RAWBMP, INFO_MULTISCREEN };
151cdf0e10cSrcweir static const Glyph NO_GLYPHID = 0;
152cdf0e10cSrcweir static RawBitmap* const NO_RAWBMP = NULL;
153cdf0e10cSrcweir static const Pixmap NO_PIXMAP = ~0;
154cdf0e10cSrcweir 
155cdf0e10cSrcweir // ---------------------------------------------------------------------------
156cdf0e10cSrcweir 
PrepareForMultiscreen(ExtGlyphData & rEGD) const157cdf0e10cSrcweir MultiScreenGlyph* X11GlyphPeer::PrepareForMultiscreen( ExtGlyphData& rEGD ) const
158cdf0e10cSrcweir {
159cdf0e10cSrcweir     // prepare to store screen specific pixmaps
160cdf0e10cSrcweir     MultiScreenGlyph* pMSGlyph = (MultiScreenGlyph*)new char[ mnExtByteCount ];
161cdf0e10cSrcweir 
162cdf0e10cSrcweir     // init the glyph formats
163cdf0e10cSrcweir     pMSGlyph->mpRawBitmap = NO_RAWBMP;
164cdf0e10cSrcweir     pMSGlyph->maXRGlyphId = NO_GLYPHID;
165cdf0e10cSrcweir     for( int i = 0; i < mnMaxScreens; ++i )
166cdf0e10cSrcweir         pMSGlyph->maPixmaps[i] = NO_PIXMAP;
167cdf0e10cSrcweir     // reuse already available glyph formats
168cdf0e10cSrcweir     if( rEGD.meInfo == INFO_XRENDER )
169cdf0e10cSrcweir         pMSGlyph->maXRGlyphId = reinterpret_cast<Glyph>(rEGD.mpData);
170cdf0e10cSrcweir     else if( rEGD.meInfo == INFO_RAWBMP )
171cdf0e10cSrcweir         pMSGlyph->mpRawBitmap = reinterpret_cast<RawBitmap*>(rEGD.mpData);
172cdf0e10cSrcweir     else if( rEGD.meInfo == INFO_PIXMAP )
173cdf0e10cSrcweir     {
174cdf0e10cSrcweir         Pixmap aPixmap = reinterpret_cast<Pixmap>(rEGD.mpData);
175cdf0e10cSrcweir         if( aPixmap != None )
176cdf0e10cSrcweir             // pixmap for the default screen is available
177cdf0e10cSrcweir             pMSGlyph->maPixmaps[ mnDefaultScreen ] = aPixmap;
178cdf0e10cSrcweir         else // empty pixmap for all screens is available
179cdf0e10cSrcweir             for( int i = 0; i < mnMaxScreens; ++i )
180cdf0e10cSrcweir                 pMSGlyph->maPixmaps[ i ] = None;
181cdf0e10cSrcweir     }
182cdf0e10cSrcweir     // enable use of multiscreen glyph
183cdf0e10cSrcweir     rEGD.mpData = (void*)pMSGlyph;
184cdf0e10cSrcweir     rEGD.meInfo = INFO_MULTISCREEN;
185cdf0e10cSrcweir 
186cdf0e10cSrcweir     return pMSGlyph;
187cdf0e10cSrcweir  }
188cdf0e10cSrcweir 
189cdf0e10cSrcweir // ---------------------------------------------------------------------------
190cdf0e10cSrcweir 
GetRenderGlyph(const GlyphData & rGD) const191cdf0e10cSrcweir Glyph X11GlyphPeer::GetRenderGlyph( const GlyphData& rGD ) const
192cdf0e10cSrcweir {
193cdf0e10cSrcweir     Glyph aGlyphId = NO_GLYPHID;
194cdf0e10cSrcweir     const ExtGlyphData& rEGD = rGD.ExtDataRef();
195cdf0e10cSrcweir     if( rEGD.meInfo == INFO_XRENDER )
196cdf0e10cSrcweir         aGlyphId = reinterpret_cast<Glyph>(rEGD.mpData);
197cdf0e10cSrcweir     else if( rEGD.meInfo == INFO_MULTISCREEN )
198cdf0e10cSrcweir         aGlyphId = reinterpret_cast<MultiScreenGlyph*>(rEGD.mpData)->maXRGlyphId;
199cdf0e10cSrcweir     return aGlyphId;
200cdf0e10cSrcweir }
201cdf0e10cSrcweir 
202cdf0e10cSrcweir // ---------------------------------------------------------------------------
203cdf0e10cSrcweir 
SetRenderGlyph(GlyphData & rGD,Glyph aGlyphId) const204cdf0e10cSrcweir void X11GlyphPeer::SetRenderGlyph( GlyphData& rGD, Glyph aGlyphId ) const
205cdf0e10cSrcweir {
206cdf0e10cSrcweir     ExtGlyphData& rEGD = rGD.ExtDataRef();
207cdf0e10cSrcweir     switch( rEGD.meInfo )
208cdf0e10cSrcweir     {
209cdf0e10cSrcweir         case INFO_EMPTY:
210cdf0e10cSrcweir             rEGD.meInfo = INFO_XRENDER;
211cdf0e10cSrcweir             // fall through
212cdf0e10cSrcweir         case INFO_XRENDER:
213cdf0e10cSrcweir             rEGD.mpData = reinterpret_cast<void*>(aGlyphId);
214cdf0e10cSrcweir             break;
215cdf0e10cSrcweir         case INFO_PIXMAP:
216cdf0e10cSrcweir         case INFO_RAWBMP:
217cdf0e10cSrcweir             PrepareForMultiscreen( rEGD );
218cdf0e10cSrcweir             // fall through
219cdf0e10cSrcweir         case INFO_MULTISCREEN:
220cdf0e10cSrcweir             reinterpret_cast<MultiScreenGlyph*>(rEGD.mpData)->maXRGlyphId = aGlyphId;
221cdf0e10cSrcweir             break;
222cdf0e10cSrcweir         default:
223cdf0e10cSrcweir             break;  // cannot happen...
224cdf0e10cSrcweir     }
225cdf0e10cSrcweir }
226cdf0e10cSrcweir 
227cdf0e10cSrcweir // ---------------------------------------------------------------------------
228cdf0e10cSrcweir 
GetRawBitmap(const GlyphData & rGD) const229cdf0e10cSrcweir const RawBitmap* X11GlyphPeer::GetRawBitmap( const GlyphData& rGD ) const
230cdf0e10cSrcweir {
231cdf0e10cSrcweir     const RawBitmap* pRawBitmap = NO_RAWBMP;
232cdf0e10cSrcweir     const ExtGlyphData& rEGD = rGD.ExtDataRef();
233cdf0e10cSrcweir     if( rEGD.meInfo == INFO_RAWBMP )
234cdf0e10cSrcweir         pRawBitmap = reinterpret_cast<RawBitmap*>(rEGD.mpData);
235cdf0e10cSrcweir     else if( rEGD.meInfo == INFO_MULTISCREEN )
236cdf0e10cSrcweir         pRawBitmap = reinterpret_cast<MultiScreenGlyph*>(rEGD.mpData)->mpRawBitmap;
237cdf0e10cSrcweir     return pRawBitmap;
238cdf0e10cSrcweir }
239cdf0e10cSrcweir 
240cdf0e10cSrcweir // ---------------------------------------------------------------------------
241cdf0e10cSrcweir 
SetRawBitmap(GlyphData & rGD,const RawBitmap * pRawBitmap) const242cdf0e10cSrcweir void X11GlyphPeer::SetRawBitmap( GlyphData& rGD, const RawBitmap* pRawBitmap ) const
243cdf0e10cSrcweir {
244cdf0e10cSrcweir     ExtGlyphData& rEGD = rGD.ExtDataRef();
245cdf0e10cSrcweir     switch( rEGD.meInfo )
246cdf0e10cSrcweir     {
247cdf0e10cSrcweir         case INFO_EMPTY:
248cdf0e10cSrcweir             rEGD.meInfo = INFO_RAWBMP;
249cdf0e10cSrcweir             // fall through
250cdf0e10cSrcweir         case INFO_RAWBMP:
251cdf0e10cSrcweir             rEGD.mpData = (void*)pRawBitmap;
252cdf0e10cSrcweir             break;
253cdf0e10cSrcweir         case INFO_PIXMAP:
254cdf0e10cSrcweir         case INFO_XRENDER:
255cdf0e10cSrcweir             PrepareForMultiscreen( rEGD );
256cdf0e10cSrcweir             // fall through
257cdf0e10cSrcweir         case INFO_MULTISCREEN:
258cdf0e10cSrcweir             reinterpret_cast<MultiScreenGlyph*>(rEGD.mpData)->mpRawBitmap = pRawBitmap;
259cdf0e10cSrcweir             break;
260cdf0e10cSrcweir         default:
261cdf0e10cSrcweir             // cannot happen...
262cdf0e10cSrcweir             break;
263cdf0e10cSrcweir     }
264cdf0e10cSrcweir }
265cdf0e10cSrcweir 
266cdf0e10cSrcweir // ---------------------------------------------------------------------------
267cdf0e10cSrcweir 
GetPixmap(const GlyphData & rGD,int nScreen) const268cdf0e10cSrcweir Pixmap X11GlyphPeer::GetPixmap( const GlyphData& rGD, int nScreen ) const
269cdf0e10cSrcweir {
270cdf0e10cSrcweir     Pixmap aPixmap = NO_PIXMAP;
271cdf0e10cSrcweir     const ExtGlyphData& rEGD = rGD.ExtDataRef();
272cdf0e10cSrcweir     if( (rEGD.meInfo == INFO_PIXMAP) && (nScreen == mnDefaultScreen) )
273cdf0e10cSrcweir         aPixmap = (Pixmap)rEGD.mpData;
274cdf0e10cSrcweir     else if( rEGD.meInfo == INFO_MULTISCREEN )
275cdf0e10cSrcweir         aPixmap = (Pixmap)(reinterpret_cast<MultiScreenGlyph*>(rEGD.mpData)->maPixmaps[nScreen]);
276cdf0e10cSrcweir     return aPixmap;
277cdf0e10cSrcweir }
278cdf0e10cSrcweir 
279cdf0e10cSrcweir // ---------------------------------------------------------------------------
280cdf0e10cSrcweir 
SetPixmap(GlyphData & rGD,Pixmap aPixmap,int nScreen) const281cdf0e10cSrcweir void X11GlyphPeer::SetPixmap( GlyphData& rGD, Pixmap aPixmap, int nScreen ) const
282cdf0e10cSrcweir {
283cdf0e10cSrcweir     if( aPixmap == NO_PIXMAP )
284cdf0e10cSrcweir         aPixmap = None;
285cdf0e10cSrcweir 
286cdf0e10cSrcweir     ExtGlyphData& rEGD = rGD.ExtDataRef();
287cdf0e10cSrcweir     if( (rEGD.meInfo == INFO_EMPTY) && (nScreen == mnDefaultScreen) )
288cdf0e10cSrcweir     {
289cdf0e10cSrcweir         rEGD.meInfo = INFO_PIXMAP;
290cdf0e10cSrcweir         rEGD.mpData = (void*)aPixmap;
291cdf0e10cSrcweir     }
292cdf0e10cSrcweir     else
293cdf0e10cSrcweir     {
294cdf0e10cSrcweir         MultiScreenGlyph* pMSGlyph;
295cdf0e10cSrcweir         if( rEGD.meInfo == INFO_MULTISCREEN )
296cdf0e10cSrcweir             pMSGlyph = reinterpret_cast<MultiScreenGlyph*>(rEGD.mpData);
297cdf0e10cSrcweir         else
298cdf0e10cSrcweir             pMSGlyph = PrepareForMultiscreen( rEGD );
299cdf0e10cSrcweir 
300cdf0e10cSrcweir         pMSGlyph->maPixmaps[ nScreen ] = aPixmap;
301cdf0e10cSrcweir     }
302cdf0e10cSrcweir }
303cdf0e10cSrcweir 
304cdf0e10cSrcweir // ---------------------------------------------------------------------------
305cdf0e10cSrcweir 
RemovingFont(ServerFont & rServerFont)306cdf0e10cSrcweir void X11GlyphPeer::RemovingFont( ServerFont& rServerFont )
307cdf0e10cSrcweir {
308cdf0e10cSrcweir     void* pFontExt = rServerFont.GetExtPointer();
309cdf0e10cSrcweir     switch( rServerFont.GetExtInfo() )
310cdf0e10cSrcweir     {
311cdf0e10cSrcweir         case INFO_PIXMAP:
312cdf0e10cSrcweir         case INFO_RAWBMP:
313cdf0e10cSrcweir             // nothing to do
314cdf0e10cSrcweir             break;
315cdf0e10cSrcweir         case INFO_MULTISCREEN:
316cdf0e10cSrcweir             // cannot happen...
317cdf0e10cSrcweir             break;
318cdf0e10cSrcweir 
319cdf0e10cSrcweir         case INFO_XRENDER:
320cdf0e10cSrcweir             XRenderPeer::GetInstance().FreeGlyphSet( (GlyphSet)pFontExt );
321cdf0e10cSrcweir             break;
322cdf0e10cSrcweir     }
323cdf0e10cSrcweir 
324cdf0e10cSrcweir     rServerFont.SetExtended( INFO_EMPTY, NULL );
325cdf0e10cSrcweir }
326cdf0e10cSrcweir 
327cdf0e10cSrcweir // ---------------------------------------------------------------------------
328cdf0e10cSrcweir 
329cdf0e10cSrcweir // notification to clean up GlyphPeer resources for this glyph
RemovingGlyph(ServerFont &,GlyphData & rGlyphData,sal_GlyphId)330*248a599fSHerbert Dürr void X11GlyphPeer::RemovingGlyph( ServerFont& /*rServerFont*/, GlyphData& rGlyphData, sal_GlyphId /*aGlyphId*/ )
331cdf0e10cSrcweir {
332cdf0e10cSrcweir     // nothing to do if the GlyphPeer hasn't allocated resources for the glyph
333cdf0e10cSrcweir     if( rGlyphData.ExtDataRef().meInfo == INFO_EMPTY )
334cdf0e10cSrcweir         return;
335cdf0e10cSrcweir 
336cdf0e10cSrcweir     const GlyphMetric& rGM = rGlyphData.GetMetric();
337cdf0e10cSrcweir     const int nWidth  = rGM.GetSize().Width();
338cdf0e10cSrcweir     const int nHeight = rGM.GetSize().Height();
339cdf0e10cSrcweir 
340cdf0e10cSrcweir     void* pGlyphExt = rGlyphData.ExtDataRef().mpData;
341cdf0e10cSrcweir     switch( rGlyphData.ExtDataRef().meInfo )
342cdf0e10cSrcweir     {
343cdf0e10cSrcweir         case INFO_PIXMAP:
344cdf0e10cSrcweir             {
345cdf0e10cSrcweir                 Pixmap aPixmap = (Pixmap)pGlyphExt;
346cdf0e10cSrcweir                 if( aPixmap != None )
347cdf0e10cSrcweir                 {
348cdf0e10cSrcweir                     XFreePixmap( mpDisplay, aPixmap );
349cdf0e10cSrcweir                     mnBytesUsed -= nHeight * ((nWidth + 7) >> 3);
350cdf0e10cSrcweir                 }
351cdf0e10cSrcweir             }
352cdf0e10cSrcweir             break;
353cdf0e10cSrcweir 
354cdf0e10cSrcweir         case INFO_MULTISCREEN:
355cdf0e10cSrcweir             {
356cdf0e10cSrcweir                 MultiScreenGlyph* pMSGlyph = reinterpret_cast<MultiScreenGlyph*>(pGlyphExt);
357cdf0e10cSrcweir                 for( int i = 0; i < mnMaxScreens; ++i)
358cdf0e10cSrcweir                 {
359cdf0e10cSrcweir                     if( pMSGlyph->maPixmaps[i] == NO_PIXMAP )
360cdf0e10cSrcweir                         continue;
361cdf0e10cSrcweir                     if( pMSGlyph->maPixmaps[i] == None )
362cdf0e10cSrcweir                         continue;
363cdf0e10cSrcweir                     XFreePixmap( mpDisplay, pMSGlyph->maPixmaps[i] );
364cdf0e10cSrcweir                     mnBytesUsed -= nHeight * ((nWidth + 7) >> 3);
365cdf0e10cSrcweir                 }
366cdf0e10cSrcweir                 delete pMSGlyph->mpRawBitmap;
367*248a599fSHerbert Dürr                 // XRenderGlyph nXRGlyph = (XRenderGlyph)rGlyphData.GetExtPointer();
368*248a599fSHerbert Dürr                 // XRenderPeer::GetInstance().FreeGlyph( aGlyphSet, &nXRGlyph );
369cdf0e10cSrcweir                 delete[] pMSGlyph; // it was allocated with new char[]
370cdf0e10cSrcweir             }
371cdf0e10cSrcweir             break;
372cdf0e10cSrcweir 
373cdf0e10cSrcweir         case INFO_RAWBMP:
374cdf0e10cSrcweir             {
375cdf0e10cSrcweir                 RawBitmap* pRawBitmap = (RawBitmap*)pGlyphExt;
376cdf0e10cSrcweir                 if( pRawBitmap != NULL )
377cdf0e10cSrcweir                 {
378cdf0e10cSrcweir                     mnBytesUsed -= pRawBitmap->mnScanlineSize * pRawBitmap->mnHeight;
379cdf0e10cSrcweir                     mnBytesUsed -= sizeof(RawBitmap);
380cdf0e10cSrcweir                     delete pRawBitmap;
381cdf0e10cSrcweir                 }
382cdf0e10cSrcweir             }
383cdf0e10cSrcweir             break;
384cdf0e10cSrcweir 
385cdf0e10cSrcweir         case INFO_XRENDER:
386cdf0e10cSrcweir             {
387*248a599fSHerbert Dürr                 // XRenderGlyph nXRGlyph = (XRenderGlyph)rGlyphData.GetExtPointer();
388*248a599fSHerbert Dürr                 // XRenderPeer::GetInstance().FreeGlyph( aGlyphSet, &nXRGlyph );
389cdf0e10cSrcweir                 mnBytesUsed -= nHeight * ((nWidth + 3) & ~3);
390cdf0e10cSrcweir             }
391cdf0e10cSrcweir             break;
392cdf0e10cSrcweir     }
393cdf0e10cSrcweir 
394cdf0e10cSrcweir     if( mnBytesUsed < 0 )   // TODO: eliminate nBytesUsed calc mismatch
395cdf0e10cSrcweir         mnBytesUsed = 0;
396cdf0e10cSrcweir 
397cdf0e10cSrcweir     rGlyphData.ExtDataRef() = ExtGlyphData();
398cdf0e10cSrcweir }
399cdf0e10cSrcweir 
400cdf0e10cSrcweir // ---------------------------------------------------------------------------
401cdf0e10cSrcweir 
ForcedAntialiasing(const ServerFont & rServerFont,int nScreen) const402cdf0e10cSrcweir bool X11GlyphPeer::ForcedAntialiasing( const ServerFont& rServerFont, int nScreen ) const
403cdf0e10cSrcweir {
404cdf0e10cSrcweir     bool bForceOk = rServerFont.GetAntialiasAdvice();
405cdf0e10cSrcweir     // maximum size for antialiasing is 250 pixels
406cdf0e10cSrcweir     bForceOk &= (rServerFont.GetFontSelData().mnHeight < 250);
407cdf0e10cSrcweir     return (bForceOk && ((mnForcedAA >> nScreen) & 1));
408cdf0e10cSrcweir }
409cdf0e10cSrcweir 
410cdf0e10cSrcweir // ---------------------------------------------------------------------------
411cdf0e10cSrcweir 
GetGlyphSet(ServerFont & rServerFont,int nScreen)412cdf0e10cSrcweir GlyphSet X11GlyphPeer::GetGlyphSet( ServerFont& rServerFont, int nScreen )
413cdf0e10cSrcweir {
414cdf0e10cSrcweir     if( (nScreen >= 0) && ((mnUsingXRender >> nScreen) & 1) == 0 )
415cdf0e10cSrcweir         return 0;
416cdf0e10cSrcweir 
417cdf0e10cSrcweir     GlyphSet aGlyphSet;
418cdf0e10cSrcweir 
419cdf0e10cSrcweir     switch( rServerFont.GetExtInfo() )
420cdf0e10cSrcweir     {
421cdf0e10cSrcweir         case INFO_XRENDER:
422cdf0e10cSrcweir             aGlyphSet = (GlyphSet)rServerFont.GetExtPointer();
423cdf0e10cSrcweir             break;
424cdf0e10cSrcweir 
425cdf0e10cSrcweir         case INFO_EMPTY:
426cdf0e10cSrcweir             {
427cdf0e10cSrcweir                 // antialiasing for reasonable font heights only
428cdf0e10cSrcweir                 // => prevents crashes caused by X11 requests >= 256k
429cdf0e10cSrcweir                 // => prefer readablity of hinted glyphs at small sizes
430cdf0e10cSrcweir                 // => prefer "grey clouds" to "black clouds" at very small sizes
431cdf0e10cSrcweir                 int nHeight = rServerFont.GetFontSelData().mnHeight;
432cdf0e10cSrcweir                 if( nHeight<250 && rServerFont.GetAntialiasAdvice() )
433cdf0e10cSrcweir                 {
434cdf0e10cSrcweir                     aGlyphSet = XRenderPeer::GetInstance().CreateGlyphSet();
435cdf0e10cSrcweir                     rServerFont.SetExtended( INFO_XRENDER, (void*)aGlyphSet );
436cdf0e10cSrcweir                 }
437cdf0e10cSrcweir                 else
438cdf0e10cSrcweir                     aGlyphSet = 0;
439cdf0e10cSrcweir             }
440cdf0e10cSrcweir             break;
441cdf0e10cSrcweir 
442cdf0e10cSrcweir         default:
443cdf0e10cSrcweir             aGlyphSet = 0;
444cdf0e10cSrcweir             break;
445cdf0e10cSrcweir     }
446cdf0e10cSrcweir 
447cdf0e10cSrcweir     return aGlyphSet;
448cdf0e10cSrcweir }
449cdf0e10cSrcweir 
450cdf0e10cSrcweir // ---------------------------------------------------------------------------
451cdf0e10cSrcweir 
GetPixmap(ServerFont & rServerFont,sal_GlyphId aGlyphId,int nReqScreen)452*248a599fSHerbert Dürr Pixmap X11GlyphPeer::GetPixmap( ServerFont& rServerFont, sal_GlyphId aGlyphId, int nReqScreen )
453cdf0e10cSrcweir {
454*248a599fSHerbert Dürr     if( rServerFont.IsGlyphInvisible( aGlyphId ) )
455cdf0e10cSrcweir         return None;
456cdf0e10cSrcweir 
457*248a599fSHerbert Dürr     GlyphData& rGlyphData = rServerFont.GetGlyphData( aGlyphId );
458cdf0e10cSrcweir     Pixmap aPixmap = GetPixmap( rGlyphData, nReqScreen );
459cdf0e10cSrcweir     if( aPixmap == NO_PIXMAP )
460cdf0e10cSrcweir     {
461cdf0e10cSrcweir         aPixmap = None;
462*248a599fSHerbert Dürr         if( rServerFont.GetGlyphBitmap1( aGlyphId, maRawBitmap ) )
463cdf0e10cSrcweir         {
464cdf0e10cSrcweir             // #94666# circumvent bug in some X11 systems, e.g. XF410.LynxEM.v163
465cdf0e10cSrcweir             sal_uLong nPixmapWidth = 8 * maRawBitmap.mnScanlineSize - 1;
466cdf0e10cSrcweir             nPixmapWidth = Max( nPixmapWidth, maRawBitmap.mnWidth );
467cdf0e10cSrcweir 
468cdf0e10cSrcweir             rGlyphData.SetSize( Size( nPixmapWidth, maRawBitmap.mnHeight ) );
469cdf0e10cSrcweir             rGlyphData.SetOffset( +maRawBitmap.mnXOffset, +maRawBitmap.mnYOffset );
470cdf0e10cSrcweir 
471cdf0e10cSrcweir             const sal_uLong nBytes = maRawBitmap.mnHeight * maRawBitmap.mnScanlineSize;
472cdf0e10cSrcweir             if( nBytes > 0 )
473cdf0e10cSrcweir             {
474cdf0e10cSrcweir                 // conversion table LSB<->MSB (for XCreatePixmapFromData)
475cdf0e10cSrcweir                 static const unsigned char lsb2msb[256] =
476cdf0e10cSrcweir                 {
477cdf0e10cSrcweir                     0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
478cdf0e10cSrcweir                     0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
479cdf0e10cSrcweir                     0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
480cdf0e10cSrcweir                     0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
481cdf0e10cSrcweir                     0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
482cdf0e10cSrcweir                     0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
483cdf0e10cSrcweir                     0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
484cdf0e10cSrcweir                     0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
485cdf0e10cSrcweir                     0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
486cdf0e10cSrcweir                     0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
487cdf0e10cSrcweir                     0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
488cdf0e10cSrcweir                     0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
489cdf0e10cSrcweir                     0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
490cdf0e10cSrcweir                     0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
491cdf0e10cSrcweir                     0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
492cdf0e10cSrcweir                     0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
493cdf0e10cSrcweir                     0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
494cdf0e10cSrcweir                     0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
495cdf0e10cSrcweir                     0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
496cdf0e10cSrcweir                     0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
497cdf0e10cSrcweir                     0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
498cdf0e10cSrcweir                     0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
499cdf0e10cSrcweir                     0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
500cdf0e10cSrcweir                     0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
501cdf0e10cSrcweir                     0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
502cdf0e10cSrcweir                     0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
503cdf0e10cSrcweir                     0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
504cdf0e10cSrcweir                     0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
505cdf0e10cSrcweir                     0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
506cdf0e10cSrcweir                     0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
507cdf0e10cSrcweir                     0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
508cdf0e10cSrcweir                     0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
509cdf0e10cSrcweir                 };
510cdf0e10cSrcweir 
511cdf0e10cSrcweir                 unsigned char* pTemp = maRawBitmap.mpBits;
512cdf0e10cSrcweir                 for( int i = nBytes; --i >= 0; ++pTemp )
513cdf0e10cSrcweir                     *pTemp = lsb2msb[ *pTemp ];
514cdf0e10cSrcweir 
515cdf0e10cSrcweir                 // often a glyph pixmap is only needed on the default screen
516cdf0e10cSrcweir                 // => optimize for this common case
517cdf0e10cSrcweir                 int nMinScreen = 0;
518cdf0e10cSrcweir                 int nEndScreen = mnMaxScreens;
519cdf0e10cSrcweir                 if( nReqScreen == mnDefaultScreen ) {
520cdf0e10cSrcweir                     nMinScreen = mnDefaultScreen;
521cdf0e10cSrcweir                     nEndScreen = mnDefaultScreen + 1;
522cdf0e10cSrcweir                 }
523cdf0e10cSrcweir                 // prepare glyph pixmaps for the different screens
524cdf0e10cSrcweir                 for( int i = nMinScreen; i < nEndScreen; ++i )
525cdf0e10cSrcweir                 {
526cdf0e10cSrcweir                     // don't bother if the pixmap is already there
527cdf0e10cSrcweir                     if( GetPixmap( rGlyphData, i ) != NO_PIXMAP )
528cdf0e10cSrcweir                         continue;
529cdf0e10cSrcweir                     // create the glyph pixmap
530cdf0e10cSrcweir                     Pixmap aScreenPixmap = XCreatePixmapFromBitmapData( mpDisplay,
531cdf0e10cSrcweir                         RootWindow( mpDisplay, i ), (char*)maRawBitmap.mpBits,
532cdf0e10cSrcweir                         nPixmapWidth, maRawBitmap.mnHeight, 1, 0, 1 );
533cdf0e10cSrcweir                     // and cache it as glyph specific data
534cdf0e10cSrcweir                     SetPixmap( rGlyphData, aScreenPixmap, i );
535cdf0e10cSrcweir                     mnBytesUsed += nBytes;
536cdf0e10cSrcweir                     if( i == nReqScreen )
537cdf0e10cSrcweir                         aPixmap = aScreenPixmap;
538cdf0e10cSrcweir                 }
539cdf0e10cSrcweir             }
540cdf0e10cSrcweir         }
541cdf0e10cSrcweir         else
542cdf0e10cSrcweir         {
543cdf0e10cSrcweir             // fall back to .notdef glyph
544*248a599fSHerbert Dürr             if( aGlyphId != 0 )  // recurse only once
545cdf0e10cSrcweir                 aPixmap = GetPixmap( rServerFont, 0, nReqScreen );
546cdf0e10cSrcweir 
547cdf0e10cSrcweir             if( aPixmap == NO_PIXMAP )
548cdf0e10cSrcweir                 aPixmap = None;
549cdf0e10cSrcweir         }
550cdf0e10cSrcweir     }
551cdf0e10cSrcweir 
552cdf0e10cSrcweir     return aPixmap;
553cdf0e10cSrcweir }
554cdf0e10cSrcweir 
555cdf0e10cSrcweir // ---------------------------------------------------------------------------
556cdf0e10cSrcweir 
GetRawBitmap(ServerFont & rServerFont,sal_GlyphId aGlyphId)557*248a599fSHerbert Dürr const RawBitmap* X11GlyphPeer::GetRawBitmap( ServerFont& rServerFont, sal_GlyphId aGlyphId )
558cdf0e10cSrcweir {
559*248a599fSHerbert Dürr     if( rServerFont.IsGlyphInvisible( aGlyphId ) )
560cdf0e10cSrcweir         return NO_RAWBMP;
561cdf0e10cSrcweir 
562*248a599fSHerbert Dürr     GlyphData& rGlyphData = rServerFont.GetGlyphData( aGlyphId );
563cdf0e10cSrcweir 
564cdf0e10cSrcweir     const RawBitmap* pRawBitmap = GetRawBitmap( rGlyphData );
565cdf0e10cSrcweir     if( pRawBitmap == NO_RAWBMP )
566cdf0e10cSrcweir     {
567cdf0e10cSrcweir         RawBitmap* pNewBitmap = new RawBitmap;
568*248a599fSHerbert Dürr         if( rServerFont.GetGlyphBitmap8( aGlyphId, *pNewBitmap ) )
569cdf0e10cSrcweir         {
570cdf0e10cSrcweir             pRawBitmap = pNewBitmap;
571cdf0e10cSrcweir             mnBytesUsed += pNewBitmap->mnScanlineSize * pNewBitmap->mnHeight;
572cdf0e10cSrcweir             mnBytesUsed += sizeof(pNewBitmap);
573cdf0e10cSrcweir         }
574cdf0e10cSrcweir         else
575cdf0e10cSrcweir         {
576cdf0e10cSrcweir             delete pNewBitmap;
577cdf0e10cSrcweir             // fall back to .notdef glyph
578*248a599fSHerbert Dürr             if( aGlyphId != 0 )  // recurse only once
579cdf0e10cSrcweir                 pRawBitmap = GetRawBitmap( rServerFont, 0 );
580cdf0e10cSrcweir         }
581cdf0e10cSrcweir 
582cdf0e10cSrcweir         SetRawBitmap( rGlyphData, pRawBitmap );
583cdf0e10cSrcweir     }
584cdf0e10cSrcweir 
585cdf0e10cSrcweir     return pRawBitmap;
586cdf0e10cSrcweir }
587cdf0e10cSrcweir 
588cdf0e10cSrcweir // ---------------------------------------------------------------------------
589cdf0e10cSrcweir 
GetXRGlyph(ServerFont & rServerFont,sal_GlyphId aGlyphId)590*248a599fSHerbert Dürr XRenderGlyph X11GlyphPeer::GetXRGlyph( ServerFont& rServerFont, sal_GlyphId aGlyphId )
591cdf0e10cSrcweir {
592*248a599fSHerbert Dürr     if( rServerFont.IsGlyphInvisible( aGlyphId ) )
593cdf0e10cSrcweir         return NO_GLYPHID;
594cdf0e10cSrcweir 
595*248a599fSHerbert Dürr     GlyphData& rGlyphData = rServerFont.GetGlyphData( aGlyphId );
596cdf0e10cSrcweir 
597*248a599fSHerbert Dürr     XRenderGlyph nXRGlyph = GetRenderGlyph( rGlyphData );
598*248a599fSHerbert Dürr     if( nXRGlyph == NO_GLYPHID )
599cdf0e10cSrcweir     {
600cdf0e10cSrcweir         // prepare GlyphInfo and Bitmap
601*248a599fSHerbert Dürr         if( rServerFont.GetGlyphBitmap8( aGlyphId, maRawBitmap ) )
602cdf0e10cSrcweir         {
603cdf0e10cSrcweir             XGlyphInfo aGlyphInfo;
604cdf0e10cSrcweir             aGlyphInfo.width    = maRawBitmap.mnWidth;
605cdf0e10cSrcweir             aGlyphInfo.height   = maRawBitmap.mnHeight;
606cdf0e10cSrcweir             aGlyphInfo.x        = -maRawBitmap.mnXOffset;
607cdf0e10cSrcweir             aGlyphInfo.y        = -maRawBitmap.mnYOffset;
608cdf0e10cSrcweir 
609cdf0e10cSrcweir             rGlyphData.SetSize( Size( maRawBitmap.mnWidth, maRawBitmap.mnHeight ) );
610cdf0e10cSrcweir             rGlyphData.SetOffset( +maRawBitmap.mnXOffset, +maRawBitmap.mnYOffset );
611cdf0e10cSrcweir 
612cdf0e10cSrcweir             const GlyphMetric& rGM = rGlyphData.GetMetric();
613cdf0e10cSrcweir             aGlyphInfo.xOff     = +rGM.GetDelta().X();
614cdf0e10cSrcweir             aGlyphInfo.yOff     = +rGM.GetDelta().Y();
615cdf0e10cSrcweir 
616cdf0e10cSrcweir             // upload glyph bitmap to server
617cdf0e10cSrcweir             GlyphSet aGlyphSet = GetGlyphSet( rServerFont, -1 );
618cdf0e10cSrcweir 
619*248a599fSHerbert Dürr             nXRGlyph = aGlyphId & 0x00FFFFFF;
620cdf0e10cSrcweir             const sal_uLong nBytes = maRawBitmap.mnScanlineSize * maRawBitmap.mnHeight;
621*248a599fSHerbert Dürr             XRenderPeer::GetInstance().AddGlyph( aGlyphSet, nXRGlyph,
622cdf0e10cSrcweir                 aGlyphInfo, (char*)maRawBitmap.mpBits, nBytes );
623cdf0e10cSrcweir             mnBytesUsed += nBytes;
624cdf0e10cSrcweir         }
625cdf0e10cSrcweir         else
626cdf0e10cSrcweir         {
627cdf0e10cSrcweir             // fall back to .notdef glyph
628*248a599fSHerbert Dürr             if( nXRGlyph != 0 )  // recurse only once
629*248a599fSHerbert Dürr                 nXRGlyph = GetXRGlyph( rServerFont, 0 );
630cdf0e10cSrcweir         }
631cdf0e10cSrcweir 
632*248a599fSHerbert Dürr         SetRenderGlyph( rGlyphData, nXRGlyph );
633cdf0e10cSrcweir     }
634cdf0e10cSrcweir 
635*248a599fSHerbert Dürr     return nXRGlyph;
636cdf0e10cSrcweir }
637cdf0e10cSrcweir 
638cdf0e10cSrcweir // ===========================================================================
639cdf0e10cSrcweir 
X11GlyphCache(X11GlyphPeer & rPeer)640cdf0e10cSrcweir X11GlyphCache::X11GlyphCache( X11GlyphPeer& rPeer )
641cdf0e10cSrcweir :	GlyphCache( rPeer )
642cdf0e10cSrcweir {
643cdf0e10cSrcweir }
644cdf0e10cSrcweir 
645cdf0e10cSrcweir // ---------------------------------------------------------------------------
646cdf0e10cSrcweir 
647cdf0e10cSrcweir static X11GlyphPeer* pX11GlyphPeer = NULL;
648cdf0e10cSrcweir static X11GlyphCache* pX11GlyphCache = NULL;
649cdf0e10cSrcweir 
GetInstance()650cdf0e10cSrcweir X11GlyphCache& X11GlyphCache::GetInstance()
651cdf0e10cSrcweir {
652cdf0e10cSrcweir     if( !pX11GlyphCache )
653cdf0e10cSrcweir     {
654cdf0e10cSrcweir         pX11GlyphPeer = new X11GlyphPeer();
655cdf0e10cSrcweir         pX11GlyphCache = new X11GlyphCache( *pX11GlyphPeer );
656cdf0e10cSrcweir     }
657cdf0e10cSrcweir     return *pX11GlyphCache;
658cdf0e10cSrcweir }
659cdf0e10cSrcweir 
660cdf0e10cSrcweir // ---------------------------------------------------------------------------
661cdf0e10cSrcweir 
KillInstance()662cdf0e10cSrcweir void X11GlyphCache::KillInstance()
663cdf0e10cSrcweir {
664cdf0e10cSrcweir     delete pX11GlyphCache;
665cdf0e10cSrcweir     delete pX11GlyphPeer;
666cdf0e10cSrcweir     pX11GlyphCache = NULL;
667cdf0e10cSrcweir     pX11GlyphPeer = NULL;
668cdf0e10cSrcweir }
669cdf0e10cSrcweir 
670cdf0e10cSrcweir // ===========================================================================
671cdf0e10cSrcweir 
releaseGlyphPeer()672cdf0e10cSrcweir void X11SalGraphics::releaseGlyphPeer()
673cdf0e10cSrcweir {
674cdf0e10cSrcweir     X11GlyphCache::KillInstance();
675cdf0e10cSrcweir }
676cdf0e10cSrcweir 
677cdf0e10cSrcweir // ===========================================================================
678cdf0e10cSrcweir 
679