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