xref: /aoo4110/main/vcl/source/gdi/outdev.cxx (revision b1cdbd2c)
1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski 
23*b1cdbd2cSJim Jagielski 
24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove
25*b1cdbd2cSJim Jagielski #include "precompiled_vcl.hxx"
26*b1cdbd2cSJim Jagielski 
27*b1cdbd2cSJim Jagielski #include <tools/ref.hxx>
28*b1cdbd2cSJim Jagielski #include <tools/debug.hxx>
29*b1cdbd2cSJim Jagielski #include <tools/poly.hxx>
30*b1cdbd2cSJim Jagielski 
31*b1cdbd2cSJim Jagielski #include <vcl/svapp.hxx>
32*b1cdbd2cSJim Jagielski #include <vcl/ctrl.hxx>
33*b1cdbd2cSJim Jagielski #include <vcl/region.hxx>
34*b1cdbd2cSJim Jagielski #include <vcl/virdev.hxx>
35*b1cdbd2cSJim Jagielski #include <vcl/window.hxx>
36*b1cdbd2cSJim Jagielski #include <vcl/metaact.hxx>
37*b1cdbd2cSJim Jagielski #include <vcl/gdimtf.hxx>
38*b1cdbd2cSJim Jagielski #include <vcl/print.hxx>
39*b1cdbd2cSJim Jagielski #include <vcl/outdev.hxx>
40*b1cdbd2cSJim Jagielski #include <vcl/unowrap.hxx>
41*b1cdbd2cSJim Jagielski // declare system types in sysdata.hxx
42*b1cdbd2cSJim Jagielski #include <svsys.h>
43*b1cdbd2cSJim Jagielski #include <vcl/sysdata.hxx>
44*b1cdbd2cSJim Jagielski 
45*b1cdbd2cSJim Jagielski #include <salgdi.hxx>
46*b1cdbd2cSJim Jagielski #include <sallayout.hxx>
47*b1cdbd2cSJim Jagielski #include <salframe.hxx>
48*b1cdbd2cSJim Jagielski #include <salvd.hxx>
49*b1cdbd2cSJim Jagielski #include <salprn.hxx>
50*b1cdbd2cSJim Jagielski #include <svdata.hxx>
51*b1cdbd2cSJim Jagielski #include <window.h>
52*b1cdbd2cSJim Jagielski #include <outdev.h>
53*b1cdbd2cSJim Jagielski #include <outdata.hxx>
54*b1cdbd2cSJim Jagielski 
55*b1cdbd2cSJim Jagielski #include <basegfx/point/b2dpoint.hxx>
56*b1cdbd2cSJim Jagielski #include <basegfx/vector/b2dvector.hxx>
57*b1cdbd2cSJim Jagielski #include <basegfx/polygon/b2dpolygon.hxx>
58*b1cdbd2cSJim Jagielski #include <basegfx/polygon/b2dpolypolygon.hxx>
59*b1cdbd2cSJim Jagielski #include <basegfx/matrix/b2dhommatrix.hxx>
60*b1cdbd2cSJim Jagielski #include <basegfx/polygon/b2dpolygontools.hxx>
61*b1cdbd2cSJim Jagielski #include <basegfx/polygon/b2dpolypolygontools.hxx>
62*b1cdbd2cSJim Jagielski #include <basegfx/polygon/b2dlinegeometry.hxx>
63*b1cdbd2cSJim Jagielski 
64*b1cdbd2cSJim Jagielski #include <com/sun/star/awt/XGraphics.hpp>
65*b1cdbd2cSJim Jagielski #include <com/sun/star/uno/Sequence.hxx>
66*b1cdbd2cSJim Jagielski #include <com/sun/star/rendering/XCanvas.hpp>
67*b1cdbd2cSJim Jagielski #include <com/sun/star/lang/XMultiServiceFactory.hpp>
68*b1cdbd2cSJim Jagielski #include <vcl/unohelp.hxx>
69*b1cdbd2cSJim Jagielski 
70*b1cdbd2cSJim Jagielski #include <numeric>
71*b1cdbd2cSJim Jagielski 
72*b1cdbd2cSJim Jagielski using namespace ::com::sun::star;
73*b1cdbd2cSJim Jagielski 
74*b1cdbd2cSJim Jagielski DBG_NAME( OutputDevice )
DBG_NAME(Polygon)75*b1cdbd2cSJim Jagielski DBG_NAME( Polygon )
76*b1cdbd2cSJim Jagielski DBG_NAME( PolyPolygon )
77*b1cdbd2cSJim Jagielski DBG_NAMEEX( Region )
78*b1cdbd2cSJim Jagielski 
79*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
80*b1cdbd2cSJim Jagielski 
81*b1cdbd2cSJim Jagielski #ifdef DBG_UTIL
82*b1cdbd2cSJim Jagielski const char* ImplDbgCheckOutputDevice( const void* pObj )
83*b1cdbd2cSJim Jagielski {
84*b1cdbd2cSJim Jagielski 	DBG_TESTSOLARMUTEX();
85*b1cdbd2cSJim Jagielski 
86*b1cdbd2cSJim Jagielski 	const OutputDevice* pOutDev = (OutputDevice*)pObj;
87*b1cdbd2cSJim Jagielski 
88*b1cdbd2cSJim Jagielski 	if ( (pOutDev->GetOutDevType() != OUTDEV_DONTKNOW) &&
89*b1cdbd2cSJim Jagielski 		 (pOutDev->GetOutDevType() != OUTDEV_WINDOW) &&
90*b1cdbd2cSJim Jagielski 		 (pOutDev->GetOutDevType() != OUTDEV_PRINTER) &&
91*b1cdbd2cSJim Jagielski 		 (pOutDev->GetOutDevType() != OUTDEV_VIRDEV) )
92*b1cdbd2cSJim Jagielski 		return "OutputDevice data overwrite";
93*b1cdbd2cSJim Jagielski 
94*b1cdbd2cSJim Jagielski 	return NULL;
95*b1cdbd2cSJim Jagielski }
96*b1cdbd2cSJim Jagielski #endif
97*b1cdbd2cSJim Jagielski 
98*b1cdbd2cSJim Jagielski // =======================================================================
99*b1cdbd2cSJim Jagielski 
100*b1cdbd2cSJim Jagielski #define OUTDEV_POLYPOLY_STACKBUF		32
101*b1cdbd2cSJim Jagielski 
102*b1cdbd2cSJim Jagielski // =======================================================================
103*b1cdbd2cSJim Jagielski 
104*b1cdbd2cSJim Jagielski struct ImplObjStack
105*b1cdbd2cSJim Jagielski {
106*b1cdbd2cSJim Jagielski     ImplObjStack*   mpPrev;
107*b1cdbd2cSJim Jagielski     MapMode*        mpMapMode;
108*b1cdbd2cSJim Jagielski     bool            mbMapActive;
109*b1cdbd2cSJim Jagielski     Region*         mpClipRegion;
110*b1cdbd2cSJim Jagielski     Color*          mpLineColor;
111*b1cdbd2cSJim Jagielski     Color*          mpFillColor;
112*b1cdbd2cSJim Jagielski     Font*           mpFont;
113*b1cdbd2cSJim Jagielski     Color*          mpTextColor;
114*b1cdbd2cSJim Jagielski     Color*          mpTextFillColor;
115*b1cdbd2cSJim Jagielski     Color*          mpTextLineColor;
116*b1cdbd2cSJim Jagielski     Color*          mpOverlineColor;
117*b1cdbd2cSJim Jagielski     Point*          mpRefPoint;
118*b1cdbd2cSJim Jagielski     TextAlign       meTextAlign;
119*b1cdbd2cSJim Jagielski     RasterOp        meRasterOp;
120*b1cdbd2cSJim Jagielski     sal_uLong           mnTextLayoutMode;
121*b1cdbd2cSJim Jagielski     LanguageType    meTextLanguage;
122*b1cdbd2cSJim Jagielski     sal_uInt16          mnFlags;
123*b1cdbd2cSJim Jagielski };
124*b1cdbd2cSJim Jagielski 
125*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
126*b1cdbd2cSJim Jagielski 
ImplDeleteObjStack(ImplObjStack * pObjStack)127*b1cdbd2cSJim Jagielski static void ImplDeleteObjStack( ImplObjStack* pObjStack )
128*b1cdbd2cSJim Jagielski {
129*b1cdbd2cSJim Jagielski 	if ( pObjStack->mnFlags & PUSH_LINECOLOR )
130*b1cdbd2cSJim Jagielski 	{
131*b1cdbd2cSJim Jagielski 		if ( pObjStack->mpLineColor )
132*b1cdbd2cSJim Jagielski 			delete pObjStack->mpLineColor;
133*b1cdbd2cSJim Jagielski 	}
134*b1cdbd2cSJim Jagielski 	if ( pObjStack->mnFlags & PUSH_FILLCOLOR )
135*b1cdbd2cSJim Jagielski 	{
136*b1cdbd2cSJim Jagielski 		if ( pObjStack->mpFillColor )
137*b1cdbd2cSJim Jagielski 			delete pObjStack->mpFillColor;
138*b1cdbd2cSJim Jagielski 	}
139*b1cdbd2cSJim Jagielski 	if ( pObjStack->mnFlags & PUSH_FONT )
140*b1cdbd2cSJim Jagielski 		delete pObjStack->mpFont;
141*b1cdbd2cSJim Jagielski 	if ( pObjStack->mnFlags & PUSH_TEXTCOLOR )
142*b1cdbd2cSJim Jagielski 		delete pObjStack->mpTextColor;
143*b1cdbd2cSJim Jagielski 	if ( pObjStack->mnFlags & PUSH_TEXTFILLCOLOR )
144*b1cdbd2cSJim Jagielski 	{
145*b1cdbd2cSJim Jagielski 		if ( pObjStack->mpTextFillColor )
146*b1cdbd2cSJim Jagielski 			delete pObjStack->mpTextFillColor;
147*b1cdbd2cSJim Jagielski 	}
148*b1cdbd2cSJim Jagielski 	if ( pObjStack->mnFlags & PUSH_TEXTLINECOLOR )
149*b1cdbd2cSJim Jagielski 	{
150*b1cdbd2cSJim Jagielski 		if ( pObjStack->mpTextLineColor )
151*b1cdbd2cSJim Jagielski 			delete pObjStack->mpTextLineColor;
152*b1cdbd2cSJim Jagielski 	}
153*b1cdbd2cSJim Jagielski 	if ( pObjStack->mnFlags & PUSH_OVERLINECOLOR )
154*b1cdbd2cSJim Jagielski 	{
155*b1cdbd2cSJim Jagielski 		if ( pObjStack->mpOverlineColor )
156*b1cdbd2cSJim Jagielski 			delete pObjStack->mpOverlineColor;
157*b1cdbd2cSJim Jagielski 	}
158*b1cdbd2cSJim Jagielski 	if ( pObjStack->mnFlags & PUSH_MAPMODE )
159*b1cdbd2cSJim Jagielski 	{
160*b1cdbd2cSJim Jagielski 		if ( pObjStack->mpMapMode )
161*b1cdbd2cSJim Jagielski 			delete pObjStack->mpMapMode;
162*b1cdbd2cSJim Jagielski 	}
163*b1cdbd2cSJim Jagielski 	if ( pObjStack->mnFlags & PUSH_CLIPREGION )
164*b1cdbd2cSJim Jagielski 	{
165*b1cdbd2cSJim Jagielski 		if ( pObjStack->mpClipRegion )
166*b1cdbd2cSJim Jagielski 			delete pObjStack->mpClipRegion;
167*b1cdbd2cSJim Jagielski 	}
168*b1cdbd2cSJim Jagielski 	if ( pObjStack->mnFlags & PUSH_REFPOINT )
169*b1cdbd2cSJim Jagielski 	{
170*b1cdbd2cSJim Jagielski 		if ( pObjStack->mpRefPoint )
171*b1cdbd2cSJim Jagielski 			delete pObjStack->mpRefPoint;
172*b1cdbd2cSJim Jagielski 	}
173*b1cdbd2cSJim Jagielski 
174*b1cdbd2cSJim Jagielski 	delete pObjStack;
175*b1cdbd2cSJim Jagielski }
176*b1cdbd2cSJim Jagielski 
177*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
178*b1cdbd2cSJim Jagielski 
ImplIsAntiparallel() const179*b1cdbd2cSJim Jagielski bool OutputDevice::ImplIsAntiparallel() const
180*b1cdbd2cSJim Jagielski {
181*b1cdbd2cSJim Jagielski     bool bRet = false;
182*b1cdbd2cSJim Jagielski     if( ImplGetGraphics() )
183*b1cdbd2cSJim Jagielski     {
184*b1cdbd2cSJim Jagielski         if( ( (mpGraphics->GetLayout() & SAL_LAYOUT_BIDI_RTL) && ! IsRTLEnabled() ) ||
185*b1cdbd2cSJim Jagielski             ( ! (mpGraphics->GetLayout() & SAL_LAYOUT_BIDI_RTL) && IsRTLEnabled() ) )
186*b1cdbd2cSJim Jagielski         {
187*b1cdbd2cSJim Jagielski             bRet = true;
188*b1cdbd2cSJim Jagielski         }
189*b1cdbd2cSJim Jagielski     }
190*b1cdbd2cSJim Jagielski     return bRet;
191*b1cdbd2cSJim Jagielski }
192*b1cdbd2cSJim Jagielski 
193*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
194*b1cdbd2cSJim Jagielski 
195*b1cdbd2cSJim Jagielski 
ImplSelectClipRegion(const Region & rRegion,SalGraphics * pGraphics)196*b1cdbd2cSJim Jagielski bool OutputDevice::ImplSelectClipRegion( const Region& rRegion, SalGraphics* pGraphics )
197*b1cdbd2cSJim Jagielski {
198*b1cdbd2cSJim Jagielski 	DBG_TESTSOLARMUTEX();
199*b1cdbd2cSJim Jagielski 
200*b1cdbd2cSJim Jagielski 	if( !pGraphics )
201*b1cdbd2cSJim Jagielski 	{
202*b1cdbd2cSJim Jagielski 		if( !mpGraphics )
203*b1cdbd2cSJim Jagielski 			if( !ImplGetGraphics() )
204*b1cdbd2cSJim Jagielski 				return false;
205*b1cdbd2cSJim Jagielski 		pGraphics = mpGraphics;
206*b1cdbd2cSJim Jagielski 	}
207*b1cdbd2cSJim Jagielski 
208*b1cdbd2cSJim Jagielski 	bool bClipRegion = pGraphics->SetClipRegion( rRegion, this );
209*b1cdbd2cSJim Jagielski 	OSL_ENSURE( bClipRegion, "OutputDevice::ImplSelectClipRegion() - can't cerate region" );
210*b1cdbd2cSJim Jagielski 	return bClipRegion;
211*b1cdbd2cSJim Jagielski }
212*b1cdbd2cSJim Jagielski 
213*b1cdbd2cSJim Jagielski 
214*b1cdbd2cSJim Jagielski // =======================================================================
215*b1cdbd2cSJim Jagielski 
ImplSubdivideBezier(const Polygon & rPoly)216*b1cdbd2cSJim Jagielski Polygon ImplSubdivideBezier( const Polygon& rPoly )
217*b1cdbd2cSJim Jagielski {
218*b1cdbd2cSJim Jagielski     Polygon aPoly;
219*b1cdbd2cSJim Jagielski 
220*b1cdbd2cSJim Jagielski     // #100127# Use adaptive subdivide instead of fixed 25 segments
221*b1cdbd2cSJim Jagielski     rPoly.AdaptiveSubdivide( aPoly );
222*b1cdbd2cSJim Jagielski 
223*b1cdbd2cSJim Jagielski     return aPoly;
224*b1cdbd2cSJim Jagielski }
225*b1cdbd2cSJim Jagielski 
226*b1cdbd2cSJim Jagielski // =======================================================================
227*b1cdbd2cSJim Jagielski 
ImplSubdivideBezier(const PolyPolygon & rPolyPoly)228*b1cdbd2cSJim Jagielski PolyPolygon ImplSubdivideBezier( const PolyPolygon& rPolyPoly )
229*b1cdbd2cSJim Jagielski {
230*b1cdbd2cSJim Jagielski     sal_uInt16 i, nPolys = rPolyPoly.Count();
231*b1cdbd2cSJim Jagielski     PolyPolygon aPolyPoly( nPolys );
232*b1cdbd2cSJim Jagielski     for( i=0; i<nPolys; ++i )
233*b1cdbd2cSJim Jagielski         aPolyPoly.Insert( ImplSubdivideBezier( rPolyPoly.GetObject(i) ) );
234*b1cdbd2cSJim Jagielski 
235*b1cdbd2cSJim Jagielski     return aPolyPoly;
236*b1cdbd2cSJim Jagielski }
237*b1cdbd2cSJim Jagielski 
238*b1cdbd2cSJim Jagielski // =======================================================================
239*b1cdbd2cSJim Jagielski 
240*b1cdbd2cSJim Jagielski // #100127# Extracted from OutputDevice::DrawPolyPolygon()
ImplDrawPolyPolygon(sal_uInt16 nPoly,const PolyPolygon & rPolyPoly)241*b1cdbd2cSJim Jagielski void OutputDevice::ImplDrawPolyPolygon( sal_uInt16 nPoly, const PolyPolygon& rPolyPoly )
242*b1cdbd2cSJim Jagielski {
243*b1cdbd2cSJim Jagielski     // AW: This crashes on empty PolyPolygons, avoid that
244*b1cdbd2cSJim Jagielski     if(!nPoly)
245*b1cdbd2cSJim Jagielski         return;
246*b1cdbd2cSJim Jagielski 
247*b1cdbd2cSJim Jagielski     sal_uInt32			aStackAry1[OUTDEV_POLYPOLY_STACKBUF];
248*b1cdbd2cSJim Jagielski     PCONSTSALPOINT		aStackAry2[OUTDEV_POLYPOLY_STACKBUF];
249*b1cdbd2cSJim Jagielski     sal_uInt8*				aStackAry3[OUTDEV_POLYPOLY_STACKBUF];
250*b1cdbd2cSJim Jagielski     sal_uInt32*			pPointAry;
251*b1cdbd2cSJim Jagielski     PCONSTSALPOINT* 	pPointAryAry;
252*b1cdbd2cSJim Jagielski     const sal_uInt8**	 	pFlagAryAry;
253*b1cdbd2cSJim Jagielski     sal_uInt16				i = 0, j = 0, last = 0;
254*b1cdbd2cSJim Jagielski     sal_Bool				bHaveBezier = sal_False;
255*b1cdbd2cSJim Jagielski     if ( nPoly > OUTDEV_POLYPOLY_STACKBUF )
256*b1cdbd2cSJim Jagielski     {
257*b1cdbd2cSJim Jagielski         pPointAry		= new sal_uInt32[nPoly];
258*b1cdbd2cSJim Jagielski         pPointAryAry	= new PCONSTSALPOINT[nPoly];
259*b1cdbd2cSJim Jagielski         pFlagAryAry		= new const sal_uInt8*[nPoly];
260*b1cdbd2cSJim Jagielski     }
261*b1cdbd2cSJim Jagielski     else
262*b1cdbd2cSJim Jagielski     {
263*b1cdbd2cSJim Jagielski         pPointAry		= aStackAry1;
264*b1cdbd2cSJim Jagielski         pPointAryAry	= aStackAry2;
265*b1cdbd2cSJim Jagielski         pFlagAryAry		= (const sal_uInt8**)aStackAry3;
266*b1cdbd2cSJim Jagielski     }
267*b1cdbd2cSJim Jagielski     do
268*b1cdbd2cSJim Jagielski     {
269*b1cdbd2cSJim Jagielski         const Polygon&	rPoly = rPolyPoly.GetObject( i );
270*b1cdbd2cSJim Jagielski         sal_uInt16			nSize = rPoly.GetSize();
271*b1cdbd2cSJim Jagielski         if ( nSize )
272*b1cdbd2cSJim Jagielski         {
273*b1cdbd2cSJim Jagielski             pPointAry[j]	= nSize;
274*b1cdbd2cSJim Jagielski             pPointAryAry[j] = (PCONSTSALPOINT)rPoly.GetConstPointAry();
275*b1cdbd2cSJim Jagielski             pFlagAryAry[j]  = rPoly.GetConstFlagAry();
276*b1cdbd2cSJim Jagielski             last 			= i;
277*b1cdbd2cSJim Jagielski 
278*b1cdbd2cSJim Jagielski             if( pFlagAryAry[j] )
279*b1cdbd2cSJim Jagielski                 bHaveBezier = sal_True;
280*b1cdbd2cSJim Jagielski 
281*b1cdbd2cSJim Jagielski             ++j;
282*b1cdbd2cSJim Jagielski         }
283*b1cdbd2cSJim Jagielski 
284*b1cdbd2cSJim Jagielski         ++i;
285*b1cdbd2cSJim Jagielski     }
286*b1cdbd2cSJim Jagielski     while ( i < nPoly );
287*b1cdbd2cSJim Jagielski 
288*b1cdbd2cSJim Jagielski     if ( j == 1 )
289*b1cdbd2cSJim Jagielski     {
290*b1cdbd2cSJim Jagielski         // #100127# Forward beziers to sal, if any
291*b1cdbd2cSJim Jagielski         if( bHaveBezier )
292*b1cdbd2cSJim Jagielski         {
293*b1cdbd2cSJim Jagielski             if( !mpGraphics->DrawPolygonBezier( *pPointAry, *pPointAryAry, *pFlagAryAry, this ) )
294*b1cdbd2cSJim Jagielski             {
295*b1cdbd2cSJim Jagielski                 Polygon aPoly = ImplSubdivideBezier( rPolyPoly.GetObject( last ) );
296*b1cdbd2cSJim Jagielski                 mpGraphics->DrawPolygon( aPoly.GetSize(), (const SalPoint*)aPoly.GetConstPointAry(), this );
297*b1cdbd2cSJim Jagielski             }
298*b1cdbd2cSJim Jagielski         }
299*b1cdbd2cSJim Jagielski         else
300*b1cdbd2cSJim Jagielski         {
301*b1cdbd2cSJim Jagielski             mpGraphics->DrawPolygon( *pPointAry, *pPointAryAry, this );
302*b1cdbd2cSJim Jagielski         }
303*b1cdbd2cSJim Jagielski     }
304*b1cdbd2cSJim Jagielski     else
305*b1cdbd2cSJim Jagielski     {
306*b1cdbd2cSJim Jagielski         // #100127# Forward beziers to sal, if any
307*b1cdbd2cSJim Jagielski         if( bHaveBezier )
308*b1cdbd2cSJim Jagielski         {
309*b1cdbd2cSJim Jagielski             if( !mpGraphics->DrawPolyPolygonBezier( j, pPointAry, pPointAryAry, pFlagAryAry, this ) )
310*b1cdbd2cSJim Jagielski             {
311*b1cdbd2cSJim Jagielski                 PolyPolygon aPolyPoly = ImplSubdivideBezier( rPolyPoly );
312*b1cdbd2cSJim Jagielski                 ImplDrawPolyPolygon( aPolyPoly.Count(), aPolyPoly );
313*b1cdbd2cSJim Jagielski             }
314*b1cdbd2cSJim Jagielski         }
315*b1cdbd2cSJim Jagielski         else
316*b1cdbd2cSJim Jagielski         {
317*b1cdbd2cSJim Jagielski             mpGraphics->DrawPolyPolygon( j, pPointAry, pPointAryAry, this );
318*b1cdbd2cSJim Jagielski         }
319*b1cdbd2cSJim Jagielski     }
320*b1cdbd2cSJim Jagielski 
321*b1cdbd2cSJim Jagielski     if ( pPointAry != aStackAry1 )
322*b1cdbd2cSJim Jagielski     {
323*b1cdbd2cSJim Jagielski         delete[] pPointAry;
324*b1cdbd2cSJim Jagielski         delete[] pPointAryAry;
325*b1cdbd2cSJim Jagielski         delete[] pFlagAryAry;
326*b1cdbd2cSJim Jagielski     }
327*b1cdbd2cSJim Jagielski }
328*b1cdbd2cSJim Jagielski 
329*b1cdbd2cSJim Jagielski // =======================================================================
330*b1cdbd2cSJim Jagielski 
OutputDevice()331*b1cdbd2cSJim Jagielski OutputDevice::OutputDevice() :
332*b1cdbd2cSJim Jagielski 	maRegion(true),
333*b1cdbd2cSJim Jagielski 	maFillColor( COL_WHITE ),
334*b1cdbd2cSJim Jagielski 	maTextLineColor( COL_TRANSPARENT ),
335*b1cdbd2cSJim Jagielski 	maSettings( Application::GetSettings() )
336*b1cdbd2cSJim Jagielski {
337*b1cdbd2cSJim Jagielski 	DBG_CTOR( OutputDevice, ImplDbgCheckOutputDevice );
338*b1cdbd2cSJim Jagielski 
339*b1cdbd2cSJim Jagielski 	mpGraphics			= NULL;
340*b1cdbd2cSJim Jagielski 	mpUnoGraphicsList	= NULL;
341*b1cdbd2cSJim Jagielski 	mpPrevGraphics		= NULL;
342*b1cdbd2cSJim Jagielski 	mpNextGraphics		= NULL;
343*b1cdbd2cSJim Jagielski 	mpMetaFile			= NULL;
344*b1cdbd2cSJim Jagielski 	mpFontEntry 		= NULL;
345*b1cdbd2cSJim Jagielski 	mpFontCache 		= NULL;
346*b1cdbd2cSJim Jagielski 	mpFontList			= NULL;
347*b1cdbd2cSJim Jagielski 	mpGetDevFontList	= NULL;
348*b1cdbd2cSJim Jagielski 	mpGetDevSizeList	= NULL;
349*b1cdbd2cSJim Jagielski 	mpObjStack			= NULL;
350*b1cdbd2cSJim Jagielski 	mpOutDevData		= NULL;
351*b1cdbd2cSJim Jagielski     mpPDFWriter			= NULL;
352*b1cdbd2cSJim Jagielski     mpAlphaVDev			= NULL;
353*b1cdbd2cSJim Jagielski 	mpExtOutDevData		= NULL;
354*b1cdbd2cSJim Jagielski 	mnOutOffX			= 0;
355*b1cdbd2cSJim Jagielski 	mnOutOffY			= 0;
356*b1cdbd2cSJim Jagielski 	mnOutWidth			= 0;
357*b1cdbd2cSJim Jagielski 	mnOutHeight 		= 0;
358*b1cdbd2cSJim Jagielski 	mnDPIX				= 0;
359*b1cdbd2cSJim Jagielski 	mnDPIY				= 0;
360*b1cdbd2cSJim Jagielski 	mnTextOffX			= 0;
361*b1cdbd2cSJim Jagielski 	mnTextOffY			= 0;
362*b1cdbd2cSJim Jagielski 	mnOutOffOrigX		= 0;
363*b1cdbd2cSJim Jagielski 	mnOutOffLogicX		= 0;
364*b1cdbd2cSJim Jagielski 	mnOutOffOrigY		= 0;
365*b1cdbd2cSJim Jagielski 	mnOutOffLogicY		= 0;
366*b1cdbd2cSJim Jagielski 	mnEmphasisAscent	= 0;
367*b1cdbd2cSJim Jagielski 	mnEmphasisDescent	= 0;
368*b1cdbd2cSJim Jagielski 	mnDrawMode			= 0;
369*b1cdbd2cSJim Jagielski 	mnTextLayoutMode        = TEXT_LAYOUT_DEFAULT;
370*b1cdbd2cSJim Jagielski 	if( Application::GetSettings().GetLayoutRTL() ) //#i84553# tip BiDi preference to RTL
371*b1cdbd2cSJim Jagielski 		mnTextLayoutMode = TEXT_LAYOUT_BIDI_RTL | TEXT_LAYOUT_TEXTORIGIN_LEFT;
372*b1cdbd2cSJim Jagielski 	meOutDevType		= OUTDEV_DONTKNOW;
373*b1cdbd2cSJim Jagielski     meOutDevViewType    = OUTDEV_VIEWTYPE_DONTKNOW;
374*b1cdbd2cSJim Jagielski 	mbMap				= sal_False;
375*b1cdbd2cSJim Jagielski 	mbMapIsDefault		= sal_True;
376*b1cdbd2cSJim Jagielski 	mbClipRegion		= sal_False;
377*b1cdbd2cSJim Jagielski 	mbBackground		= sal_False;
378*b1cdbd2cSJim Jagielski 	mbOutput			= sal_True;
379*b1cdbd2cSJim Jagielski 	mbDevOutput 		= sal_False;
380*b1cdbd2cSJim Jagielski 	mbOutputClipped 	= sal_False;
381*b1cdbd2cSJim Jagielski 	maTextColor 		= Color( COL_BLACK );
382*b1cdbd2cSJim Jagielski 	maOverlineColor 	= Color( COL_TRANSPARENT );
383*b1cdbd2cSJim Jagielski 	meTextAlign 		= maFont.GetAlign();
384*b1cdbd2cSJim Jagielski 	meRasterOp			= ROP_OVERPAINT;
385*b1cdbd2cSJim Jagielski 	mnAntialiasing		= 0;
386*b1cdbd2cSJim Jagielski     meTextLanguage      = 0;  // TODO: get default from configuration?
387*b1cdbd2cSJim Jagielski 	mbLineColor 		= sal_True;
388*b1cdbd2cSJim Jagielski 	mbFillColor 		= sal_True;
389*b1cdbd2cSJim Jagielski 	mbInitLineColor 	= sal_True;
390*b1cdbd2cSJim Jagielski 	mbInitFillColor 	= sal_True;
391*b1cdbd2cSJim Jagielski 	mbInitFont			= sal_True;
392*b1cdbd2cSJim Jagielski 	mbInitTextColor 	= sal_True;
393*b1cdbd2cSJim Jagielski 	mbInitClipRegion	= sal_True;
394*b1cdbd2cSJim Jagielski 	mbClipRegionSet 	= sal_False;
395*b1cdbd2cSJim Jagielski 	mbKerning			= sal_False;
396*b1cdbd2cSJim Jagielski 	mbNewFont			= sal_True;
397*b1cdbd2cSJim Jagielski 	mbTextLines 		= sal_False;
398*b1cdbd2cSJim Jagielski 	mbTextSpecial		= sal_False;
399*b1cdbd2cSJim Jagielski 	mbRefPoint			= sal_False;
400*b1cdbd2cSJim Jagielski     mbEnableRTL         = sal_False;    // mirroring must be explicitly allowed (typically for windows only)
401*b1cdbd2cSJim Jagielski 
402*b1cdbd2cSJim Jagielski 	// struct ImplMapRes
403*b1cdbd2cSJim Jagielski     maMapRes.mnMapOfsX 			= 0;
404*b1cdbd2cSJim Jagielski     maMapRes.mnMapOfsY 			= 0;
405*b1cdbd2cSJim Jagielski     maMapRes.mnMapScNumX 		= 1;
406*b1cdbd2cSJim Jagielski     maMapRes.mnMapScNumY 		= 1;
407*b1cdbd2cSJim Jagielski     maMapRes.mnMapScDenomX 		= 1;
408*b1cdbd2cSJim Jagielski     maMapRes.mnMapScDenomY		= 1;
409*b1cdbd2cSJim Jagielski 	// struct ImplThresholdRes
410*b1cdbd2cSJim Jagielski     maThresRes.mnThresLogToPixX	= 0;
411*b1cdbd2cSJim Jagielski     maThresRes.mnThresLogToPixY	= 0;
412*b1cdbd2cSJim Jagielski     maThresRes.mnThresPixToLogX	= 0;
413*b1cdbd2cSJim Jagielski     maThresRes.mnThresPixToLogY	= 0;
414*b1cdbd2cSJim Jagielski }
415*b1cdbd2cSJim Jagielski 
416*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
417*b1cdbd2cSJim Jagielski 
~OutputDevice()418*b1cdbd2cSJim Jagielski OutputDevice::~OutputDevice()
419*b1cdbd2cSJim Jagielski {
420*b1cdbd2cSJim Jagielski 	DBG_DTOR( OutputDevice, ImplDbgCheckOutputDevice );
421*b1cdbd2cSJim Jagielski 
422*b1cdbd2cSJim Jagielski 	if ( GetUnoGraphicsList() )
423*b1cdbd2cSJim Jagielski 	{
424*b1cdbd2cSJim Jagielski 		UnoWrapperBase* pWrapper = Application::GetUnoWrapper( sal_False );
425*b1cdbd2cSJim Jagielski 		if ( pWrapper )
426*b1cdbd2cSJim Jagielski 			pWrapper->ReleaseAllGraphics( this );
427*b1cdbd2cSJim Jagielski 		delete mpUnoGraphicsList;
428*b1cdbd2cSJim Jagielski 		mpUnoGraphicsList = NULL;
429*b1cdbd2cSJim Jagielski 	}
430*b1cdbd2cSJim Jagielski 
431*b1cdbd2cSJim Jagielski 	if ( mpOutDevData )
432*b1cdbd2cSJim Jagielski 		ImplDeInitOutDevData();
433*b1cdbd2cSJim Jagielski 
434*b1cdbd2cSJim Jagielski 	ImplObjStack* pData = mpObjStack;
435*b1cdbd2cSJim Jagielski 	if ( pData )
436*b1cdbd2cSJim Jagielski 	{
437*b1cdbd2cSJim Jagielski 		DBG_ERRORFILE( "OutputDevice::~OutputDevice(): OutputDevice::Push() calls != OutputDevice::Pop() calls" );
438*b1cdbd2cSJim Jagielski 		while ( pData )
439*b1cdbd2cSJim Jagielski 		{
440*b1cdbd2cSJim Jagielski 			ImplObjStack* pTemp = pData;
441*b1cdbd2cSJim Jagielski 			pData = pData->mpPrev;
442*b1cdbd2cSJim Jagielski 			ImplDeleteObjStack( pTemp );
443*b1cdbd2cSJim Jagielski 		}
444*b1cdbd2cSJim Jagielski 	}
445*b1cdbd2cSJim Jagielski 
446*b1cdbd2cSJim Jagielski     // release the active font instance
447*b1cdbd2cSJim Jagielski     if( mpFontEntry )
448*b1cdbd2cSJim Jagielski         mpFontCache->Release( mpFontEntry );
449*b1cdbd2cSJim Jagielski     // remove cached results of GetDevFontList/GetDevSizeList
450*b1cdbd2cSJim Jagielski     // TODO: use smart pointers for them
451*b1cdbd2cSJim Jagielski     if( mpGetDevFontList )
452*b1cdbd2cSJim Jagielski         delete mpGetDevFontList;
453*b1cdbd2cSJim Jagielski     if( mpGetDevSizeList )
454*b1cdbd2cSJim Jagielski         delete mpGetDevSizeList;
455*b1cdbd2cSJim Jagielski 
456*b1cdbd2cSJim Jagielski     // release ImplFontCache specific to this OutputDevice
457*b1cdbd2cSJim Jagielski     // TODO: refcount ImplFontCache
458*b1cdbd2cSJim Jagielski     if( mpFontCache
459*b1cdbd2cSJim Jagielski     && (mpFontCache != ImplGetSVData()->maGDIData.mpScreenFontCache)
460*b1cdbd2cSJim Jagielski     && (ImplGetSVData()->maGDIData.mpScreenFontCache != NULL) )
461*b1cdbd2cSJim Jagielski     {
462*b1cdbd2cSJim Jagielski         delete mpFontCache;
463*b1cdbd2cSJim Jagielski         mpFontCache = NULL;
464*b1cdbd2cSJim Jagielski     }
465*b1cdbd2cSJim Jagielski 
466*b1cdbd2cSJim Jagielski     // release ImplFontList specific to this OutputDevice
467*b1cdbd2cSJim Jagielski     // TODO: refcount ImplFontList
468*b1cdbd2cSJim Jagielski     if( mpFontList
469*b1cdbd2cSJim Jagielski     && (mpFontList != ImplGetSVData()->maGDIData.mpScreenFontList)
470*b1cdbd2cSJim Jagielski     && (ImplGetSVData()->maGDIData.mpScreenFontList != NULL) )
471*b1cdbd2cSJim Jagielski     {
472*b1cdbd2cSJim Jagielski         mpFontList->Clear();
473*b1cdbd2cSJim Jagielski         delete mpFontList;
474*b1cdbd2cSJim Jagielski         mpFontList = NULL;
475*b1cdbd2cSJim Jagielski     }
476*b1cdbd2cSJim Jagielski 
477*b1cdbd2cSJim Jagielski     delete mpAlphaVDev;
478*b1cdbd2cSJim Jagielski }
479*b1cdbd2cSJim Jagielski 
supportsOperation(OutDevSupportType eType) const480*b1cdbd2cSJim Jagielski bool OutputDevice::supportsOperation( OutDevSupportType eType ) const
481*b1cdbd2cSJim Jagielski {
482*b1cdbd2cSJim Jagielski 	if( !mpGraphics )
483*b1cdbd2cSJim Jagielski 		if( !ImplGetGraphics() )
484*b1cdbd2cSJim Jagielski 			return false;
485*b1cdbd2cSJim Jagielski 	const bool bHasSupport = mpGraphics->supportsOperation( eType );
486*b1cdbd2cSJim Jagielski 	return bHasSupport;
487*b1cdbd2cSJim Jagielski }
488*b1cdbd2cSJim Jagielski 
489*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
490*b1cdbd2cSJim Jagielski 
EnableRTL(sal_Bool bEnable)491*b1cdbd2cSJim Jagielski void OutputDevice::EnableRTL( sal_Bool bEnable )
492*b1cdbd2cSJim Jagielski {
493*b1cdbd2cSJim Jagielski     mbEnableRTL = (bEnable != 0);
494*b1cdbd2cSJim Jagielski     if( meOutDevType == OUTDEV_VIRDEV )
495*b1cdbd2cSJim Jagielski     {
496*b1cdbd2cSJim Jagielski         // virdevs default to not mirroring, they will only be set to mirroring
497*b1cdbd2cSJim Jagielski         // under rare circumstances in the UI, eg the valueset control
498*b1cdbd2cSJim Jagielski         // because each virdev has its own SalGraphics we can safely switch the SalGraphics here
499*b1cdbd2cSJim Jagielski         // ...hopefully
500*b1cdbd2cSJim Jagielski         if( ImplGetGraphics() )
501*b1cdbd2cSJim Jagielski             mpGraphics->SetLayout( mbEnableRTL ? SAL_LAYOUT_BIDI_RTL : 0 );
502*b1cdbd2cSJim Jagielski     }
503*b1cdbd2cSJim Jagielski 
504*b1cdbd2cSJim Jagielski     // convenience: for controls also switch layout mode
505*b1cdbd2cSJim Jagielski     if( dynamic_cast<Control*>(this) != 0 )
506*b1cdbd2cSJim Jagielski         SetLayoutMode( bEnable ? TEXT_LAYOUT_BIDI_RTL | TEXT_LAYOUT_TEXTORIGIN_LEFT : TEXT_LAYOUT_BIDI_LTR | TEXT_LAYOUT_TEXTORIGIN_LEFT);
507*b1cdbd2cSJim Jagielski 
508*b1cdbd2cSJim Jagielski     Window* pWin = dynamic_cast<Window*>(this);
509*b1cdbd2cSJim Jagielski     if( pWin )
510*b1cdbd2cSJim Jagielski         pWin->StateChanged( STATE_CHANGE_MIRRORING );
511*b1cdbd2cSJim Jagielski 
512*b1cdbd2cSJim Jagielski     if( mpAlphaVDev )
513*b1cdbd2cSJim Jagielski         mpAlphaVDev->EnableRTL( bEnable );
514*b1cdbd2cSJim Jagielski }
515*b1cdbd2cSJim Jagielski 
ImplHasMirroredGraphics()516*b1cdbd2cSJim Jagielski sal_Bool OutputDevice::ImplHasMirroredGraphics()
517*b1cdbd2cSJim Jagielski {
518*b1cdbd2cSJim Jagielski    // HOTFIX for #i55719#
519*b1cdbd2cSJim Jagielski    if( meOutDevType == OUTDEV_PRINTER )
520*b1cdbd2cSJim Jagielski        return sal_False;
521*b1cdbd2cSJim Jagielski 
522*b1cdbd2cSJim Jagielski    return ( ImplGetGraphics() && (mpGraphics->GetLayout() & SAL_LAYOUT_BIDI_RTL) );
523*b1cdbd2cSJim Jagielski }
524*b1cdbd2cSJim Jagielski 
525*b1cdbd2cSJim Jagielski // note: the coordiantes to be remirrored are in frame coordiantes !
526*b1cdbd2cSJim Jagielski 
ImplReMirror(Point & rPoint) const527*b1cdbd2cSJim Jagielski void    OutputDevice::ImplReMirror( Point &rPoint ) const
528*b1cdbd2cSJim Jagielski {
529*b1cdbd2cSJim Jagielski     rPoint.X() = mnOutOffX + mnOutWidth - 1 - rPoint.X() + mnOutOffX;
530*b1cdbd2cSJim Jagielski }
ImplReMirror(Rectangle & rRect) const531*b1cdbd2cSJim Jagielski void    OutputDevice::ImplReMirror( Rectangle &rRect ) const
532*b1cdbd2cSJim Jagielski {
533*b1cdbd2cSJim Jagielski     long nWidth = rRect.nRight - rRect.nLeft;
534*b1cdbd2cSJim Jagielski 
535*b1cdbd2cSJim Jagielski     //long lc_x = rRect.nLeft - mnOutOffX;    // normalize
536*b1cdbd2cSJim Jagielski     //lc_x = mnOutWidth - nWidth - 1 - lc_x;  // mirror
537*b1cdbd2cSJim Jagielski     //rRect.nLeft = lc_x + mnOutOffX;         // re-normalize
538*b1cdbd2cSJim Jagielski 
539*b1cdbd2cSJim Jagielski     rRect.nLeft = mnOutOffX + mnOutWidth - nWidth - 1 - rRect.nLeft + mnOutOffX;
540*b1cdbd2cSJim Jagielski     rRect.nRight = rRect.nLeft + nWidth;
541*b1cdbd2cSJim Jagielski }
ImplReMirror(Region & rRegion) const542*b1cdbd2cSJim Jagielski void    OutputDevice::ImplReMirror( Region &rRegion ) const
543*b1cdbd2cSJim Jagielski {
544*b1cdbd2cSJim Jagielski     RectangleVector aRectangles;
545*b1cdbd2cSJim Jagielski     rRegion.GetRegionRectangles(aRectangles);
546*b1cdbd2cSJim Jagielski     Region aMirroredRegion;
547*b1cdbd2cSJim Jagielski 
548*b1cdbd2cSJim Jagielski     for(RectangleVector::iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
549*b1cdbd2cSJim Jagielski     {
550*b1cdbd2cSJim Jagielski         ImplReMirror(*aRectIter);
551*b1cdbd2cSJim Jagielski         aMirroredRegion.Union(*aRectIter);
552*b1cdbd2cSJim Jagielski     }
553*b1cdbd2cSJim Jagielski 
554*b1cdbd2cSJim Jagielski     rRegion = aMirroredRegion;
555*b1cdbd2cSJim Jagielski 
556*b1cdbd2cSJim Jagielski //	long				nX;
557*b1cdbd2cSJim Jagielski //	long				nY;
558*b1cdbd2cSJim Jagielski //	long				nWidth;
559*b1cdbd2cSJim Jagielski //	long				nHeight;
560*b1cdbd2cSJim Jagielski //	ImplRegionInfo		aInfo;
561*b1cdbd2cSJim Jagielski //	sal_Bool				bRegionRect;
562*b1cdbd2cSJim Jagielski //    Region              aMirroredRegion;
563*b1cdbd2cSJim Jagielski //
564*b1cdbd2cSJim Jagielski //	bRegionRect = rRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
565*b1cdbd2cSJim Jagielski //	while ( bRegionRect )
566*b1cdbd2cSJim Jagielski //	{
567*b1cdbd2cSJim Jagielski //        Rectangle aRect( Point(nX, nY), Size(nWidth, nHeight) );
568*b1cdbd2cSJim Jagielski //        ImplReMirror( aRect );
569*b1cdbd2cSJim Jagielski //        aMirroredRegion.Union( aRect );
570*b1cdbd2cSJim Jagielski //		bRegionRect = rRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
571*b1cdbd2cSJim Jagielski //	}
572*b1cdbd2cSJim Jagielski //    rRegion = aMirroredRegion;
573*b1cdbd2cSJim Jagielski }
574*b1cdbd2cSJim Jagielski 
575*b1cdbd2cSJim Jagielski 
576*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
577*b1cdbd2cSJim Jagielski 
ImplGetGraphics() const578*b1cdbd2cSJim Jagielski int OutputDevice::ImplGetGraphics() const
579*b1cdbd2cSJim Jagielski {
580*b1cdbd2cSJim Jagielski 	DBG_TESTSOLARMUTEX();
581*b1cdbd2cSJim Jagielski 
582*b1cdbd2cSJim Jagielski 	if ( mpGraphics )
583*b1cdbd2cSJim Jagielski 		return sal_True;
584*b1cdbd2cSJim Jagielski 
585*b1cdbd2cSJim Jagielski 	mbInitLineColor 	= sal_True;
586*b1cdbd2cSJim Jagielski 	mbInitFillColor 	= sal_True;
587*b1cdbd2cSJim Jagielski 	mbInitFont			= sal_True;
588*b1cdbd2cSJim Jagielski 	mbInitTextColor 	= sal_True;
589*b1cdbd2cSJim Jagielski 	mbInitClipRegion	= sal_True;
590*b1cdbd2cSJim Jagielski 
591*b1cdbd2cSJim Jagielski 	ImplSVData* pSVData = ImplGetSVData();
592*b1cdbd2cSJim Jagielski 	if ( meOutDevType == OUTDEV_WINDOW )
593*b1cdbd2cSJim Jagielski 	{
594*b1cdbd2cSJim Jagielski 		Window* pWindow = (Window*)this;
595*b1cdbd2cSJim Jagielski 
596*b1cdbd2cSJim Jagielski 		mpGraphics = pWindow->mpWindowImpl->mpFrame->GetGraphics();
597*b1cdbd2cSJim Jagielski         // try harder if no wingraphics was available directly
598*b1cdbd2cSJim Jagielski 		if ( !mpGraphics )
599*b1cdbd2cSJim Jagielski 		{
600*b1cdbd2cSJim Jagielski             // find another output device in the same frame
601*b1cdbd2cSJim Jagielski 			OutputDevice* pReleaseOutDev = pSVData->maGDIData.mpLastWinGraphics;
602*b1cdbd2cSJim Jagielski 			while ( pReleaseOutDev )
603*b1cdbd2cSJim Jagielski 			{
604*b1cdbd2cSJim Jagielski 				if ( ((Window*)pReleaseOutDev)->mpWindowImpl->mpFrame == pWindow->mpWindowImpl->mpFrame )
605*b1cdbd2cSJim Jagielski 					break;
606*b1cdbd2cSJim Jagielski 				pReleaseOutDev = pReleaseOutDev->mpPrevGraphics;
607*b1cdbd2cSJim Jagielski 			}
608*b1cdbd2cSJim Jagielski 
609*b1cdbd2cSJim Jagielski 			if ( pReleaseOutDev )
610*b1cdbd2cSJim Jagielski 			{
611*b1cdbd2cSJim Jagielski                 // steal the wingraphics from the other outdev
612*b1cdbd2cSJim Jagielski 				mpGraphics = pReleaseOutDev->mpGraphics;
613*b1cdbd2cSJim Jagielski 				pReleaseOutDev->ImplReleaseGraphics( sal_False );
614*b1cdbd2cSJim Jagielski 			}
615*b1cdbd2cSJim Jagielski 			else
616*b1cdbd2cSJim Jagielski 			{
617*b1cdbd2cSJim Jagielski                 // if needed retry after releasing least recently used wingraphics
618*b1cdbd2cSJim Jagielski 				while ( !mpGraphics )
619*b1cdbd2cSJim Jagielski 				{
620*b1cdbd2cSJim Jagielski 					if ( !pSVData->maGDIData.mpLastWinGraphics )
621*b1cdbd2cSJim Jagielski 						break;
622*b1cdbd2cSJim Jagielski 					pSVData->maGDIData.mpLastWinGraphics->ImplReleaseGraphics();
623*b1cdbd2cSJim Jagielski 					mpGraphics = pWindow->mpWindowImpl->mpFrame->GetGraphics();
624*b1cdbd2cSJim Jagielski 				}
625*b1cdbd2cSJim Jagielski 			}
626*b1cdbd2cSJim Jagielski 		}
627*b1cdbd2cSJim Jagielski 
628*b1cdbd2cSJim Jagielski         // update global LRU list of wingraphics
629*b1cdbd2cSJim Jagielski 		if ( mpGraphics )
630*b1cdbd2cSJim Jagielski 		{
631*b1cdbd2cSJim Jagielski 			mpNextGraphics = pSVData->maGDIData.mpFirstWinGraphics;
632*b1cdbd2cSJim Jagielski 			pSVData->maGDIData.mpFirstWinGraphics = const_cast<OutputDevice*>(this);
633*b1cdbd2cSJim Jagielski 			if ( mpNextGraphics )
634*b1cdbd2cSJim Jagielski 				mpNextGraphics->mpPrevGraphics = const_cast<OutputDevice*>(this);
635*b1cdbd2cSJim Jagielski 			if ( !pSVData->maGDIData.mpLastWinGraphics )
636*b1cdbd2cSJim Jagielski 				pSVData->maGDIData.mpLastWinGraphics = const_cast<OutputDevice*>(this);
637*b1cdbd2cSJim Jagielski 		}
638*b1cdbd2cSJim Jagielski 	}
639*b1cdbd2cSJim Jagielski 	else if ( meOutDevType == OUTDEV_VIRDEV )
640*b1cdbd2cSJim Jagielski 	{
641*b1cdbd2cSJim Jagielski 		const VirtualDevice* pVirDev = (const VirtualDevice*)this;
642*b1cdbd2cSJim Jagielski 
643*b1cdbd2cSJim Jagielski 		if ( pVirDev->mpVirDev )
644*b1cdbd2cSJim Jagielski 		{
645*b1cdbd2cSJim Jagielski 			mpGraphics = pVirDev->mpVirDev->GetGraphics();
646*b1cdbd2cSJim Jagielski             // if needed retry after releasing least recently used virtual device graphics
647*b1cdbd2cSJim Jagielski 			while ( !mpGraphics )
648*b1cdbd2cSJim Jagielski 			{
649*b1cdbd2cSJim Jagielski 				if ( !pSVData->maGDIData.mpLastVirGraphics )
650*b1cdbd2cSJim Jagielski 					break;
651*b1cdbd2cSJim Jagielski 				pSVData->maGDIData.mpLastVirGraphics->ImplReleaseGraphics();
652*b1cdbd2cSJim Jagielski 				mpGraphics = pVirDev->mpVirDev->GetGraphics();
653*b1cdbd2cSJim Jagielski 			}
654*b1cdbd2cSJim Jagielski             // update global LRU list of virtual device graphics
655*b1cdbd2cSJim Jagielski 			if ( mpGraphics )
656*b1cdbd2cSJim Jagielski 			{
657*b1cdbd2cSJim Jagielski 				mpNextGraphics = pSVData->maGDIData.mpFirstVirGraphics;
658*b1cdbd2cSJim Jagielski 				pSVData->maGDIData.mpFirstVirGraphics = const_cast<OutputDevice*>(this);
659*b1cdbd2cSJim Jagielski 				if ( mpNextGraphics )
660*b1cdbd2cSJim Jagielski 					mpNextGraphics->mpPrevGraphics = const_cast<OutputDevice*>(this);
661*b1cdbd2cSJim Jagielski 				if ( !pSVData->maGDIData.mpLastVirGraphics )
662*b1cdbd2cSJim Jagielski 					pSVData->maGDIData.mpLastVirGraphics = const_cast<OutputDevice*>(this);
663*b1cdbd2cSJim Jagielski 			}
664*b1cdbd2cSJim Jagielski 		}
665*b1cdbd2cSJim Jagielski 	}
666*b1cdbd2cSJim Jagielski 	else if ( meOutDevType == OUTDEV_PRINTER )
667*b1cdbd2cSJim Jagielski 	{
668*b1cdbd2cSJim Jagielski 		const Printer* pPrinter = (const Printer*)this;
669*b1cdbd2cSJim Jagielski 
670*b1cdbd2cSJim Jagielski 		if ( pPrinter->mpJobGraphics )
671*b1cdbd2cSJim Jagielski 			mpGraphics = pPrinter->mpJobGraphics;
672*b1cdbd2cSJim Jagielski 		else if ( pPrinter->mpDisplayDev )
673*b1cdbd2cSJim Jagielski 		{
674*b1cdbd2cSJim Jagielski 			const VirtualDevice* pVirDev = pPrinter->mpDisplayDev;
675*b1cdbd2cSJim Jagielski 			mpGraphics = pVirDev->mpVirDev->GetGraphics();
676*b1cdbd2cSJim Jagielski             // if needed retry after releasing least recently used virtual device graphics
677*b1cdbd2cSJim Jagielski 			while ( !mpGraphics )
678*b1cdbd2cSJim Jagielski 			{
679*b1cdbd2cSJim Jagielski 				if ( !pSVData->maGDIData.mpLastVirGraphics )
680*b1cdbd2cSJim Jagielski 					break;
681*b1cdbd2cSJim Jagielski 				pSVData->maGDIData.mpLastVirGraphics->ImplReleaseGraphics();
682*b1cdbd2cSJim Jagielski 				mpGraphics = pVirDev->mpVirDev->GetGraphics();
683*b1cdbd2cSJim Jagielski 			}
684*b1cdbd2cSJim Jagielski             // update global LRU list of virtual device graphics
685*b1cdbd2cSJim Jagielski 			if ( mpGraphics )
686*b1cdbd2cSJim Jagielski 			{
687*b1cdbd2cSJim Jagielski 				mpNextGraphics = pSVData->maGDIData.mpFirstVirGraphics;
688*b1cdbd2cSJim Jagielski 				pSVData->maGDIData.mpFirstVirGraphics = const_cast<OutputDevice*>(this);
689*b1cdbd2cSJim Jagielski 				if ( mpNextGraphics )
690*b1cdbd2cSJim Jagielski 					mpNextGraphics->mpPrevGraphics = const_cast<OutputDevice*>(this);
691*b1cdbd2cSJim Jagielski 				if ( !pSVData->maGDIData.mpLastVirGraphics )
692*b1cdbd2cSJim Jagielski 					pSVData->maGDIData.mpLastVirGraphics = const_cast<OutputDevice*>(this);
693*b1cdbd2cSJim Jagielski 			}
694*b1cdbd2cSJim Jagielski 		}
695*b1cdbd2cSJim Jagielski 		else
696*b1cdbd2cSJim Jagielski 		{
697*b1cdbd2cSJim Jagielski 			mpGraphics = pPrinter->mpInfoPrinter->GetGraphics();
698*b1cdbd2cSJim Jagielski             // if needed retry after releasing least recently used printer graphics
699*b1cdbd2cSJim Jagielski 			while ( !mpGraphics )
700*b1cdbd2cSJim Jagielski 			{
701*b1cdbd2cSJim Jagielski 				if ( !pSVData->maGDIData.mpLastPrnGraphics )
702*b1cdbd2cSJim Jagielski 					break;
703*b1cdbd2cSJim Jagielski 				pSVData->maGDIData.mpLastPrnGraphics->ImplReleaseGraphics();
704*b1cdbd2cSJim Jagielski 				mpGraphics = pPrinter->mpInfoPrinter->GetGraphics();
705*b1cdbd2cSJim Jagielski 			}
706*b1cdbd2cSJim Jagielski             // update global LRU list of printer graphics
707*b1cdbd2cSJim Jagielski 			if ( mpGraphics )
708*b1cdbd2cSJim Jagielski 			{
709*b1cdbd2cSJim Jagielski 				mpNextGraphics = pSVData->maGDIData.mpFirstPrnGraphics;
710*b1cdbd2cSJim Jagielski 				pSVData->maGDIData.mpFirstPrnGraphics = const_cast<OutputDevice*>(this);
711*b1cdbd2cSJim Jagielski 				if ( mpNextGraphics )
712*b1cdbd2cSJim Jagielski 					mpNextGraphics->mpPrevGraphics = const_cast<OutputDevice*>(this);
713*b1cdbd2cSJim Jagielski 				if ( !pSVData->maGDIData.mpLastPrnGraphics )
714*b1cdbd2cSJim Jagielski 					pSVData->maGDIData.mpLastPrnGraphics = const_cast<OutputDevice*>(this);
715*b1cdbd2cSJim Jagielski 			}
716*b1cdbd2cSJim Jagielski 		}
717*b1cdbd2cSJim Jagielski 	}
718*b1cdbd2cSJim Jagielski 
719*b1cdbd2cSJim Jagielski 	if ( mpGraphics )
720*b1cdbd2cSJim Jagielski 	{
721*b1cdbd2cSJim Jagielski 		mpGraphics->SetXORMode( (ROP_INVERT == meRasterOp) || (ROP_XOR == meRasterOp), ROP_INVERT == meRasterOp );
722*b1cdbd2cSJim Jagielski         mpGraphics->setAntiAliasB2DDraw(mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW);
723*b1cdbd2cSJim Jagielski         return sal_True;
724*b1cdbd2cSJim Jagielski 	}
725*b1cdbd2cSJim Jagielski 
726*b1cdbd2cSJim Jagielski 	return sal_False;
727*b1cdbd2cSJim Jagielski }
728*b1cdbd2cSJim Jagielski 
729*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
730*b1cdbd2cSJim Jagielski 
ImplReleaseGraphics(sal_Bool bRelease)731*b1cdbd2cSJim Jagielski void OutputDevice::ImplReleaseGraphics( sal_Bool bRelease )
732*b1cdbd2cSJim Jagielski {
733*b1cdbd2cSJim Jagielski 	DBG_TESTSOLARMUTEX();
734*b1cdbd2cSJim Jagielski 
735*b1cdbd2cSJim Jagielski 	if ( !mpGraphics )
736*b1cdbd2cSJim Jagielski 		return;
737*b1cdbd2cSJim Jagielski 
738*b1cdbd2cSJim Jagielski     // release the fonts of the physically released graphics device
739*b1cdbd2cSJim Jagielski     if( bRelease )
740*b1cdbd2cSJim Jagielski     {
741*b1cdbd2cSJim Jagielski #ifndef UNX
742*b1cdbd2cSJim Jagielski         // HACK to fix an urgent P1 printing issue fast
743*b1cdbd2cSJim Jagielski         // WinSalPrinter does not respect GetGraphics/ReleaseGraphics conventions
744*b1cdbd2cSJim Jagielski         // so Printer::mpGraphics often points to a dead WinSalGraphics
745*b1cdbd2cSJim Jagielski         // TODO: fix WinSalPrinter's GetGraphics/ReleaseGraphics handling
746*b1cdbd2cSJim Jagielski         if( meOutDevType != OUTDEV_PRINTER )
747*b1cdbd2cSJim Jagielski #endif
748*b1cdbd2cSJim Jagielski         mpGraphics->ReleaseFonts();
749*b1cdbd2cSJim Jagielski 
750*b1cdbd2cSJim Jagielski         mbNewFont = true;
751*b1cdbd2cSJim Jagielski         mbInitFont = true;
752*b1cdbd2cSJim Jagielski 
753*b1cdbd2cSJim Jagielski         if ( mpFontEntry )
754*b1cdbd2cSJim Jagielski         {
755*b1cdbd2cSJim Jagielski             mpFontCache->Release( mpFontEntry );
756*b1cdbd2cSJim Jagielski             mpFontEntry = NULL;
757*b1cdbd2cSJim Jagielski         }
758*b1cdbd2cSJim Jagielski 
759*b1cdbd2cSJim Jagielski         if ( mpGetDevFontList )
760*b1cdbd2cSJim Jagielski         {
761*b1cdbd2cSJim Jagielski             delete mpGetDevFontList;
762*b1cdbd2cSJim Jagielski             mpGetDevFontList = NULL;
763*b1cdbd2cSJim Jagielski         }
764*b1cdbd2cSJim Jagielski 
765*b1cdbd2cSJim Jagielski         if ( mpGetDevSizeList )
766*b1cdbd2cSJim Jagielski         {
767*b1cdbd2cSJim Jagielski             delete mpGetDevSizeList;
768*b1cdbd2cSJim Jagielski             mpGetDevSizeList = NULL;
769*b1cdbd2cSJim Jagielski         }
770*b1cdbd2cSJim Jagielski     }
771*b1cdbd2cSJim Jagielski 
772*b1cdbd2cSJim Jagielski 	ImplSVData* pSVData = ImplGetSVData();
773*b1cdbd2cSJim Jagielski 	if ( meOutDevType == OUTDEV_WINDOW )
774*b1cdbd2cSJim Jagielski 	{
775*b1cdbd2cSJim Jagielski 		Window* pWindow = (Window*)this;
776*b1cdbd2cSJim Jagielski 
777*b1cdbd2cSJim Jagielski 		if ( bRelease )
778*b1cdbd2cSJim Jagielski 			pWindow->mpWindowImpl->mpFrame->ReleaseGraphics( mpGraphics );
779*b1cdbd2cSJim Jagielski         // remove from global LRU list of window graphics
780*b1cdbd2cSJim Jagielski 		if ( mpPrevGraphics )
781*b1cdbd2cSJim Jagielski 			mpPrevGraphics->mpNextGraphics = mpNextGraphics;
782*b1cdbd2cSJim Jagielski 		else
783*b1cdbd2cSJim Jagielski 			pSVData->maGDIData.mpFirstWinGraphics = mpNextGraphics;
784*b1cdbd2cSJim Jagielski 		if ( mpNextGraphics )
785*b1cdbd2cSJim Jagielski 			mpNextGraphics->mpPrevGraphics = mpPrevGraphics;
786*b1cdbd2cSJim Jagielski 		else
787*b1cdbd2cSJim Jagielski 			pSVData->maGDIData.mpLastWinGraphics = mpPrevGraphics;
788*b1cdbd2cSJim Jagielski 	}
789*b1cdbd2cSJim Jagielski 	else if ( meOutDevType == OUTDEV_VIRDEV )
790*b1cdbd2cSJim Jagielski 	{
791*b1cdbd2cSJim Jagielski 		VirtualDevice* pVirDev = (VirtualDevice*)this;
792*b1cdbd2cSJim Jagielski 
793*b1cdbd2cSJim Jagielski 		if ( bRelease )
794*b1cdbd2cSJim Jagielski 			pVirDev->mpVirDev->ReleaseGraphics( mpGraphics );
795*b1cdbd2cSJim Jagielski         // remove from global LRU list of virtual device graphics
796*b1cdbd2cSJim Jagielski 		if ( mpPrevGraphics )
797*b1cdbd2cSJim Jagielski 			mpPrevGraphics->mpNextGraphics = mpNextGraphics;
798*b1cdbd2cSJim Jagielski 		else
799*b1cdbd2cSJim Jagielski 			pSVData->maGDIData.mpFirstVirGraphics = mpNextGraphics;
800*b1cdbd2cSJim Jagielski 		if ( mpNextGraphics )
801*b1cdbd2cSJim Jagielski 			mpNextGraphics->mpPrevGraphics = mpPrevGraphics;
802*b1cdbd2cSJim Jagielski 		else
803*b1cdbd2cSJim Jagielski 			pSVData->maGDIData.mpLastVirGraphics = mpPrevGraphics;
804*b1cdbd2cSJim Jagielski 	}
805*b1cdbd2cSJim Jagielski 	else if ( meOutDevType == OUTDEV_PRINTER )
806*b1cdbd2cSJim Jagielski 	{
807*b1cdbd2cSJim Jagielski 		Printer* pPrinter = (Printer*)this;
808*b1cdbd2cSJim Jagielski 
809*b1cdbd2cSJim Jagielski 		if ( !pPrinter->mpJobGraphics )
810*b1cdbd2cSJim Jagielski 		{
811*b1cdbd2cSJim Jagielski 			if ( pPrinter->mpDisplayDev )
812*b1cdbd2cSJim Jagielski 			{
813*b1cdbd2cSJim Jagielski 				VirtualDevice* pVirDev = pPrinter->mpDisplayDev;
814*b1cdbd2cSJim Jagielski 				if ( bRelease )
815*b1cdbd2cSJim Jagielski 					pVirDev->mpVirDev->ReleaseGraphics( mpGraphics );
816*b1cdbd2cSJim Jagielski                 // remove from global LRU list of virtual device graphics
817*b1cdbd2cSJim Jagielski 				if ( mpPrevGraphics )
818*b1cdbd2cSJim Jagielski 					mpPrevGraphics->mpNextGraphics = mpNextGraphics;
819*b1cdbd2cSJim Jagielski 				else
820*b1cdbd2cSJim Jagielski 					pSVData->maGDIData.mpFirstVirGraphics = mpNextGraphics;
821*b1cdbd2cSJim Jagielski 				if ( mpNextGraphics )
822*b1cdbd2cSJim Jagielski 					mpNextGraphics->mpPrevGraphics = mpPrevGraphics;
823*b1cdbd2cSJim Jagielski 				else
824*b1cdbd2cSJim Jagielski 					pSVData->maGDIData.mpLastVirGraphics = mpPrevGraphics;
825*b1cdbd2cSJim Jagielski 			}
826*b1cdbd2cSJim Jagielski 			else
827*b1cdbd2cSJim Jagielski 			{
828*b1cdbd2cSJim Jagielski 				if ( bRelease )
829*b1cdbd2cSJim Jagielski 					pPrinter->mpInfoPrinter->ReleaseGraphics( mpGraphics );
830*b1cdbd2cSJim Jagielski                 // remove from global LRU list of printer graphics
831*b1cdbd2cSJim Jagielski 				if ( mpPrevGraphics )
832*b1cdbd2cSJim Jagielski 					mpPrevGraphics->mpNextGraphics = mpNextGraphics;
833*b1cdbd2cSJim Jagielski 				else
834*b1cdbd2cSJim Jagielski 					pSVData->maGDIData.mpFirstPrnGraphics = mpNextGraphics;
835*b1cdbd2cSJim Jagielski 				if ( mpNextGraphics )
836*b1cdbd2cSJim Jagielski 					mpNextGraphics->mpPrevGraphics = mpPrevGraphics;
837*b1cdbd2cSJim Jagielski 				else
838*b1cdbd2cSJim Jagielski 					pSVData->maGDIData.mpLastPrnGraphics = mpPrevGraphics;
839*b1cdbd2cSJim Jagielski 		   }
840*b1cdbd2cSJim Jagielski 		}
841*b1cdbd2cSJim Jagielski 	}
842*b1cdbd2cSJim Jagielski 
843*b1cdbd2cSJim Jagielski 	mpGraphics		= NULL;
844*b1cdbd2cSJim Jagielski 	mpPrevGraphics	= NULL;
845*b1cdbd2cSJim Jagielski 	mpNextGraphics	= NULL;
846*b1cdbd2cSJim Jagielski }
847*b1cdbd2cSJim Jagielski 
848*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
849*b1cdbd2cSJim Jagielski 
ImplInitOutDevData()850*b1cdbd2cSJim Jagielski void OutputDevice::ImplInitOutDevData()
851*b1cdbd2cSJim Jagielski {
852*b1cdbd2cSJim Jagielski 	if ( !mpOutDevData )
853*b1cdbd2cSJim Jagielski 	{
854*b1cdbd2cSJim Jagielski 		mpOutDevData = new ImplOutDevData;
855*b1cdbd2cSJim Jagielski 		mpOutDevData->mpRotateDev = NULL;
856*b1cdbd2cSJim Jagielski         mpOutDevData->mpRecordLayout = NULL;
857*b1cdbd2cSJim Jagielski 
858*b1cdbd2cSJim Jagielski 		// #i75163#
859*b1cdbd2cSJim Jagielski 		mpOutDevData->mpViewTransform = NULL;
860*b1cdbd2cSJim Jagielski 		mpOutDevData->mpInverseViewTransform = NULL;
861*b1cdbd2cSJim Jagielski 	}
862*b1cdbd2cSJim Jagielski }
863*b1cdbd2cSJim Jagielski 
864*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
865*b1cdbd2cSJim Jagielski 
866*b1cdbd2cSJim Jagielski // #i75163#
ImplInvalidateViewTransform()867*b1cdbd2cSJim Jagielski void OutputDevice::ImplInvalidateViewTransform()
868*b1cdbd2cSJim Jagielski {
869*b1cdbd2cSJim Jagielski 	if(mpOutDevData)
870*b1cdbd2cSJim Jagielski 	{
871*b1cdbd2cSJim Jagielski 		if(mpOutDevData->mpViewTransform)
872*b1cdbd2cSJim Jagielski 		{
873*b1cdbd2cSJim Jagielski 			delete mpOutDevData->mpViewTransform;
874*b1cdbd2cSJim Jagielski 			mpOutDevData->mpViewTransform = NULL;
875*b1cdbd2cSJim Jagielski 		}
876*b1cdbd2cSJim Jagielski 
877*b1cdbd2cSJim Jagielski 		if(mpOutDevData->mpInverseViewTransform)
878*b1cdbd2cSJim Jagielski 		{
879*b1cdbd2cSJim Jagielski 			delete mpOutDevData->mpInverseViewTransform;
880*b1cdbd2cSJim Jagielski 			mpOutDevData->mpInverseViewTransform = NULL;
881*b1cdbd2cSJim Jagielski 		}
882*b1cdbd2cSJim Jagielski 	}
883*b1cdbd2cSJim Jagielski }
884*b1cdbd2cSJim Jagielski 
885*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
886*b1cdbd2cSJim Jagielski 
ImplIsRecordLayout() const887*b1cdbd2cSJim Jagielski sal_Bool OutputDevice::ImplIsRecordLayout() const
888*b1cdbd2cSJim Jagielski {
889*b1cdbd2cSJim Jagielski     return mpOutDevData && mpOutDevData->mpRecordLayout;
890*b1cdbd2cSJim Jagielski }
891*b1cdbd2cSJim Jagielski 
892*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
893*b1cdbd2cSJim Jagielski 
ImplDeInitOutDevData()894*b1cdbd2cSJim Jagielski void OutputDevice::ImplDeInitOutDevData()
895*b1cdbd2cSJim Jagielski {
896*b1cdbd2cSJim Jagielski 	if ( mpOutDevData )
897*b1cdbd2cSJim Jagielski 	{
898*b1cdbd2cSJim Jagielski 		if ( mpOutDevData->mpRotateDev )
899*b1cdbd2cSJim Jagielski 			delete mpOutDevData->mpRotateDev;
900*b1cdbd2cSJim Jagielski 
901*b1cdbd2cSJim Jagielski 		// #i75163#
902*b1cdbd2cSJim Jagielski 		ImplInvalidateViewTransform();
903*b1cdbd2cSJim Jagielski 
904*b1cdbd2cSJim Jagielski 		delete mpOutDevData;
905*b1cdbd2cSJim Jagielski 	}
906*b1cdbd2cSJim Jagielski }
907*b1cdbd2cSJim Jagielski 
908*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
909*b1cdbd2cSJim Jagielski 
ImplInitLineColor()910*b1cdbd2cSJim Jagielski void OutputDevice::ImplInitLineColor()
911*b1cdbd2cSJim Jagielski {
912*b1cdbd2cSJim Jagielski 	DBG_TESTSOLARMUTEX();
913*b1cdbd2cSJim Jagielski 
914*b1cdbd2cSJim Jagielski 	if( mbLineColor )
915*b1cdbd2cSJim Jagielski 	{
916*b1cdbd2cSJim Jagielski 		if( ROP_0 == meRasterOp )
917*b1cdbd2cSJim Jagielski 			mpGraphics->SetROPLineColor( SAL_ROP_0 );
918*b1cdbd2cSJim Jagielski 		else if( ROP_1 == meRasterOp )
919*b1cdbd2cSJim Jagielski 			mpGraphics->SetROPLineColor( SAL_ROP_1 );
920*b1cdbd2cSJim Jagielski 		else if( ROP_INVERT == meRasterOp )
921*b1cdbd2cSJim Jagielski 			mpGraphics->SetROPLineColor( SAL_ROP_INVERT );
922*b1cdbd2cSJim Jagielski 		else
923*b1cdbd2cSJim Jagielski 			mpGraphics->SetLineColor( ImplColorToSal( maLineColor ) );
924*b1cdbd2cSJim Jagielski 	}
925*b1cdbd2cSJim Jagielski 	else
926*b1cdbd2cSJim Jagielski 		mpGraphics->SetLineColor();
927*b1cdbd2cSJim Jagielski 
928*b1cdbd2cSJim Jagielski 	mbInitLineColor = sal_False;
929*b1cdbd2cSJim Jagielski }
930*b1cdbd2cSJim Jagielski 
931*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
932*b1cdbd2cSJim Jagielski 
ImplInitFillColor()933*b1cdbd2cSJim Jagielski void OutputDevice::ImplInitFillColor()
934*b1cdbd2cSJim Jagielski {
935*b1cdbd2cSJim Jagielski 	DBG_TESTSOLARMUTEX();
936*b1cdbd2cSJim Jagielski 
937*b1cdbd2cSJim Jagielski 	if( mbFillColor )
938*b1cdbd2cSJim Jagielski 	{
939*b1cdbd2cSJim Jagielski 		if( ROP_0 == meRasterOp )
940*b1cdbd2cSJim Jagielski 			mpGraphics->SetROPFillColor( SAL_ROP_0 );
941*b1cdbd2cSJim Jagielski 		else if( ROP_1 == meRasterOp )
942*b1cdbd2cSJim Jagielski 			mpGraphics->SetROPFillColor( SAL_ROP_1 );
943*b1cdbd2cSJim Jagielski 		else if( ROP_INVERT == meRasterOp )
944*b1cdbd2cSJim Jagielski 			mpGraphics->SetROPFillColor( SAL_ROP_INVERT );
945*b1cdbd2cSJim Jagielski 		else
946*b1cdbd2cSJim Jagielski 			mpGraphics->SetFillColor( ImplColorToSal( maFillColor ) );
947*b1cdbd2cSJim Jagielski 	}
948*b1cdbd2cSJim Jagielski 	else
949*b1cdbd2cSJim Jagielski 		mpGraphics->SetFillColor();
950*b1cdbd2cSJim Jagielski 
951*b1cdbd2cSJim Jagielski 	mbInitFillColor = sal_False;
952*b1cdbd2cSJim Jagielski }
953*b1cdbd2cSJim Jagielski 
954*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
955*b1cdbd2cSJim Jagielski 
ImplInitClipRegion()956*b1cdbd2cSJim Jagielski void OutputDevice::ImplInitClipRegion()
957*b1cdbd2cSJim Jagielski {
958*b1cdbd2cSJim Jagielski 	DBG_TESTSOLARMUTEX();
959*b1cdbd2cSJim Jagielski 
960*b1cdbd2cSJim Jagielski 	if ( GetOutDevType() == OUTDEV_WINDOW )
961*b1cdbd2cSJim Jagielski 	{
962*b1cdbd2cSJim Jagielski 		Window* pWindow = (Window*)this;
963*b1cdbd2cSJim Jagielski 		Region	aRegion;
964*b1cdbd2cSJim Jagielski 
965*b1cdbd2cSJim Jagielski 		// Hintergrund-Sicherung zuruecksetzen
966*b1cdbd2cSJim Jagielski 		if ( pWindow->mpWindowImpl->mpFrameData->mpFirstBackWin )
967*b1cdbd2cSJim Jagielski 			pWindow->ImplInvalidateAllOverlapBackgrounds();
968*b1cdbd2cSJim Jagielski 		if ( pWindow->mpWindowImpl->mbInPaint )
969*b1cdbd2cSJim Jagielski 			aRegion = *(pWindow->mpWindowImpl->mpPaintRegion);
970*b1cdbd2cSJim Jagielski 		else
971*b1cdbd2cSJim Jagielski         {
972*b1cdbd2cSJim Jagielski 			aRegion = *(pWindow->ImplGetWinChildClipRegion());
973*b1cdbd2cSJim Jagielski             // --- RTL -- only this region is in frame coordinates, so re-mirror it
974*b1cdbd2cSJim Jagielski             // the mpWindowImpl->mpPaintRegion above is already correct (see ImplCallPaint()) !
975*b1cdbd2cSJim Jagielski             if( ImplIsAntiparallel() )
976*b1cdbd2cSJim Jagielski 	            ImplReMirror ( aRegion );
977*b1cdbd2cSJim Jagielski         }
978*b1cdbd2cSJim Jagielski 		if ( mbClipRegion )
979*b1cdbd2cSJim Jagielski 			aRegion.Intersect( ImplPixelToDevicePixel( maRegion ) );
980*b1cdbd2cSJim Jagielski 		if ( aRegion.IsEmpty() )
981*b1cdbd2cSJim Jagielski 			mbOutputClipped = sal_True;
982*b1cdbd2cSJim Jagielski 		else
983*b1cdbd2cSJim Jagielski 		{
984*b1cdbd2cSJim Jagielski 			mbOutputClipped = sal_False;
985*b1cdbd2cSJim Jagielski 			ImplSelectClipRegion( aRegion );
986*b1cdbd2cSJim Jagielski 		}
987*b1cdbd2cSJim Jagielski 		mbClipRegionSet = sal_True;
988*b1cdbd2cSJim Jagielski 	}
989*b1cdbd2cSJim Jagielski 	else
990*b1cdbd2cSJim Jagielski 	{
991*b1cdbd2cSJim Jagielski 		if ( mbClipRegion )
992*b1cdbd2cSJim Jagielski 		{
993*b1cdbd2cSJim Jagielski 			if ( maRegion.IsEmpty() )
994*b1cdbd2cSJim Jagielski 				mbOutputClipped = sal_True;
995*b1cdbd2cSJim Jagielski 			else
996*b1cdbd2cSJim Jagielski 			{
997*b1cdbd2cSJim Jagielski 				mbOutputClipped = sal_False;
998*b1cdbd2cSJim Jagielski 
999*b1cdbd2cSJim Jagielski 				// #102532# Respect output offset also for clip region
1000*b1cdbd2cSJim Jagielski                 Region aRegion( ImplPixelToDevicePixel( maRegion ) );
1001*b1cdbd2cSJim Jagielski                 const bool bClipDeviceBounds( ! GetPDFWriter()
1002*b1cdbd2cSJim Jagielski                                               && GetOutDevType() != OUTDEV_PRINTER );
1003*b1cdbd2cSJim Jagielski                 if( bClipDeviceBounds )
1004*b1cdbd2cSJim Jagielski                 {
1005*b1cdbd2cSJim Jagielski                     // #b6520266# Perform actual rect clip against outdev
1006*b1cdbd2cSJim Jagielski                     // dimensions, to generate empty clips whenever one of the
1007*b1cdbd2cSJim Jagielski                     // values is completely off the device.
1008*b1cdbd2cSJim Jagielski                     Rectangle aDeviceBounds( mnOutOffX, mnOutOffY,
1009*b1cdbd2cSJim Jagielski                                              mnOutOffX+GetOutputWidthPixel()-1,
1010*b1cdbd2cSJim Jagielski                                              mnOutOffY+GetOutputHeightPixel()-1 );
1011*b1cdbd2cSJim Jagielski                     aRegion.Intersect( aDeviceBounds );
1012*b1cdbd2cSJim Jagielski                 }
1013*b1cdbd2cSJim Jagielski 
1014*b1cdbd2cSJim Jagielski                 if ( aRegion.IsEmpty() )
1015*b1cdbd2cSJim Jagielski                 {
1016*b1cdbd2cSJim Jagielski 			        mbOutputClipped = sal_True;
1017*b1cdbd2cSJim Jagielski                 }
1018*b1cdbd2cSJim Jagielski 		        else
1019*b1cdbd2cSJim Jagielski 		        {
1020*b1cdbd2cSJim Jagielski 			        mbOutputClipped = sal_False;
1021*b1cdbd2cSJim Jagielski 			        ImplSelectClipRegion( aRegion );
1022*b1cdbd2cSJim Jagielski 		        }
1023*b1cdbd2cSJim Jagielski 			}
1024*b1cdbd2cSJim Jagielski 
1025*b1cdbd2cSJim Jagielski 			mbClipRegionSet = sal_True;
1026*b1cdbd2cSJim Jagielski 		}
1027*b1cdbd2cSJim Jagielski 		else
1028*b1cdbd2cSJim Jagielski 		{
1029*b1cdbd2cSJim Jagielski 			if ( mbClipRegionSet )
1030*b1cdbd2cSJim Jagielski 			{
1031*b1cdbd2cSJim Jagielski 				mpGraphics->ResetClipRegion();
1032*b1cdbd2cSJim Jagielski 				mbClipRegionSet = sal_False;
1033*b1cdbd2cSJim Jagielski 			}
1034*b1cdbd2cSJim Jagielski 
1035*b1cdbd2cSJim Jagielski 			mbOutputClipped = sal_False;
1036*b1cdbd2cSJim Jagielski 		}
1037*b1cdbd2cSJim Jagielski 	}
1038*b1cdbd2cSJim Jagielski 
1039*b1cdbd2cSJim Jagielski 	mbInitClipRegion = sal_False;
1040*b1cdbd2cSJim Jagielski }
1041*b1cdbd2cSJim Jagielski 
1042*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
1043*b1cdbd2cSJim Jagielski 
ImplSetClipRegion(const Region * pRegion)1044*b1cdbd2cSJim Jagielski void OutputDevice::ImplSetClipRegion( const Region* pRegion )
1045*b1cdbd2cSJim Jagielski {
1046*b1cdbd2cSJim Jagielski 	DBG_TESTSOLARMUTEX();
1047*b1cdbd2cSJim Jagielski 
1048*b1cdbd2cSJim Jagielski 	if ( !pRegion )
1049*b1cdbd2cSJim Jagielski 	{
1050*b1cdbd2cSJim Jagielski 		if ( mbClipRegion )
1051*b1cdbd2cSJim Jagielski 		{
1052*b1cdbd2cSJim Jagielski 			maRegion			= Region(true);
1053*b1cdbd2cSJim Jagielski 			mbClipRegion		= sal_False;
1054*b1cdbd2cSJim Jagielski 			mbInitClipRegion	= sal_True;
1055*b1cdbd2cSJim Jagielski 		}
1056*b1cdbd2cSJim Jagielski 	}
1057*b1cdbd2cSJim Jagielski 	else
1058*b1cdbd2cSJim Jagielski 	{
1059*b1cdbd2cSJim Jagielski 		maRegion			= *pRegion;
1060*b1cdbd2cSJim Jagielski 		mbClipRegion		= sal_True;
1061*b1cdbd2cSJim Jagielski 		mbInitClipRegion	= sal_True;
1062*b1cdbd2cSJim Jagielski 	}
1063*b1cdbd2cSJim Jagielski }
1064*b1cdbd2cSJim Jagielski 
1065*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
1066*b1cdbd2cSJim Jagielski 
SetClipRegion()1067*b1cdbd2cSJim Jagielski void OutputDevice::SetClipRegion()
1068*b1cdbd2cSJim Jagielski {
1069*b1cdbd2cSJim Jagielski 	DBG_TRACE( "OutputDevice::SetClipRegion()" );
1070*b1cdbd2cSJim Jagielski 	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1071*b1cdbd2cSJim Jagielski 
1072*b1cdbd2cSJim Jagielski 	if ( mpMetaFile )
1073*b1cdbd2cSJim Jagielski 		mpMetaFile->AddAction( new MetaClipRegionAction( Region(), sal_False ) );
1074*b1cdbd2cSJim Jagielski 
1075*b1cdbd2cSJim Jagielski 	ImplSetClipRegion( NULL );
1076*b1cdbd2cSJim Jagielski 
1077*b1cdbd2cSJim Jagielski     if( mpAlphaVDev )
1078*b1cdbd2cSJim Jagielski         mpAlphaVDev->SetClipRegion();
1079*b1cdbd2cSJim Jagielski }
1080*b1cdbd2cSJim Jagielski 
1081*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
1082*b1cdbd2cSJim Jagielski 
SetClipRegion(const Region & rRegion)1083*b1cdbd2cSJim Jagielski void OutputDevice::SetClipRegion( const Region& rRegion )
1084*b1cdbd2cSJim Jagielski {
1085*b1cdbd2cSJim Jagielski 	DBG_TRACE( "OutputDevice::SetClipRegion( rRegion )" );
1086*b1cdbd2cSJim Jagielski 	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1087*b1cdbd2cSJim Jagielski 
1088*b1cdbd2cSJim Jagielski 	if ( mpMetaFile )
1089*b1cdbd2cSJim Jagielski 		mpMetaFile->AddAction( new MetaClipRegionAction( rRegion, sal_True ) );
1090*b1cdbd2cSJim Jagielski 
1091*b1cdbd2cSJim Jagielski 	if ( rRegion.IsNull() )
1092*b1cdbd2cSJim Jagielski     {
1093*b1cdbd2cSJim Jagielski 		ImplSetClipRegion( NULL );
1094*b1cdbd2cSJim Jagielski     }
1095*b1cdbd2cSJim Jagielski 	else
1096*b1cdbd2cSJim Jagielski 	{
1097*b1cdbd2cSJim Jagielski 		Region aRegion = LogicToPixel( rRegion );
1098*b1cdbd2cSJim Jagielski 		ImplSetClipRegion( &aRegion );
1099*b1cdbd2cSJim Jagielski 	}
1100*b1cdbd2cSJim Jagielski 
1101*b1cdbd2cSJim Jagielski     if( mpAlphaVDev )
1102*b1cdbd2cSJim Jagielski         mpAlphaVDev->SetClipRegion( rRegion );
1103*b1cdbd2cSJim Jagielski }
1104*b1cdbd2cSJim Jagielski 
1105*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
1106*b1cdbd2cSJim Jagielski 
GetClipRegion() const1107*b1cdbd2cSJim Jagielski Region OutputDevice::GetClipRegion() const
1108*b1cdbd2cSJim Jagielski {
1109*b1cdbd2cSJim Jagielski 	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1110*b1cdbd2cSJim Jagielski 
1111*b1cdbd2cSJim Jagielski 	return PixelToLogic( maRegion );
1112*b1cdbd2cSJim Jagielski }
1113*b1cdbd2cSJim Jagielski 
1114*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
1115*b1cdbd2cSJim Jagielski 
GetActiveClipRegion() const1116*b1cdbd2cSJim Jagielski Region OutputDevice::GetActiveClipRegion() const
1117*b1cdbd2cSJim Jagielski {
1118*b1cdbd2cSJim Jagielski 	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1119*b1cdbd2cSJim Jagielski 
1120*b1cdbd2cSJim Jagielski 	if ( GetOutDevType() == OUTDEV_WINDOW )
1121*b1cdbd2cSJim Jagielski 	{
1122*b1cdbd2cSJim Jagielski 		Region aRegion(true);
1123*b1cdbd2cSJim Jagielski 		Window* pWindow = (Window*)this;
1124*b1cdbd2cSJim Jagielski 		if ( pWindow->mpWindowImpl->mbInPaint )
1125*b1cdbd2cSJim Jagielski 		{
1126*b1cdbd2cSJim Jagielski 			aRegion = *(pWindow->mpWindowImpl->mpPaintRegion);
1127*b1cdbd2cSJim Jagielski 			aRegion.Move( -mnOutOffX, -mnOutOffY );
1128*b1cdbd2cSJim Jagielski 		}
1129*b1cdbd2cSJim Jagielski 		if ( mbClipRegion )
1130*b1cdbd2cSJim Jagielski 			aRegion.Intersect( maRegion );
1131*b1cdbd2cSJim Jagielski 		return PixelToLogic( aRegion );
1132*b1cdbd2cSJim Jagielski 	}
1133*b1cdbd2cSJim Jagielski 	else
1134*b1cdbd2cSJim Jagielski 		return GetClipRegion();
1135*b1cdbd2cSJim Jagielski }
1136*b1cdbd2cSJim Jagielski 
1137*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
1138*b1cdbd2cSJim Jagielski 
MoveClipRegion(long nHorzMove,long nVertMove)1139*b1cdbd2cSJim Jagielski void OutputDevice::MoveClipRegion( long nHorzMove, long nVertMove )
1140*b1cdbd2cSJim Jagielski {
1141*b1cdbd2cSJim Jagielski 	DBG_TRACE( "OutputDevice::MoveClipRegion()" );
1142*b1cdbd2cSJim Jagielski 	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1143*b1cdbd2cSJim Jagielski 
1144*b1cdbd2cSJim Jagielski 	if ( mbClipRegion )
1145*b1cdbd2cSJim Jagielski 	{
1146*b1cdbd2cSJim Jagielski 		if( mpMetaFile )
1147*b1cdbd2cSJim Jagielski 			mpMetaFile->AddAction( new MetaMoveClipRegionAction( nHorzMove, nVertMove ) );
1148*b1cdbd2cSJim Jagielski 
1149*b1cdbd2cSJim Jagielski 		maRegion.Move( ImplLogicWidthToDevicePixel( nHorzMove ),
1150*b1cdbd2cSJim Jagielski 					   ImplLogicHeightToDevicePixel( nVertMove ) );
1151*b1cdbd2cSJim Jagielski 		mbInitClipRegion = sal_True;
1152*b1cdbd2cSJim Jagielski 	}
1153*b1cdbd2cSJim Jagielski 
1154*b1cdbd2cSJim Jagielski     if( mpAlphaVDev )
1155*b1cdbd2cSJim Jagielski         mpAlphaVDev->MoveClipRegion( nHorzMove, nVertMove );
1156*b1cdbd2cSJim Jagielski }
1157*b1cdbd2cSJim Jagielski 
1158*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
1159*b1cdbd2cSJim Jagielski 
IntersectClipRegion(const Rectangle & rRect)1160*b1cdbd2cSJim Jagielski void OutputDevice::IntersectClipRegion( const Rectangle& rRect )
1161*b1cdbd2cSJim Jagielski {
1162*b1cdbd2cSJim Jagielski 	DBG_TRACE( "OutputDevice::IntersectClipRegion( rRect )" );
1163*b1cdbd2cSJim Jagielski 	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1164*b1cdbd2cSJim Jagielski 
1165*b1cdbd2cSJim Jagielski 	if ( mpMetaFile )
1166*b1cdbd2cSJim Jagielski 		mpMetaFile->AddAction( new MetaISectRectClipRegionAction( rRect ) );
1167*b1cdbd2cSJim Jagielski 
1168*b1cdbd2cSJim Jagielski 	Rectangle aRect = LogicToPixel( rRect );
1169*b1cdbd2cSJim Jagielski 	maRegion.Intersect( aRect );
1170*b1cdbd2cSJim Jagielski 	mbClipRegion		= sal_True;
1171*b1cdbd2cSJim Jagielski 	mbInitClipRegion	= sal_True;
1172*b1cdbd2cSJim Jagielski 
1173*b1cdbd2cSJim Jagielski     if( mpAlphaVDev )
1174*b1cdbd2cSJim Jagielski         mpAlphaVDev->IntersectClipRegion( rRect );
1175*b1cdbd2cSJim Jagielski }
1176*b1cdbd2cSJim Jagielski 
1177*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
1178*b1cdbd2cSJim Jagielski 
IntersectClipRegion(const Region & rRegion)1179*b1cdbd2cSJim Jagielski void OutputDevice::IntersectClipRegion( const Region& rRegion )
1180*b1cdbd2cSJim Jagielski {
1181*b1cdbd2cSJim Jagielski 	DBG_TRACE( "OutputDevice::IntersectClipRegion( rRegion )" );
1182*b1cdbd2cSJim Jagielski 	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1183*b1cdbd2cSJim Jagielski 
1184*b1cdbd2cSJim Jagielski 	if(!rRegion.IsNull())
1185*b1cdbd2cSJim Jagielski 	{
1186*b1cdbd2cSJim Jagielski 		if ( mpMetaFile )
1187*b1cdbd2cSJim Jagielski 			mpMetaFile->AddAction( new MetaISectRegionClipRegionAction( rRegion ) );
1188*b1cdbd2cSJim Jagielski 
1189*b1cdbd2cSJim Jagielski 		Region aRegion = LogicToPixel( rRegion );
1190*b1cdbd2cSJim Jagielski 		maRegion.Intersect( aRegion );
1191*b1cdbd2cSJim Jagielski 		mbClipRegion		= sal_True;
1192*b1cdbd2cSJim Jagielski 		mbInitClipRegion	= sal_True;
1193*b1cdbd2cSJim Jagielski 	}
1194*b1cdbd2cSJim Jagielski 
1195*b1cdbd2cSJim Jagielski     if( mpAlphaVDev )
1196*b1cdbd2cSJim Jagielski         mpAlphaVDev->IntersectClipRegion( rRegion );
1197*b1cdbd2cSJim Jagielski }
1198*b1cdbd2cSJim Jagielski 
1199*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
1200*b1cdbd2cSJim Jagielski 
SetDrawMode(sal_uLong nDrawMode)1201*b1cdbd2cSJim Jagielski void OutputDevice::SetDrawMode( sal_uLong nDrawMode )
1202*b1cdbd2cSJim Jagielski {
1203*b1cdbd2cSJim Jagielski 	DBG_TRACE1( "OutputDevice::SetDrawMode( %lx )", nDrawMode );
1204*b1cdbd2cSJim Jagielski 	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1205*b1cdbd2cSJim Jagielski 
1206*b1cdbd2cSJim Jagielski 	mnDrawMode = nDrawMode;
1207*b1cdbd2cSJim Jagielski 
1208*b1cdbd2cSJim Jagielski     if( mpAlphaVDev )
1209*b1cdbd2cSJim Jagielski         mpAlphaVDev->SetDrawMode( nDrawMode );
1210*b1cdbd2cSJim Jagielski }
1211*b1cdbd2cSJim Jagielski 
1212*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
1213*b1cdbd2cSJim Jagielski 
SetRasterOp(RasterOp eRasterOp)1214*b1cdbd2cSJim Jagielski void OutputDevice::SetRasterOp( RasterOp eRasterOp )
1215*b1cdbd2cSJim Jagielski {
1216*b1cdbd2cSJim Jagielski 	DBG_TRACE1( "OutputDevice::SetRasterOp( %d )", (int)eRasterOp );
1217*b1cdbd2cSJim Jagielski 	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1218*b1cdbd2cSJim Jagielski 
1219*b1cdbd2cSJim Jagielski 	if ( mpMetaFile )
1220*b1cdbd2cSJim Jagielski 		mpMetaFile->AddAction( new MetaRasterOpAction( eRasterOp ) );
1221*b1cdbd2cSJim Jagielski 
1222*b1cdbd2cSJim Jagielski 	if ( meRasterOp != eRasterOp )
1223*b1cdbd2cSJim Jagielski 	{
1224*b1cdbd2cSJim Jagielski 		meRasterOp = eRasterOp;
1225*b1cdbd2cSJim Jagielski 		mbInitLineColor = mbInitFillColor = sal_True;
1226*b1cdbd2cSJim Jagielski 
1227*b1cdbd2cSJim Jagielski 		if( mpGraphics || ImplGetGraphics() )
1228*b1cdbd2cSJim Jagielski 			mpGraphics->SetXORMode( (ROP_INVERT == meRasterOp) || (ROP_XOR == meRasterOp), ROP_INVERT == meRasterOp );
1229*b1cdbd2cSJim Jagielski 	}
1230*b1cdbd2cSJim Jagielski 
1231*b1cdbd2cSJim Jagielski     if( mpAlphaVDev )
1232*b1cdbd2cSJim Jagielski         mpAlphaVDev->SetRasterOp( eRasterOp );
1233*b1cdbd2cSJim Jagielski }
1234*b1cdbd2cSJim Jagielski 
1235*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
1236*b1cdbd2cSJim Jagielski 
SetLineColor()1237*b1cdbd2cSJim Jagielski void OutputDevice::SetLineColor()
1238*b1cdbd2cSJim Jagielski {
1239*b1cdbd2cSJim Jagielski 	DBG_TRACE( "OutputDevice::SetLineColor()" );
1240*b1cdbd2cSJim Jagielski 	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1241*b1cdbd2cSJim Jagielski 
1242*b1cdbd2cSJim Jagielski 	if ( mpMetaFile )
1243*b1cdbd2cSJim Jagielski 		mpMetaFile->AddAction( new MetaLineColorAction( Color(), sal_False ) );
1244*b1cdbd2cSJim Jagielski 
1245*b1cdbd2cSJim Jagielski 	if ( mbLineColor )
1246*b1cdbd2cSJim Jagielski 	{
1247*b1cdbd2cSJim Jagielski 		mbInitLineColor = sal_True;
1248*b1cdbd2cSJim Jagielski 		mbLineColor = sal_False;
1249*b1cdbd2cSJim Jagielski 		maLineColor = Color( COL_TRANSPARENT );
1250*b1cdbd2cSJim Jagielski 	}
1251*b1cdbd2cSJim Jagielski 
1252*b1cdbd2cSJim Jagielski     if( mpAlphaVDev )
1253*b1cdbd2cSJim Jagielski         mpAlphaVDev->SetLineColor();
1254*b1cdbd2cSJim Jagielski }
1255*b1cdbd2cSJim Jagielski 
1256*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
1257*b1cdbd2cSJim Jagielski 
SetLineColor(const Color & rColor)1258*b1cdbd2cSJim Jagielski void OutputDevice::SetLineColor( const Color& rColor )
1259*b1cdbd2cSJim Jagielski {
1260*b1cdbd2cSJim Jagielski 	DBG_TRACE1( "OutputDevice::SetLineColor( %lx )", rColor.GetColor() );
1261*b1cdbd2cSJim Jagielski 	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1262*b1cdbd2cSJim Jagielski 
1263*b1cdbd2cSJim Jagielski 	Color aColor( rColor );
1264*b1cdbd2cSJim Jagielski 
1265*b1cdbd2cSJim Jagielski 	if( mnDrawMode & ( DRAWMODE_BLACKLINE | DRAWMODE_WHITELINE |
1266*b1cdbd2cSJim Jagielski 					   DRAWMODE_GRAYLINE | DRAWMODE_GHOSTEDLINE |
1267*b1cdbd2cSJim Jagielski                        DRAWMODE_SETTINGSLINE ) )
1268*b1cdbd2cSJim Jagielski 	{
1269*b1cdbd2cSJim Jagielski 		if( !ImplIsColorTransparent( aColor ) )
1270*b1cdbd2cSJim Jagielski 		{
1271*b1cdbd2cSJim Jagielski 			if( mnDrawMode & DRAWMODE_BLACKLINE )
1272*b1cdbd2cSJim Jagielski 			{
1273*b1cdbd2cSJim Jagielski 				aColor = Color( COL_BLACK );
1274*b1cdbd2cSJim Jagielski 			}
1275*b1cdbd2cSJim Jagielski 			else if( mnDrawMode & DRAWMODE_WHITELINE )
1276*b1cdbd2cSJim Jagielski 			{
1277*b1cdbd2cSJim Jagielski 				aColor = Color( COL_WHITE );
1278*b1cdbd2cSJim Jagielski 			}
1279*b1cdbd2cSJim Jagielski 			else if( mnDrawMode & DRAWMODE_GRAYLINE )
1280*b1cdbd2cSJim Jagielski 			{
1281*b1cdbd2cSJim Jagielski 				const sal_uInt8 cLum = aColor.GetLuminance();
1282*b1cdbd2cSJim Jagielski 				aColor = Color( cLum, cLum, cLum );
1283*b1cdbd2cSJim Jagielski 			}
1284*b1cdbd2cSJim Jagielski             else if( mnDrawMode & DRAWMODE_SETTINGSLINE )
1285*b1cdbd2cSJim Jagielski             {
1286*b1cdbd2cSJim Jagielski                 aColor = GetSettings().GetStyleSettings().GetFontColor();
1287*b1cdbd2cSJim Jagielski             }
1288*b1cdbd2cSJim Jagielski 
1289*b1cdbd2cSJim Jagielski 			if( mnDrawMode & DRAWMODE_GHOSTEDLINE )
1290*b1cdbd2cSJim Jagielski 			{
1291*b1cdbd2cSJim Jagielski 				aColor = Color( ( aColor.GetRed() >> 1 ) | 0x80,
1292*b1cdbd2cSJim Jagielski 								( aColor.GetGreen() >> 1 ) | 0x80,
1293*b1cdbd2cSJim Jagielski 								( aColor.GetBlue() >> 1 ) | 0x80);
1294*b1cdbd2cSJim Jagielski 			}
1295*b1cdbd2cSJim Jagielski 		}
1296*b1cdbd2cSJim Jagielski 	}
1297*b1cdbd2cSJim Jagielski 
1298*b1cdbd2cSJim Jagielski 	if( mpMetaFile )
1299*b1cdbd2cSJim Jagielski 		mpMetaFile->AddAction( new MetaLineColorAction( aColor, sal_True ) );
1300*b1cdbd2cSJim Jagielski 
1301*b1cdbd2cSJim Jagielski 	if( ImplIsColorTransparent( aColor ) )
1302*b1cdbd2cSJim Jagielski 	{
1303*b1cdbd2cSJim Jagielski 		if ( mbLineColor )
1304*b1cdbd2cSJim Jagielski 		{
1305*b1cdbd2cSJim Jagielski 			mbInitLineColor = sal_True;
1306*b1cdbd2cSJim Jagielski 			mbLineColor = sal_False;
1307*b1cdbd2cSJim Jagielski 			maLineColor = Color( COL_TRANSPARENT );
1308*b1cdbd2cSJim Jagielski 		}
1309*b1cdbd2cSJim Jagielski 	}
1310*b1cdbd2cSJim Jagielski 	else
1311*b1cdbd2cSJim Jagielski 	{
1312*b1cdbd2cSJim Jagielski 		if( maLineColor != aColor )
1313*b1cdbd2cSJim Jagielski 		{
1314*b1cdbd2cSJim Jagielski 			mbInitLineColor = sal_True;
1315*b1cdbd2cSJim Jagielski 			mbLineColor = sal_True;
1316*b1cdbd2cSJim Jagielski 			maLineColor = aColor;
1317*b1cdbd2cSJim Jagielski 		}
1318*b1cdbd2cSJim Jagielski 	}
1319*b1cdbd2cSJim Jagielski 
1320*b1cdbd2cSJim Jagielski     if( mpAlphaVDev )
1321*b1cdbd2cSJim Jagielski         mpAlphaVDev->SetLineColor( COL_BLACK );
1322*b1cdbd2cSJim Jagielski }
1323*b1cdbd2cSJim Jagielski 
1324*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
1325*b1cdbd2cSJim Jagielski 
SetFillColor()1326*b1cdbd2cSJim Jagielski void OutputDevice::SetFillColor()
1327*b1cdbd2cSJim Jagielski {
1328*b1cdbd2cSJim Jagielski 	DBG_TRACE( "OutputDevice::SetFillColor()" );
1329*b1cdbd2cSJim Jagielski 	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1330*b1cdbd2cSJim Jagielski 
1331*b1cdbd2cSJim Jagielski 	if ( mpMetaFile )
1332*b1cdbd2cSJim Jagielski 		mpMetaFile->AddAction( new MetaFillColorAction( Color(), sal_False ) );
1333*b1cdbd2cSJim Jagielski 
1334*b1cdbd2cSJim Jagielski 	if ( mbFillColor )
1335*b1cdbd2cSJim Jagielski 	{
1336*b1cdbd2cSJim Jagielski 		mbInitFillColor = sal_True;
1337*b1cdbd2cSJim Jagielski 		mbFillColor = sal_False;
1338*b1cdbd2cSJim Jagielski 		maFillColor = Color( COL_TRANSPARENT );
1339*b1cdbd2cSJim Jagielski 	}
1340*b1cdbd2cSJim Jagielski 
1341*b1cdbd2cSJim Jagielski     if( mpAlphaVDev )
1342*b1cdbd2cSJim Jagielski         mpAlphaVDev->SetFillColor();
1343*b1cdbd2cSJim Jagielski }
1344*b1cdbd2cSJim Jagielski 
1345*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
1346*b1cdbd2cSJim Jagielski 
SetFillColor(const Color & rColor)1347*b1cdbd2cSJim Jagielski void OutputDevice::SetFillColor( const Color& rColor )
1348*b1cdbd2cSJim Jagielski {
1349*b1cdbd2cSJim Jagielski 	DBG_TRACE1( "OutputDevice::SetFillColor( %lx )", rColor.GetColor() );
1350*b1cdbd2cSJim Jagielski 	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1351*b1cdbd2cSJim Jagielski 
1352*b1cdbd2cSJim Jagielski 	Color aColor( rColor );
1353*b1cdbd2cSJim Jagielski 
1354*b1cdbd2cSJim Jagielski 	if( mnDrawMode & ( DRAWMODE_BLACKFILL | DRAWMODE_WHITEFILL |
1355*b1cdbd2cSJim Jagielski 					   DRAWMODE_GRAYFILL | DRAWMODE_NOFILL |
1356*b1cdbd2cSJim Jagielski 					   DRAWMODE_GHOSTEDFILL | DRAWMODE_SETTINGSFILL ) )
1357*b1cdbd2cSJim Jagielski 	{
1358*b1cdbd2cSJim Jagielski 		if( !ImplIsColorTransparent( aColor ) )
1359*b1cdbd2cSJim Jagielski 		{
1360*b1cdbd2cSJim Jagielski 			if( mnDrawMode & DRAWMODE_BLACKFILL )
1361*b1cdbd2cSJim Jagielski 			{
1362*b1cdbd2cSJim Jagielski 				aColor = Color( COL_BLACK );
1363*b1cdbd2cSJim Jagielski 			}
1364*b1cdbd2cSJim Jagielski 			else if( mnDrawMode & DRAWMODE_WHITEFILL )
1365*b1cdbd2cSJim Jagielski 			{
1366*b1cdbd2cSJim Jagielski 				aColor = Color( COL_WHITE );
1367*b1cdbd2cSJim Jagielski 			}
1368*b1cdbd2cSJim Jagielski 			else if( mnDrawMode & DRAWMODE_GRAYFILL )
1369*b1cdbd2cSJim Jagielski 			{
1370*b1cdbd2cSJim Jagielski 				const sal_uInt8 cLum = aColor.GetLuminance();
1371*b1cdbd2cSJim Jagielski 				aColor = Color( cLum, cLum, cLum );
1372*b1cdbd2cSJim Jagielski 			}
1373*b1cdbd2cSJim Jagielski 			else if( mnDrawMode & DRAWMODE_NOFILL )
1374*b1cdbd2cSJim Jagielski 			{
1375*b1cdbd2cSJim Jagielski 				aColor = Color( COL_TRANSPARENT );
1376*b1cdbd2cSJim Jagielski 			}
1377*b1cdbd2cSJim Jagielski             else if( mnDrawMode & DRAWMODE_SETTINGSFILL )
1378*b1cdbd2cSJim Jagielski             {
1379*b1cdbd2cSJim Jagielski                 aColor = GetSettings().GetStyleSettings().GetWindowColor();
1380*b1cdbd2cSJim Jagielski             }
1381*b1cdbd2cSJim Jagielski 
1382*b1cdbd2cSJim Jagielski 			if( mnDrawMode & DRAWMODE_GHOSTEDFILL )
1383*b1cdbd2cSJim Jagielski 			{
1384*b1cdbd2cSJim Jagielski 				aColor = Color( (aColor.GetRed() >> 1) | 0x80,
1385*b1cdbd2cSJim Jagielski 								(aColor.GetGreen() >> 1) | 0x80,
1386*b1cdbd2cSJim Jagielski 								(aColor.GetBlue() >> 1) | 0x80);
1387*b1cdbd2cSJim Jagielski 			}
1388*b1cdbd2cSJim Jagielski 		}
1389*b1cdbd2cSJim Jagielski 	}
1390*b1cdbd2cSJim Jagielski 
1391*b1cdbd2cSJim Jagielski 	if ( mpMetaFile )
1392*b1cdbd2cSJim Jagielski 		mpMetaFile->AddAction( new MetaFillColorAction( aColor, sal_True ) );
1393*b1cdbd2cSJim Jagielski 
1394*b1cdbd2cSJim Jagielski 	if ( ImplIsColorTransparent( aColor ) )
1395*b1cdbd2cSJim Jagielski 	{
1396*b1cdbd2cSJim Jagielski 		if ( mbFillColor )
1397*b1cdbd2cSJim Jagielski 		{
1398*b1cdbd2cSJim Jagielski 			mbInitFillColor = sal_True;
1399*b1cdbd2cSJim Jagielski 			mbFillColor = sal_False;
1400*b1cdbd2cSJim Jagielski 			maFillColor = Color( COL_TRANSPARENT );
1401*b1cdbd2cSJim Jagielski 		}
1402*b1cdbd2cSJim Jagielski 	}
1403*b1cdbd2cSJim Jagielski 	else
1404*b1cdbd2cSJim Jagielski 	{
1405*b1cdbd2cSJim Jagielski 		if ( maFillColor != aColor )
1406*b1cdbd2cSJim Jagielski 		{
1407*b1cdbd2cSJim Jagielski 			mbInitFillColor = sal_True;
1408*b1cdbd2cSJim Jagielski 			mbFillColor = sal_True;
1409*b1cdbd2cSJim Jagielski 			maFillColor = aColor;
1410*b1cdbd2cSJim Jagielski 		}
1411*b1cdbd2cSJim Jagielski 	}
1412*b1cdbd2cSJim Jagielski 
1413*b1cdbd2cSJim Jagielski     if( mpAlphaVDev )
1414*b1cdbd2cSJim Jagielski         mpAlphaVDev->SetFillColor( COL_BLACK );
1415*b1cdbd2cSJim Jagielski }
1416*b1cdbd2cSJim Jagielski 
1417*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
1418*b1cdbd2cSJim Jagielski 
SetBackground()1419*b1cdbd2cSJim Jagielski void OutputDevice::SetBackground()
1420*b1cdbd2cSJim Jagielski {
1421*b1cdbd2cSJim Jagielski 	DBG_TRACE( "OutputDevice::SetBackground()" );
1422*b1cdbd2cSJim Jagielski 	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1423*b1cdbd2cSJim Jagielski 
1424*b1cdbd2cSJim Jagielski 	maBackground = Wallpaper();
1425*b1cdbd2cSJim Jagielski 	mbBackground = sal_False;
1426*b1cdbd2cSJim Jagielski 
1427*b1cdbd2cSJim Jagielski     if( mpAlphaVDev )
1428*b1cdbd2cSJim Jagielski         mpAlphaVDev->SetBackground();
1429*b1cdbd2cSJim Jagielski }
1430*b1cdbd2cSJim Jagielski 
1431*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
1432*b1cdbd2cSJim Jagielski 
SetBackground(const Wallpaper & rBackground)1433*b1cdbd2cSJim Jagielski void OutputDevice::SetBackground( const Wallpaper& rBackground )
1434*b1cdbd2cSJim Jagielski {
1435*b1cdbd2cSJim Jagielski 	DBG_TRACE( "OutputDevice::SetBackground( rBackground )" );
1436*b1cdbd2cSJim Jagielski 	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1437*b1cdbd2cSJim Jagielski 
1438*b1cdbd2cSJim Jagielski 	maBackground = rBackground;
1439*b1cdbd2cSJim Jagielski 
1440*b1cdbd2cSJim Jagielski 	if( rBackground.GetStyle() == WALLPAPER_NULL )
1441*b1cdbd2cSJim Jagielski 		mbBackground = sal_False;
1442*b1cdbd2cSJim Jagielski 	else
1443*b1cdbd2cSJim Jagielski 		mbBackground = sal_True;
1444*b1cdbd2cSJim Jagielski 
1445*b1cdbd2cSJim Jagielski     if( mpAlphaVDev )
1446*b1cdbd2cSJim Jagielski         mpAlphaVDev->SetBackground( rBackground );
1447*b1cdbd2cSJim Jagielski }
1448*b1cdbd2cSJim Jagielski 
1449*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
1450*b1cdbd2cSJim Jagielski 
SetRefPoint()1451*b1cdbd2cSJim Jagielski void OutputDevice::SetRefPoint()
1452*b1cdbd2cSJim Jagielski {
1453*b1cdbd2cSJim Jagielski 	DBG_TRACE( "OutputDevice::SetRefPoint()" );
1454*b1cdbd2cSJim Jagielski 	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1455*b1cdbd2cSJim Jagielski 
1456*b1cdbd2cSJim Jagielski 	if ( mpMetaFile )
1457*b1cdbd2cSJim Jagielski 		mpMetaFile->AddAction( new MetaRefPointAction( Point(), sal_False ) );
1458*b1cdbd2cSJim Jagielski 
1459*b1cdbd2cSJim Jagielski 	mbRefPoint = sal_False;
1460*b1cdbd2cSJim Jagielski 	maRefPoint.X() = maRefPoint.Y() = 0L;
1461*b1cdbd2cSJim Jagielski 
1462*b1cdbd2cSJim Jagielski     if( mpAlphaVDev )
1463*b1cdbd2cSJim Jagielski         mpAlphaVDev->SetRefPoint();
1464*b1cdbd2cSJim Jagielski }
1465*b1cdbd2cSJim Jagielski 
1466*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
1467*b1cdbd2cSJim Jagielski 
SetRefPoint(const Point & rRefPoint)1468*b1cdbd2cSJim Jagielski void OutputDevice::SetRefPoint( const Point& rRefPoint )
1469*b1cdbd2cSJim Jagielski {
1470*b1cdbd2cSJim Jagielski 	DBG_TRACE( "OutputDevice::SetRefPoint( rRefPoint )" );
1471*b1cdbd2cSJim Jagielski 	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1472*b1cdbd2cSJim Jagielski 
1473*b1cdbd2cSJim Jagielski 	if ( mpMetaFile )
1474*b1cdbd2cSJim Jagielski 		mpMetaFile->AddAction( new MetaRefPointAction( rRefPoint, sal_True ) );
1475*b1cdbd2cSJim Jagielski 
1476*b1cdbd2cSJim Jagielski 	mbRefPoint = sal_True;
1477*b1cdbd2cSJim Jagielski 	maRefPoint = rRefPoint;
1478*b1cdbd2cSJim Jagielski 
1479*b1cdbd2cSJim Jagielski     if( mpAlphaVDev )
1480*b1cdbd2cSJim Jagielski         mpAlphaVDev->SetRefPoint( rRefPoint );
1481*b1cdbd2cSJim Jagielski }
1482*b1cdbd2cSJim Jagielski 
1483*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
1484*b1cdbd2cSJim Jagielski 
DrawLine(const Point & rStartPt,const Point & rEndPt)1485*b1cdbd2cSJim Jagielski void OutputDevice::DrawLine( const Point& rStartPt, const Point& rEndPt )
1486*b1cdbd2cSJim Jagielski {
1487*b1cdbd2cSJim Jagielski 	DBG_TRACE( "OutputDevice::DrawLine()" );
1488*b1cdbd2cSJim Jagielski 	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1489*b1cdbd2cSJim Jagielski 
1490*b1cdbd2cSJim Jagielski 	if ( mpMetaFile )
1491*b1cdbd2cSJim Jagielski 		mpMetaFile->AddAction( new MetaLineAction( rStartPt, rEndPt ) );
1492*b1cdbd2cSJim Jagielski 
1493*b1cdbd2cSJim Jagielski 	if ( !IsDeviceOutputNecessary() || !mbLineColor || ImplIsRecordLayout() )
1494*b1cdbd2cSJim Jagielski 		return;
1495*b1cdbd2cSJim Jagielski 
1496*b1cdbd2cSJim Jagielski 	if ( !mpGraphics )
1497*b1cdbd2cSJim Jagielski 	{
1498*b1cdbd2cSJim Jagielski 		if ( !ImplGetGraphics() )
1499*b1cdbd2cSJim Jagielski 			return;
1500*b1cdbd2cSJim Jagielski 	}
1501*b1cdbd2cSJim Jagielski 
1502*b1cdbd2cSJim Jagielski 	if ( mbInitClipRegion )
1503*b1cdbd2cSJim Jagielski 		ImplInitClipRegion();
1504*b1cdbd2cSJim Jagielski 	if ( mbOutputClipped )
1505*b1cdbd2cSJim Jagielski 		return;
1506*b1cdbd2cSJim Jagielski 
1507*b1cdbd2cSJim Jagielski 	if ( mbInitLineColor )
1508*b1cdbd2cSJim Jagielski 		ImplInitLineColor();
1509*b1cdbd2cSJim Jagielski 
1510*b1cdbd2cSJim Jagielski 	// #i101598# support AA and snap for lines, too
1511*b1cdbd2cSJim Jagielski 	if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
1512*b1cdbd2cSJim Jagielski 		&& mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
1513*b1cdbd2cSJim Jagielski 		&& ROP_OVERPAINT == GetRasterOp()
1514*b1cdbd2cSJim Jagielski 		&& IsLineColor())
1515*b1cdbd2cSJim Jagielski 	{
1516*b1cdbd2cSJim Jagielski 		// at least transform with double precision to device coordinates; this will
1517*b1cdbd2cSJim Jagielski 		// avoid pixel snap of single, appended lines
1518*b1cdbd2cSJim Jagielski 		const basegfx::B2DHomMatrix aTransform(ImplGetDeviceTransformation());
1519*b1cdbd2cSJim Jagielski         const basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 );
1520*b1cdbd2cSJim Jagielski 		basegfx::B2DPolygon aB2DPolyLine;
1521*b1cdbd2cSJim Jagielski 
1522*b1cdbd2cSJim Jagielski 		aB2DPolyLine.append(basegfx::B2DPoint(rStartPt.X(), rStartPt.Y()));
1523*b1cdbd2cSJim Jagielski 		aB2DPolyLine.append(basegfx::B2DPoint(rEndPt.X(), rEndPt.Y()));
1524*b1cdbd2cSJim Jagielski 		aB2DPolyLine.transform( aTransform );
1525*b1cdbd2cSJim Jagielski 
1526*b1cdbd2cSJim Jagielski         if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
1527*b1cdbd2cSJim Jagielski         {
1528*b1cdbd2cSJim Jagielski             aB2DPolyLine = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyLine);
1529*b1cdbd2cSJim Jagielski         }
1530*b1cdbd2cSJim Jagielski 
1531*b1cdbd2cSJim Jagielski 		if( mpGraphics->DrawPolyLine( aB2DPolyLine, 0.0, aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, com::sun::star::drawing::LineCap_BUTT, this))
1532*b1cdbd2cSJim Jagielski 		{
1533*b1cdbd2cSJim Jagielski 			return;
1534*b1cdbd2cSJim Jagielski 		}
1535*b1cdbd2cSJim Jagielski 	}
1536*b1cdbd2cSJim Jagielski 
1537*b1cdbd2cSJim Jagielski 	const Point aStartPt(ImplLogicToDevicePixel(rStartPt));
1538*b1cdbd2cSJim Jagielski 	const Point aEndPt(ImplLogicToDevicePixel(rEndPt));
1539*b1cdbd2cSJim Jagielski 
1540*b1cdbd2cSJim Jagielski 	mpGraphics->DrawLine( aStartPt.X(), aStartPt.Y(), aEndPt.X(), aEndPt.Y(), this );
1541*b1cdbd2cSJim Jagielski 
1542*b1cdbd2cSJim Jagielski     if( mpAlphaVDev )
1543*b1cdbd2cSJim Jagielski         mpAlphaVDev->DrawLine( rStartPt, rEndPt );
1544*b1cdbd2cSJim Jagielski }
1545*b1cdbd2cSJim Jagielski 
1546*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
1547*b1cdbd2cSJim Jagielski 
impPaintLineGeometryWithEvtlExpand(const LineInfo & rInfo,basegfx::B2DPolyPolygon aLinePolyPolygon)1548*b1cdbd2cSJim Jagielski void OutputDevice::impPaintLineGeometryWithEvtlExpand(
1549*b1cdbd2cSJim Jagielski     const LineInfo& rInfo,
1550*b1cdbd2cSJim Jagielski     basegfx::B2DPolyPolygon aLinePolyPolygon)
1551*b1cdbd2cSJim Jagielski {
1552*b1cdbd2cSJim Jagielski     const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
1553*b1cdbd2cSJim Jagielski         && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
1554*b1cdbd2cSJim Jagielski         && ROP_OVERPAINT == GetRasterOp()
1555*b1cdbd2cSJim Jagielski         && IsLineColor());
1556*b1cdbd2cSJim Jagielski     basegfx::B2DPolyPolygon aFillPolyPolygon;
1557*b1cdbd2cSJim Jagielski     const bool bDashUsed(LINE_DASH == rInfo.GetStyle());
1558*b1cdbd2cSJim Jagielski     const bool bLineWidthUsed(rInfo.GetWidth() > 1);
1559*b1cdbd2cSJim Jagielski 
1560*b1cdbd2cSJim Jagielski     if(bDashUsed && aLinePolyPolygon.count())
1561*b1cdbd2cSJim Jagielski     {
1562*b1cdbd2cSJim Jagielski         ::std::vector< double > fDotDashArray;
1563*b1cdbd2cSJim Jagielski         const double fDashLen(rInfo.GetDashLen());
1564*b1cdbd2cSJim Jagielski         const double fDotLen(rInfo.GetDotLen());
1565*b1cdbd2cSJim Jagielski         const double fDistance(rInfo.GetDistance());
1566*b1cdbd2cSJim Jagielski 
1567*b1cdbd2cSJim Jagielski         for(sal_uInt16 a(0); a < rInfo.GetDashCount(); a++)
1568*b1cdbd2cSJim Jagielski         {
1569*b1cdbd2cSJim Jagielski             fDotDashArray.push_back(fDashLen);
1570*b1cdbd2cSJim Jagielski             fDotDashArray.push_back(fDistance);
1571*b1cdbd2cSJim Jagielski         }
1572*b1cdbd2cSJim Jagielski 
1573*b1cdbd2cSJim Jagielski         for(sal_uInt16 b(0); b < rInfo.GetDotCount(); b++)
1574*b1cdbd2cSJim Jagielski         {
1575*b1cdbd2cSJim Jagielski             fDotDashArray.push_back(fDotLen);
1576*b1cdbd2cSJim Jagielski             fDotDashArray.push_back(fDistance);
1577*b1cdbd2cSJim Jagielski         }
1578*b1cdbd2cSJim Jagielski 
1579*b1cdbd2cSJim Jagielski         const double fAccumulated(::std::accumulate(fDotDashArray.begin(), fDotDashArray.end(), 0.0));
1580*b1cdbd2cSJim Jagielski 
1581*b1cdbd2cSJim Jagielski         if(fAccumulated > 0.0)
1582*b1cdbd2cSJim Jagielski         {
1583*b1cdbd2cSJim Jagielski             basegfx::B2DPolyPolygon aResult;
1584*b1cdbd2cSJim Jagielski 
1585*b1cdbd2cSJim Jagielski             for(sal_uInt32 c(0); c < aLinePolyPolygon.count(); c++)
1586*b1cdbd2cSJim Jagielski             {
1587*b1cdbd2cSJim Jagielski                 basegfx::B2DPolyPolygon aLineTraget;
1588*b1cdbd2cSJim Jagielski                 basegfx::tools::applyLineDashing(
1589*b1cdbd2cSJim Jagielski                     aLinePolyPolygon.getB2DPolygon(c),
1590*b1cdbd2cSJim Jagielski                     fDotDashArray,
1591*b1cdbd2cSJim Jagielski                     &aLineTraget);
1592*b1cdbd2cSJim Jagielski                 aResult.append(aLineTraget);
1593*b1cdbd2cSJim Jagielski             }
1594*b1cdbd2cSJim Jagielski 
1595*b1cdbd2cSJim Jagielski             aLinePolyPolygon = aResult;
1596*b1cdbd2cSJim Jagielski         }
1597*b1cdbd2cSJim Jagielski     }
1598*b1cdbd2cSJim Jagielski 
1599*b1cdbd2cSJim Jagielski     if(bLineWidthUsed && aLinePolyPolygon.count())
1600*b1cdbd2cSJim Jagielski     {
1601*b1cdbd2cSJim Jagielski 	    const double fHalfLineWidth((rInfo.GetWidth() * 0.5) + 0.5);
1602*b1cdbd2cSJim Jagielski 
1603*b1cdbd2cSJim Jagielski 		if(aLinePolyPolygon.areControlPointsUsed())
1604*b1cdbd2cSJim Jagielski 		{
1605*b1cdbd2cSJim Jagielski 			// #i110768# When area geometry has to be created, do not
1606*b1cdbd2cSJim Jagielski 			// use the fallback bezier decomposition inside createAreaGeometry,
1607*b1cdbd2cSJim Jagielski 			// but one that is at least as good as ImplSubdivideBezier was.
1608*b1cdbd2cSJim Jagielski 			// There, Polygon::AdaptiveSubdivide was used with default parameter
1609*b1cdbd2cSJim Jagielski 			// 1.0 as quality index.
1610*b1cdbd2cSJim Jagielski 			aLinePolyPolygon = basegfx::tools::adaptiveSubdivideByDistance(aLinePolyPolygon, 1.0);
1611*b1cdbd2cSJim Jagielski 		}
1612*b1cdbd2cSJim Jagielski 
1613*b1cdbd2cSJim Jagielski         for(sal_uInt32 a(0); a < aLinePolyPolygon.count(); a++)
1614*b1cdbd2cSJim Jagielski         {
1615*b1cdbd2cSJim Jagielski 	        aFillPolyPolygon.append(basegfx::tools::createAreaGeometry(
1616*b1cdbd2cSJim Jagielski                 aLinePolyPolygon.getB2DPolygon(a),
1617*b1cdbd2cSJim Jagielski                 fHalfLineWidth,
1618*b1cdbd2cSJim Jagielski                 rInfo.GetLineJoin(),
1619*b1cdbd2cSJim Jagielski                 rInfo.GetLineCap()));
1620*b1cdbd2cSJim Jagielski         }
1621*b1cdbd2cSJim Jagielski 
1622*b1cdbd2cSJim Jagielski         aLinePolyPolygon.clear();
1623*b1cdbd2cSJim Jagielski     }
1624*b1cdbd2cSJim Jagielski 
1625*b1cdbd2cSJim Jagielski     GDIMetaFile* pOldMetaFile = mpMetaFile;
1626*b1cdbd2cSJim Jagielski     mpMetaFile = NULL;
1627*b1cdbd2cSJim Jagielski 
1628*b1cdbd2cSJim Jagielski     if(aLinePolyPolygon.count())
1629*b1cdbd2cSJim Jagielski     {
1630*b1cdbd2cSJim Jagielski         for(sal_uInt32 a(0); a < aLinePolyPolygon.count(); a++)
1631*b1cdbd2cSJim Jagielski         {
1632*b1cdbd2cSJim Jagielski             const basegfx::B2DPolygon aCandidate(aLinePolyPolygon.getB2DPolygon(a));
1633*b1cdbd2cSJim Jagielski             bool bDone(false);
1634*b1cdbd2cSJim Jagielski 
1635*b1cdbd2cSJim Jagielski             if(bTryAA)
1636*b1cdbd2cSJim Jagielski             {
1637*b1cdbd2cSJim Jagielski                 bDone = mpGraphics->DrawPolyLine( aCandidate, 0.0, basegfx::B2DVector(1.0,1.0), basegfx::B2DLINEJOIN_NONE, com::sun::star::drawing::LineCap_BUTT, this);
1638*b1cdbd2cSJim Jagielski             }
1639*b1cdbd2cSJim Jagielski 
1640*b1cdbd2cSJim Jagielski             if(!bDone)
1641*b1cdbd2cSJim Jagielski             {
1642*b1cdbd2cSJim Jagielski                 const Polygon aPolygon(aCandidate);
1643*b1cdbd2cSJim Jagielski 		        mpGraphics->DrawPolyLine(aPolygon.GetSize(), (const SalPoint*)aPolygon.GetConstPointAry(), this);
1644*b1cdbd2cSJim Jagielski             }
1645*b1cdbd2cSJim Jagielski         }
1646*b1cdbd2cSJim Jagielski     }
1647*b1cdbd2cSJim Jagielski 
1648*b1cdbd2cSJim Jagielski     if(aFillPolyPolygon.count())
1649*b1cdbd2cSJim Jagielski     {
1650*b1cdbd2cSJim Jagielski         const Color 	aOldLineColor( maLineColor );
1651*b1cdbd2cSJim Jagielski         const Color 	aOldFillColor( maFillColor );
1652*b1cdbd2cSJim Jagielski 
1653*b1cdbd2cSJim Jagielski         SetLineColor();
1654*b1cdbd2cSJim Jagielski         ImplInitLineColor();
1655*b1cdbd2cSJim Jagielski         SetFillColor( aOldLineColor );
1656*b1cdbd2cSJim Jagielski         ImplInitFillColor();
1657*b1cdbd2cSJim Jagielski 
1658*b1cdbd2cSJim Jagielski         bool bDone(false);
1659*b1cdbd2cSJim Jagielski 
1660*b1cdbd2cSJim Jagielski         if(bTryAA)
1661*b1cdbd2cSJim Jagielski         {
1662*b1cdbd2cSJim Jagielski             bDone = mpGraphics->DrawPolyPolygon(aFillPolyPolygon, 0.0, this);
1663*b1cdbd2cSJim Jagielski         }
1664*b1cdbd2cSJim Jagielski 
1665*b1cdbd2cSJim Jagielski         if(!bDone)
1666*b1cdbd2cSJim Jagielski         {
1667*b1cdbd2cSJim Jagielski             for(sal_uInt32 a(0); a < aFillPolyPolygon.count(); a++)
1668*b1cdbd2cSJim Jagielski             {
1669*b1cdbd2cSJim Jagielski                 Polygon aPolygon(aFillPolyPolygon.getB2DPolygon(a));
1670*b1cdbd2cSJim Jagielski 
1671*b1cdbd2cSJim Jagielski                 // need to subdivide, mpGraphics->DrawPolygon ignores curves
1672*b1cdbd2cSJim Jagielski                 aPolygon.AdaptiveSubdivide(aPolygon);
1673*b1cdbd2cSJim Jagielski 			    mpGraphics->DrawPolygon(aPolygon.GetSize(), (const SalPoint*)aPolygon.GetConstPointAry(), this);
1674*b1cdbd2cSJim Jagielski             }
1675*b1cdbd2cSJim Jagielski         }
1676*b1cdbd2cSJim Jagielski 
1677*b1cdbd2cSJim Jagielski         SetFillColor( aOldFillColor );
1678*b1cdbd2cSJim Jagielski         SetLineColor( aOldLineColor );
1679*b1cdbd2cSJim Jagielski     }
1680*b1cdbd2cSJim Jagielski 
1681*b1cdbd2cSJim Jagielski     mpMetaFile = pOldMetaFile;
1682*b1cdbd2cSJim Jagielski }
1683*b1cdbd2cSJim Jagielski 
1684*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
1685*b1cdbd2cSJim Jagielski 
DrawLine(const Point & rStartPt,const Point & rEndPt,const LineInfo & rLineInfo)1686*b1cdbd2cSJim Jagielski void OutputDevice::DrawLine( const Point& rStartPt, const Point& rEndPt,
1687*b1cdbd2cSJim Jagielski 							 const LineInfo& rLineInfo )
1688*b1cdbd2cSJim Jagielski {
1689*b1cdbd2cSJim Jagielski 	DBG_TRACE( "OutputDevice::DrawLine()" );
1690*b1cdbd2cSJim Jagielski 	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1691*b1cdbd2cSJim Jagielski 
1692*b1cdbd2cSJim Jagielski 	if ( rLineInfo.IsDefault() )
1693*b1cdbd2cSJim Jagielski 	{
1694*b1cdbd2cSJim Jagielski 		DrawLine( rStartPt, rEndPt );
1695*b1cdbd2cSJim Jagielski 		return;
1696*b1cdbd2cSJim Jagielski 	}
1697*b1cdbd2cSJim Jagielski 
1698*b1cdbd2cSJim Jagielski 	if ( mpMetaFile )
1699*b1cdbd2cSJim Jagielski 		mpMetaFile->AddAction( new MetaLineAction( rStartPt, rEndPt, rLineInfo ) );
1700*b1cdbd2cSJim Jagielski 
1701*b1cdbd2cSJim Jagielski 	if ( !IsDeviceOutputNecessary() || !mbLineColor || ( LINE_NONE == rLineInfo.GetStyle() ) || ImplIsRecordLayout() )
1702*b1cdbd2cSJim Jagielski 		return;
1703*b1cdbd2cSJim Jagielski 
1704*b1cdbd2cSJim Jagielski 	if( !mpGraphics && !ImplGetGraphics() )
1705*b1cdbd2cSJim Jagielski 		return;
1706*b1cdbd2cSJim Jagielski 
1707*b1cdbd2cSJim Jagielski 	if ( mbInitClipRegion )
1708*b1cdbd2cSJim Jagielski 		ImplInitClipRegion();
1709*b1cdbd2cSJim Jagielski 
1710*b1cdbd2cSJim Jagielski 	if ( mbOutputClipped )
1711*b1cdbd2cSJim Jagielski 		return;
1712*b1cdbd2cSJim Jagielski 
1713*b1cdbd2cSJim Jagielski 	const Point aStartPt( ImplLogicToDevicePixel( rStartPt ) );
1714*b1cdbd2cSJim Jagielski 	const Point aEndPt( ImplLogicToDevicePixel( rEndPt ) );
1715*b1cdbd2cSJim Jagielski 	const LineInfo aInfo( ImplLogicToDevicePixel( rLineInfo ) );
1716*b1cdbd2cSJim Jagielski     const bool bDashUsed(LINE_DASH == aInfo.GetStyle());
1717*b1cdbd2cSJim Jagielski     const bool bLineWidthUsed(aInfo.GetWidth() > 1);
1718*b1cdbd2cSJim Jagielski 
1719*b1cdbd2cSJim Jagielski     if ( mbInitLineColor )
1720*b1cdbd2cSJim Jagielski         ImplInitLineColor();
1721*b1cdbd2cSJim Jagielski 
1722*b1cdbd2cSJim Jagielski     if(bDashUsed || bLineWidthUsed)
1723*b1cdbd2cSJim Jagielski     {
1724*b1cdbd2cSJim Jagielski         basegfx::B2DPolygon aLinePolygon;
1725*b1cdbd2cSJim Jagielski         aLinePolygon.append(basegfx::B2DPoint(aStartPt.X(), aStartPt.Y()));
1726*b1cdbd2cSJim Jagielski         aLinePolygon.append(basegfx::B2DPoint(aEndPt.X(), aEndPt.Y()));
1727*b1cdbd2cSJim Jagielski 
1728*b1cdbd2cSJim Jagielski         impPaintLineGeometryWithEvtlExpand(aInfo, basegfx::B2DPolyPolygon(aLinePolygon));
1729*b1cdbd2cSJim Jagielski     }
1730*b1cdbd2cSJim Jagielski 	else
1731*b1cdbd2cSJim Jagielski 	{
1732*b1cdbd2cSJim Jagielski 		mpGraphics->DrawLine( aStartPt.X(), aStartPt.Y(), aEndPt.X(), aEndPt.Y(), this );
1733*b1cdbd2cSJim Jagielski 	}
1734*b1cdbd2cSJim Jagielski 
1735*b1cdbd2cSJim Jagielski     if( mpAlphaVDev )
1736*b1cdbd2cSJim Jagielski         mpAlphaVDev->DrawLine( rStartPt, rEndPt, rLineInfo );
1737*b1cdbd2cSJim Jagielski }
1738*b1cdbd2cSJim Jagielski 
1739*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
1740*b1cdbd2cSJim Jagielski 
DrawRect(const Rectangle & rRect)1741*b1cdbd2cSJim Jagielski void OutputDevice::DrawRect( const Rectangle& rRect )
1742*b1cdbd2cSJim Jagielski {
1743*b1cdbd2cSJim Jagielski 	DBG_TRACE( "OutputDevice::DrawRect()" );
1744*b1cdbd2cSJim Jagielski 	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1745*b1cdbd2cSJim Jagielski 
1746*b1cdbd2cSJim Jagielski 	if ( mpMetaFile )
1747*b1cdbd2cSJim Jagielski 		mpMetaFile->AddAction( new MetaRectAction( rRect ) );
1748*b1cdbd2cSJim Jagielski 
1749*b1cdbd2cSJim Jagielski 	if ( !IsDeviceOutputNecessary() || (!mbLineColor && !mbFillColor) || ImplIsRecordLayout() )
1750*b1cdbd2cSJim Jagielski 		return;
1751*b1cdbd2cSJim Jagielski 
1752*b1cdbd2cSJim Jagielski 	Rectangle aRect( ImplLogicToDevicePixel( rRect ) );
1753*b1cdbd2cSJim Jagielski 
1754*b1cdbd2cSJim Jagielski 	if ( aRect.IsEmpty() )
1755*b1cdbd2cSJim Jagielski 		return;
1756*b1cdbd2cSJim Jagielski 	aRect.Justify();
1757*b1cdbd2cSJim Jagielski 
1758*b1cdbd2cSJim Jagielski 	if ( !mpGraphics )
1759*b1cdbd2cSJim Jagielski 	{
1760*b1cdbd2cSJim Jagielski 		if ( !ImplGetGraphics() )
1761*b1cdbd2cSJim Jagielski 			return;
1762*b1cdbd2cSJim Jagielski 	}
1763*b1cdbd2cSJim Jagielski 
1764*b1cdbd2cSJim Jagielski 	if ( mbInitClipRegion )
1765*b1cdbd2cSJim Jagielski 		ImplInitClipRegion();
1766*b1cdbd2cSJim Jagielski 	if ( mbOutputClipped )
1767*b1cdbd2cSJim Jagielski 		return;
1768*b1cdbd2cSJim Jagielski 
1769*b1cdbd2cSJim Jagielski 	if ( mbInitLineColor )
1770*b1cdbd2cSJim Jagielski 		ImplInitLineColor();
1771*b1cdbd2cSJim Jagielski 	if ( mbInitFillColor )
1772*b1cdbd2cSJim Jagielski 		ImplInitFillColor();
1773*b1cdbd2cSJim Jagielski 
1774*b1cdbd2cSJim Jagielski 	mpGraphics->DrawRect( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(), this );
1775*b1cdbd2cSJim Jagielski 
1776*b1cdbd2cSJim Jagielski     if( mpAlphaVDev )
1777*b1cdbd2cSJim Jagielski         mpAlphaVDev->DrawRect( rRect );
1778*b1cdbd2cSJim Jagielski }
1779*b1cdbd2cSJim Jagielski 
1780*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
1781*b1cdbd2cSJim Jagielski 
DrawPolyLine(const Polygon & rPoly)1782*b1cdbd2cSJim Jagielski void OutputDevice::DrawPolyLine( const Polygon& rPoly )
1783*b1cdbd2cSJim Jagielski {
1784*b1cdbd2cSJim Jagielski 	DBG_TRACE( "OutputDevice::DrawPolyLine()" );
1785*b1cdbd2cSJim Jagielski 	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1786*b1cdbd2cSJim Jagielski 	DBG_CHKOBJ( &rPoly, Polygon, NULL );
1787*b1cdbd2cSJim Jagielski 
1788*b1cdbd2cSJim Jagielski 	if( mpMetaFile )
1789*b1cdbd2cSJim Jagielski 		mpMetaFile->AddAction( new MetaPolyLineAction( rPoly ) );
1790*b1cdbd2cSJim Jagielski 
1791*b1cdbd2cSJim Jagielski 	sal_uInt16 nPoints = rPoly.GetSize();
1792*b1cdbd2cSJim Jagielski 
1793*b1cdbd2cSJim Jagielski 	if ( !IsDeviceOutputNecessary() || !mbLineColor || (nPoints < 2) || ImplIsRecordLayout() )
1794*b1cdbd2cSJim Jagielski 		return;
1795*b1cdbd2cSJim Jagielski 
1796*b1cdbd2cSJim Jagielski 	// we need a graphics
1797*b1cdbd2cSJim Jagielski 	if ( !mpGraphics )
1798*b1cdbd2cSJim Jagielski 		if ( !ImplGetGraphics() )
1799*b1cdbd2cSJim Jagielski 			return;
1800*b1cdbd2cSJim Jagielski 
1801*b1cdbd2cSJim Jagielski 	if ( mbInitClipRegion )
1802*b1cdbd2cSJim Jagielski 		ImplInitClipRegion();
1803*b1cdbd2cSJim Jagielski 	if ( mbOutputClipped )
1804*b1cdbd2cSJim Jagielski 		return;
1805*b1cdbd2cSJim Jagielski 
1806*b1cdbd2cSJim Jagielski 	if ( mbInitLineColor )
1807*b1cdbd2cSJim Jagielski 		ImplInitLineColor();
1808*b1cdbd2cSJim Jagielski 
1809*b1cdbd2cSJim Jagielski     const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
1810*b1cdbd2cSJim Jagielski         && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
1811*b1cdbd2cSJim Jagielski         && ROP_OVERPAINT == GetRasterOp()
1812*b1cdbd2cSJim Jagielski         && IsLineColor());
1813*b1cdbd2cSJim Jagielski 
1814*b1cdbd2cSJim Jagielski 	// use b2dpolygon drawing if possible
1815*b1cdbd2cSJim Jagielski 	if(bTryAA && ImpTryDrawPolyLineDirect(rPoly.getB2DPolygon()))
1816*b1cdbd2cSJim Jagielski 	{
1817*b1cdbd2cSJim Jagielski 		basegfx::B2DPolygon aB2DPolyLine(rPoly.getB2DPolygon());
1818*b1cdbd2cSJim Jagielski 		const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation();
1819*b1cdbd2cSJim Jagielski         const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 );
1820*b1cdbd2cSJim Jagielski 
1821*b1cdbd2cSJim Jagielski         // transform the polygon
1822*b1cdbd2cSJim Jagielski 		aB2DPolyLine.transform( aTransform );
1823*b1cdbd2cSJim Jagielski 
1824*b1cdbd2cSJim Jagielski         if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
1825*b1cdbd2cSJim Jagielski         {
1826*b1cdbd2cSJim Jagielski             aB2DPolyLine = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyLine);
1827*b1cdbd2cSJim Jagielski         }
1828*b1cdbd2cSJim Jagielski 
1829*b1cdbd2cSJim Jagielski 		if(mpGraphics->DrawPolyLine( aB2DPolyLine, 0.0, aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, com::sun::star::drawing::LineCap_BUTT, this))
1830*b1cdbd2cSJim Jagielski 		{
1831*b1cdbd2cSJim Jagielski 			return;
1832*b1cdbd2cSJim Jagielski 		}
1833*b1cdbd2cSJim Jagielski 	}
1834*b1cdbd2cSJim Jagielski 
1835*b1cdbd2cSJim Jagielski 	Polygon aPoly = ImplLogicToDevicePixel( rPoly );
1836*b1cdbd2cSJim Jagielski     const SalPoint* pPtAry = (const SalPoint*)aPoly.GetConstPointAry();
1837*b1cdbd2cSJim Jagielski 
1838*b1cdbd2cSJim Jagielski     // #100127# Forward beziers to sal, if any
1839*b1cdbd2cSJim Jagielski     if( aPoly.HasFlags() )
1840*b1cdbd2cSJim Jagielski     {
1841*b1cdbd2cSJim Jagielski         const sal_uInt8* pFlgAry = aPoly.GetConstFlagAry();
1842*b1cdbd2cSJim Jagielski         if( !mpGraphics->DrawPolyLineBezier( nPoints, pPtAry, pFlgAry, this ) )
1843*b1cdbd2cSJim Jagielski         {
1844*b1cdbd2cSJim Jagielski             aPoly = ImplSubdivideBezier(aPoly);
1845*b1cdbd2cSJim Jagielski             pPtAry = (const SalPoint*)aPoly.GetConstPointAry();
1846*b1cdbd2cSJim Jagielski             mpGraphics->DrawPolyLine( aPoly.GetSize(), pPtAry, this );
1847*b1cdbd2cSJim Jagielski         }
1848*b1cdbd2cSJim Jagielski     }
1849*b1cdbd2cSJim Jagielski     else
1850*b1cdbd2cSJim Jagielski     {
1851*b1cdbd2cSJim Jagielski         mpGraphics->DrawPolyLine( nPoints, pPtAry, this );
1852*b1cdbd2cSJim Jagielski     }
1853*b1cdbd2cSJim Jagielski 
1854*b1cdbd2cSJim Jagielski     if( mpAlphaVDev )
1855*b1cdbd2cSJim Jagielski         mpAlphaVDev->DrawPolyLine( rPoly );
1856*b1cdbd2cSJim Jagielski }
1857*b1cdbd2cSJim Jagielski 
1858*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
1859*b1cdbd2cSJim Jagielski 
DrawPolyLine(const Polygon & rPoly,const LineInfo & rLineInfo)1860*b1cdbd2cSJim Jagielski void OutputDevice::DrawPolyLine( const Polygon& rPoly, const LineInfo& rLineInfo )
1861*b1cdbd2cSJim Jagielski {
1862*b1cdbd2cSJim Jagielski 	DBG_TRACE( "OutputDevice::DrawPolyLine()" );
1863*b1cdbd2cSJim Jagielski 	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1864*b1cdbd2cSJim Jagielski 	DBG_CHKOBJ( &rPoly, Polygon, NULL );
1865*b1cdbd2cSJim Jagielski 
1866*b1cdbd2cSJim Jagielski 	if ( rLineInfo.IsDefault() )
1867*b1cdbd2cSJim Jagielski 	{
1868*b1cdbd2cSJim Jagielski 		DrawPolyLine( rPoly );
1869*b1cdbd2cSJim Jagielski 		return;
1870*b1cdbd2cSJim Jagielski 	}
1871*b1cdbd2cSJim Jagielski 
1872*b1cdbd2cSJim Jagielski     // #i101491#
1873*b1cdbd2cSJim Jagielski     // Try direct Fallback to B2D-Version of DrawPolyLine
1874*b1cdbd2cSJim Jagielski     if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
1875*b1cdbd2cSJim Jagielski         && LINE_SOLID == rLineInfo.GetStyle())
1876*b1cdbd2cSJim Jagielski     {
1877*b1cdbd2cSJim Jagielski 		DrawPolyLine( rPoly.getB2DPolygon(), (double)rLineInfo.GetWidth(), rLineInfo.GetLineJoin(), rLineInfo.GetLineCap());
1878*b1cdbd2cSJim Jagielski 		return;
1879*b1cdbd2cSJim Jagielski     }
1880*b1cdbd2cSJim Jagielski 
1881*b1cdbd2cSJim Jagielski 	if ( mpMetaFile )
1882*b1cdbd2cSJim Jagielski 		mpMetaFile->AddAction( new MetaPolyLineAction( rPoly, rLineInfo ) );
1883*b1cdbd2cSJim Jagielski 
1884*b1cdbd2cSJim Jagielski     ImpDrawPolyLineWithLineInfo(rPoly, rLineInfo);
1885*b1cdbd2cSJim Jagielski }
1886*b1cdbd2cSJim Jagielski 
ImpDrawPolyLineWithLineInfo(const Polygon & rPoly,const LineInfo & rLineInfo)1887*b1cdbd2cSJim Jagielski void OutputDevice::ImpDrawPolyLineWithLineInfo(const Polygon& rPoly, const LineInfo& rLineInfo)
1888*b1cdbd2cSJim Jagielski {
1889*b1cdbd2cSJim Jagielski 	sal_uInt16 nPoints(rPoly.GetSize());
1890*b1cdbd2cSJim Jagielski 
1891*b1cdbd2cSJim Jagielski 	if ( !IsDeviceOutputNecessary() || !mbLineColor || ( nPoints < 2 ) || ( LINE_NONE == rLineInfo.GetStyle() ) || ImplIsRecordLayout() )
1892*b1cdbd2cSJim Jagielski 		return;
1893*b1cdbd2cSJim Jagielski 
1894*b1cdbd2cSJim Jagielski     Polygon aPoly = ImplLogicToDevicePixel( rPoly );
1895*b1cdbd2cSJim Jagielski 
1896*b1cdbd2cSJim Jagielski     // #100127# LineInfo is not curve-safe, subdivide always
1897*b1cdbd2cSJim Jagielski     //
1898*b1cdbd2cSJim Jagielski     // What shall this mean? It's wrong to subdivide here when the
1899*b1cdbd2cSJim Jagielski     // polygon is a fat line. In that case, the painted geometry
1900*b1cdbd2cSJim Jagielski     // WILL be much different.
1901*b1cdbd2cSJim Jagielski     // I also have no idea how this could be related to the given ID
1902*b1cdbd2cSJim Jagielski     // which reads 'consolidate boost versions' in the task description.
1903*b1cdbd2cSJim Jagielski     // Removing.
1904*b1cdbd2cSJim Jagielski     //
1905*b1cdbd2cSJim Jagielski     //if( aPoly.HasFlags() )
1906*b1cdbd2cSJim Jagielski     //{
1907*b1cdbd2cSJim Jagielski     //    aPoly = ImplSubdivideBezier( aPoly );
1908*b1cdbd2cSJim Jagielski     //    nPoints = aPoly.GetSize();
1909*b1cdbd2cSJim Jagielski     //}
1910*b1cdbd2cSJim Jagielski 
1911*b1cdbd2cSJim Jagielski 	// we need a graphics
1912*b1cdbd2cSJim Jagielski 	if ( !mpGraphics && !ImplGetGraphics() )
1913*b1cdbd2cSJim Jagielski 		return;
1914*b1cdbd2cSJim Jagielski 
1915*b1cdbd2cSJim Jagielski 	if ( mbInitClipRegion )
1916*b1cdbd2cSJim Jagielski 		ImplInitClipRegion();
1917*b1cdbd2cSJim Jagielski 
1918*b1cdbd2cSJim Jagielski 	if ( mbOutputClipped )
1919*b1cdbd2cSJim Jagielski 		return;
1920*b1cdbd2cSJim Jagielski 
1921*b1cdbd2cSJim Jagielski 	if ( mbInitLineColor )
1922*b1cdbd2cSJim Jagielski 		ImplInitLineColor();
1923*b1cdbd2cSJim Jagielski 
1924*b1cdbd2cSJim Jagielski     const LineInfo aInfo( ImplLogicToDevicePixel( rLineInfo ) );
1925*b1cdbd2cSJim Jagielski     const bool bDashUsed(LINE_DASH == aInfo.GetStyle());
1926*b1cdbd2cSJim Jagielski     const bool bLineWidthUsed(aInfo.GetWidth() > 1);
1927*b1cdbd2cSJim Jagielski 
1928*b1cdbd2cSJim Jagielski     if(bDashUsed || bLineWidthUsed)
1929*b1cdbd2cSJim Jagielski     {
1930*b1cdbd2cSJim Jagielski         impPaintLineGeometryWithEvtlExpand(aInfo, basegfx::B2DPolyPolygon(aPoly.getB2DPolygon()));
1931*b1cdbd2cSJim Jagielski     }
1932*b1cdbd2cSJim Jagielski     else
1933*b1cdbd2cSJim Jagielski     {
1934*b1cdbd2cSJim Jagielski         // #100127# the subdivision HAS to be done here since only a pointer
1935*b1cdbd2cSJim Jagielski         // to an array of points is given to the DrawPolyLine method, there is
1936*b1cdbd2cSJim Jagielski         // NO way to find out there that it's a curve.
1937*b1cdbd2cSJim Jagielski         if( aPoly.HasFlags() )
1938*b1cdbd2cSJim Jagielski         {
1939*b1cdbd2cSJim Jagielski             aPoly = ImplSubdivideBezier( aPoly );
1940*b1cdbd2cSJim Jagielski             nPoints = aPoly.GetSize();
1941*b1cdbd2cSJim Jagielski         }
1942*b1cdbd2cSJim Jagielski 
1943*b1cdbd2cSJim Jagielski         mpGraphics->DrawPolyLine(nPoints, (const SalPoint*)aPoly.GetConstPointAry(), this);
1944*b1cdbd2cSJim Jagielski     }
1945*b1cdbd2cSJim Jagielski 
1946*b1cdbd2cSJim Jagielski     if( mpAlphaVDev )
1947*b1cdbd2cSJim Jagielski         mpAlphaVDev->DrawPolyLine( rPoly, rLineInfo );
1948*b1cdbd2cSJim Jagielski }
1949*b1cdbd2cSJim Jagielski 
1950*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
1951*b1cdbd2cSJim Jagielski 
DrawPolygon(const Polygon & rPoly)1952*b1cdbd2cSJim Jagielski void OutputDevice::DrawPolygon( const Polygon& rPoly )
1953*b1cdbd2cSJim Jagielski {
1954*b1cdbd2cSJim Jagielski 	DBG_TRACE( "OutputDevice::DrawPolygon()" );
1955*b1cdbd2cSJim Jagielski 	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1956*b1cdbd2cSJim Jagielski 	DBG_CHKOBJ( &rPoly, Polygon, NULL );
1957*b1cdbd2cSJim Jagielski 
1958*b1cdbd2cSJim Jagielski 	if( mpMetaFile )
1959*b1cdbd2cSJim Jagielski 		mpMetaFile->AddAction( new MetaPolygonAction( rPoly ) );
1960*b1cdbd2cSJim Jagielski 
1961*b1cdbd2cSJim Jagielski 	sal_uInt16 nPoints = rPoly.GetSize();
1962*b1cdbd2cSJim Jagielski 
1963*b1cdbd2cSJim Jagielski 	if ( !IsDeviceOutputNecessary() || (!mbLineColor && !mbFillColor) || (nPoints < 2) || ImplIsRecordLayout() )
1964*b1cdbd2cSJim Jagielski 		return;
1965*b1cdbd2cSJim Jagielski 
1966*b1cdbd2cSJim Jagielski 	// we need a graphics
1967*b1cdbd2cSJim Jagielski 	if ( !mpGraphics )
1968*b1cdbd2cSJim Jagielski 		if ( !ImplGetGraphics() )
1969*b1cdbd2cSJim Jagielski 			return;
1970*b1cdbd2cSJim Jagielski 
1971*b1cdbd2cSJim Jagielski 	if ( mbInitClipRegion )
1972*b1cdbd2cSJim Jagielski 		ImplInitClipRegion();
1973*b1cdbd2cSJim Jagielski 	if ( mbOutputClipped )
1974*b1cdbd2cSJim Jagielski 		return;
1975*b1cdbd2cSJim Jagielski 
1976*b1cdbd2cSJim Jagielski 	if ( mbInitLineColor )
1977*b1cdbd2cSJim Jagielski 		ImplInitLineColor();
1978*b1cdbd2cSJim Jagielski 	if ( mbInitFillColor )
1979*b1cdbd2cSJim Jagielski 		ImplInitFillColor();
1980*b1cdbd2cSJim Jagielski 
1981*b1cdbd2cSJim Jagielski 	// use b2dpolygon drawing if possible
1982*b1cdbd2cSJim Jagielski 	if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
1983*b1cdbd2cSJim Jagielski 		&& mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
1984*b1cdbd2cSJim Jagielski 		&& ROP_OVERPAINT == GetRasterOp()
1985*b1cdbd2cSJim Jagielski 		&& (IsLineColor() || IsFillColor()))
1986*b1cdbd2cSJim Jagielski 	{
1987*b1cdbd2cSJim Jagielski 		const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation();
1988*b1cdbd2cSJim Jagielski 		basegfx::B2DPolygon aB2DPolygon(rPoly.getB2DPolygon());
1989*b1cdbd2cSJim Jagielski 		bool bSuccess(true);
1990*b1cdbd2cSJim Jagielski 
1991*b1cdbd2cSJim Jagielski         // transform the polygon and ensure closed
1992*b1cdbd2cSJim Jagielski 		aB2DPolygon.transform(aTransform);
1993*b1cdbd2cSJim Jagielski         aB2DPolygon.setClosed(true);
1994*b1cdbd2cSJim Jagielski 
1995*b1cdbd2cSJim Jagielski 		if(IsFillColor())
1996*b1cdbd2cSJim Jagielski 		{
1997*b1cdbd2cSJim Jagielski 			bSuccess = mpGraphics->DrawPolyPolygon(basegfx::B2DPolyPolygon(aB2DPolygon), 0.0, this);
1998*b1cdbd2cSJim Jagielski 		}
1999*b1cdbd2cSJim Jagielski 
2000*b1cdbd2cSJim Jagielski 		if(bSuccess && IsLineColor())
2001*b1cdbd2cSJim Jagielski 		{
2002*b1cdbd2cSJim Jagielski 			const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 );
2003*b1cdbd2cSJim Jagielski 
2004*b1cdbd2cSJim Jagielski 			if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
2005*b1cdbd2cSJim Jagielski 			{
2006*b1cdbd2cSJim Jagielski 				aB2DPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolygon);
2007*b1cdbd2cSJim Jagielski 			}
2008*b1cdbd2cSJim Jagielski 
2009*b1cdbd2cSJim Jagielski 			bSuccess = mpGraphics->DrawPolyLine(
2010*b1cdbd2cSJim Jagielski                 aB2DPolygon,
2011*b1cdbd2cSJim Jagielski                 0.0,
2012*b1cdbd2cSJim Jagielski                 aB2DLineWidth,
2013*b1cdbd2cSJim Jagielski                 basegfx::B2DLINEJOIN_NONE,
2014*b1cdbd2cSJim Jagielski                 com::sun::star::drawing::LineCap_BUTT,
2015*b1cdbd2cSJim Jagielski                 this);
2016*b1cdbd2cSJim Jagielski 		}
2017*b1cdbd2cSJim Jagielski 
2018*b1cdbd2cSJim Jagielski 		if(bSuccess)
2019*b1cdbd2cSJim Jagielski 		{
2020*b1cdbd2cSJim Jagielski 			return;
2021*b1cdbd2cSJim Jagielski 		}
2022*b1cdbd2cSJim Jagielski 	}
2023*b1cdbd2cSJim Jagielski 
2024*b1cdbd2cSJim Jagielski 	Polygon aPoly = ImplLogicToDevicePixel( rPoly );
2025*b1cdbd2cSJim Jagielski 	const SalPoint* pPtAry = (const SalPoint*)aPoly.GetConstPointAry();
2026*b1cdbd2cSJim Jagielski 
2027*b1cdbd2cSJim Jagielski     // #100127# Forward beziers to sal, if any
2028*b1cdbd2cSJim Jagielski     if( aPoly.HasFlags() )
2029*b1cdbd2cSJim Jagielski     {
2030*b1cdbd2cSJim Jagielski         const sal_uInt8* pFlgAry = aPoly.GetConstFlagAry();
2031*b1cdbd2cSJim Jagielski         if( !mpGraphics->DrawPolygonBezier( nPoints, pPtAry, pFlgAry, this ) )
2032*b1cdbd2cSJim Jagielski         {
2033*b1cdbd2cSJim Jagielski             aPoly = ImplSubdivideBezier(aPoly);
2034*b1cdbd2cSJim Jagielski             pPtAry = (const SalPoint*)aPoly.GetConstPointAry();
2035*b1cdbd2cSJim Jagielski             mpGraphics->DrawPolygon( aPoly.GetSize(), pPtAry, this );
2036*b1cdbd2cSJim Jagielski         }
2037*b1cdbd2cSJim Jagielski     }
2038*b1cdbd2cSJim Jagielski     else
2039*b1cdbd2cSJim Jagielski     {
2040*b1cdbd2cSJim Jagielski         mpGraphics->DrawPolygon( nPoints, pPtAry, this );
2041*b1cdbd2cSJim Jagielski     }
2042*b1cdbd2cSJim Jagielski     if( mpAlphaVDev )
2043*b1cdbd2cSJim Jagielski         mpAlphaVDev->DrawPolygon( rPoly );
2044*b1cdbd2cSJim Jagielski }
2045*b1cdbd2cSJim Jagielski 
2046*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
2047*b1cdbd2cSJim Jagielski 
DrawPolyPolygon(const PolyPolygon & rPolyPoly)2048*b1cdbd2cSJim Jagielski void OutputDevice::DrawPolyPolygon( const PolyPolygon& rPolyPoly )
2049*b1cdbd2cSJim Jagielski {
2050*b1cdbd2cSJim Jagielski 	DBG_TRACE( "OutputDevice::DrawPolyPolygon()" );
2051*b1cdbd2cSJim Jagielski 	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
2052*b1cdbd2cSJim Jagielski 	DBG_CHKOBJ( &rPolyPoly, PolyPolygon, NULL );
2053*b1cdbd2cSJim Jagielski 
2054*b1cdbd2cSJim Jagielski 	if( mpMetaFile )
2055*b1cdbd2cSJim Jagielski 		mpMetaFile->AddAction( new MetaPolyPolygonAction( rPolyPoly ) );
2056*b1cdbd2cSJim Jagielski 
2057*b1cdbd2cSJim Jagielski 	sal_uInt16 nPoly = rPolyPoly.Count();
2058*b1cdbd2cSJim Jagielski 
2059*b1cdbd2cSJim Jagielski 	if ( !IsDeviceOutputNecessary() || (!mbLineColor && !mbFillColor) || !nPoly || ImplIsRecordLayout() )
2060*b1cdbd2cSJim Jagielski 		return;
2061*b1cdbd2cSJim Jagielski 
2062*b1cdbd2cSJim Jagielski 	// we need a graphics
2063*b1cdbd2cSJim Jagielski 	if ( !mpGraphics )
2064*b1cdbd2cSJim Jagielski 		if ( !ImplGetGraphics() )
2065*b1cdbd2cSJim Jagielski 			return;
2066*b1cdbd2cSJim Jagielski 
2067*b1cdbd2cSJim Jagielski 	if ( mbInitClipRegion )
2068*b1cdbd2cSJim Jagielski 		ImplInitClipRegion();
2069*b1cdbd2cSJim Jagielski 	if ( mbOutputClipped )
2070*b1cdbd2cSJim Jagielski 		return;
2071*b1cdbd2cSJim Jagielski 
2072*b1cdbd2cSJim Jagielski 	if ( mbInitLineColor )
2073*b1cdbd2cSJim Jagielski 		ImplInitLineColor();
2074*b1cdbd2cSJim Jagielski 	if ( mbInitFillColor )
2075*b1cdbd2cSJim Jagielski 		ImplInitFillColor();
2076*b1cdbd2cSJim Jagielski 
2077*b1cdbd2cSJim Jagielski 	// use b2dpolygon drawing if possible
2078*b1cdbd2cSJim Jagielski 	if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
2079*b1cdbd2cSJim Jagielski 		&& mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
2080*b1cdbd2cSJim Jagielski 		&& ROP_OVERPAINT == GetRasterOp()
2081*b1cdbd2cSJim Jagielski 		&& (IsLineColor() || IsFillColor()))
2082*b1cdbd2cSJim Jagielski 	{
2083*b1cdbd2cSJim Jagielski 		const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation();
2084*b1cdbd2cSJim Jagielski 		basegfx::B2DPolyPolygon aB2DPolyPolygon(rPolyPoly.getB2DPolyPolygon());
2085*b1cdbd2cSJim Jagielski 		bool bSuccess(true);
2086*b1cdbd2cSJim Jagielski 
2087*b1cdbd2cSJim Jagielski 		// transform the polygon and ensure closed
2088*b1cdbd2cSJim Jagielski 		aB2DPolyPolygon.transform(aTransform);
2089*b1cdbd2cSJim Jagielski         aB2DPolyPolygon.setClosed(true);
2090*b1cdbd2cSJim Jagielski 
2091*b1cdbd2cSJim Jagielski 		if(IsFillColor())
2092*b1cdbd2cSJim Jagielski 		{
2093*b1cdbd2cSJim Jagielski 			bSuccess = mpGraphics->DrawPolyPolygon(aB2DPolyPolygon, 0.0, this);
2094*b1cdbd2cSJim Jagielski 		}
2095*b1cdbd2cSJim Jagielski 
2096*b1cdbd2cSJim Jagielski 		if(bSuccess && IsLineColor())
2097*b1cdbd2cSJim Jagielski 		{
2098*b1cdbd2cSJim Jagielski 			const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 );
2099*b1cdbd2cSJim Jagielski 
2100*b1cdbd2cSJim Jagielski 			if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
2101*b1cdbd2cSJim Jagielski 			{
2102*b1cdbd2cSJim Jagielski 				aB2DPolyPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyPolygon);
2103*b1cdbd2cSJim Jagielski 			}
2104*b1cdbd2cSJim Jagielski 
2105*b1cdbd2cSJim Jagielski 			for(sal_uInt32 a(0); bSuccess && a < aB2DPolyPolygon.count(); a++)
2106*b1cdbd2cSJim Jagielski 			{
2107*b1cdbd2cSJim Jagielski 				bSuccess = mpGraphics->DrawPolyLine(
2108*b1cdbd2cSJim Jagielski                     aB2DPolyPolygon.getB2DPolygon(a),
2109*b1cdbd2cSJim Jagielski                     0.0,
2110*b1cdbd2cSJim Jagielski                     aB2DLineWidth,
2111*b1cdbd2cSJim Jagielski                     basegfx::B2DLINEJOIN_NONE,
2112*b1cdbd2cSJim Jagielski                     com::sun::star::drawing::LineCap_BUTT,
2113*b1cdbd2cSJim Jagielski                     this);
2114*b1cdbd2cSJim Jagielski 			}
2115*b1cdbd2cSJim Jagielski 		}
2116*b1cdbd2cSJim Jagielski 
2117*b1cdbd2cSJim Jagielski 		if(bSuccess)
2118*b1cdbd2cSJim Jagielski 		{
2119*b1cdbd2cSJim Jagielski 			return;
2120*b1cdbd2cSJim Jagielski 		}
2121*b1cdbd2cSJim Jagielski 	}
2122*b1cdbd2cSJim Jagielski 
2123*b1cdbd2cSJim Jagielski 	if ( nPoly == 1 )
2124*b1cdbd2cSJim Jagielski 	{
2125*b1cdbd2cSJim Jagielski         // #100127# Map to DrawPolygon
2126*b1cdbd2cSJim Jagielski         Polygon aPoly = rPolyPoly.GetObject( 0 );
2127*b1cdbd2cSJim Jagielski 		if( aPoly.GetSize() >= 2 )
2128*b1cdbd2cSJim Jagielski         {
2129*b1cdbd2cSJim Jagielski             GDIMetaFile* pOldMF = mpMetaFile;
2130*b1cdbd2cSJim Jagielski             mpMetaFile = NULL;
2131*b1cdbd2cSJim Jagielski 
2132*b1cdbd2cSJim Jagielski 			DrawPolygon( aPoly );
2133*b1cdbd2cSJim Jagielski 
2134*b1cdbd2cSJim Jagielski             mpMetaFile = pOldMF;
2135*b1cdbd2cSJim Jagielski         }
2136*b1cdbd2cSJim Jagielski 	}
2137*b1cdbd2cSJim Jagielski 	else
2138*b1cdbd2cSJim Jagielski 	{
2139*b1cdbd2cSJim Jagielski         // #100127# moved real PolyPolygon draw to separate method,
2140*b1cdbd2cSJim Jagielski         // have to call recursively, avoiding duplicate
2141*b1cdbd2cSJim Jagielski         // ImplLogicToDevicePixel calls
2142*b1cdbd2cSJim Jagielski         ImplDrawPolyPolygon( nPoly, ImplLogicToDevicePixel( rPolyPoly ) );
2143*b1cdbd2cSJim Jagielski 	}
2144*b1cdbd2cSJim Jagielski     if( mpAlphaVDev )
2145*b1cdbd2cSJim Jagielski         mpAlphaVDev->DrawPolyPolygon( rPolyPoly );
2146*b1cdbd2cSJim Jagielski }
2147*b1cdbd2cSJim Jagielski 
2148*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
2149*b1cdbd2cSJim Jagielski 
DrawPolygon(const::basegfx::B2DPolygon & rB2DPolygon)2150*b1cdbd2cSJim Jagielski void OutputDevice::DrawPolygon( const ::basegfx::B2DPolygon& rB2DPolygon)
2151*b1cdbd2cSJim Jagielski {
2152*b1cdbd2cSJim Jagielski     // AW: Do NOT paint empty polygons
2153*b1cdbd2cSJim Jagielski     if(rB2DPolygon.count())
2154*b1cdbd2cSJim Jagielski     {
2155*b1cdbd2cSJim Jagielski         ::basegfx::B2DPolyPolygon aPP( rB2DPolygon );
2156*b1cdbd2cSJim Jagielski         DrawPolyPolygon( aPP );
2157*b1cdbd2cSJim Jagielski     }
2158*b1cdbd2cSJim Jagielski }
2159*b1cdbd2cSJim Jagielski 
2160*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
2161*b1cdbd2cSJim Jagielski // Caution: This method is nearly the same as
2162*b1cdbd2cSJim Jagielski // OutputDevice::DrawTransparent( const basegfx::B2DPolyPolygon& rB2DPolyPoly, double fTransparency),
2163*b1cdbd2cSJim Jagielski // so when changes are made here do not forget to make change sthere, too
2164*b1cdbd2cSJim Jagielski 
DrawPolyPolygon(const basegfx::B2DPolyPolygon & rB2DPolyPoly)2165*b1cdbd2cSJim Jagielski void OutputDevice::DrawPolyPolygon( const basegfx::B2DPolyPolygon& rB2DPolyPoly )
2166*b1cdbd2cSJim Jagielski {
2167*b1cdbd2cSJim Jagielski 	DBG_TRACE( "OutputDevice::DrawPolyPolygon(B2D&)" );
2168*b1cdbd2cSJim Jagielski 	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
2169*b1cdbd2cSJim Jagielski 
2170*b1cdbd2cSJim Jagielski #if 0
2171*b1cdbd2cSJim Jagielski     // MetaB2DPolyPolygonAction is not implemented yet:
2172*b1cdbd2cSJim Jagielski     // according to AW adding it is very dangerous since there is a lot
2173*b1cdbd2cSJim Jagielski     // of code that uses the metafile actions directly and unless every
2174*b1cdbd2cSJim Jagielski     // place that does this knows about the new action we need to fallback
2175*b1cdbd2cSJim Jagielski     if( mpMetaFile )
2176*b1cdbd2cSJim Jagielski         mpMetaFile->AddAction( new MetaB2DPolyPolygonAction( rB2DPolyPoly ) );
2177*b1cdbd2cSJim Jagielski #else
2178*b1cdbd2cSJim Jagielski     if( mpMetaFile )
2179*b1cdbd2cSJim Jagielski         mpMetaFile->AddAction( new MetaPolyPolygonAction( PolyPolygon( rB2DPolyPoly ) ) );
2180*b1cdbd2cSJim Jagielski #endif
2181*b1cdbd2cSJim Jagielski 
2182*b1cdbd2cSJim Jagielski 	// call helper
2183*b1cdbd2cSJim Jagielski 	ImpDrawPolyPolygonWithB2DPolyPolygon(rB2DPolyPoly);
2184*b1cdbd2cSJim Jagielski }
2185*b1cdbd2cSJim Jagielski 
ImpDrawPolyPolygonWithB2DPolyPolygon(const basegfx::B2DPolyPolygon & rB2DPolyPoly)2186*b1cdbd2cSJim Jagielski void OutputDevice::ImpDrawPolyPolygonWithB2DPolyPolygon(const basegfx::B2DPolyPolygon& rB2DPolyPoly)
2187*b1cdbd2cSJim Jagielski {
2188*b1cdbd2cSJim Jagielski     // AW: Do NOT paint empty PolyPolygons
2189*b1cdbd2cSJim Jagielski     if(!rB2DPolyPoly.count())
2190*b1cdbd2cSJim Jagielski         return;
2191*b1cdbd2cSJim Jagielski 
2192*b1cdbd2cSJim Jagielski     // we need a graphics
2193*b1cdbd2cSJim Jagielski     if( !mpGraphics )
2194*b1cdbd2cSJim Jagielski 	    if( !ImplGetGraphics() )
2195*b1cdbd2cSJim Jagielski 		    return;
2196*b1cdbd2cSJim Jagielski 
2197*b1cdbd2cSJim Jagielski     if( mbInitClipRegion )
2198*b1cdbd2cSJim Jagielski 	    ImplInitClipRegion();
2199*b1cdbd2cSJim Jagielski     if( mbOutputClipped )
2200*b1cdbd2cSJim Jagielski 	    return;
2201*b1cdbd2cSJim Jagielski 
2202*b1cdbd2cSJim Jagielski     if( mbInitLineColor )
2203*b1cdbd2cSJim Jagielski 	    ImplInitLineColor();
2204*b1cdbd2cSJim Jagielski     if( mbInitFillColor )
2205*b1cdbd2cSJim Jagielski 	    ImplInitFillColor();
2206*b1cdbd2cSJim Jagielski 
2207*b1cdbd2cSJim Jagielski 	if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
2208*b1cdbd2cSJim Jagielski 		&& mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
2209*b1cdbd2cSJim Jagielski 		&& ROP_OVERPAINT == GetRasterOp()
2210*b1cdbd2cSJim Jagielski 		&& (IsLineColor() || IsFillColor()))
2211*b1cdbd2cSJim Jagielski     {
2212*b1cdbd2cSJim Jagielski 		const basegfx::B2DHomMatrix aTransform(ImplGetDeviceTransformation());
2213*b1cdbd2cSJim Jagielski 		basegfx::B2DPolyPolygon aB2DPolyPolygon(rB2DPolyPoly);
2214*b1cdbd2cSJim Jagielski 		bool bSuccess(true);
2215*b1cdbd2cSJim Jagielski 
2216*b1cdbd2cSJim Jagielski 		// transform the polygon and ensure closed
2217*b1cdbd2cSJim Jagielski 		aB2DPolyPolygon.transform(aTransform);
2218*b1cdbd2cSJim Jagielski         aB2DPolyPolygon.setClosed(true);
2219*b1cdbd2cSJim Jagielski 
2220*b1cdbd2cSJim Jagielski 		if(IsFillColor())
2221*b1cdbd2cSJim Jagielski 		{
2222*b1cdbd2cSJim Jagielski 			bSuccess = mpGraphics->DrawPolyPolygon(aB2DPolyPolygon, 0.0, this);
2223*b1cdbd2cSJim Jagielski 		}
2224*b1cdbd2cSJim Jagielski 
2225*b1cdbd2cSJim Jagielski 		if(bSuccess && IsLineColor())
2226*b1cdbd2cSJim Jagielski 		{
2227*b1cdbd2cSJim Jagielski 			const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 );
2228*b1cdbd2cSJim Jagielski 
2229*b1cdbd2cSJim Jagielski 			if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
2230*b1cdbd2cSJim Jagielski 			{
2231*b1cdbd2cSJim Jagielski 				aB2DPolyPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyPolygon);
2232*b1cdbd2cSJim Jagielski 			}
2233*b1cdbd2cSJim Jagielski 
2234*b1cdbd2cSJim Jagielski 			for(sal_uInt32 a(0);bSuccess && a < aB2DPolyPolygon.count(); a++)
2235*b1cdbd2cSJim Jagielski 			{
2236*b1cdbd2cSJim Jagielski 				bSuccess = mpGraphics->DrawPolyLine(
2237*b1cdbd2cSJim Jagielski                     aB2DPolyPolygon.getB2DPolygon(a),
2238*b1cdbd2cSJim Jagielski                     0.0,
2239*b1cdbd2cSJim Jagielski                     aB2DLineWidth,
2240*b1cdbd2cSJim Jagielski                     basegfx::B2DLINEJOIN_NONE,
2241*b1cdbd2cSJim Jagielski                     com::sun::star::drawing::LineCap_BUTT,
2242*b1cdbd2cSJim Jagielski                     this);
2243*b1cdbd2cSJim Jagielski 			}
2244*b1cdbd2cSJim Jagielski 		}
2245*b1cdbd2cSJim Jagielski 
2246*b1cdbd2cSJim Jagielski 		if(bSuccess)
2247*b1cdbd2cSJim Jagielski 		{
2248*b1cdbd2cSJim Jagielski 			return;
2249*b1cdbd2cSJim Jagielski 		}
2250*b1cdbd2cSJim Jagielski     }
2251*b1cdbd2cSJim Jagielski 
2252*b1cdbd2cSJim Jagielski     // fallback to old polygon drawing if needed
2253*b1cdbd2cSJim Jagielski     const PolyPolygon aToolsPolyPolygon( rB2DPolyPoly );
2254*b1cdbd2cSJim Jagielski     const PolyPolygon aPixelPolyPolygon = ImplLogicToDevicePixel( aToolsPolyPolygon );
2255*b1cdbd2cSJim Jagielski     ImplDrawPolyPolygon( aPixelPolyPolygon.Count(), aPixelPolyPolygon );
2256*b1cdbd2cSJim Jagielski }
2257*b1cdbd2cSJim Jagielski 
2258*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
2259*b1cdbd2cSJim Jagielski 
ImpTryDrawPolyLineDirect(const basegfx::B2DPolygon & rB2DPolygon,double fLineWidth,double fTransparency,basegfx::B2DLineJoin eLineJoin,com::sun::star::drawing::LineCap eLineCap)2260*b1cdbd2cSJim Jagielski bool OutputDevice::ImpTryDrawPolyLineDirect(
2261*b1cdbd2cSJim Jagielski 	const basegfx::B2DPolygon& rB2DPolygon,
2262*b1cdbd2cSJim Jagielski     double fLineWidth,
2263*b1cdbd2cSJim Jagielski     double fTransparency,
2264*b1cdbd2cSJim Jagielski     basegfx::B2DLineJoin eLineJoin,
2265*b1cdbd2cSJim Jagielski     com::sun::star::drawing::LineCap eLineCap)
2266*b1cdbd2cSJim Jagielski {
2267*b1cdbd2cSJim Jagielski     const basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation();
2268*b1cdbd2cSJim Jagielski     basegfx::B2DVector aB2DLineWidth(1.0, 1.0);
2269*b1cdbd2cSJim Jagielski 
2270*b1cdbd2cSJim Jagielski 	// transform the line width if used
2271*b1cdbd2cSJim Jagielski     if( fLineWidth != 0.0 )
2272*b1cdbd2cSJim Jagielski 	{
2273*b1cdbd2cSJim Jagielski         aB2DLineWidth = aTransform * ::basegfx::B2DVector( fLineWidth, fLineWidth );
2274*b1cdbd2cSJim Jagielski 	}
2275*b1cdbd2cSJim Jagielski 
2276*b1cdbd2cSJim Jagielski     // transform the polygon
2277*b1cdbd2cSJim Jagielski     basegfx::B2DPolygon aB2DPolygon(rB2DPolygon);
2278*b1cdbd2cSJim Jagielski     aB2DPolygon.transform(aTransform);
2279*b1cdbd2cSJim Jagielski 
2280*b1cdbd2cSJim Jagielski     if((mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
2281*b1cdbd2cSJim Jagielski 		&& aB2DPolygon.count() < 1000)
2282*b1cdbd2cSJim Jagielski     {
2283*b1cdbd2cSJim Jagielski 		// #i98289#, #i101491#
2284*b1cdbd2cSJim Jagielski         // better to remove doubles on device coordinates. Also assume from a given amount
2285*b1cdbd2cSJim Jagielski         // of points that the single edges are not long enough to smooth
2286*b1cdbd2cSJim Jagielski         aB2DPolygon.removeDoublePoints();
2287*b1cdbd2cSJim Jagielski         aB2DPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolygon);
2288*b1cdbd2cSJim Jagielski     }
2289*b1cdbd2cSJim Jagielski 
2290*b1cdbd2cSJim Jagielski     // draw the polyline
2291*b1cdbd2cSJim Jagielski     return mpGraphics->DrawPolyLine(
2292*b1cdbd2cSJim Jagielski         aB2DPolygon,
2293*b1cdbd2cSJim Jagielski         fTransparency,
2294*b1cdbd2cSJim Jagielski         aB2DLineWidth,
2295*b1cdbd2cSJim Jagielski         eLineJoin,
2296*b1cdbd2cSJim Jagielski         eLineCap,
2297*b1cdbd2cSJim Jagielski         this);
2298*b1cdbd2cSJim Jagielski }
2299*b1cdbd2cSJim Jagielski 
TryDrawPolyLineDirect(const basegfx::B2DPolygon & rB2DPolygon,double fLineWidth,double fTransparency,basegfx::B2DLineJoin eLineJoin,com::sun::star::drawing::LineCap eLineCap)2300*b1cdbd2cSJim Jagielski bool OutputDevice::TryDrawPolyLineDirect(
2301*b1cdbd2cSJim Jagielski     const basegfx::B2DPolygon& rB2DPolygon,
2302*b1cdbd2cSJim Jagielski     double fLineWidth,
2303*b1cdbd2cSJim Jagielski     double fTransparency,
2304*b1cdbd2cSJim Jagielski     basegfx::B2DLineJoin eLineJoin,
2305*b1cdbd2cSJim Jagielski     com::sun::star::drawing::LineCap eLineCap)
2306*b1cdbd2cSJim Jagielski {
2307*b1cdbd2cSJim Jagielski     // AW: Do NOT paint empty PolyPolygons
2308*b1cdbd2cSJim Jagielski     if(!rB2DPolygon.count())
2309*b1cdbd2cSJim Jagielski         return true;
2310*b1cdbd2cSJim Jagielski 
2311*b1cdbd2cSJim Jagielski     // we need a graphics
2312*b1cdbd2cSJim Jagielski     if( !mpGraphics )
2313*b1cdbd2cSJim Jagielski         if( !ImplGetGraphics() )
2314*b1cdbd2cSJim Jagielski             return false;
2315*b1cdbd2cSJim Jagielski 
2316*b1cdbd2cSJim Jagielski     if( mbInitClipRegion )
2317*b1cdbd2cSJim Jagielski         ImplInitClipRegion();
2318*b1cdbd2cSJim Jagielski 
2319*b1cdbd2cSJim Jagielski     if( mbOutputClipped )
2320*b1cdbd2cSJim Jagielski         return true;
2321*b1cdbd2cSJim Jagielski 
2322*b1cdbd2cSJim Jagielski     if( mbInitLineColor )
2323*b1cdbd2cSJim Jagielski         ImplInitLineColor();
2324*b1cdbd2cSJim Jagielski 
2325*b1cdbd2cSJim Jagielski     const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
2326*b1cdbd2cSJim Jagielski         && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
2327*b1cdbd2cSJim Jagielski         && ROP_OVERPAINT == GetRasterOp()
2328*b1cdbd2cSJim Jagielski         && IsLineColor());
2329*b1cdbd2cSJim Jagielski 
2330*b1cdbd2cSJim Jagielski     if(bTryAA)
2331*b1cdbd2cSJim Jagielski     {
2332*b1cdbd2cSJim Jagielski         if(ImpTryDrawPolyLineDirect(rB2DPolygon, fLineWidth, fTransparency, eLineJoin, eLineCap))
2333*b1cdbd2cSJim Jagielski         {
2334*b1cdbd2cSJim Jagielski             // worked, add metafile action (if recorded) and return true
2335*b1cdbd2cSJim Jagielski             if( mpMetaFile )
2336*b1cdbd2cSJim Jagielski             {
2337*b1cdbd2cSJim Jagielski                 LineInfo aLineInfo;
2338*b1cdbd2cSJim Jagielski                 if( fLineWidth != 0.0 )
2339*b1cdbd2cSJim Jagielski                     aLineInfo.SetWidth( static_cast<long>(fLineWidth+0.5) );
2340*b1cdbd2cSJim Jagielski                 const Polygon aToolsPolygon( rB2DPolygon );
2341*b1cdbd2cSJim Jagielski                 mpMetaFile->AddAction( new MetaPolyLineAction( aToolsPolygon, aLineInfo ) );
2342*b1cdbd2cSJim Jagielski             }
2343*b1cdbd2cSJim Jagielski 
2344*b1cdbd2cSJim Jagielski             return true;
2345*b1cdbd2cSJim Jagielski         }
2346*b1cdbd2cSJim Jagielski     }
2347*b1cdbd2cSJim Jagielski 
2348*b1cdbd2cSJim Jagielski     return false;
2349*b1cdbd2cSJim Jagielski }
2350*b1cdbd2cSJim Jagielski 
DrawPolyLine(const basegfx::B2DPolygon & rB2DPolygon,double fLineWidth,basegfx::B2DLineJoin eLineJoin,com::sun::star::drawing::LineCap eLineCap)2351*b1cdbd2cSJim Jagielski void OutputDevice::DrawPolyLine(
2352*b1cdbd2cSJim Jagielski     const basegfx::B2DPolygon& rB2DPolygon,
2353*b1cdbd2cSJim Jagielski     double fLineWidth,
2354*b1cdbd2cSJim Jagielski     basegfx::B2DLineJoin eLineJoin,
2355*b1cdbd2cSJim Jagielski     com::sun::star::drawing::LineCap eLineCap)
2356*b1cdbd2cSJim Jagielski {
2357*b1cdbd2cSJim Jagielski 	DBG_TRACE( "OutputDevice::DrawPolyLine(B2D&)" );
2358*b1cdbd2cSJim Jagielski 	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
2359*b1cdbd2cSJim Jagielski 
2360*b1cdbd2cSJim Jagielski #if 0 // MetaB2DPolyLineAction is not implemented yet:
2361*b1cdbd2cSJim Jagielski       // according to AW adding it is very dangerous since there is a lot
2362*b1cdbd2cSJim Jagielski       // of code that uses the metafile actions directly and unless every
2363*b1cdbd2cSJim Jagielski       // place that does this knows about the new action we need to fallback
2364*b1cdbd2cSJim Jagielski     if( mpMetaFile )
2365*b1cdbd2cSJim Jagielski         mpMetaFile->AddAction( new MetaB2DPolyLineAction( rB2DPolygon ) );
2366*b1cdbd2cSJim Jagielski #else
2367*b1cdbd2cSJim Jagielski     if( mpMetaFile )
2368*b1cdbd2cSJim Jagielski     {
2369*b1cdbd2cSJim Jagielski         LineInfo aLineInfo;
2370*b1cdbd2cSJim Jagielski         if( fLineWidth != 0.0 )
2371*b1cdbd2cSJim Jagielski             aLineInfo.SetWidth( static_cast<long>(fLineWidth+0.5) );
2372*b1cdbd2cSJim Jagielski         const Polygon aToolsPolygon( rB2DPolygon );
2373*b1cdbd2cSJim Jagielski         mpMetaFile->AddAction( new MetaPolyLineAction( aToolsPolygon, aLineInfo ) );
2374*b1cdbd2cSJim Jagielski     }
2375*b1cdbd2cSJim Jagielski #endif
2376*b1cdbd2cSJim Jagielski 
2377*b1cdbd2cSJim Jagielski     // AW: Do NOT paint empty PolyPolygons
2378*b1cdbd2cSJim Jagielski     if(!rB2DPolygon.count())
2379*b1cdbd2cSJim Jagielski         return;
2380*b1cdbd2cSJim Jagielski 
2381*b1cdbd2cSJim Jagielski     // we need a graphics
2382*b1cdbd2cSJim Jagielski 	if( !mpGraphics )
2383*b1cdbd2cSJim Jagielski 		if( !ImplGetGraphics() )
2384*b1cdbd2cSJim Jagielski 			return;
2385*b1cdbd2cSJim Jagielski 
2386*b1cdbd2cSJim Jagielski 	if( mbInitClipRegion )
2387*b1cdbd2cSJim Jagielski 		ImplInitClipRegion();
2388*b1cdbd2cSJim Jagielski 	if( mbOutputClipped )
2389*b1cdbd2cSJim Jagielski 		return;
2390*b1cdbd2cSJim Jagielski 
2391*b1cdbd2cSJim Jagielski 	if( mbInitLineColor )
2392*b1cdbd2cSJim Jagielski 		ImplInitLineColor();
2393*b1cdbd2cSJim Jagielski 
2394*b1cdbd2cSJim Jagielski     const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
2395*b1cdbd2cSJim Jagielski         && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
2396*b1cdbd2cSJim Jagielski         && ROP_OVERPAINT == GetRasterOp()
2397*b1cdbd2cSJim Jagielski         && IsLineColor());
2398*b1cdbd2cSJim Jagielski 
2399*b1cdbd2cSJim Jagielski 	// use b2dpolygon drawing if possible
2400*b1cdbd2cSJim Jagielski 	if(bTryAA && ImpTryDrawPolyLineDirect(rB2DPolygon, fLineWidth, 0.0, eLineJoin, eLineCap))
2401*b1cdbd2cSJim Jagielski 	{
2402*b1cdbd2cSJim Jagielski 		return;
2403*b1cdbd2cSJim Jagielski 	}
2404*b1cdbd2cSJim Jagielski 
2405*b1cdbd2cSJim Jagielski 	// #i101491#
2406*b1cdbd2cSJim Jagielski 	// no output yet; fallback to geometry decomposition and use filled polygon paint
2407*b1cdbd2cSJim Jagielski 	// when line is fat and not too complex. ImpDrawPolyPolygonWithB2DPolyPolygon
2408*b1cdbd2cSJim Jagielski 	// will do internal needed AA checks etc.
2409*b1cdbd2cSJim Jagielski 	if(fLineWidth >= 2.5
2410*b1cdbd2cSJim Jagielski 		&& rB2DPolygon.count()
2411*b1cdbd2cSJim Jagielski 		&& rB2DPolygon.count() <= 1000)
2412*b1cdbd2cSJim Jagielski 	{
2413*b1cdbd2cSJim Jagielski 		const double fHalfLineWidth((fLineWidth * 0.5) + 0.5);
2414*b1cdbd2cSJim Jagielski 		const basegfx::B2DPolyPolygon aAreaPolyPolygon(
2415*b1cdbd2cSJim Jagielski             basegfx::tools::createAreaGeometry(
2416*b1cdbd2cSJim Jagielski 			    rB2DPolygon,
2417*b1cdbd2cSJim Jagielski                 fHalfLineWidth,
2418*b1cdbd2cSJim Jagielski                 eLineJoin,
2419*b1cdbd2cSJim Jagielski                 eLineCap));
2420*b1cdbd2cSJim Jagielski 		const Color aOldLineColor(maLineColor);
2421*b1cdbd2cSJim Jagielski 		const Color aOldFillColor(maFillColor);
2422*b1cdbd2cSJim Jagielski 
2423*b1cdbd2cSJim Jagielski 		SetLineColor();
2424*b1cdbd2cSJim Jagielski 		ImplInitLineColor();
2425*b1cdbd2cSJim Jagielski 		SetFillColor(aOldLineColor);
2426*b1cdbd2cSJim Jagielski 		ImplInitFillColor();
2427*b1cdbd2cSJim Jagielski 
2428*b1cdbd2cSJim Jagielski 		// draw usig a loop; else the topology will paint a PolyPolygon
2429*b1cdbd2cSJim Jagielski 		for(sal_uInt32 a(0); a < aAreaPolyPolygon.count(); a++)
2430*b1cdbd2cSJim Jagielski 		{
2431*b1cdbd2cSJim Jagielski 			ImpDrawPolyPolygonWithB2DPolyPolygon(
2432*b1cdbd2cSJim Jagielski 				basegfx::B2DPolyPolygon(aAreaPolyPolygon.getB2DPolygon(a)));
2433*b1cdbd2cSJim Jagielski 		}
2434*b1cdbd2cSJim Jagielski 
2435*b1cdbd2cSJim Jagielski         SetLineColor(aOldLineColor);
2436*b1cdbd2cSJim Jagielski 		ImplInitLineColor();
2437*b1cdbd2cSJim Jagielski 		SetFillColor(aOldFillColor);
2438*b1cdbd2cSJim Jagielski 		ImplInitFillColor();
2439*b1cdbd2cSJim Jagielski 
2440*b1cdbd2cSJim Jagielski 		if(bTryAA)
2441*b1cdbd2cSJim Jagielski 		{
2442*b1cdbd2cSJim Jagielski 			// when AA it is necessary to also paint the filled polygon's outline
2443*b1cdbd2cSJim Jagielski 			// to avoid optical gaps
2444*b1cdbd2cSJim Jagielski 			for(sal_uInt32 a(0); a < aAreaPolyPolygon.count(); a++)
2445*b1cdbd2cSJim Jagielski 			{
2446*b1cdbd2cSJim Jagielski 				ImpTryDrawPolyLineDirect(aAreaPolyPolygon.getB2DPolygon(a));
2447*b1cdbd2cSJim Jagielski 			}
2448*b1cdbd2cSJim Jagielski 		}
2449*b1cdbd2cSJim Jagielski 	}
2450*b1cdbd2cSJim Jagielski 	else
2451*b1cdbd2cSJim Jagielski 	{
2452*b1cdbd2cSJim Jagielski 		// fallback to old polygon drawing if needed
2453*b1cdbd2cSJim Jagielski 		const Polygon aToolsPolygon( rB2DPolygon );
2454*b1cdbd2cSJim Jagielski 		LineInfo aLineInfo;
2455*b1cdbd2cSJim Jagielski 		if( fLineWidth != 0.0 )
2456*b1cdbd2cSJim Jagielski 			aLineInfo.SetWidth( static_cast<long>(fLineWidth+0.5) );
2457*b1cdbd2cSJim Jagielski 		ImpDrawPolyLineWithLineInfo( aToolsPolygon, aLineInfo );
2458*b1cdbd2cSJim Jagielski 	}
2459*b1cdbd2cSJim Jagielski }
2460*b1cdbd2cSJim Jagielski 
2461*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
2462*b1cdbd2cSJim Jagielski 
GetGCStackDepth() const2463*b1cdbd2cSJim Jagielski sal_uInt32 OutputDevice::GetGCStackDepth() const
2464*b1cdbd2cSJim Jagielski {
2465*b1cdbd2cSJim Jagielski     const ImplObjStack* pData = mpObjStack;
2466*b1cdbd2cSJim Jagielski     sal_uInt32 nDepth = 0;
2467*b1cdbd2cSJim Jagielski     while( pData )
2468*b1cdbd2cSJim Jagielski     {
2469*b1cdbd2cSJim Jagielski         nDepth++;
2470*b1cdbd2cSJim Jagielski         pData = pData->mpPrev;
2471*b1cdbd2cSJim Jagielski     }
2472*b1cdbd2cSJim Jagielski     return nDepth;
2473*b1cdbd2cSJim Jagielski }
2474*b1cdbd2cSJim Jagielski 
2475*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
2476*b1cdbd2cSJim Jagielski 
Push(sal_uInt16 nFlags)2477*b1cdbd2cSJim Jagielski void OutputDevice::Push( sal_uInt16 nFlags )
2478*b1cdbd2cSJim Jagielski {
2479*b1cdbd2cSJim Jagielski 	DBG_TRACE( "OutputDevice::Push()" );
2480*b1cdbd2cSJim Jagielski 	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
2481*b1cdbd2cSJim Jagielski 
2482*b1cdbd2cSJim Jagielski 	if ( mpMetaFile )
2483*b1cdbd2cSJim Jagielski 		mpMetaFile->AddAction( new MetaPushAction( nFlags ) );
2484*b1cdbd2cSJim Jagielski 
2485*b1cdbd2cSJim Jagielski 	ImplObjStack* pData = new ImplObjStack;
2486*b1cdbd2cSJim Jagielski 	pData->mpPrev = mpObjStack;
2487*b1cdbd2cSJim Jagielski 	mpObjStack = pData;
2488*b1cdbd2cSJim Jagielski 
2489*b1cdbd2cSJim Jagielski 	pData->mnFlags = nFlags;
2490*b1cdbd2cSJim Jagielski 
2491*b1cdbd2cSJim Jagielski 	if ( nFlags & PUSH_LINECOLOR )
2492*b1cdbd2cSJim Jagielski 	{
2493*b1cdbd2cSJim Jagielski 		if ( mbLineColor )
2494*b1cdbd2cSJim Jagielski 			pData->mpLineColor = new Color( maLineColor );
2495*b1cdbd2cSJim Jagielski 		else
2496*b1cdbd2cSJim Jagielski 			pData->mpLineColor = NULL;
2497*b1cdbd2cSJim Jagielski 	}
2498*b1cdbd2cSJim Jagielski 	if ( nFlags & PUSH_FILLCOLOR )
2499*b1cdbd2cSJim Jagielski 	{
2500*b1cdbd2cSJim Jagielski 		if ( mbFillColor )
2501*b1cdbd2cSJim Jagielski 			pData->mpFillColor = new Color( maFillColor );
2502*b1cdbd2cSJim Jagielski 		else
2503*b1cdbd2cSJim Jagielski 			pData->mpFillColor = NULL;
2504*b1cdbd2cSJim Jagielski 	}
2505*b1cdbd2cSJim Jagielski 	if ( nFlags & PUSH_FONT )
2506*b1cdbd2cSJim Jagielski 		pData->mpFont = new Font( maFont );
2507*b1cdbd2cSJim Jagielski 	if ( nFlags & PUSH_TEXTCOLOR )
2508*b1cdbd2cSJim Jagielski 		pData->mpTextColor = new Color( GetTextColor() );
2509*b1cdbd2cSJim Jagielski 	if ( nFlags & PUSH_TEXTFILLCOLOR )
2510*b1cdbd2cSJim Jagielski 	{
2511*b1cdbd2cSJim Jagielski 		if ( IsTextFillColor() )
2512*b1cdbd2cSJim Jagielski 			pData->mpTextFillColor = new Color( GetTextFillColor() );
2513*b1cdbd2cSJim Jagielski 		else
2514*b1cdbd2cSJim Jagielski 			pData->mpTextFillColor = NULL;
2515*b1cdbd2cSJim Jagielski 	}
2516*b1cdbd2cSJim Jagielski 	if ( nFlags & PUSH_TEXTLINECOLOR )
2517*b1cdbd2cSJim Jagielski 	{
2518*b1cdbd2cSJim Jagielski 		if ( IsTextLineColor() )
2519*b1cdbd2cSJim Jagielski 			pData->mpTextLineColor = new Color( GetTextLineColor() );
2520*b1cdbd2cSJim Jagielski 		else
2521*b1cdbd2cSJim Jagielski 			pData->mpTextLineColor = NULL;
2522*b1cdbd2cSJim Jagielski 	}
2523*b1cdbd2cSJim Jagielski 	if ( nFlags & PUSH_OVERLINECOLOR )
2524*b1cdbd2cSJim Jagielski 	{
2525*b1cdbd2cSJim Jagielski 		if ( IsOverlineColor() )
2526*b1cdbd2cSJim Jagielski 			pData->mpOverlineColor = new Color( GetOverlineColor() );
2527*b1cdbd2cSJim Jagielski 		else
2528*b1cdbd2cSJim Jagielski 			pData->mpOverlineColor = NULL;
2529*b1cdbd2cSJim Jagielski 	}
2530*b1cdbd2cSJim Jagielski 	if ( nFlags & PUSH_TEXTALIGN )
2531*b1cdbd2cSJim Jagielski 		pData->meTextAlign = GetTextAlign();
2532*b1cdbd2cSJim Jagielski 	if( nFlags & PUSH_TEXTLAYOUTMODE )
2533*b1cdbd2cSJim Jagielski 		pData->mnTextLayoutMode = GetLayoutMode();
2534*b1cdbd2cSJim Jagielski 	if( nFlags & PUSH_TEXTLANGUAGE )
2535*b1cdbd2cSJim Jagielski 		pData->meTextLanguage = GetDigitLanguage();
2536*b1cdbd2cSJim Jagielski 	if ( nFlags & PUSH_RASTEROP )
2537*b1cdbd2cSJim Jagielski 		pData->meRasterOp = GetRasterOp();
2538*b1cdbd2cSJim Jagielski 	if ( nFlags & PUSH_MAPMODE )
2539*b1cdbd2cSJim Jagielski 	{
2540*b1cdbd2cSJim Jagielski 		pData->mpMapMode = new MapMode( maMapMode );
2541*b1cdbd2cSJim Jagielski         pData->mbMapActive = mbMap;
2542*b1cdbd2cSJim Jagielski 	}
2543*b1cdbd2cSJim Jagielski 	if ( nFlags & PUSH_CLIPREGION )
2544*b1cdbd2cSJim Jagielski 	{
2545*b1cdbd2cSJim Jagielski 		if ( mbClipRegion )
2546*b1cdbd2cSJim Jagielski 			pData->mpClipRegion = new Region( maRegion );
2547*b1cdbd2cSJim Jagielski 		else
2548*b1cdbd2cSJim Jagielski 			pData->mpClipRegion = NULL;
2549*b1cdbd2cSJim Jagielski 	}
2550*b1cdbd2cSJim Jagielski 	if ( nFlags & PUSH_REFPOINT )
2551*b1cdbd2cSJim Jagielski 	{
2552*b1cdbd2cSJim Jagielski 		if ( mbRefPoint )
2553*b1cdbd2cSJim Jagielski 			pData->mpRefPoint = new Point( maRefPoint );
2554*b1cdbd2cSJim Jagielski 		else
2555*b1cdbd2cSJim Jagielski 			pData->mpRefPoint = NULL;
2556*b1cdbd2cSJim Jagielski 	}
2557*b1cdbd2cSJim Jagielski 
2558*b1cdbd2cSJim Jagielski     if( mpAlphaVDev )
2559*b1cdbd2cSJim Jagielski         mpAlphaVDev->Push();
2560*b1cdbd2cSJim Jagielski }
2561*b1cdbd2cSJim Jagielski 
2562*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
2563*b1cdbd2cSJim Jagielski 
Pop()2564*b1cdbd2cSJim Jagielski void OutputDevice::Pop()
2565*b1cdbd2cSJim Jagielski {
2566*b1cdbd2cSJim Jagielski 	DBG_TRACE( "OutputDevice::Pop()" );
2567*b1cdbd2cSJim Jagielski 	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
2568*b1cdbd2cSJim Jagielski 
2569*b1cdbd2cSJim Jagielski 	if( mpMetaFile )
2570*b1cdbd2cSJim Jagielski 		mpMetaFile->AddAction( new MetaPopAction() );
2571*b1cdbd2cSJim Jagielski 
2572*b1cdbd2cSJim Jagielski 	GDIMetaFile*	pOldMetaFile = mpMetaFile;
2573*b1cdbd2cSJim Jagielski 	ImplObjStack*	pData = mpObjStack;
2574*b1cdbd2cSJim Jagielski 	mpMetaFile = NULL;
2575*b1cdbd2cSJim Jagielski 
2576*b1cdbd2cSJim Jagielski 	if ( !pData )
2577*b1cdbd2cSJim Jagielski 	{
2578*b1cdbd2cSJim Jagielski 		DBG_ERRORFILE( "OutputDevice::Pop() without OutputDevice::Push()" );
2579*b1cdbd2cSJim Jagielski 		return;
2580*b1cdbd2cSJim Jagielski 	}
2581*b1cdbd2cSJim Jagielski 
2582*b1cdbd2cSJim Jagielski     if( mpAlphaVDev )
2583*b1cdbd2cSJim Jagielski         mpAlphaVDev->Pop();
2584*b1cdbd2cSJim Jagielski 
2585*b1cdbd2cSJim Jagielski 	mpObjStack = pData->mpPrev;
2586*b1cdbd2cSJim Jagielski 
2587*b1cdbd2cSJim Jagielski 	if ( pData->mnFlags & PUSH_LINECOLOR )
2588*b1cdbd2cSJim Jagielski 	{
2589*b1cdbd2cSJim Jagielski 		if ( pData->mpLineColor )
2590*b1cdbd2cSJim Jagielski 			SetLineColor( *pData->mpLineColor );
2591*b1cdbd2cSJim Jagielski 		else
2592*b1cdbd2cSJim Jagielski 			SetLineColor();
2593*b1cdbd2cSJim Jagielski 	}
2594*b1cdbd2cSJim Jagielski 	if ( pData->mnFlags & PUSH_FILLCOLOR )
2595*b1cdbd2cSJim Jagielski 	{
2596*b1cdbd2cSJim Jagielski 		if ( pData->mpFillColor )
2597*b1cdbd2cSJim Jagielski 			SetFillColor( *pData->mpFillColor );
2598*b1cdbd2cSJim Jagielski 		else
2599*b1cdbd2cSJim Jagielski 			SetFillColor();
2600*b1cdbd2cSJim Jagielski 	}
2601*b1cdbd2cSJim Jagielski 	if ( pData->mnFlags & PUSH_FONT )
2602*b1cdbd2cSJim Jagielski 		SetFont( *pData->mpFont );
2603*b1cdbd2cSJim Jagielski 	if ( pData->mnFlags & PUSH_TEXTCOLOR )
2604*b1cdbd2cSJim Jagielski 		SetTextColor( *pData->mpTextColor );
2605*b1cdbd2cSJim Jagielski 	if ( pData->mnFlags & PUSH_TEXTFILLCOLOR )
2606*b1cdbd2cSJim Jagielski 	{
2607*b1cdbd2cSJim Jagielski 		if ( pData->mpTextFillColor )
2608*b1cdbd2cSJim Jagielski 			SetTextFillColor( *pData->mpTextFillColor );
2609*b1cdbd2cSJim Jagielski 		else
2610*b1cdbd2cSJim Jagielski 			SetTextFillColor();
2611*b1cdbd2cSJim Jagielski 	}
2612*b1cdbd2cSJim Jagielski 	if ( pData->mnFlags & PUSH_TEXTLINECOLOR )
2613*b1cdbd2cSJim Jagielski 	{
2614*b1cdbd2cSJim Jagielski 		if ( pData->mpTextLineColor )
2615*b1cdbd2cSJim Jagielski 			SetTextLineColor( *pData->mpTextLineColor );
2616*b1cdbd2cSJim Jagielski 		else
2617*b1cdbd2cSJim Jagielski 			SetTextLineColor();
2618*b1cdbd2cSJim Jagielski 	}
2619*b1cdbd2cSJim Jagielski 	if ( pData->mnFlags & PUSH_OVERLINECOLOR )
2620*b1cdbd2cSJim Jagielski 	{
2621*b1cdbd2cSJim Jagielski 		if ( pData->mpOverlineColor )
2622*b1cdbd2cSJim Jagielski 			SetOverlineColor( *pData->mpOverlineColor );
2623*b1cdbd2cSJim Jagielski 		else
2624*b1cdbd2cSJim Jagielski 			SetOverlineColor();
2625*b1cdbd2cSJim Jagielski 	}
2626*b1cdbd2cSJim Jagielski 	if ( pData->mnFlags & PUSH_TEXTALIGN )
2627*b1cdbd2cSJim Jagielski 		SetTextAlign( pData->meTextAlign );
2628*b1cdbd2cSJim Jagielski 	if( pData->mnFlags & PUSH_TEXTLAYOUTMODE )
2629*b1cdbd2cSJim Jagielski 		SetLayoutMode( pData->mnTextLayoutMode );
2630*b1cdbd2cSJim Jagielski 	if( pData->mnFlags & PUSH_TEXTLANGUAGE )
2631*b1cdbd2cSJim Jagielski 		SetDigitLanguage( pData->meTextLanguage );
2632*b1cdbd2cSJim Jagielski 	if ( pData->mnFlags & PUSH_RASTEROP )
2633*b1cdbd2cSJim Jagielski 		SetRasterOp( pData->meRasterOp );
2634*b1cdbd2cSJim Jagielski 	if ( pData->mnFlags & PUSH_MAPMODE )
2635*b1cdbd2cSJim Jagielski 	{
2636*b1cdbd2cSJim Jagielski 		if ( pData->mpMapMode )
2637*b1cdbd2cSJim Jagielski 			SetMapMode( *pData->mpMapMode );
2638*b1cdbd2cSJim Jagielski 		else
2639*b1cdbd2cSJim Jagielski 			SetMapMode();
2640*b1cdbd2cSJim Jagielski         mbMap = pData->mbMapActive;
2641*b1cdbd2cSJim Jagielski 	}
2642*b1cdbd2cSJim Jagielski 	if ( pData->mnFlags & PUSH_CLIPREGION )
2643*b1cdbd2cSJim Jagielski 		ImplSetClipRegion( pData->mpClipRegion );
2644*b1cdbd2cSJim Jagielski 	if ( pData->mnFlags & PUSH_REFPOINT )
2645*b1cdbd2cSJim Jagielski 	{
2646*b1cdbd2cSJim Jagielski 		if ( pData->mpRefPoint )
2647*b1cdbd2cSJim Jagielski 			SetRefPoint( *pData->mpRefPoint );
2648*b1cdbd2cSJim Jagielski 		else
2649*b1cdbd2cSJim Jagielski 			SetRefPoint();
2650*b1cdbd2cSJim Jagielski 	}
2651*b1cdbd2cSJim Jagielski 
2652*b1cdbd2cSJim Jagielski 	ImplDeleteObjStack( pData );
2653*b1cdbd2cSJim Jagielski 
2654*b1cdbd2cSJim Jagielski 	mpMetaFile = pOldMetaFile;
2655*b1cdbd2cSJim Jagielski }
2656*b1cdbd2cSJim Jagielski 
2657*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
2658*b1cdbd2cSJim Jagielski 
SetConnectMetaFile(GDIMetaFile * pMtf)2659*b1cdbd2cSJim Jagielski void OutputDevice::SetConnectMetaFile( GDIMetaFile* pMtf )
2660*b1cdbd2cSJim Jagielski {
2661*b1cdbd2cSJim Jagielski     mpMetaFile = pMtf;
2662*b1cdbd2cSJim Jagielski }
2663*b1cdbd2cSJim Jagielski 
2664*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
2665*b1cdbd2cSJim Jagielski 
EnableOutput(sal_Bool bEnable)2666*b1cdbd2cSJim Jagielski void OutputDevice::EnableOutput( sal_Bool bEnable )
2667*b1cdbd2cSJim Jagielski {
2668*b1cdbd2cSJim Jagielski     mbOutput = (bEnable != 0);
2669*b1cdbd2cSJim Jagielski 
2670*b1cdbd2cSJim Jagielski     if( mpAlphaVDev )
2671*b1cdbd2cSJim Jagielski         mpAlphaVDev->EnableOutput( bEnable );
2672*b1cdbd2cSJim Jagielski }
2673*b1cdbd2cSJim Jagielski 
2674*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
2675*b1cdbd2cSJim Jagielski 
SetSettings(const AllSettings & rSettings)2676*b1cdbd2cSJim Jagielski void OutputDevice::SetSettings( const AllSettings& rSettings )
2677*b1cdbd2cSJim Jagielski {
2678*b1cdbd2cSJim Jagielski     maSettings = rSettings;
2679*b1cdbd2cSJim Jagielski 
2680*b1cdbd2cSJim Jagielski     if( mpAlphaVDev )
2681*b1cdbd2cSJim Jagielski         mpAlphaVDev->SetSettings( rSettings );
2682*b1cdbd2cSJim Jagielski }
2683*b1cdbd2cSJim Jagielski 
2684*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
2685*b1cdbd2cSJim Jagielski 
GetBitCount() const2686*b1cdbd2cSJim Jagielski sal_uInt16 OutputDevice::GetBitCount() const
2687*b1cdbd2cSJim Jagielski {
2688*b1cdbd2cSJim Jagielski 	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
2689*b1cdbd2cSJim Jagielski 
2690*b1cdbd2cSJim Jagielski 	if ( meOutDevType == OUTDEV_VIRDEV )
2691*b1cdbd2cSJim Jagielski 		return ((VirtualDevice*)this)->mnBitCount;
2692*b1cdbd2cSJim Jagielski 
2693*b1cdbd2cSJim Jagielski 	// we need a graphics
2694*b1cdbd2cSJim Jagielski 	if ( !mpGraphics )
2695*b1cdbd2cSJim Jagielski 	{
2696*b1cdbd2cSJim Jagielski 		if ( !((OutputDevice*)this)->ImplGetGraphics() )
2697*b1cdbd2cSJim Jagielski 			return 0;
2698*b1cdbd2cSJim Jagielski 	}
2699*b1cdbd2cSJim Jagielski 
2700*b1cdbd2cSJim Jagielski 	return (sal_uInt16)mpGraphics->GetBitCount();
2701*b1cdbd2cSJim Jagielski }
2702*b1cdbd2cSJim Jagielski 
2703*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
2704*b1cdbd2cSJim Jagielski 
GetAlphaBitCount() const2705*b1cdbd2cSJim Jagielski sal_uInt16 OutputDevice::GetAlphaBitCount() const
2706*b1cdbd2cSJim Jagielski {
2707*b1cdbd2cSJim Jagielski 	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
2708*b1cdbd2cSJim Jagielski 
2709*b1cdbd2cSJim Jagielski 	if ( meOutDevType == OUTDEV_VIRDEV &&
2710*b1cdbd2cSJim Jagielski         mpAlphaVDev != NULL )
2711*b1cdbd2cSJim Jagielski     {
2712*b1cdbd2cSJim Jagielski 		return mpAlphaVDev->GetBitCount();
2713*b1cdbd2cSJim Jagielski     }
2714*b1cdbd2cSJim Jagielski 
2715*b1cdbd2cSJim Jagielski     return 0;
2716*b1cdbd2cSJim Jagielski }
2717*b1cdbd2cSJim Jagielski 
2718*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
2719*b1cdbd2cSJim Jagielski 
GetColorCount() const2720*b1cdbd2cSJim Jagielski sal_uLong OutputDevice::GetColorCount() const
2721*b1cdbd2cSJim Jagielski {
2722*b1cdbd2cSJim Jagielski 	DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
2723*b1cdbd2cSJim Jagielski 
2724*b1cdbd2cSJim Jagielski 	const sal_uInt16 nBitCount = GetBitCount();
2725*b1cdbd2cSJim Jagielski 	return( ( nBitCount > 31 ) ? ULONG_MAX : ( ( (sal_uLong) 1 ) << nBitCount) );
2726*b1cdbd2cSJim Jagielski }
2727*b1cdbd2cSJim Jagielski 
2728*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
2729*b1cdbd2cSJim Jagielski 
HasAlpha()2730*b1cdbd2cSJim Jagielski sal_Bool OutputDevice::HasAlpha()
2731*b1cdbd2cSJim Jagielski {
2732*b1cdbd2cSJim Jagielski     return mpAlphaVDev != NULL;
2733*b1cdbd2cSJim Jagielski }
2734*b1cdbd2cSJim Jagielski 
2735*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
2736*b1cdbd2cSJim Jagielski 
CreateUnoGraphics()2737*b1cdbd2cSJim Jagielski ::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics > OutputDevice::CreateUnoGraphics()
2738*b1cdbd2cSJim Jagielski {
2739*b1cdbd2cSJim Jagielski 	UnoWrapperBase* pWrapper = Application::GetUnoWrapper();
2740*b1cdbd2cSJim Jagielski 	return pWrapper ? pWrapper->CreateGraphics( this ) : ::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics >();
2741*b1cdbd2cSJim Jagielski }
2742*b1cdbd2cSJim Jagielski 
2743*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
2744*b1cdbd2cSJim Jagielski 
GetSystemGfxData() const2745*b1cdbd2cSJim Jagielski SystemGraphicsData OutputDevice::GetSystemGfxData() const
2746*b1cdbd2cSJim Jagielski {
2747*b1cdbd2cSJim Jagielski 	if ( !mpGraphics )
2748*b1cdbd2cSJim Jagielski 	{
2749*b1cdbd2cSJim Jagielski 		if ( !ImplGetGraphics() )
2750*b1cdbd2cSJim Jagielski 			return SystemGraphicsData();
2751*b1cdbd2cSJim Jagielski 	}
2752*b1cdbd2cSJim Jagielski 
2753*b1cdbd2cSJim Jagielski     return mpGraphics->GetGraphicsData();
2754*b1cdbd2cSJim Jagielski }
2755*b1cdbd2cSJim Jagielski 
2756*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
2757*b1cdbd2cSJim Jagielski 
GetSystemGfxDataAny() const2758*b1cdbd2cSJim Jagielski ::com::sun::star::uno::Any OutputDevice::GetSystemGfxDataAny() const
2759*b1cdbd2cSJim Jagielski {
2760*b1cdbd2cSJim Jagielski     ::com::sun::star::uno::Any aRet;
2761*b1cdbd2cSJim Jagielski     const SystemGraphicsData aSysData = GetSystemGfxData();
2762*b1cdbd2cSJim Jagielski     ::com::sun::star::uno::Sequence< sal_Int8 > aSeq( (sal_Int8*)&aSysData,
2763*b1cdbd2cSJim Jagielski                                                       aSysData.nSize );
2764*b1cdbd2cSJim Jagielski 
2765*b1cdbd2cSJim Jagielski     return uno::makeAny(aSeq);
2766*b1cdbd2cSJim Jagielski }
2767*b1cdbd2cSJim Jagielski 
2768*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
2769*b1cdbd2cSJim Jagielski 
GetCanvas() const2770*b1cdbd2cSJim Jagielski ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XCanvas > OutputDevice::GetCanvas() const
2771*b1cdbd2cSJim Jagielski {
2772*b1cdbd2cSJim Jagielski     uno::Sequence< uno::Any > aArg(6);
2773*b1cdbd2cSJim Jagielski 
2774*b1cdbd2cSJim Jagielski     aArg[ 0 ] = uno::makeAny( reinterpret_cast<sal_Int64>(this) );
2775*b1cdbd2cSJim Jagielski     aArg[ 2 ] = uno::makeAny( ::com::sun::star::awt::Rectangle( mnOutOffX, mnOutOffY, mnOutWidth, mnOutHeight ) );
2776*b1cdbd2cSJim Jagielski     aArg[ 3 ] = uno::makeAny( sal_False );
2777*b1cdbd2cSJim Jagielski     aArg[ 5 ] = GetSystemGfxDataAny();
2778*b1cdbd2cSJim Jagielski 
2779*b1cdbd2cSJim Jagielski     uno::Reference<lang::XMultiServiceFactory> xFactory = vcl::unohelper::GetMultiServiceFactory();
2780*b1cdbd2cSJim Jagielski 
2781*b1cdbd2cSJim Jagielski     uno::Reference<rendering::XCanvas> xCanvas;
2782*b1cdbd2cSJim Jagielski 
2783*b1cdbd2cSJim Jagielski     // Create canvas instance with window handle
2784*b1cdbd2cSJim Jagielski     // =========================================
2785*b1cdbd2cSJim Jagielski     if ( xFactory.is() )
2786*b1cdbd2cSJim Jagielski     {
2787*b1cdbd2cSJim Jagielski         static uno::Reference<lang::XMultiServiceFactory> xCanvasFactory(
2788*b1cdbd2cSJim Jagielski             xFactory->createInstance(
2789*b1cdbd2cSJim Jagielski                 OUString( RTL_CONSTASCII_USTRINGPARAM(
2790*b1cdbd2cSJim Jagielski                               "com.sun.star."
2791*b1cdbd2cSJim Jagielski                               "rendering.CanvasFactory") ) ),
2792*b1cdbd2cSJim Jagielski             uno::UNO_QUERY );
2793*b1cdbd2cSJim Jagielski         if(xCanvasFactory.is())
2794*b1cdbd2cSJim Jagielski         {
2795*b1cdbd2cSJim Jagielski             xCanvas.set(
2796*b1cdbd2cSJim Jagielski                 xCanvasFactory->createInstanceWithArguments(
2797*b1cdbd2cSJim Jagielski                     OUString( RTL_CONSTASCII_USTRINGPARAM(
2798*b1cdbd2cSJim Jagielski                                   "com.sun.star.rendering.Canvas" )),
2799*b1cdbd2cSJim Jagielski                     aArg ),
2800*b1cdbd2cSJim Jagielski                 uno::UNO_QUERY );
2801*b1cdbd2cSJim Jagielski         }
2802*b1cdbd2cSJim Jagielski     }
2803*b1cdbd2cSJim Jagielski 
2804*b1cdbd2cSJim Jagielski     return xCanvas;
2805*b1cdbd2cSJim Jagielski }
2806*b1cdbd2cSJim Jagielski 
2807*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------
2808