LibreOffice Module vcl (master)  1
outdevstate.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 <sal/config.h>
21 #include <sal/log.hxx>
22 
23 #include <tools/debug.hxx>
24 #include <vcl/gdimtf.hxx>
25 #include <vcl/metaact.hxx>
26 #include <vcl/outdevstate.hxx>
27 #include <vcl/virdev.hxx>
28 #include <vcl/settings.hxx>
29 
30 #include <outdev.h>
31 #include <outdata.hxx>
32 #include <salgdi.hxx>
33 
35  : mbMapActive(false)
36  , meTextAlign(ALIGN_TOP)
37  , meRasterOp(RasterOp::OverPaint)
38  , mnTextLayoutMode(ComplexTextLayoutFlags::Default)
39  , meTextLanguage(0)
41 {
42 }
43 
45 
47 {
48  mpLineColor.reset();
49  mpFillColor.reset();
50  mpFont.reset();
51  mpTextColor.reset();
52  mpTextFillColor.reset();
53  mpTextLineColor.reset();
54  mpOverlineColor.reset();
55  mpMapMode.reset();
56  mpClipRegion.reset();
57  mpRefPoint.reset();
58 }
59 
61 {
62 
63  if ( mpMetaFile )
64  mpMetaFile->AddAction( new MetaPushAction( nFlags ) );
65 
66  maOutDevStateStack.emplace_back();
67  OutDevState& rState = maOutDevStateStack.back();
68 
69  rState.mnFlags = nFlags;
70 
71  if (nFlags & PushFlags::LINECOLOR && mbLineColor)
72  {
73  rState.mpLineColor = maLineColor;
74  }
75  if (nFlags & PushFlags::FILLCOLOR && mbFillColor)
76  {
77  rState.mpFillColor = maFillColor;
78  }
79  if ( nFlags & PushFlags::FONT )
80  rState.mpFont.reset( new vcl::Font( maFont ) );
81  if ( nFlags & PushFlags::TEXTCOLOR )
82  rState.mpTextColor = GetTextColor();
83  if (nFlags & PushFlags::TEXTFILLCOLOR && IsTextFillColor())
84  {
86  }
87  if (nFlags & PushFlags::TEXTLINECOLOR && IsTextLineColor())
88  {
90  }
91  if (nFlags & PushFlags::OVERLINECOLOR && IsOverlineColor())
92  {
94  }
95  if ( nFlags & PushFlags::TEXTALIGN )
96  rState.meTextAlign = GetTextAlign();
97  if( nFlags & PushFlags::TEXTLAYOUTMODE )
99  if( nFlags & PushFlags::TEXTLANGUAGE )
100  rState.meTextLanguage = GetDigitLanguage();
101  if ( nFlags & PushFlags::RASTEROP )
102  rState.meRasterOp = GetRasterOp();
103  if ( nFlags & PushFlags::MAPMODE )
104  {
105  rState.mpMapMode = maMapMode;
106  rState.mbMapActive = mbMap;
107  }
108  if (nFlags & PushFlags::CLIPREGION && mbClipRegion)
109  {
110  rState.mpClipRegion.reset( new vcl::Region( maRegion ) );
111  }
112  if (nFlags & PushFlags::REFPOINT && mbRefPoint)
113  {
114  rState.mpRefPoint = maRefPoint;
115  }
116 
117  if( mpAlphaVDev )
118  mpAlphaVDev->Push();
119 }
120 
122 {
123 
124  if( mpMetaFile )
125  mpMetaFile->AddAction( new MetaPopAction() );
126 
127  GDIMetaFile* pOldMetaFile = mpMetaFile;
128  mpMetaFile = nullptr;
129 
130  if ( maOutDevStateStack.empty() )
131  {
132  SAL_WARN( "vcl.gdi", "OutputDevice::Pop() without OutputDevice::Push()" );
133  return;
134  }
135  const OutDevState& rState = maOutDevStateStack.back();
136 
137  if( mpAlphaVDev )
138  mpAlphaVDev->Pop();
139 
140  if ( rState.mnFlags & PushFlags::LINECOLOR )
141  {
142  if ( rState.mpLineColor )
143  SetLineColor( *rState.mpLineColor );
144  else
145  SetLineColor();
146  }
147 
148  if ( rState.mnFlags & PushFlags::FILLCOLOR )
149  {
150  if ( rState.mpFillColor )
151  SetFillColor( *rState.mpFillColor );
152  else
153  SetFillColor();
154  }
155 
156  if ( rState.mnFlags & PushFlags::FONT )
157  SetFont( *rState.mpFont );
158 
159  if ( rState.mnFlags & PushFlags::TEXTCOLOR )
160  SetTextColor( *rState.mpTextColor );
161 
162  if ( rState.mnFlags & PushFlags::TEXTFILLCOLOR )
163  {
164  if ( rState.mpTextFillColor )
166  else
168  }
169 
170  if ( rState.mnFlags & PushFlags::TEXTLINECOLOR )
171  {
172  if ( rState.mpTextLineColor )
174  else
176  }
177 
178  if ( rState.mnFlags & PushFlags::OVERLINECOLOR )
179  {
180  if ( rState.mpOverlineColor )
182  else
184  }
185 
186  if ( rState.mnFlags & PushFlags::TEXTALIGN )
187  SetTextAlign( rState.meTextAlign );
188 
189  if( rState.mnFlags & PushFlags::TEXTLAYOUTMODE )
191 
192  if( rState.mnFlags & PushFlags::TEXTLANGUAGE )
194 
195  if ( rState.mnFlags & PushFlags::RASTEROP )
196  SetRasterOp( rState.meRasterOp );
197 
198  if ( rState.mnFlags & PushFlags::MAPMODE )
199  {
200  if ( rState.mpMapMode )
201  SetMapMode( *rState.mpMapMode );
202  else
203  SetMapMode();
204  mbMap = rState.mbMapActive;
205  }
206 
207  if ( rState.mnFlags & PushFlags::CLIPREGION )
208  SetDeviceClipRegion( rState.mpClipRegion.get() );
209 
210  if ( rState.mnFlags & PushFlags::REFPOINT )
211  {
212  if ( rState.mpRefPoint )
213  SetRefPoint( *rState.mpRefPoint );
214  else
215  SetRefPoint();
216  }
217 
218  maOutDevStateStack.pop_back();
219 
220  mpMetaFile = pOldMetaFile;
221 }
222 
224 {
225  return maOutDevStateStack.size();
226 }
227 
229 {
230  sal_uInt32 nCount = GetGCStackDepth();
231  while( nCount-- )
232  Pop();
233 }
234 
235 void OutputDevice::EnableOutput( bool bEnable )
236 {
237  mbOutput = bEnable;
238 
239  if( mpAlphaVDev )
240  mpAlphaVDev->EnableOutput( bEnable );
241 }
242 
244 {
245  if ( mnAntialiasing != nMode )
246  {
247  mnAntialiasing = nMode;
248  mbInitFont = true;
249 
250  if(mpGraphics)
251  {
253  }
254  }
255 
256  if( mpAlphaVDev )
257  mpAlphaVDev->SetAntialiasing( nMode );
258 }
259 
261 {
262 
263  mnDrawMode = nDrawMode;
264 
265  if( mpAlphaVDev )
266  mpAlphaVDev->SetDrawMode( nDrawMode );
267 }
268 
270 {
271  if( mpMetaFile )
272  mpMetaFile->AddAction( new MetaLayoutModeAction( nTextLayoutMode ) );
273 
274  mnTextLayoutMode = nTextLayoutMode;
275 
276  if( mpAlphaVDev )
277  mpAlphaVDev->SetLayoutMode( nTextLayoutMode );
278 }
279 
281 {
282  if( mpMetaFile )
283  mpMetaFile->AddAction( new MetaTextLanguageAction( eTextLanguage ) );
284 
285  meTextLanguage = eTextLanguage;
286 
287  if( mpAlphaVDev )
288  mpAlphaVDev->SetDigitLanguage( eTextLanguage );
289 }
290 
292 {
293 
294  if ( mpMetaFile )
295  mpMetaFile->AddAction( new MetaRasterOpAction( eRasterOp ) );
296 
297  if ( meRasterOp != eRasterOp )
298  {
299  meRasterOp = eRasterOp;
301 
302  if( mpGraphics || AcquireGraphics() )
304  }
305 
306  if( mpAlphaVDev )
307  mpAlphaVDev->SetRasterOp( eRasterOp );
308 }
309 
310 
312 {
313 
314  if ( mpMetaFile )
315  mpMetaFile->AddAction( new MetaFillColorAction( Color(), false ) );
316 
317  if ( mbFillColor )
318  {
319  mbInitFillColor = true;
320  mbFillColor = false;
322  }
323 
324  if( mpAlphaVDev )
326 }
327 
328 void OutputDevice::SetFillColor( const Color& rColor )
329 {
330 
331  Color aColor( rColor );
332 
336  {
337  if( !ImplIsColorTransparent( aColor ) )
338  {
340  {
341  aColor = COL_BLACK;
342  }
344  {
345  aColor = COL_WHITE;
346  }
348  {
349  const sal_uInt8 cLum = aColor.GetLuminance();
350  aColor = Color( cLum, cLum, cLum );
351  }
352  else if( mnDrawMode & DrawModeFlags::NoFill )
353  {
354  aColor = COL_TRANSPARENT;
355  }
357  {
359  }
360  }
361  }
362 
363  if ( mpMetaFile )
364  mpMetaFile->AddAction( new MetaFillColorAction( aColor, true ) );
365 
366  if ( ImplIsColorTransparent( aColor ) )
367  {
368  if ( mbFillColor )
369  {
370  mbInitFillColor = true;
371  mbFillColor = false;
373  }
374  }
375  else
376  {
377  if ( maFillColor != aColor )
378  {
379  mbInitFillColor = true;
380  mbFillColor = true;
381  maFillColor = aColor;
382  }
383  }
384 
385  if( mpAlphaVDev )
387 }
388 
390 {
391 
392  if ( mpMetaFile )
393  mpMetaFile->AddAction( new MetaLineColorAction( Color(), false ) );
394 
395  if ( mbLineColor )
396  {
397  mbInitLineColor = true;
398  mbLineColor = false;
400  }
401 
402  if( mpAlphaVDev )
404 }
405 
406 void OutputDevice::SetLineColor( const Color& rColor )
407 {
408 
409  Color aColor = ImplDrawModeToColor( rColor );
410 
411  if( mpMetaFile )
412  mpMetaFile->AddAction( new MetaLineColorAction( aColor, true ) );
413 
414  if( ImplIsColorTransparent( aColor ) )
415  {
416  if ( mbLineColor )
417  {
418  mbInitLineColor = true;
419  mbLineColor = false;
421  }
422  }
423  else
424  {
425  if( maLineColor != aColor )
426  {
427  mbInitLineColor = true;
428  mbLineColor = true;
429  maLineColor = aColor;
430  }
431  }
432 
433  if( mpAlphaVDev )
435 }
436 
438 {
439 
441  mbBackground = false;
442 
443  if( mpAlphaVDev )
445 }
446 
447 void OutputDevice::SetBackground( const Wallpaper& rBackground )
448 {
449 
450  maBackground = rBackground;
451 
452  if( rBackground.GetStyle() == WallpaperStyle::NONE )
453  mbBackground = false;
454  else
455  mbBackground = true;
456 
457  if( mpAlphaVDev )
458  mpAlphaVDev->SetBackground( rBackground );
459 }
460 
461 void OutputDevice::SetFont( const vcl::Font& rNewFont )
462 {
463 
464  vcl::Font aFont( rNewFont );
468  {
469  Color aTextColor( aFont.GetColor() );
470 
472  aTextColor = COL_BLACK;
474  aTextColor = COL_WHITE;
475  else if ( mnDrawMode & DrawModeFlags::GrayText )
476  {
477  const sal_uInt8 cLum = aTextColor.GetLuminance();
478  aTextColor = Color( cLum, cLum, cLum );
479  }
481  aTextColor = GetSettings().GetStyleSettings().GetFontColor();
482 
483  aFont.SetColor( aTextColor );
484 
485  bool bTransFill = aFont.IsTransparent();
486  if ( !bTransFill )
487  {
488  Color aTextFillColor( aFont.GetFillColor() );
489 
491  aTextFillColor = COL_BLACK;
493  aTextFillColor = COL_WHITE;
494  else if ( mnDrawMode & DrawModeFlags::GrayFill )
495  {
496  const sal_uInt8 cLum = aTextFillColor.GetLuminance();
497  aTextFillColor = Color( cLum, cLum, cLum );
498  }
500  aTextFillColor = GetSettings().GetStyleSettings().GetWindowColor();
501  else if ( mnDrawMode & DrawModeFlags::NoFill )
502  {
503  aTextFillColor = COL_TRANSPARENT;
504  }
505 
506  aFont.SetFillColor( aTextFillColor );
507  }
508  }
509 
510  if ( mpMetaFile )
511  {
512  mpMetaFile->AddAction( new MetaFontAction( aFont ) );
513  // the color and alignment actions don't belong here
514  // TODO: get rid of them without breaking anything...
515  mpMetaFile->AddAction( new MetaTextAlignAction( aFont.GetAlignment() ) );
516  mpMetaFile->AddAction( new MetaTextFillColorAction( aFont.GetFillColor(), !aFont.IsTransparent() ) );
517  }
518 
519  if ( !maFont.IsSameInstance( aFont ) )
520  {
521  // Optimization MT/HDU: COL_TRANSPARENT means SetFont should ignore the font color,
522  // because SetTextColor() is used for this.
523  // #i28759# maTextColor might have been changed behind our back, commit then, too.
524  if( aFont.GetColor() != COL_TRANSPARENT
525  && (aFont.GetColor() != maFont.GetColor() || aFont.GetColor() != maTextColor ) )
526  {
527  maTextColor = aFont.GetColor();
528  mbInitTextColor = true;
529  if( mpMetaFile )
530  mpMetaFile->AddAction( new MetaTextColorAction( aFont.GetColor() ) );
531  }
532  maFont = aFont;
533  mbNewFont = true;
534 
535  if( mpAlphaVDev )
536  {
537  // #i30463#
538  // Since SetFont might change the text color, apply that only
539  // selectively to alpha vdev (which normally paints opaque text
540  // with COL_BLACK)
541  if( aFont.GetColor() != COL_TRANSPARENT )
542  {
544  aFont.SetColor( COL_TRANSPARENT );
545  }
546 
547  mpAlphaVDev->SetFont( aFont );
548  }
549  }
550 }
551 
552 
554 {
556 
557  if( mbLineColor )
558  {
559  if( RasterOp::N0 == meRasterOp )
561  else if( RasterOp::N1 == meRasterOp )
563  else if( RasterOp::Invert == meRasterOp )
565  else
567  }
568  else
570 
571  mbInitLineColor = false;
572 }
573 
574 
576 {
578 
579  if( mbFillColor )
580  {
581  if( RasterOp::N0 == meRasterOp )
583  else if( RasterOp::N1 == meRasterOp )
585  else if( RasterOp::Invert == meRasterOp )
587  else
589  }
590  else
592 
593  mbInitFillColor = false;
594 }
595 
597 {
599 
600  mbNewFont = true;
601  mbInitFont = true;
602 
603  mpFontInstance.clear();
604  mpDeviceFontList.reset();
605  mpDeviceFontSizeList.reset();
606 }
607 
608 
609 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void EnableOutput(bool bEnable=true)
const Color & GetTextColor() const
Definition: outdev.hxx:1127
void SetDigitLanguage(LanguageType)
void SetFillColor(const Color &)
Definition: font/font.cxx:88
std::optional< Color > mpTextColor
Definition: outdevstate.hxx:90
constexpr::Color COL_BLACK(0x00, 0x00, 0x00)
void SetAntialiasing(AntialiasingFlags nMode)
sal_uInt32 GetGCStackDepth() const
bool mbOutput
Definition: outdev.hxx:377
Color maTextColor
Definition: outdev.hxx:363
DrawModeFlags
Definition: outdev.hxx:198
SAL_DLLPRIVATE void SetDeviceClipRegion(const vcl::Region *pRegion)
const Color & GetTextLineColor() const
Definition: outdev.hxx:1136
DrawModeFlags mnDrawMode
Definition: outdev.hxx:353
Color maLineColor
Definition: outdev.hxx:360
const StyleSettings & GetStyleSettings() const
TextAlign GetTextAlign() const
Definition: outdev.hxx:1145
sal_uInt8 GetLuminance() const
bool IsTextLineColor() const
Definition: outdev.hxx:1137
vcl::Region maRegion
Definition: outdev.hxx:359
ComplexTextLayoutFlags mnTextLayoutMode
Definition: outdevstate.hxx:97
ComplexTextLayoutFlags GetLayoutMode() const
Definition: outdev.hxx:610
void SetTextFillColor()
Definition: text.cxx:700
SAL_DLLPRIVATE Color ImplDrawModeToColor(const Color &rColor) const
Definition: transparent.cxx:79
void SetLayoutMode(ComplexTextLayoutFlags nTextLayoutMode)
std::unique_ptr< ImplDeviceFontSizeList > mpDeviceFontSizeList
Definition: outdev.hxx:322
WallpaperStyle GetStyle() const
Definition: wall.cxx:219
bool ImplIsColorTransparent(Color aColor)
Definition: outdata.hxx:25
bool mbMap
Definition: outdev.hxx:374
void SetMapMode()
Definition: map.cxx:655
FontAlign GetAlignment() const
Definition: font/font.cxx:668
NONE
MapMode maMapMode
Definition: outdev.hxx:369
void SetDrawMode(DrawModeFlags nDrawMode)
std::optional< Color > mpLineColor
Definition: outdevstate.hxx:87
const Color & GetOverlineColor() const
Definition: outdev.hxx:1141
FuncFlags mnFlags
Color GetTextFillColor() const
Definition: text.cxx:758
SAL_DLLPRIVATE void InitLineColor()
constexpr::Color COL_TRANSPARENT(0xFF, 0xFF, 0xFF, 0xFF)
void SetBackground()
PushFlags mnFlags
Definition: outdevstate.hxx:99
RasterOp
Definition: vclenum.hxx:194
virtual void SetROPLineColor(SalROPColor nROPColor)=0
int nCount
AntialiasingFlags mnAntialiasing
Definition: outdev.hxx:371
bool mbBackground
Definition: outdev.hxx:376
PushFlags
Definition: outdevstate.hxx:38
LanguageType meTextLanguage
Definition: outdevstate.hxx:98
void ClearStack()
Color maFillColor
Definition: outdev.hxx:361
std::optional< Color > mpFillColor
Definition: outdevstate.hxx:88
void SetTextLineColor()
Definition: textline.cxx:800
std::unique_ptr< vcl::Font > mpFont
Definition: outdevstate.hxx:89
SalGraphics * mpGraphics
Graphics context to draw on.
Definition: outdev.hxx:314
std::vector< OutDevState > maOutDevStateStack
Definition: outdev.hxx:323
bool IsTextFillColor() const
Definition: outdev.hxx:1132
virtual void SetFillColor()=0
void SetLineColor()
SAL_DLLPRIVATE void InitFillColor()
void SetRefPoint()
Definition: outdev.cxx:278
Wallpaper maBackground
Definition: outdev.hxx:367
virtual void SetLineColor()=0
std::optional< Color > mpOverlineColor
Definition: outdevstate.hxx:93
ComplexTextLayoutFlags
Definition: outdevstate.hxx:66
virtual bool AcquireGraphics() const =0
Acquire a graphics device that the output device uses to draw on.
std::unique_ptr< ImplDeviceFontList > mpDeviceFontList
Definition: outdev.hxx:321
std::unique_ptr< vcl::Region > mpClipRegion
Definition: outdevstate.hxx:86
bool mbInitLineColor
Definition: outdev.hxx:382
void SetFillColor()
bool mbNewFont
Definition: outdev.hxx:388
AntialiasingFlags
Definition: outdev.hxx:229
const Color & GetFontColor() const
void SetTextColor(const Color &rColor)
Definition: text.cxx:665
TextAlign meTextAlign
Definition: outdevstate.hxx:95
vcl::Font maFont
Definition: outdev.hxx:362
bool mbLineColor
Definition: outdev.hxx:380
void SetOverlineColor()
Definition: textline.cxx:849
RasterOp meRasterOp
Definition: outdev.hxx:366
const AllSettings & GetSettings() const
Definition: outdev.hxx:418
bool mbInitTextColor
Definition: outdev.hxx:385
const Color & GetFillColor() const
Definition: font/font.cxx:665
void ReleaseFonts()
Definition: salgdi.hxx:127
bool mbRefPoint
Definition: outdev.hxx:391
void SetColor(const Color &)
Definition: font/font.cxx:80
virtual void SetXORMode(bool bSet, bool bInvertOnly)=0
bool mbFillColor
Definition: outdev.hxx:381
VclPtr< VirtualDevice > mpAlphaVDev
Definition: outdev.hxx:329
ALIGN_TOP
RasterOp meRasterOp
Definition: outdevstate.hxx:96
const Color & GetColor() const
Definition: font/font.cxx:664
bool mbClipRegion
Definition: outdev.hxx:375
std::optional< MapMode > mpMapMode
Definition: outdevstate.hxx:84
unsigned char sal_uInt8
void SetFont(const vcl::Font &rNewFont)
void AddAction(const rtl::Reference< MetaAction > &pAction)
Definition: gdimtf.cxx:566
LanguageType GetDigitLanguage() const
Definition: outdev.hxx:613
virtual void SetROPFillColor(SalROPColor nROPColor)=0
bool IsTransparent() const
Definition: font/font.cxx:666
void SetRasterOp(RasterOp eRasterOp)
std::optional< Color > mpTextFillColor
Definition: outdevstate.hxx:91
void setAntiAliasB2DDraw(bool bNew)
Definition: salgdi.hxx:80
const Color & GetWindowColor() const
bool mbInitFont
Definition: outdev.hxx:384
RasterOp GetRasterOp() const
Definition: outdev.hxx:616
constexpr::Color COL_WHITE(0xFF, 0xFF, 0xFF)
rtl::Reference< LogicalFontInstance > mpFontInstance
Definition: outdev.hxx:318
std::optional< Color > mpTextLineColor
Definition: outdevstate.hxx:92
bool mbInitFillColor
Definition: outdev.hxx:383
bool IsSameInstance(const Font &) const
Definition: font/font.cxx:715
ComplexTextLayoutFlags mnTextLayoutMode
Definition: outdev.hxx:354
#define SAL_WARN(area, stream)
#define DBG_TESTSOLARMUTEX()
bool IsOverlineColor() const
Definition: outdev.hxx:1142
void Push(PushFlags nFlags=PushFlags::ALL)
Definition: outdevstate.cxx:60
Point maRefPoint
Definition: outdev.hxx:370
std::optional< Point > mpRefPoint
Definition: outdevstate.hxx:94
virtual void ImplReleaseFonts()
void SetTextAlign(TextAlign eAlign)
Definition: text.cxx:766
GDIMetaFile * mpMetaFile
Definition: outdev.hxx:317
bool mbMapActive
Definition: outdevstate.hxx:85
LanguageType meTextLanguage
Definition: outdev.hxx:372