LibreOffice Module vcl (master) 1
wallpaper.cxx
Go to the documentation of this file.
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/metaact.hxx>
21#include <vcl/virdev.hxx>
22
23#include <cassert>
24
25Color OutputDevice::GetReadableFontColor(const Color& rFontColor, const Color& rBgColor) const
26{
27 if (rBgColor.IsDark() && rFontColor.IsDark())
28 return COL_WHITE;
29 else if (rBgColor.IsBright() && rFontColor.IsBright())
30 return COL_BLACK;
31 else
32 return rFontColor;
33}
34
36 const Wallpaper& rWallpaper )
37{
39
40 if ( mpMetaFile )
41 mpMetaFile->AddAction( new MetaWallpaperAction( rRect, rWallpaper ) );
42
44 return;
45
46 if ( rWallpaper.GetStyle() != WallpaperStyle::NONE )
47 {
48 tools::Rectangle aRect = LogicToPixel( rRect );
49 aRect.Normalize();
50
51 if ( !aRect.IsEmpty() )
52 {
53 DrawWallpaper( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(),
54 rWallpaper );
55 }
56 }
57
58 if( mpAlphaVDev )
59 mpAlphaVDev->DrawWallpaper( rRect, rWallpaper );
60}
61
63 tools::Long nWidth, tools::Long nHeight,
64 const Wallpaper& rWallpaper )
65{
67
68 if( rWallpaper.IsBitmap() )
69 DrawBitmapWallpaper( nX, nY, nWidth, nHeight, rWallpaper );
70 else if( rWallpaper.IsGradient() )
71 DrawGradientWallpaper( nX, nY, nWidth, nHeight, rWallpaper );
72 else
73 DrawColorWallpaper( nX, nY, nWidth, nHeight, rWallpaper );
74}
75
77 tools::Long nWidth, tools::Long nHeight,
78 const Wallpaper& rWallpaper )
79{
81
82 // draw wallpaper without border
83 Color aOldLineColor = GetLineColor();
84 Color aOldFillColor = GetFillColor();
86 SetFillColor( rWallpaper.GetColor() );
87
88 bool bMap = mbMap;
89 EnableMapMode( false );
90 DrawRect( tools::Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) ) );
91 SetLineColor( aOldLineColor );
92 SetFillColor( aOldFillColor );
93 EnableMapMode( bMap );
94}
95
97{
99 return;
100
101 if ( mbBackground )
102 {
103 RasterOp eRasterOp = GetRasterOp();
104 if ( eRasterOp != RasterOp::OverPaint )
107 if ( eRasterOp != RasterOp::OverPaint )
108 SetRasterOp( eRasterOp );
109 }
110
111 if( mpAlphaVDev )
113}
114
116{
117 const RasterOp eRasterOp = GetRasterOp();
118 if ( eRasterOp != RasterOp::OverPaint )
121 if ( eRasterOp != RasterOp::OverPaint )
122 SetRasterOp( eRasterOp );
123
124 if (mpAlphaVDev)
125 mpAlphaVDev->Erase(rRect);
126}
127
129 tools::Long nWidth, tools::Long nHeight,
130 const Wallpaper& rWallpaper )
131{
132 assert(!is_double_buffered_window());
133
134 const BitmapEx* pCached = rWallpaper.ImplGetCachedBitmap();
135
136 GDIMetaFile* pOldMetaFile = mpMetaFile;
137 const bool bOldMap = mbMap;
138
139 BitmapEx aBmpEx;
140 if( pCached )
141 aBmpEx = *pCached;
142 else
143 aBmpEx = rWallpaper.GetBitmap();
144
145 const tools::Long nBmpWidth = aBmpEx.GetSizePixel().Width();
146 const tools::Long nBmpHeight = aBmpEx.GetSizePixel().Height();
147 const bool bTransparent = aBmpEx.IsAlpha();
148
149 const WallpaperStyle eStyle = rWallpaper.GetStyle();
150
151 bool bDrawGradientBackground = false;
152 bool bDrawColorBackground = false;
153
154 // draw background
155 if( bTransparent )
156 {
157 if( rWallpaper.IsGradient() )
158 bDrawGradientBackground = true;
159 else
160 {
161 if( !pCached && !rWallpaper.GetColor().IsTransparent() )
162 {
164 aVDev->SetBackground( rWallpaper.GetColor() );
165 aVDev->SetOutputSizePixel( Size( nBmpWidth, nBmpHeight ) );
166 aVDev->DrawBitmapEx( Point(), aBmpEx );
167 aBmpEx = aVDev->GetBitmapEx( Point(), aVDev->GetOutputSizePixel() );
168 }
169
170 bDrawColorBackground = true;
171 }
172 }
173 else if( eStyle != WallpaperStyle::Tile && eStyle != WallpaperStyle::Scale )
174 {
175 if( rWallpaper.IsGradient() )
176 bDrawGradientBackground = true;
177 else
178 bDrawColorBackground = true;
179 }
180
181 // background of bitmap?
182 if( bDrawGradientBackground )
183 {
184 DrawGradientWallpaper( nX, nY, nWidth, nHeight, rWallpaper );
185 }
186 else if( bDrawColorBackground && bTransparent )
187 {
188 DrawColorWallpaper( nX, nY, nWidth, nHeight, rWallpaper );
189 bDrawColorBackground = false;
190 }
191
192 Point aPos;
193 Size aSize;
194
195 // calc pos and size
196 if( rWallpaper.IsRect() )
197 {
198 const tools::Rectangle aBound( LogicToPixel( rWallpaper.GetRect() ) );
199 aPos = aBound.TopLeft();
200 aSize = aBound.GetSize();
201 }
202 else
203 {
204 aPos = Point( 0, 0 );
205 aSize = Size( nWidth, nHeight );
206 }
207
208 mpMetaFile = nullptr;
209 EnableMapMode( false );
211 IntersectClipRegion( tools::Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) ) );
212
213 bool bDrawn = false;
214
215 switch( eStyle )
216 {
218 if( !pCached || ( pCached->GetSizePixel() != aSize ) )
219 {
220 if( pCached )
221 rWallpaper.ImplReleaseCachedBitmap();
222
223 aBmpEx = rWallpaper.GetBitmap();
224 aBmpEx.Scale( aSize );
225 aBmpEx = BitmapEx( aBmpEx.GetBitmap().CreateDisplayBitmap( this ), aBmpEx.GetAlpha() );
226 }
227 break;
228
230 break;
231
233 aPos.AdjustX(( aSize.Width() - nBmpWidth ) >> 1 );
234 break;
235
237 aPos.AdjustX( aSize.Width() - nBmpWidth);
238 break;
239
241 aPos.AdjustY(( aSize.Height() - nBmpHeight ) >> 1 );
242 break;
243
245 aPos.AdjustX(( aSize.Width() - nBmpWidth ) >> 1 );
246 aPos.AdjustY(( aSize.Height() - nBmpHeight ) >> 1 );
247 break;
248
250 aPos.AdjustX(aSize.Width() - nBmpWidth);
251 aPos.AdjustY(( aSize.Height() - nBmpHeight ) >> 1 );
252 break;
253
255 aPos.AdjustY( aSize.Height() - nBmpHeight );
256 break;
257
259 aPos.AdjustX(( aSize.Width() - nBmpWidth ) >> 1 );
260 aPos.AdjustY( aSize.Height() - nBmpHeight );
261 break;
262
264 aPos.AdjustX( aSize.Width() - nBmpWidth );
265 aPos.AdjustY( aSize.Height() - nBmpHeight );
266 break;
267
268 default:
269 {
270 const tools::Long nRight = nX + nWidth - 1;
271 const tools::Long nBottom = nY + nHeight - 1;
272 tools::Long nFirstX;
273 tools::Long nFirstY;
274
275 if( eStyle == WallpaperStyle::Tile )
276 {
277 nFirstX = aPos.X();
278 nFirstY = aPos.Y();
279 }
280 else
281 {
282 nFirstX = aPos.X() + ( ( aSize.Width() - nBmpWidth ) >> 1 );
283 nFirstY = aPos.Y() + ( ( aSize.Height() - nBmpHeight ) >> 1 );
284 }
285
286 const tools::Long nOffX = ( nFirstX - nX ) % nBmpWidth;
287 const tools::Long nOffY = ( nFirstY - nY ) % nBmpHeight;
288 tools::Long nStartX = nX + nOffX;
289 tools::Long nStartY = nY + nOffY;
290
291 if( nOffX > 0 )
292 nStartX -= nBmpWidth;
293
294 if( nOffY > 0 )
295 nStartY -= nBmpHeight;
296
297 for( tools::Long nBmpY = nStartY; nBmpY <= nBottom; nBmpY += nBmpHeight )
298 {
299 for( tools::Long nBmpX = nStartX; nBmpX <= nRight; nBmpX += nBmpWidth )
300 {
301 DrawBitmapEx( Point( nBmpX, nBmpY ), aBmpEx );
302 }
303 }
304 bDrawn = true;
305 }
306 break;
307 }
308
309 if( !bDrawn )
310 {
311 // optimized for non-transparent bitmaps
312 if( bDrawColorBackground )
313 {
314 const Size aBmpSize( aBmpEx.GetSizePixel() );
315 const Point aTmpPoint;
316 const tools::Rectangle aOutRect( aTmpPoint, GetOutputSizePixel() );
317 const tools::Rectangle aColRect( Point( nX, nY ), Size( nWidth, nHeight ) );
318
319 tools::Rectangle aWorkRect( 0, 0, aOutRect.Right(), aPos.Y() - 1 );
320 aWorkRect.Normalize();
321 aWorkRect.Intersection( aColRect );
322 if( !aWorkRect.IsEmpty() )
323 {
324 DrawColorWallpaper( aWorkRect.Left(), aWorkRect.Top(),
325 aWorkRect.GetWidth(), aWorkRect.GetHeight(),
326 rWallpaper );
327 }
328
329 aWorkRect = tools::Rectangle( 0, aPos.Y(), aPos.X() - 1, aPos.Y() + aBmpSize.Height() - 1 );
330 aWorkRect.Normalize();
331 aWorkRect.Intersection( aColRect );
332 if( !aWorkRect.IsEmpty() )
333 {
334 DrawColorWallpaper( aWorkRect.Left(), aWorkRect.Top(),
335 aWorkRect.GetWidth(), aWorkRect.GetHeight(),
336 rWallpaper );
337 }
338
339 aWorkRect = tools::Rectangle( aPos.X() + aBmpSize.Width(), aPos.Y(),
340 aOutRect.Right(), aPos.Y() + aBmpSize.Height() - 1 );
341 aWorkRect.Normalize();
342 aWorkRect.Intersection( aColRect );
343 if( !aWorkRect.IsEmpty() )
344 {
345 DrawColorWallpaper( aWorkRect.Left(), aWorkRect.Top(),
346 aWorkRect.GetWidth(), aWorkRect.GetHeight(),
347 rWallpaper );
348 }
349
350 aWorkRect = tools::Rectangle( 0, aPos.Y() + aBmpSize.Height(),
351 aOutRect.Right(), aOutRect.Bottom() );
352 aWorkRect.Normalize();
353 aWorkRect.Intersection( aColRect );
354 if( !aWorkRect.IsEmpty() )
355 {
356 DrawColorWallpaper( aWorkRect.Left(), aWorkRect.Top(),
357 aWorkRect.GetWidth(), aWorkRect.GetHeight(),
358 rWallpaper );
359 }
360 }
361
362 DrawBitmapEx( aPos, aBmpEx );
363 }
364
365 rWallpaper.ImplSetCachedBitmap( aBmpEx );
366
367 Pop();
368 EnableMapMode( bOldMap );
369 mpMetaFile = pOldMetaFile;
370}
371
373 tools::Long nWidth, tools::Long nHeight,
374 const Wallpaper& rWallpaper )
375{
376 assert(!is_double_buffered_window());
377
378 tools::Rectangle aBound;
379 GDIMetaFile* pOldMetaFile = mpMetaFile;
380 const bool bOldMap = mbMap;
381
382 aBound = tools::Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) );
383
384 mpMetaFile = nullptr;
385 EnableMapMode( false );
387 IntersectClipRegion( tools::Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) ) );
388
389 DrawGradient( aBound, rWallpaper.GetGradient() );
390
391 Pop();
392 EnableMapMode( bOldMap );
393 mpMetaFile = pOldMetaFile;
394}
395
396/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
RasterOp
Definition: RasterOp.hxx:23
AlphaMask GetAlpha() const
Definition: BitmapEx.cxx:215
bool Scale(const Size &rNewSize, BmpScaleFlag nScaleFlag=BmpScaleFlag::Default)
Scale the bitmap.
Definition: BitmapEx.cxx:296
bool IsAlpha() const
Definition: BitmapEx.cxx:193
Bitmap GetBitmap(Color aTransparentReplaceColor) const
Definition: BitmapEx.cxx:203
const Size & GetSizePixel() const
Definition: bitmapex.hxx:72
Bitmap CreateDisplayBitmap(OutputDevice *pDisplay) const
bool IsBright() const
bool IsDark() const
bool IsTransparent() const
void AddAction(const rtl::Reference< MetaAction > &pAction)
Definition: gdimtf.cxx:581
void EnableMapMode(bool bEnable=true)
Definition: map.cxx:602
void DrawBitmapEx(const Point &rDestPt, const BitmapEx &rBitmapEx)
Definition: bitmapex.cxx:33
SAL_DLLPRIVATE bool is_double_buffered_window() const
void DrawGradientWallpaper(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, const Wallpaper &rWallpaper)
Definition: wallpaper.cxx:372
RasterOp GetRasterOp() const
Definition: outdev.hxx:497
Size GetOutputSizePixel() const
Definition: outdev.hxx:315
SAL_DLLPRIVATE bool ImplIsRecordLayout() const
Definition: outdev.cxx:708
void DrawRect(const tools::Rectangle &rRect)
Definition: rect.cxx:50
SAL_DLLPRIVATE void DrawColorWallpaper(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, const Wallpaper &rWallpaper)
Definition: wallpaper.cxx:76
virtual Color GetReadableFontColor(const Color &rFontColor, const Color &rBgColor) const
Definition: wallpaper.cxx:25
GDIMetaFile * mpMetaFile
Definition: outdev.hxx:186
const Wallpaper & GetBackground() const
Definition: outdev.hxx:524
bool mbMap
Definition: outdev.hxx:241
void SetLineColor()
Definition: line.cxx:37
tools::Long mnOutWidth
Definition: outdev.hxx:211
SAL_DLLPRIVATE void DrawBitmapWallpaper(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, const Wallpaper &rWallpaper)
Definition: wallpaper.cxx:128
void SetFillColor()
Definition: fill.cxx:29
SAL_WARN_UNUSED_RESULT Point LogicToPixel(const Point &rLogicPt) const
Definition: map.cxx:892
void SetRasterOp(RasterOp eRasterOp)
Definition: outdev.cxx:320
const Color & GetLineColor() const
Definition: outdev.hxx:511
bool IsDeviceOutputNecessary() const
Definition: outdev.hxx:482
VclPtr< VirtualDevice > mpAlphaVDev
Definition: outdev.hxx:197
void DrawWallpaper(const tools::Rectangle &rRect, const Wallpaper &rWallpaper)
Definition: wallpaper.cxx:35
bool mbBackground
Definition: outdev.hxx:243
void Erase()
Definition: wallpaper.cxx:96
void Push(vcl::PushFlags nFlags=vcl::PushFlags::ALL)
Definition: stack.cxx:32
void DrawGradient(const tools::Rectangle &rRect, const Gradient &rGradient)
void Pop()
Definition: stack.cxx:91
void IntersectClipRegion(const tools::Rectangle &rRect)
tools::Long mnOutHeight
Definition: outdev.hxx:212
Wallpaper maBackground
Definition: outdev.hxx:234
const Color & GetFillColor() const
Definition: outdev.hxx:516
constexpr tools::Long Height() const
constexpr tools::Long Width() const
SAL_DLLPRIVATE void ImplSetCachedBitmap(const BitmapEx &rBmp) const
Definition: wall.cxx:141
bool IsRect() const
Definition: wall.cxx:232
const BitmapEx & GetBitmap() const
Definition: wall.cxx:184
SAL_DLLPRIVATE void ImplReleaseCachedBitmap() const
Definition: wall.cxx:151
const Color & GetColor() const
Definition: wall.hxx:71
bool IsBitmap() const
Definition: wall.cxx:189
WallpaperStyle GetStyle() const
Definition: wall.hxx:74
SAL_DLLPRIVATE const BitmapEx * ImplGetCachedBitmap() const
Definition: wall.cxx:146
bool IsGradient() const
Definition: wall.cxx:213
Gradient GetGradient() const
Definition: wall.cxx:203
const tools::Rectangle & GetRect() const
Definition: wall.hxx:85
constexpr tools::Long GetWidth() const
constexpr tools::Long Top() const
constexpr Point TopLeft() const
constexpr Size GetSize() const
constexpr tools::Long Right() const
constexpr tools::Long GetHeight() const
tools::Rectangle & Intersection(const tools::Rectangle &rRect)
constexpr tools::Long Left() const
constexpr tools::Long Bottom() const
constexpr bool IsEmpty() const
constexpr ::Color COL_WHITE(0xFF, 0xFF, 0xFF)
constexpr ::Color COL_BLACK(0x00, 0x00, 0x00)
long Long
WallpaperStyle
Definition: wall.hxx:35