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  BitmapEx aBmpEx;
135  const BitmapEx* pCached = rWallpaper.ImplGetCachedBitmap();
136  Point aPos;
137  Size aSize;
138  GDIMetaFile* pOldMetaFile = mpMetaFile;
139  const WallpaperStyle eStyle = rWallpaper.GetStyle();
140  const bool bOldMap = mbMap;
141  bool bDrawn = false;
142  bool bDrawGradientBackground = false;
143  bool bDrawColorBackground = false;
144 
145  if( pCached )
146  aBmpEx = *pCached;
147  else
148  aBmpEx = rWallpaper.GetBitmap();
149 
150  const tools::Long nBmpWidth = aBmpEx.GetSizePixel().Width();
151  const tools::Long nBmpHeight = aBmpEx.GetSizePixel().Height();
152  const bool bTransparent = aBmpEx.IsAlpha();
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  DrawGradientWallpaper( nX, nY, nWidth, nHeight, rWallpaper );
184  else if( bDrawColorBackground && bTransparent )
185  {
186  DrawColorWallpaper( nX, nY, nWidth, nHeight, rWallpaper );
187  bDrawColorBackground = false;
188  }
189 
190  // calc pos and size
191  if( rWallpaper.IsRect() )
192  {
193  const tools::Rectangle aBound( LogicToPixel( rWallpaper.GetRect() ) );
194  aPos = aBound.TopLeft();
195  aSize = aBound.GetSize();
196  }
197  else
198  {
199  aPos = Point( 0, 0 );
200  aSize = Size( nWidth, nHeight );
201  }
202 
203  mpMetaFile = nullptr;
204  EnableMapMode( false );
206  IntersectClipRegion( tools::Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) ) );
207 
208  switch( eStyle )
209  {
211  if( !pCached || ( pCached->GetSizePixel() != aSize ) )
212  {
213  if( pCached )
214  rWallpaper.ImplReleaseCachedBitmap();
215 
216  aBmpEx = rWallpaper.GetBitmap();
217  aBmpEx.Scale( aSize );
218  aBmpEx = BitmapEx( aBmpEx.GetBitmap().CreateDisplayBitmap( this ), aBmpEx.GetAlpha() );
219  }
220  break;
221 
223  break;
224 
225  case WallpaperStyle::Top:
226  aPos.AdjustX(( aSize.Width() - nBmpWidth ) >> 1 );
227  break;
228 
230  aPos.AdjustX( aSize.Width() - nBmpWidth);
231  break;
232 
234  aPos.AdjustY(( aSize.Height() - nBmpHeight ) >> 1 );
235  break;
236 
238  aPos.AdjustX(( aSize.Width() - nBmpWidth ) >> 1 );
239  aPos.AdjustY(( aSize.Height() - nBmpHeight ) >> 1 );
240  break;
241 
243  aPos.AdjustX(aSize.Width() - nBmpWidth);
244  aPos.AdjustY(( aSize.Height() - nBmpHeight ) >> 1 );
245  break;
246 
248  aPos.AdjustY( aSize.Height() - nBmpHeight );
249  break;
250 
252  aPos.AdjustX(( aSize.Width() - nBmpWidth ) >> 1 );
253  aPos.AdjustY( aSize.Height() - nBmpHeight );
254  break;
255 
257  aPos.AdjustX( aSize.Width() - nBmpWidth );
258  aPos.AdjustY( aSize.Height() - nBmpHeight );
259  break;
260 
261  default:
262  {
263  const tools::Long nRight = nX + nWidth - 1;
264  const tools::Long nBottom = nY + nHeight - 1;
265  tools::Long nFirstX;
266  tools::Long nFirstY;
267 
268  if( eStyle == WallpaperStyle::Tile )
269  {
270  nFirstX = aPos.X();
271  nFirstY = aPos.Y();
272  }
273  else
274  {
275  nFirstX = aPos.X() + ( ( aSize.Width() - nBmpWidth ) >> 1 );
276  nFirstY = aPos.Y() + ( ( aSize.Height() - nBmpHeight ) >> 1 );
277  }
278 
279  const tools::Long nOffX = ( nFirstX - nX ) % nBmpWidth;
280  const tools::Long nOffY = ( nFirstY - nY ) % nBmpHeight;
281  tools::Long nStartX = nX + nOffX;
282  tools::Long nStartY = nY + nOffY;
283 
284  if( nOffX > 0 )
285  nStartX -= nBmpWidth;
286 
287  if( nOffY > 0 )
288  nStartY -= nBmpHeight;
289 
290  for( tools::Long nBmpY = nStartY; nBmpY <= nBottom; nBmpY += nBmpHeight )
291  {
292  for( tools::Long nBmpX = nStartX; nBmpX <= nRight; nBmpX += nBmpWidth )
293  {
294  DrawBitmapEx( Point( nBmpX, nBmpY ), aBmpEx );
295  }
296  }
297  bDrawn = true;
298  }
299  break;
300  }
301 
302  if( !bDrawn )
303  {
304  // optimized for non-transparent bitmaps
305  if( bDrawColorBackground )
306  {
307  const Size aBmpSize( aBmpEx.GetSizePixel() );
308  const Point aTmpPoint;
309  const tools::Rectangle aOutRect( aTmpPoint, GetOutputSizePixel() );
310  const tools::Rectangle aColRect( Point( nX, nY ), Size( nWidth, nHeight ) );
311 
312  tools::Rectangle aWorkRect( 0, 0, aOutRect.Right(), aPos.Y() - 1 );
313  aWorkRect.Justify();
314  aWorkRect.Intersection( aColRect );
315  if( !aWorkRect.IsEmpty() )
316  {
317  DrawColorWallpaper( aWorkRect.Left(), aWorkRect.Top(),
318  aWorkRect.GetWidth(), aWorkRect.GetHeight(),
319  rWallpaper );
320  }
321 
322  aWorkRect = tools::Rectangle( 0, aPos.Y(), aPos.X() - 1, aPos.Y() + aBmpSize.Height() - 1 );
323  aWorkRect.Justify();
324  aWorkRect.Intersection( aColRect );
325  if( !aWorkRect.IsEmpty() )
326  {
327  DrawColorWallpaper( aWorkRect.Left(), aWorkRect.Top(),
328  aWorkRect.GetWidth(), aWorkRect.GetHeight(),
329  rWallpaper );
330  }
331 
332  aWorkRect = tools::Rectangle( aPos.X() + aBmpSize.Width(), aPos.Y(),
333  aOutRect.Right(), aPos.Y() + aBmpSize.Height() - 1 );
334  aWorkRect.Justify();
335  aWorkRect.Intersection( aColRect );
336  if( !aWorkRect.IsEmpty() )
337  {
338  DrawColorWallpaper( aWorkRect.Left(), aWorkRect.Top(),
339  aWorkRect.GetWidth(), aWorkRect.GetHeight(),
340  rWallpaper );
341  }
342 
343  aWorkRect = tools::Rectangle( 0, aPos.Y() + aBmpSize.Height(),
344  aOutRect.Right(), aOutRect.Bottom() );
345  aWorkRect.Justify();
346  aWorkRect.Intersection( aColRect );
347  if( !aWorkRect.IsEmpty() )
348  {
349  DrawColorWallpaper( aWorkRect.Left(), aWorkRect.Top(),
350  aWorkRect.GetWidth(), aWorkRect.GetHeight(),
351  rWallpaper );
352  }
353  }
354 
355  DrawBitmapEx( aPos, aBmpEx );
356  }
357 
358  rWallpaper.ImplSetCachedBitmap( aBmpEx );
359 
360  Pop();
361  EnableMapMode( bOldMap );
362  mpMetaFile = pOldMetaFile;
363 }
364 
366  tools::Long nWidth, tools::Long nHeight,
367  const Wallpaper& rWallpaper )
368 {
369  assert(!is_double_buffered_window());
370 
371  tools::Rectangle aBound;
372  GDIMetaFile* pOldMetaFile = mpMetaFile;
373  const bool bOldMap = mbMap;
374 
375  aBound = tools::Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) );
376 
377  mpMetaFile = nullptr;
378  EnableMapMode( false );
380  IntersectClipRegion( tools::Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) ) );
381 
382  DrawGradient( aBound, rWallpaper.GetGradient() );
383 
384  Pop();
385  EnableMapMode( bOldMap );
386  mpMetaFile = pOldMetaFile;
387 }
388 
389 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const Wallpaper & GetBackground() const
Definition: outdev.hxx:519
SAL_DLLPRIVATE bool ImplIsRecordLayout() const
Definition: outdev.cxx:702
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:586
bool mbMap
Definition: outdev.hxx:239
void DrawGradientWallpaper(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, const Wallpaper &rWallpaper)
Definition: wallpaper.cxx:365
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:241
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:232
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:210
void SetFillColor()
Definition: fill.cxx:29
const Color & GetLineColor() const
Definition: outdev.hxx:506
constexpr tools::Long Top() const
Size GetOutputSizePixel() const
Definition: outdev.hxx:310
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:878
VclPtr< VirtualDevice > mpAlphaVDev
Definition: outdev.hxx:195
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:562
WallpaperStyle
Definition: wall.hxx:34
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_WHITE
void SetRasterOp(RasterOp eRasterOp)
Definition: outdev.cxx:312
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_BLACK
RasterOp GetRasterOp() const
Definition: outdev.hxx:492
tools::Long mnOutWidth
Definition: outdev.hxx:209
const tools::Rectangle & GetRect() const
Definition: wall.hxx:85
bool IsBitmap() const
Definition: wall.cxx:189
const Size & GetSizePixel() const
Definition: bitmapex.hxx:73
bool IsDeviceOutputNecessary() const
Definition: outdev.hxx:477
void DrawGradient(const tools::Rectangle &rRect, const Gradient &rGradient)
const Color & GetFillColor() const
Definition: outdev.hxx:511
GDIMetaFile * mpMetaFile
Definition: outdev.hxx:184
constexpr tools::Long GetHeight() const