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 
25 Color 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 {
38  assert(!is_double_buffered_window());
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.Justify();
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 {
66  assert(!is_double_buffered_window());
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 {
80  assert(!is_double_buffered_window());
81 
82  // draw wallpaper without border
83  Color aOldLineColor = GetLineColor();
84  Color aOldFillColor = GetFillColor();
85  SetLineColor();
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 )
112  mpAlphaVDev->Erase();
113 }
114 
116 {
117  const RasterOp eRasterOp = GetRasterOp();
118  if ( eRasterOp != RasterOp::OverPaint )
120  DrawWallpaper(rRect, GetBackground());
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 
232  case WallpaperStyle::Top:
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.Justify();
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.Justify();
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.Justify();
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.Justify();
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: */
const Wallpaper & GetBackground() const
Definition: outdev.hxx:534
SAL_DLLPRIVATE bool ImplIsRecordLayout() const
Definition: outdev.cxx:724
SAL_DLLPRIVATE void ImplReleaseCachedBitmap() const
Definition: wall.cxx:151
bool IsTransparent() const
constexpr tools::Long Left() const
void DrawBitmapEx(const Point &rDestPt, const BitmapEx &rBitmapEx)
Definition: bitmapex.cxx:33
bool Scale(const Size &rNewSize, BmpScaleFlag nScaleFlag=BmpScaleFlag::Default)
Scale the bitmap.
Definition: BitmapEx.cxx:296
long Long
void Push(vcl::PushFlags nFlags=vcl::PushFlags::ALL)
Definition: stack.cxx:33
SAL_DLLPRIVATE bool is_double_buffered_window() const
void IntersectClipRegion(const tools::Rectangle &rRect)
WallpaperStyle GetStyle() const
Definition: wall.hxx:74
void EnableMapMode(bool bEnable=true)
Definition: map.cxx:641
bool mbMap
Definition: outdev.hxx:247
void DrawGradientWallpaper(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, const Wallpaper &rWallpaper)
Definition: wallpaper.cxx:372
void DrawWallpaper(const tools::Rectangle &rRect, const Wallpaper &rWallpaper)
Definition: wallpaper.cxx:35
constexpr tools::Long Width() const
bool IsAlpha() const
Definition: BitmapEx.cxx:193
bool mbBackground
Definition: outdev.hxx:249
constexpr tools::Long GetWidth() const
void Pop()
Definition: stack.cxx:92
SAL_DLLPRIVATE const BitmapEx * ImplGetCachedBitmap() const
Definition: wall.cxx:146
void DrawRect(const tools::Rectangle &rRect)
Definition: rect.cxx:51
constexpr bool IsEmpty() const
void SetLineColor()
Definition: line.cxx:36
Wallpaper maBackground
Definition: outdev.hxx:239
Bitmap CreateDisplayBitmap(OutputDevice *pDisplay) const
bool IsDark() const
bool IsRect() const
Definition: wall.cxx:232
bool IsBright() const
const Color & GetColor() const
Definition: wall.hxx:71
constexpr tools::Long Right() const
tools::Long mnOutHeight
Definition: outdev.hxx:217
void SetFillColor()
Definition: fill.cxx:29
const Color & GetLineColor() const
Definition: outdev.hxx:521
constexpr tools::Long Top() const
Size GetOutputSizePixel() const
Definition: outdev.hxx:321
SAL_DLLPRIVATE void ImplSetCachedBitmap(const BitmapEx &rBmp) const
Definition: wall.cxx:141
SAL_DLLPRIVATE void DrawColorWallpaper(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, const Wallpaper &rWallpaper)
Definition: wallpaper.cxx:76
RasterOp
Definition: RasterOp.hxx:22
constexpr Point TopLeft() const
Gradient GetGradient() const
Definition: wall.cxx:203
constexpr tools::Long Bottom() const
Bitmap GetBitmap(Color aTransparentReplaceColor) const
Definition: BitmapEx.cxx:203
SAL_WARN_UNUSED_RESULT Point LogicToPixel(const Point &rLogicPt) const
Definition: map.cxx:933
VclPtr< VirtualDevice > mpAlphaVDev
Definition: outdev.hxx:202
constexpr Size GetSize() const
bool IsGradient() const
Definition: wall.cxx:213
void Erase()
Definition: wallpaper.cxx:96
AlphaMask GetAlpha() const
Definition: BitmapEx.cxx:215
SAL_DLLPRIVATE void DrawBitmapWallpaper(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, const Wallpaper &rWallpaper)
Definition: wallpaper.cxx:128
const BitmapEx & GetBitmap() const
Definition: wall.cxx:184
constexpr tools::Long Height() const
virtual Color GetReadableFontColor(const Color &rFontColor, const Color &rBgColor) const
Definition: wallpaper.cxx:25
void AddAction(const rtl::Reference< MetaAction > &pAction)
Definition: gdimtf.cxx:581
WallpaperStyle
Definition: wall.hxx:34
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_WHITE
void SetRasterOp(RasterOp eRasterOp)
Definition: outdev.cxx:322
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_BLACK
RasterOp GetRasterOp() const
Definition: outdev.hxx:507
tools::Long mnOutWidth
Definition: outdev.hxx:216
const tools::Rectangle & GetRect() const
Definition: wall.hxx:85
bool IsBitmap() const
Definition: wall.cxx:189
const Size & GetSizePixel() const
Definition: bitmapex.hxx:72
bool IsDeviceOutputNecessary() const
Definition: outdev.hxx:488
void DrawGradient(const tools::Rectangle &rRect, const Gradient &rGradient)
const Color & GetFillColor() const
Definition: outdev.hxx:526
GDIMetaFile * mpMetaFile
Definition: outdev.hxx:191
constexpr tools::Long GetHeight() const