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