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 10c82f2877SAndrew Rist * 11c82f2877SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12c82f2877SAndrew Rist * 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. 19c82f2877SAndrew Rist * 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 "tools/debug.hxx" 28cdf0e10cSrcweir 29cdf0e10cSrcweir #include "basegfx/polygon/b2dpolygon.hxx" 30cdf0e10cSrcweir #include "basegfx/polygon/b2dpolypolygon.hxx" 31cdf0e10cSrcweir #include "basegfx/polygon/b2dpolypolygontools.hxx" 32cdf0e10cSrcweir #include "basegfx/polygon/b2dpolygontools.hxx" 33cdf0e10cSrcweir #include "basegfx/polygon/b2dpolygonclipper.hxx" 34cdf0e10cSrcweir #include "basegfx/polygon/b2dlinegeometry.hxx" 35cdf0e10cSrcweir #include "basegfx/matrix/b2dhommatrix.hxx" 36cdf0e10cSrcweir #include "basegfx/matrix/b2dhommatrixtools.hxx" 37cdf0e10cSrcweir #include "basegfx/polygon/b2dpolypolygoncutter.hxx" 38cdf0e10cSrcweir #include "basegfx/polygon/b2dtrapezoid.hxx" 39cdf0e10cSrcweir 40cdf0e10cSrcweir #include "vcl/jobdata.hxx" 41cdf0e10cSrcweir 42cdf0e10cSrcweir #include "unx/Xproto.h" 43cdf0e10cSrcweir #include "unx/salunx.h" 44cdf0e10cSrcweir #include "unx/saldata.hxx" 45cdf0e10cSrcweir #include "unx/saldisp.hxx" 46cdf0e10cSrcweir #include "unx/salgdi.h" 47cdf0e10cSrcweir #include "unx/salframe.h" 48cdf0e10cSrcweir #include "unx/salvd.h" 49cdf0e10cSrcweir 50cdf0e10cSrcweir #include "printergfx.hxx" 51cdf0e10cSrcweir #include "xrender_peer.hxx" 52cdf0e10cSrcweir 53cdf0e10cSrcweir #include <vector> 54cdf0e10cSrcweir #include <queue> 55cdf0e10cSrcweir #include <set> 56cdf0e10cSrcweir 57cdf0e10cSrcweir // -=-= SalPolyLine =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 58cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 59cdf0e10cSrcweir #define STATIC_POINTS 64 60cdf0e10cSrcweir 61cdf0e10cSrcweir class SalPolyLine 62cdf0e10cSrcweir { 63cdf0e10cSrcweir XPoint Points_[STATIC_POINTS]; 64cdf0e10cSrcweir XPoint *pFirst_; 65cdf0e10cSrcweir public: 66cdf0e10cSrcweir inline SalPolyLine( sal_uLong nPoints ); 67cdf0e10cSrcweir inline SalPolyLine( sal_uLong nPoints, const SalPoint *p ); 68cdf0e10cSrcweir inline ~SalPolyLine(); 69cdf0e10cSrcweir inline XPoint &operator [] ( sal_uLong n ) const 70cdf0e10cSrcweir { return pFirst_[n]; } 71cdf0e10cSrcweir }; 72cdf0e10cSrcweir 73cdf0e10cSrcweir inline SalPolyLine::SalPolyLine( sal_uLong nPoints ) 74cdf0e10cSrcweir : pFirst_( nPoints+1 > STATIC_POINTS ? new XPoint[nPoints+1] : Points_ ) 75cdf0e10cSrcweir {} 76cdf0e10cSrcweir 77cdf0e10cSrcweir inline SalPolyLine::SalPolyLine( sal_uLong nPoints, const SalPoint *p ) 78cdf0e10cSrcweir : pFirst_( nPoints+1 > STATIC_POINTS ? new XPoint[nPoints+1] : Points_ ) 79cdf0e10cSrcweir { 80cdf0e10cSrcweir for( sal_uLong i = 0; i < nPoints; i++ ) 81cdf0e10cSrcweir { 82cdf0e10cSrcweir pFirst_[i].x = (short)p[i].mnX; 83cdf0e10cSrcweir pFirst_[i].y = (short)p[i].mnY; 84cdf0e10cSrcweir } 85cdf0e10cSrcweir pFirst_[nPoints] = pFirst_[0]; // close polyline 86cdf0e10cSrcweir } 87cdf0e10cSrcweir 88cdf0e10cSrcweir inline SalPolyLine::~SalPolyLine() 89cdf0e10cSrcweir { if( pFirst_ != Points_ ) delete [] pFirst_; } 90cdf0e10cSrcweir 91cdf0e10cSrcweir #undef STATIC_POINTS 92cdf0e10cSrcweir // -=-= X11SalGraphics =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 93cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 94cdf0e10cSrcweir X11SalGraphics::X11SalGraphics() 95cdf0e10cSrcweir { 96cdf0e10cSrcweir m_pFrame = NULL; 97cdf0e10cSrcweir m_pVDev = NULL; 98cdf0e10cSrcweir m_pDeleteColormap = NULL; 99cdf0e10cSrcweir hDrawable_ = None; 100cdf0e10cSrcweir m_aRenderPicture = 0; 101cdf0e10cSrcweir m_pRenderFormat = NULL; 102cdf0e10cSrcweir 103cdf0e10cSrcweir mpClipRegion = NULL; 104cdf0e10cSrcweir pPaintRegion_ = NULL; 105cdf0e10cSrcweir 106cdf0e10cSrcweir pPenGC_ = NULL; 107cdf0e10cSrcweir nPenPixel_ = 0; 108cdf0e10cSrcweir nPenColor_ = MAKE_SALCOLOR( 0x00, 0x00, 0x00 ); // Black 109cdf0e10cSrcweir 110cdf0e10cSrcweir pFontGC_ = NULL; 111cdf0e10cSrcweir for( int i = 0; i < MAX_FALLBACK; ++i ) 112cdf0e10cSrcweir mpServerFont[i] = NULL; 113cdf0e10cSrcweir 114cdf0e10cSrcweir nTextPixel_ = 0; 115cdf0e10cSrcweir nTextColor_ = MAKE_SALCOLOR( 0x00, 0x00, 0x00 ); // Black 116cdf0e10cSrcweir 117cdf0e10cSrcweir #ifdef ENABLE_GRAPHITE 118cdf0e10cSrcweir // check if graphite fonts have been disabled 119cdf0e10cSrcweir static const char* pDisableGraphiteStr = getenv( "SAL_DISABLE_GRAPHITE" ); 120cdf0e10cSrcweir bDisableGraphite_ = pDisableGraphiteStr ? (pDisableGraphiteStr[0]!='0') : sal_False; 121cdf0e10cSrcweir #endif 122cdf0e10cSrcweir 123cdf0e10cSrcweir pBrushGC_ = NULL; 124cdf0e10cSrcweir nBrushPixel_ = 0; 125cdf0e10cSrcweir nBrushColor_ = MAKE_SALCOLOR( 0xFF, 0xFF, 0xFF ); // White 126cdf0e10cSrcweir hBrush_ = None; 127cdf0e10cSrcweir 128cdf0e10cSrcweir pMonoGC_ = NULL; 129cdf0e10cSrcweir pCopyGC_ = NULL; 130cdf0e10cSrcweir pMaskGC_ = NULL; 131cdf0e10cSrcweir pInvertGC_ = NULL; 132cdf0e10cSrcweir pInvert50GC_ = NULL; 133cdf0e10cSrcweir pStippleGC_ = NULL; 134cdf0e10cSrcweir pTrackingGC_ = NULL; 135cdf0e10cSrcweir 136cdf0e10cSrcweir bWindow_ = sal_False; 137cdf0e10cSrcweir bPrinter_ = sal_False; 138cdf0e10cSrcweir bVirDev_ = sal_False; 139cdf0e10cSrcweir bPenGC_ = sal_False; 140cdf0e10cSrcweir bFontGC_ = sal_False; 141cdf0e10cSrcweir bBrushGC_ = sal_False; 142cdf0e10cSrcweir bMonoGC_ = sal_False; 143cdf0e10cSrcweir bCopyGC_ = sal_False; 144cdf0e10cSrcweir bInvertGC_ = sal_False; 145cdf0e10cSrcweir bInvert50GC_ = sal_False; 146cdf0e10cSrcweir bStippleGC_ = sal_False; 147cdf0e10cSrcweir bTrackingGC_ = sal_False; 148cdf0e10cSrcweir bXORMode_ = sal_False; 149cdf0e10cSrcweir bDitherBrush_ = sal_False; 150cdf0e10cSrcweir } 151cdf0e10cSrcweir 152cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 153cdf0e10cSrcweir X11SalGraphics::~X11SalGraphics() 154cdf0e10cSrcweir { 155cdf0e10cSrcweir ReleaseFonts(); 156cdf0e10cSrcweir freeResources(); 157cdf0e10cSrcweir } 158cdf0e10cSrcweir 159cdf0e10cSrcweir // -=-= SalGraphics / X11SalGraphics =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 160cdf0e10cSrcweir 161cdf0e10cSrcweir void X11SalGraphics::freeResources() 162cdf0e10cSrcweir { 163cdf0e10cSrcweir Display *pDisplay = GetXDisplay(); 164cdf0e10cSrcweir 165cdf0e10cSrcweir DBG_ASSERT( !pPaintRegion_, "pPaintRegion_" ); 166cdf0e10cSrcweir if( mpClipRegion ) XDestroyRegion( mpClipRegion ), mpClipRegion = None; 167cdf0e10cSrcweir 168cdf0e10cSrcweir if( hBrush_ ) XFreePixmap( pDisplay, hBrush_ ), hBrush_ = None; 169cdf0e10cSrcweir if( pPenGC_ ) XFreeGC( pDisplay, pPenGC_ ), pPenGC_ = None; 170cdf0e10cSrcweir if( pFontGC_ ) XFreeGC( pDisplay, pFontGC_ ), pFontGC_ = None; 171cdf0e10cSrcweir if( pBrushGC_ ) XFreeGC( pDisplay, pBrushGC_ ), pBrushGC_ = None; 172cdf0e10cSrcweir if( pMonoGC_ ) XFreeGC( pDisplay, pMonoGC_ ), pMonoGC_ = None; 173cdf0e10cSrcweir if( pCopyGC_ ) XFreeGC( pDisplay, pCopyGC_ ), pCopyGC_ = None; 174cdf0e10cSrcweir if( pMaskGC_ ) XFreeGC( pDisplay, pMaskGC_ ), pMaskGC_ = None; 175cdf0e10cSrcweir if( pInvertGC_ ) XFreeGC( pDisplay, pInvertGC_ ), pInvertGC_ = None; 176cdf0e10cSrcweir if( pInvert50GC_ ) XFreeGC( pDisplay, pInvert50GC_ ), pInvert50GC_ = None; 177cdf0e10cSrcweir if( pStippleGC_ ) XFreeGC( pDisplay, pStippleGC_ ), pStippleGC_ = None; 178cdf0e10cSrcweir if( pTrackingGC_ ) XFreeGC( pDisplay, pTrackingGC_ ), pTrackingGC_ = None; 179cdf0e10cSrcweir if( m_pDeleteColormap ) 180cdf0e10cSrcweir delete m_pDeleteColormap, m_pColormap = m_pDeleteColormap = NULL; 181cdf0e10cSrcweir 182cdf0e10cSrcweir if( m_aRenderPicture ) 183cdf0e10cSrcweir XRenderPeer::GetInstance().FreePicture( m_aRenderPicture ), m_aRenderPicture = 0; 184cdf0e10cSrcweir 185cdf0e10cSrcweir bPenGC_ = bFontGC_ = bBrushGC_ = bMonoGC_ = bCopyGC_ = bInvertGC_ = bInvert50GC_ = bStippleGC_ = bTrackingGC_ = false; 186cdf0e10cSrcweir } 187cdf0e10cSrcweir 188cdf0e10cSrcweir void X11SalGraphics::SetDrawable( Drawable aDrawable, int nScreen ) 189cdf0e10cSrcweir { 190cdf0e10cSrcweir // shortcut if nothing changed 191cdf0e10cSrcweir if( hDrawable_ == aDrawable ) 192cdf0e10cSrcweir return; 193cdf0e10cSrcweir 194cdf0e10cSrcweir // free screen specific resources if needed 195cdf0e10cSrcweir if( nScreen != m_nScreen ) 196cdf0e10cSrcweir { 197cdf0e10cSrcweir freeResources(); 198cdf0e10cSrcweir m_pColormap = &GetX11SalData()->GetDisplay()->GetColormap( nScreen ); 199cdf0e10cSrcweir m_nScreen = nScreen; 200cdf0e10cSrcweir } 201cdf0e10cSrcweir 202cdf0e10cSrcweir hDrawable_ = aDrawable; 203cdf0e10cSrcweir SetXRenderFormat( NULL ); 204cdf0e10cSrcweir if( m_aRenderPicture ) 205cdf0e10cSrcweir { 206cdf0e10cSrcweir XRenderPeer::GetInstance().FreePicture( m_aRenderPicture ); 207cdf0e10cSrcweir m_aRenderPicture = 0; 208cdf0e10cSrcweir } 209cdf0e10cSrcweir 210cdf0e10cSrcweir if( hDrawable_ ) 211cdf0e10cSrcweir { 212cdf0e10cSrcweir nPenPixel_ = GetPixel( nPenColor_ ); 213cdf0e10cSrcweir nTextPixel_ = GetPixel( nTextColor_ ); 214cdf0e10cSrcweir nBrushPixel_ = GetPixel( nBrushColor_ ); 215cdf0e10cSrcweir } 216cdf0e10cSrcweir } 217cdf0e10cSrcweir 218cdf0e10cSrcweir void X11SalGraphics::Init( SalFrame *pFrame, Drawable aTarget, int nScreen ) 219cdf0e10cSrcweir { 220cdf0e10cSrcweir #if 0 // TODO: use SetDrawable() instead 221cdf0e10cSrcweir m_pColormap = &GetX11SalData()->GetDisplay()->GetColormap(nScreen); 222cdf0e10cSrcweir hDrawable_ = aTarget; 223cdf0e10cSrcweir m_nScreen = nScreen; 224cdf0e10cSrcweir SetXRenderFormat( NULL ); 225cdf0e10cSrcweir if( m_aRenderPicture ) 226cdf0e10cSrcweir XRenderPeer::GetInstance().FreePicture( m_aRenderPicture ), m_aRenderPicture = 0; 227cdf0e10cSrcweir 228cdf0e10cSrcweir nPenPixel_ = GetPixel( nPenColor_ ); 229cdf0e10cSrcweir nTextPixel_ = GetPixel( nTextColor_ ); 230cdf0e10cSrcweir nBrushPixel_ = GetPixel( nBrushColor_ ); 231cdf0e10cSrcweir #else 232cdf0e10cSrcweir m_pColormap = &GetX11SalData()->GetDisplay()->GetColormap(nScreen); 233cdf0e10cSrcweir m_nScreen = nScreen; 234cdf0e10cSrcweir SetDrawable( aTarget, nScreen ); 235cdf0e10cSrcweir #endif 236cdf0e10cSrcweir 237cdf0e10cSrcweir bWindow_ = sal_True; 238cdf0e10cSrcweir m_pFrame = pFrame; 239cdf0e10cSrcweir m_pVDev = NULL; 240cdf0e10cSrcweir } 241cdf0e10cSrcweir 242cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 243cdf0e10cSrcweir void X11SalGraphics::DeInit() 244cdf0e10cSrcweir { 245cdf0e10cSrcweir SetDrawable( None, m_nScreen ); 246cdf0e10cSrcweir } 247cdf0e10cSrcweir 248cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 249cdf0e10cSrcweir void X11SalGraphics::SetClipRegion( GC pGC, XLIB_Region pXReg ) const 250cdf0e10cSrcweir { 251cdf0e10cSrcweir Display *pDisplay = GetXDisplay(); 252cdf0e10cSrcweir 253cdf0e10cSrcweir int n = 0; 254cdf0e10cSrcweir XLIB_Region Regions[3]; 255cdf0e10cSrcweir 256cdf0e10cSrcweir if( mpClipRegion /* && !XEmptyRegion( mpClipRegion ) */ ) 257cdf0e10cSrcweir Regions[n++] = mpClipRegion; 258cdf0e10cSrcweir // if( pPaintRegion_ /* && !XEmptyRegion( pPaintRegion_ ) */ ) 259cdf0e10cSrcweir // Regions[n++] = pPaintRegion_; 260cdf0e10cSrcweir 261cdf0e10cSrcweir if( pXReg && !XEmptyRegion( pXReg ) ) 262cdf0e10cSrcweir Regions[n++] = pXReg; 263cdf0e10cSrcweir 264cdf0e10cSrcweir if( 0 == n ) 265cdf0e10cSrcweir XSetClipMask( pDisplay, pGC, None ); 266cdf0e10cSrcweir else if( 1 == n ) 267cdf0e10cSrcweir XSetRegion( pDisplay, pGC, Regions[0] ); 268cdf0e10cSrcweir else 269cdf0e10cSrcweir { 270cdf0e10cSrcweir XLIB_Region pTmpRegion = XCreateRegion(); 271cdf0e10cSrcweir XIntersectRegion( Regions[0], Regions[1], pTmpRegion ); 272cdf0e10cSrcweir // if( 3 == n ) 273cdf0e10cSrcweir // XIntersectRegion( Regions[2], pTmpRegion, pTmpRegion ); 274cdf0e10cSrcweir XSetRegion( pDisplay, pGC, pTmpRegion ); 275cdf0e10cSrcweir XDestroyRegion( pTmpRegion ); 276cdf0e10cSrcweir } 277cdf0e10cSrcweir } 278cdf0e10cSrcweir 279cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 280cdf0e10cSrcweir GC X11SalGraphics::SelectPen() 281cdf0e10cSrcweir { 282cdf0e10cSrcweir Display *pDisplay = GetXDisplay(); 283cdf0e10cSrcweir 284cdf0e10cSrcweir if( !pPenGC_ ) 285cdf0e10cSrcweir { 286cdf0e10cSrcweir XGCValues values; 287cdf0e10cSrcweir values.subwindow_mode = ClipByChildren; 288cdf0e10cSrcweir values.fill_rule = EvenOddRule; // Pict import/ Gradient 289cdf0e10cSrcweir values.graphics_exposures = False; 290cdf0e10cSrcweir 291cdf0e10cSrcweir pPenGC_ = XCreateGC( pDisplay, hDrawable_, 292cdf0e10cSrcweir GCSubwindowMode | GCFillRule | GCGraphicsExposures, 293cdf0e10cSrcweir &values ); 294cdf0e10cSrcweir } 295cdf0e10cSrcweir 296cdf0e10cSrcweir if( !bPenGC_ ) 297cdf0e10cSrcweir { 298cdf0e10cSrcweir if( nPenColor_ != SALCOLOR_NONE ) 299cdf0e10cSrcweir XSetForeground( pDisplay, pPenGC_, nPenPixel_ ); 300cdf0e10cSrcweir XSetFunction ( pDisplay, pPenGC_, bXORMode_ ? GXxor : GXcopy ); 301cdf0e10cSrcweir SetClipRegion( pPenGC_ ); 302cdf0e10cSrcweir bPenGC_ = sal_True; 303cdf0e10cSrcweir } 304cdf0e10cSrcweir 305cdf0e10cSrcweir return pPenGC_; 306cdf0e10cSrcweir } 307cdf0e10cSrcweir 308cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 309cdf0e10cSrcweir GC X11SalGraphics::SelectBrush() 310cdf0e10cSrcweir { 311cdf0e10cSrcweir Display *pDisplay = GetXDisplay(); 312cdf0e10cSrcweir 313cdf0e10cSrcweir DBG_ASSERT( nBrushColor_ != SALCOLOR_NONE, "Brush Transparent" ); 314cdf0e10cSrcweir 315cdf0e10cSrcweir if( !pBrushGC_ ) 316cdf0e10cSrcweir { 317cdf0e10cSrcweir XGCValues values; 318cdf0e10cSrcweir // values.subwindow_mode = IncludeInferiors; 319cdf0e10cSrcweir values.subwindow_mode = ClipByChildren; 320cdf0e10cSrcweir values.fill_rule = EvenOddRule; // Pict import/ Gradient 321cdf0e10cSrcweir values.graphics_exposures = False; 322cdf0e10cSrcweir 323cdf0e10cSrcweir pBrushGC_ = XCreateGC( pDisplay, hDrawable_, 324cdf0e10cSrcweir GCSubwindowMode | GCFillRule | GCGraphicsExposures, 325cdf0e10cSrcweir &values ); 326cdf0e10cSrcweir } 327cdf0e10cSrcweir 328cdf0e10cSrcweir if( !bBrushGC_ ) 329cdf0e10cSrcweir { 330cdf0e10cSrcweir if( !bDitherBrush_ ) 331cdf0e10cSrcweir { 332cdf0e10cSrcweir XSetFillStyle ( pDisplay, pBrushGC_, FillSolid ); 333cdf0e10cSrcweir XSetForeground( pDisplay, pBrushGC_, nBrushPixel_ ); 334cdf0e10cSrcweir if( bPrinter_ ) 335cdf0e10cSrcweir XSetTile( pDisplay, pBrushGC_, None ); 336cdf0e10cSrcweir } 337cdf0e10cSrcweir else 338cdf0e10cSrcweir { 339cdf0e10cSrcweir // Bug in Sun Solaris 2.5.1, XFillPolygon doesn't allways reflect 340cdf0e10cSrcweir // changes of the tile. PROPERTY_BUG_Tile doesn't fix this ! 341cdf0e10cSrcweir if (GetDisplay()->GetProperties() & PROPERTY_BUG_FillPolygon_Tile) 342cdf0e10cSrcweir XSetFillStyle ( pDisplay, pBrushGC_, FillSolid ); 343cdf0e10cSrcweir 344cdf0e10cSrcweir XSetFillStyle ( pDisplay, pBrushGC_, FillTiled ); 345cdf0e10cSrcweir XSetTile ( pDisplay, pBrushGC_, hBrush_ ); 346cdf0e10cSrcweir } 347cdf0e10cSrcweir XSetFunction ( pDisplay, pBrushGC_, bXORMode_ ? GXxor : GXcopy ); 348cdf0e10cSrcweir SetClipRegion( pBrushGC_ ); 349cdf0e10cSrcweir 350cdf0e10cSrcweir bBrushGC_ = sal_True; 351cdf0e10cSrcweir } 352cdf0e10cSrcweir 353cdf0e10cSrcweir return pBrushGC_; 354cdf0e10cSrcweir } 355cdf0e10cSrcweir 356cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 357cdf0e10cSrcweir GC X11SalGraphics::GetTrackingGC() 358cdf0e10cSrcweir { 359cdf0e10cSrcweir const char dash_list[2] = {2, 2}; 360cdf0e10cSrcweir 361cdf0e10cSrcweir if( !pTrackingGC_ ) 362cdf0e10cSrcweir { 363cdf0e10cSrcweir XGCValues values; 364cdf0e10cSrcweir 365cdf0e10cSrcweir values.graphics_exposures = False; 366cdf0e10cSrcweir values.foreground = m_pColormap->GetBlackPixel() 367cdf0e10cSrcweir ^ m_pColormap->GetWhitePixel(); 368cdf0e10cSrcweir values.function = GXxor; 369cdf0e10cSrcweir values.line_width = 1; 370cdf0e10cSrcweir values.line_style = LineOnOffDash; 371cdf0e10cSrcweir 372cdf0e10cSrcweir pTrackingGC_ = XCreateGC( GetXDisplay(), GetDrawable(), 373cdf0e10cSrcweir GCGraphicsExposures | GCForeground | GCFunction 374cdf0e10cSrcweir | GCLineWidth | GCLineStyle, 375cdf0e10cSrcweir &values ); 376cdf0e10cSrcweir XSetDashes( GetXDisplay(), pTrackingGC_, 0, dash_list, 2 ); 377cdf0e10cSrcweir } 378cdf0e10cSrcweir 379cdf0e10cSrcweir if( !bTrackingGC_ ) 380cdf0e10cSrcweir { 381cdf0e10cSrcweir SetClipRegion( pTrackingGC_ ); 382cdf0e10cSrcweir bTrackingGC_ = sal_True; 383cdf0e10cSrcweir } 384cdf0e10cSrcweir 385cdf0e10cSrcweir return pTrackingGC_; 386cdf0e10cSrcweir } 387cdf0e10cSrcweir 388cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 389cdf0e10cSrcweir void X11SalGraphics::DrawLines( sal_uLong nPoints, 390cdf0e10cSrcweir const SalPolyLine &rPoints, 391cdf0e10cSrcweir GC pGC, 392cdf0e10cSrcweir bool bClose 393cdf0e10cSrcweir ) 394cdf0e10cSrcweir { 395cdf0e10cSrcweir // errechne wie viele Linien XWindow auf einmal zeichnen kann 396cdf0e10cSrcweir sal_uLong nMaxLines = (GetDisplay()->GetMaxRequestSize() - sizeof(xPolyPointReq)) 397cdf0e10cSrcweir / sizeof(xPoint); 398cdf0e10cSrcweir if( nMaxLines > nPoints ) nMaxLines = nPoints; 399cdf0e10cSrcweir 400cdf0e10cSrcweir // gebe alle Linien aus, die XWindows zeichnen kann. 401cdf0e10cSrcweir sal_uLong n; 402cdf0e10cSrcweir for( n = 0; nPoints - n > nMaxLines; n += nMaxLines - 1 ) 403cdf0e10cSrcweir XDrawLines( GetXDisplay(), 404cdf0e10cSrcweir GetDrawable(), 405cdf0e10cSrcweir pGC, 406cdf0e10cSrcweir &rPoints[n], 407cdf0e10cSrcweir nMaxLines, 408cdf0e10cSrcweir CoordModeOrigin ); 409cdf0e10cSrcweir 410cdf0e10cSrcweir if( n < nPoints ) 411cdf0e10cSrcweir XDrawLines( GetXDisplay(), 412cdf0e10cSrcweir GetDrawable(), 413cdf0e10cSrcweir pGC, 414cdf0e10cSrcweir &rPoints[n], 415cdf0e10cSrcweir nPoints - n, 416cdf0e10cSrcweir CoordModeOrigin ); 417cdf0e10cSrcweir if( bClose ) 418cdf0e10cSrcweir { 419cdf0e10cSrcweir if( rPoints[nPoints-1].x != rPoints[0].x || rPoints[nPoints-1].y != rPoints[0].y ) 420cdf0e10cSrcweir drawLine( rPoints[nPoints-1].x, rPoints[nPoints-1].y, rPoints[0].x, rPoints[0].y ); 421cdf0e10cSrcweir } 422cdf0e10cSrcweir } 423cdf0e10cSrcweir 424cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 425cdf0e10cSrcweir // Dithern: Calculate a dither-pixmap and make a brush of it 426cdf0e10cSrcweir #define P_DELTA 51 427cdf0e10cSrcweir #define DMAP( v, m ) ((v % P_DELTA) > m ? (v / P_DELTA) + 1 : (v / P_DELTA)) 428cdf0e10cSrcweir 429cdf0e10cSrcweir BOOL X11SalGraphics::GetDitherPixmap( SalColor nSalColor ) 430cdf0e10cSrcweir { 431cdf0e10cSrcweir static const short nOrdDither8Bit[ 8 ][ 8 ] = 432cdf0e10cSrcweir { 433cdf0e10cSrcweir { 0, 38, 9, 48, 2, 40, 12, 50}, 434cdf0e10cSrcweir {25, 12, 35, 22, 28, 15, 37, 24}, 435cdf0e10cSrcweir { 6, 44, 3, 41, 8, 47, 5, 44}, 436cdf0e10cSrcweir {32, 19, 28, 16, 34, 21, 31, 18}, 437cdf0e10cSrcweir { 1, 40, 11, 49, 0, 39, 10, 48}, 438cdf0e10cSrcweir {27, 14, 36, 24, 26, 13, 36, 23}, 439cdf0e10cSrcweir { 8, 46, 4, 43, 7, 45, 4, 42}, 440cdf0e10cSrcweir {33, 20, 30, 17, 32, 20, 29, 16} 441cdf0e10cSrcweir }; 442cdf0e10cSrcweir 443cdf0e10cSrcweir // test for correct depth (8bit) 444cdf0e10cSrcweir if( GetColormap().GetVisual().GetDepth() != 8 ) 445cdf0e10cSrcweir return sal_False; 446cdf0e10cSrcweir 447cdf0e10cSrcweir char pBits[64]; 448cdf0e10cSrcweir char *pBitsPtr = pBits; 449cdf0e10cSrcweir 450cdf0e10cSrcweir // Set the pallette-entries for the dithering tile 451cdf0e10cSrcweir sal_uInt8 nSalColorRed = SALCOLOR_RED ( nSalColor ); 452cdf0e10cSrcweir sal_uInt8 nSalColorGreen = SALCOLOR_GREEN ( nSalColor ); 453cdf0e10cSrcweir sal_uInt8 nSalColorBlue = SALCOLOR_BLUE ( nSalColor ); 454cdf0e10cSrcweir 455cdf0e10cSrcweir for( int nY = 0; nY < 8; nY++ ) 456cdf0e10cSrcweir { 457cdf0e10cSrcweir for( int nX = 0; nX < 8; nX++ ) 458cdf0e10cSrcweir { 459cdf0e10cSrcweir short nMagic = nOrdDither8Bit[nY][nX]; 460cdf0e10cSrcweir sal_uInt8 nR = P_DELTA * DMAP( nSalColorRed, nMagic ); 461cdf0e10cSrcweir sal_uInt8 nG = P_DELTA * DMAP( nSalColorGreen, nMagic ); 462cdf0e10cSrcweir sal_uInt8 nB = P_DELTA * DMAP( nSalColorBlue, nMagic ); 463cdf0e10cSrcweir 464cdf0e10cSrcweir *pBitsPtr++ = GetColormap().GetPixel( MAKE_SALCOLOR( nR, nG, nB ) ); 465cdf0e10cSrcweir } 466cdf0e10cSrcweir } 467cdf0e10cSrcweir 468cdf0e10cSrcweir // create the tile as ximage and an according pixmap -> caching 469cdf0e10cSrcweir XImage *pImage = XCreateImage( GetXDisplay(), 470cdf0e10cSrcweir GetColormap().GetXVisual(), 471cdf0e10cSrcweir 8, 472cdf0e10cSrcweir ZPixmap, 473cdf0e10cSrcweir 0, // offset 474cdf0e10cSrcweir pBits, // data 475cdf0e10cSrcweir 8, 8, // width & height 476cdf0e10cSrcweir 8, // bitmap_pad 477cdf0e10cSrcweir 0 ); // (default) bytes_per_line 478cdf0e10cSrcweir 479cdf0e10cSrcweir if ( GetDisplay()->GetProperties() & PROPERTY_BUG_Tile ) 480cdf0e10cSrcweir { 481cdf0e10cSrcweir if (hBrush_) 482cdf0e10cSrcweir XFreePixmap (GetXDisplay(), hBrush_); 483cdf0e10cSrcweir hBrush_ = XCreatePixmap( GetXDisplay(), GetDrawable(), 8, 8, 8 ); 484cdf0e10cSrcweir } 485cdf0e10cSrcweir else 486cdf0e10cSrcweir if( !hBrush_ ) 487cdf0e10cSrcweir hBrush_ = XCreatePixmap( GetXDisplay(), GetDrawable(), 8, 8, 8 ); 488cdf0e10cSrcweir 489cdf0e10cSrcweir // put the ximage to the pixmap 490cdf0e10cSrcweir XPutImage( GetXDisplay(), 491cdf0e10cSrcweir hBrush_, 492cdf0e10cSrcweir GetDisplay()->GetCopyGC( m_nScreen ), 493cdf0e10cSrcweir pImage, 494cdf0e10cSrcweir 0, 0, // Source 495cdf0e10cSrcweir 0, 0, // Destination 496cdf0e10cSrcweir 8, 8 ); // width & height 497cdf0e10cSrcweir 498cdf0e10cSrcweir // destroy image-frame but not palette-data 499cdf0e10cSrcweir pImage->data = NULL; 500cdf0e10cSrcweir XDestroyImage( pImage ); 501cdf0e10cSrcweir 502cdf0e10cSrcweir return sal_True; 503cdf0e10cSrcweir } 504cdf0e10cSrcweir 505cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 506cdf0e10cSrcweir void X11SalGraphics::GetResolution( sal_Int32 &rDPIX, sal_Int32 &rDPIY ) // const 507cdf0e10cSrcweir { 508cdf0e10cSrcweir const SalDisplay *pDisplay = GetDisplay(); 509cdf0e10cSrcweir 510cdf0e10cSrcweir rDPIX = pDisplay->GetResolution().A(); 511cdf0e10cSrcweir rDPIY = pDisplay->GetResolution().B(); 512cdf0e10cSrcweir if( !pDisplay->GetExactResolution() && rDPIY < 96 ) 513cdf0e10cSrcweir { 514cdf0e10cSrcweir rDPIX = Divide( rDPIX * 96, rDPIY ); 515cdf0e10cSrcweir rDPIY = 96; 516cdf0e10cSrcweir } 517cdf0e10cSrcweir else if ( rDPIY > 200 ) 518cdf0e10cSrcweir { 519cdf0e10cSrcweir rDPIX = Divide( rDPIX * 200, rDPIY ); 520cdf0e10cSrcweir rDPIY = 200; 521cdf0e10cSrcweir } 522cdf0e10cSrcweir 523cdf0e10cSrcweir // #i12705# equalize x- and y-resolution if they are close enough 524cdf0e10cSrcweir if( rDPIX != rDPIY ) 525cdf0e10cSrcweir { 526cdf0e10cSrcweir // different x- and y- resolutions are usually artifacts of 527cdf0e10cSrcweir // a wrongly calculated screen size. 528cdf0e10cSrcweir //if( (13*rDPIX >= 10*rDPIY) && (13*rDPIY >= 10*rDPIX) ) //+-30% 529cdf0e10cSrcweir { 530cdf0e10cSrcweir #ifdef DEBUG 531cdf0e10cSrcweir printf("Forcing Resolution from %" SAL_PRIdINT32 "x%" SAL_PRIdINT32 " to %" SAL_PRIdINT32 "x%" SAL_PRIdINT32 "\n", 532cdf0e10cSrcweir rDPIX,rDPIY,rDPIY,rDPIY); 533cdf0e10cSrcweir #endif 534cdf0e10cSrcweir rDPIX = rDPIY; // y-resolution is more trustworthy 535cdf0e10cSrcweir } 536cdf0e10cSrcweir } 537cdf0e10cSrcweir } 538cdf0e10cSrcweir 539cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 540cdf0e10cSrcweir sal_uInt16 X11SalGraphics::GetBitCount() // const 541cdf0e10cSrcweir { 542cdf0e10cSrcweir return GetVisual().GetDepth(); 543cdf0e10cSrcweir } 544cdf0e10cSrcweir 545cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 546cdf0e10cSrcweir long X11SalGraphics::GetGraphicsWidth() const 547cdf0e10cSrcweir { 548cdf0e10cSrcweir if( m_pFrame ) 549cdf0e10cSrcweir return m_pFrame->maGeometry.nWidth; 550cdf0e10cSrcweir else if( m_pVDev ) 551cdf0e10cSrcweir return m_pVDev->GetWidth(); 552cdf0e10cSrcweir else 553cdf0e10cSrcweir return 0; 554cdf0e10cSrcweir } 555cdf0e10cSrcweir 556cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 557cdf0e10cSrcweir long X11SalGraphics::GetGraphicsHeight() const 558cdf0e10cSrcweir { 559cdf0e10cSrcweir if( m_pFrame ) 560cdf0e10cSrcweir return m_pFrame->maGeometry.nHeight; 561cdf0e10cSrcweir else if( m_pVDev ) 562cdf0e10cSrcweir return m_pVDev->GetHeight(); 563cdf0e10cSrcweir else 564cdf0e10cSrcweir return 0; 565cdf0e10cSrcweir } 566cdf0e10cSrcweir 567cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 568cdf0e10cSrcweir void X11SalGraphics::ResetClipRegion() 569cdf0e10cSrcweir { 570cdf0e10cSrcweir if( mpClipRegion ) 571cdf0e10cSrcweir { 572cdf0e10cSrcweir bPenGC_ = sal_False; 573cdf0e10cSrcweir bFontGC_ = sal_False; 574cdf0e10cSrcweir bBrushGC_ = sal_False; 575cdf0e10cSrcweir bMonoGC_ = sal_False; 576cdf0e10cSrcweir bCopyGC_ = sal_False; 577cdf0e10cSrcweir bInvertGC_ = sal_False; 578cdf0e10cSrcweir bInvert50GC_ = sal_False; 579cdf0e10cSrcweir bStippleGC_ = sal_False; 580cdf0e10cSrcweir bTrackingGC_ = sal_False; 581cdf0e10cSrcweir 582cdf0e10cSrcweir XDestroyRegion( mpClipRegion ); 583cdf0e10cSrcweir mpClipRegion = NULL; 584cdf0e10cSrcweir } 585cdf0e10cSrcweir } 586cdf0e10cSrcweir 587cdf0e10cSrcweir bool X11SalGraphics::setClipRegion( const Region& i_rClip ) 588cdf0e10cSrcweir { 589cdf0e10cSrcweir if( mpClipRegion ) 590cdf0e10cSrcweir XDestroyRegion( mpClipRegion ); 591cdf0e10cSrcweir mpClipRegion = XCreateRegion(); 592*e6f63103SArmin Le Grand 593*e6f63103SArmin Le Grand RectangleVector aRectangles; 594*e6f63103SArmin Le Grand i_rClip.GetRegionRectangles(aRectangles); 595*e6f63103SArmin Le Grand 596*e6f63103SArmin Le Grand for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++) 597cdf0e10cSrcweir { 598*e6f63103SArmin Le Grand const long nW(aRectIter->GetWidth()); 599*e6f63103SArmin Le Grand 600*e6f63103SArmin Le Grand if(nW) 601cdf0e10cSrcweir { 602*e6f63103SArmin Le Grand const long nH(aRectIter->GetHeight()); 603*e6f63103SArmin Le Grand 604*e6f63103SArmin Le Grand if(nH) 605*e6f63103SArmin Le Grand { 606*e6f63103SArmin Le Grand XRectangle aRect; 607*e6f63103SArmin Le Grand 608*e6f63103SArmin Le Grand aRect.x = (short)aRectIter->Left(); 609*e6f63103SArmin Le Grand aRect.y = (short)aRectIter->Top(); 610*e6f63103SArmin Le Grand aRect.width = (unsigned short)nW; 611*e6f63103SArmin Le Grand aRect.height = (unsigned short)nH; 612*e6f63103SArmin Le Grand XUnionRectWithRegion(&aRect, mpClipRegion, mpClipRegion); 613*e6f63103SArmin Le Grand } 614cdf0e10cSrcweir } 615cdf0e10cSrcweir } 616cdf0e10cSrcweir 617*e6f63103SArmin Le Grand //ImplRegionInfo aInfo; 618*e6f63103SArmin Le Grand //long nX, nY, nW, nH; 619*e6f63103SArmin Le Grand //bool bRegionRect = i_rClip.ImplGetFirstRect(aInfo, nX, nY, nW, nH ); 620*e6f63103SArmin Le Grand //while( bRegionRect ) 621*e6f63103SArmin Le Grand //{ 622*e6f63103SArmin Le Grand // if ( nW && nH ) 623*e6f63103SArmin Le Grand // { 624*e6f63103SArmin Le Grand // XRectangle aRect; 625*e6f63103SArmin Le Grand // aRect.x = (short)nX; 626*e6f63103SArmin Le Grand // aRect.y = (short)nY; 627*e6f63103SArmin Le Grand // aRect.width = (unsigned short)nW; 628*e6f63103SArmin Le Grand // aRect.height = (unsigned short)nH; 629*e6f63103SArmin Le Grand // 630*e6f63103SArmin Le Grand // XUnionRectWithRegion( &aRect, mpClipRegion, mpClipRegion ); 631*e6f63103SArmin Le Grand // } 632*e6f63103SArmin Le Grand // bRegionRect = i_rClip.ImplGetNextRect( aInfo, nX, nY, nW, nH ); 633*e6f63103SArmin Le Grand //} 634*e6f63103SArmin Le Grand 635cdf0e10cSrcweir // done, invalidate GCs 636cdf0e10cSrcweir bPenGC_ = sal_False; 637cdf0e10cSrcweir bFontGC_ = sal_False; 638cdf0e10cSrcweir bBrushGC_ = sal_False; 639cdf0e10cSrcweir bMonoGC_ = sal_False; 640cdf0e10cSrcweir bCopyGC_ = sal_False; 641cdf0e10cSrcweir bInvertGC_ = sal_False; 642cdf0e10cSrcweir bInvert50GC_ = sal_False; 643cdf0e10cSrcweir bStippleGC_ = sal_False; 644cdf0e10cSrcweir bTrackingGC_ = sal_False; 645cdf0e10cSrcweir 646cdf0e10cSrcweir if( XEmptyRegion( mpClipRegion ) ) 647cdf0e10cSrcweir { 648cdf0e10cSrcweir XDestroyRegion( mpClipRegion ); 649cdf0e10cSrcweir mpClipRegion= NULL; 650cdf0e10cSrcweir } 651cdf0e10cSrcweir return true; 652cdf0e10cSrcweir } 653cdf0e10cSrcweir 654cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 655cdf0e10cSrcweir void X11SalGraphics::SetLineColor() 656cdf0e10cSrcweir { 657cdf0e10cSrcweir if( nPenColor_ != SALCOLOR_NONE ) 658cdf0e10cSrcweir { 659cdf0e10cSrcweir nPenColor_ = SALCOLOR_NONE; 660cdf0e10cSrcweir bPenGC_ = sal_False; 661cdf0e10cSrcweir } 662cdf0e10cSrcweir } 663cdf0e10cSrcweir 664cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 665cdf0e10cSrcweir void X11SalGraphics::SetLineColor( SalColor nSalColor ) 666cdf0e10cSrcweir { 667cdf0e10cSrcweir if( nPenColor_ != nSalColor ) 668cdf0e10cSrcweir { 669cdf0e10cSrcweir nPenColor_ = nSalColor; 670cdf0e10cSrcweir nPenPixel_ = GetPixel( nSalColor ); 671cdf0e10cSrcweir bPenGC_ = sal_False; 672cdf0e10cSrcweir } 673cdf0e10cSrcweir } 674cdf0e10cSrcweir 675cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 676cdf0e10cSrcweir void X11SalGraphics::SetFillColor() 677cdf0e10cSrcweir { 678cdf0e10cSrcweir if( nBrushColor_ != SALCOLOR_NONE ) 679cdf0e10cSrcweir { 680cdf0e10cSrcweir bDitherBrush_ = sal_False; 681cdf0e10cSrcweir nBrushColor_ = SALCOLOR_NONE; 682cdf0e10cSrcweir bBrushGC_ = sal_False; 683cdf0e10cSrcweir } 684cdf0e10cSrcweir } 685cdf0e10cSrcweir 686cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 687cdf0e10cSrcweir void X11SalGraphics::SetFillColor( SalColor nSalColor ) 688cdf0e10cSrcweir { 689cdf0e10cSrcweir if( nBrushColor_ != nSalColor ) 690cdf0e10cSrcweir { 691cdf0e10cSrcweir bDitherBrush_ = sal_False; 692cdf0e10cSrcweir nBrushColor_ = nSalColor; 693cdf0e10cSrcweir nBrushPixel_ = GetPixel( nSalColor ); 694cdf0e10cSrcweir if( TrueColor != GetColormap().GetVisual().GetClass() 695cdf0e10cSrcweir && GetColormap().GetColor( nBrushPixel_ ) != nBrushColor_ 696cdf0e10cSrcweir && nSalColor != MAKE_SALCOLOR( 0x00, 0x00, 0x00 ) // black 697cdf0e10cSrcweir && nSalColor != MAKE_SALCOLOR( 0x00, 0x00, 0x80 ) // blue 698cdf0e10cSrcweir && nSalColor != MAKE_SALCOLOR( 0x00, 0x80, 0x00 ) // green 699cdf0e10cSrcweir && nSalColor != MAKE_SALCOLOR( 0x00, 0x80, 0x80 ) // cyan 700cdf0e10cSrcweir && nSalColor != MAKE_SALCOLOR( 0x80, 0x00, 0x00 ) // red 701cdf0e10cSrcweir && nSalColor != MAKE_SALCOLOR( 0x80, 0x00, 0x80 ) // magenta 702cdf0e10cSrcweir && nSalColor != MAKE_SALCOLOR( 0x80, 0x80, 0x00 ) // brown 703cdf0e10cSrcweir && nSalColor != MAKE_SALCOLOR( 0x80, 0x80, 0x80 ) // gray 704cdf0e10cSrcweir && nSalColor != MAKE_SALCOLOR( 0xC0, 0xC0, 0xC0 ) // light gray 705cdf0e10cSrcweir && nSalColor != MAKE_SALCOLOR( 0x00, 0x00, 0xFF ) // light blue 706cdf0e10cSrcweir && nSalColor != MAKE_SALCOLOR( 0x00, 0xFF, 0x00 ) // light green 707cdf0e10cSrcweir && nSalColor != MAKE_SALCOLOR( 0x00, 0xFF, 0xFF ) // light cyan 708cdf0e10cSrcweir && nSalColor != MAKE_SALCOLOR( 0xFF, 0x00, 0x00 ) // light red 709cdf0e10cSrcweir && nSalColor != MAKE_SALCOLOR( 0xFF, 0x00, 0xFF ) // light magenta 710cdf0e10cSrcweir && nSalColor != MAKE_SALCOLOR( 0xFF, 0xFF, 0x00 ) // light brown 711cdf0e10cSrcweir && nSalColor != MAKE_SALCOLOR( 0xFF, 0xFF, 0xFF ) ) 712cdf0e10cSrcweir bDitherBrush_ = GetDitherPixmap(nSalColor); 713cdf0e10cSrcweir bBrushGC_ = sal_False; 714cdf0e10cSrcweir } 715cdf0e10cSrcweir } 716cdf0e10cSrcweir 717cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 718cdf0e10cSrcweir void X11SalGraphics::SetROPLineColor( SalROPColor nROPColor ) 719cdf0e10cSrcweir { 720cdf0e10cSrcweir switch( nROPColor ) 721cdf0e10cSrcweir { 722cdf0e10cSrcweir case SAL_ROP_0 : // 0 723cdf0e10cSrcweir nPenPixel_ = (Pixel)0; 724cdf0e10cSrcweir break; 725cdf0e10cSrcweir case SAL_ROP_1 : // 1 726cdf0e10cSrcweir nPenPixel_ = (Pixel)(1 << GetVisual().GetDepth()) - 1; 727cdf0e10cSrcweir break; 728cdf0e10cSrcweir case SAL_ROP_INVERT : // 2 729cdf0e10cSrcweir nPenPixel_ = (Pixel)(1 << GetVisual().GetDepth()) - 1; 730cdf0e10cSrcweir break; 731cdf0e10cSrcweir } 732cdf0e10cSrcweir nPenColor_ = GetColormap().GetColor( nPenPixel_ ); 733cdf0e10cSrcweir bPenGC_ = sal_False; 734cdf0e10cSrcweir } 735cdf0e10cSrcweir 736cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 737cdf0e10cSrcweir void X11SalGraphics::SetROPFillColor( SalROPColor nROPColor ) 738cdf0e10cSrcweir { 739cdf0e10cSrcweir switch( nROPColor ) 740cdf0e10cSrcweir { 741cdf0e10cSrcweir case SAL_ROP_0 : // 0 742cdf0e10cSrcweir nBrushPixel_ = (Pixel)0; 743cdf0e10cSrcweir break; 744cdf0e10cSrcweir case SAL_ROP_1 : // 1 745cdf0e10cSrcweir nBrushPixel_ = (Pixel)(1 << GetVisual().GetDepth()) - 1; 746cdf0e10cSrcweir break; 747cdf0e10cSrcweir case SAL_ROP_INVERT : // 2 748cdf0e10cSrcweir nBrushPixel_ = (Pixel)(1 << GetVisual().GetDepth()) - 1; 749cdf0e10cSrcweir break; 750cdf0e10cSrcweir } 751cdf0e10cSrcweir bDitherBrush_ = sal_False; 752cdf0e10cSrcweir nBrushColor_ = GetColormap().GetColor( nBrushPixel_ ); 753cdf0e10cSrcweir bBrushGC_ = sal_False; 754cdf0e10cSrcweir } 755cdf0e10cSrcweir 756cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 757cdf0e10cSrcweir void X11SalGraphics::SetXORMode( bool bSet, bool ) 758cdf0e10cSrcweir { 759cdf0e10cSrcweir if( !bXORMode_ == bSet ) 760cdf0e10cSrcweir { 761cdf0e10cSrcweir bXORMode_ = bSet; 762cdf0e10cSrcweir bPenGC_ = sal_False; 763cdf0e10cSrcweir bFontGC_ = sal_False; 764cdf0e10cSrcweir bBrushGC_ = sal_False; 765cdf0e10cSrcweir bMonoGC_ = sal_False; 766cdf0e10cSrcweir bCopyGC_ = sal_False; 767cdf0e10cSrcweir bInvertGC_ = sal_False; 768cdf0e10cSrcweir bInvert50GC_ = sal_False; 769cdf0e10cSrcweir bStippleGC_ = sal_False; 770cdf0e10cSrcweir bTrackingGC_ = sal_False; 771cdf0e10cSrcweir } 772cdf0e10cSrcweir } 773cdf0e10cSrcweir 774cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 775cdf0e10cSrcweir void X11SalGraphics::drawPixel( long nX, long nY ) 776cdf0e10cSrcweir { 777cdf0e10cSrcweir if( nPenColor_ != SALCOLOR_NONE ) 778cdf0e10cSrcweir XDrawPoint( GetXDisplay(), GetDrawable(), SelectPen(), nX, nY ); 779cdf0e10cSrcweir } 780cdf0e10cSrcweir 781cdf0e10cSrcweir void X11SalGraphics::drawPixel( long nX, long nY, SalColor nSalColor ) 782cdf0e10cSrcweir { 783cdf0e10cSrcweir if( nSalColor != SALCOLOR_NONE ) 784cdf0e10cSrcweir { 785cdf0e10cSrcweir Display *pDisplay = GetXDisplay(); 786cdf0e10cSrcweir 787cdf0e10cSrcweir if( (nPenColor_ == SALCOLOR_NONE) && !bPenGC_ ) 788cdf0e10cSrcweir { 789cdf0e10cSrcweir SetLineColor( nSalColor ); 790cdf0e10cSrcweir XDrawPoint( pDisplay, GetDrawable(), SelectPen(), nX, nY ); 791cdf0e10cSrcweir nPenColor_ = SALCOLOR_NONE; 792cdf0e10cSrcweir bPenGC_ = False; 793cdf0e10cSrcweir } 794cdf0e10cSrcweir else 795cdf0e10cSrcweir { 796cdf0e10cSrcweir GC pGC = SelectPen(); 797cdf0e10cSrcweir 798cdf0e10cSrcweir if( nSalColor != nPenColor_ ) 799cdf0e10cSrcweir XSetForeground( pDisplay, pGC, GetPixel( nSalColor ) ); 800cdf0e10cSrcweir 801cdf0e10cSrcweir XDrawPoint( pDisplay, GetDrawable(), pGC, nX, nY ); 802cdf0e10cSrcweir 803cdf0e10cSrcweir if( nSalColor != nPenColor_ ) 804cdf0e10cSrcweir XSetForeground( pDisplay, pGC, nPenPixel_ ); 805cdf0e10cSrcweir } 806cdf0e10cSrcweir } 807cdf0e10cSrcweir } 808cdf0e10cSrcweir 809cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 810cdf0e10cSrcweir void X11SalGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 ) 811cdf0e10cSrcweir { 812cdf0e10cSrcweir if( nPenColor_ != SALCOLOR_NONE ) 813cdf0e10cSrcweir { 814cdf0e10cSrcweir if ( GetDisplay()->GetProperties() & PROPERTY_BUG_DrawLine ) 815cdf0e10cSrcweir { 816cdf0e10cSrcweir GC aGC = SelectPen(); 817cdf0e10cSrcweir XDrawPoint (GetXDisplay(), GetDrawable(), aGC, (int)nX1, (int)nY1); 818cdf0e10cSrcweir XDrawPoint (GetXDisplay(), GetDrawable(), aGC, (int)nX2, (int)nY2); 819cdf0e10cSrcweir XDrawLine (GetXDisplay(), GetDrawable(), aGC, nX1, nY1, nX2, nY2 ); 820cdf0e10cSrcweir } 821cdf0e10cSrcweir else 822cdf0e10cSrcweir XDrawLine( GetXDisplay(), GetDrawable(),SelectPen(), 823cdf0e10cSrcweir nX1, nY1, nX2, nY2 ); 824cdf0e10cSrcweir } 825cdf0e10cSrcweir } 826cdf0e10cSrcweir 827cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 828cdf0e10cSrcweir void X11SalGraphics::drawRect( long nX, long nY, long nDX, long nDY ) 829cdf0e10cSrcweir { 830cdf0e10cSrcweir if( nBrushColor_ != SALCOLOR_NONE ) 831cdf0e10cSrcweir { 832cdf0e10cSrcweir XFillRectangle( GetXDisplay(), 833cdf0e10cSrcweir GetDrawable(), 834cdf0e10cSrcweir SelectBrush(), 835cdf0e10cSrcweir nX, nY, nDX, nDY ); 836cdf0e10cSrcweir } 837cdf0e10cSrcweir // Beschreibung DrawRect verkehrt, deshalb -1 838cdf0e10cSrcweir if( nPenColor_ != SALCOLOR_NONE ) 839cdf0e10cSrcweir XDrawRectangle( GetXDisplay(), 840cdf0e10cSrcweir GetDrawable(), 841cdf0e10cSrcweir SelectPen(), 842cdf0e10cSrcweir nX, nY, nDX-1, nDY-1 ); 843cdf0e10cSrcweir } 844cdf0e10cSrcweir 845cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 846cdf0e10cSrcweir void X11SalGraphics::drawPolyLine( sal_uLong nPoints, const SalPoint *pPtAry ) 847cdf0e10cSrcweir { 848cdf0e10cSrcweir drawPolyLine( nPoints, pPtAry, false ); 849cdf0e10cSrcweir } 850cdf0e10cSrcweir 851cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 852cdf0e10cSrcweir void X11SalGraphics::drawPolyLine( sal_uLong nPoints, const SalPoint *pPtAry, bool bClose ) 853cdf0e10cSrcweir { 8540d3f51feSHerbert Dürr if( nPenColor_ != SALCOLOR_NONE) 855cdf0e10cSrcweir { 856cdf0e10cSrcweir SalPolyLine Points( nPoints, pPtAry ); 857cdf0e10cSrcweir 858cdf0e10cSrcweir DrawLines( nPoints, Points, SelectPen(), bClose ); 859cdf0e10cSrcweir } 860cdf0e10cSrcweir } 861cdf0e10cSrcweir 862cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 863cdf0e10cSrcweir void X11SalGraphics::drawPolygon( sal_uLong nPoints, const SalPoint* pPtAry ) 864cdf0e10cSrcweir { 865cdf0e10cSrcweir if( nPoints == 0 ) 866cdf0e10cSrcweir return; 867cdf0e10cSrcweir 868cdf0e10cSrcweir if( nPoints < 3 ) 869cdf0e10cSrcweir { 870cdf0e10cSrcweir if( !bXORMode_ ) 871cdf0e10cSrcweir { 872cdf0e10cSrcweir if( 1 == nPoints ) 873cdf0e10cSrcweir drawPixel( pPtAry[0].mnX, pPtAry[0].mnY ); 874cdf0e10cSrcweir else 875cdf0e10cSrcweir drawLine( pPtAry[0].mnX, pPtAry[0].mnY, 876cdf0e10cSrcweir pPtAry[1].mnX, pPtAry[1].mnY ); 877cdf0e10cSrcweir } 878cdf0e10cSrcweir return; 879cdf0e10cSrcweir } 880cdf0e10cSrcweir 881cdf0e10cSrcweir SalPolyLine Points( nPoints, pPtAry ); 882cdf0e10cSrcweir 883cdf0e10cSrcweir nPoints++; 884cdf0e10cSrcweir 885cdf0e10cSrcweir /* WORKAROUND: some Xservers (Xorg, VIA chipset in this case) 886cdf0e10cSrcweir * do not draw the visible part of a polygon 887cdf0e10cSrcweir * if it overlaps to the left of screen 0,y. 888cdf0e10cSrcweir * This happens to be the case in the gradient drawn in the 889cdf0e10cSrcweir * menubar background. workaround for the special case of 890cdf0e10cSrcweir * of a rectangle overlapping to the left. 891cdf0e10cSrcweir */ 892cdf0e10cSrcweir if( nPoints == 5 && 893cdf0e10cSrcweir Points[ 0 ].x == Points[ 1 ].x && 894cdf0e10cSrcweir Points[ 1 ].y == Points[ 2 ].y && 895cdf0e10cSrcweir Points[ 2 ].x == Points[ 3 ].x && 896cdf0e10cSrcweir Points[ 0 ].x == Points[ 4 ].x && Points[ 0 ].y == Points[ 4 ].y 897cdf0e10cSrcweir ) 898cdf0e10cSrcweir { 899cdf0e10cSrcweir bool bLeft = false; 900cdf0e10cSrcweir bool bRight = false; 901cdf0e10cSrcweir for(unsigned int i = 0; i < nPoints; i++ ) 902cdf0e10cSrcweir { 903cdf0e10cSrcweir if( Points[i].x < 0 ) 904cdf0e10cSrcweir bLeft = true; 905cdf0e10cSrcweir else 906cdf0e10cSrcweir bRight= true; 907cdf0e10cSrcweir } 908cdf0e10cSrcweir if( bLeft && ! bRight ) 909cdf0e10cSrcweir return; 910cdf0e10cSrcweir if( bLeft && bRight ) 911cdf0e10cSrcweir { 912cdf0e10cSrcweir for( unsigned int i = 0; i < nPoints; i++ ) 913cdf0e10cSrcweir if( Points[i].x < 0 ) 914cdf0e10cSrcweir Points[i].x = 0; 915cdf0e10cSrcweir } 916cdf0e10cSrcweir } 917cdf0e10cSrcweir 918cdf0e10cSrcweir if( nBrushColor_ != SALCOLOR_NONE ) 919cdf0e10cSrcweir XFillPolygon( GetXDisplay(), 920cdf0e10cSrcweir GetDrawable(), 921cdf0e10cSrcweir SelectBrush(), 922cdf0e10cSrcweir &Points[0], nPoints, 923cdf0e10cSrcweir Complex, CoordModeOrigin ); 924cdf0e10cSrcweir 9250d3f51feSHerbert Dürr if( nPenColor_ != SALCOLOR_NONE) 926cdf0e10cSrcweir DrawLines( nPoints, Points, SelectPen(), true ); 927cdf0e10cSrcweir } 928cdf0e10cSrcweir 929cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 930cdf0e10cSrcweir void X11SalGraphics::drawPolyPolygon( sal_uInt32 nPoly, 931cdf0e10cSrcweir const sal_uInt32 *pPoints, 932cdf0e10cSrcweir PCONSTSALPOINT *pPtAry ) 933cdf0e10cSrcweir { 934cdf0e10cSrcweir if( nBrushColor_ != SALCOLOR_NONE ) 935cdf0e10cSrcweir { 936cdf0e10cSrcweir sal_uInt32 i, n; 937cdf0e10cSrcweir XLIB_Region pXRegA = NULL; 938cdf0e10cSrcweir 939cdf0e10cSrcweir for( i = 0; i < nPoly; i++ ) { 940cdf0e10cSrcweir n = pPoints[i]; 941cdf0e10cSrcweir SalPolyLine Points( n, pPtAry[i] ); 942cdf0e10cSrcweir if( n > 2 ) 943cdf0e10cSrcweir { 944cdf0e10cSrcweir XLIB_Region pXRegB = XPolygonRegion( &Points[0], n+1, WindingRule ); 945cdf0e10cSrcweir if( !pXRegA ) 946cdf0e10cSrcweir pXRegA = pXRegB; 947cdf0e10cSrcweir else 948cdf0e10cSrcweir { 949cdf0e10cSrcweir XXorRegion( pXRegA, pXRegB, pXRegA ); 950cdf0e10cSrcweir XDestroyRegion( pXRegB ); 951cdf0e10cSrcweir } 952cdf0e10cSrcweir } 953cdf0e10cSrcweir } 954cdf0e10cSrcweir 955cdf0e10cSrcweir if( pXRegA ) 956cdf0e10cSrcweir { 957cdf0e10cSrcweir XRectangle aXRect; 958cdf0e10cSrcweir XClipBox( pXRegA, &aXRect ); 959cdf0e10cSrcweir 960cdf0e10cSrcweir GC pGC = SelectBrush(); 961cdf0e10cSrcweir SetClipRegion( pGC, pXRegA ); // ??? doppelt 962cdf0e10cSrcweir XDestroyRegion( pXRegA ); 963cdf0e10cSrcweir bBrushGC_ = sal_False; 964cdf0e10cSrcweir 965cdf0e10cSrcweir XFillRectangle( GetXDisplay(), 966cdf0e10cSrcweir GetDrawable(), 967cdf0e10cSrcweir pGC, 968cdf0e10cSrcweir aXRect.x, aXRect.y, aXRect.width, aXRect.height ); 969cdf0e10cSrcweir } 970cdf0e10cSrcweir } 971cdf0e10cSrcweir 972cdf0e10cSrcweir if( nPenColor_ != SALCOLOR_NONE ) 973cdf0e10cSrcweir for( sal_uInt32 i = 0; i < nPoly; i++ ) 974cdf0e10cSrcweir drawPolyLine( pPoints[i], pPtAry[i], true ); 975cdf0e10cSrcweir } 976cdf0e10cSrcweir 977cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 978cdf0e10cSrcweir 979cdf0e10cSrcweir sal_Bool X11SalGraphics::drawPolyLineBezier( sal_uLong, const SalPoint*, const BYTE* ) 980cdf0e10cSrcweir { 981cdf0e10cSrcweir return sal_False; 982cdf0e10cSrcweir } 983cdf0e10cSrcweir 984cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 985cdf0e10cSrcweir 986cdf0e10cSrcweir sal_Bool X11SalGraphics::drawPolygonBezier( sal_uLong, const SalPoint*, const BYTE* ) 987cdf0e10cSrcweir { 988cdf0e10cSrcweir return sal_False; 989cdf0e10cSrcweir } 990cdf0e10cSrcweir 991cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 992cdf0e10cSrcweir 993cdf0e10cSrcweir sal_Bool X11SalGraphics::drawPolyPolygonBezier( sal_uInt32, const sal_uInt32*, 994cdf0e10cSrcweir const SalPoint* const*, const BYTE* const* ) 995cdf0e10cSrcweir { 996cdf0e10cSrcweir return sal_False; 997cdf0e10cSrcweir } 998cdf0e10cSrcweir 999cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 1000cdf0e10cSrcweir 1001cdf0e10cSrcweir void X11SalGraphics::invert( sal_uLong nPoints, 1002cdf0e10cSrcweir const SalPoint* pPtAry, 1003cdf0e10cSrcweir SalInvert nFlags ) 1004cdf0e10cSrcweir { 1005cdf0e10cSrcweir SalPolyLine Points ( nPoints, pPtAry ); 1006cdf0e10cSrcweir 1007cdf0e10cSrcweir GC pGC; 1008cdf0e10cSrcweir if( SAL_INVERT_50 & nFlags ) 1009cdf0e10cSrcweir pGC = GetInvert50GC(); 1010cdf0e10cSrcweir else 1011cdf0e10cSrcweir if ( SAL_INVERT_TRACKFRAME & nFlags ) 1012cdf0e10cSrcweir pGC = GetTrackingGC(); 1013cdf0e10cSrcweir else 1014cdf0e10cSrcweir pGC = GetInvertGC(); 1015cdf0e10cSrcweir 1016cdf0e10cSrcweir if( SAL_INVERT_TRACKFRAME & nFlags ) 1017cdf0e10cSrcweir DrawLines ( nPoints, Points, pGC, true ); 1018cdf0e10cSrcweir else 1019cdf0e10cSrcweir XFillPolygon( GetXDisplay(), 1020cdf0e10cSrcweir GetDrawable(), 1021cdf0e10cSrcweir pGC, 1022cdf0e10cSrcweir &Points[0], nPoints, 1023cdf0e10cSrcweir Complex, CoordModeOrigin ); 1024cdf0e10cSrcweir } 1025cdf0e10cSrcweir 1026cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 1027cdf0e10cSrcweir 1028cdf0e10cSrcweir BOOL X11SalGraphics::drawEPS( long,long,long,long,void*,sal_uLong ) 1029cdf0e10cSrcweir { 1030cdf0e10cSrcweir return sal_False; 1031cdf0e10cSrcweir } 1032cdf0e10cSrcweir 1033cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 1034cdf0e10cSrcweir 1035cdf0e10cSrcweir XID X11SalGraphics::GetXRenderPicture() 1036cdf0e10cSrcweir { 1037cdf0e10cSrcweir XRenderPeer& rRenderPeer = XRenderPeer::GetInstance(); 1038cdf0e10cSrcweir 1039cdf0e10cSrcweir if( !m_aRenderPicture ) 1040cdf0e10cSrcweir { 1041cdf0e10cSrcweir // check xrender support for matching visual 1042cdf0e10cSrcweir // find a XRenderPictFormat compatible with the Drawable 1043cdf0e10cSrcweir XRenderPictFormat* pVisualFormat = static_cast<XRenderPictFormat*>(GetXRenderFormat()); 1044cdf0e10cSrcweir if( !pVisualFormat ) 1045cdf0e10cSrcweir { 1046cdf0e10cSrcweir Visual* pVisual = GetDisplay()->GetVisual( m_nScreen ).GetVisual(); 1047cdf0e10cSrcweir pVisualFormat = rRenderPeer.FindVisualFormat( pVisual ); 1048cdf0e10cSrcweir if( !pVisualFormat ) 1049cdf0e10cSrcweir return 0; 1050cdf0e10cSrcweir // cache the XRenderPictFormat 1051cdf0e10cSrcweir SetXRenderFormat( static_cast<void*>(pVisualFormat) ); 1052cdf0e10cSrcweir } 1053cdf0e10cSrcweir 1054cdf0e10cSrcweir // get the matching xrender target for drawable 1055cdf0e10cSrcweir m_aRenderPicture = rRenderPeer.CreatePicture( hDrawable_, pVisualFormat, 0, NULL ); 1056cdf0e10cSrcweir } 1057cdf0e10cSrcweir 1058cdf0e10cSrcweir #if 0 1059cdf0e10cSrcweir // setup clipping so the callers don't have to do it themselves 1060cdf0e10cSrcweir // TODO: avoid clipping if already set correctly 1061cdf0e10cSrcweir if( mpClipRegion && !XEmptyRegion( mpClipRegion ) ) 1062cdf0e10cSrcweir rRenderPeer.SetPictureClipRegion( aDstPic, mpClipRegion ); 1063cdf0e10cSrcweir else 1064cdf0e10cSrcweir #endif 1065cdf0e10cSrcweir { 1066cdf0e10cSrcweir // reset clip region 1067cdf0e10cSrcweir // TODO: avoid clip reset if already done 1068cdf0e10cSrcweir XRenderPictureAttributes aAttr; 1069cdf0e10cSrcweir aAttr.clip_mask = None; 1070cdf0e10cSrcweir rRenderPeer.ChangePicture( m_aRenderPicture, CPClipMask, &aAttr ); 1071cdf0e10cSrcweir } 1072cdf0e10cSrcweir 1073cdf0e10cSrcweir return m_aRenderPicture; 1074cdf0e10cSrcweir } 1075cdf0e10cSrcweir 1076cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 1077cdf0e10cSrcweir 1078cdf0e10cSrcweir SystemGraphicsData X11SalGraphics::GetGraphicsData() const 1079cdf0e10cSrcweir { 1080cdf0e10cSrcweir SystemGraphicsData aRes; 1081cdf0e10cSrcweir 1082cdf0e10cSrcweir aRes.nSize = sizeof(aRes); 1083cdf0e10cSrcweir aRes.pDisplay = GetXDisplay(); 1084cdf0e10cSrcweir aRes.hDrawable = hDrawable_; 1085cdf0e10cSrcweir aRes.pVisual = GetDisplay()->GetVisual( m_nScreen ).GetVisual(); 1086cdf0e10cSrcweir aRes.nScreen = m_nScreen; 1087cdf0e10cSrcweir aRes.nDepth = GetDisplay()->GetVisual( m_nScreen ).GetDepth(); 1088cdf0e10cSrcweir aRes.aColormap = GetDisplay()->GetColormap( m_nScreen ).GetXColormap(); 1089cdf0e10cSrcweir aRes.pRenderFormat = m_pRenderFormat; 1090cdf0e10cSrcweir return aRes; 1091cdf0e10cSrcweir } 1092cdf0e10cSrcweir 1093cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 1094cdf0e10cSrcweir 1095cdf0e10cSrcweir // draw a poly-polygon 1096cdf0e10cSrcweir bool X11SalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rOrigPolyPoly, double fTransparency ) 1097cdf0e10cSrcweir { 1098cdf0e10cSrcweir // nothing to do for empty polypolygons 1099cdf0e10cSrcweir const int nOrigPolyCount = rOrigPolyPoly.count(); 1100cdf0e10cSrcweir if( nOrigPolyCount <= 0 ) 1101cdf0e10cSrcweir return sal_True; 1102cdf0e10cSrcweir 1103cdf0e10cSrcweir // nothing to do if everything is transparent 1104cdf0e10cSrcweir if( (nBrushColor_ == SALCOLOR_NONE) 1105cdf0e10cSrcweir && (nPenColor_ == SALCOLOR_NONE) ) 1106cdf0e10cSrcweir return sal_True; 1107cdf0e10cSrcweir 1108cdf0e10cSrcweir // cannot handle pencolor!=brushcolor yet 1109cdf0e10cSrcweir if( (nPenColor_ != SALCOLOR_NONE) 1110cdf0e10cSrcweir && (nPenColor_ != nBrushColor_) ) 1111cdf0e10cSrcweir return sal_False; 1112cdf0e10cSrcweir 1113cdf0e10cSrcweir // TODO: remove the env-variable when no longer needed 1114cdf0e10cSrcweir static const char* pRenderEnv = getenv( "SAL_DISABLE_RENDER_POLY" ); 1115cdf0e10cSrcweir if( pRenderEnv ) 1116cdf0e10cSrcweir return sal_False; 1117cdf0e10cSrcweir 1118cdf0e10cSrcweir // snap to raster if requested 1119cdf0e10cSrcweir basegfx::B2DPolyPolygon aPolyPoly = rOrigPolyPoly; 1120cdf0e10cSrcweir const bool bSnapToRaster = !getAntiAliasB2DDraw(); 1121cdf0e10cSrcweir if( bSnapToRaster ) 1122cdf0e10cSrcweir aPolyPoly = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges( aPolyPoly ); 1123cdf0e10cSrcweir 1124cdf0e10cSrcweir // don't bother with polygons outside of visible area 1125cdf0e10cSrcweir const basegfx::B2DRange aViewRange( 0, 0, GetGraphicsWidth(), GetGraphicsHeight() ); 1126cdf0e10cSrcweir aPolyPoly = basegfx::tools::clipPolyPolygonOnRange( aPolyPoly, aViewRange, true, false ); 1127cdf0e10cSrcweir if( !aPolyPoly.count() ) 1128cdf0e10cSrcweir return true; 1129cdf0e10cSrcweir 1130cdf0e10cSrcweir // tesselate the polypolygon into trapezoids 1131cdf0e10cSrcweir basegfx::B2DTrapezoidVector aB2DTrapVector; 1132cdf0e10cSrcweir basegfx::tools::trapezoidSubdivide( aB2DTrapVector, aPolyPoly ); 1133cdf0e10cSrcweir const int nTrapCount = aB2DTrapVector.size(); 1134cdf0e10cSrcweir if( !nTrapCount ) 1135cdf0e10cSrcweir return true; 1136cdf0e10cSrcweir const bool bDrawn = drawFilledTrapezoids( &aB2DTrapVector[0], nTrapCount, fTransparency ); 1137cdf0e10cSrcweir return bDrawn; 1138cdf0e10cSrcweir } 1139cdf0e10cSrcweir 1140cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 1141cdf0e10cSrcweir 1142cdf0e10cSrcweir bool X11SalGraphics::drawFilledTrapezoids( const ::basegfx::B2DTrapezoid* pB2DTraps, int nTrapCount, double fTransparency ) 1143cdf0e10cSrcweir { 1144cdf0e10cSrcweir if( nTrapCount <= 0 ) 1145cdf0e10cSrcweir return true; 1146cdf0e10cSrcweir 1147cdf0e10cSrcweir Picture aDstPic = GetXRenderPicture(); 1148cdf0e10cSrcweir // check xrender support for this drawable 1149cdf0e10cSrcweir if( !aDstPic ) 1150cdf0e10cSrcweir return false; 1151cdf0e10cSrcweir 1152cdf0e10cSrcweir // convert the B2DTrapezoids into XRender-Trapezoids 1153cdf0e10cSrcweir typedef std::vector<XTrapezoid> TrapezoidVector; 1154cdf0e10cSrcweir TrapezoidVector aTrapVector( nTrapCount ); 1155cdf0e10cSrcweir const basegfx::B2DTrapezoid* pB2DTrap = pB2DTraps; 1156cdf0e10cSrcweir for( int i = 0; i < nTrapCount; ++pB2DTrap, ++i ) 1157cdf0e10cSrcweir { 1158cdf0e10cSrcweir XTrapezoid& rTrap = aTrapVector[ i ] ; 1159cdf0e10cSrcweir 1160cdf0e10cSrcweir // set y-coordinates 1161cdf0e10cSrcweir const double fY1 = pB2DTrap->getTopY(); 1162cdf0e10cSrcweir rTrap.left.p1.y = rTrap.right.p1.y = rTrap.top = XDoubleToFixed( fY1 ); 1163cdf0e10cSrcweir const double fY2 = pB2DTrap->getBottomY(); 1164cdf0e10cSrcweir rTrap.left.p2.y = rTrap.right.p2.y = rTrap.bottom = XDoubleToFixed( fY2 ); 1165cdf0e10cSrcweir 1166cdf0e10cSrcweir // set x-coordinates 1167cdf0e10cSrcweir const double fXL1 = pB2DTrap->getTopXLeft(); 1168cdf0e10cSrcweir rTrap.left.p1.x = XDoubleToFixed( fXL1 ); 1169cdf0e10cSrcweir const double fXR1 = pB2DTrap->getTopXRight(); 1170cdf0e10cSrcweir rTrap.right.p1.x = XDoubleToFixed( fXR1 ); 1171cdf0e10cSrcweir const double fXL2 = pB2DTrap->getBottomXLeft(); 1172cdf0e10cSrcweir rTrap.left.p2.x = XDoubleToFixed( fXL2 ); 1173cdf0e10cSrcweir const double fXR2 = pB2DTrap->getBottomXRight(); 1174cdf0e10cSrcweir rTrap.right.p2.x = XDoubleToFixed( fXR2 ); 1175cdf0e10cSrcweir } 1176cdf0e10cSrcweir 1177cdf0e10cSrcweir // get xrender Picture for polygon foreground 1178cdf0e10cSrcweir // TODO: cache it like the target picture which uses GetXRenderPicture() 1179cdf0e10cSrcweir XRenderPeer& rRenderPeer = XRenderPeer::GetInstance(); 1180cdf0e10cSrcweir SalDisplay::RenderEntry& rEntry = GetDisplay()->GetRenderEntries( m_nScreen )[ 32 ]; 1181cdf0e10cSrcweir if( !rEntry.m_aPicture ) 1182cdf0e10cSrcweir { 1183cdf0e10cSrcweir Display* pXDisplay = GetXDisplay(); 1184cdf0e10cSrcweir 1185cdf0e10cSrcweir rEntry.m_aPixmap = ::XCreatePixmap( pXDisplay, hDrawable_, 1, 1, 32 ); 1186cdf0e10cSrcweir XRenderPictureAttributes aAttr; 1187cdf0e10cSrcweir aAttr.repeat = true; 1188cdf0e10cSrcweir 1189cdf0e10cSrcweir XRenderPictFormat* pXRPF = rRenderPeer.FindStandardFormat( PictStandardARGB32 ); 1190cdf0e10cSrcweir rEntry.m_aPicture = rRenderPeer.CreatePicture( rEntry.m_aPixmap, pXRPF, CPRepeat, &aAttr ); 1191cdf0e10cSrcweir } 1192cdf0e10cSrcweir 1193cdf0e10cSrcweir // set polygon foreground color and opacity 1194cdf0e10cSrcweir XRenderColor aRenderColor = GetXRenderColor( nBrushColor_ , fTransparency ); 1195cdf0e10cSrcweir rRenderPeer.FillRectangle( PictOpSrc, rEntry.m_aPicture, &aRenderColor, 0, 0, 1, 1 ); 1196cdf0e10cSrcweir 1197cdf0e10cSrcweir // set clipping 1198cdf0e10cSrcweir // TODO: move into GetXRenderPicture? 1199cdf0e10cSrcweir if( mpClipRegion && !XEmptyRegion( mpClipRegion ) ) 1200cdf0e10cSrcweir rRenderPeer.SetPictureClipRegion( aDstPic, mpClipRegion ); 1201cdf0e10cSrcweir 1202cdf0e10cSrcweir // render the trapezoids 1203cdf0e10cSrcweir const XRenderPictFormat* pMaskFormat = rRenderPeer.GetStandardFormatA8(); 1204cdf0e10cSrcweir rRenderPeer.CompositeTrapezoids( PictOpOver, 1205cdf0e10cSrcweir rEntry.m_aPicture, aDstPic, pMaskFormat, 0, 0, &aTrapVector[0], aTrapVector.size() ); 1206cdf0e10cSrcweir 1207cdf0e10cSrcweir return true; 1208cdf0e10cSrcweir } 1209cdf0e10cSrcweir 1210cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 1211cdf0e10cSrcweir 12125aaf853bSArmin Le Grand bool X11SalGraphics::drawPolyLine( 12135aaf853bSArmin Le Grand const ::basegfx::B2DPolygon& rPolygon, 12145aaf853bSArmin Le Grand double fTransparency, 12155aaf853bSArmin Le Grand const ::basegfx::B2DVector& rLineWidth, 12165aaf853bSArmin Le Grand basegfx::B2DLineJoin eLineJoin, 12175aaf853bSArmin Le Grand com::sun::star::drawing::LineCap eLineCap) 1218cdf0e10cSrcweir { 1219cdf0e10cSrcweir const bool bIsHairline = (rLineWidth.getX() == rLineWidth.getY()) && (rLineWidth.getX() <= 1.2); 1220cdf0e10cSrcweir 1221cdf0e10cSrcweir // #i101491# 1222cdf0e10cSrcweir if( !bIsHairline && (rPolygon.count() > 1000) ) 1223cdf0e10cSrcweir { 1224cdf0e10cSrcweir // the used basegfx::tools::createAreaGeometry is simply too 1225cdf0e10cSrcweir // expensive with very big polygons; fallback to caller (who 1226cdf0e10cSrcweir // should use ImplLineConverter normally) 1227cdf0e10cSrcweir // AW: ImplLineConverter had to be removed since it does not even 1228cdf0e10cSrcweir // know LineJoins, so the fallback will now prepare the line geometry 1229cdf0e10cSrcweir // the same way. 1230cdf0e10cSrcweir return false; 1231cdf0e10cSrcweir } 1232cdf0e10cSrcweir 1233cdf0e10cSrcweir // temporarily adjust brush color to pen color 1234cdf0e10cSrcweir // since the line is drawn as an area-polygon 1235cdf0e10cSrcweir const SalColor aKeepBrushColor = nBrushColor_; 1236cdf0e10cSrcweir nBrushColor_ = nPenColor_; 1237cdf0e10cSrcweir 1238cdf0e10cSrcweir // #i11575#desc5#b adjust B2D tesselation result to raster positions 1239cdf0e10cSrcweir basegfx::B2DPolygon aPolygon = rPolygon; 1240cdf0e10cSrcweir const double fHalfWidth = 0.5 * rLineWidth.getX(); 1241cdf0e10cSrcweir aPolygon.transform( basegfx::tools::createTranslateB2DHomMatrix(+fHalfWidth,+fHalfWidth) ); 1242cdf0e10cSrcweir 1243cdf0e10cSrcweir // shortcut for hairline drawing to improve performance 1244cdf0e10cSrcweir bool bDrawnOk = true; 1245cdf0e10cSrcweir if( bIsHairline ) 1246cdf0e10cSrcweir { 1247cdf0e10cSrcweir // hairlines can benefit from a simplified tesselation 1248cdf0e10cSrcweir // e.g. for hairlines the linejoin style can be ignored 1249cdf0e10cSrcweir basegfx::B2DTrapezoidVector aB2DTrapVector; 1250cdf0e10cSrcweir basegfx::tools::createLineTrapezoidFromB2DPolygon( aB2DTrapVector, aPolygon, rLineWidth.getX() ); 1251cdf0e10cSrcweir 1252cdf0e10cSrcweir // draw tesselation result 1253cdf0e10cSrcweir const int nTrapCount = aB2DTrapVector.size(); 1254cdf0e10cSrcweir if( nTrapCount > 0 ) 1255cdf0e10cSrcweir bDrawnOk = drawFilledTrapezoids( &aB2DTrapVector[0], nTrapCount, fTransparency ); 1256cdf0e10cSrcweir 1257cdf0e10cSrcweir // restore the original brush GC 1258cdf0e10cSrcweir nBrushColor_ = aKeepBrushColor; 1259cdf0e10cSrcweir return bDrawnOk; 1260cdf0e10cSrcweir } 1261cdf0e10cSrcweir 1262cdf0e10cSrcweir // get the area polygon for the line polygon 1263cdf0e10cSrcweir if( (rLineWidth.getX() != rLineWidth.getY()) 1264cdf0e10cSrcweir && !basegfx::fTools::equalZero( rLineWidth.getY() ) ) 1265cdf0e10cSrcweir { 1266cdf0e10cSrcweir // prepare for createAreaGeometry() with anisotropic linewidth 1267cdf0e10cSrcweir aPolygon.transform( basegfx::tools::createScaleB2DHomMatrix(1.0, rLineWidth.getX() / rLineWidth.getY())); 1268cdf0e10cSrcweir } 1269cdf0e10cSrcweir 1270cdf0e10cSrcweir // create the area-polygon for the line 12715aaf853bSArmin Le Grand const basegfx::B2DPolyPolygon aAreaPolyPoly( basegfx::tools::createAreaGeometry(aPolygon, fHalfWidth, eLineJoin, eLineCap) ); 1272cdf0e10cSrcweir 1273cdf0e10cSrcweir if( (rLineWidth.getX() != rLineWidth.getY()) 1274cdf0e10cSrcweir && !basegfx::fTools::equalZero( rLineWidth.getX() ) ) 1275cdf0e10cSrcweir { 1276cdf0e10cSrcweir // postprocess createAreaGeometry() for anisotropic linewidth 1277cdf0e10cSrcweir aPolygon.transform(basegfx::tools::createScaleB2DHomMatrix(1.0, rLineWidth.getY() / rLineWidth.getX())); 1278cdf0e10cSrcweir } 1279cdf0e10cSrcweir 1280cdf0e10cSrcweir // draw each area polypolygon component individually 1281cdf0e10cSrcweir // to emulate the polypolygon winding rule "non-zero" 1282cdf0e10cSrcweir const int nPolyCount = aAreaPolyPoly.count(); 1283cdf0e10cSrcweir for( int nPolyIdx = 0; nPolyIdx < nPolyCount; ++nPolyIdx ) 1284cdf0e10cSrcweir { 1285cdf0e10cSrcweir const ::basegfx::B2DPolyPolygon aOnePoly( aAreaPolyPoly.getB2DPolygon( nPolyIdx ) ); 1286cdf0e10cSrcweir bDrawnOk = drawPolyPolygon( aOnePoly, fTransparency ); 1287cdf0e10cSrcweir if( !bDrawnOk ) 1288cdf0e10cSrcweir break; 1289cdf0e10cSrcweir } 1290cdf0e10cSrcweir 1291cdf0e10cSrcweir // restore the original brush GC 1292cdf0e10cSrcweir nBrushColor_ = aKeepBrushColor; 1293cdf0e10cSrcweir return bDrawnOk; 1294cdf0e10cSrcweir } 1295cdf0e10cSrcweir 1296cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 1297cdf0e10cSrcweir 1298