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