Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <tools/debug.hxx>
31 : : #include <vcl/outdev.hxx>
32 : : #include <vcl/virdev.hxx>
33 : : #include <vcl/bmpacc.hxx>
34 : : #include <vcl/metaact.hxx>
35 : : #include <vcl/gdimtf.hxx>
36 : : #include <vcl/svapp.hxx>
37 : : #include <vcl/wrkwin.hxx>
38 : : #include <vcl/graph.hxx>
39 : : #include <vcl/rendergraphicrasterizer.hxx>
40 : :
41 : : #include <wall2.hxx>
42 : : #include <salgdi.hxx>
43 : : #include <window.h>
44 : : #include <svdata.hxx>
45 : : #include <outdev.h>
46 : :
47 : : #include <com/sun/star/uno/Sequence.hxx>
48 : :
49 : : #include <basegfx/vector/b2dvector.hxx>
50 : : #include <basegfx/polygon/b2dpolypolygon.hxx>
51 : : #include <basegfx/polygon/b2dpolygon.hxx>
52 : : #include <basegfx/matrix/b2dhommatrix.hxx>
53 : :
54 : : #include <math.h>
55 : :
56 : : // ========================================================================
57 : :
58 : : DBG_NAMEEX( OutputDevice )
59 : :
60 : : // ------------------------------------------------------------------------
61 : :
62 : 3764 : void OutputDevice::DrawGrid( const Rectangle& rRect, const Size& rDist, sal_uLong nFlags )
63 : : {
64 : : OSL_TRACE( "OutputDevice::DrawGrid()" );
65 : : DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
66 : :
67 [ + - ][ + - ]: 3764 : Rectangle aDstRect( PixelToLogic( Point() ), GetOutputSize() );
[ + - ]
68 [ + - ]: 3764 : aDstRect.Intersection( rRect );
69 : :
70 [ + - ][ + - ]: 3764 : if( aDstRect.IsEmpty() || ImplIsRecordLayout() )
[ + - ][ - + ]
[ + - ]
71 : : return;
72 : :
73 [ - + ][ # # ]: 3764 : if( !mpGraphics && !ImplGetGraphics() )
[ # # ][ + - ]
74 : : return;
75 : :
76 [ + + ]: 3764 : if( mbInitClipRegion )
77 [ + - ]: 25 : ImplInitClipRegion();
78 : :
79 [ + - ]: 3764 : if( mbOutputClipped )
80 : : return;
81 : :
82 : 3764 : const long nDistX = Max( rDist.Width(), 1L );
83 : 3764 : const long nDistY = Max( rDist.Height(), 1L );
84 [ + + ]: 3764 : long nX = ( rRect.Left() >= aDstRect.Left() ) ? rRect.Left() : ( rRect.Left() + ( ( aDstRect.Left() - rRect.Left() ) / nDistX ) * nDistX );
85 [ + - ]: 3764 : long nY = ( rRect.Top() >= aDstRect.Top() ) ? rRect.Top() : ( rRect.Top() + ( ( aDstRect.Top() - rRect.Top() ) / nDistY ) * nDistY );
86 : 3764 : const long nRight = aDstRect.Right();
87 : 3764 : const long nBottom = aDstRect.Bottom();
88 [ + - ]: 3764 : const long nStartX = ImplLogicXToDevicePixel( nX );
89 [ + - ]: 3764 : const long nEndX = ImplLogicXToDevicePixel( nRight );
90 [ + - ]: 3764 : const long nStartY = ImplLogicYToDevicePixel( nY );
91 [ + - ]: 3764 : const long nEndY = ImplLogicYToDevicePixel( nBottom );
92 : 3764 : long nHorzCount = 0L;
93 : 3764 : long nVertCount = 0L;
94 : :
95 [ + - ]: 3764 : ::com::sun::star::uno::Sequence< sal_Int32 > aVertBuf;
96 [ + - ]: 3764 : ::com::sun::star::uno::Sequence< sal_Int32 > aHorzBuf;
97 : :
98 [ + + ][ + + ]: 3764 : if( ( nFlags & GRID_DOTS ) || ( nFlags & GRID_HORZLINES ) )
99 : : {
100 [ + - ][ + - ]: 2193 : aVertBuf.realloc( aDstRect.GetHeight() / nDistY + 2L );
101 [ + - ]: 2193 : aVertBuf[ nVertCount++ ] = nStartY;
102 [ + + ]: 27962 : while( ( nY += nDistY ) <= nBottom )
103 [ + - ][ + - ]: 25769 : aVertBuf[ nVertCount++ ] = ImplLogicYToDevicePixel( nY );
104 : : }
105 : :
106 [ + + ][ + + ]: 3764 : if( ( nFlags & GRID_DOTS ) || ( nFlags & GRID_VERTLINES ) )
107 : : {
108 [ + - ][ + - ]: 1961 : aHorzBuf.realloc( aDstRect.GetWidth() / nDistX + 2L );
109 [ + - ]: 1961 : aHorzBuf[ nHorzCount++ ] = nStartX;
110 [ + + ]: 20449 : while( ( nX += nDistX ) <= nRight )
111 [ + - ][ + - ]: 18488 : aHorzBuf[ nHorzCount++ ] = ImplLogicXToDevicePixel( nX );
112 : : }
113 : :
114 [ + + ]: 3764 : if( mbInitLineColor )
115 [ + - ]: 1920 : ImplInitLineColor();
116 : :
117 [ - + ]: 3764 : if( mbInitFillColor )
118 [ # # ]: 0 : ImplInitFillColor();
119 : :
120 : 3764 : const sal_Bool bOldMap = mbMap;
121 [ + - ]: 3764 : EnableMapMode( sal_False );
122 : :
123 [ + + ]: 3764 : if( nFlags & GRID_DOTS )
124 : : {
125 [ + + ]: 5249 : for( long i = 0L; i < nVertCount; i++ )
126 [ + - ][ + + ]: 102788 : for( long j = 0L, Y = aVertBuf[ i ]; j < nHorzCount; j++ )
127 [ + - ][ + - ]: 97929 : mpGraphics->DrawPixel( aHorzBuf[ j ], Y, this );
128 : : }
129 : : else
130 : : {
131 [ + + ]: 3374 : if( nFlags & GRID_HORZLINES )
132 : : {
133 [ + + ]: 24906 : for( long i = 0L; i < nVertCount; i++ )
134 : : {
135 [ + - ]: 23103 : nY = aVertBuf[ i ];
136 [ + - ]: 23103 : mpGraphics->DrawLine( nStartX, nY, nEndX, nY, this );
137 : : }
138 : : }
139 : :
140 [ + + ]: 3374 : if( nFlags & GRID_VERTLINES )
141 : : {
142 [ + + ]: 14158 : for( long i = 0L; i < nHorzCount; i++ )
143 : : {
144 [ + - ]: 12587 : nX = aHorzBuf[ i ];
145 [ + - ]: 12587 : mpGraphics->DrawLine( nX, nStartY, nX, nEndY, this );
146 : : }
147 : : }
148 : : }
149 : :
150 [ + - ]: 3764 : EnableMapMode( bOldMap );
151 : :
152 [ - + ]: 3764 : if( mpAlphaVDev )
153 [ # # ][ + - ]: 3764 : mpAlphaVDev->DrawGrid( rRect, rDist, nFlags );
[ + - ]
154 : : }
155 : :
156 : : // ------------------------------------------------------------------------
157 : : // Caution: This method is nearly the same as
158 : : // void OutputDevice::DrawPolyPolygon( const basegfx::B2DPolyPolygon& rB2DPolyPoly )
159 : : // so when changes are made here do not forget to make change sthere, too
160 : :
161 : 0 : void OutputDevice::DrawTransparent( const basegfx::B2DPolyPolygon& rB2DPolyPoly, double fTransparency)
162 : : {
163 : : OSL_TRACE( "OutputDevice::DrawTransparent(B2D&,transparency)" );
164 : : DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
165 : :
166 : : // AW: Do NOT paint empty PolyPolygons
167 [ # # ][ # # ]: 0 : if(!rB2DPolyPoly.count())
168 : : return;
169 : :
170 : : // we need a graphics
171 [ # # ]: 0 : if( !mpGraphics )
172 [ # # ][ # # ]: 0 : if( !ImplGetGraphics() )
173 : : return;
174 : :
175 [ # # ]: 0 : if( mbInitClipRegion )
176 [ # # ]: 0 : ImplInitClipRegion();
177 [ # # ]: 0 : if( mbOutputClipped )
178 : : return;
179 : :
180 [ # # ]: 0 : if( mbInitLineColor )
181 [ # # ]: 0 : ImplInitLineColor();
182 [ # # ]: 0 : if( mbInitFillColor )
183 [ # # ]: 0 : ImplInitFillColor();
184 : :
185 [ # # ]: 0 : if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
[ # # # # ]
[ # # ]
186 [ # # ]: 0 : && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
187 : 0 : && ROP_OVERPAINT == GetRasterOp() )
188 : : {
189 : : // b2dpolygon support not implemented yet on non-UNX platforms
190 [ # # ]: 0 : const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation();
191 [ # # ]: 0 : basegfx::B2DPolyPolygon aB2DPolyPolygon(rB2DPolyPoly);
192 : :
193 : : // transform the polygon into device space and ensure it is closed
194 [ # # ]: 0 : aB2DPolyPolygon.transform( aTransform );
195 [ # # ]: 0 : aB2DPolyPolygon.setClosed( true );
196 : :
197 : 0 : bool bDrawnOk = true;
198 [ # # ]: 0 : if( IsFillColor() )
199 [ # # ]: 0 : bDrawnOk = mpGraphics->DrawPolyPolygon( aB2DPolyPolygon, fTransparency, this );
200 [ # # ][ # # ]: 0 : if( bDrawnOk && IsLineColor() )
[ # # ]
201 : : {
202 : 0 : const basegfx::B2DVector aHairlineWidth(1,1);
203 [ # # ]: 0 : const int nPolyCount = aB2DPolyPolygon.count();
204 [ # # ]: 0 : for( int nPolyIdx = 0; nPolyIdx < nPolyCount; ++nPolyIdx )
205 : : {
206 [ # # ]: 0 : const ::basegfx::B2DPolygon aOnePoly = aB2DPolyPolygon.getB2DPolygon( nPolyIdx );
207 [ # # ]: 0 : mpGraphics->DrawPolyLine( aOnePoly, fTransparency, aHairlineWidth, ::basegfx::B2DLINEJOIN_NONE, this );
208 [ # # ]: 0 : }
209 : : }
210 : :
211 [ # # ]: 0 : if( bDrawnOk )
212 : : {
213 [ # # ]: 0 : if( mpMetaFile )
214 [ # # ][ # # ]: 0 : mpMetaFile->AddAction( new MetaTransparentAction( PolyPolygon( rB2DPolyPoly ), static_cast< sal_uInt16 >(fTransparency * 100.0)));
[ # # ][ # # ]
[ # # ]
215 : : return;
216 [ # # ][ # # ]: 0 : }
[ # # ][ # # ]
217 : : }
218 : :
219 : : // fallback to old polygon drawing if needed
220 [ # # ]: 0 : const PolyPolygon aToolsPolyPolygon( rB2DPolyPoly );
221 [ # # ][ # # ]: 0 : DrawTransparent(PolyPolygon(rB2DPolyPoly), static_cast< sal_uInt16 >(fTransparency * 100.0));
[ # # ][ # # ]
222 : : }
223 : :
224 : : // ------------------------------------------------------------------------
225 : :
226 : 4186 : void OutputDevice::DrawTransparent( const PolyPolygon& rPolyPoly,
227 : : sal_uInt16 nTransparencePercent )
228 : : {
229 : : OSL_TRACE( "OutputDevice::DrawTransparent()" );
230 : : DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
231 : :
232 : : // short circuit for drawing an opaque polygon
233 [ + - ][ - + ]: 4186 : if( (nTransparencePercent < 1) || ((mnDrawMode & DRAWMODE_NOTRANSPARENCY) != 0) )
234 : : {
235 : 0 : DrawPolyPolygon( rPolyPoly );
236 : 0 : return;
237 : : }
238 : :
239 : : // short circut for drawing an invisible polygon
240 [ + + ][ - + ]: 4186 : if( !mbFillColor || (nTransparencePercent >= 100) )
241 : : {
242 : : // short circuit if the polygon border is invisible too
243 [ + - ]: 2 : if( !mbLineColor )
244 : 2 : return;
245 : :
246 : : // DrawTransparent() assumes that the border is NOT to be drawn transparently???
247 : 0 : Push( PUSH_FILLCOLOR );
248 : 0 : SetFillColor();
249 : 0 : DrawPolyPolygon( rPolyPoly );
250 : 0 : Pop();
251 : 0 : return;
252 : : }
253 : :
254 : : // handle metafile recording
255 [ - + ]: 4184 : if( mpMetaFile )
256 [ # # ]: 0 : mpMetaFile->AddAction( new MetaTransparentAction( rPolyPoly, nTransparencePercent ) );
257 : :
258 [ + - ][ - + ]: 4184 : bool bDrawn = !IsDeviceOutputNecessary() || ImplIsRecordLayout();
259 [ - + ]: 4184 : if( bDrawn )
260 : 0 : return;
261 : :
262 : : // get the device graphics as drawing target
263 [ - + ]: 4184 : if( !mpGraphics )
264 [ # # ]: 0 : if( !ImplGetGraphics() )
265 : 0 : return;
266 : :
267 : : // debug helper:
268 [ + + ][ + - ]: 4184 : static const char* pDisableNative = getenv( "SAL_DISABLE_NATIVE_ALPHA");
269 : :
270 : : // try hard to draw it directly, because the emulation layers are slower
271 [ + - - + : 8368 : if( !pDisableNative
# # ][ - + ]
272 : 4184 : && mpGraphics->supportsOperation( OutDevSupport_B2DDraw )
273 : : #if defined UNX && ! defined QUARTZ
274 : 0 : && GetBitCount() > 8
275 : : #endif
276 : : #ifdef WIN32
277 : : // workaround bad dithering on remote displaying when using GDI+ with toolbar buttoin hilighting
278 : : && !rPolyPoly.IsRect()
279 : : #endif
280 : : )
281 : : {
282 : : // prepare the graphics device
283 [ # # ]: 0 : if( mbInitClipRegion )
284 [ # # ]: 0 : ImplInitClipRegion();
285 [ # # ]: 0 : if( mbOutputClipped )
286 : : return;
287 [ # # ]: 0 : if( mbInitLineColor )
288 [ # # ]: 0 : ImplInitLineColor();
289 [ # # ]: 0 : if( mbInitFillColor )
290 [ # # ]: 0 : ImplInitFillColor();
291 : :
292 : : // get the polygon in device coordinates
293 [ # # ]: 0 : basegfx::B2DPolyPolygon aB2DPolyPolygon( rPolyPoly.getB2DPolyPolygon() );
294 [ # # ]: 0 : const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation();
295 [ # # ]: 0 : aB2DPolyPolygon.transform( aTransform );
296 : :
297 : 0 : const double fTransparency = 0.01 * nTransparencePercent;
298 [ # # ]: 0 : if( mbFillColor )
299 : : {
300 : : // draw the transparent polygon
301 : : // NOTE: filled polygons are assumed to be drawn as if they were always closed
302 [ # # ]: 0 : bDrawn = mpGraphics->DrawPolyPolygon( aB2DPolyPolygon, fTransparency, this );
303 : : }
304 : :
305 [ # # ]: 0 : if( mbLineColor )
306 : : {
307 : : // disable the fill color for now
308 [ # # ]: 0 : mpGraphics->SetFillColor();
309 : : // draw the border line
310 : 0 : const basegfx::B2DVector aLineWidths( 1, 1 );
311 [ # # ]: 0 : const int nPolyCount = aB2DPolyPolygon.count();
312 [ # # ]: 0 : for( int nPolyIdx = 0; nPolyIdx < nPolyCount; ++nPolyIdx )
313 : : {
314 [ # # ]: 0 : const ::basegfx::B2DPolygon& rPolygon = aB2DPolyPolygon.getB2DPolygon( nPolyIdx );
315 [ # # ]: 0 : bDrawn = mpGraphics->DrawPolyLine( rPolygon, fTransparency, aLineWidths, ::basegfx::B2DLINEJOIN_NONE, this );
316 [ # # ]: 0 : }
317 : : // prepare to restore the fill color
318 : 0 : mbInitFillColor = mbFillColor;
319 [ # # ][ # # ]: 0 : }
320 : : }
321 : :
322 [ - + ]: 4184 : if( bDrawn )
323 : 0 : return;
324 : :
325 : 4184 : VirtualDevice* pOldAlphaVDev = mpAlphaVDev;
326 : :
327 : : // #110958# Disable alpha VDev, we perform the necessary
328 : : // operation explicitly further below.
329 [ - + ]: 4184 : if( mpAlphaVDev )
330 : 0 : mpAlphaVDev = NULL;
331 : :
332 : 4184 : GDIMetaFile* pOldMetaFile = mpMetaFile;
333 : 4184 : mpMetaFile = NULL;
334 : :
335 [ - + ]: 4184 : if( OUTDEV_PRINTER == meOutDevType )
336 : : {
337 [ # # ]: 0 : if(100 <= nTransparencePercent)
338 : : {
339 : : // #i112959# 100% transparent, draw nothing
340 : : return;
341 : : }
342 : :
343 [ # # ][ # # ]: 0 : Rectangle aPolyRect( LogicToPixel( rPolyPoly ).GetBoundRect() );
[ # # ]
344 [ # # ][ # # ]: 0 : const Size aDPISize( LogicToPixel( Size( 1, 1 ), MAP_INCH ) );
[ # # ]
345 : 0 : const long nBaseExtent = Max( FRound( aDPISize.Width() / 300. ), 1L );
346 : : long nMove;
347 : : const sal_uInt16 nTrans = ( nTransparencePercent < 13 ) ? 0 :
348 : : ( nTransparencePercent < 38 ) ? 25 :
349 : : ( nTransparencePercent < 63 ) ? 50 :
350 [ # # ][ # # ]: 0 : ( nTransparencePercent < 88 ) ? 75 : 100;
[ # # ][ # # ]
351 : :
352 [ # # # # : 0 : switch( nTrans )
# ]
353 : : {
354 : 0 : case( 25 ): nMove = nBaseExtent * 3; break;
355 : 0 : case( 50 ): nMove = nBaseExtent * 4; break;
356 : 0 : case( 75 ): nMove = nBaseExtent * 6; break;
357 : :
358 : : // #i112959# very transparent (88 < nTransparencePercent <= 99)
359 : 0 : case( 100 ): nMove = nBaseExtent * 8; break;
360 : :
361 : : // #i112959# not transparent (nTransparencePercent < 13)
362 : 0 : default: nMove = 0; break;
363 : : }
364 : :
365 [ # # ]: 0 : Push( PUSH_CLIPREGION | PUSH_LINECOLOR );
366 [ # # ][ # # ]: 0 : IntersectClipRegion( rPolyPoly );
[ # # ]
367 [ # # ]: 0 : SetLineColor( GetFillColor() );
368 : 0 : const sal_Bool bOldMap = mbMap;
369 [ # # ]: 0 : EnableMapMode( sal_False );
370 : :
371 [ # # ]: 0 : if(nMove)
372 : : {
373 [ # # ][ # # ]: 0 : Rectangle aRect( aPolyRect.TopLeft(), Size( aPolyRect.GetWidth(), nBaseExtent ) );
374 [ # # ]: 0 : while( aRect.Top() <= aPolyRect.Bottom() )
375 : : {
376 [ # # ]: 0 : DrawRect( aRect );
377 [ # # ]: 0 : aRect.Move( 0, nMove );
378 : : }
379 : :
380 [ # # ][ # # ]: 0 : aRect = Rectangle( aPolyRect.TopLeft(), Size( nBaseExtent, aPolyRect.GetHeight() ) );
381 [ # # ]: 0 : while( aRect.Left() <= aPolyRect.Right() )
382 : : {
383 [ # # ]: 0 : DrawRect( aRect );
384 [ # # ]: 0 : aRect.Move( nMove, 0 );
385 : : }
386 : : }
387 : : else
388 : : {
389 : : // #i112959# if not transparent, draw full rectangle in clip region
390 [ # # ]: 0 : DrawRect( aPolyRect );
391 : : }
392 : :
393 [ # # ]: 0 : EnableMapMode( bOldMap );
394 [ # # ]: 0 : Pop();
395 : : }
396 : : else
397 : : {
398 [ + - ]: 4184 : PolyPolygon aPolyPoly( LogicToPixel( rPolyPoly ) );
399 [ + - ]: 4184 : Rectangle aPolyRect( aPolyPoly.GetBoundRect() );
400 : 4184 : Point aPoint;
401 [ + - ]: 4184 : Rectangle aDstRect( aPoint, GetOutputSizePixel() );
402 : :
403 [ + - ]: 4184 : aDstRect.Intersection( aPolyRect );
404 : :
405 [ + - ]: 4184 : if( OUTDEV_WINDOW == meOutDevType )
406 : : {
407 [ + - ]: 4184 : const Region aPaintRgn( ( (Window*) this )->GetPaintRegion() );
408 : :
409 [ + - ][ + + ]: 4184 : if( !aPaintRgn.IsNull() )
410 [ + - ][ + - ]: 4184 : aDstRect.Intersection( LogicToPixel( aPaintRgn ).GetBoundRect() );
[ + - ][ + - ]
[ + - ]
411 : : }
412 : :
413 [ + - ][ + - ]: 4184 : if( !aDstRect.IsEmpty() )
414 : : {
415 : : // #i66849# Added fast path for exactly rectangular
416 : : // polygons
417 : : // #i83087# Naturally, system alpha blending cannot
418 : : // work with separate alpha VDev
419 [ + - ][ + - ]: 4184 : if( !mpAlphaVDev && !pDisableNative && aPolyPoly.IsRect() )
[ + - ][ - + ]
[ - + ]
420 : : {
421 : : // setup Graphics only here (other cases delegate
422 : : // to basic OutDev methods)
423 [ # # ]: 0 : if ( mbInitClipRegion )
424 [ # # ]: 0 : ImplInitClipRegion();
425 [ # # ]: 0 : if ( mbInitLineColor )
426 [ # # ]: 0 : ImplInitLineColor();
427 [ # # ]: 0 : if ( mbInitFillColor )
428 [ # # ]: 0 : ImplInitFillColor();
429 : :
430 [ # # ]: 0 : Rectangle aLogicPolyRect( rPolyPoly.GetBoundRect() );
431 [ # # ]: 0 : Rectangle aPixelRect( ImplLogicToDevicePixel( aLogicPolyRect ) );
432 : :
433 [ # # ]: 0 : if( !mbOutputClipped )
434 : : {
435 : : bDrawn = mpGraphics->DrawAlphaRect(
436 : 0 : aPixelRect.Left(), aPixelRect.Top(),
437 : : // #i98405# use methods with small g, else one pixel too much will be painted.
438 : : // This is because the source is a polygon which when painted would not paint
439 : : // the rightmost and lowest pixel line(s), so use one pixel less for the
440 : : // rectangle, too.
441 : : aPixelRect.getWidth(), aPixelRect.getHeight(),
442 : 0 : sal::static_int_cast<sal_uInt8>(nTransparencePercent),
443 [ # # ]: 0 : this );
444 : : }
445 : : else
446 : 0 : bDrawn = true;
447 : : }
448 : :
449 [ + - ]: 4184 : if( !bDrawn )
450 : : {
451 [ + - ]: 4184 : VirtualDevice aVDev( *this, 1 );
452 [ + - ]: 4184 : const Size aDstSz( aDstRect.GetSize() );
453 : 4184 : const sal_uInt8 cTrans = (sal_uInt8) MinMax( FRound( nTransparencePercent * 2.55 ), 0, 255 );
454 : :
455 [ - + ][ + + ]: 4184 : if( aDstRect.Left() || aDstRect.Top() )
[ + + ]
456 [ + - ]: 4001 : aPolyPoly.Move( -aDstRect.Left(), -aDstRect.Top() );
457 : :
458 [ + - ][ + - ]: 4184 : if( aVDev.SetOutputSizePixel( aDstSz ) )
459 : : {
460 : 4184 : const sal_Bool bOldMap = mbMap;
461 : :
462 [ + - ]: 4184 : EnableMapMode( sal_False );
463 : :
464 [ + - ]: 4184 : aVDev.SetLineColor( COL_BLACK );
465 [ + - ]: 4184 : aVDev.SetFillColor( COL_BLACK );
466 [ + - ]: 4184 : aVDev.DrawPolyPolygon( aPolyPoly );
467 : :
468 [ + - ]: 4184 : Bitmap aPaint( GetBitmap( aDstRect.TopLeft(), aDstSz ) );
469 [ + - ]: 4184 : Bitmap aPolyMask( aVDev.GetBitmap( Point(), aDstSz ) );
470 : :
471 : : // #107766# check for non-empty bitmaps before accessing them
472 [ + - ][ + - ]: 4184 : if( !!aPaint && !!aPolyMask )
[ + - ]
473 : : {
474 [ + - ]: 4184 : BitmapWriteAccess* pW = aPaint.AcquireWriteAccess();
475 [ + - ]: 4184 : BitmapReadAccess* pR = aPolyMask.AcquireReadAccess();
476 : :
477 [ + - ][ + - ]: 4184 : if( pW && pR )
478 : : {
479 : 4184 : BitmapColor aPixCol;
480 : 4184 : const BitmapColor aFillCol( GetFillColor() );
481 [ + - ]: 4184 : const BitmapColor aWhite( pR->GetBestMatchingColor( Color( COL_WHITE ) ) );
482 [ + - ]: 4184 : const BitmapColor aBlack( pR->GetBestMatchingColor( Color( COL_BLACK ) ) );
483 : 4184 : const long nWidth = pW->Width(), nHeight = pW->Height();
484 : 4184 : const long nR = aFillCol.GetRed(), nG = aFillCol.GetGreen(), nB = aFillCol.GetBlue();
485 : : long nX, nY;
486 : :
487 [ - + ][ + - ]: 4184 : if( aPaint.GetBitCount() <= 8 )
488 : : {
489 : 0 : const BitmapPalette& rPal = pW->GetPalette();
490 : 0 : const sal_uInt16 nCount = rPal.GetEntryCount();
491 [ # # ]: 0 : BitmapColor* pMap = (BitmapColor*) new sal_uInt8[ nCount * sizeof( BitmapColor ) ];
492 : :
493 [ # # ]: 0 : for( sal_uInt16 i = 0; i < nCount; i++ )
494 : : {
495 : 0 : BitmapColor aCol( rPal[ i ] );
496 : 0 : pMap[ i ] = BitmapColor( (sal_uInt8) rPal.GetBestIndex( aCol.Merge( aFillCol, cTrans ) ) );
497 : 0 : }
498 : :
499 [ # # # # ]: 0 : if( pR->GetScanlineFormat() == BMP_FORMAT_1BIT_MSB_PAL &&
[ # # ]
500 : 0 : pW->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL )
501 : : {
502 : 0 : const sal_uInt8 cBlack = aBlack.GetIndex();
503 : :
504 [ # # ]: 0 : for( nY = 0; nY < nHeight; nY++ )
505 : : {
506 : 0 : Scanline pWScan = pW->GetScanline( nY );
507 : 0 : Scanline pRScan = pR->GetScanline( nY );
508 : 0 : sal_uInt8 cBit = 128;
509 : :
510 [ # # ]: 0 : for( nX = 0; nX < nWidth; nX++, cBit >>= 1, pWScan++ )
511 : : {
512 [ # # ]: 0 : if( !cBit )
513 : 0 : cBit = 128, pRScan++;
514 : :
515 [ # # ]: 0 : if( ( *pRScan & cBit ) == cBlack )
516 : 0 : *pWScan = (sal_uInt8) pMap[ *pWScan ].GetIndex();
517 : : }
518 : : }
519 : : }
520 : : else
521 : : {
522 [ # # ]: 0 : for( nY = 0; nY < nHeight; nY++ )
523 [ # # ]: 0 : for( nX = 0; nX < nWidth; nX++ )
524 [ # # ][ # # ]: 0 : if( pR->GetPixel( nY, nX ) == aBlack )
525 [ # # ][ # # ]: 0 : pW->SetPixel( nY, nX, pMap[ pW->GetPixel( nY, nX ).GetIndex() ] );
526 : : }
527 : :
528 [ # # ]: 0 : delete[] (sal_uInt8*) pMap;
529 : : }
530 : : else
531 : : {
532 [ + - + - ]: 8368 : if( pR->GetScanlineFormat() == BMP_FORMAT_1BIT_MSB_PAL &&
[ + - ]
533 : 4184 : pW->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_BGR )
534 : : {
535 : 4184 : const sal_uInt8 cBlack = aBlack.GetIndex();
536 : :
537 [ + + ]: 100504 : for( nY = 0; nY < nHeight; nY++ )
538 : : {
539 : 96320 : Scanline pWScan = pW->GetScanline( nY );
540 : 96320 : Scanline pRScan = pR->GetScanline( nY );
541 : 96320 : sal_uInt8 cBit = 128;
542 : :
543 [ + + ]: 2315520 : for( nX = 0; nX < nWidth; nX++, cBit >>= 1, pWScan += 3 )
544 : : {
545 [ + + ]: 2219200 : if( !cBit )
546 : 193322 : cBit = 128, pRScan++;
547 : :
548 [ + + ]: 2219200 : if( ( *pRScan & cBit ) == cBlack )
549 : : {
550 : 2202464 : pWScan[ 0 ] = COLOR_CHANNEL_MERGE( pWScan[ 0 ], nB, cTrans );
551 : 2202464 : pWScan[ 1 ] = COLOR_CHANNEL_MERGE( pWScan[ 1 ], nG, cTrans );
552 : 2202464 : pWScan[ 2 ] = COLOR_CHANNEL_MERGE( pWScan[ 2 ], nR, cTrans );
553 : : }
554 : : }
555 : : }
556 : : }
557 : : else
558 : : {
559 [ # # ]: 0 : for( nY = 0; nY < nHeight; nY++ )
560 : : {
561 [ # # ]: 0 : for( nX = 0; nX < nWidth; nX++ )
562 : : {
563 [ # # ][ # # ]: 0 : if( pR->GetPixel( nY, nX ) == aBlack )
564 : : {
565 [ # # ]: 0 : aPixCol = pW->GetColor( nY, nX );
566 [ # # ]: 0 : pW->SetPixel( nY, nX, aPixCol.Merge( aFillCol, cTrans ) );
567 : : }
568 : : }
569 : : }
570 : : }
571 : 4184 : }
572 : : }
573 : :
574 [ + - ]: 4184 : aPolyMask.ReleaseAccess( pR );
575 [ + - ]: 4184 : aPaint.ReleaseAccess( pW );
576 : :
577 [ + - ]: 4184 : DrawBitmap( aDstRect.TopLeft(), aPaint );
578 : :
579 [ + - ]: 4184 : EnableMapMode( bOldMap );
580 : :
581 [ + - ]: 4184 : if( mbLineColor )
582 : : {
583 [ + - ]: 4184 : Push( PUSH_FILLCOLOR );
584 [ + - ]: 4184 : SetFillColor();
585 [ + - ]: 4184 : DrawPolyPolygon( rPolyPoly );
586 [ + - ]: 4184 : Pop();
587 : : }
588 [ + - ][ + - ]: 4184 : }
589 : : }
590 : : else
591 [ # # ][ + - ]: 4184 : DrawPolyPolygon( rPolyPoly );
592 : : }
593 [ + - ]: 4184 : }
594 : : }
595 : :
596 : 4184 : mpMetaFile = pOldMetaFile;
597 : :
598 : : // #110958# Restore disabled alpha VDev
599 : 4184 : mpAlphaVDev = pOldAlphaVDev;
600 : :
601 : : // #110958# Apply alpha value also to VDev alpha channel
602 [ - + ]: 4184 : if( mpAlphaVDev )
603 : : {
604 : 0 : const Color aFillCol( mpAlphaVDev->GetFillColor() );
605 : 0 : mpAlphaVDev->SetFillColor( Color(sal::static_int_cast<sal_uInt8>(255*nTransparencePercent/100),
606 : 0 : sal::static_int_cast<sal_uInt8>(255*nTransparencePercent/100),
607 [ # # ]: 0 : sal::static_int_cast<sal_uInt8>(255*nTransparencePercent/100)) );
608 : :
609 [ # # ]: 0 : mpAlphaVDev->DrawTransparent( rPolyPoly, nTransparencePercent );
610 : :
611 [ # # ]: 4186 : mpAlphaVDev->SetFillColor( aFillCol );
612 : : }
613 : : }
614 : :
615 : : // -----------------------------------------------------------------------
616 : :
617 : 0 : void OutputDevice::DrawTransparent( const GDIMetaFile& rMtf, const Point& rPos,
618 : : const Size& rSize, const Gradient& rTransparenceGradient )
619 : : {
620 : : OSL_TRACE( "OutputDevice::DrawTransparent()" );
621 : : DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
622 : :
623 : 0 : const Color aBlack( COL_BLACK );
624 : :
625 [ # # ]: 0 : if( mpMetaFile )
626 [ # # ][ # # ]: 0 : mpMetaFile->AddAction( new MetaFloatTransparentAction( rMtf, rPos, rSize, rTransparenceGradient ) );
[ # # ]
627 : :
628 [ # # ][ # # ]: 0 : if( ( rTransparenceGradient.GetStartColor() == aBlack && rTransparenceGradient.GetEndColor() == aBlack ) ||
[ # # ][ # # ]
629 : : ( mnDrawMode & ( DRAWMODE_NOTRANSPARENCY ) ) )
630 : : {
631 [ # # ]: 0 : ( (GDIMetaFile&) rMtf ).WindStart();
632 [ # # ]: 0 : ( (GDIMetaFile&) rMtf ).Play( this, rPos, rSize );
633 [ # # ]: 0 : ( (GDIMetaFile&) rMtf ).WindStart();
634 : : }
635 : : else
636 : : {
637 : 0 : GDIMetaFile* pOldMetaFile = mpMetaFile;
638 [ # # ][ # # ]: 0 : Rectangle aOutRect( LogicToPixel( rPos ), LogicToPixel( rSize ) );
[ # # ]
639 : 0 : Point aPoint;
640 [ # # ]: 0 : Rectangle aDstRect( aPoint, GetOutputSizePixel() );
641 : :
642 : 0 : mpMetaFile = NULL;
643 [ # # ]: 0 : aDstRect.Intersection( aOutRect );
644 : :
645 [ # # ]: 0 : if( OUTDEV_WINDOW == meOutDevType )
646 : : {
647 [ # # ]: 0 : const Region aPaintRgn( ( (Window*) this )->GetPaintRegion() );
648 : :
649 [ # # ][ # # ]: 0 : if( !aPaintRgn.IsNull() )
650 [ # # ][ # # ]: 0 : aDstRect.Intersection( LogicToPixel( aPaintRgn.GetBoundRect() ) );
[ # # ][ # # ]
651 : : }
652 : :
653 [ # # ][ # # ]: 0 : if( !aDstRect.IsEmpty() )
654 : : {
655 [ # # ][ # # ]: 0 : VirtualDevice* pVDev = new VirtualDevice;
656 : :
657 : 0 : ((OutputDevice*)pVDev)->mnDPIX = mnDPIX;
658 : 0 : ((OutputDevice*)pVDev)->mnDPIY = mnDPIY;
659 : :
660 [ # # ][ # # ]: 0 : if( pVDev->SetOutputSizePixel( aDstRect.GetSize() ) )
[ # # ]
661 : : {
662 [ # # ]: 0 : if(GetAntialiasing())
663 : : {
664 : : // #i102109#
665 : : // For MetaFile replay (see task) it may now be neccessary to take
666 : : // into account that the content is AntiAlialised and needs to be masked
667 : : // like that. Instead of masking, i will use a copy-modify-paste cycle
668 : : // here (as i already use in the VclPrimiziveRenderer with successs)
669 [ # # ]: 0 : pVDev->SetAntialiasing(GetAntialiasing());
670 : :
671 : : // create MapMode for buffer (offset needed) and set
672 [ # # ]: 0 : MapMode aMap(GetMapMode());
673 [ # # ]: 0 : const Point aOutPos(PixelToLogic(aDstRect.TopLeft()));
674 [ # # ]: 0 : aMap.SetOrigin(Point(-aOutPos.X(), -aOutPos.Y()));
675 [ # # ]: 0 : pVDev->SetMapMode(aMap);
676 : :
677 : : // copy MapMode state and disable for target
678 : 0 : const bool bOrigMapModeEnabled(IsMapModeEnabled());
679 [ # # ]: 0 : EnableMapMode(false);
680 : :
681 : : // copy MapMode state and disable for buffer
682 : 0 : const bool bBufferMapModeEnabled(pVDev->IsMapModeEnabled());
683 [ # # ]: 0 : pVDev->EnableMapMode(false);
684 : :
685 : : // copy content from original to buffer
686 : : pVDev->DrawOutDev(
687 : 0 : aPoint, pVDev->GetOutputSizePixel(), // dest
688 : 0 : aDstRect.TopLeft(), pVDev->GetOutputSizePixel(), // source
689 [ # # ]: 0 : *this);
690 : :
691 : : // draw MetaFile to buffer
692 [ # # ]: 0 : pVDev->EnableMapMode(bBufferMapModeEnabled);
693 [ # # ]: 0 : ((GDIMetaFile&)rMtf).WindStart();
694 [ # # ]: 0 : ((GDIMetaFile&)rMtf).Play(pVDev, rPos, rSize);
695 [ # # ]: 0 : ((GDIMetaFile&)rMtf).WindStart();
696 : :
697 : : // get content bitmap from buffer
698 [ # # ]: 0 : pVDev->EnableMapMode(false);
699 [ # # ]: 0 : const Bitmap aPaint(pVDev->GetBitmap(aPoint, pVDev->GetOutputSizePixel()));
700 : :
701 : : // create alpha mask from gradient and get as Bitmap
702 [ # # ]: 0 : pVDev->EnableMapMode(bBufferMapModeEnabled);
703 [ # # ]: 0 : pVDev->SetDrawMode(DRAWMODE_GRAYGRADIENT);
704 [ # # ][ # # ]: 0 : pVDev->DrawGradient(Rectangle(rPos, rSize), rTransparenceGradient);
705 [ # # ]: 0 : pVDev->SetDrawMode(DRAWMODE_DEFAULT);
706 [ # # ]: 0 : pVDev->EnableMapMode(false);
707 [ # # ][ # # ]: 0 : const AlphaMask aAlpha(pVDev->GetBitmap(aPoint, pVDev->GetOutputSizePixel()));
[ # # ]
708 : :
709 [ # # ][ # # ]: 0 : delete pVDev;
710 : :
711 : : // draw masked content to target and restore MapMode
712 [ # # ][ # # ]: 0 : DrawBitmapEx(aDstRect.TopLeft(), BitmapEx(aPaint, aAlpha));
[ # # ]
713 [ # # ][ # # ]: 0 : EnableMapMode(bOrigMapModeEnabled);
[ # # ][ # # ]
714 : : }
715 : : else
716 : : {
717 [ # # ][ # # ]: 0 : Bitmap aPaint, aMask;
718 [ # # ]: 0 : AlphaMask aAlpha;
719 [ # # ]: 0 : MapMode aMap( GetMapMode() );
720 [ # # ]: 0 : Point aOutPos( PixelToLogic( aDstRect.TopLeft() ) );
721 : 0 : const sal_Bool bOldMap = mbMap;
722 : :
723 [ # # ]: 0 : aMap.SetOrigin( Point( -aOutPos.X(), -aOutPos.Y() ) );
724 [ # # ]: 0 : pVDev->SetMapMode( aMap );
725 : 0 : const sal_Bool bVDevOldMap = pVDev->IsMapModeEnabled();
726 : :
727 : : // create paint bitmap
728 [ # # ]: 0 : ( (GDIMetaFile&) rMtf ).WindStart();
729 [ # # ]: 0 : ( (GDIMetaFile&) rMtf ).Play( pVDev, rPos, rSize );
730 [ # # ]: 0 : ( (GDIMetaFile&) rMtf ).WindStart();
731 [ # # ]: 0 : pVDev->EnableMapMode( sal_False );
732 [ # # ][ # # ]: 0 : aPaint = pVDev->GetBitmap( Point(), pVDev->GetOutputSizePixel() );
[ # # ]
733 [ # # ]: 0 : pVDev->EnableMapMode( bVDevOldMap ); // #i35331#: MUST NOT use EnableMapMode( sal_True ) here!
734 : :
735 : : // create mask bitmap
736 [ # # ]: 0 : pVDev->SetLineColor( COL_BLACK );
737 [ # # ]: 0 : pVDev->SetFillColor( COL_BLACK );
738 [ # # ][ # # ]: 0 : pVDev->DrawRect( Rectangle( pVDev->PixelToLogic( Point() ), pVDev->GetOutputSize() ) );
[ # # ][ # # ]
739 : : pVDev->SetDrawMode( DRAWMODE_WHITELINE | DRAWMODE_WHITEFILL | DRAWMODE_WHITETEXT |
740 [ # # ]: 0 : DRAWMODE_WHITEBITMAP | DRAWMODE_WHITEGRADIENT );
741 [ # # ]: 0 : ( (GDIMetaFile&) rMtf ).WindStart();
742 [ # # ]: 0 : ( (GDIMetaFile&) rMtf ).Play( pVDev, rPos, rSize );
743 [ # # ]: 0 : ( (GDIMetaFile&) rMtf ).WindStart();
744 [ # # ]: 0 : pVDev->EnableMapMode( sal_False );
745 [ # # ][ # # ]: 0 : aMask = pVDev->GetBitmap( Point(), pVDev->GetOutputSizePixel() );
[ # # ]
746 [ # # ]: 0 : pVDev->EnableMapMode( bVDevOldMap ); // #i35331#: MUST NOT use EnableMapMode( sal_True ) here!
747 : :
748 : : // create alpha mask from gradient
749 [ # # ]: 0 : pVDev->SetDrawMode( DRAWMODE_GRAYGRADIENT );
750 [ # # ][ # # ]: 0 : pVDev->DrawGradient( Rectangle( rPos, rSize ), rTransparenceGradient );
751 [ # # ]: 0 : pVDev->SetDrawMode( DRAWMODE_DEFAULT );
752 [ # # ]: 0 : pVDev->EnableMapMode( sal_False );
753 [ # # ]: 0 : pVDev->DrawMask( Point(), pVDev->GetOutputSizePixel(), aMask, Color( COL_WHITE ) );
754 : :
755 [ # # ][ # # ]: 0 : aAlpha = pVDev->GetBitmap( Point(), pVDev->GetOutputSizePixel() );
[ # # ]
756 : :
757 [ # # ][ # # ]: 0 : delete pVDev;
758 : :
759 [ # # ]: 0 : EnableMapMode( sal_False );
760 [ # # ][ # # ]: 0 : DrawBitmapEx( aDstRect.TopLeft(), BitmapEx( aPaint, aAlpha ) );
[ # # ]
761 [ # # ][ # # ]: 0 : EnableMapMode( bOldMap );
[ # # ][ # # ]
[ # # ]
762 : : }
763 : : }
764 : : else
765 [ # # ][ # # ]: 0 : delete pVDev;
766 : : }
767 : :
768 : 0 : mpMetaFile = pOldMetaFile;
769 : : }
770 : 0 : }
771 : :
772 : : // -----------------------------------------------------------------------
773 : :
774 : 209310 : void OutputDevice::ImplDrawColorWallpaper( long nX, long nY,
775 : : long nWidth, long nHeight,
776 : : const Wallpaper& rWallpaper )
777 : : {
778 : : // Wallpaper ohne Umrandung zeichnen
779 : 209310 : Color aOldLineColor = GetLineColor();
780 : 209310 : Color aOldFillColor = GetFillColor();
781 [ + - ]: 209310 : SetLineColor();
782 [ + - ][ + - ]: 209310 : SetFillColor( rWallpaper.GetColor() );
783 : 209310 : sal_Bool bMap = mbMap;
784 [ + - ]: 209310 : EnableMapMode( sal_False );
785 [ + - ][ + - ]: 209310 : DrawRect( Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) ) );
786 [ + - ]: 209310 : SetLineColor( aOldLineColor );
787 [ + - ]: 209310 : SetFillColor( aOldFillColor );
788 [ + - ]: 209310 : EnableMapMode( bMap );
789 : 209310 : }
790 : :
791 : : // -----------------------------------------------------------------------
792 : :
793 : 0 : void OutputDevice::ImplDrawBitmapWallpaper( long nX, long nY,
794 : : long nWidth, long nHeight,
795 : : const Wallpaper& rWallpaper )
796 : : {
797 [ # # ]: 0 : BitmapEx aBmpEx;
798 : 0 : const BitmapEx* pCached = rWallpaper.ImplGetImpWallpaper()->ImplGetCachedBitmap();
799 : 0 : Point aPos;
800 : 0 : Size aSize;
801 : 0 : GDIMetaFile* pOldMetaFile = mpMetaFile;
802 [ # # ]: 0 : const WallpaperStyle eStyle = rWallpaper.GetStyle();
803 : 0 : const sal_Bool bOldMap = mbMap;
804 : 0 : sal_Bool bDrawn = sal_False;
805 : 0 : sal_Bool bDrawGradientBackground = sal_False;
806 : 0 : sal_Bool bDrawColorBackground = sal_False;
807 : :
808 [ # # ]: 0 : if( pCached )
809 [ # # ]: 0 : aBmpEx = *pCached;
810 : : else
811 [ # # ][ # # ]: 0 : aBmpEx = rWallpaper.GetBitmap();
[ # # ]
812 : :
813 : 0 : const long nBmpWidth = aBmpEx.GetSizePixel().Width();
814 : 0 : const long nBmpHeight = aBmpEx.GetSizePixel().Height();
815 [ # # ]: 0 : const sal_Bool bTransparent = aBmpEx.IsTransparent();
816 : :
817 : : // draw background
818 [ # # ]: 0 : if( bTransparent )
819 : : {
820 [ # # ][ # # ]: 0 : if( rWallpaper.IsGradient() )
821 : 0 : bDrawGradientBackground = sal_True;
822 : : else
823 : : {
824 [ # # ][ # # ]: 0 : if( !pCached && !rWallpaper.GetColor().GetTransparency() )
[ # # ][ # # ]
825 : : {
826 [ # # ]: 0 : VirtualDevice aVDev( *this );
827 [ # # ][ # # ]: 0 : aVDev.SetBackground( rWallpaper.GetColor() );
[ # # ][ # # ]
828 [ # # ]: 0 : aVDev.SetOutputSizePixel( Size( nBmpWidth, nBmpHeight ) );
829 [ # # ]: 0 : aVDev.DrawBitmapEx( Point(), aBmpEx );
830 [ # # ][ # # ]: 0 : aBmpEx = aVDev.GetBitmap( Point(), aVDev.GetOutputSizePixel() );
[ # # ][ # # ]
[ # # ][ # # ]
831 : : }
832 : :
833 : 0 : bDrawColorBackground = sal_True;
834 : : }
835 : : }
836 [ # # ][ # # ]: 0 : else if( eStyle != WALLPAPER_TILE && eStyle != WALLPAPER_SCALE )
837 : : {
838 [ # # ][ # # ]: 0 : if( rWallpaper.IsGradient() )
839 : 0 : bDrawGradientBackground = sal_True;
840 : : else
841 : 0 : bDrawColorBackground = sal_True;
842 : : }
843 : :
844 : : // background of bitmap?
845 [ # # ]: 0 : if( bDrawGradientBackground )
846 [ # # ]: 0 : ImplDrawGradientWallpaper( nX, nY, nWidth, nHeight, rWallpaper );
847 [ # # ][ # # ]: 0 : else if( bDrawColorBackground && bTransparent )
848 : : {
849 [ # # ]: 0 : ImplDrawColorWallpaper( nX, nY, nWidth, nHeight, rWallpaper );
850 : 0 : bDrawColorBackground = sal_False;
851 : : }
852 : :
853 : : // calc pos and size
854 [ # # ][ # # ]: 0 : if( rWallpaper.IsRect() )
855 : : {
856 [ # # ][ # # ]: 0 : const Rectangle aBound( LogicToPixel( rWallpaper.GetRect() ) );
857 : 0 : aPos = aBound.TopLeft();
858 [ # # ]: 0 : aSize = aBound.GetSize();
859 : : }
860 : : else
861 : : {
862 : 0 : aPos = Point( nX, nY );
863 : 0 : aSize = Size( nWidth, nHeight );
864 : : }
865 : :
866 : 0 : mpMetaFile = NULL;
867 [ # # ]: 0 : EnableMapMode( sal_False );
868 [ # # ]: 0 : Push( PUSH_CLIPREGION );
869 [ # # ][ # # ]: 0 : IntersectClipRegion( Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) ) );
870 : :
871 [ # # # # : 0 : switch( eStyle )
# # # # #
# # ]
872 : : {
873 : : case( WALLPAPER_SCALE ):
874 : : {
875 [ # # ][ # # ]: 0 : if( !pCached || ( pCached->GetSizePixel() != aSize ) )
[ # # ]
876 : : {
877 [ # # ]: 0 : if( pCached )
878 [ # # ]: 0 : rWallpaper.ImplGetImpWallpaper()->ImplReleaseCachedBitmap();
879 : :
880 [ # # ][ # # ]: 0 : aBmpEx = rWallpaper.GetBitmap();
[ # # ]
881 [ # # ]: 0 : aBmpEx.Scale( aSize );
882 [ # # ][ # # ]: 0 : aBmpEx = BitmapEx( aBmpEx.GetBitmap().CreateDisplayBitmap( this ), aBmpEx.GetMask() );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
883 : : }
884 : : }
885 : 0 : break;
886 : :
887 : : case( WALLPAPER_TOPLEFT ):
888 : 0 : break;
889 : :
890 : : case( WALLPAPER_TOP ):
891 : 0 : aPos.X() += ( aSize.Width() - nBmpWidth ) >> 1;
892 : 0 : break;
893 : :
894 : : case( WALLPAPER_TOPRIGHT ):
895 : 0 : aPos.X() += ( aSize.Width() - nBmpWidth );
896 : 0 : break;
897 : :
898 : : case( WALLPAPER_LEFT ):
899 : 0 : aPos.Y() += ( aSize.Height() - nBmpHeight ) >> 1;
900 : 0 : break;
901 : :
902 : : case( WALLPAPER_CENTER ):
903 : : {
904 : 0 : aPos.X() += ( aSize.Width() - nBmpWidth ) >> 1;
905 : 0 : aPos.Y() += ( aSize.Height() - nBmpHeight ) >> 1;
906 : : }
907 : 0 : break;
908 : :
909 : : case( WALLPAPER_RIGHT ):
910 : : {
911 : 0 : aPos.X() += ( aSize.Width() - nBmpWidth );
912 : 0 : aPos.Y() += ( aSize.Height() - nBmpHeight ) >> 1;
913 : : }
914 : 0 : break;
915 : :
916 : : case( WALLPAPER_BOTTOMLEFT ):
917 : 0 : aPos.Y() += ( aSize.Height() - nBmpHeight );
918 : 0 : break;
919 : :
920 : : case( WALLPAPER_BOTTOM ):
921 : : {
922 : 0 : aPos.X() += ( aSize.Width() - nBmpWidth ) >> 1;
923 : 0 : aPos.Y() += ( aSize.Height() - nBmpHeight );
924 : : }
925 : 0 : break;
926 : :
927 : : case( WALLPAPER_BOTTOMRIGHT ):
928 : : {
929 : 0 : aPos.X() += ( aSize.Width() - nBmpWidth );
930 : 0 : aPos.Y() += ( aSize.Height() - nBmpHeight );
931 : : }
932 : 0 : break;
933 : :
934 : : default:
935 : : {
936 : 0 : const long nRight = nX + nWidth - 1L;
937 : 0 : const long nBottom = nY + nHeight - 1L;
938 : : long nFirstX;
939 : : long nFirstY;
940 : :
941 [ # # ]: 0 : if( eStyle == WALLPAPER_TILE )
942 : : {
943 : 0 : nFirstX = aPos.X();
944 : 0 : nFirstY = aPos.Y();
945 : : }
946 : : else
947 : : {
948 : 0 : nFirstX = aPos.X() + ( ( aSize.Width() - nBmpWidth ) >> 1 );
949 : 0 : nFirstY = aPos.Y() + ( ( aSize.Height() - nBmpHeight ) >> 1 );
950 : : }
951 : :
952 : 0 : const long nOffX = ( nFirstX - nX ) % nBmpWidth;
953 : 0 : const long nOffY = ( nFirstY - nY ) % nBmpHeight;
954 : 0 : long nStartX = nX + nOffX;
955 : 0 : long nStartY = nY + nOffY;
956 : :
957 [ # # ]: 0 : if( nOffX > 0L )
958 : 0 : nStartX -= nBmpWidth;
959 : :
960 [ # # ]: 0 : if( nOffY > 0L )
961 : 0 : nStartY -= nBmpHeight;
962 : :
963 [ # # ]: 0 : for( long nBmpY = nStartY; nBmpY <= nBottom; nBmpY += nBmpHeight )
964 [ # # ]: 0 : for( long nBmpX = nStartX; nBmpX <= nRight; nBmpX += nBmpWidth )
965 [ # # ]: 0 : DrawBitmapEx( Point( nBmpX, nBmpY ), aBmpEx );
966 : :
967 : 0 : bDrawn = sal_True;
968 : : }
969 : 0 : break;
970 : : }
971 : :
972 [ # # ]: 0 : if( !bDrawn )
973 : : {
974 : : // optimized for non-transparent bitmaps
975 [ # # ]: 0 : if( bDrawColorBackground )
976 : : {
977 : 0 : const Size aBmpSize( aBmpEx.GetSizePixel() );
978 : 0 : const Point aTmpPoint;
979 [ # # ]: 0 : const Rectangle aOutRect( aTmpPoint, GetOutputSizePixel() );
980 [ # # ]: 0 : const Rectangle aColRect( Point( nX, nY ), Size( nWidth, nHeight ) );
981 [ # # ]: 0 : Rectangle aWorkRect;
982 : :
983 [ # # ]: 0 : aWorkRect = Rectangle( 0, 0, aOutRect.Right(), aPos.Y() - 1L );
984 [ # # ]: 0 : aWorkRect.Justify();
985 [ # # ]: 0 : aWorkRect.Intersection( aColRect );
986 [ # # ][ # # ]: 0 : if( !aWorkRect.IsEmpty() )
987 : : {
988 : 0 : ImplDrawColorWallpaper( aWorkRect.Left(), aWorkRect.Top(),
989 : : aWorkRect.GetWidth(), aWorkRect.GetHeight(),
990 [ # # ]: 0 : rWallpaper );
[ # # # # ]
991 : : }
992 : :
993 [ # # ]: 0 : aWorkRect = Rectangle( 0, aPos.Y(), aPos.X() - 1L, aPos.Y() + aBmpSize.Height() - 1L );
994 [ # # ]: 0 : aWorkRect.Justify();
995 [ # # ]: 0 : aWorkRect.Intersection( aColRect );
996 [ # # ][ # # ]: 0 : if( !aWorkRect.IsEmpty() )
997 : : {
998 : 0 : ImplDrawColorWallpaper( aWorkRect.Left(), aWorkRect.Top(),
999 : : aWorkRect.GetWidth(), aWorkRect.GetHeight(),
1000 [ # # ]: 0 : rWallpaper );
[ # # # # ]
1001 : : }
1002 : :
1003 [ # # ]: 0 : aWorkRect = Rectangle( aPos.X() + aBmpSize.Width(), aPos.Y(), aOutRect.Right(), aPos.Y() + aBmpSize.Height() - 1L );
1004 [ # # ]: 0 : aWorkRect.Justify();
1005 [ # # ]: 0 : aWorkRect.Intersection( aColRect );
1006 [ # # ][ # # ]: 0 : if( !aWorkRect.IsEmpty() )
1007 : : {
1008 : 0 : ImplDrawColorWallpaper( aWorkRect.Left(), aWorkRect.Top(),
1009 : : aWorkRect.GetWidth(), aWorkRect.GetHeight(),
1010 [ # # ]: 0 : rWallpaper );
[ # # # # ]
1011 : : }
1012 : :
1013 [ # # ]: 0 : aWorkRect = Rectangle( 0, aPos.Y() + aBmpSize.Height(), aOutRect.Right(), aOutRect.Bottom() );
1014 [ # # ]: 0 : aWorkRect.Justify();
1015 [ # # ]: 0 : aWorkRect.Intersection( aColRect );
1016 [ # # ][ # # ]: 0 : if( !aWorkRect.IsEmpty() )
1017 : : {
1018 : 0 : ImplDrawColorWallpaper( aWorkRect.Left(), aWorkRect.Top(),
1019 : : aWorkRect.GetWidth(), aWorkRect.GetHeight(),
1020 [ # # ]: 0 : rWallpaper );
[ # # # # ]
1021 : : }
1022 : : }
1023 : :
1024 [ # # ]: 0 : DrawBitmapEx( aPos, aBmpEx );
1025 : : }
1026 : :
1027 [ # # ]: 0 : rWallpaper.ImplGetImpWallpaper()->ImplSetCachedBitmap( aBmpEx );
1028 : :
1029 [ # # ]: 0 : Pop();
1030 [ # # ]: 0 : EnableMapMode( bOldMap );
1031 [ # # ]: 0 : mpMetaFile = pOldMetaFile;
1032 : 0 : }
1033 : :
1034 : : // -----------------------------------------------------------------------
1035 : :
1036 : 4458 : void OutputDevice::ImplDrawGradientWallpaper( long nX, long nY,
1037 : : long nWidth, long nHeight,
1038 : : const Wallpaper& rWallpaper )
1039 : : {
1040 [ + - ]: 4458 : Rectangle aBound;
1041 : 4458 : GDIMetaFile* pOldMetaFile = mpMetaFile;
1042 : 4458 : const sal_Bool bOldMap = mbMap;
1043 : 4458 : sal_Bool bNeedGradient = sal_True;
1044 : :
1045 [ + - ]: 4458 : aBound = Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) );
1046 : :
1047 : 4458 : mpMetaFile = NULL;
1048 [ + - ]: 4458 : EnableMapMode( sal_False );
1049 [ + - ]: 4458 : Push( PUSH_CLIPREGION );
1050 [ + - ][ + - ]: 4458 : IntersectClipRegion( Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) ) );
1051 : :
1052 [ + - ][ + - ]: 4458 : if( OUTDEV_WINDOW == meOutDevType && rWallpaper.GetStyle() == WALLPAPER_APPLICATIONGRADIENT )
[ + - ][ + - ]
1053 : : {
1054 [ - + ]: 4458 : Window *pWin = dynamic_cast< Window* >( this );
1055 [ + - ]: 4458 : if( pWin )
1056 : : {
1057 : : // limit gradient to useful size, so that it still can be noticed
1058 : : // in maximized windows
1059 [ + - ][ + - ]: 4458 : long gradientWidth = pWin->GetDesktopRectPixel().GetSize().Width();
1060 [ - + ]: 4458 : if( gradientWidth > 1024 )
1061 : 0 : gradientWidth = 1024;
1062 [ - + ]: 4458 : if( mnOutOffX+nWidth > gradientWidth )
1063 [ # # ][ # # ]: 0 : ImplDrawColorWallpaper( nX, nY, nWidth, nHeight, rWallpaper.GetGradient().GetEndColor() );
[ # # ][ # # ]
[ # # ]
1064 [ - + ]: 4458 : if( mnOutOffX > gradientWidth )
1065 : 0 : bNeedGradient = sal_False;
1066 : : else
1067 [ + - ]: 4458 : aBound = Rectangle( Point( -mnOutOffX, nY ), Size( gradientWidth, nHeight ) );
1068 : : }
1069 : : }
1070 : :
1071 [ + - ]: 4458 : if( bNeedGradient )
1072 [ + - ][ + - ]: 4458 : DrawGradient( aBound, rWallpaper.GetGradient() );
[ + - ]
1073 : :
1074 [ + - ]: 4458 : Pop();
1075 [ + - ]: 4458 : EnableMapMode( bOldMap );
1076 : 4458 : mpMetaFile = pOldMetaFile;
1077 : 4458 : }
1078 : :
1079 : : // -----------------------------------------------------------------------
1080 : :
1081 : 213768 : void OutputDevice::ImplDrawWallpaper( long nX, long nY,
1082 : : long nWidth, long nHeight,
1083 : : const Wallpaper& rWallpaper )
1084 : : {
1085 [ - + ]: 213768 : if( rWallpaper.IsBitmap() )
1086 : 0 : ImplDrawBitmapWallpaper( nX, nY, nWidth, nHeight, rWallpaper );
1087 [ + + ]: 213768 : else if( rWallpaper.IsGradient() )
1088 : 4458 : ImplDrawGradientWallpaper( nX, nY, nWidth, nHeight, rWallpaper );
1089 : : else
1090 : 209310 : ImplDrawColorWallpaper( nX, nY, nWidth, nHeight, rWallpaper );
1091 : 213768 : }
1092 : :
1093 : : // -----------------------------------------------------------------------
1094 : :
1095 : 28646 : void OutputDevice::DrawWallpaper( const Rectangle& rRect,
1096 : : const Wallpaper& rWallpaper )
1097 : : {
1098 [ + + ]: 28646 : if ( mpMetaFile )
1099 [ + - ]: 3025 : mpMetaFile->AddAction( new MetaWallpaperAction( rRect, rWallpaper ) );
1100 : :
1101 [ + + ][ - + ]: 28646 : if ( !IsDeviceOutputNecessary() || ImplIsRecordLayout() )
[ + + ]
1102 : 28646 : return;
1103 : :
1104 [ + + ]: 28633 : if ( rWallpaper.GetStyle() != WALLPAPER_NULL )
1105 : : {
1106 [ + - ]: 25758 : Rectangle aRect = LogicToPixel( rRect );
1107 [ + - ]: 25758 : aRect.Justify();
1108 : :
1109 [ + - ][ + - ]: 25758 : if ( !aRect.IsEmpty() )
1110 : : {
1111 : 25758 : ImplDrawWallpaper( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(),
1112 [ + - ]: 51516 : rWallpaper );
[ + - + - ]
1113 : : }
1114 : : }
1115 : :
1116 [ + + ]: 28633 : if( mpAlphaVDev )
1117 : 3025 : mpAlphaVDev->DrawWallpaper( rRect, rWallpaper );
1118 : : }
1119 : :
1120 : : // -----------------------------------------------------------------------
1121 : :
1122 : 188010 : void OutputDevice::Erase()
1123 : : {
1124 [ + - ][ - + ]: 188010 : if ( !IsDeviceOutputNecessary() || ImplIsRecordLayout() )
[ - + ]
1125 : 188010 : return;
1126 : :
1127 : 188010 : sal_Bool bNativeOK = sal_False;
1128 : :
1129 [ + + ]: 188010 : if( meOutDevType == OUTDEV_WINDOW )
1130 : : {
1131 : 44736 : Window* pWindow = static_cast<Window*>(this);
1132 : 44736 : ControlPart aCtrlPart = pWindow->ImplGetWindowImpl()->mnNativeBackground;
1133 [ # # ][ - + ]: 44736 : if( aCtrlPart != 0 && ! pWindow->IsControlBackground() )
[ - + ]
1134 : : {
1135 : 0 : ImplControlValue aControlValue;
1136 : 0 : Point aGcc3WorkaroundTemporary;
1137 [ # # ]: 0 : Rectangle aCtrlRegion( aGcc3WorkaroundTemporary, GetOutputSizePixel() );
1138 : 0 : ControlState nState = 0;
1139 : :
1140 [ # # ][ # # ]: 0 : if( pWindow->IsEnabled() ) nState |= CTRL_STATE_ENABLED;
1141 : : bNativeOK = pWindow->DrawNativeControl( CTRL_WINDOW_BACKGROUND, aCtrlPart, aCtrlRegion,
1142 [ # # ][ # # ]: 0 : nState, aControlValue, rtl::OUString() );
1143 : : }
1144 : : }
1145 : :
1146 [ + - ][ + - ]: 188010 : if ( mbBackground && ! bNativeOK )
1147 : : {
1148 : 188010 : RasterOp eRasterOp = GetRasterOp();
1149 [ - + ]: 188010 : if ( eRasterOp != ROP_OVERPAINT )
1150 : 0 : SetRasterOp( ROP_OVERPAINT );
1151 : 188010 : ImplDrawWallpaper( 0, 0, mnOutWidth, mnOutHeight, maBackground );
1152 [ - + ]: 188010 : if ( eRasterOp != ROP_OVERPAINT )
1153 : 0 : SetRasterOp( eRasterOp );
1154 : : }
1155 : :
1156 [ - + ]: 188010 : if( mpAlphaVDev )
1157 : 0 : mpAlphaVDev->Erase();
1158 : : }
1159 : :
1160 : : // -----------------------------------------------------------------------
1161 : :
1162 : 0 : bool OutputDevice::DrawEPS( const Point& rPoint, const Size& rSize,
1163 : : const GfxLink& rGfxLink, GDIMetaFile* pSubst )
1164 : : {
1165 : : OSL_TRACE( "OutputDevice::DrawEPS()" );
1166 : :
1167 : 0 : bool bDrawn(true);
1168 : :
1169 [ # # ]: 0 : if ( mpMetaFile )
1170 : : {
1171 [ # # ]: 0 : GDIMetaFile aSubst;
1172 : :
1173 [ # # ]: 0 : if( pSubst )
1174 [ # # ]: 0 : aSubst = *pSubst;
1175 : :
1176 [ # # ][ # # ]: 0 : mpMetaFile->AddAction( new MetaEPSAction( rPoint, rSize, rGfxLink, aSubst ) );
[ # # ][ # # ]
1177 : : }
1178 : :
1179 [ # # ][ # # ]: 0 : if ( !IsDeviceOutputNecessary() || ImplIsRecordLayout() )
[ # # ][ # # ]
1180 : 0 : return bDrawn;
1181 : :
1182 [ # # ]: 0 : if( mbOutputClipped )
1183 : 0 : return bDrawn;
1184 : :
1185 [ # # ][ # # ]: 0 : Rectangle aRect( ImplLogicToDevicePixel( Rectangle( rPoint, rSize ) ) );
1186 : :
1187 [ # # ][ # # ]: 0 : if( !aRect.IsEmpty() )
1188 : : {
1189 : : // draw the real EPS graphics
1190 [ # # ][ # # ]: 0 : if( rGfxLink.GetData() && rGfxLink.GetDataSize() )
[ # # ][ # # ]
[ # # ]
1191 : : {
1192 [ # # ][ # # ]: 0 : if( !mpGraphics && !ImplGetGraphics() )
[ # # ][ # # ]
1193 : 0 : return bDrawn;
1194 : :
1195 [ # # ]: 0 : if( mbInitClipRegion )
1196 [ # # ]: 0 : ImplInitClipRegion();
1197 : :
1198 [ # # ]: 0 : aRect.Justify();
1199 : 0 : bDrawn = mpGraphics->DrawEPS( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(),
1200 [ # # ][ # # ]: 0 : (sal_uInt8*) rGfxLink.GetData(), rGfxLink.GetDataSize(), this );
[ # # ]
[ # # # # ]
1201 : : }
1202 : :
1203 : : // else draw the substitution graphics
1204 [ # # ][ # # ]: 0 : if( !bDrawn && pSubst )
1205 : : {
1206 : 0 : GDIMetaFile* pOldMetaFile = mpMetaFile;
1207 : :
1208 : 0 : mpMetaFile = NULL;
1209 [ # # ][ # # ]: 0 : Graphic( *pSubst ).Draw( this, rPoint, rSize );
[ # # ]
1210 : 0 : mpMetaFile = pOldMetaFile;
1211 : : }
1212 : : }
1213 : :
1214 [ # # ]: 0 : if( mpAlphaVDev )
1215 [ # # ]: 0 : mpAlphaVDev->DrawEPS( rPoint, rSize, rGfxLink, pSubst );
1216 : :
1217 : 0 : return bDrawn;
1218 : : }
1219 : :
1220 : : // ------------------------------------------------------------------
1221 : :
1222 : 0 : void OutputDevice::DrawRenderGraphic( const Point& rPoint, const Size& rSize,
1223 : : const ::vcl::RenderGraphic& rRenderGraphic )
1224 : : {
1225 : : OSL_TRACE( "OutputDevice::DrawRenderGraphic()" );
1226 : :
1227 [ # # ]: 0 : if( mpMetaFile )
1228 [ # # ]: 0 : mpMetaFile->AddAction( new MetaRenderGraphicAction( rPoint, rSize, rRenderGraphic ) );
1229 : :
1230 [ # # ]: 0 : if( !rRenderGraphic.IsEmpty() )
1231 : : {
1232 [ # # ]: 0 : ::vcl::RenderGraphicRasterizer aRasterizer( rRenderGraphic );
1233 [ # # ]: 0 : BitmapEx aBmpEx;
1234 [ # # ]: 0 : const Size aSizePixel( LogicToPixel( rSize ) );
1235 : 0 : GDIMetaFile* pOldMetaFile = mpMetaFile;
1236 : :
1237 : 0 : mpMetaFile = NULL;
1238 [ # # ][ # # ]: 0 : DrawBitmapEx( rPoint, rSize, aRasterizer.Rasterize( aSizePixel ) );
1239 [ # # ][ # # ]: 0 : mpMetaFile = pOldMetaFile;
1240 : : }
1241 : 0 : }
1242 : :
1243 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|