xref: /trunk/main/vcl/unx/generic/gdi/xrender_peer.hxx (revision 248a599f)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef _SV_XRENDER_PEER_HXX
25 #define _SV_XRENDER_PEER_HXX
26 
27 #include <tools/prex.h>
28 struct _XTrap; // on some older systems this is not declared within Xrender.h
29 #include <X11/extensions/Xrender.h>
30 #include <tools/postx.h>
31 
32 #include <vcl/salgtype.hxx>
33 #include <osl/module.h>
34 
35 typedef Glyph XRenderGlyph;
36 
37 class XRenderPeer
38 {
39 public:
40     static XRenderPeer& GetInstance();
41     int                 GetVersion() const;
42 
43     sal_uInt32          InitRenderText();
44 
45 protected:
46                         XRenderPeer();
47                         ~XRenderPeer();
48     void                InitRenderLib();
49 
50     Display*            mpDisplay;
51     XRenderPictFormat*  mpStandardFormatA8;
52     int                 mnRenderVersion;
53     oslModule           mpRenderLib;
54 
55 public:
56     XRenderPictFormat* GetStandardFormatA8() const;
57     XRenderPictFormat* FindStandardFormat(int nFormat) const;
58 
59     // the methods below are thin wrappers for the XRENDER API
60     XRenderPictFormat* FindVisualFormat( Visual* ) const;
61     XRenderPictFormat* FindPictureFormat( unsigned long nMask,
62         const XRenderPictFormat& ) const;
63     Picture     CreatePicture( Drawable, const XRenderPictFormat*,
64                     unsigned long nDrawable, const XRenderPictureAttributes* ) const;
65     void        ChangePicture( Picture, unsigned long nValueMask,
66                     const XRenderPictureAttributes* ) const;
67     void        SetPictureClipRegion( Picture, XLIB_Region ) const;
68     void        CompositePicture( int nOp, Picture aSrc, Picture aMask, Picture aDst,
69                     int nXSrc, int nYSrc, int nXMask, int nYMask,
70                     int nXDst, int nYDst, unsigned nWidth, unsigned nHeight ) const;
71     void        FreePicture( Picture ) const;
72 
73     GlyphSet    CreateGlyphSet() const;
74     void        FreeGlyphSet( GlyphSet ) const;
75     void        AddGlyph( GlyphSet, XRenderGlyph nXRGlyph, const XGlyphInfo&,
76                     const char* pBuffer, int nBufSize ) const;
77     void        FreeGlyph( GlyphSet, XRenderGlyph nXRGlyphId ) const;
78     void        CompositeString32( Picture aSrc, Picture aDst, GlyphSet,
79                     int nDstX, int nDstY, const unsigned* pText, int nTextLen ) const;
80     void        FillRectangle( int nOp, Picture aDst, const XRenderColor*,
81                                int nX, int nY, unsigned nW, unsigned nH ) const;
82     void        CompositeTrapezoids( int nOp, Picture aSrc, Picture aDst,
83                     const XRenderPictFormat*, int nXSrc, int nYSrc,
84                     const XTrapezoid*, int nCount ) const;
85     bool        AddTraps( Picture aDst, int nXOfs, int nYOfs,
86                     const _XTrap*, int nCount ) const;
87 
AreTrapezoidsSupported() const88     bool        AreTrapezoidsSupported() const
89 #ifdef XRENDER_LINK
90                     { return true; }
91 #else
92                     { return mpXRenderCompositeTrapezoids!=NULL; }
93 
94 private:
95     XRenderPictFormat* (*mpXRenderFindFormat)(Display*,unsigned long,
96         const XRenderPictFormat*,int);
97     XRenderPictFormat* (*mpXRenderFindVisualFormat)(Display*,Visual*);
98     XRenderPictFormat* (*mpXRenderFindStandardFormat)(Display*,int);
99     Bool        (*mpXRenderQueryExtension)(Display*,int*,int*);
100     void        (*mpXRenderQueryVersion)(Display*,int*,int*);
101 
102     Picture     (*mpXRenderCreatePicture)(Display*,Drawable, const XRenderPictFormat*,
103                     unsigned long,const XRenderPictureAttributes*);
104     void        (*mpXRenderChangePicture)(Display*,Picture,
105                     unsigned long,const XRenderPictureAttributes*);
106     void        (*mpXRenderSetPictureClipRegion)(Display*,Picture,XLIB_Region);
107     void        (*mpXRenderFreePicture)(Display*,Picture);
108     void        (*mpXRenderComposite)(Display*,int,Picture,Picture,Picture,
109                     int,int,int,int,int,int,unsigned,unsigned);
110 
111     GlyphSet    (*mpXRenderCreateGlyphSet)(Display*, const XRenderPictFormat*);
112     void        (*mpXRenderFreeGlyphSet)(Display*,GlyphSet);
113     void        (*mpXRenderAddGlyphs)(Display*,GlyphSet,Glyph*,
114                     const XGlyphInfo*,int,const char*,int);
115     void        (*mpXRenderFreeGlyphs)(Display*,GlyphSet,Glyph*,int);
116     void        (*mpXRenderCompositeString32)(Display*,int,Picture,Picture,
117                     const XRenderPictFormat*,GlyphSet,int,int,int,int,const unsigned*,int);
118     void        (*mpXRenderFillRectangle)(Display*,int,Picture,
119                     const XRenderColor*,int,int,unsigned int,unsigned int);
120     void        (*mpXRenderCompositeTrapezoids)(Display*,int,Picture,Picture,
121                     const XRenderPictFormat*,int,int,const XTrapezoid*,int);
122     void        (*mpXRenderAddTraps)(Display*,Picture,int,int,const _XTrap*,int);
123 #endif // XRENDER_LINK
124 };
125 
126 //=====================================================================
127 
128 class ScopedPic
129 {
130 public:
131                ScopedPic( XRenderPeer& rPeer, Picture& rPic );
132                ~ScopedPic();
133     Picture&   Get();
134 
135 private:
136     XRenderPeer& mrRenderPeer;
137     Picture      maPicture;
138 
139 private: // prevent copy and assignmet
140            ScopedPic( const ScopedPic& );
141     void   operator=( const ScopedPic& );
142 };
143 
144 //=====================================================================
145 
GetVersion() const146 inline int XRenderPeer::GetVersion() const
147 {
148     return mnRenderVersion;
149 }
150 
GetStandardFormatA8() const151 inline XRenderPictFormat* XRenderPeer::GetStandardFormatA8() const
152 {
153     return mpStandardFormatA8;
154 }
155 
FindStandardFormat(int nFormat) const156 inline XRenderPictFormat* XRenderPeer::FindStandardFormat(int nFormat) const
157 {
158 #ifdef XRENDER_LINK
159     return XRenderFindStandardFormat(mpDisplay, nFormat);
160 #else
161     return (*mpXRenderFindStandardFormat)(mpDisplay, nFormat);
162 #endif
163 }
164 
FindVisualFormat(Visual * pVisual) const165 inline XRenderPictFormat* XRenderPeer::FindVisualFormat( Visual* pVisual ) const
166 {
167 #ifdef XRENDER_LINK
168     return XRenderFindVisualFormat ( mpDisplay, pVisual );
169 #else
170     return (*mpXRenderFindVisualFormat)( mpDisplay, pVisual );
171 #endif
172 }
173 
FindPictureFormat(unsigned long nFormatMask,const XRenderPictFormat & rFormatAttr) const174 inline XRenderPictFormat* XRenderPeer::FindPictureFormat( unsigned long nFormatMask,
175     const XRenderPictFormat& rFormatAttr ) const
176 {
177 #ifdef XRENDER_LINK
178     return XRenderFindFormat( mpDisplay, nFormatMask, &rFormatAttr, 0 );
179 #else
180     return (*mpXRenderFindFormat)( mpDisplay, nFormatMask, &rFormatAttr, 0 );
181 #endif
182 }
183 
CreatePicture(Drawable aDrawable,const XRenderPictFormat * pVisFormat,unsigned long nValueMask,const XRenderPictureAttributes * pRenderAttr) const184 inline Picture XRenderPeer::CreatePicture( Drawable aDrawable,
185     const XRenderPictFormat* pVisFormat, unsigned long nValueMask,
186     const XRenderPictureAttributes* pRenderAttr ) const
187 {
188 #ifdef XRENDER_LINK
189     return XRenderCreatePicture( mpDisplay, aDrawable, pVisFormat,
190                                  nValueMask, pRenderAttr );
191 #else
192     return (*mpXRenderCreatePicture)( mpDisplay, aDrawable, pVisFormat,
193         nValueMask, pRenderAttr );
194 #endif
195 }
196 
ChangePicture(Picture aPicture,unsigned long nValueMask,const XRenderPictureAttributes * pRenderAttr) const197 inline void XRenderPeer::ChangePicture( Picture aPicture,
198     unsigned long nValueMask, const XRenderPictureAttributes* pRenderAttr ) const
199 {
200 #ifdef XRENDER_LINK
201     XRenderChangePicture( mpDisplay, aPicture, nValueMask, pRenderAttr );
202 #else
203     (*mpXRenderChangePicture)( mpDisplay, aPicture, nValueMask, pRenderAttr );
204 #endif
205 }
206 
SetPictureClipRegion(Picture aPicture,XLIB_Region aXlibRegion) const207 inline void XRenderPeer::SetPictureClipRegion( Picture aPicture,
208     XLIB_Region aXlibRegion ) const
209 {
210 #ifdef XRENDER_LINK
211     XRenderSetPictureClipRegion( mpDisplay, aPicture, aXlibRegion );
212 #else
213     (*mpXRenderSetPictureClipRegion)( mpDisplay, aPicture, aXlibRegion );
214 #endif
215 }
216 
CompositePicture(int nXRenderOp,Picture aSrcPic,Picture aMaskPic,Picture aDstPic,int nSrcX,int nSrcY,int nMaskX,int nMaskY,int nDstX,int nDstY,unsigned nWidth,unsigned nHeight) const217 inline void XRenderPeer::CompositePicture( int nXRenderOp,
218     Picture aSrcPic, Picture aMaskPic, Picture aDstPic,
219     int nSrcX, int nSrcY, int nMaskX, int nMaskY, int nDstX, int nDstY,
220     unsigned nWidth, unsigned nHeight ) const
221 {
222 #ifdef XRENDER_LINK
223     XRenderComposite( mpDisplay, nXRenderOp, aSrcPic, aMaskPic, aDstPic,
224                       nSrcX, nSrcY, nMaskX, nMaskY, nDstX, nDstY, nWidth, nHeight );
225 #else
226     (*mpXRenderComposite)( mpDisplay, nXRenderOp, aSrcPic, aMaskPic, aDstPic,
227         nSrcX, nSrcY, nMaskX, nMaskY, nDstX, nDstY, nWidth, nHeight );
228 #endif
229 }
230 
FreePicture(Picture aPicture) const231 inline void XRenderPeer::FreePicture( Picture aPicture ) const
232 {
233 #ifdef XRENDER_LINK
234     XRenderFreePicture( mpDisplay, aPicture );
235 #else
236     (*mpXRenderFreePicture)( mpDisplay, aPicture );
237 #endif
238 }
239 
CreateGlyphSet() const240 inline GlyphSet XRenderPeer::CreateGlyphSet() const
241 {
242 #ifdef XRENDER_LINK
243     return XRenderCreateGlyphSet( mpDisplay, mpStandardFormatA8 );
244 #else
245     return (*mpXRenderCreateGlyphSet)( mpDisplay, mpStandardFormatA8 );
246 #endif
247 }
248 
FreeGlyphSet(GlyphSet aGS) const249 inline void XRenderPeer::FreeGlyphSet( GlyphSet aGS ) const
250 {
251 #ifdef XRENDER_LINK
252     XRenderFreeGlyphSet( mpDisplay, aGS );
253 #else
254     (*mpXRenderFreeGlyphSet)( mpDisplay, aGS );
255 #endif
256 }
257 
AddGlyph(GlyphSet aGS,XRenderGlyph nXRGlyph,const XGlyphInfo & rGI,const char * pBuffer,int nBufSize) const258 inline void XRenderPeer::AddGlyph( GlyphSet aGS, XRenderGlyph nXRGlyph,
259     const XGlyphInfo& rGI, const char* pBuffer, int nBufSize ) const
260 {
261 #ifdef XRENDER_LINK
262     XRenderAddGlyphs( mpDisplay, aGS, &nXRGlyph, &rGI, 1,
263                       const_cast<char*>(pBuffer), nBufSize );
264 #else
265     (*mpXRenderAddGlyphs)( mpDisplay, aGS, &nXRGlyph, &rGI, 1,
266         const_cast<char*>(pBuffer), nBufSize );
267 #endif
268 }
269 
FreeGlyph(GlyphSet aGS,XRenderGlyph nXRGlyph) const270 inline void XRenderPeer::FreeGlyph( GlyphSet aGS, XRenderGlyph nXRGlyph ) const
271 {
272     (void)aGS; (void)nXRGlyph;
273 
274     // XRenderFreeGlyphs not implemented yet for version<=0.2
275     // #108209# disabled because of crash potential,
276     // the glyph leak is not too bad because they will
277     // be cleaned up when the glyphset is released
278 #if 0 // TODO: reenable when it works without problems
279     if( mnRenderVersion >= 0x05 )
280     {
281 #ifdef XRENDER_LINK
282         XRenderFreeGlyphs( mpDisplay, aGS, &nXRGlyph, 1 );
283 #else
284         (*mpXRenderFreeGlyphs)( mpDisplay, aGS, &nXRGlyph, 1 );
285 #endif
286     }
287 #endif
288 }
289 
CompositeString32(Picture aSrc,Picture aDst,GlyphSet aGlyphSet,int nDstX,int nDstY,const unsigned * pText,int nTextLen) const290 inline void XRenderPeer::CompositeString32( Picture aSrc, Picture aDst,
291     GlyphSet aGlyphSet, int nDstX, int nDstY,
292     const unsigned* pText, int nTextLen ) const
293 {
294 #ifdef XRENDER_LINK
295     XRenderCompositeString32( mpDisplay, PictOpOver, aSrc, aDst, NULL,
296                               aGlyphSet, 0, 0, nDstX, nDstY, pText, nTextLen );
297 #else
298     (*mpXRenderCompositeString32)( mpDisplay, PictOpOver, aSrc, aDst, NULL,
299         aGlyphSet, 0, 0, nDstX, nDstY, pText, nTextLen );
300 #endif
301 }
302 
FillRectangle(int a,Picture b,const XRenderColor * c,int d,int e,unsigned int f,unsigned int g) const303 inline void XRenderPeer::FillRectangle( int a, Picture b, const XRenderColor* c,
304     int d, int e, unsigned int f, unsigned int g) const
305 {
306 #ifdef XRENDER_LINK
307     XRenderFillRectangle( mpDisplay, a, b, c, d, e, f, g );
308 #else
309     (*mpXRenderFillRectangle)( mpDisplay, a, b, c, d, e, f, g );
310 #endif
311 }
312 
313 
CompositeTrapezoids(int nOp,Picture aSrc,Picture aDst,const XRenderPictFormat * pXRPF,int nXSrc,int nYSrc,const XTrapezoid * pXT,int nCount) const314 inline void XRenderPeer::CompositeTrapezoids( int nOp,
315     Picture aSrc, Picture aDst, const XRenderPictFormat* pXRPF,
316     int nXSrc, int nYSrc, const XTrapezoid* pXT, int nCount ) const
317 {
318 #ifdef XRENDER_LINK
319     XRenderCompositeTrapezoids( mpDisplay, nOp, aSrc, aDst, pXRPF,
320         nXSrc, nYSrc, pXT, nCount );
321 #else
322     (*mpXRenderCompositeTrapezoids)( mpDisplay, nOp, aSrc, aDst, pXRPF,
323         nXSrc, nYSrc, pXT, nCount );
324 #endif
325 }
326 
AddTraps(Picture aDst,int nXOfs,int nYOfs,const _XTrap * pTraps,int nCount) const327 inline bool XRenderPeer::AddTraps( Picture aDst, int nXOfs, int nYOfs,
328     const _XTrap* pTraps, int nCount ) const
329 {
330 #ifdef XRENDER_LINK
331     XRenderAddTraps( mpDisplay, aDst, nXOfs, nYOfs, pTraps, nCount );
332 #else
333     if( !mpXRenderAddTraps )
334         return false;
335     (*mpXRenderAddTraps)( mpDisplay, aDst, nXOfs, nYOfs, pTraps, nCount );
336 #endif
337     return true;
338 }
339 
340 //=====================================================================
341 
ScopedPic(XRenderPeer & rPeer,Picture & rPic)342 inline ScopedPic::ScopedPic( XRenderPeer& rPeer, Picture& rPic )
343 :   mrRenderPeer( rPeer)
344 ,   maPicture( rPic )
345 {}
346 
~ScopedPic()347 inline ScopedPic::~ScopedPic()
348 {
349     if( maPicture )
350         mrRenderPeer.FreePicture( maPicture );
351 }
352 
Get()353 inline Picture& ScopedPic::Get()
354 {
355     return maPicture;
356 }
357 
358 //=====================================================================
359 
GetXRenderColor(const SalColor & rSalColor,double fTransparency=0.0)360 inline XRenderColor GetXRenderColor( const SalColor& rSalColor, double fTransparency = 0.0 )
361 {
362 	XRenderColor aRetVal;
363 	// convert the SalColor
364 	aRetVal.red   = SALCOLOR_RED(   rSalColor ); aRetVal.red   |= (aRetVal.red   << 8);
365 	aRetVal.green = SALCOLOR_GREEN( rSalColor ); aRetVal.green |= (aRetVal.green << 8);
366 	aRetVal.blue  = SALCOLOR_BLUE(  rSalColor ); aRetVal.blue  |= (aRetVal.blue  << 8);
367 
368 	// handle transparency
369 	aRetVal.alpha = 0xFFFF; // default to opaque
370 	if( fTransparency != 0 )
371 	{
372 		const double fAlpha = 1.0 - fTransparency;
373 		aRetVal.alpha = static_cast<sal_uInt16>(fAlpha * 0xFFFF + 0.5);
374 		// xrender wants pre-multiplied colors
375 		aRetVal.red   = static_cast<sal_uInt16>(fAlpha * aRetVal.red + 0.5);
376 		aRetVal.green = static_cast<sal_uInt16>(fAlpha * aRetVal.green + 0.5);
377 		aRetVal.blue  = static_cast<sal_uInt16>(fAlpha * aRetVal.blue + 0.5);
378 	}
379 
380 	return aRetVal;
381 }
382 
383 //=====================================================================
384 
385 #endif // _SV_XRENDER_PEER_HXX
386