summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarkus Mohrhard <markus.mohrhard@collabora.co.uk>2014-10-21 15:15:47 +0200
committerMarkus Mohrhard <markus.mohrhard@collabora.co.uk>2014-10-22 17:23:39 +0200
commit492768e3a4e9d497d4b6784ab59f239301542eea (patch)
tree9ac53d57c8edbc26f433706ecf032893808a92d3
parent68a6645f6d625bcff56ea93294754a9a695b01e0 (diff)
use Impl for unix vcl plugins
Change-Id: I110df787e1d4b817ab6e682fd9bf50a24332fafd
-rw-r--r--vcl/Library_vclplug_gen.mk1
-rw-r--r--vcl/inc/salgdiimpl.hxx22
-rw-r--r--vcl/inc/unx/salgdi.h62
-rw-r--r--vcl/unx/generic/gdi/gdiimpl.cxx1779
-rw-r--r--vcl/unx/generic/gdi/gdiimpl.hxx262
-rw-r--r--vcl/unx/generic/gdi/salgdi.cxx842
-rw-r--r--vcl/unx/generic/gdi/salgdi2.cxx769
7 files changed, 2124 insertions, 1613 deletions
diff --git a/vcl/Library_vclplug_gen.mk b/vcl/Library_vclplug_gen.mk
index c3f00aa4eef2..634fa741caa6 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 58d6c1a7f600..737524002b0b 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 d34c5d1a9d27..0d1a58427505 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 000000000000..e95bee51363f
--- /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 000000000000..86990f5e0fbc
--- /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 4441458578b0..539856d64a18 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;
- bPenGC_ = false;
- bFontGC_ = false;
- bBrushGC_ = false;
- bMonoGC_ = false;
- bCopyGC_ = false;
- bInvertGC_ = false;
- bInvert50GC_ = false;
- bStippleGC_ = false;
- bTrackingGC_ = false;
- }
+ mpImpl->SetXORMode( bSet, bInvertOnly );
}
void X11SalGraphics::drawPixel( long nX, long nY )
{
- if( nPenColor_ != SALCOLOR_NONE )
- XDrawPoint( GetXDisplay(), GetDrawable(), SelectPen(), nX, nY );
+ mpImpl->drawPixel( nX, nY );
}
void X11SalGraphics::drawPixel( long nX, long nY, SalColor nSalColor )
{
- if( nSalColor != SALCOLOR_NONE )
- {
- Display *pDisplay = GetXDisplay();
-
- if( (nPenColor_ == SALCOLOR_NONE) && !bPenGC_ )
- {
- SetLineColor( nSalColor );
- XDrawPoint( pDisplay, GetDrawable(), SelectPen(), nX, nY );
- nPenColor_ = SALCOLOR_NONE;
- bPenGC_ = False;
- }
- else
- {
- GC pGC = SelectPen();
-
- if( nSalColor != nPenColor_ )
- XSetForeground( pDisplay, pGC, GetPixel( nSalColor ) );
-
- XDrawPoint( pDisplay, GetDrawable(), pGC, nX, nY );
-
- if( nSalColor != nPenColor_ )
- XSetForeground( pDisplay, pGC, nPenPixel_ );
- }
- }
+ mpImpl->drawPixel( nX, nY, nSalColor );
}
void X11SalGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 )
{
- if( nPenColor_ != SALCOLOR_NONE )
- {
- if ( GetDisplay()->GetProperties() & PROPERTY_BUG_DrawLine )
- {
- GC aGC = SelectPen();
- XDrawPoint (GetXDisplay(), GetDrawable(), aGC, (int)nX1, (int)nY1);
- XDrawPoint (GetXDisplay(), GetDrawable(), aGC, (int)nX2, (int)nY2);
- XDrawLine (GetXDisplay(), GetDrawable(), aGC, nX1, nY1, nX2, nY2 );
- }
- else
- XDrawLine( GetXDisplay(), GetDrawable(),SelectPen(),
- nX1, nY1, nX2, nY2 );
- }
+ mpImpl->drawLine( nX1, nY1, nX2, nY2 );
}
void X11SalGraphics::drawRect( long nX, long nY, long nDX, long nDY )
{
- if( nBrushColor_ != SALCOLOR_NONE )
- {
- XFillRectangle( GetXDisplay(),
- GetDrawable(),
- SelectBrush(),
- nX, nY, nDX, nDY );
- }
- // description DrawRect is wrong; thus -1
- if( nPenColor_ != SALCOLOR_NONE )
- XDrawRectangle( GetXDisplay(),
- GetDrawable(),
- SelectPen(),
- nX, nY, nDX-1, nDY-1 );
+ mpImpl->drawRect( nX, nY, nDX, nDY );
}
void X11SalGraphics::drawPolyLine( sal_uInt32 nPoints, const SalPoint *pPtAry )
{
- drawPolyLine( nPoints, pPtAry, false );
-}
-
-void X11SalGraphics::drawPolyLine( sal_uInt32 nPoints, const SalPoint *pPtAry, bool bClose )
-{
- if( nPenColor_ != SALCOLOR_NONE )
- {
- SalPolyLine Points( nPoints, pPtAry );
-
- DrawLines( nPoints, Points, SelectPen(), bClose );
- }
+ mpImpl->drawPolyLine( nPoints, pPtAry );
}
void X11SalGraphics::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( GetXDisplay(),
- GetDrawable(),
- SelectBrush(),
- &Points[0], nPoints,
- Complex, CoordModeOrigin );
-
- if( nPenColor_ != SALCOLOR_NONE )
- DrawLines( nPoints, Points, SelectPen(), true );
+ mpImpl->drawPolygon( nPoints, pPtAry );
}
void X11SalGraphics::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();
- SetClipRegion( pGC, pXRegA ); // ??? twice
- XDestroyRegion( pXRegA );
- bBrushGC_ = false;
-
- XFillRectangle( GetXDisplay(),
- 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 );
+ mpImpl->drawPolyPolygon( nPoly, pPoints, pPtAry );
}
-bool X11SalGraphics::drawPolyLineBezier( sal_uInt32, const SalPoint*, const sal_uInt8* )
+bool X11SalGraphics::drawPolyLineBezier( sal_uInt32 nPoints, const SalPoint* pPtAry, const sal_uInt8* pFlgAry )
{
- return false;
+ return mpImpl->drawPolyLineBezier( nPoints, pPtAry, pFlgAry );
}
-bool X11SalGraphics::drawPolygonBezier( sal_uInt32, const SalPoint*, const sal_uInt8* )
+bool X11SalGraphics::drawPolygonBezier( sal_uInt32 nPoints, const SalPoint* pPtAry, const sal_uInt8* pFlgAry )
{
- return false;
+ return mpImpl->drawPolygonBezier( nPoints, pPtAry, pFlgAry );
}
-bool X11SalGraphics::drawPolyPolygonBezier( sal_uInt32, const sal_uInt32*,
- const SalPoint* const*, const sal_uInt8* const* )
+bool X11SalGraphics::drawPolyPolygonBezier( sal_uInt32 nPoints, const sal_uInt32* pPoints,
+ const SalPoint* const* pPtAry, const sal_uInt8* const* pFlgAry)
{
- return false;
+ return mpImpl->drawPolyPolygonBezier( nPoints, pPoints, pPtAry, pFlgAry );
}
void X11SalGraphics::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( GetXDisplay(),
- GetDrawable(),
- pGC,
- &Points[0], nPoints,
- Complex, CoordModeOrigin );
+ mpImpl->invert( nPoints, pPtAry, nFlags );
}
-bool X11SalGraphics::drawEPS( long,long,long,long,void*,sal_uLong )
+bool X11SalGraphics::drawEPS( long nX, long nY, long nWidth,
+ long nHeight, void* pPtr, sal_uLong nSize )
{
- return false;
-}
-
-XID X11SalGraphics::GetXRenderPicture()
-{
- XRenderPeer& rRenderPeer = XRenderPeer::GetInstance();
-
- if( !m_aXRenderPicture )
- {
- // check xrender support for matching visual
- XRenderPictFormat* pXRenderFormat = GetXRenderFormat();
- if( !pXRenderFormat )
- return 0;
- // get the matching xrender target for drawable
- m_aXRenderPicture = rRenderPeer.CreatePicture( hDrawable_, pXRenderFormat, 0, NULL );
- }
-
- {
- // reset clip region
- // TODO: avoid clip reset if already done
- XRenderPictureAttributes aAttr;
- aAttr.clip_mask = None;
- rRenderPeer.ChangePicture( m_aXRenderPicture, CPClipMask, &aAttr );
- }
-
- return m_aXRenderPicture;
+ return mpImpl->drawEPS( nX, nY, nWidth, nHeight, pPtr, nSize );
}
XRenderPictFormat* X11SalGraphics::GetXRenderFormat() const
@@ -1020,114 +447,7 @@ SystemGraphicsData X11SalGraphics::GetGraphicsData() const
// draw a poly-polygon
bool X11SalGraphics::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 = !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;
-}
-
-bool X11SalGraphics::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 = GetDisplay()->GetRenderEntries( m_nXScreen )[ 32 ];
- if( !rEntry.m_aPicture )
- {
- Display* pXDisplay = GetXDisplay();
-
- rEntry.m_aPixmap = limitXCreatePixmap( pXDisplay, 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( mpClipRegion && !XEmptyRegion( mpClipRegion ) )
- rRenderPeer.SetPictureClipRegion( aDstPic, 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;
+ return mpImpl->drawPolyPolygon( rOrigPolyPoly, fTransparency );
}
bool X11SalGraphics::drawPolyLine(
@@ -1137,84 +457,8 @@ bool X11SalGraphics::drawPolyLine(
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;
+ return mpImpl->drawPolyLine( rPolygon, fTransparency, rLineWidth,
+ eLineJoin, eLineCap );
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/generic/gdi/salgdi2.cxx b/vcl/unx/generic/gdi/salgdi2.cxx
index 8059449c1371..aa2732a4ba8f 100644
--- a/vcl/unx/generic/gdi/salgdi2.cxx
+++ b/vcl/unx/generic/gdi/salgdi2.cxx
@@ -19,6 +19,7 @@
#include <stdio.h>
#include <poll.h>
+#include "salgdiimpl.hxx"
#include "vcl/salbtype.hxx"
@@ -38,20 +39,6 @@
#include <outdata.hxx>
#include <boost/scoped_ptr.hpp>
-#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
-
void X11SalGraphics::CopyScreenArea( Display* pDisplay,
Drawable aSrc, SalX11Screen nXScreenSrc, int nSrcDepth,
Drawable aDest, SalX11Screen nXScreenDest, int nDestDepth,
@@ -94,133 +81,6 @@ void X11SalGraphics::CopyScreenArea( Display* pDisplay,
}
}
-GC X11SalGraphics::CreateGC( Drawable hDrawable, unsigned long nMask )
-{
- XGCValues values;
-
- values.graphics_exposures = False;
- values.foreground = m_pColormap->GetBlackPixel()
- ^ m_pColormap->GetWhitePixel();
- values.function = GXxor;
- values.line_width = 1;
- values.fill_style = FillStippled;
- values.stipple = GetDisplay()->GetInvert50( m_nXScreen );
- values.subwindow_mode = ClipByChildren;
-
- return XCreateGC( GetXDisplay(), hDrawable, nMask | GCSubwindowMode, &values );
-}
-
-inline GC X11SalGraphics::GetMonoGC( Pixmap hPixmap )
-{
- if( !pMonoGC_ )
- pMonoGC_ = CreateGC( hPixmap );
-
- if( !bMonoGC_ )
- {
- SetClipRegion( pMonoGC_ );
- bMonoGC_ = true;
- }
-
- return pMonoGC_;
-}
-
-inline GC X11SalGraphics::GetCopyGC()
-{
- if( bXORMode_ ) return GetInvertGC();
-
- if( !pCopyGC_ )
- pCopyGC_ = CreateGC( GetDrawable() );
-
- if( !bCopyGC_ )
- {
- SetClipRegion( pCopyGC_ );
- bCopyGC_ = true;
- }
- return pCopyGC_;
-}
-
-GC X11SalGraphics::GetInvertGC()
-{
- if( !pInvertGC_ )
- pInvertGC_ = CreateGC( GetDrawable(),
- GCGraphicsExposures
- | GCForeground
- | GCFunction
- | GCLineWidth );
-
- if( !bInvertGC_ )
- {
- SetClipRegion( pInvertGC_ );
- bInvertGC_ = true;
- }
- return pInvertGC_;
-}
-
-GC X11SalGraphics::GetInvert50GC()
-{
- if( !pInvert50GC_ )
- {
- XGCValues values;
-
- values.graphics_exposures = False;
- values.foreground = m_pColormap->GetWhitePixel();
- values.background = 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 = GetDisplay()->GetInvert50( m_nXScreen );
- }
-
- pInvert50GC_ = XCreateGC( GetXDisplay(), GetDrawable(),
- nValueMask,
- &values );
- }
-
- if( !bInvert50GC_ )
- {
- SetClipRegion( pInvert50GC_ );
- bInvert50GC_ = true;
- }
- return pInvert50GC_;
-}
-
-inline GC X11SalGraphics::GetStippleGC()
-{
- if( !pStippleGC_ )
- pStippleGC_ = CreateGC( GetDrawable(),
- GCGraphicsExposures
- | GCFillStyle
- | GCLineWidth );
-
- if( !bStippleGC_ )
- {
- XSetFunction( GetXDisplay(), pStippleGC_, bXORMode_ ? GXxor : GXcopy );
- SetClipRegion( pStippleGC_ );
- bStippleGC_ = true;
- }
-
- return pStippleGC_;
-}
-
extern "C"
{
static Bool GraphicsExposePredicate( Display*, XEvent* pEvent, XPointer pFrameWindow )
@@ -281,456 +141,33 @@ void X11SalGraphics::YieldGraphicsExpose()
void X11SalGraphics::copyBits( const SalTwoRect& rPosAry,
SalGraphics *pSSrcGraphics )
{
- X11SalGraphics* pSrcGraphics = pSSrcGraphics
- ? static_cast<X11SalGraphics*>(pSSrcGraphics)
- : this;
-
- if( rPosAry.mnSrcWidth <= 0
- || rPosAry.mnSrcHeight <= 0
- || rPosAry.mnDestWidth <= 0
- || rPosAry.mnDestHeight <= 0 )
- {
- return;
- }
-
- int n;
- if( pSrcGraphics == this )
- {
- n = 2;
- }
- else if( pSrcGraphics->bWindow_ )
- {
- // window or compatible virtual device
- if( pSrcGraphics->GetDisplay() == GetDisplay() &&
- pSrcGraphics->m_nXScreen == m_nXScreen &&
- pSrcGraphics->GetVisual().GetDepth() == GetVisual().GetDepth()
- )
- n = 2; // same Display
- else
- n = 1; // printer or other display
- }
- else if( pSrcGraphics->bVirDev_ )
- {
- // printer compatible virtual device
- if( 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 == this &&
- !bVirDev_ &&
- pSrcGraphics->bWindow_ );
-
- GC pCopyGC;
-
- if( bXORMode_
- && !pSrcGraphics->bVirDev_
- && (GetDisplay()->GetProperties() & PROPERTY_BUG_XCopyArea_GXxor) )
- {
- Pixmap hPixmap = limitXCreatePixmap( GetXDisplay(),
- pSrcGraphics->GetDrawable(), // source
- rPosAry.mnSrcWidth, rPosAry.mnSrcHeight,
- pSrcGraphics->GetBitCount() );
-
- pCopyGC = GetDisplay()->GetCopyGC( m_nXScreen );
-
- if( bNeedGraphicsExposures )
- XSetGraphicsExposures( GetXDisplay(),
- pCopyGC,
- True );
-
- XCopyArea( GetXDisplay(),
- pSrcGraphics->GetDrawable(), // source
- hPixmap, // destination
- pCopyGC, // no clipping
- rPosAry.mnSrcX, rPosAry.mnSrcY,
- rPosAry.mnSrcWidth, rPosAry.mnSrcHeight,
- 0, 0 ); // destination
- XCopyArea( GetXDisplay(),
- hPixmap, // source
- GetDrawable(), // destination
- GetInvertGC(), // destination clipping
- 0, 0, // source
- rPosAry.mnSrcWidth, rPosAry.mnSrcHeight,
- rPosAry.mnDestX, rPosAry.mnDestY );
- XFreePixmap( GetXDisplay(), hPixmap );
- }
- else
- {
- pCopyGC = GetCopyGC();
-
- if( bNeedGraphicsExposures )
- XSetGraphicsExposures( GetXDisplay(),
- pCopyGC,
- True );
-
- XCopyArea( GetXDisplay(),
- pSrcGraphics->GetDrawable(), // source
- GetDrawable(), // destination
- pCopyGC, // destination clipping
- rPosAry.mnSrcX, rPosAry.mnSrcY,
- rPosAry.mnSrcWidth, rPosAry.mnSrcHeight,
- rPosAry.mnDestX, rPosAry.mnDestY );
- }
-
- if( bNeedGraphicsExposures )
- {
- YieldGraphicsExpose();
-
- if( pCopyGC )
- XSetGraphicsExposures( 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( "X11SalGraphics::CopyBits from Printer not yet implemented\n" );
- }
+ mpImpl->copyBits( rPosAry, pSSrcGraphics );
}
void X11SalGraphics::copyArea ( long nDestX, long nDestY,
long nSrcX, long nSrcY,
long nSrcWidth, long nSrcHeight,
- sal_uInt16 )
+ sal_uInt16 n )
{
- 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 );
-}
-
-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);
- }
- }
+ mpImpl->copyArea( nDestX, nDestY, nSrcX, nSrcY, nSrcWidth, nSrcHeight, n );
}
void X11SalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap )
{
- const SalDisplay* pSalDisp = GetDisplay();
- Display* pXDisp = pSalDisp->GetDisplay();
- const Drawable aDrawable( GetDrawable() );
- const SalColormap& rColMap = pSalDisp->GetColormap( m_nXScreen );
- const long nDepth = GetDisplay()->GetVisual( 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, m_nXScreen, nDepth, rPosAry, aGC );
-
- if( rSalBitmap.GetBitCount() == 1 )
- XChangeGC( pXDisp, aGC, nValues, &aOldVal );
- XFlush( pXDisp );
+ mpImpl->drawBitmap( rPosAry, rSalBitmap );
}
void X11SalGraphics::drawBitmap( const SalTwoRect& rPosAry,
const SalBitmap& rSrcBitmap,
const SalBitmap& rMaskBitmap )
{
- DBG_ASSERT( !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 X11SalGraphics::drawMaskedBitmap( const SalTwoRect& rPosAry,
- const SalBitmap& rSalBitmap,
- const SalBitmap& rTransBitmap )
-{
- const SalDisplay* pSalDisp = GetDisplay();
- Display* pXDisp = pSalDisp->GetDisplay();
- Drawable aDrawable( 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( m_pVDev ?
- m_pVDev->GetDepth() :
- pSalDisp->GetVisual( 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(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, 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, 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, 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 );
+ mpImpl->drawBitmap( rPosAry, rSrcBitmap, rMaskBitmap );
}
bool X11SalGraphics::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 = GetDisplay();
- const SalVisual& rSalVis = pSalDisp->GetVisual( m_nXScreen );
- Display* pXDisplay = pSalDisp->GetDisplay();
-
- // create source Picture
- int nDepth = m_pVDev ? m_pVDev->GetDepth() : rSalVis.GetDepth();
- const X11SalBitmap& rSrcX11Bmp = static_cast<const X11SalBitmap&>( rSrcBitmap );
- ImplSalDDB* pSrcDDB = rSrcX11Bmp.ImplGetDDB( hDrawable_, 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, 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( mpClipRegion && !XEmptyRegion( mpClipRegion ) )
- rPeer.SetPictureClipRegion( aDstPic, 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;
+ return mpImpl->drawAlphaBitmap( rTR, rSrcBitmap, rAlphaBmp );
}
bool X11SalGraphics::drawTransformedBitmap(
@@ -740,191 +177,37 @@ bool X11SalGraphics::drawTransformedBitmap(
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;
+ return mpImpl->drawTransformedBitmap( rNull, rX, rY, rSourceBitmap, pAlphaBitmap );
}
bool X11SalGraphics::drawAlphaRect( long nX, long nY, long nWidth,
long nHeight, sal_uInt8 nTransparency )
{
- if( ! m_pFrame && ! m_pVDev )
- return false;
-
- if( bPenGC_ || !bBrushGC_ || bXORMode_ )
- return false; // can only perform solid fills without XOR.
-
- if( m_pVDev && 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;
+ return mpImpl->drawAlphaRect( nX, nY, nWidth, nHeight, nTransparency );
}
-void X11SalGraphics::drawBitmap( const SalTwoRect&,
- const SalBitmap&,
- SalColor )
+void X11SalGraphics::drawBitmap( const SalTwoRect& rRect,
+ const SalBitmap& rBitmap,
+ SalColor nColor )
{
- OSL_FAIL( "::DrawBitmap with transparent color not supported" );
+ mpImpl->drawBitmap( rRect, rBitmap, nColor );
}
void X11SalGraphics::drawMask( const SalTwoRect& rPosAry,
const SalBitmap &rSalBitmap,
SalColor nMaskColor )
{
- const SalDisplay* pSalDisp = GetDisplay();
- Display* pXDisp = pSalDisp->GetDisplay();
- Drawable aDrawable( 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, 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, GetPixel( nMaskColor ) );
- XFillRectangle( pXDisp, aDrawable, aStippleGC,
- nX, nY,
- rPosAry.mnDestWidth, rPosAry.mnDestHeight );
- XFreePixmap( pXDisp, aStipple );
- XFlush( pXDisp );
- }
- else
- drawBitmap( rPosAry, rSalBitmap );
+ mpImpl->drawMask( rPosAry, rSalBitmap, nMaskColor );
}
SalBitmap *X11SalGraphics::getBitmap( long nX, long nY, long nDX, long nDY )
{
- if( bPrinter_ && !bVirDev_ )
- return NULL;
-
- bool bFakeWindowBG = false;
-
- // normalize
- if( nDX < 0 )
- {
- nX += nDX;
- nDX = -nDX;
- }
- if ( nDY < 0 )
- {
- nY += nDY;
- nDY = -nDY;
- }
-
- if( bWindow_ && !bVirDev_ )
- {
- XWindowAttributes aAttrib;
-
- XGetWindowAttributes( GetXDisplay(), 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( &GetDisplay()->GetColormap( m_nXScreen ) != &GetColormap() )
- nBitCount = 1;
-
- if( ! bFakeWindowBG )
- pSalBitmap->ImplCreateFromDrawable( GetDrawable(), m_nXScreen, nBitCount, nX, nY, nDX, nDY );
- else
- pSalBitmap->Create( Size( nDX, nDY ), (nBitCount > 8) ? 24 : nBitCount, BitmapPalette( nBitCount > 8 ? nBitCount : 0 ) );
-
- return pSalBitmap;
+ return mpImpl->getBitmap( nX, nY, nDX, nDY );
}
SalColor X11SalGraphics::getPixel( long nX, long nY )
{
- if( bWindow_ && !bVirDev_ )
- {
- XWindowAttributes aAttrib;
-
- XGetWindowAttributes( GetXDisplay(), GetDrawable(), &aAttrib );
- if( aAttrib.map_state != IsViewable )
- {
- stderr0( "X11SalGraphics::GetPixel drawable not viewable\n" );
- return 0;
- }
- }
-
- XImage *pXImage = XGetImage( GetXDisplay(),
- 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 GetColormap().GetColor( aXColor.pixel );
+ return mpImpl->getPixel( nX, nY );
}
void X11SalGraphics::invert( long nX,
@@ -933,25 +216,7 @@ void X11SalGraphics::invert( long nX,
long nDY,
SalInvert nFlags )
{
- GC pGC;
- if( SAL_INVERT_50 & nFlags )
- {
- pGC = GetInvert50GC();
- XFillRectangle( GetXDisplay(), GetDrawable(), pGC, nX, nY, nDX, nDY );
- }
- else
- {
- if ( SAL_INVERT_TRACKFRAME & nFlags )
- {
- pGC = GetTrackingGC();
- XDrawRectangle( GetXDisplay(), GetDrawable(), pGC, nX, nY, nDX, nDY );
- }
- else
- {
- pGC = GetInvertGC();
- XFillRectangle( GetXDisplay(), GetDrawable(), pGC, nX, nY, nDX, nDY );
- }
- }
+ mpImpl->invert( nX, nY, nDX, nDY, nFlags );
}
bool X11SalGraphics::supportsOperation( OutDevSupportType eType ) const