[Libreoffice-commits] core.git: Branch 'feature/opengl-vcl' - 3 commits - vcl/inc vcl/Library_vclplug_gen.mk vcl/unx

Markus Mohrhard markus.mohrhard at collabora.co.uk
Wed Oct 22 08:26:27 PDT 2014


 vcl/Library_vclplug_gen.mk      |    1 
 vcl/inc/salgdiimpl.hxx          |   26 
 vcl/inc/unx/salgdi.h            |   62 -
 vcl/unx/generic/gdi/gdiimpl.cxx | 1779 ++++++++++++++++++++++++++++++++++++++++
 vcl/unx/generic/gdi/gdiimpl.hxx |  262 +++++
 vcl/unx/generic/gdi/salgdi.cxx  |  842 ------------------
 vcl/unx/generic/gdi/salgdi2.cxx |  769 -----------------
 7 files changed, 2127 insertions(+), 1614 deletions(-)

New commits:
commit ad1119c4e978858cb9e4f47a23db587d792669af
Author: Markus Mohrhard <markus.mohrhard at collabora.co.uk>
Date:   Wed Oct 22 17:24:48 2014 +0200

    no need for these methods to be virtual
    
    Change-Id: I23413704b27474f6a59121bb1cbf24ee7484acd2

diff --git a/vcl/unx/generic/gdi/gdiimpl.hxx b/vcl/unx/generic/gdi/gdiimpl.hxx
index 86990f5..254eaa9 100644
--- a/vcl/unx/generic/gdi/gdiimpl.hxx
+++ b/vcl/unx/generic/gdi/gdiimpl.hxx
@@ -84,9 +84,9 @@ private:
                                );
 
     XID GetXRenderPicture();
-    virtual bool drawFilledTrapezoids( const ::basegfx::B2DTrapezoid*, int nTrapCount, double fTransparency );
+    bool drawFilledTrapezoids( const ::basegfx::B2DTrapezoid*, int nTrapCount, double fTransparency );
 
-    virtual long GetGraphicsHeight() const;
+    long GetGraphicsHeight() const;
 
     void drawMaskedBitmap( const SalTwoRect& rPosAry,
                                               const SalBitmap& rSalBitmap,
commit d1da933407de3112fe766c2d05e8b6fd5464b4e2
Author: Markus Mohrhard <markus.mohrhard at collabora.co.uk>
Date:   Wed Oct 22 16:49:24 2014 +0200

    we need to export the SalGraphicsImpl class
    
    Change-Id: I569a1aacdb7a87b0e8045863a8569520bd0df09a

diff --git a/vcl/inc/salgdiimpl.hxx b/vcl/inc/salgdiimpl.hxx
index 7375240..1230d1c 100644
--- a/vcl/inc/salgdiimpl.hxx
+++ b/vcl/inc/salgdiimpl.hxx
@@ -17,6 +17,8 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
+#include <vcl/dllapi.h>
+
 #include <rtl/ustring.hxx>
 
 #include <tools/solar.h>
@@ -30,7 +32,7 @@
 class SalGraphics;
 class SalBitmap;
 
-class SalGraphicsImpl
+class VCL_PLUGIN_PUBLIC SalGraphicsImpl
 {
 public:
 
commit 492768e3a4e9d497d4b6784ab59f239301542eea
Author: Markus Mohrhard <markus.mohrhard at collabora.co.uk>
Date:   Tue Oct 21 15:15:47 2014 +0200

    use Impl for unix vcl plugins
    
    Change-Id: I110df787e1d4b817ab6e682fd9bf50a24332fafd

diff --git a/vcl/Library_vclplug_gen.mk b/vcl/Library_vclplug_gen.mk
index c3f00aa..634fa74 100644
--- a/vcl/Library_vclplug_gen.mk
+++ b/vcl/Library_vclplug_gen.mk
@@ -84,6 +84,7 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_gen,\
     vcl/unx/generic/dtrans/X11_service \
     vcl/unx/generic/dtrans/X11_transferable \
     vcl/unx/generic/gdi/gcach_xpeer \
+	vcl/unx/generic/gdi/gdiimpl \
     vcl/unx/generic/gdi/salbmp \
     vcl/unx/generic/gdi/salgdi2 \
     vcl/unx/generic/gdi/salgdi3 \
diff --git a/vcl/inc/salgdiimpl.hxx b/vcl/inc/salgdiimpl.hxx
index 58d6c1a..7375240 100644
--- a/vcl/inc/salgdiimpl.hxx
+++ b/vcl/inc/salgdiimpl.hxx
@@ -36,39 +36,41 @@ public:
 
     virtual ~SalGraphicsImpl();
 
+    virtual void freeResources() = 0;
+
     virtual bool setClipRegion( const vcl::Region& ) = 0;
     //
     // get the depth of the device
-    virtual sal_uInt16          GetBitCount() const = 0;
+    virtual sal_uInt16 GetBitCount() const = 0;
 
     // get the width of the device
-    virtual long                GetGraphicsWidth() const = 0;
+    virtual long GetGraphicsWidth() const = 0;
 
     // set the clip region to empty
-    virtual void                ResetClipRegion() = 0;
+    virtual void ResetClipRegion() = 0;
 
     // set the line color to transparent (= don't draw lines)
 
-    virtual void                SetLineColor() = 0;
+    virtual void SetLineColor() = 0;
 
     // set the line color to a specific color
-    virtual void                SetLineColor( SalColor nSalColor ) = 0;
+    virtual void SetLineColor( SalColor nSalColor ) = 0;
 
     // set the fill color to transparent (= don't fill)
-    virtual void                SetFillColor() = 0;
+    virtual void SetFillColor() = 0;
 
     // set the fill color to a specific color, shapes will be
     // filled accordingly
-    virtual void                SetFillColor( SalColor nSalColor ) = 0;
+    virtual void SetFillColor( SalColor nSalColor ) = 0;
 
     // enable/disable XOR drawing
-    virtual void                SetXORMode( bool bSet, bool bInvertOnly ) = 0;
+    virtual void SetXORMode( bool bSet, bool bInvertOnly ) = 0;
 
     // set line color for raster operations
-    virtual void                SetROPLineColor( SalROPColor nROPColor ) = 0;
+    virtual void SetROPLineColor( SalROPColor nROPColor ) = 0;
 
     // set fill color for raster operations
-    virtual void                SetROPFillColor( SalROPColor nROPColor ) = 0;
+    virtual void SetROPFillColor( SalROPColor nROPColor ) = 0;
 
     // draw --> LineColor and FillColor and RasterOp and ClipRegion
     virtual void drawPixel( long nX, long nY ) = 0;
diff --git a/vcl/inc/unx/salgdi.h b/vcl/inc/unx/salgdi.h
index d34c5d1..0d1a584 100644
--- a/vcl/inc/unx/salgdi.h
+++ b/vcl/inc/unx/salgdi.h
@@ -41,7 +41,7 @@ class SalColormap;
 class SalDisplay;
 class SalFrame;
 class X11SalVirtualDevice;
-class SalPolyLine;
+class X11SalGraphicsImpl;
 class PspSalPrinter;
 class PspSalInfoPrinter;
 class ServerFont;
@@ -49,6 +49,7 @@ class ImplLayoutArgs;
 class ServerFontLayout;
 class PhysicalFontCollection;
 class PhysicalFontFace;
+class SalGraphicsImpl;
 
 namespace basegfx {
     class B2DTrapezoid;
@@ -86,7 +87,12 @@ public:
 
 class VCLPLUG_GEN_PUBLIC X11SalGraphics : public SalGraphics
 {
-    friend class            ServerFontLayout;
+    friend class ServerFontLayout;
+    friend class X11SalGraphicsImpl;
+
+private:
+    SalGraphicsImpl* mpImpl;
+
 protected:
     SalFrame*               m_pFrame; // the SalFrame which created this Graphics or NULL
     X11SalVirtualDevice*    m_pVDev;  // the SalVirtualDevice which created this Graphics or NULL
@@ -102,10 +108,6 @@ protected:
     Region          pPaintRegion_;
     Region          mpClipRegion;
 
-    GC              pPenGC_;        // Pen attributes
-    SalColor        nPenColor_;
-    Pixel           nPenPixel_;
-
     GC              pFontGC_;       // Font attributes
     ServerFont*             mpServerFont[ MAX_FALLBACK ];
 
@@ -114,55 +116,19 @@ protected:
 
     bool            bDisableGraphite_;
 
-    GC              pBrushGC_;      // Brush attributes
-    SalColor        nBrushColor_;
-    Pixel           nBrushPixel_;
     Pixmap          hBrush_;        // Dither
 
-    GC              pMonoGC_;
-    GC              pCopyGC_;
-    GC              pMaskGC_;
-    GC              pInvertGC_;
-    GC              pInvert50GC_;
-    GC              pStippleGC_;
-    GC              pTrackingGC_;
-
     bool            bWindow_ : 1;       // is Window
     bool            bPrinter_ : 1;      // is Printer
     bool            bVirDev_ : 1;       // is VirDev
-    bool            bPenGC_ : 1;        // is Pen GC valid
-    bool            bFontGC_ : 1;       // is Font GC valid
-    bool            bBrushGC_ : 1;      // is Brush GC valid
-    bool            bMonoGC_ : 1;       // is Mono GC valid
-    bool            bCopyGC_ : 1;       // is Copy GC valid
-    bool            bInvertGC_ : 1;     // is Invert GC valid
-    bool            bInvert50GC_ : 1;   // is Invert50 GC valid
-    bool            bStippleGC_ : 1;    // is Stipple GC valid
-    bool            bTrackingGC_ : 1;   // is Tracking GC valid
-    bool            bXORMode_ : 1;      // is ROP XOR Mode set
-    bool            bDitherBrush_ : 1;  // is solid or tile
+    bool bFontGC_ : 1;       // is Font GC valid
 
     using SalGraphics::SetClipRegion;
     void            SetClipRegion( GC          pGC,
                                    Region      pXReg = NULL ) const;
 
-    GC              GetTrackingGC();
-    GC              GetInvertGC();
-    GC              GetInvert50GC();
-    GC              CreateGC( Drawable      hDrawable,
-                              unsigned long nMask = GCGraphicsExposures );
-    GC              SelectPen();
-    GC              SelectBrush();
-    void            DrawLines( sal_uIntPtr              nPoints,
-                               const SalPolyLine &rPoints,
-                               GC                 pGC,
-                               bool bClose
-                               );
     bool            GetDitherPixmap ( SalColor nSalColor );
 
-    inline  GC              GetMonoGC( Pixmap hPixmap );
-    inline  GC              GetCopyGC();
-    inline  GC              GetStippleGC();
 
     using SalGraphics::DrawBitmap;
     void            DrawBitmap( const SalTwoRect& rPosAry,
@@ -174,10 +140,6 @@ protected:
     GC                      GetFontGC();
     bool                    setFont( const FontSelectPattern* pEntry, int nFallbackLevel );
 
-    void                    drawMaskedBitmap( const SalTwoRect& rPosAry,
-                                              const SalBitmap& rSalBitmap,
-                                              const SalBitmap& rTransparentBitmap );
-
 protected:
     void                    DrawPrinterString( const SalLayout& );
 
@@ -198,12 +160,11 @@ public:
     inline  const SalVisual&    GetVisual() const;
     inline  Drawable        GetDrawable() const { return hDrawable_; }
     void                    SetDrawable( Drawable d, SalX11Screen nXScreen );
-    XID                     GetXRenderPicture();
     XRenderPictFormat*      GetXRenderFormat() const;
     inline  void            SetXRenderFormat( XRenderPictFormat* pXRenderFormat ) { m_pXRenderFormat = pXRenderFormat; }
     inline  const SalColormap&    GetColormap() const { return *m_pColormap; }
     using SalGraphics::GetPixel;
-    inline  Pixel           GetPixel( SalColor nSalColor ) const;
+    inline  Pixel GetPixel( SalColor nSalColor ) const;
 
     SalX11Screen            GetScreenNumber() const { return m_nXScreen; }
 
@@ -211,7 +172,6 @@ public:
     virtual void            GetResolution( sal_Int32& rDPIX, sal_Int32& rDPIY ) SAL_OVERRIDE;
     virtual sal_uInt16          GetBitCount() const SAL_OVERRIDE;
     virtual long            GetGraphicsWidth() const SAL_OVERRIDE;
-    virtual long            GetGraphicsHeight() const;
 
     virtual void            ResetClipRegion() SAL_OVERRIDE;
     virtual bool            setClipRegion( const vcl::Region& ) SAL_OVERRIDE;
@@ -263,7 +223,6 @@ public:
     virtual void            drawPixel( long nX, long nY, SalColor nSalColor ) SAL_OVERRIDE;
     virtual void            drawLine( long nX1, long nY1, long nX2, long nY2 ) SAL_OVERRIDE;
     virtual void            drawRect( long nX, long nY, long nWidth, long nHeight ) SAL_OVERRIDE;
-    void                    drawPolyLine( sal_uInt32 nPoints, const SalPoint* pPtAry, bool bClose );
     virtual void            drawPolyLine( sal_uInt32 nPoints, const SalPoint* pPtAry ) SAL_OVERRIDE;
     virtual void            drawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry ) SAL_OVERRIDE;
     virtual void            drawPolyPolygon( sal_uInt32 nPoly,
@@ -276,7 +235,6 @@ public:
         const ::basegfx::B2DVector& rLineWidth,
         basegfx::B2DLineJoin,
         com::sun::star::drawing::LineCap) SAL_OVERRIDE;
-    virtual bool            drawFilledTrapezoids( const ::basegfx::B2DTrapezoid*, int nTrapCount, double fTransparency );
 
 #if 1 // TODO: remove these obselete methods
     virtual bool        drawPolyLineBezier( sal_uInt32 nPoints,
diff --git a/vcl/unx/generic/gdi/gdiimpl.cxx b/vcl/unx/generic/gdi/gdiimpl.cxx
new file mode 100644
index 0000000..e95bee5
--- /dev/null
+++ b/vcl/unx/generic/gdi/gdiimpl.cxx
@@ -0,0 +1,1779 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <prex.h>
+#include <X11/Xproto.h>
+#include <postx.h>
+
+#include "gdiimpl.hxx"
+
+#include "vcl/salbtype.hxx"
+
+#include "unx/salunx.h"
+#include "unx/saldata.hxx"
+#include "unx/saldisp.hxx"
+#include "unx/salbmp.h"
+#include "unx/salgdi.h"
+#include "unx/salframe.h"
+#include "unx/salvd.h"
+#include <unx/x11/xlimits.hxx>
+#include "xrender_peer.hxx"
+
+#include "outdata.hxx"
+
+#include "basegfx/polygon/b2dpolygon.hxx"
+#include "basegfx/polygon/b2dpolypolygon.hxx"
+#include "basegfx/polygon/b2dpolypolygontools.hxx"
+#include "basegfx/polygon/b2dpolygontools.hxx"
+#include "basegfx/polygon/b2dpolygonclipper.hxx"
+#include "basegfx/polygon/b2dlinegeometry.hxx"
+#include "basegfx/matrix/b2dhommatrix.hxx"
+#include "basegfx/matrix/b2dhommatrixtools.hxx"
+#include "basegfx/polygon/b2dpolypolygoncutter.hxx"
+#include "basegfx/polygon/b2dtrapezoid.hxx"
+
+#undef SALGDI2_TESTTRANS
+
+#if (OSL_DEBUG_LEVEL > 1) && defined SALGDI2_TESTTRANS
+#define DBG_TESTTRANS( _def_drawable )                              \
+{                                                                   \
+    XCopyArea( pXDisp, _def_drawable, aDrawable, GetCopyGC(),       \
+               0, 0,                                                \
+               rPosAry.mnDestWidth, rPosAry.mnDestHeight,         \
+               0, 0 );                                              \
+}
+#else // (OSL_DEBUG_LEVEL > 1) && defined SALGDI2_TESTTRANS
+#define DBG_TESTTRANS( _def_drawable )
+#endif // (OSL_DEBUG_LEVEL > 1) && defined SALGDI2_TESTTRANS
+
+#define STATIC_POINTS 64
+
+class SalPolyLine
+{
+    XPoint Points_[STATIC_POINTS];
+    XPoint *pFirst_;
+public:
+    SalPolyLine(sal_uLong nPoints, const SalPoint *p)
+        : pFirst_(nPoints+1 > STATIC_POINTS ? new XPoint[nPoints+1] : Points_)
+    {
+        for( sal_uLong i = 0; i < nPoints; i++ )
+        {
+            pFirst_[i].x = (short)p[i].mnX;
+            pFirst_[i].y = (short)p[i].mnY;
+        }
+        pFirst_[nPoints] = pFirst_[0]; // close polyline
+    }
+
+    ~SalPolyLine()
+    {
+        if( pFirst_ != Points_ )
+            delete [] pFirst_;
+    }
+
+    XPoint &operator [] ( sal_uLong n ) const
+    {
+        return pFirst_[n];
+    }
+};
+
+#undef STATIC_POINTS
+
+namespace
+{
+    void setForeBack(XGCValues& rValues, const SalColormap& rColMap, const SalBitmap& rSalBitmap)
+    {
+        rValues.foreground = rColMap.GetWhitePixel();
+        rValues.background = rColMap.GetBlackPixel();
+
+        //fdo#33455 and fdo#80160 handle 1 bit depth pngs with palette entries
+        //to set fore/back colors
+        SalBitmap& rBitmap = const_cast<SalBitmap&>(rSalBitmap);
+        if (BitmapBuffer* pBitmapBuffer = rBitmap.AcquireBuffer(true))
+        {
+            const BitmapPalette& rPalette = pBitmapBuffer->maPalette;
+            if (rPalette.GetEntryCount() == 2)
+            {
+                const BitmapColor aWhite(rPalette[rPalette.GetBestIndex(Color(COL_WHITE))]);
+                rValues.foreground = rColMap.GetPixel(ImplColorToSal(aWhite));
+
+                const BitmapColor aBlack(rPalette[rPalette.GetBestIndex(Color(COL_BLACK))]);
+                rValues.background = rColMap.GetPixel(ImplColorToSal(aBlack));
+            }
+            rBitmap.ReleaseBuffer(pBitmapBuffer, true);
+        }
+    }
+}
+
+X11SalGraphicsImpl::X11SalGraphicsImpl(X11SalGraphics& rParent):
+    mrParent(rParent),
+    nBrushColor_( MAKE_SALCOLOR( 0xFF, 0xFF, 0XFF ) ),
+    pBrushGC_(NULL),
+    nBrushPixel_(0),
+    bPenGC_(false),
+    bBrushGC_(false),
+    bMonoGC_(false),
+    bCopyGC_(false),
+    bInvertGC_(false),
+    bInvert50GC_(false),
+    bStippleGC_(false),
+    bTrackingGC_(false),
+    bDitherBrush_(false),
+    bXORMode_(false),
+    pPenGC_(NULL),
+    nPenColor_( MAKE_SALCOLOR( 0x00, 0x00, 0x00 ) ),
+    nPenPixel_(0),
+    pMonoGC_(NULL),
+    pCopyGC_(NULL),
+    pMaskGC_(NULL),
+    pInvertGC_(NULL),
+    pInvert50GC_(NULL),
+    pStippleGC_(NULL),
+    pTrackingGC_(NULL)
+{
+}
+
+X11SalGraphicsImpl::~X11SalGraphicsImpl()
+{
+}
+
+XID X11SalGraphicsImpl::GetXRenderPicture()
+{
+    XRenderPeer& rRenderPeer = XRenderPeer::GetInstance();
+
+    if( !mrParent.m_aXRenderPicture )
+    {
+        // check xrender support for matching visual
+        XRenderPictFormat* pXRenderFormat = mrParent.GetXRenderFormat();
+        if( !pXRenderFormat )
+            return 0;
+        // get the matching xrender target for drawable
+        mrParent.m_aXRenderPicture = rRenderPeer.CreatePicture( mrParent.hDrawable_, pXRenderFormat, 0, NULL );
+    }
+
+    {
+        // reset clip region
+        // TODO: avoid clip reset if already done
+        XRenderPictureAttributes aAttr;
+        aAttr.clip_mask = None;
+        rRenderPeer.ChangePicture( mrParent.m_aXRenderPicture, CPClipMask, &aAttr );
+    }
+
+    return mrParent.m_aXRenderPicture;
+}
+
+void X11SalGraphicsImpl::freeResources()
+{
+    Display *pDisplay = mrParent.GetXDisplay();
+
+    if( pPenGC_ ) XFreeGC( pDisplay, pPenGC_ ), pPenGC_ = None;
+    if( pBrushGC_ ) XFreeGC( pDisplay, pBrushGC_ ), pBrushGC_ = None;
+    if( pMonoGC_ ) XFreeGC( pDisplay, pMonoGC_ ), pMonoGC_ = None;
+    if( pTrackingGC_ ) XFreeGC( pDisplay, pTrackingGC_ ), pTrackingGC_ = None;
+    if( pCopyGC_ ) XFreeGC( pDisplay, pCopyGC_ ), pCopyGC_ = None;
+    if( pMaskGC_ ) XFreeGC( pDisplay, pMaskGC_ ), pMaskGC_ = None;
+    if( pInvertGC_ ) XFreeGC( pDisplay, pInvertGC_ ), pInvertGC_ = None;
+    if( pInvert50GC_ ) XFreeGC( pDisplay, pInvert50GC_ ), pInvert50GC_ = None;
+    if( pStippleGC_ ) XFreeGC( pDisplay, pStippleGC_ ), pStippleGC_ = None;
+    bTrackingGC_ = bPenGC_ = bBrushGC_ = bMonoGC_ = bCopyGC_ = bInvertGC_ = bInvert50GC_ = bStippleGC_ = false;
+}
+
+GC X11SalGraphicsImpl::CreateGC( Drawable hDrawable, unsigned long nMask )
+{
+    XGCValues values;
+
+    values.graphics_exposures   = False;
+    values.foreground           = mrParent.m_pColormap->GetBlackPixel()
+                                  ^ mrParent.m_pColormap->GetWhitePixel();
+    values.function             = GXxor;
+    values.line_width           = 1;
+    values.fill_style           = FillStippled;
+    values.stipple              = mrParent.GetDisplay()->GetInvert50( mrParent.m_nXScreen );
+    values.subwindow_mode       = ClipByChildren;
+
+    return XCreateGC( mrParent.GetXDisplay(), hDrawable, nMask | GCSubwindowMode, &values );
+}
+
+inline GC X11SalGraphicsImpl::GetCopyGC()
+{
+    if( bXORMode_ ) return GetInvertGC();
+
+    if( !pCopyGC_ )
+        pCopyGC_ = CreateGC( mrParent.GetDrawable() );
+
+    if( !bCopyGC_ )
+    {
+        mrParent.SetClipRegion( pCopyGC_ );
+        bCopyGC_ = true;
+    }
+    return pCopyGC_;
+}
+
+GC X11SalGraphicsImpl::GetTrackingGC()
+{
+    const char    dash_list[2] = {2, 2};
+
+    if( !pTrackingGC_ )
+    {
+        XGCValues     values;
+
+        values.graphics_exposures   = False;
+        values.foreground           = mrParent.m_pColormap->GetBlackPixel()
+                                      ^ mrParent.m_pColormap->GetWhitePixel();
+        values.function             = GXxor;
+        values.line_width           = 1;
+        values.line_style           = LineOnOffDash;
+
+        pTrackingGC_ = XCreateGC( mrParent.GetXDisplay(), mrParent.GetDrawable(),
+                                  GCGraphicsExposures | GCForeground | GCFunction
+                                  | GCLineWidth | GCLineStyle,
+                                  &values );
+        XSetDashes( mrParent.GetXDisplay(), pTrackingGC_, 0, dash_list, 2 );
+    }
+
+    if( !bTrackingGC_ )
+    {
+        mrParent.SetClipRegion( pTrackingGC_ );
+        bTrackingGC_ = true;
+    }
+
+    return pTrackingGC_;
+}
+
+inline GC X11SalGraphicsImpl::GetMonoGC( Pixmap hPixmap )
+{
+    if( !pMonoGC_ )
+        pMonoGC_ = CreateGC( hPixmap );
+
+    if( !bMonoGC_ )
+    {
+        mrParent.SetClipRegion( pMonoGC_ );
+        bMonoGC_ = true;
+    }
+
+    return pMonoGC_;
+}
+
+GC X11SalGraphicsImpl::GetInvertGC()
+{
+    if( !pInvertGC_ )
+        pInvertGC_ = CreateGC( mrParent.GetDrawable(),
+                               GCGraphicsExposures
+                               | GCForeground
+                               | GCFunction
+                               | GCLineWidth );
+
+    if( !bInvertGC_ )
+    {
+        mrParent.SetClipRegion( pInvertGC_ );
+        bInvertGC_ = true;
+    }
+    return pInvertGC_;
+}
+
+GC X11SalGraphicsImpl::GetInvert50GC()
+{
+    if( !pInvert50GC_ )
+    {
+        XGCValues values;
+
+        values.graphics_exposures   = False;
+        values.foreground           = mrParent.m_pColormap->GetWhitePixel();
+        values.background           = mrParent.m_pColormap->GetBlackPixel();
+        values.function             = GXinvert;
+        values.line_width           = 1;
+        values.line_style           = LineSolid;
+        unsigned long nValueMask =
+                                  GCGraphicsExposures
+                                  | GCForeground
+                                  | GCBackground
+                                  | GCFunction
+                                  | GCLineWidth
+                                  | GCLineStyle
+                                  | GCFillStyle
+                                  | GCStipple;
+
+        char* pEnv = getenv( "SAL_DO_NOT_USE_INVERT50" );
+        if( pEnv && ! strcasecmp( pEnv, "true" ) )
+        {
+            values.fill_style = FillSolid;
+            nValueMask &= ~ GCStipple;
+        }
+        else
+        {
+            values.fill_style           = FillStippled;
+            values.stipple              = mrParent.GetDisplay()->GetInvert50( mrParent.m_nXScreen );
+        }
+
+        pInvert50GC_ = XCreateGC( mrParent.GetXDisplay(), mrParent.GetDrawable(),
+                                  nValueMask,
+                                  &values );
+    }
+
+    if( !bInvert50GC_ )
+    {
+        mrParent.SetClipRegion( pInvert50GC_ );
+        bInvert50GC_ = true;
+    }
+    return pInvert50GC_;
+}
+
+inline GC X11SalGraphicsImpl::GetStippleGC()
+{
+    if( !pStippleGC_ )
+        pStippleGC_ = CreateGC( mrParent.GetDrawable(),
+                                GCGraphicsExposures
+                                | GCFillStyle
+                                | GCLineWidth );
+
+    if( !bStippleGC_ )
+    {
+        XSetFunction( mrParent.GetXDisplay(), pStippleGC_, bXORMode_ ? GXxor : GXcopy );
+        mrParent.SetClipRegion( pStippleGC_ );
+        bStippleGC_ = true;
+    }
+
+    return pStippleGC_;
+}
+
+GC X11SalGraphicsImpl::SelectBrush()
+{
+    Display *pDisplay = mrParent.GetXDisplay();
+
+    DBG_ASSERT( nBrushColor_ != SALCOLOR_NONE, "Brush Transparent" );
+
+    if( !pBrushGC_ )
+    {
+        XGCValues values;
+        values.subwindow_mode       = ClipByChildren;
+        values.fill_rule            = EvenOddRule;      // Pict import/ Gradient
+        values.graphics_exposures   = False;
+
+        pBrushGC_ = XCreateGC( pDisplay, mrParent.hDrawable_,
+                               GCSubwindowMode | GCFillRule | GCGraphicsExposures,
+                               &values );
+    }
+
+    if( !bBrushGC_ )
+    {
+        if( !bDitherBrush_ )
+        {
+            XSetFillStyle ( pDisplay, pBrushGC_, FillSolid );
+            XSetForeground( pDisplay, pBrushGC_, nBrushPixel_ );
+            if( mrParent.bPrinter_ )
+                XSetTile( pDisplay, pBrushGC_, None );
+        }
+        else
+        {
+            // Bug in Sun Solaris 2.5.1, XFillPolygon doesn't always reflect
+            // changes of the tile. PROPERTY_BUG_Tile doesn't fix this !
+            if (mrParent.GetDisplay()->GetProperties() & PROPERTY_BUG_FillPolygon_Tile)
+                XSetFillStyle ( pDisplay, pBrushGC_, FillSolid );
+
+            XSetFillStyle ( pDisplay, pBrushGC_, FillTiled );
+            XSetTile      ( pDisplay, pBrushGC_, mrParent.hBrush_ );
+        }
+        XSetFunction  ( pDisplay, pBrushGC_, bXORMode_ ? GXxor : GXcopy );
+        mrParent.SetClipRegion( pBrushGC_ );
+
+        bBrushGC_ = true;
+    }
+
+    return pBrushGC_;
+}
+
+GC X11SalGraphicsImpl::SelectPen()
+{
+    Display *pDisplay = mrParent.GetXDisplay();
+
+    if( !pPenGC_ )
+    {
+        XGCValues values;
+        values.subwindow_mode       = ClipByChildren;
+        values.fill_rule            = EvenOddRule;      // Pict import/ Gradient
+        values.graphics_exposures   = False;
+
+        pPenGC_ = XCreateGC( pDisplay, mrParent.hDrawable_,
+                             GCSubwindowMode | GCFillRule | GCGraphicsExposures,
+                             &values );
+    }
+
+    if( !bPenGC_ )
+    {
+        if( nPenColor_ != SALCOLOR_NONE )
+            XSetForeground( pDisplay, pPenGC_, nPenPixel_ );
+        XSetFunction  ( pDisplay, pPenGC_, bXORMode_ ? GXxor : GXcopy );
+        mrParent.SetClipRegion( pPenGC_ );
+        bPenGC_ = true;
+    }
+
+    return pPenGC_;
+}
+
+void X11SalGraphicsImpl::DrawLines( sal_uLong              nPoints,
+                                const SalPolyLine &rPoints,
+                                GC                 pGC,
+                                bool               bClose
+                                )
+{
+    // calculate how many lines XWindow can draw in one go
+    sal_uLong nMaxLines = (mrParent.GetDisplay()->GetMaxRequestSize() - sizeof(xPolyPointReq))
+                      / sizeof(xPoint);
+    if( nMaxLines > nPoints ) nMaxLines = nPoints;
+
+    // print all lines that XWindows can draw
+    sal_uLong n;
+    for( n = 0; nPoints - n > nMaxLines; n += nMaxLines - 1 )
+        XDrawLines( mrParent.GetXDisplay(),
+                    mrParent.GetDrawable(),
+                    pGC,
+                    &rPoints[n],
+                    nMaxLines,
+                    CoordModeOrigin );
+
+    if( n < nPoints )
+        XDrawLines( mrParent.GetXDisplay(),
+                    mrParent.GetDrawable(),
+                    pGC,
+                    &rPoints[n],
+                    nPoints - n,
+                    CoordModeOrigin );
+    if( bClose )
+    {
+        if( rPoints[nPoints-1].x != rPoints[0].x || rPoints[nPoints-1].y != rPoints[0].y )
+            drawLine( rPoints[nPoints-1].x, rPoints[nPoints-1].y, rPoints[0].x, rPoints[0].y );
+    }
+}
+
+void X11SalGraphicsImpl::copyBits( const SalTwoRect& rPosAry,
+                                  SalGraphics      *pSSrcGraphics )
+{
+    X11SalGraphics* pSrcGraphics = pSSrcGraphics
+        ? static_cast<X11SalGraphics*>(pSSrcGraphics)
+        : &mrParent;
+
+    if( rPosAry.mnSrcWidth <= 0
+        || rPosAry.mnSrcHeight <= 0
+        || rPosAry.mnDestWidth <= 0
+        || rPosAry.mnDestHeight <= 0 )
+    {
+        return;
+    }
+
+    int n;
+    if( pSrcGraphics == &mrParent )
+    {
+        n = 2;
+    }
+    else if( pSrcGraphics->bWindow_ )
+    {
+        // window or compatible virtual device
+        if( pSrcGraphics->GetDisplay() == mrParent.GetDisplay() &&
+            pSrcGraphics->m_nXScreen == mrParent.m_nXScreen &&
+            pSrcGraphics->GetVisual().GetDepth() == mrParent.GetVisual().GetDepth()
+            )
+            n = 2; // same Display
+        else
+            n = 1; // printer or other display
+    }
+    else if( pSrcGraphics->bVirDev_ )
+    {
+        // printer compatible virtual device
+        if( mrParent.bPrinter_ )
+            n = 2; // printer or compatible virtual device == same display
+        else
+            n = 1; // window or compatible virtual device
+    }
+    else
+        n = 0;
+
+    if( n == 2
+        && rPosAry.mnSrcWidth   == rPosAry.mnDestWidth
+        && rPosAry.mnSrcHeight == rPosAry.mnDestHeight
+        )
+    {
+        // #i60699# Need to generate graphics exposures (to repaint
+        // obscured areas beneath overlapping windows), src and dest
+        // are the same window.
+        const bool bNeedGraphicsExposures( pSrcGraphics == &mrParent &&
+                                           !mrParent.bVirDev_ &&
+                                           pSrcGraphics->bWindow_ );
+
+        GC pCopyGC;
+
+        if( bXORMode_
+            && !pSrcGraphics->bVirDev_
+            && (mrParent.GetDisplay()->GetProperties() & PROPERTY_BUG_XCopyArea_GXxor) )
+        {
+            Pixmap hPixmap = limitXCreatePixmap( mrParent.GetXDisplay(),
+                                            pSrcGraphics->GetDrawable(),        // source
+                                            rPosAry.mnSrcWidth, rPosAry.mnSrcHeight,
+                                            pSrcGraphics->GetBitCount() );
+
+            pCopyGC = mrParent.GetDisplay()->GetCopyGC( mrParent.m_nXScreen );
+
+            if( bNeedGraphicsExposures )
+                XSetGraphicsExposures( mrParent.GetXDisplay(),
+                                       pCopyGC,
+                                       True );
+
+            XCopyArea( mrParent.GetXDisplay(),
+                       pSrcGraphics->GetDrawable(),     // source
+                       hPixmap,                         // destination
+                       pCopyGC,                         // no clipping
+                       rPosAry.mnSrcX,     rPosAry.mnSrcY,
+                       rPosAry.mnSrcWidth, rPosAry.mnSrcHeight,
+                       0,                   0 );            // destination
+            XCopyArea( mrParent.GetXDisplay(),
+                       hPixmap,                             // source
+                       mrParent.GetDrawable(),                       // destination
+                       GetInvertGC(),       // destination clipping
+                       0,                   0,              // source
+                       rPosAry.mnSrcWidth, rPosAry.mnSrcHeight,
+                       rPosAry.mnDestX,    rPosAry.mnDestY );
+            XFreePixmap( mrParent.GetXDisplay(), hPixmap );
+        }
+        else
+        {
+            pCopyGC = GetCopyGC();
+
+            if( bNeedGraphicsExposures )
+                XSetGraphicsExposures( mrParent.GetXDisplay(),
+                                       pCopyGC,
+                                       True );
+
+            XCopyArea( mrParent.GetXDisplay(),
+                       pSrcGraphics->GetDrawable(),     // source
+                       mrParent.GetDrawable(),                   // destination
+                       pCopyGC,                         // destination clipping
+                       rPosAry.mnSrcX,     rPosAry.mnSrcY,
+                       rPosAry.mnSrcWidth, rPosAry.mnSrcHeight,
+                       rPosAry.mnDestX,    rPosAry.mnDestY );
+        }
+
+        if( bNeedGraphicsExposures )
+        {
+            mrParent.YieldGraphicsExpose();
+
+            if( pCopyGC )
+                XSetGraphicsExposures( mrParent.GetXDisplay(),
+                                       pCopyGC,
+                                       False );
+        }
+    }
+    else if( n )
+    {
+        // #i60699# No chance to handle graphics exposures - we copy
+        // to a temp bitmap first, into which no repaints are
+        // technically possible.
+        boost::scoped_ptr<SalBitmap> pDDB(pSrcGraphics->getBitmap( rPosAry.mnSrcX,
+                                                                   rPosAry.mnSrcY,
+                                                                   rPosAry.mnSrcWidth,
+                                                                   rPosAry.mnSrcHeight ));
+
+        if( !pDDB )
+        {
+            stderr0( "SalGraphics::CopyBits !pSrcGraphics->GetBitmap()\n" );
+            return;
+        }
+
+        SalTwoRect aPosAry( rPosAry );
+
+        aPosAry.mnSrcX = 0, aPosAry.mnSrcY = 0;
+        drawBitmap( aPosAry, *pDDB );
+    }
+    else {
+        stderr0( "X11SalGraphicsImpl::CopyBits from Printer not yet implemented\n" );
+    }
+}
+
+void X11SalGraphicsImpl::copyArea ( long nDestX,    long nDestY,
+                                long nSrcX,     long nSrcY,
+                                long nSrcWidth, long nSrcHeight,
+                                sal_uInt16 )
+{
+    SalTwoRect aPosAry;
+
+    aPosAry.mnDestX = nDestX;
+    aPosAry.mnDestY = nDestY;
+    aPosAry.mnDestWidth  = nSrcWidth;
+    aPosAry.mnDestHeight = nSrcHeight;
+
+    aPosAry.mnSrcX = nSrcX;
+    aPosAry.mnSrcY = nSrcY;
+    aPosAry.mnSrcWidth  = nSrcWidth;
+    aPosAry.mnSrcHeight = nSrcHeight;
+
+    copyBits ( aPosAry, 0 );
+}
+
+void X11SalGraphicsImpl::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap )
+{
+    const SalDisplay*   pSalDisp = mrParent.GetDisplay();
+    Display*            pXDisp = pSalDisp->GetDisplay();
+    const Drawable      aDrawable( mrParent.GetDrawable() );
+    const SalColormap&  rColMap = pSalDisp->GetColormap( mrParent.m_nXScreen );
+    const long          nDepth = mrParent.GetDisplay()->GetVisual( mrParent.m_nXScreen ).GetDepth();
+    GC                  aGC( GetCopyGC() );
+    XGCValues           aOldVal, aNewVal;
+    int                 nValues = GCForeground | GCBackground;
+
+    if( rSalBitmap.GetBitCount() == 1 )
+    {
+        // set foreground/background values for 1Bit bitmaps
+        XGetGCValues( pXDisp, aGC, nValues, &aOldVal );
+        setForeBack(aNewVal, rColMap, rSalBitmap);
+        XChangeGC( pXDisp, aGC, nValues, &aNewVal );
+    }
+
+    static_cast<const X11SalBitmap&>(rSalBitmap).ImplDraw( aDrawable, mrParent.m_nXScreen, nDepth, rPosAry, aGC );
+
+    if( rSalBitmap.GetBitCount() == 1 )
+        XChangeGC( pXDisp, aGC, nValues, &aOldVal );
+    XFlush( pXDisp );
+}
+
+void X11SalGraphicsImpl::drawBitmap( const SalTwoRect& rPosAry,
+                                 const SalBitmap& rSrcBitmap,
+                                 const SalBitmap& rMaskBitmap )
+{
+    DBG_ASSERT( !mrParent.bPrinter_, "Drawing of transparent bitmaps on printer devices is strictly forbidden" );
+
+    // decide if alpha masking or transparency masking is needed
+    BitmapBuffer* pAlphaBuffer = const_cast<SalBitmap&>(rMaskBitmap).AcquireBuffer( true );
+    if( pAlphaBuffer != NULL )
+    {
+        int nMaskFormat = pAlphaBuffer->mnFormat;
+        const_cast<SalBitmap&>(rMaskBitmap).ReleaseBuffer( pAlphaBuffer, true );
+        if( nMaskFormat == BMP_FORMAT_8BIT_PAL )
+            drawAlphaBitmap( rPosAry, rSrcBitmap, rMaskBitmap );
+    }
+
+    drawMaskedBitmap( rPosAry, rSrcBitmap, rMaskBitmap );
+}
+
+void X11SalGraphicsImpl::drawMaskedBitmap( const SalTwoRect& rPosAry,
+                                       const SalBitmap& rSalBitmap,
+                                       const SalBitmap& rTransBitmap )
+{
+    const SalDisplay*   pSalDisp = mrParent.GetDisplay();
+    Display*            pXDisp = pSalDisp->GetDisplay();
+    Drawable            aDrawable( mrParent.GetDrawable() );
+
+    // figure work mode depth. If this is a VDev Drawable, use its
+    // bitdepth to create pixmaps for, otherwise, XCopyArea will
+    // refuse to work.
+    const sal_uInt16    nDepth( mrParent.m_pVDev ?
+                            mrParent.m_pVDev->GetDepth() :
+                            pSalDisp->GetVisual( mrParent.m_nXScreen ).GetDepth() );
+    Pixmap          aFG( limitXCreatePixmap( pXDisp, aDrawable, rPosAry.mnDestWidth,
+                                        rPosAry.mnDestHeight, nDepth ) );
+    Pixmap          aBG( limitXCreatePixmap( pXDisp, aDrawable, rPosAry.mnDestWidth,
+                                        rPosAry.mnDestHeight, nDepth ) );
+
+    if( aFG && aBG )
+    {
+        GC                  aTmpGC;
+        XGCValues           aValues;
+        setForeBack(aValues, pSalDisp->GetColormap(mrParent.m_nXScreen), rSalBitmap);
+        const int           nValues = GCFunction | GCForeground | GCBackground;
+        SalTwoRect          aTmpRect( rPosAry ); aTmpRect.mnDestX = aTmpRect.mnDestY = 0;
+
+        // draw paint bitmap in pixmap #1
+        aValues.function = GXcopy;
+        aTmpGC = XCreateGC( pXDisp, aFG, nValues, &aValues );
+        static_cast<const X11SalBitmap&>(rSalBitmap).ImplDraw( aFG, mrParent.m_nXScreen, nDepth, aTmpRect, aTmpGC );
+        DBG_TESTTRANS( aFG );
+
+        // draw background in pixmap #2
+        XCopyArea( pXDisp, aDrawable, aBG, aTmpGC,
+                   rPosAry.mnDestX, rPosAry.mnDestY,
+                   rPosAry.mnDestWidth, rPosAry.mnDestHeight,
+                   0, 0 );
+
+        DBG_TESTTRANS( aBG );
+
+        // mask out paint bitmap in pixmap #1 (transparent areas 0)
+        aValues.function = GXand, aValues.foreground = 0x00000000, aValues.background = 0xffffffff;
+        XChangeGC( pXDisp, aTmpGC, nValues, &aValues );
+        static_cast<const X11SalBitmap&>(rTransBitmap).ImplDraw( aFG, mrParent.m_nXScreen, 1, aTmpRect, aTmpGC );
+
+        DBG_TESTTRANS( aFG );
+
+        // #105055# For XOR mode, keep background behind bitmap intact
+        if( !bXORMode_ )
+        {
+            // mask out background in pixmap #2 (nontransparent areas 0)
+            aValues.function = GXand, aValues.foreground = 0xffffffff, aValues.background = 0x00000000;
+            XChangeGC( pXDisp, aTmpGC, nValues, &aValues );
+            static_cast<const X11SalBitmap&>(rTransBitmap).ImplDraw( aBG, mrParent.m_nXScreen, 1, aTmpRect, aTmpGC );
+
+            DBG_TESTTRANS( aBG );
+        }
+
+        // merge pixmap #1 and pixmap #2 in pixmap #2
+        aValues.function = GXxor, aValues.foreground = 0xffffffff, aValues.background = 0x00000000;
+        XChangeGC( pXDisp, aTmpGC, nValues, &aValues );
+        XCopyArea( pXDisp, aFG, aBG, aTmpGC,
+                   0, 0,
+                   rPosAry.mnDestWidth, rPosAry.mnDestHeight,
+                   0, 0 );
+        DBG_TESTTRANS( aBG );
+
+        // #105055# Disable XOR temporarily
+        bool bOldXORMode( bXORMode_ );
+        bXORMode_ = false;
+
+        // copy pixmap #2 (result) to background
+        XCopyArea( pXDisp, aBG, aDrawable, GetCopyGC(),
+                   0, 0,
+                   rPosAry.mnDestWidth, rPosAry.mnDestHeight,
+                   rPosAry.mnDestX, rPosAry.mnDestY );
+
+        DBG_TESTTRANS( aBG );
+
+        bXORMode_ = bOldXORMode;
+
+        XFreeGC( pXDisp, aTmpGC );
+        XFlush( pXDisp );
+    }
+    else
+        drawBitmap( rPosAry, rSalBitmap );
+
+    if( aFG )
+        XFreePixmap( pXDisp, aFG );
+
+    if( aBG )
+        XFreePixmap( pXDisp, aBG );
+}
+
+bool X11SalGraphicsImpl::drawAlphaBitmap( const SalTwoRect& rTR,
+    const SalBitmap& rSrcBitmap, const SalBitmap& rAlphaBmp )
+{
+    // non 8-bit alpha not implemented yet
+    if( rAlphaBmp.GetBitCount() != 8 )
+        return false;
+
+    // horizontal mirroring not implemented yet
+    if( rTR.mnDestWidth < 0 )
+        return false;
+
+    // stretched conversion is not implemented yet
+    if( rTR.mnDestWidth != rTR.mnSrcWidth )
+        return false;
+    if( rTR.mnDestHeight!= rTR.mnSrcHeight )
+        return false;
+
+    // create destination picture
+    Picture aDstPic = GetXRenderPicture();
+    if( !aDstPic )
+        return false;
+
+    const SalDisplay* pSalDisp = mrParent.GetDisplay();
+    const SalVisual& rSalVis = pSalDisp->GetVisual( mrParent.m_nXScreen );
+    Display* pXDisplay = pSalDisp->GetDisplay();
+
+    // create source Picture
+    int nDepth = mrParent.m_pVDev ? mrParent.m_pVDev->GetDepth() : rSalVis.GetDepth();
+    const X11SalBitmap& rSrcX11Bmp = static_cast<const X11SalBitmap&>( rSrcBitmap );
+    ImplSalDDB* pSrcDDB = rSrcX11Bmp.ImplGetDDB( mrParent.hDrawable_, mrParent.m_nXScreen, nDepth, rTR );
+    if( !pSrcDDB )
+        return false;
+
+    //#i75249# workaround for ImplGetDDB() giving us back a different depth than
+    // we requested. E.g. mask pixmaps are always compatible with the drawable
+    // TODO: find an appropriate picture format for these cases
+    //       then remove the workaround below and the one for #i75531#
+    if( nDepth != pSrcDDB->ImplGetDepth() )
+        return false;
+
+    Pixmap aSrcPM = pSrcDDB->ImplGetPixmap();
+    if( !aSrcPM )
+        return false;
+
+    // create source picture
+    // TODO: use scoped picture
+    Visual* pSrcXVisual = rSalVis.GetVisual();
+    XRenderPeer& rPeer = XRenderPeer::GetInstance();
+    XRenderPictFormat* pSrcVisFmt = rPeer.FindVisualFormat( pSrcXVisual );
+    if( !pSrcVisFmt )
+        return false;
+    Picture aSrcPic = rPeer.CreatePicture( aSrcPM, pSrcVisFmt, 0, NULL );
+    if( !aSrcPic )
+        return false;
+
+    // create alpha Picture
+
+    // TODO: use SalX11Bitmap functionality and caching for the Alpha Pixmap
+    // problem is that they don't provide an 8bit Pixmap on a non-8bit display
+    BitmapBuffer* pAlphaBuffer = const_cast<SalBitmap&>(rAlphaBmp).AcquireBuffer( true );
+
+    // an XImage needs its data top_down
+    // TODO: avoid wrongly oriented images in upper layers!
+    const int nImageSize = pAlphaBuffer->mnHeight * pAlphaBuffer->mnScanlineSize;
+    const char* pSrcBits = (char*)pAlphaBuffer->mpBits;
+    char* pAlphaBits = new char[ nImageSize ];
+    if( BMP_SCANLINE_ADJUSTMENT( pAlphaBuffer->mnFormat ) == BMP_FORMAT_TOP_DOWN )
+        memcpy( pAlphaBits, pSrcBits, nImageSize );
+    else
+    {
+        char* pDstBits = pAlphaBits + nImageSize;
+        const int nLineSize = pAlphaBuffer->mnScanlineSize;
+        for(; (pDstBits -= nLineSize) >= pAlphaBits; pSrcBits += nLineSize )
+            memcpy( pDstBits, pSrcBits, nLineSize );
+    }
+
+    // the alpha values need to be inverted for XRender
+    // TODO: make upper layers use standard alpha
+    long* pLDst = (long*)pAlphaBits;
+    for( int i = nImageSize/sizeof(long); --i >= 0; ++pLDst )
+        *pLDst = ~*pLDst;
+
+    char* pCDst = (char*)pLDst;
+    for( int i = nImageSize & (sizeof(long)-1); --i >= 0; ++pCDst )
+        *pCDst = ~*pCDst;
+
+    const XRenderPictFormat* pAlphaFormat = rPeer.GetStandardFormatA8();
+    XImage* pAlphaImg = XCreateImage( pXDisplay, pSrcXVisual, 8, ZPixmap, 0,
+        pAlphaBits, pAlphaBuffer->mnWidth, pAlphaBuffer->mnHeight,
+        pAlphaFormat->depth, pAlphaBuffer->mnScanlineSize );
+
+    Pixmap aAlphaPM = limitXCreatePixmap( pXDisplay, mrParent.hDrawable_,
+        rTR.mnDestWidth, rTR.mnDestHeight, 8 );
+
+    XGCValues aAlphaGCV;
+    aAlphaGCV.function = GXcopy;
+    GC aAlphaGC = XCreateGC( pXDisplay, aAlphaPM, GCFunction, &aAlphaGCV );
+    XPutImage( pXDisplay, aAlphaPM, aAlphaGC, pAlphaImg,
+        rTR.mnSrcX, rTR.mnSrcY, 0, 0, rTR.mnDestWidth, rTR.mnDestHeight );
+    XFreeGC( pXDisplay, aAlphaGC );
+    XFree( pAlphaImg );
+    if( pAlphaBits != (char*)pAlphaBuffer->mpBits )
+        delete[] pAlphaBits;
+
+    const_cast<SalBitmap&>(rAlphaBmp).ReleaseBuffer( pAlphaBuffer, true );
+
+    XRenderPictureAttributes aAttr;
+    aAttr.repeat = int(true);
+    Picture aAlphaPic = rPeer.CreatePicture( aAlphaPM, pAlphaFormat, CPRepeat, &aAttr );
+    if( !aAlphaPic )
+        return false;
+
+    // set clipping
+    if( mrParent.mpClipRegion && !XEmptyRegion( mrParent.mpClipRegion ) )
+        rPeer.SetPictureClipRegion( aDstPic, mrParent.mpClipRegion );
+
+    // paint source * mask over destination picture
+    rPeer.CompositePicture( PictOpOver, aSrcPic, aAlphaPic, aDstPic,
+        rTR.mnSrcX, rTR.mnSrcY, 0, 0,
+        rTR.mnDestX, rTR.mnDestY, rTR.mnDestWidth, rTR.mnDestHeight );
+
+    rPeer.FreePicture( aAlphaPic );
+    XFreePixmap(pXDisplay, aAlphaPM);
+    rPeer.FreePicture( aSrcPic );
+    return true;
+}
+
+bool X11SalGraphicsImpl::drawTransformedBitmap(
+    const basegfx::B2DPoint& rNull,
+    const basegfx::B2DPoint& rX,
+    const basegfx::B2DPoint& rY,
+    const SalBitmap& rSourceBitmap,
+    const SalBitmap* pAlphaBitmap)
+{
+    // here direct support for transformed bitmaps can be impemented
+    (void)rNull; (void)rX; (void)rY; (void)rSourceBitmap; (void)pAlphaBitmap;
+    return false;
+}
+
+bool X11SalGraphicsImpl::drawAlphaRect( long nX, long nY, long nWidth,
+                                    long nHeight, sal_uInt8 nTransparency )
+{
+    if( ! mrParent.m_pFrame && ! mrParent.m_pVDev )
+        return false;
+
+    if( bPenGC_ || !bBrushGC_ || bXORMode_ )
+        return false; // can only perform solid fills without XOR.
+
+    if( mrParent.m_pVDev && mrParent.m_pVDev->GetDepth() < 8 )
+        return false;
+
+    Picture aDstPic = GetXRenderPicture();
+    if( !aDstPic )
+        return false;
+
+    const double fTransparency = (100 - nTransparency) * (1.0/100);
+    const XRenderColor aRenderColor = GetXRenderColor( nBrushColor_ , fTransparency);
+
+    XRenderPeer& rPeer = XRenderPeer::GetInstance();
+    rPeer.FillRectangle( PictOpOver,
+                         aDstPic,
+                         &aRenderColor,
+                         nX, nY,
+                         nWidth, nHeight );
+
+    return true;
+}
+
+void X11SalGraphicsImpl::drawBitmap( const SalTwoRect&,
+                                 const SalBitmap&,
+                                 SalColor )
+{
+    OSL_FAIL( "::DrawBitmap with transparent color not supported" );
+}
+
+void X11SalGraphicsImpl::drawMask( const SalTwoRect& rPosAry,
+                               const SalBitmap &rSalBitmap,
+                               SalColor nMaskColor )
+{
+    const SalDisplay*   pSalDisp = mrParent.GetDisplay();
+    Display*            pXDisp = pSalDisp->GetDisplay();
+    Drawable            aDrawable( mrParent.GetDrawable() );
+    Pixmap              aStipple( limitXCreatePixmap( pXDisp, aDrawable,
+                                                 rPosAry.mnDestWidth,
+                                                 rPosAry.mnDestHeight, 1 ) );
+
+    if( aStipple )
+    {
+        SalTwoRect  aTwoRect( rPosAry ); aTwoRect.mnDestX = aTwoRect.mnDestY = 0;
+        GC          aTmpGC;
+        XGCValues   aValues;
+
+        // create a stipple bitmap first (set bits are changed to unset bits and vice versa)
+        aValues.function = GXcopyInverted;
+        aValues.foreground = 1, aValues.background = 0;
+        aTmpGC = XCreateGC( pXDisp, aStipple, GCFunction | GCForeground | GCBackground, &aValues );
+        static_cast<const X11SalBitmap&>(rSalBitmap).ImplDraw( aStipple, mrParent.m_nXScreen, 1, aTwoRect, aTmpGC );
+
+        XFreeGC( pXDisp, aTmpGC );
+
+        // Set stipple and draw rectangle
+        GC  aStippleGC( GetStippleGC() );
+        int nX = rPosAry.mnDestX, nY = rPosAry.mnDestY;
+
+        XSetStipple( pXDisp, aStippleGC, aStipple );
+        XSetTSOrigin( pXDisp, aStippleGC, nX, nY );
+        XSetForeground( pXDisp, aStippleGC, mrParent.GetPixel( nMaskColor ) );
+        XFillRectangle( pXDisp, aDrawable, aStippleGC,
+                        nX, nY,
+                        rPosAry.mnDestWidth, rPosAry.mnDestHeight );
+        XFreePixmap( pXDisp, aStipple );
+        XFlush( pXDisp );
+    }
+    else
+        drawBitmap( rPosAry, rSalBitmap );
+}
+
+void X11SalGraphicsImpl::ResetClipRegion()
+{
+    if( mrParent.mpClipRegion )
+    {
+        bPenGC_         = false;
+        mrParent.bFontGC_ = false;
+        bBrushGC_       = false;
+        bMonoGC_        = false;
+        bCopyGC_        = false;
+        bInvertGC_      = false;
+        bInvert50GC_    = false;
+        bStippleGC_     = false;
+        bTrackingGC_    = false;
+
+        XDestroyRegion( mrParent.mpClipRegion );
+        mrParent.mpClipRegion    = NULL;
+    }
+}
+
+bool X11SalGraphicsImpl::setClipRegion( const vcl::Region& i_rClip )
+{
+    if( mrParent.mpClipRegion )
+        XDestroyRegion( mrParent.mpClipRegion );
+    mrParent.mpClipRegion = XCreateRegion();
+
+    RectangleVector aRectangles;
+    i_rClip.GetRegionRectangles(aRectangles);
+
+    for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); ++aRectIter)
+    {
+        const long nW(aRectIter->GetWidth());
+
+        if(nW)
+        {
+            const long nH(aRectIter->GetHeight());
+
+            if(nH)
+            {
+                XRectangle aRect;
+
+                aRect.x = (short)aRectIter->Left();
+                aRect.y = (short)aRectIter->Top();
+                aRect.width = (unsigned short)nW;
+                aRect.height = (unsigned short)nH;
+                XUnionRectWithRegion(&aRect, mrParent.mpClipRegion, mrParent.mpClipRegion);
+            }
+        }
+    }
+
+    //ImplRegionInfo aInfo;
+    //long nX, nY, nW, nH;
+    //bool bRegionRect = i_rClip.ImplGetFirstRect(aInfo, nX, nY, nW, nH );
+    //while( bRegionRect )
+    //{
+    //    if ( nW && nH )
+    //    {
+    //        XRectangle aRect;
+    //        aRect.x           = (short)nX;
+    //        aRect.y           = (short)nY;
+    //        aRect.width       = (unsigned short)nW;
+    //        aRect.height  = (unsigned short)nH;
+
+    //        XUnionRectWithRegion( &aRect, mrParent.mpClipRegion, mrParent.mpClipRegion );
+    //    }
+    //    bRegionRect = i_rClip.ImplGetNextRect( aInfo, nX, nY, nW, nH );
+    //}
+
+    // done, invalidate GCs
+    bPenGC_         = false;
+    mrParent.bFontGC_ = false;
+    bBrushGC_       = false;
+    bMonoGC_        = false;
+    bCopyGC_        = false;
+    bInvertGC_      = false;
+    bInvert50GC_    = false;
+    bStippleGC_     = false;
+    bTrackingGC_    = false;
+
+    if( XEmptyRegion( mrParent.mpClipRegion ) )
+    {
+        XDestroyRegion( mrParent.mpClipRegion );
+        mrParent.mpClipRegion= NULL;
+    }
+    return true;
+}
+
+void X11SalGraphicsImpl::SetLineColor()
+{
+    if( nPenColor_ != SALCOLOR_NONE )
+    {
+        nPenColor_      = SALCOLOR_NONE;
+        bPenGC_         = false;
+    }
+}
+
+void X11SalGraphicsImpl::SetLineColor( SalColor nSalColor )
+{
+    if( nPenColor_ != nSalColor )
+    {
+        nPenColor_      = nSalColor;
+        nPenPixel_      = mrParent.GetPixel( nSalColor );
+        bPenGC_         = false;
+    }
+}
+
+void X11SalGraphicsImpl::SetFillColor()
+{
+    if( nBrushColor_ != SALCOLOR_NONE )
+    {
+        bDitherBrush_   = false;
+        nBrushColor_    = SALCOLOR_NONE;
+        bBrushGC_       = false;
+    }
+}
+
+void X11SalGraphicsImpl::SetFillColor( SalColor nSalColor )
+{
+    if( nBrushColor_ != nSalColor )
+    {
+        bDitherBrush_   = false;
+        nBrushColor_    = nSalColor;
+        nBrushPixel_    = mrParent.GetPixel( nSalColor );
+        if( TrueColor != mrParent.GetColormap().GetVisual().GetClass()
+            && mrParent.GetColormap().GetColor( nBrushPixel_ ) != nBrushColor_
+            && nSalColor != MAKE_SALCOLOR( 0x00, 0x00, 0x00 ) // black
+            && nSalColor != MAKE_SALCOLOR( 0x00, 0x00, 0x80 ) // blue
+            && nSalColor != MAKE_SALCOLOR( 0x00, 0x80, 0x00 ) // green
+            && nSalColor != MAKE_SALCOLOR( 0x00, 0x80, 0x80 ) // cyan
+            && nSalColor != MAKE_SALCOLOR( 0x80, 0x00, 0x00 ) // red
+            && nSalColor != MAKE_SALCOLOR( 0x80, 0x00, 0x80 ) // magenta
+            && nSalColor != MAKE_SALCOLOR( 0x80, 0x80, 0x00 ) // brown
+            && nSalColor != MAKE_SALCOLOR( 0x80, 0x80, 0x80 ) // gray
+            && nSalColor != MAKE_SALCOLOR( 0xC0, 0xC0, 0xC0 ) // light gray
+            && nSalColor != MAKE_SALCOLOR( 0x00, 0x00, 0xFF ) // light blue
+            && nSalColor != MAKE_SALCOLOR( 0x00, 0xFF, 0x00 ) // light green
+            && nSalColor != MAKE_SALCOLOR( 0x00, 0xFF, 0xFF ) // light cyan
+            && nSalColor != MAKE_SALCOLOR( 0xFF, 0x00, 0x00 ) // light red
+            && nSalColor != MAKE_SALCOLOR( 0xFF, 0x00, 0xFF ) // light magenta
+            && nSalColor != MAKE_SALCOLOR( 0xFF, 0xFF, 0x00 ) // light brown
+            && nSalColor != MAKE_SALCOLOR( 0xFF, 0xFF, 0xFF ) )
+            bDitherBrush_ = mrParent.GetDitherPixmap(nSalColor);
+        bBrushGC_       = false;
+    }
+}
+
+void X11SalGraphicsImpl::SetROPLineColor( SalROPColor nROPColor )
+{
+    switch( nROPColor )
+    {
+        case SAL_ROP_0 : // 0
+            nPenPixel_ = (Pixel)0;
+            break;
+        case SAL_ROP_1 : // 1
+            nPenPixel_ = (Pixel)(1 << mrParent.GetVisual().GetDepth()) - 1;
+            break;
+        case SAL_ROP_INVERT : // 2
+            nPenPixel_ = (Pixel)(1 << mrParent.GetVisual().GetDepth()) - 1;
+            break;
+    }
+    nPenColor_  = mrParent.GetColormap().GetColor( nPenPixel_ );
+    bPenGC_     = false;
+}
+
+void X11SalGraphicsImpl::SetROPFillColor( SalROPColor nROPColor )
+{
+    switch( nROPColor )
+    {
+        case SAL_ROP_0 : // 0
+            nBrushPixel_ = (Pixel)0;
+            break;
+        case SAL_ROP_1 : // 1
+            nBrushPixel_ = (Pixel)(1 << mrParent.GetVisual().GetDepth()) - 1;
+            break;
+        case SAL_ROP_INVERT : // 2
+            nBrushPixel_ = (Pixel)(1 << mrParent.GetVisual().GetDepth()) - 1;
+            break;
+    }
+    bDitherBrush_   = false;
+    nBrushColor_    = mrParent.GetColormap().GetColor( nBrushPixel_ );
+    bBrushGC_       = false;
+}
+
+void X11SalGraphicsImpl::SetXORMode( bool bSet, bool )
+{
+    if( !bXORMode_ == bSet )
+    {
+        bXORMode_   = bSet;
+        bPenGC_     = false;
+        mrParent.bFontGC_ = false;
+        bBrushGC_   = false;
+        bMonoGC_        = false;
+        bCopyGC_        = false;
+        bInvertGC_  = false;
+        bInvert50GC_    = false;
+        bStippleGC_ = false;
+        bTrackingGC_    = false;
+    }
+}
+
+void X11SalGraphicsImpl::drawPixel( long nX, long nY )
+{
+    if( nPenColor_ !=  SALCOLOR_NONE )
+        XDrawPoint( mrParent.GetXDisplay(), mrParent.GetDrawable(), SelectPen(), nX, nY );
+}
+
+void X11SalGraphicsImpl::drawPixel( long nX, long nY, SalColor nSalColor )
+{
+    if( nSalColor != SALCOLOR_NONE )
+    {
+        Display *pDisplay = mrParent.GetXDisplay();
+
+        if( (nPenColor_ == SALCOLOR_NONE) && !bPenGC_ )
+        {
+            SetLineColor( nSalColor );
+            XDrawPoint( pDisplay, mrParent.GetDrawable(), SelectPen(), nX, nY );
+            nPenColor_ = SALCOLOR_NONE;
+            bPenGC_ = False;
+        }
+        else
+        {
+            GC pGC = SelectPen();
+
+            if( nSalColor != nPenColor_ )
+                XSetForeground( pDisplay, pGC, mrParent.GetPixel( nSalColor ) );
+
+            XDrawPoint( pDisplay, mrParent.GetDrawable(), pGC, nX, nY );
+
+            if( nSalColor != nPenColor_ )
+                XSetForeground( pDisplay, pGC, nPenPixel_ );
+        }
+    }
+}
+
+void X11SalGraphicsImpl::drawLine( long nX1, long nY1, long nX2, long nY2 )
+{
+    if( nPenColor_ != SALCOLOR_NONE )
+    {
+        if ( mrParent.GetDisplay()->GetProperties() & PROPERTY_BUG_DrawLine )
+        {
+            GC aGC = SelectPen();
+            XDrawPoint (mrParent.GetXDisplay(), mrParent.GetDrawable(), aGC, (int)nX1, (int)nY1);
+            XDrawPoint (mrParent.GetXDisplay(), mrParent.GetDrawable(), aGC, (int)nX2, (int)nY2);
+            XDrawLine  (mrParent.GetXDisplay(), mrParent.GetDrawable(), aGC, nX1, nY1, nX2, nY2 );
+        }
+        else
+            XDrawLine( mrParent.GetXDisplay(), mrParent.GetDrawable(),SelectPen(),
+                       nX1, nY1, nX2, nY2 );
+    }
+}
+
+void X11SalGraphicsImpl::drawRect( long nX, long nY, long nDX, long nDY )
+{
+    if( nBrushColor_ != SALCOLOR_NONE )
+    {
+        XFillRectangle( mrParent.GetXDisplay(),
+                        mrParent.GetDrawable(),
+                        SelectBrush(),
+                        nX, nY, nDX, nDY );
+    }
+    // description DrawRect is wrong; thus -1
+    if( nPenColor_ != SALCOLOR_NONE )
+        XDrawRectangle( mrParent.GetXDisplay(),
+                        mrParent.GetDrawable(),
+                        SelectPen(),
+                        nX, nY, nDX-1, nDY-1 );
+}
+
+void X11SalGraphicsImpl::drawPolyLine( sal_uInt32 nPoints, const SalPoint *pPtAry )
+{
+    drawPolyLine( nPoints, pPtAry, false );
+}
+
+void X11SalGraphicsImpl::drawPolyLine( sal_uInt32 nPoints, const SalPoint *pPtAry, bool bClose )
+{
+    if( nPenColor_ != SALCOLOR_NONE )
+    {
+        SalPolyLine Points( nPoints, pPtAry );
+
+        DrawLines( nPoints, Points, SelectPen(), bClose );
+    }
+}
+
+void X11SalGraphicsImpl::drawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry )
+{
+    if( nPoints == 0 )
+        return;
+
+    if( nPoints < 3 )
+    {
+        if( !bXORMode_ )
+        {
+            if( 1 == nPoints  )
+                drawPixel( pPtAry[0].mnX, pPtAry[0].mnY );
+            else
+                drawLine( pPtAry[0].mnX, pPtAry[0].mnY,
+                          pPtAry[1].mnX, pPtAry[1].mnY );
+        }
+        return;
+    }
+
+    SalPolyLine Points( nPoints, pPtAry );
+
+    nPoints++;
+
+    /* WORKAROUND: some Xservers (Xorg, VIA chipset in this case)
+     * do not draw the visible part of a polygon
+     * if it overlaps to the left of screen 0,y.
+     * This happens to be the case in the gradient drawn in the
+     * menubar background. workaround for the special case of
+     * of a rectangle overlapping to the left.
+     */
+    if( nPoints == 5 &&
+    Points[ 0 ].x == Points[ 1 ].x &&
+        Points[ 1 ].y == Points[ 2 ].y &&
+        Points[ 2 ].x == Points[ 3 ].x &&
+        Points[ 0 ].x == Points[ 4 ].x && Points[ 0 ].y == Points[ 4 ].y
+       )
+    {
+        bool bLeft = false;
+        bool bRight = false;
+        for(unsigned int i = 0; i < nPoints; i++ )
+    {
+            if( Points[i].x < 0 )
+                bLeft = true;
+            else
+                bRight= true;
+    }
+    if( bLeft && ! bRight )
+        return;
+    if( bLeft && bRight )
+        {
+            for( unsigned int i = 0; i < nPoints; i++ )
+                if( Points[i].x < 0 )
+                    Points[i].x = 0;
+        }
+    }
+
+    if( nBrushColor_ != SALCOLOR_NONE )
+        XFillPolygon( mrParent.GetXDisplay(),
+                      mrParent.GetDrawable(),
+                      SelectBrush(),
+                      &Points[0], nPoints,
+                      Complex, CoordModeOrigin );
+
+    if( nPenColor_ != SALCOLOR_NONE )
+        DrawLines( nPoints, Points, SelectPen(), true );
+}
+
+void X11SalGraphicsImpl::drawPolyPolygon( sal_uInt32 nPoly,
+                                   const sal_uInt32    *pPoints,
+                                   PCONSTSALPOINT  *pPtAry )
+{
+    if( nBrushColor_ != SALCOLOR_NONE )
+    {
+        sal_uInt32      i, n;
+        Region          pXRegA  = NULL;
+
+        for( i = 0; i < nPoly; i++ ) {
+            n = pPoints[i];
+            SalPolyLine Points( n, pPtAry[i] );
+            if( n > 2 )
+            {
+                Region pXRegB = XPolygonRegion( &Points[0], n+1, WindingRule );
+                if( !pXRegA )
+                    pXRegA = pXRegB;
+                else
+                {
+                    XXorRegion( pXRegA, pXRegB, pXRegA );
+                    XDestroyRegion( pXRegB );
+                }
+            }
+        }
+
+        if( pXRegA )
+        {
+            XRectangle aXRect;
+            XClipBox( pXRegA, &aXRect );
+
+            GC pGC = SelectBrush();
+            mrParent.SetClipRegion( pGC, pXRegA ); // ??? twice
+            XDestroyRegion( pXRegA );
+            bBrushGC_ = false;
+
+            XFillRectangle( mrParent.GetXDisplay(),
+                            mrParent.GetDrawable(),
+                            pGC,
+                            aXRect.x, aXRect.y, aXRect.width, aXRect.height );
+        }
+   }
+
+   if( nPenColor_ != SALCOLOR_NONE )
+       for( sal_uInt32 i = 0; i < nPoly; i++ )
+           drawPolyLine( pPoints[i], pPtAry[i], true );
+}
+
+bool X11SalGraphicsImpl::drawPolyLineBezier( sal_uInt32, const SalPoint*, const sal_uInt8* )
+{
+    return false;
+}
+
+bool X11SalGraphicsImpl::drawPolygonBezier( sal_uInt32, const SalPoint*, const sal_uInt8* )
+{
+    return false;
+}
+
+bool X11SalGraphicsImpl::drawPolyPolygonBezier( sal_uInt32, const sal_uInt32*,
+                                                const SalPoint* const*, const sal_uInt8* const* )
+{
+    return false;
+}
+
+void X11SalGraphicsImpl::invert( long       nX,
+                                long        nY,
+                                long        nDX,
+                                long        nDY,
+                                SalInvert   nFlags )
+{
+    GC pGC;
+    if( SAL_INVERT_50 & nFlags )
+    {
+        pGC = GetInvert50GC();
+        XFillRectangle( mrParent.GetXDisplay(), mrParent.GetDrawable(), pGC, nX, nY, nDX, nDY );
+    }
+    else
+    {
+        if ( SAL_INVERT_TRACKFRAME & nFlags )
+        {
+            pGC = GetTrackingGC();
+            XDrawRectangle( mrParent.GetXDisplay(), mrParent.GetDrawable(),  pGC, nX, nY, nDX, nDY );
+        }
+        else
+        {
+            pGC = GetInvertGC();
+            XFillRectangle( mrParent.GetXDisplay(), mrParent.GetDrawable(),  pGC, nX, nY, nDX, nDY );
+        }
+    }
+}
+
+void X11SalGraphicsImpl::invert( sal_uInt32 nPoints,
+                             const SalPoint* pPtAry,
+                             SalInvert nFlags )
+{
+    SalPolyLine Points ( nPoints, pPtAry );
+
+    GC pGC;
+    if( SAL_INVERT_50 & nFlags )
+        pGC = GetInvert50GC();
+    else
+        if ( SAL_INVERT_TRACKFRAME & nFlags )
+            pGC = GetTrackingGC();
+        else
+            pGC = GetInvertGC();
+
+    if( SAL_INVERT_TRACKFRAME & nFlags )
+        DrawLines ( nPoints, Points, pGC, true );
+    else
+        XFillPolygon( mrParent.GetXDisplay(),
+                      mrParent.GetDrawable(),
+                      pGC,
+                      &Points[0], nPoints,
+                      Complex, CoordModeOrigin );
+}
+
+bool X11SalGraphicsImpl::drawEPS( long,long,long,long,void*,sal_uLong )
+{
+    return false;
+}
+
+// draw a poly-polygon
+bool X11SalGraphicsImpl::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rOrigPolyPoly, double fTransparency )
+{
+    // nothing to do for empty polypolygons
+    const int nOrigPolyCount = rOrigPolyPoly.count();
+    if( nOrigPolyCount <= 0 )
+        return true;
+
+    // nothing to do if everything is transparent
+    if( (nBrushColor_ == SALCOLOR_NONE)
+    &&  (nPenColor_ == SALCOLOR_NONE) )
+        return true;
+
+    // cannot handle pencolor!=brushcolor yet
+    if( (nPenColor_ != SALCOLOR_NONE)
+    &&  (nPenColor_ != nBrushColor_) )
+        return false;
+
+    // TODO: remove the env-variable when no longer needed
+    static const char* pRenderEnv = getenv( "SAL_DISABLE_RENDER_POLY" );
+    if( pRenderEnv )
+        return false;
+
+    // snap to raster if requested
+    basegfx::B2DPolyPolygon aPolyPoly = rOrigPolyPoly;
+    const bool bSnapToRaster = !mrParent.getAntiAliasB2DDraw();
+    if( bSnapToRaster )
+        aPolyPoly = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges( aPolyPoly );
+
+    // don't bother with polygons outside of visible area
+    const basegfx::B2DRange aViewRange( 0, 0, GetGraphicsWidth(), GetGraphicsHeight() );
+    aPolyPoly = basegfx::tools::clipPolyPolygonOnRange( aPolyPoly, aViewRange, true, false );
+    if( !aPolyPoly.count() )
+        return true;
+
+    // tesselate the polypolygon into trapezoids
+    basegfx::B2DTrapezoidVector aB2DTrapVector;
+    basegfx::tools::trapezoidSubdivide( aB2DTrapVector, aPolyPoly );
+    const int nTrapCount = aB2DTrapVector.size();
+    if( !nTrapCount )
+        return true;
+    const bool bDrawn = drawFilledTrapezoids( &aB2DTrapVector[0], nTrapCount, fTransparency );
+    return bDrawn;
+}
+
+long X11SalGraphicsImpl::GetGraphicsHeight() const
+{
+    if( mrParent.m_pFrame )
+        return mrParent.m_pFrame->maGeometry.nHeight;
+    else if( mrParent.m_pVDev )
+        return mrParent.m_pVDev->GetHeight();
+    else
+        return 0;
+}
+
+bool X11SalGraphicsImpl::drawFilledTrapezoids( const ::basegfx::B2DTrapezoid* pB2DTraps, int nTrapCount, double fTransparency )
+{
+    if( nTrapCount <= 0 )
+        return true;
+
+    Picture aDstPic = GetXRenderPicture();
+    // check xrender support for this drawable
+    if( !aDstPic )
+        return false;
+
+     // convert the B2DTrapezoids into XRender-Trapezoids
+    typedef std::vector<XTrapezoid> TrapezoidVector;
+    TrapezoidVector aTrapVector( nTrapCount );
+    const basegfx::B2DTrapezoid* pB2DTrap = pB2DTraps;
+    for( int i = 0; i < nTrapCount; ++pB2DTrap, ++i )
+    {
+        XTrapezoid& rTrap = aTrapVector[ i ] ;
+
+         // set y-coordinates
+        const double fY1 = pB2DTrap->getTopY();
+        rTrap.left.p1.y = rTrap.right.p1.y = rTrap.top = XDoubleToFixed( fY1 );
+        const double fY2 = pB2DTrap->getBottomY();
+        rTrap.left.p2.y = rTrap.right.p2.y = rTrap.bottom = XDoubleToFixed( fY2 );
+
+         // set x-coordinates
+        const double fXL1 = pB2DTrap->getTopXLeft();
+        rTrap.left.p1.x = XDoubleToFixed( fXL1 );
+        const double fXR1 = pB2DTrap->getTopXRight();
+        rTrap.right.p1.x = XDoubleToFixed( fXR1 );
+        const double fXL2 = pB2DTrap->getBottomXLeft();
+        rTrap.left.p2.x = XDoubleToFixed( fXL2 );
+        const double fXR2 = pB2DTrap->getBottomXRight();
+        rTrap.right.p2.x = XDoubleToFixed( fXR2 );
+    }
+
+    // get xrender Picture for polygon foreground
+    // TODO: cache it like the target picture which uses GetXRenderPicture()
+    XRenderPeer& rRenderPeer = XRenderPeer::GetInstance();
+    SalDisplay::RenderEntry& rEntry = mrParent.GetDisplay()->GetRenderEntries( mrParent.m_nXScreen )[ 32 ];
+    if( !rEntry.m_aPicture )
+    {
+        Display* pXDisplay = mrParent.GetXDisplay();
+
+        rEntry.m_aPixmap = limitXCreatePixmap( pXDisplay, mrParent.hDrawable_, 1, 1, 32 );
+        XRenderPictureAttributes aAttr;
+        aAttr.repeat = int(true);
+
+        XRenderPictFormat* pXRPF = rRenderPeer.FindStandardFormat( PictStandardARGB32 );
+        rEntry.m_aPicture = rRenderPeer.CreatePicture( rEntry.m_aPixmap, pXRPF, CPRepeat, &aAttr );
+    }
+
+    // set polygon foreground color and opacity
+    XRenderColor aRenderColor = GetXRenderColor( nBrushColor_ , fTransparency );
+    rRenderPeer.FillRectangle( PictOpSrc, rEntry.m_aPicture, &aRenderColor, 0, 0, 1, 1 );
+
+    // set clipping
+    // TODO: move into GetXRenderPicture?
+    if( mrParent.mpClipRegion && !XEmptyRegion( mrParent.mpClipRegion ) )
+        rRenderPeer.SetPictureClipRegion( aDstPic, mrParent.mpClipRegion );
+
+    // render the trapezoids
+    const XRenderPictFormat* pMaskFormat = rRenderPeer.GetStandardFormatA8();
+    rRenderPeer.CompositeTrapezoids( PictOpOver,
+        rEntry.m_aPicture, aDstPic, pMaskFormat, 0, 0, &aTrapVector[0], aTrapVector.size() );
+
+    return true;
+}
+
+bool X11SalGraphicsImpl::drawPolyLine(
+    const ::basegfx::B2DPolygon& rPolygon,
+    double fTransparency,
+    const ::basegfx::B2DVector& rLineWidth,
+    basegfx::B2DLineJoin eLineJoin,
+    com::sun::star::drawing::LineCap eLineCap)
+{
+    const bool bIsHairline = (rLineWidth.getX() == rLineWidth.getY()) && (rLineWidth.getX() <= 1.2);
+
+    // #i101491#
+    if( !bIsHairline && (rPolygon.count() > 1000) )
+    {
+        // the used basegfx::tools::createAreaGeometry is simply too
+        // expensive with very big polygons; fallback to caller (who
+        // should use ImplLineConverter normally)
+        // AW: ImplLineConverter had to be removed since it does not even
+        // know LineJoins, so the fallback will now prepare the line geometry
+        // the same way.
+        return false;
+    }
+
+    // temporarily adjust brush color to pen color
+    // since the line is drawn as an area-polygon
+    const SalColor aKeepBrushColor = nBrushColor_;
+    nBrushColor_ = nPenColor_;
+
+    // #i11575#desc5#b adjust B2D tesselation result to raster positions
+    basegfx::B2DPolygon aPolygon = rPolygon;
+    const double fHalfWidth = 0.5 * rLineWidth.getX();
+
+    // #i122456# This is probably thought to happen to align hairlines to pixel positions, so
+    // it should be a 0.5 translation, not more. It will definitely go wrong with fat lines
+    aPolygon.transform( basegfx::tools::createTranslateB2DHomMatrix(0.5, 0.5) );
+
+    // shortcut for hairline drawing to improve performance
+    bool bDrawnOk = true;
+    if( bIsHairline )
+    {
+        // hairlines can benefit from a simplified tesselation
+        // e.g. for hairlines the linejoin style can be ignored
+        basegfx::B2DTrapezoidVector aB2DTrapVector;
+        basegfx::tools::createLineTrapezoidFromB2DPolygon( aB2DTrapVector, aPolygon, rLineWidth.getX() );
+
+        // draw tesselation result
+        const int nTrapCount = aB2DTrapVector.size();
+        if( nTrapCount > 0 )
+            bDrawnOk = drawFilledTrapezoids( &aB2DTrapVector[0], nTrapCount, fTransparency );
+
+        // restore the original brush GC
+        nBrushColor_ = aKeepBrushColor;
+        return bDrawnOk;
+    }
+
+    // get the area polygon for the line polygon
+    if( (rLineWidth.getX() != rLineWidth.getY())
+    && !basegfx::fTools::equalZero( rLineWidth.getY() ) )
+    {
+        // prepare for createAreaGeometry() with anisotropic linewidth
+        aPolygon.transform( basegfx::tools::createScaleB2DHomMatrix(1.0, rLineWidth.getX() / rLineWidth.getY()));
+    }
+
+    // create the area-polygon for the line
+    const basegfx::B2DPolyPolygon aAreaPolyPoly( basegfx::tools::createAreaGeometry(aPolygon, fHalfWidth, eLineJoin, eLineCap) );
+
+    if( (rLineWidth.getX() != rLineWidth.getY())
+    && !basegfx::fTools::equalZero( rLineWidth.getX() ) )
+    {
+        // postprocess createAreaGeometry() for anisotropic linewidth
+        aPolygon.transform(basegfx::tools::createScaleB2DHomMatrix(1.0, rLineWidth.getY() / rLineWidth.getX()));
+    }
+
+    // draw each area polypolygon component individually
+    // to emulate the polypolygon winding rule "non-zero"
+    const int nPolyCount = aAreaPolyPoly.count();
+    for( int nPolyIdx = 0; nPolyIdx < nPolyCount; ++nPolyIdx )
+    {
+        const ::basegfx::B2DPolyPolygon aOnePoly( aAreaPolyPoly.getB2DPolygon( nPolyIdx ) );
+        bDrawnOk = drawPolyPolygon( aOnePoly, fTransparency );
+        if( !bDrawnOk )
+            break;
+    }
+
+    // restore the original brush GC
+    nBrushColor_ = aKeepBrushColor;
+    return bDrawnOk;
+}
+
+SalColor X11SalGraphicsImpl::getPixel( long nX, long nY )
+{
+    if( mrParent.bWindow_ && !mrParent.bVirDev_ )
+    {
+        XWindowAttributes aAttrib;
+
+        XGetWindowAttributes( mrParent.GetXDisplay(), mrParent.GetDrawable(), &aAttrib );
+        if( aAttrib.map_state != IsViewable )
+        {
+            stderr0( "X11SalGraphics::GetPixel drawable not viewable\n" );
+            return 0;
+        }
+    }
+
+    XImage *pXImage = XGetImage( mrParent.GetXDisplay(),
+                                     mrParent.GetDrawable(),
+                                 nX, nY,
+                                 1,  1,
+                                 AllPlanes,
+                                 ZPixmap );
+    if( !pXImage )
+    {
+        stderr0( "X11SalGraphics::GetPixel !XGetImage()\n" );
+        return 0;
+    }
+
+    XColor aXColor;
+
+    aXColor.pixel = XGetPixel( pXImage, 0, 0 );
+    XDestroyImage( pXImage );
+
+    return mrParent.GetColormap().GetColor( aXColor.pixel );
+}
+
+SalBitmap *X11SalGraphicsImpl::getBitmap( long nX, long nY, long nDX, long nDY )
+{
+    if( mrParent.bPrinter_ && !mrParent.bVirDev_ )
+        return NULL;
+
+    bool bFakeWindowBG = false;
+
+    // normalize
+    if( nDX < 0 )
+    {
+        nX += nDX;
+        nDX = -nDX;
+    }
+    if ( nDY < 0 )
+    {
+        nY += nDY;
+        nDY = -nDY;
+    }
+
+    if( mrParent.bWindow_ && !mrParent.bVirDev_ )
+    {
+        XWindowAttributes aAttrib;
+
+        XGetWindowAttributes( mrParent.GetXDisplay(), mrParent.GetDrawable(), &aAttrib );
+        if( aAttrib.map_state != IsViewable )
+            bFakeWindowBG = true;
+        else
+        {
+            long nOrgDX = nDX, nOrgDY = nDY;
+
+            // clip to window size
+            if ( nX < 0 )
+            {
+                nDX += nX;
+                nX   = 0;
+            }
+            if ( nY < 0 )
+            {
+                nDY += nY;
+                nY   = 0;
+            }
+            if( nX + nDX > aAttrib.width )
+                nDX = aAttrib.width  - nX;
+            if( nY + nDY > aAttrib.height )
+                nDY = aAttrib.height - nY;
+
+            // inside ?
+            if( nDX <= 0 || nDY <= 0 )
+            {
+                bFakeWindowBG = true;
+                nDX = nOrgDX;
+                nDY = nOrgDY;
+            }
+        }
+    }
+
+    X11SalBitmap* pSalBitmap = new X11SalBitmap;
+    sal_uInt16 nBitCount = GetBitCount();
+
+    if( &mrParent.GetDisplay()->GetColormap( mrParent.m_nXScreen ) != &mrParent.GetColormap() )
+        nBitCount = 1;
+
+    if( ! bFakeWindowBG )
+        pSalBitmap->ImplCreateFromDrawable( mrParent.GetDrawable(), mrParent.m_nXScreen, nBitCount, nX, nY, nDX, nDY );
+    else
+        pSalBitmap->Create( Size( nDX, nDY ), (nBitCount > 8) ? 24 : nBitCount, BitmapPalette( nBitCount > 8 ? nBitCount : 0 ) );
+
+    return pSalBitmap;
+}
+
+sal_uInt16 X11SalGraphicsImpl::GetBitCount() const
+{
+    return mrParent.GetVisual().GetDepth();
+}
+
+long X11SalGraphicsImpl::GetGraphicsWidth() const
+{
+    if( mrParent.m_pFrame )
+        return mrParent.m_pFrame->maGeometry.nWidth;
+    else if( mrParent.m_pVDev )
+        return mrParent.m_pVDev->GetWidth();
+    else
+        return 0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/generic/gdi/gdiimpl.hxx b/vcl/unx/generic/gdi/gdiimpl.hxx
new file mode 100644
index 0000000..86990f5
--- /dev/null
+++ b/vcl/unx/generic/gdi/gdiimpl.hxx
@@ -0,0 +1,262 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <prex.h>
+#include <postx.h>
+
+#include "unx/saltype.h"
+
+#include "salgdiimpl.hxx"
+
+#include <basegfx/polygon/b2dtrapezoid.hxx>
+
+class SalGraphics;
+class SalBitmap;
+class SalPolyLine;
+class X11SalGraphics;
+
+class X11SalGraphicsImpl : public SalGraphicsImpl
+{
+private:
+    X11SalGraphics& mrParent;
+
+    SalColor nBrushColor_;
+    GC pBrushGC_;      // Brush attributes
+    Pixel nBrushPixel_;
+
+    bool bPenGC_ : 1;        // is Pen GC valid
+    bool bBrushGC_ : 1;      // is Brush GC valid
+    bool bMonoGC_ : 1;       // is Mono GC valid
+    bool bCopyGC_ : 1;       // is Copy GC valid
+    bool bInvertGC_ : 1;     // is Invert GC valid
+    bool bInvert50GC_ : 1;   // is Invert50 GC valid
+    bool bStippleGC_ : 1;    // is Stipple GC valid
+    bool bTrackingGC_ : 1;   // is Tracking GC valid
+    bool bDitherBrush_ : 1;  // is solid or tile
+
+    bool bXORMode_ : 1;      // is ROP XOR Mode set
+
+    GC pPenGC_;        // Pen attributes
+    SalColor nPenColor_;
+    Pixel nPenPixel_;
+
+
+    GC pMonoGC_;
+    GC pCopyGC_;
+    GC pMaskGC_;
+    GC pInvertGC_;
+    GC pInvert50GC_;
+    GC pStippleGC_;
+    GC pTrackingGC_;
+
+    GC CreateGC( Drawable      hDrawable,
+            unsigned long nMask = GCGraphicsExposures );
+
+    GC SelectBrush();
+    GC SelectPen();
+    inline GC GetCopyGC();
+    inline GC GetStippleGC();
+    GC GetTrackingGC();
+    GC GetInvertGC();
+    GC GetInvert50GC();
+    inline GC GetMonoGC( Pixmap hPixmap );
+
+    void DrawLines( sal_uIntPtr              nPoints,
+                               const SalPolyLine &rPoints,
+                               GC                 pGC,
+                               bool bClose
+                               );
+
+    XID GetXRenderPicture();
+    virtual bool drawFilledTrapezoids( const ::basegfx::B2DTrapezoid*, int nTrapCount, double fTransparency );
+
+    virtual long GetGraphicsHeight() const;
+
+    void drawMaskedBitmap( const SalTwoRect& rPosAry,
+                                              const SalBitmap& rSalBitmap,
+                                              const SalBitmap& rTransparentBitmap );
+
+    void drawPolyLine( sal_uInt32 nPoints, const SalPoint* pPtAry, bool bClose );
+
+public:
+
+    X11SalGraphicsImpl(X11SalGraphics& rParent);
+
+    virtual void freeResources() SAL_OVERRIDE;
+
+    virtual ~X11SalGraphicsImpl();
+
+    virtual bool setClipRegion( const vcl::Region& ) SAL_OVERRIDE;
+    //
+    // get the depth of the device
+    virtual sal_uInt16 GetBitCount() const SAL_OVERRIDE;
+
+    // get the width of the device
+    virtual long GetGraphicsWidth() const SAL_OVERRIDE;
+
+    // set the clip region to empty
+    virtual void ResetClipRegion() SAL_OVERRIDE;
+
+    // set the line color to transparent (= don't draw lines)
+
+    virtual void SetLineColor() SAL_OVERRIDE;
+
+    // set the line color to a specific color
+    virtual void SetLineColor( SalColor nSalColor ) SAL_OVERRIDE;
+
+    // set the fill color to transparent (= don't fill)
+    virtual void SetFillColor() SAL_OVERRIDE;
+
+    // set the fill color to a specific color, shapes will be
+    // filled accordingly
+    virtual void SetFillColor( SalColor nSalColor ) SAL_OVERRIDE;
+
+    // enable/disable XOR drawing
+    virtual void SetXORMode( bool bSet, bool bInvertOnly ) SAL_OVERRIDE;
+
+    // set line color for raster operations
+    virtual void SetROPLineColor( SalROPColor nROPColor ) SAL_OVERRIDE;
+
+    // set fill color for raster operations
+    virtual void SetROPFillColor( SalROPColor nROPColor ) SAL_OVERRIDE;
+
+    // draw --> LineColor and FillColor and RasterOp and ClipRegion
+    virtual void drawPixel( long nX, long nY ) SAL_OVERRIDE;
+    virtual void drawPixel( long nX, long nY, SalColor nSalColor ) SAL_OVERRIDE;
+
+    virtual void drawLine( long nX1, long nY1, long nX2, long nY2 ) SAL_OVERRIDE;
+
+    virtual void drawRect( long nX, long nY, long nWidth, long nHeight ) SAL_OVERRIDE;
+
+    virtual void drawPolyLine( sal_uInt32 nPoints, const SalPoint* pPtAry ) SAL_OVERRIDE;
+
+    virtual void drawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry ) SAL_OVERRIDE;
+
+    virtual void drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32* pPoints, PCONSTSALPOINT* pPtAry ) SAL_OVERRIDE;
+    virtual bool drawPolyPolygon( const ::basegfx::B2DPolyPolygon&, double fTransparency ) SAL_OVERRIDE;
+
+    virtual bool drawPolyLine(
+                const ::basegfx::B2DPolygon&,
+                double fTransparency,
+                const ::basegfx::B2DVector& rLineWidths,
+                basegfx::B2DLineJoin,
+                com::sun::star::drawing::LineCap) SAL_OVERRIDE;
+
+    virtual bool drawPolyLineBezier(
+                sal_uInt32 nPoints,
+                const SalPoint* pPtAry,
+                const sal_uInt8* pFlgAry ) SAL_OVERRIDE;
+
+    virtual bool drawPolygonBezier(
+                sal_uInt32 nPoints,
+                const SalPoint* pPtAry,
+                const sal_uInt8* pFlgAry ) SAL_OVERRIDE;
+
+    virtual bool drawPolyPolygonBezier(
+                sal_uInt32 nPoly,
+                const sal_uInt32* pPoints,
+                const SalPoint* const* pPtAry,
+                const sal_uInt8* const* pFlgAry ) SAL_OVERRIDE;
+
+    // CopyArea --> No RasterOp, but ClipRegion
+    virtual void copyArea(
+                long nDestX, long nDestY,
+                long nSrcX, long nSrcY,
+                long nSrcWidth, long nSrcHeight,
+                sal_uInt16 nFlags ) SAL_OVERRIDE;
+
+    // CopyBits and DrawBitmap --> RasterOp and ClipRegion
+    // CopyBits() --> pSrcGraphics == NULL, then CopyBits on same Graphics
+    virtual void copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ) SAL_OVERRIDE;
+
+    virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap ) SAL_OVERRIDE;
+
+    virtual void drawBitmap(
+                const SalTwoRect& rPosAry,
+                const SalBitmap& rSalBitmap,
+                SalColor nTransparentColor ) SAL_OVERRIDE;
+
+    virtual void drawBitmap(
+                const SalTwoRect& rPosAry,
+                const SalBitmap& rSalBitmap,
+                const SalBitmap& rMaskBitmap ) SAL_OVERRIDE;
+
+    virtual void drawMask(
+                const SalTwoRect& rPosAry,
+                const SalBitmap& rSalBitmap,
+                SalColor nMaskColor ) SAL_OVERRIDE;
+
+    virtual SalBitmap* getBitmap( long nX, long nY, long nWidth, long nHeight ) SAL_OVERRIDE;
+
+    virtual SalColor getPixel( long nX, long nY ) SAL_OVERRIDE;
+
+    // invert --> ClipRegion (only Windows or VirDevs)
+    virtual void invert(
+                long nX, long nY,
+                long nWidth, long nHeight,
+                SalInvert nFlags) SAL_OVERRIDE;
+
+    virtual void invert( sal_uInt32 nPoints, const SalPoint* pPtAry, SalInvert nFlags ) SAL_OVERRIDE;
+
+    virtual bool drawEPS(
+                long nX, long nY,
+                long nWidth, long nHeight,
+                void* pPtr,
+                sal_uLong nSize ) SAL_OVERRIDE;
+
+    /** Render bitmap with alpha channel
+
+        @param rSourceBitmap
+        Source bitmap to blit
+
+        @param rAlphaBitmap
+        Alpha channel to use for blitting
+
+        @return true, if the operation succeeded, and false
+        otherwise. In this case, clients should try to emulate alpha
+        compositing themselves
+     */
+    virtual bool drawAlphaBitmap(
+                const SalTwoRect&,
+                const SalBitmap& rSourceBitmap,
+                const SalBitmap& rAlphaBitmap ) SAL_OVERRIDE;
+
+    /** draw transformed bitmap (maybe with alpha) where Null, X, Y define the coordinate system */
+    virtual bool drawTransformedBitmap(
+                const basegfx::B2DPoint& rNull,
+                const basegfx::B2DPoint& rX,
+                const basegfx::B2DPoint& rY,
+                const SalBitmap& rSourceBitmap,
+                const SalBitmap* pAlphaBitmap) SAL_OVERRIDE;
+
+    /** Render solid rectangle with given transparency
+
+        @param nTransparency
+        Transparency value (0-255) to use. 0 blits and opaque, 255 a
+        fully transparent rectangle
+     */
+    virtual bool drawAlphaRect(
+                    long nX, long nY,
+                    long nWidth, long nHeight,
+                    sal_uInt8 nTransparency ) SAL_OVERRIDE;
+
+
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/generic/gdi/salgdi.cxx b/vcl/unx/generic/gdi/salgdi.cxx
index 4441458..539856d 100644
--- a/vcl/unx/generic/gdi/salgdi.cxx
+++ b/vcl/unx/generic/gdi/salgdi.cxx
@@ -50,43 +50,14 @@
 #include "unx/salvd.h"
 #include <unx/x11/xlimits.hxx>
 
+#include "salgdiimpl.hxx"
+
 #include "generic/printergfx.hxx"
 #include "xrender_peer.hxx"
 
-#define STATIC_POINTS 64
-
-class SalPolyLine
-{
-    XPoint Points_[STATIC_POINTS];
-    XPoint *pFirst_;
-public:
-    SalPolyLine(sal_uLong nPoints, const SalPoint *p)
-        : pFirst_(nPoints+1 > STATIC_POINTS ? new XPoint[nPoints+1] : Points_)
-    {
-        for( sal_uLong i = 0; i < nPoints; i++ )
-        {
-            pFirst_[i].x = (short)p[i].mnX;
-            pFirst_[i].y = (short)p[i].mnY;
-        }
-        pFirst_[nPoints] = pFirst_[0]; // close polyline
-    }
-
-    ~SalPolyLine()
-    {
-        if( pFirst_ != Points_ )
-            delete [] pFirst_;
-    }
-
-    XPoint &operator [] ( sal_uLong n ) const
-    {
-        return pFirst_[n];
-    }
-};
-
-#undef STATIC_POINTS
-
 X11SalGraphics::X11SalGraphics()
-    : m_nXScreen( 0 )
+    : m_nXScreen( 0 ),
+    pFontGC_(NULL)
 {
     m_pFrame            = NULL;
     m_pVDev             = NULL;
@@ -99,11 +70,6 @@ X11SalGraphics::X11SalGraphics()
     mpClipRegion            = NULL;
     pPaintRegion_       = NULL;
 
-    pPenGC_         = NULL;
-    nPenPixel_          = 0;
-    nPenColor_          = MAKE_SALCOLOR( 0x00, 0x00, 0x00 ); // Black
-
-    pFontGC_            = NULL;
     for( int i = 0; i < MAX_FALLBACK; ++i )
         mpServerFont[i] = NULL;
 
@@ -116,33 +82,11 @@ X11SalGraphics::X11SalGraphics()
     bDisableGraphite_   = pDisableGraphiteStr && (pDisableGraphiteStr[0]!='0');
 #endif
 
-    pBrushGC_           = NULL;
-    nBrushPixel_            = 0;
-    nBrushColor_        = MAKE_SALCOLOR( 0xFF, 0xFF, 0xFF ); // White
     hBrush_             = None;
 
-    pMonoGC_            = NULL;
-    pCopyGC_            = NULL;
-    pMaskGC_            = NULL;
-    pInvertGC_          = NULL;
-    pInvert50GC_        = NULL;
-    pStippleGC_         = NULL;
-    pTrackingGC_        = NULL;
-
     bWindow_            = false;
     bPrinter_           = false;
     bVirDev_            = false;
-    bPenGC_         = false;
-    bFontGC_            = false;
-    bBrushGC_           = false;
-    bMonoGC_            = false;
-    bCopyGC_            = false;
-    bInvertGC_          = false;
-    bInvert50GC_        = false;
-    bStippleGC_         = false;
-    bTrackingGC_        = false;
-    bXORMode_           = false;
-    bDitherBrush_       = false;
 }
 
 X11SalGraphics::~X11SalGraphics()
@@ -159,23 +103,16 @@ void X11SalGraphics::freeResources()
     if( mpClipRegion ) XDestroyRegion( mpClipRegion ), mpClipRegion = None;
 
     if( hBrush_ )       XFreePixmap( pDisplay, hBrush_ ), hBrush_ = None;
-    if( pPenGC_ )       XFreeGC( pDisplay, pPenGC_ ), pPenGC_ = None;
-    if( pFontGC_ )      XFreeGC( pDisplay, pFontGC_ ), pFontGC_ = None;
-    if( pBrushGC_ )     XFreeGC( pDisplay, pBrushGC_ ), pBrushGC_ = None;
-    if( pMonoGC_ )      XFreeGC( pDisplay, pMonoGC_ ), pMonoGC_ = None;
-    if( pCopyGC_ )      XFreeGC( pDisplay, pCopyGC_ ), pCopyGC_ = None;
-    if( pMaskGC_ )      XFreeGC( pDisplay, pMaskGC_ ), pMaskGC_ = None;
-    if( pInvertGC_ )    XFreeGC( pDisplay, pInvertGC_ ), pInvertGC_ = None;
-    if( pInvert50GC_ )  XFreeGC( pDisplay, pInvert50GC_ ), pInvert50GC_ = None;
-    if( pStippleGC_ )   XFreeGC( pDisplay, pStippleGC_ ), pStippleGC_ = None;
-    if( pTrackingGC_ )  XFreeGC( pDisplay, pTrackingGC_ ), pTrackingGC_ = None;
+    if( pFontGC_ ) XFreeGC( pDisplay, pFontGC_ ), pFontGC_ = None;
     if( m_pDeleteColormap )
         delete m_pDeleteColormap, m_pColormap = m_pDeleteColormap = NULL;
 
     if( m_aXRenderPicture )
         XRenderPeer::GetInstance().FreePicture( m_aXRenderPicture ), m_aXRenderPicture = 0;
 
-    bPenGC_ = bFontGC_ = bBrushGC_ = bMonoGC_ = bCopyGC_ = bInvertGC_ = bInvert50GC_ = bStippleGC_ = bTrackingGC_ = false;
+    bFontGC_ = false;
+
+    mpImpl->freeResources();
 }
 
 void X11SalGraphics::SetDrawable( Drawable aDrawable, SalX11Screen nXScreen )
@@ -202,9 +139,9 @@ void X11SalGraphics::SetDrawable( Drawable aDrawable, SalX11Screen nXScreen )
 
     if( hDrawable_ )
     {
-        nPenPixel_      = GetPixel( nPenColor_ );
+        // nPenPixel_      = GetPixel( nPenColor_ ); // TODO: moggi: FIX ME
         nTextPixel_     = GetPixel( nTextColor_ );
-        nBrushPixel_    = GetPixel( nBrushColor_ );
+        // nBrushPixel_    = GetPixel( nBrushColor_ ); // TODO: moggi: FIX ME
     }
 }
 
@@ -252,146 +189,6 @@ void X11SalGraphics::SetClipRegion( GC pGC, Region pXReg ) const
     }
 }
 
-GC X11SalGraphics::SelectPen()
-{
-    Display *pDisplay = GetXDisplay();
-
-    if( !pPenGC_ )
-    {
-        XGCValues values;
-        values.subwindow_mode       = ClipByChildren;
-        values.fill_rule            = EvenOddRule;      // Pict import/ Gradient
-        values.graphics_exposures   = False;
-
-        pPenGC_ = XCreateGC( pDisplay, hDrawable_,
-                             GCSubwindowMode | GCFillRule | GCGraphicsExposures,
-                             &values );
-    }
-
-    if( !bPenGC_ )
-    {
-        if( nPenColor_ != SALCOLOR_NONE )
-            XSetForeground( pDisplay, pPenGC_, nPenPixel_ );
-        XSetFunction  ( pDisplay, pPenGC_, bXORMode_ ? GXxor : GXcopy );
-        SetClipRegion( pPenGC_ );
-        bPenGC_ = true;
-    }
-
-    return pPenGC_;
-}
-
-GC X11SalGraphics::SelectBrush()
-{
-    Display *pDisplay = GetXDisplay();
-
-    DBG_ASSERT( nBrushColor_ != SALCOLOR_NONE, "Brush Transparent" );
-
-    if( !pBrushGC_ )
-    {
-        XGCValues values;
-        values.subwindow_mode       = ClipByChildren;
-        values.fill_rule            = EvenOddRule;      // Pict import/ Gradient
-        values.graphics_exposures   = False;
-
-        pBrushGC_ = XCreateGC( pDisplay, hDrawable_,
-                               GCSubwindowMode | GCFillRule | GCGraphicsExposures,
-                               &values );
-    }
-
-    if( !bBrushGC_ )
-    {
-        if( !bDitherBrush_ )
-        {
-            XSetFillStyle ( pDisplay, pBrushGC_, FillSolid );
-            XSetForeground( pDisplay, pBrushGC_, nBrushPixel_ );
-            if( bPrinter_ )
-                XSetTile( pDisplay, pBrushGC_, None );
-        }
-        else
-        {
-            // Bug in Sun Solaris 2.5.1, XFillPolygon doesn't always reflect
-            // changes of the tile. PROPERTY_BUG_Tile doesn't fix this !
-            if (GetDisplay()->GetProperties() & PROPERTY_BUG_FillPolygon_Tile)
-                XSetFillStyle ( pDisplay, pBrushGC_, FillSolid );
-
-            XSetFillStyle ( pDisplay, pBrushGC_, FillTiled );
-            XSetTile      ( pDisplay, pBrushGC_, hBrush_ );
-        }
-        XSetFunction  ( pDisplay, pBrushGC_, bXORMode_ ? GXxor : GXcopy );
-        SetClipRegion( pBrushGC_ );
-
-        bBrushGC_ = true;
-    }
-
-    return pBrushGC_;
-}
-
-GC X11SalGraphics::GetTrackingGC()
-{
-    const char    dash_list[2] = {2, 2};
-
-    if( !pTrackingGC_ )
-    {
-        XGCValues     values;
-
-        values.graphics_exposures   = False;
-        values.foreground           = m_pColormap->GetBlackPixel()
-                                      ^ m_pColormap->GetWhitePixel();
-        values.function             = GXxor;
-        values.line_width           = 1;
-        values.line_style           = LineOnOffDash;
-
-        pTrackingGC_ = XCreateGC( GetXDisplay(), GetDrawable(),
-                                  GCGraphicsExposures | GCForeground | GCFunction
-                                  | GCLineWidth | GCLineStyle,
-                                  &values );
-        XSetDashes( GetXDisplay(), pTrackingGC_, 0, dash_list, 2 );
-    }
-
-    if( !bTrackingGC_ )
-    {
-        SetClipRegion( pTrackingGC_ );
-        bTrackingGC_ = true;
-    }
-
-    return pTrackingGC_;
-}
-
-void X11SalGraphics::DrawLines( sal_uLong              nPoints,
-                                const SalPolyLine &rPoints,
-                                GC                 pGC,
-                                bool               bClose
-                                )
-{
-    // calculate how many lines XWindow can draw in one go
-    sal_uLong nMaxLines = (GetDisplay()->GetMaxRequestSize() - sizeof(xPolyPointReq))
-                      / sizeof(xPoint);
-    if( nMaxLines > nPoints ) nMaxLines = nPoints;
-
-    // print all lines that XWindows can draw
-    sal_uLong n;
-    for( n = 0; nPoints - n > nMaxLines; n += nMaxLines - 1 )
-        XDrawLines( GetXDisplay(),
-                    GetDrawable(),
-                    pGC,
-                    &rPoints[n],
-                    nMaxLines,
-                    CoordModeOrigin );
-
-    if( n < nPoints )
-        XDrawLines( GetXDisplay(),
-                    GetDrawable(),
-                    pGC,
-                    &rPoints[n],
-                    nPoints - n,
-                    CoordModeOrigin );
-    if( bClose )
-    {
-        if( rPoints[nPoints-1].x != rPoints[0].x || rPoints[nPoints-1].y != rPoints[0].y )
-            drawLine( rPoints[nPoints-1].x, rPoints[nPoints-1].y, rPoints[0].x, rPoints[0].y );
-    }
-}
-
 // Calculate a dither-pixmap and make a brush of it
 #define P_DELTA         51
 #define DMAP( v, m )    ((v % P_DELTA) > m ? (v / P_DELTA) + 1 : (v / P_DELTA))
@@ -506,493 +303,123 @@ void X11SalGraphics::GetResolution( sal_Int32 &rDPIX, sal_Int32 &rDPIY ) // cons
 
 sal_uInt16 X11SalGraphics::GetBitCount() const
 {
-    return GetVisual().GetDepth();
+    return mpImpl->GetBitCount();
 }
 
 long X11SalGraphics::GetGraphicsWidth() const
 {
-    if( m_pFrame )
-        return m_pFrame->maGeometry.nWidth;
-    else if( m_pVDev )
-        return m_pVDev->GetWidth();
-    else
-        return 0;
-}
-
-long X11SalGraphics::GetGraphicsHeight() const
-{
-    if( m_pFrame )
-        return m_pFrame->maGeometry.nHeight;
-    else if( m_pVDev )
-        return m_pVDev->GetHeight();
-    else
-        return 0;
+    return mpImpl->GetGraphicsWidth();
 }
 
 void X11SalGraphics::ResetClipRegion()
 {
-    if( mpClipRegion )
-    {
-        bPenGC_         = false;
-        bFontGC_        = false;
-        bBrushGC_       = false;
-        bMonoGC_        = false;
-        bCopyGC_        = false;
-        bInvertGC_      = false;
-        bInvert50GC_    = false;
-        bStippleGC_     = false;
-        bTrackingGC_    = false;
-
-        XDestroyRegion( mpClipRegion );
-        mpClipRegion    = NULL;
-    }
+    mpImpl->ResetClipRegion();
 }
 
 bool X11SalGraphics::setClipRegion( const vcl::Region& i_rClip )
 {
-    if( mpClipRegion )
-        XDestroyRegion( mpClipRegion );
-    mpClipRegion = XCreateRegion();
-
-    RectangleVector aRectangles;
-    i_rClip.GetRegionRectangles(aRectangles);
-
-    for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); ++aRectIter)
-    {
-        const long nW(aRectIter->GetWidth());
-
-        if(nW)
-        {
-            const long nH(aRectIter->GetHeight());
-
-            if(nH)
-            {
-                XRectangle aRect;
-
-                aRect.x = (short)aRectIter->Left();
-                aRect.y = (short)aRectIter->Top();
-                aRect.width = (unsigned short)nW;
-                aRect.height = (unsigned short)nH;
-                XUnionRectWithRegion(&aRect, mpClipRegion, mpClipRegion);
-            }
-        }
-    }
-
-    //ImplRegionInfo aInfo;
-    //long nX, nY, nW, nH;
-    //bool bRegionRect = i_rClip.ImplGetFirstRect(aInfo, nX, nY, nW, nH );
-    //while( bRegionRect )
-    //{
-    //    if ( nW && nH )
-    //    {
-    //        XRectangle aRect;
-    //        aRect.x           = (short)nX;
-    //        aRect.y           = (short)nY;
-    //        aRect.width       = (unsigned short)nW;
-    //        aRect.height  = (unsigned short)nH;
-
-    //        XUnionRectWithRegion( &aRect, mpClipRegion, mpClipRegion );
-    //    }
-    //    bRegionRect = i_rClip.ImplGetNextRect( aInfo, nX, nY, nW, nH );
-    //}
-
-    // done, invalidate GCs
-    bPenGC_         = false;
-    bFontGC_        = false;
-    bBrushGC_       = false;
-    bMonoGC_        = false;
-    bCopyGC_        = false;
-    bInvertGC_      = false;
-    bInvert50GC_    = false;
-    bStippleGC_     = false;
-    bTrackingGC_    = false;
-
-    if( XEmptyRegion( mpClipRegion ) )
-    {
-        XDestroyRegion( mpClipRegion );
-        mpClipRegion= NULL;
-    }
-    return true;
+    return mpImpl->setClipRegion( i_rClip );
 }
 
 void X11SalGraphics::SetLineColor()
 {
-    if( nPenColor_ != SALCOLOR_NONE )
-    {
-        nPenColor_      = SALCOLOR_NONE;
-        bPenGC_         = false;
-    }
+    mpImpl->SetLineColor();
 }
 
 void X11SalGraphics::SetLineColor( SalColor nSalColor )
 {
-    if( nPenColor_ != nSalColor )
-    {
-        nPenColor_      = nSalColor;
-        nPenPixel_      = GetPixel( nSalColor );
-        bPenGC_         = false;
-    }
+    mpImpl->SetLineColor( nSalColor );
 }
 
 void X11SalGraphics::SetFillColor()
 {
-    if( nBrushColor_ != SALCOLOR_NONE )
-    {
-        bDitherBrush_   = false;
-        nBrushColor_    = SALCOLOR_NONE;
-        bBrushGC_       = false;
-    }
+    mpImpl->SetFillColor();
 }
 
 void X11SalGraphics::SetFillColor( SalColor nSalColor )
 {
-    if( nBrushColor_ != nSalColor )
-    {
-        bDitherBrush_   = false;
-        nBrushColor_    = nSalColor;
-        nBrushPixel_    = GetPixel( nSalColor );
-        if( TrueColor != GetColormap().GetVisual().GetClass()
-            && GetColormap().GetColor( nBrushPixel_ ) != nBrushColor_
-            && nSalColor != MAKE_SALCOLOR( 0x00, 0x00, 0x00 ) // black
-            && nSalColor != MAKE_SALCOLOR( 0x00, 0x00, 0x80 ) // blue
-            && nSalColor != MAKE_SALCOLOR( 0x00, 0x80, 0x00 ) // green
-            && nSalColor != MAKE_SALCOLOR( 0x00, 0x80, 0x80 ) // cyan
-            && nSalColor != MAKE_SALCOLOR( 0x80, 0x00, 0x00 ) // red
-            && nSalColor != MAKE_SALCOLOR( 0x80, 0x00, 0x80 ) // magenta
-            && nSalColor != MAKE_SALCOLOR( 0x80, 0x80, 0x00 ) // brown
-            && nSalColor != MAKE_SALCOLOR( 0x80, 0x80, 0x80 ) // gray
-            && nSalColor != MAKE_SALCOLOR( 0xC0, 0xC0, 0xC0 ) // light gray
-            && nSalColor != MAKE_SALCOLOR( 0x00, 0x00, 0xFF ) // light blue
-            && nSalColor != MAKE_SALCOLOR( 0x00, 0xFF, 0x00 ) // light green
-            && nSalColor != MAKE_SALCOLOR( 0x00, 0xFF, 0xFF ) // light cyan
-            && nSalColor != MAKE_SALCOLOR( 0xFF, 0x00, 0x00 ) // light red
-            && nSalColor != MAKE_SALCOLOR( 0xFF, 0x00, 0xFF ) // light magenta
-            && nSalColor != MAKE_SALCOLOR( 0xFF, 0xFF, 0x00 ) // light brown
-            && nSalColor != MAKE_SALCOLOR( 0xFF, 0xFF, 0xFF ) )
-            bDitherBrush_ = GetDitherPixmap(nSalColor);
-        bBrushGC_       = false;
-    }
+    mpImpl->SetFillColor( nSalColor );
 }
 
 void X11SalGraphics::SetROPLineColor( SalROPColor nROPColor )
 {
-    switch( nROPColor )
-    {
-        case SAL_ROP_0 : // 0
-            nPenPixel_ = (Pixel)0;
-            break;
-        case SAL_ROP_1 : // 1
-            nPenPixel_ = (Pixel)(1 << GetVisual().GetDepth()) - 1;
-            break;
-        case SAL_ROP_INVERT : // 2
-            nPenPixel_ = (Pixel)(1 << GetVisual().GetDepth()) - 1;
-            break;
-    }
-    nPenColor_  = GetColormap().GetColor( nPenPixel_ );
-    bPenGC_     = false;
+    mpImpl->SetROPLineColor( nROPColor );
 }
 
 void X11SalGraphics::SetROPFillColor( SalROPColor nROPColor )
 {
-    switch( nROPColor )
-    {
-        case SAL_ROP_0 : // 0
-            nBrushPixel_ = (Pixel)0;
-            break;
-        case SAL_ROP_1 : // 1
-            nBrushPixel_ = (Pixel)(1 << GetVisual().GetDepth()) - 1;
-            break;
-        case SAL_ROP_INVERT : // 2
-            nBrushPixel_ = (Pixel)(1 << GetVisual().GetDepth()) - 1;
-            break;
-    }
-    bDitherBrush_   = false;
-    nBrushColor_    = GetColormap().GetColor( nBrushPixel_ );
-    bBrushGC_       = false;
+    mpImpl->SetROPFillColor( nROPColor );
 }
 
-void X11SalGraphics::SetXORMode( bool bSet, bool )
+void X11SalGraphics::SetXORMode( bool bSet, bool bInvertOnly )
 {
-    if( !bXORMode_ == bSet )
-    {
-        bXORMode_   = bSet;

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list