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