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 <cassert>
21 
22 #include <vcl/gdimtf.hxx>
23 #include <vcl/metaact.hxx>
24 #include <vcl/outdev.hxx>
25 #include <vcl/virdev.hxx>
26 
27 Color OutputDevice::GetReadableFontColor(const Color& rFontColor, const Color& rBgColor) const
28 {
29  if (rBgColor.IsDark() && rFontColor.IsDark())
30  return COL_WHITE;
31  else if (rBgColor.IsBright() && rFontColor.IsBright())
32  return COL_BLACK;
33  else
34  return rFontColor;
35 }
36 
38 {
39  return GetBackground().GetColor();
40 }
41 
43  const Wallpaper& rWallpaper )
44 {
46 
47  if ( mpMetaFile )
48  mpMetaFile->AddAction( new MetaWallpaperAction( rRect, rWallpaper ) );
49 
51  return;
52 
53  if ( rWallpaper.GetStyle() != WallpaperStyle::NONE )
54  {
55  tools::Rectangle aRect = LogicToPixel( rRect );
56  aRect.Justify();
57 
58  if ( !aRect.IsEmpty() )
59  {
60  DrawWallpaper( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(),
61  rWallpaper );
62  }
63  }
64 
65  if( mpAlphaVDev )
66  mpAlphaVDev->DrawWallpaper( rRect, rWallpaper );
67 }
68 
70  tools::Long nWidth, tools::Long nHeight,
71  const Wallpaper& rWallpaper )
72 {
74 
75  if( rWallpaper.IsBitmap() )
76  DrawBitmapWallpaper( nX, nY, nWidth, nHeight, rWallpaper );
77  else if( rWallpaper.IsGradient() )
78  DrawGradientWallpaper( nX, nY, nWidth, nHeight, rWallpaper );
79  else
80  DrawColorWallpaper( nX, nY, nWidth, nHeight, rWallpaper );
81 }
82 
84  tools::Long nWidth, tools::Long nHeight,
85  const Wallpaper& rWallpaper )
86 {
88 
89  // draw wallpaper without border
90  Color aOldLineColor = GetLineColor();
91  Color aOldFillColor = GetFillColor();
92  SetLineColor();
93  SetFillColor( rWallpaper.GetColor() );
94 
95  bool bMap = mbMap;
96  EnableMapMode( false );
97  DrawRect( tools::Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) ) );
98  SetLineColor( aOldLineColor );
99  SetFillColor( aOldFillColor );
100  EnableMapMode( bMap );
101 }
102 
104 {
106  return;
107 
108  if ( mbBackground )
109  {
110  RasterOp eRasterOp = GetRasterOp();
111  if ( eRasterOp != RasterOp::OverPaint )
114  if ( eRasterOp != RasterOp::OverPaint )
115  SetRasterOp( eRasterOp );
116  }
117 
118  if( mpAlphaVDev )
119  mpAlphaVDev->Erase();
120 }
121 
123 {
124  const RasterOp eRasterOp = GetRasterOp();
125  if ( eRasterOp != RasterOp::OverPaint )
127  DrawWallpaper(rRect, GetBackground());
128  if ( eRasterOp != RasterOp::OverPaint )
129  SetRasterOp( eRasterOp );
130 
131  if (mpAlphaVDev)
132  mpAlphaVDev->Erase(rRect);
133 }
134 
136  tools::Long nWidth, tools::Long nHeight,
137  const Wallpaper& rWallpaper )
138 {
140 
141  BitmapEx aBmpEx;
142  const BitmapEx* pCached = rWallpaper.ImplGetCachedBitmap();
143  Point aPos;
144  Size aSize;
145  GDIMetaFile* pOldMetaFile = mpMetaFile;
146  const WallpaperStyle eStyle = rWallpaper.GetStyle();
147  const bool bOldMap = mbMap;
148  bool bDrawn = false;
149  bool bDrawGradientBackground = false;
150  bool bDrawColorBackground = false;
151 
152  if( pCached )
153  aBmpEx = *pCached;
154  else
155  aBmpEx = rWallpaper.GetBitmap();
156 
157  const tools::Long nBmpWidth = aBmpEx.GetSizePixel().Width();
158  const tools::Long nBmpHeight = aBmpEx.GetSizePixel().Height();
159  const bool bTransparent = aBmpEx.IsTransparent();
160 
161  // draw background
162  if( bTransparent )
163  {
164  if( rWallpaper.IsGradient() )
165  bDrawGradientBackground = true;
166  else
167  {
168  if( !pCached && !rWallpaper.GetColor().GetTransparency() )
169  {
171  aVDev->SetBackground( rWallpaper.GetColor() );
172  aVDev->SetOutputSizePixel( Size( nBmpWidth, nBmpHeight ) );
173  aVDev->DrawBitmapEx( Point(), aBmpEx );
174  aBmpEx = aVDev->GetBitmapEx( Point(), aVDev->GetOutputSizePixel() );
175  }
176 
177  bDrawColorBackground = true;
178  }
179  }
180  else if( eStyle != WallpaperStyle::Tile && eStyle != WallpaperStyle::Scale )
181  {
182  if( rWallpaper.IsGradient() )
183  bDrawGradientBackground = true;
184  else
185  bDrawColorBackground = true;
186  }
187 
188  // background of bitmap?
189  if( bDrawGradientBackground )
190  DrawGradientWallpaper( nX, nY, nWidth, nHeight, rWallpaper );
191  else if( bDrawColorBackground && bTransparent )
192  {
193  DrawColorWallpaper( nX, nY, nWidth, nHeight, rWallpaper );
194  bDrawColorBackground = false;
195  }
196 
197  // calc pos and size
198  if( rWallpaper.IsRect() )
199  {
200  const tools::Rectangle aBound( LogicToPixel( rWallpaper.GetRect() ) );
201  aPos = aBound.TopLeft();
202  aSize = aBound.GetSize();
203  }
204  else
205  {
206  aPos = Point( 0, 0 );
207  aSize = Size( nWidth, nHeight );
208  }
209 
210  mpMetaFile = nullptr;
211  EnableMapMode( false );
213  IntersectClipRegion( tools::Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) ) );
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.GetMask() );
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 {
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: */
Point TopLeft() const
Bitmap GetMask() const
Definition: bitmapex.cxx:254
const Wallpaper & GetBackground() const
Definition: outdev.hxx:642
SAL_DLLPRIVATE bool ImplIsRecordLayout() const
Definition: outdev.cxx:636
SAL_DLLPRIVATE void ImplReleaseCachedBitmap() const
Definition: wall.cxx:184
void DrawBitmapEx(const Point &rDestPt, const BitmapEx &rBitmapEx)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool Scale(const Size &rNewSize, BmpScaleFlag nScaleFlag=BmpScaleFlag::Default)
Scale the bitmap.
Definition: bitmapex.cxx:366
sal_uInt8 GetTransparency() const
long Long
SAL_DLLPRIVATE bool is_double_buffered_window() const
tools::Long GetWidth() const
void IntersectClipRegion(const tools::Rectangle &rRect)
WallpaperStyle GetStyle() const
Definition: wall.cxx:213
void EnableMapMode(bool bEnable=true)
Definition: map.cxx:538
bool mbMap
Definition: outdev.hxx:373
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:42
bool IsEmpty() const
tools::Long Left() const
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
RasterOp
Definition: vclenum.hxx:194
tools::Long Bottom() const
bool mbBackground
Definition: outdev.hxx:375
SAL_DLLPRIVATE const BitmapEx * ImplGetCachedBitmap() const
Definition: wall.cxx:179
void DrawRect(const tools::Rectangle &rRect)
Definition: rect.cxx:51
void SetLineColor()
tools::Rectangle GetRect() const
Definition: wall.cxx:308
Wallpaper maBackground
Definition: outdev.hxx:366
Bitmap CreateDisplayBitmap(OutputDevice *pDisplay) const
bool IsDark() const
bool IsRect() const
Definition: wall.cxx:316
bool IsBright() const
const Color & GetColor() const
Definition: wall.cxx:198
tools::Long mnOutHeight
Definition: outdev.hxx:344
void SetFillColor()
tools::Long Width() const
const Color & GetLineColor() const
Definition: outdev.hxx:629
virtual Color GetBackgroundColor() const
Definition: wallpaper.cxx:37
Size GetOutputSizePixel() const
Definition: outdev.hxx:440
SAL_DLLPRIVATE void DrawColorWallpaper(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, const Wallpaper &rWallpaper)
Definition: wallpaper.cxx:83
bool IsTransparent() const
Definition: bitmapex.cxx:217
tools::Long Top() const
Size GetSize() const
Gradient GetGradient() const
Definition: wall.cxx:267
Bitmap GetBitmap(Color aTransparentReplaceColor) const
Definition: bitmapex.cxx:232
Point LogicToPixel(const Point &rLogicPt) const
Definition: map.cxx:828
VclPtr< VirtualDevice > mpAlphaVDev
Definition: outdev.hxx:329
BitmapEx GetBitmap() const
Definition: wall.cxx:241
bool IsGradient() const
Definition: wall.cxx:277
void Erase()
Definition: wallpaper.cxx:103
SAL_DLLPRIVATE void DrawBitmapWallpaper(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, const Wallpaper &rWallpaper)
Definition: wallpaper.cxx:135
virtual Color GetReadableFontColor(const Color &rFontColor, const Color &rBgColor) const
Definition: wallpaper.cxx:27
void AddAction(const rtl::Reference< MetaAction > &pAction)
Definition: gdimtf.cxx:566
WallpaperStyle
Definition: wall.hxx:32
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_WHITE
void SetRasterOp(RasterOp eRasterOp)
tools::Long Height() const
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_BLACK
RasterOp GetRasterOp() const
Definition: outdev.hxx:615
tools::Long mnOutWidth
Definition: outdev.hxx:343
bool IsBitmap() const
Definition: wall.cxx:249
tools::Long GetHeight() const
const Size & GetSizePixel() const
Definition: bitmapex.hxx:84
bool IsDeviceOutputNecessary() const
Definition: outdev.hxx:600
void Push(PushFlags nFlags=PushFlags::ALL)
Definition: outdevstate.cxx:60
void DrawGradient(const tools::Rectangle &rRect, const Gradient &rGradient)
tools::Long Right() const
SAL_DLLPRIVATE void ImplSetCachedBitmap(BitmapEx &rBmp) const
Definition: wall.cxx:171
const Color & GetFillColor() const
Definition: outdev.hxx:634
GDIMetaFile * mpMetaFile
Definition: outdev.hxx:317