Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <vcl/outdev.hxx>
21 : #include <vcl/virdev.hxx>
22 :
23 : #include <wall2.hxx>
24 :
25 163987 : void OutputDevice::DrawWallpaper( const Rectangle& rRect,
26 : const Wallpaper& rWallpaper )
27 : {
28 163987 : if ( mpMetaFile )
29 1867 : mpMetaFile->AddAction( new MetaWallpaperAction( rRect, rWallpaper ) );
30 :
31 163987 : if ( !IsDeviceOutputNecessary() || ImplIsRecordLayout() )
32 164003 : return;
33 :
34 163971 : if ( rWallpaper.GetStyle() != WALLPAPER_NULL )
35 : {
36 90875 : Rectangle aRect = LogicToPixel( rRect );
37 90875 : aRect.Justify();
38 :
39 90875 : if ( !aRect.IsEmpty() )
40 : {
41 180902 : DrawWallpaper( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(),
42 271353 : rWallpaper );
43 : }
44 : }
45 :
46 163971 : if( mpAlphaVDev )
47 1867 : mpAlphaVDev->DrawWallpaper( rRect, rWallpaper );
48 : }
49 :
50 575977 : void OutputDevice::DrawWallpaper( long nX, long nY,
51 : long nWidth, long nHeight,
52 : const Wallpaper& rWallpaper )
53 : {
54 575977 : if( rWallpaper.IsBitmap() )
55 2 : DrawBitmapWallpaper( nX, nY, nWidth, nHeight, rWallpaper );
56 575975 : else if( rWallpaper.IsGradient() )
57 17391 : DrawGradientWallpaper( nX, nY, nWidth, nHeight, rWallpaper );
58 : else
59 558584 : DrawColorWallpaper( nX, nY, nWidth, nHeight, rWallpaper );
60 575977 : }
61 :
62 558586 : void OutputDevice::DrawColorWallpaper( long nX, long nY,
63 : long nWidth, long nHeight,
64 : const Wallpaper& rWallpaper )
65 : {
66 : // draw wallpaper without border
67 558586 : Color aOldLineColor = GetLineColor();
68 558586 : Color aOldFillColor = GetFillColor();
69 558586 : SetLineColor();
70 558586 : SetFillColor( rWallpaper.GetColor() );
71 :
72 558586 : bool bMap = mbMap;
73 558586 : EnableMapMode( false );
74 558586 : DrawRect( Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) ) );
75 558586 : SetLineColor( aOldLineColor );
76 558586 : SetFillColor( aOldFillColor );
77 558586 : EnableMapMode( bMap );
78 558586 : }
79 :
80 260200 : void OutputDevice::Erase()
81 : {
82 260200 : if ( !IsDeviceOutputNecessary() || ImplIsRecordLayout() )
83 260200 : return;
84 :
85 260200 : if ( mbBackground )
86 : {
87 260200 : RasterOp eRasterOp = GetRasterOp();
88 260200 : if ( eRasterOp != ROP_OVERPAINT )
89 0 : SetRasterOp( ROP_OVERPAINT );
90 260200 : DrawWallpaper( 0, 0, mnOutWidth, mnOutHeight, maBackground );
91 260200 : if ( eRasterOp != ROP_OVERPAINT )
92 0 : SetRasterOp( eRasterOp );
93 : }
94 :
95 260200 : if( mpAlphaVDev )
96 0 : mpAlphaVDev->Erase();
97 : }
98 :
99 2 : void OutputDevice::DrawBitmapWallpaper( long nX, long nY,
100 : long nWidth, long nHeight,
101 : const Wallpaper& rWallpaper )
102 : {
103 2 : BitmapEx aBmpEx;
104 2 : const BitmapEx* pCached = rWallpaper.ImplGetImpWallpaper()->ImplGetCachedBitmap();
105 2 : Point aPos;
106 2 : Size aSize;
107 2 : GDIMetaFile* pOldMetaFile = mpMetaFile;
108 2 : const WallpaperStyle eStyle = rWallpaper.GetStyle();
109 2 : const bool bOldMap = mbMap;
110 2 : bool bDrawn = false;
111 2 : bool bDrawGradientBackground = false;
112 2 : bool bDrawColorBackground = false;
113 :
114 2 : if( pCached )
115 0 : aBmpEx = *pCached;
116 : else
117 2 : aBmpEx = rWallpaper.GetBitmap();
118 :
119 2 : const long nBmpWidth = aBmpEx.GetSizePixel().Width();
120 2 : const long nBmpHeight = aBmpEx.GetSizePixel().Height();
121 2 : const bool bTransparent = aBmpEx.IsTransparent();
122 :
123 : // draw background
124 2 : if( bTransparent )
125 : {
126 2 : if( rWallpaper.IsGradient() )
127 0 : bDrawGradientBackground = true;
128 : else
129 : {
130 2 : if( !pCached && !rWallpaper.GetColor().GetTransparency() )
131 : {
132 2 : VirtualDevice aVDev( *this );
133 2 : aVDev.SetBackground( rWallpaper.GetColor() );
134 2 : aVDev.SetOutputSizePixel( Size( nBmpWidth, nBmpHeight ) );
135 2 : aVDev.DrawBitmapEx( Point(), aBmpEx );
136 2 : aBmpEx = aVDev.GetBitmap( Point(), aVDev.GetOutputSizePixel() );
137 : }
138 :
139 2 : bDrawColorBackground = true;
140 : }
141 : }
142 0 : else if( eStyle != WALLPAPER_TILE && eStyle != WALLPAPER_SCALE )
143 : {
144 0 : if( rWallpaper.IsGradient() )
145 0 : bDrawGradientBackground = true;
146 : else
147 0 : bDrawColorBackground = true;
148 : }
149 :
150 : // background of bitmap?
151 2 : if( bDrawGradientBackground )
152 0 : DrawGradientWallpaper( nX, nY, nWidth, nHeight, rWallpaper );
153 2 : else if( bDrawColorBackground && bTransparent )
154 : {
155 2 : DrawColorWallpaper( nX, nY, nWidth, nHeight, rWallpaper );
156 2 : bDrawColorBackground = false;
157 : }
158 :
159 : // calc pos and size
160 2 : if( rWallpaper.IsRect() )
161 : {
162 0 : const Rectangle aBound( LogicToPixel( rWallpaper.GetRect() ) );
163 0 : aPos = aBound.TopLeft();
164 0 : aSize = aBound.GetSize();
165 : }
166 : else
167 : {
168 2 : aPos = Point( 0, 0 );
169 2 : aSize = Size( mnOutWidth, mnOutHeight );
170 : }
171 :
172 2 : mpMetaFile = NULL;
173 2 : EnableMapMode( false );
174 2 : Push( PushFlags::CLIPREGION );
175 2 : IntersectClipRegion( Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) ) );
176 :
177 2 : switch( eStyle )
178 : {
179 : case( WALLPAPER_SCALE ):
180 0 : if( !pCached || ( pCached->GetSizePixel() != aSize ) )
181 : {
182 0 : if( pCached )
183 0 : rWallpaper.ImplGetImpWallpaper()->ImplReleaseCachedBitmap();
184 :
185 0 : aBmpEx = rWallpaper.GetBitmap();
186 0 : aBmpEx.Scale( aSize );
187 0 : aBmpEx = BitmapEx( aBmpEx.GetBitmap().CreateDisplayBitmap( this ), aBmpEx.GetMask() );
188 : }
189 0 : break;
190 :
191 : case( WALLPAPER_TOPLEFT ):
192 0 : break;
193 :
194 : case( WALLPAPER_TOP ):
195 0 : aPos.X() += ( aSize.Width() - nBmpWidth ) >> 1;
196 0 : break;
197 :
198 : case( WALLPAPER_TOPRIGHT ):
199 0 : aPos.X() += ( aSize.Width() - nBmpWidth );
200 0 : break;
201 :
202 : case( WALLPAPER_LEFT ):
203 0 : aPos.Y() += ( aSize.Height() - nBmpHeight ) >> 1;
204 0 : break;
205 :
206 : case( WALLPAPER_CENTER ):
207 0 : aPos.X() += ( aSize.Width() - nBmpWidth ) >> 1;
208 0 : aPos.Y() += ( aSize.Height() - nBmpHeight ) >> 1;
209 0 : break;
210 :
211 : case( WALLPAPER_RIGHT ):
212 0 : aPos.X() += ( aSize.Width() - nBmpWidth );
213 0 : aPos.Y() += ( aSize.Height() - nBmpHeight ) >> 1;
214 0 : break;
215 :
216 : case( WALLPAPER_BOTTOMLEFT ):
217 0 : aPos.Y() += ( aSize.Height() - nBmpHeight );
218 0 : break;
219 :
220 : case( WALLPAPER_BOTTOM ):
221 0 : aPos.X() += ( aSize.Width() - nBmpWidth ) >> 1;
222 0 : aPos.Y() += ( aSize.Height() - nBmpHeight );
223 0 : break;
224 :
225 : case( WALLPAPER_BOTTOMRIGHT ):
226 2 : aPos.X() += ( aSize.Width() - nBmpWidth );
227 2 : aPos.Y() += ( aSize.Height() - nBmpHeight );
228 2 : break;
229 :
230 : default:
231 : {
232 0 : const long nRight = nX + nWidth - 1L;
233 0 : const long nBottom = nY + nHeight - 1L;
234 : long nFirstX;
235 : long nFirstY;
236 :
237 0 : if( eStyle == WALLPAPER_TILE )
238 : {
239 0 : nFirstX = aPos.X();
240 0 : nFirstY = aPos.Y();
241 : }
242 : else
243 : {
244 0 : nFirstX = aPos.X() + ( ( aSize.Width() - nBmpWidth ) >> 1 );
245 0 : nFirstY = aPos.Y() + ( ( aSize.Height() - nBmpHeight ) >> 1 );
246 : }
247 :
248 0 : const long nOffX = ( nFirstX - nX ) % nBmpWidth;
249 0 : const long nOffY = ( nFirstY - nY ) % nBmpHeight;
250 0 : long nStartX = nX + nOffX;
251 0 : long nStartY = nY + nOffY;
252 :
253 0 : if( nOffX > 0L )
254 0 : nStartX -= nBmpWidth;
255 :
256 0 : if( nOffY > 0L )
257 0 : nStartY -= nBmpHeight;
258 :
259 0 : for( long nBmpY = nStartY; nBmpY <= nBottom; nBmpY += nBmpHeight )
260 : {
261 0 : for( long nBmpX = nStartX; nBmpX <= nRight; nBmpX += nBmpWidth )
262 : {
263 0 : DrawBitmapEx( Point( nBmpX, nBmpY ), aBmpEx );
264 : }
265 : }
266 0 : bDrawn = true;
267 : }
268 0 : break;
269 : }
270 :
271 2 : if( !bDrawn )
272 : {
273 : // optimized for non-transparent bitmaps
274 2 : if( bDrawColorBackground )
275 : {
276 0 : const Size aBmpSize( aBmpEx.GetSizePixel() );
277 0 : const Point aTmpPoint;
278 0 : const Rectangle aOutRect( aTmpPoint, GetOutputSizePixel() );
279 0 : const Rectangle aColRect( Point( nX, nY ), Size( nWidth, nHeight ) );
280 0 : Rectangle aWorkRect;
281 :
282 0 : aWorkRect = Rectangle( 0, 0, aOutRect.Right(), aPos.Y() - 1L );
283 0 : aWorkRect.Justify();
284 0 : aWorkRect.Intersection( aColRect );
285 0 : if( !aWorkRect.IsEmpty() )
286 : {
287 0 : DrawColorWallpaper( aWorkRect.Left(), aWorkRect.Top(),
288 : aWorkRect.GetWidth(), aWorkRect.GetHeight(),
289 0 : rWallpaper );
290 : }
291 :
292 0 : aWorkRect = Rectangle( 0, aPos.Y(), aPos.X() - 1L, aPos.Y() + aBmpSize.Height() - 1L );
293 0 : aWorkRect.Justify();
294 0 : aWorkRect.Intersection( aColRect );
295 0 : if( !aWorkRect.IsEmpty() )
296 : {
297 0 : DrawColorWallpaper( aWorkRect.Left(), aWorkRect.Top(),
298 : aWorkRect.GetWidth(), aWorkRect.GetHeight(),
299 0 : rWallpaper );
300 : }
301 :
302 0 : aWorkRect = Rectangle( aPos.X() + aBmpSize.Width(), aPos.Y(),
303 0 : aOutRect.Right(), aPos.Y() + aBmpSize.Height() - 1L );
304 0 : aWorkRect.Justify();
305 0 : aWorkRect.Intersection( aColRect );
306 0 : if( !aWorkRect.IsEmpty() )
307 : {
308 0 : DrawColorWallpaper( aWorkRect.Left(), aWorkRect.Top(),
309 : aWorkRect.GetWidth(), aWorkRect.GetHeight(),
310 0 : rWallpaper );
311 : }
312 :
313 0 : aWorkRect = Rectangle( 0, aPos.Y() + aBmpSize.Height(),
314 0 : aOutRect.Right(), aOutRect.Bottom() );
315 0 : aWorkRect.Justify();
316 0 : aWorkRect.Intersection( aColRect );
317 0 : if( !aWorkRect.IsEmpty() )
318 : {
319 0 : DrawColorWallpaper( aWorkRect.Left(), aWorkRect.Top(),
320 : aWorkRect.GetWidth(), aWorkRect.GetHeight(),
321 0 : rWallpaper );
322 : }
323 : }
324 :
325 2 : DrawBitmapEx( aPos, aBmpEx );
326 : }
327 :
328 2 : rWallpaper.ImplGetImpWallpaper()->ImplSetCachedBitmap( aBmpEx );
329 :
330 2 : Pop();
331 2 : EnableMapMode( bOldMap );
332 2 : mpMetaFile = pOldMetaFile;
333 2 : }
334 :
335 0 : void OutputDevice::DrawGradientWallpaper( long nX, long nY,
336 : long nWidth, long nHeight,
337 : const Wallpaper& rWallpaper )
338 : {
339 0 : Rectangle aBound;
340 0 : GDIMetaFile* pOldMetaFile = mpMetaFile;
341 0 : const bool bOldMap = mbMap;
342 :
343 0 : aBound = Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) );
344 :
345 0 : mpMetaFile = NULL;
346 0 : EnableMapMode( false );
347 0 : Push( PushFlags::CLIPREGION );
348 0 : IntersectClipRegion( Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) ) );
349 :
350 0 : DrawGradient( aBound, rWallpaper.GetGradient() );
351 :
352 0 : Pop();
353 0 : EnableMapMode( bOldMap );
354 0 : mpMetaFile = pOldMetaFile;
355 1233 : }
356 :
357 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|