LibreOffice Module vcl (master)  1
paint.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 <config_features.h>
21 #include <vcl/gdimtf.hxx>
22 #include <vcl/window.hxx>
23 #include <vcl/virdev.hxx>
24 #include <vcl/cursor.hxx>
25 #include <vcl/settings.hxx>
26 #include <vcl/syswin.hxx>
27 
28 #include <sal/types.h>
29 #include <sal/log.hxx>
30 
31 #include <window.h>
32 #include <salgdi.hxx>
33 #include <salframe.hxx>
34 #include <svdata.hxx>
35 #include <comphelper/lok.hxx>
37 #if HAVE_FEATURE_OPENGL
39 #endif
40 
41 // PaintBufferGuard
42 
43 namespace vcl
44 {
46  : mpFrameData(pFrameData),
47  m_pWindow(pWindow),
48  mbBackground(false),
49  mnOutOffX(0),
50  mnOutOffY(0)
51 {
52  if (!pFrameData->mpBuffer)
53  return;
54 
55  // transfer various settings
56  // FIXME: this must disappear as we move to RenderContext only,
57  // the painting must become state-less, so that no actual
58  // vcl::Window setting affects this
59  mbBackground = pFrameData->mpBuffer->IsBackground();
60  if (pWindow->IsBackground())
61  {
62  maBackground = pFrameData->mpBuffer->GetBackground();
63  pFrameData->mpBuffer->SetBackground(pWindow->GetBackground());
64  }
65  //else
66  //SAL_WARN("vcl.window", "the root of the double-buffering hierarchy should not have a transparent background");
67 
70  nFlags |= vcl::PushFlags::FILLCOLOR;
71  nFlags |= vcl::PushFlags::FONT;
72  nFlags |= vcl::PushFlags::LINECOLOR;
73  nFlags |= vcl::PushFlags::MAPMODE;
74  maSettings = pFrameData->mpBuffer->GetSettings();
75  nFlags |= vcl::PushFlags::REFPOINT;
76  nFlags |= vcl::PushFlags::TEXTCOLOR;
80  nFlags |= vcl::PushFlags::TEXTALIGN;
81  nFlags |= vcl::PushFlags::RASTEROP;
84  pFrameData->mpBuffer->Push(nFlags);
85  auto& rDev = *pWindow->GetOutDev();
86  pFrameData->mpBuffer->SetClipRegion(rDev.GetClipRegion());
87  pFrameData->mpBuffer->SetFillColor(rDev.GetFillColor());
88  pFrameData->mpBuffer->SetFont(pWindow->GetFont());
89  pFrameData->mpBuffer->SetLineColor(rDev.GetLineColor());
90  pFrameData->mpBuffer->SetMapMode(pWindow->GetMapMode());
91  pFrameData->mpBuffer->SetRefPoint(rDev.GetRefPoint());
92  pFrameData->mpBuffer->SetSettings(pWindow->GetSettings());
93  pFrameData->mpBuffer->SetTextColor(pWindow->GetTextColor());
94  pFrameData->mpBuffer->SetTextLineColor(pWindow->GetTextLineColor());
95  pFrameData->mpBuffer->SetOverlineColor(pWindow->GetOverlineColor());
96  pFrameData->mpBuffer->SetTextFillColor(pWindow->GetTextFillColor());
97  pFrameData->mpBuffer->SetTextAlign(pWindow->GetTextAlign());
98  pFrameData->mpBuffer->SetRasterOp(rDev.GetRasterOp());
99  pFrameData->mpBuffer->SetLayoutMode(rDev.GetLayoutMode());
100  pFrameData->mpBuffer->SetDigitLanguage(rDev.GetDigitLanguage());
101 
102  mnOutOffX = pFrameData->mpBuffer->GetOutOffXPixel();
103  mnOutOffY = pFrameData->mpBuffer->GetOutOffYPixel();
104  pFrameData->mpBuffer->SetOutOffXPixel(pWindow->GetOutOffXPixel());
105  pFrameData->mpBuffer->SetOutOffYPixel(pWindow->GetOutOffYPixel());
106  pFrameData->mpBuffer->EnableRTL(pWindow->IsRTLEnabled());
107 }
108 
109 PaintBufferGuard::~PaintBufferGuard() COVERITY_NOEXCEPT_FALSE
110 {
111  if (!mpFrameData->mpBuffer)
112  return;
113 
114  if (!m_aPaintRect.IsEmpty())
115  {
116  // copy the buffer content to the actual window
117  // export VCL_DOUBLEBUFFERING_AVOID_PAINT=1 to see where we are
118  // painting directly instead of using Invalidate()
119  // [ie. everything you can see was painted directly to the
120  // window either above or in eg. an event handler]
121  if (!getenv("VCL_DOUBLEBUFFERING_AVOID_PAINT"))
122  {
123  // Make sure that the +1 value GetSize() adds to the size is in pixels.
124  Size aPaintRectSize;
125  if (m_pWindow->GetMapMode().GetMapUnit() == MapUnit::MapPixel)
126  {
127  aPaintRectSize = m_aPaintRect.GetSize();
128  }
129  else
130  {
132  aPaintRectSize = m_pWindow->PixelToLogic(aRectanglePixel.GetSize());
133  }
134 
135  m_pWindow->GetOutDev()->DrawOutDev(m_aPaintRect.TopLeft(), aPaintRectSize, m_aPaintRect.TopLeft(), aPaintRectSize, *mpFrameData->mpBuffer);
136  }
137  }
138 
139  // Restore buffer state.
142 
145  if (mbBackground)
147  else
149 }
150 
152 {
153  m_aPaintRect = rRectangle;
154 }
155 
157 {
158  if (mpFrameData->mpBuffer)
159  return mpFrameData->mpBuffer;
160  else
161  return m_pWindow->GetOutDev();
162 }
163 }
164 
166 {
167 private:
169  std::unique_ptr<vcl::Region> m_pChildRegion;
174  bool m_bPop : 1;
177 public:
178  PaintHelper(vcl::Window* pWindow, ImplPaintFlags nPaintFlags);
179  void SetPop()
180  {
181  m_bPop = true;
182  }
183  void SetPaintRect(const tools::Rectangle& rRect)
184  {
185  m_aPaintRect = rRect;
186  }
188  {
189  m_aSelectionRect = rRect;
190  }
191  void SetRestoreCursor(bool bRestoreCursor)
192  {
193  m_bRestoreCursor = bRestoreCursor;
194  }
195  bool GetRestoreCursor() const
196  {
197  return m_bRestoreCursor;
198  }
200  {
201  return m_nPaintFlags;
202  }
204  {
205  return m_aPaintRegion;
206  }
207  void DoPaint(const vcl::Region* pRegion);
208 
210  void StartBufferedPaint();
211 
213  void PaintBuffer();
214 
215  ~PaintHelper();
216 };
217 
219  : m_pWindow(pWindow)
220  , m_nPaintFlags(nPaintFlags)
221  , m_bPop(false)
222  , m_bRestoreCursor(false)
223  , m_bStartedBufferedPaint(false)
224 {
225 }
226 
228 {
229  ImplFrameData* pFrameData = m_pWindow->mpWindowImpl->mpFrameData;
230  assert(!pFrameData->mbInBufferedPaint);
231 
232  pFrameData->mbInBufferedPaint = true;
233  pFrameData->maBufferedRect = tools::Rectangle();
235 }
236 
238 {
239  ImplFrameData* pFrameData = m_pWindow->mpWindowImpl->mpFrameData;
240  assert(pFrameData->mbInBufferedPaint);
241  assert(m_bStartedBufferedPaint);
242 
243  vcl::PaintBufferGuard aGuard(pFrameData, m_pWindow);
244  aGuard.SetPaintRect(pFrameData->maBufferedRect);
245 }
246 
247 void PaintHelper::DoPaint(const vcl::Region* pRegion)
248 {
249  WindowImpl* pWindowImpl = m_pWindow->ImplGetWindowImpl();
250 
251  vcl::Region& rWinChildClipRegion = m_pWindow->ImplGetWinChildClipRegion();
252  ImplFrameData* pFrameData = m_pWindow->mpWindowImpl->mpFrameData;
253  if (pWindowImpl->mnPaintFlags & ImplPaintFlags::PaintAll || pFrameData->mbInBufferedPaint)
254  {
255  pWindowImpl->maInvalidateRegion = rWinChildClipRegion;
256  }
257  else
258  {
259  if (pRegion)
260  pWindowImpl->maInvalidateRegion.Union( *pRegion );
261 
262  if (pWindowImpl->mpWinData && pWindowImpl->mbTrackVisible)
263  /* #98602# need to repaint all children within the
264  * tracking rectangle, so the following invert
265  * operation takes places without traces of the previous
266  * one.
267  */
268  pWindowImpl->maInvalidateRegion.Union(*pWindowImpl->mpWinData->mpTrackRect);
269 
271  m_pChildRegion.reset( new vcl::Region(pWindowImpl->maInvalidateRegion) );
272  pWindowImpl->maInvalidateRegion.Intersect(rWinChildClipRegion);
273  }
274  pWindowImpl->mnPaintFlags = ImplPaintFlags::NONE;
275  if (pWindowImpl->maInvalidateRegion.IsEmpty())
276  return;
277 
278 #if HAVE_FEATURE_OPENGL
279  VCL_GL_INFO("PaintHelper::DoPaint on " <<
280  typeid( *m_pWindow ).name() << " '" << m_pWindow->GetText() << "' begin");
281 #endif
282  // double-buffering: setup the buffer if it does not exist
283  if (!pFrameData->mbInBufferedPaint && m_pWindow->SupportsDoubleBuffering())
285 
286  // double-buffering: if this window does not support double-buffering,
287  // but we are in the middle of double-buffered paint, we might be
288  // losing information
289  if (pFrameData->mbInBufferedPaint && !m_pWindow->SupportsDoubleBuffering())
290  SAL_WARN("vcl.window", "non-double buffered window in the double-buffered hierarchy, painting directly: " << typeid(*m_pWindow.get()).name());
291 
293  {
294  // double-buffering
295  vcl::PaintBufferGuard g(pFrameData, m_pWindow);
296  m_pWindow->ApplySettings(*pFrameData->mpBuffer);
297 
298  m_pWindow->PushPaintHelper(this, *pFrameData->mpBuffer);
299  m_pWindow->Paint(*pFrameData->mpBuffer, m_aPaintRect);
300  pFrameData->maBufferedRect.Union(m_aPaintRect);
301  }
302  else
303  {
304  // direct painting
305  Wallpaper aBackground = m_pWindow->GetBackground();
307  // Restore bitmap background if it was lost.
308  if (aBackground.IsBitmap() && !m_pWindow->GetBackground().IsBitmap())
309  {
310  m_pWindow->SetBackground(aBackground);
311  }
314  }
315 #if HAVE_FEATURE_OPENGL
316  VCL_GL_INFO("PaintHelper::DoPaint end on " <<
317  typeid( *m_pWindow ).name() << " '" << m_pWindow->GetText() << "'");
318 #endif
319 }
320 
321 namespace vcl
322 {
323 
325  const tools::Rectangle& rRect, sal_uInt16 nHighlight,
326  bool bChecked, bool bDrawBorder, bool bDrawExtBorderOnly,
327  Color* pSelectionTextColor, tools::Long nCornerRadius, Color const * pPaintColor)
328 {
329  if (rRect.IsEmpty())
330  return;
331 
332  bool bRoundEdges = nCornerRadius > 0;
333 
334  const StyleSettings& rStyles = rRenderContext.GetSettings().GetStyleSettings();
335 
336  // colors used for item highlighting
337  Color aSelectionBorderColor(pPaintColor ? *pPaintColor : rStyles.GetHighlightColor());
338  Color aSelectionFillColor(aSelectionBorderColor);
339 
340  bool bDark = rStyles.GetFaceColor().IsDark();
341  bool bBright = ( rStyles.GetFaceColor() == COL_WHITE );
342 
343  int c1 = aSelectionBorderColor.GetLuminance();
344  int c2 = rWindow.GetBackgroundColor().GetLuminance();
345 
346  if (!bDark && !bBright && std::abs(c2 - c1) < (pPaintColor ? 40 : 75))
347  {
348  // contrast too low
349  sal_uInt16 h, s, b;
350  aSelectionFillColor.RGBtoHSB( h, s, b );
351  if( b > 50 ) b -= 40;
352  else b += 40;
353  aSelectionFillColor = Color::HSBtoRGB( h, s, b );
354  aSelectionBorderColor = aSelectionFillColor;
355  }
356 
357  if (bRoundEdges)
358  {
359  if (aSelectionBorderColor.IsDark())
360  aSelectionBorderColor.IncreaseLuminance(128);
361  else
362  aSelectionBorderColor.DecreaseLuminance(128);
363  }
364 
365  tools::Rectangle aRect(rRect);
366  if (bDrawExtBorderOnly)
367  {
368  aRect.AdjustLeft( -1 );
369  aRect.AdjustTop( -1 );
370  aRect.AdjustRight(1 );
371  aRect.AdjustBottom(1 );
372  }
374 
375  if (bDrawBorder)
376  rRenderContext.SetLineColor(bDark ? COL_WHITE : (bBright ? COL_BLACK : aSelectionBorderColor));
377  else
378  rRenderContext.SetLineColor();
379 
380  sal_uInt16 nPercent = 0;
381  if (!nHighlight)
382  {
383  if (bDark)
384  aSelectionFillColor = COL_BLACK;
385  else
386  nPercent = 80; // just checked (light)
387  }
388  else
389  {
390  if (bChecked && nHighlight == 2)
391  {
392  if (bDark)
393  aSelectionFillColor = COL_LIGHTGRAY;
394  else if (bBright)
395  {
396  aSelectionFillColor = COL_BLACK;
397  rRenderContext.SetLineColor(COL_BLACK);
398  nPercent = 0;
399  }
400  else
401  nPercent = bRoundEdges ? 40 : 20; // selected, pressed or checked ( very dark )
402  }
403  else if (bChecked || nHighlight == 1)
404  {
405  if (bDark)
406  aSelectionFillColor = COL_GRAY;
407  else if (bBright)
408  {
409  aSelectionFillColor = COL_BLACK;
410  rRenderContext.SetLineColor(COL_BLACK);
411  nPercent = 0;
412  }
413  else
414  nPercent = bRoundEdges ? 60 : 35; // selected, pressed or checked ( very dark )
415  }
416  else
417  {
418  if (bDark)
419  aSelectionFillColor = COL_LIGHTGRAY;
420  else if (bBright)
421  {
422  aSelectionFillColor = COL_BLACK;
423  rRenderContext.SetLineColor(COL_BLACK);
424  if (nHighlight == 3)
425  nPercent = 80;
426  else
427  nPercent = 0;
428  }
429  else
430  nPercent = 70; // selected ( dark )
431  }
432  }
433 
434  if (bDark && bDrawExtBorderOnly)
435  {
436  rRenderContext.SetFillColor();
437  if (pSelectionTextColor)
438  *pSelectionTextColor = rStyles.GetHighlightTextColor();
439  }
440  else
441  {
442  rRenderContext.SetFillColor(aSelectionFillColor);
443  if (pSelectionTextColor)
444  {
445  Color aTextColor = rWindow.IsControlBackground() ? rWindow.GetControlForeground() : rStyles.GetButtonTextColor();
446  Color aHLTextColor = rStyles.GetHighlightTextColor();
447  int nTextDiff = std::abs(aSelectionFillColor.GetLuminance() - aTextColor.GetLuminance());
448  int nHLDiff = std::abs(aSelectionFillColor.GetLuminance() - aHLTextColor.GetLuminance());
449  *pSelectionTextColor = (nHLDiff >= nTextDiff) ? aHLTextColor : aTextColor;
450  }
451  }
452 
453  if (bDark)
454  {
455  rRenderContext.DrawRect(aRect);
456  }
457  else
458  {
459  if (bRoundEdges)
460  {
461  tools::Polygon aPoly(aRect, nCornerRadius, nCornerRadius);
462  tools::PolyPolygon aPolyPoly(aPoly);
463  rRenderContext.DrawTransparent(aPolyPoly, nPercent);
464  }
465  else
466  {
467  tools::Polygon aPoly(aRect);
468  tools::PolyPolygon aPolyPoly(aPoly);
469  rRenderContext.DrawTransparent(aPolyPoly, nPercent);
470  }
471  }
472 
473  rRenderContext.Pop(); // LINECOLOR | FILLCOLOR
474 }
475 
477 {
478  pHelper->SetPop();
479 
480  if ( mpWindowImpl->mpCursor )
481  pHelper->SetRestoreCursor(mpWindowImpl->mpCursor->ImplSuspend());
482 
483  GetOutDev()->mbInitClipRegion = true;
484  mpWindowImpl->mbInPaint = true;
485 
486  // restore Paint-Region
487  vcl::Region &rPaintRegion = pHelper->GetPaintRegion();
488  rPaintRegion = mpWindowImpl->maInvalidateRegion;
489  tools::Rectangle aPaintRect = rPaintRegion.GetBoundRect();
490 
491  // RTL: re-mirror paint rect and region at this window
492  if (GetOutDev()->ImplIsAntiparallel())
493  {
494  rRenderContext.ReMirror(aPaintRect);
495  rRenderContext.ReMirror(rPaintRegion);
496  }
497  aPaintRect = GetOutDev()->ImplDevicePixelToLogic(aPaintRect);
498  mpWindowImpl->mpPaintRegion = &rPaintRegion;
499  mpWindowImpl->maInvalidateRegion.SetEmpty();
500 
501  if ((pHelper->GetPaintFlags() & ImplPaintFlags::Erase) && rRenderContext.IsBackground())
502  {
503  if (rRenderContext.IsClipRegion())
504  {
505  vcl::Region aOldRegion = rRenderContext.GetClipRegion();
506  rRenderContext.SetClipRegion();
507  Erase(rRenderContext);
508  rRenderContext.SetClipRegion(aOldRegion);
509  }
510  else
511  Erase(rRenderContext);
512  }
513 
514  // #98943# trigger drawing of toolbox selection after all children are painted
515  if (mpWindowImpl->mbDrawSelectionBackground)
516  pHelper->SetSelectionRect(aPaintRect);
517  pHelper->SetPaintRect(aPaintRect);
518 }
519 
521 {
522  if (mpWindowImpl->mpWinData)
523  {
524  if (mpWindowImpl->mbFocusVisible)
525  ImplInvertFocus(*mpWindowImpl->mpWinData->mpFocusRect);
526  }
527  mpWindowImpl->mbInPaint = false;
528  GetOutDev()->mbInitClipRegion = true;
529  mpWindowImpl->mpPaintRegion = nullptr;
530  if (mpWindowImpl->mpCursor)
531  mpWindowImpl->mpCursor->ImplResume(pHelper->GetRestoreCursor());
532 }
533 
534 } /* namespace vcl */
535 
537 {
538  WindowImpl* pWindowImpl = m_pWindow->ImplGetWindowImpl();
539  if (m_bPop)
540  {
541  m_pWindow->PopPaintHelper(this);
542  }
543 
544  ImplFrameData* pFrameData = m_pWindow->mpWindowImpl->mpFrameData;
546  {
547  // Paint from the bottom child window and frontward.
548  vcl::Window* pTempWindow = pWindowImpl->mpLastChild;
549  while (pTempWindow)
550  {
551  if (pTempWindow->mpWindowImpl->mbVisible)
552  pTempWindow->ImplCallPaint(m_pChildRegion.get(), m_nPaintFlags);
553  pTempWindow = pTempWindow->mpWindowImpl->mpPrev;
554  }
555  }
556 
557  if ( pWindowImpl->mpWinData && pWindowImpl->mbTrackVisible && (pWindowImpl->mpWinData->mnTrackFlags & ShowTrackFlags::TrackWindow) )
558  /* #98602# need to invert the tracking rect AFTER
559  * the children have painted
560  */
561  m_pWindow->InvertTracking( *pWindowImpl->mpWinData->mpTrackRect, pWindowImpl->mpWinData->mnTrackFlags );
562 
563  // double-buffering: paint in case we created the buffer, the children are
564  // already painted inside
565  if (m_bStartedBufferedPaint && pFrameData->mbInBufferedPaint)
566  {
567  PaintBuffer();
568  pFrameData->mbInBufferedPaint = false;
569  pFrameData->maBufferedRect = tools::Rectangle();
570  }
571 
572  // #98943# draw toolbox selection
573  if( !m_aSelectionRect.IsEmpty() )
575 }
576 
577 namespace vcl {
578 
579 void Window::ImplCallPaint(const vcl::Region* pRegion, ImplPaintFlags nPaintFlags)
580 {
581  // call PrePaint. PrePaint may add to the invalidate region as well as
582  // other parameters used below.
583  PrePaint(*GetOutDev());
584 
585  mpWindowImpl->mbPaintFrame = false;
586 
587  if (nPaintFlags & ImplPaintFlags::PaintAllChildren)
588  mpWindowImpl->mnPaintFlags |= ImplPaintFlags::Paint | ImplPaintFlags::PaintAllChildren | (nPaintFlags & ImplPaintFlags::PaintAll);
589  if (nPaintFlags & ImplPaintFlags::PaintChildren)
591  if (nPaintFlags & ImplPaintFlags::Erase)
592  mpWindowImpl->mnPaintFlags |= ImplPaintFlags::Erase;
593  if (nPaintFlags & ImplPaintFlags::CheckRtl)
594  mpWindowImpl->mnPaintFlags |= ImplPaintFlags::CheckRtl;
595  if (!mpWindowImpl->mpFirstChild)
596  mpWindowImpl->mnPaintFlags &= ~ImplPaintFlags::PaintAllChildren;
597 
598  // If tiled rendering is used, windows are only invalidated, never painted to.
599  if (mpWindowImpl->mbPaintDisabled || comphelper::LibreOfficeKit::isActive())
600  {
601  if (mpWindowImpl->mnPaintFlags & ImplPaintFlags::PaintAll)
603  else if ( pRegion )
605 
606  // call PostPaint before returning
607  PostPaint(*GetOutDev());
608 
609  return;
610  }
611 
612  nPaintFlags = mpWindowImpl->mnPaintFlags & ~ImplPaintFlags::Paint;
613 
614  PaintHelper aHelper(this, nPaintFlags);
615 
616  if (mpWindowImpl->mnPaintFlags & ImplPaintFlags::Paint)
617  aHelper.DoPaint(pRegion);
618  else
619  mpWindowImpl->mnPaintFlags = ImplPaintFlags::NONE;
620 
621  // call PostPaint
622  PostPaint(*GetOutDev());
623 }
624 
626 {
627  if (!mpWindowImpl)
628  return;
629 
630  // emit overlapping windows first
631  vcl::Window* pTempWindow = mpWindowImpl->mpFirstOverlap;
632  while ( pTempWindow )
633  {
634  if ( pTempWindow->mpWindowImpl->mbReallyVisible )
635  pTempWindow->ImplCallOverlapPaint();
636  pTempWindow = pTempWindow->mpWindowImpl->mpNext;
637  }
638 
639  // only then ourself
641  {
642  // RTL: notify ImplCallPaint to check for re-mirroring
643  // because we were called from the Sal layer
644  ImplCallPaint(nullptr, mpWindowImpl->mnPaintFlags /*| ImplPaintFlags::CheckRtl */);
645  }
646 }
647 
648 IMPL_LINK_NOARG(Window, ImplHandlePaintHdl, Timer *, void)
649 {
650  comphelper::ProfileZone aZone("VCL idle re-paint");
651 
652  // save paint events until layout is done
653  if (IsSystemWindow() && static_cast<const SystemWindow*>(this)->hasPendingLayout())
654  {
655  mpWindowImpl->mpFrameData->maPaintIdle.Start();
656  return;
657  }
658 
659  // save paint events until resizing or initial sizing done
660  if (mpWindowImpl->mbFrame &&
661  mpWindowImpl->mpFrameData->maResizeIdle.IsActive())
662  {
663  mpWindowImpl->mpFrameData->maPaintIdle.Start();
664  }
665  else if ( mpWindowImpl->mbReallyVisible )
666  {
667  ImplCallOverlapPaint();
669  mpWindowImpl->mpFrameData->maPaintIdle.IsActive())
670  mpWindowImpl->mpFrameData->maPaintIdle.Stop();
671  }
672 }
673 
674 IMPL_LINK_NOARG(Window, ImplHandleResizeTimerHdl, Timer *, void)
675 {
676  comphelper::ProfileZone aZone("VCL idle resize");
677 
678  if( mpWindowImpl->mbReallyVisible )
679  {
680  ImplCallResize();
681  if( mpWindowImpl->mpFrameData->maPaintIdle.IsActive() )
682  {
683  mpWindowImpl->mpFrameData->maPaintIdle.Stop();
684  mpWindowImpl->mpFrameData->maPaintIdle.Invoke( nullptr );
685  }
686  }
687 }
688 
690 {
691  // set PAINTCHILDREN for all parent windows till the first OverlapWindow
692  if ( !ImplIsOverlapWindow() )
693  {
694  vcl::Window* pTempWindow = this;
696  do
697  {
698  pTempWindow = pTempWindow->ImplGetParent();
699  if ( pTempWindow->mpWindowImpl->mnPaintFlags & ImplPaintFlags::PaintChildren )
700  break;
701  pTempWindow->mpWindowImpl->mnPaintFlags |= ImplPaintFlags::PaintChildren | nTranspPaint;
702  if( ! pTempWindow->IsPaintTransparent() )
703  nTranspPaint = ImplPaintFlags::NONE;
704  }
705  while ( !pTempWindow->ImplIsOverlapWindow() );
706  }
707 
708  // set Paint-Flags
709  mpWindowImpl->mnPaintFlags |= ImplPaintFlags::Paint;
710  if ( nFlags & InvalidateFlags::Children )
712  if ( !(nFlags & InvalidateFlags::NoErase) )
713  mpWindowImpl->mnPaintFlags |= ImplPaintFlags::Erase;
714 
715  if ( !pRegion )
716  mpWindowImpl->mnPaintFlags |= ImplPaintFlags::PaintAll;
717  else if ( !(mpWindowImpl->mnPaintFlags & ImplPaintFlags::PaintAll) )
718  {
719  // if not everything has to be redrawn, add the region to it
720  mpWindowImpl->maInvalidateRegion.Union( *pRegion );
721  }
722 
723  // Handle transparent windows correctly: invalidate must be done on the first opaque parent
725  && ImplGetParent() )
726  {
727  vcl::Window *pParent = ImplGetParent();
728  while( pParent && pParent->IsPaintTransparent() )
729  pParent = pParent->ImplGetParent();
730  if( pParent )
731  {
732  vcl::Region *pChildRegion;
733  if ( mpWindowImpl->mnPaintFlags & ImplPaintFlags::PaintAll )
734  // invalidate the whole child window region in the parent
735  pChildRegion = &ImplGetWinChildClipRegion();
736  else
737  // invalidate the same region in the parent that has to be repainted in the child
738  pChildRegion = &mpWindowImpl->maInvalidateRegion;
739 
740  nFlags |= InvalidateFlags::Children; // paint should also be done on all children
741  nFlags &= ~InvalidateFlags::NoErase; // parent should paint and erase to create proper background
742  pParent->ImplInvalidateFrameRegion( pChildRegion, nFlags );
743  }
744  }
745 
746  if ( !mpWindowImpl->mpFrameData->maPaintIdle.IsActive() )
747  mpWindowImpl->mpFrameData->maPaintIdle.Start();
748 }
749 
751 {
752  vcl::Region aRegion = rRegion;
753 
754  ImplClipBoundaries( aRegion, true, true );
755  if ( !aRegion.IsEmpty() )
757 
758  // now we invalidate the overlapping windows
759  vcl::Window* pTempWindow = mpWindowImpl->mpFirstOverlap;
760  while ( pTempWindow )
761  {
762  if ( pTempWindow->IsVisible() )
763  pTempWindow->ImplInvalidateOverlapFrameRegion( rRegion );
764 
765  pTempWindow = pTempWindow->mpWindowImpl->mpNext;
766  }
767 }
768 
770 {
771  if ( mpWindowImpl->mbOverlapWin )
772  mpWindowImpl->mpFrameWindow->ImplInvalidateOverlapFrameRegion( rRegion );
773  else
774  {
775  if( ImplGetParent() )
777  }
778 }
779 
780 void Window::ImplInvalidate( const vcl::Region* pRegion, InvalidateFlags nFlags )
781 {
782  // check what has to be redrawn
783  bool bInvalidateAll = !pRegion;
784 
785  // take Transparent-Invalidate into account
786  vcl::Window* pOpaqueWindow = this;
787  if ( (mpWindowImpl->mbPaintTransparent && !(nFlags & InvalidateFlags::NoTransparent)) || (nFlags & InvalidateFlags::Transparent) )
788  {
789  vcl::Window* pTempWindow = pOpaqueWindow->ImplGetParent();
790  while ( pTempWindow )
791  {
792  if ( !pTempWindow->IsPaintTransparent() )
793  {
794  pOpaqueWindow = pTempWindow;
795  nFlags |= InvalidateFlags::Children;
796  bInvalidateAll = false;
797  break;
798  }
799 
800  if ( pTempWindow->ImplIsOverlapWindow() )
801  break;
802 
803  pTempWindow = pTempWindow->ImplGetParent();
804  }
805  }
806 
807  // assemble region
808  InvalidateFlags nOrgFlags = nFlags;
810  {
811  if ( GetStyle() & WB_CLIPCHILDREN )
812  nFlags |= InvalidateFlags::NoChildren;
813  else
814  nFlags |= InvalidateFlags::Children;
815  }
816  if ( (nFlags & InvalidateFlags::NoChildren) && mpWindowImpl->mpFirstChild )
817  bInvalidateAll = false;
818  if ( bInvalidateAll )
819  ImplInvalidateFrameRegion( nullptr, nFlags );
820  else
821  {
822  vcl::Region aRegion( GetOutputRectPixel() );
823  if ( pRegion )
824  {
825  // RTL: remirror region before intersecting it
826  if ( GetOutDev()->ImplIsAntiparallel() )
827  {
828  const OutputDevice *pOutDev = GetOutDev();
829 
830  vcl::Region aRgn( *pRegion );
831  pOutDev->ReMirror( aRgn );
832  aRegion.Intersect( aRgn );
833  }
834  else
835  aRegion.Intersect( *pRegion );
836  }
837  ImplClipBoundaries( aRegion, true, true );
838  if ( nFlags & InvalidateFlags::NoChildren )
839  {
840  nFlags &= ~InvalidateFlags::Children;
841  if ( !(nFlags & InvalidateFlags::NoClipChildren) )
842  {
843  if ( nOrgFlags & InvalidateFlags::NoChildren )
844  ImplClipAllChildren( aRegion );
845  else
846  {
847  if ( ImplClipChildren( aRegion ) )
848  nFlags |= InvalidateFlags::Children;
849  }
850  }
851  }
852  if ( !aRegion.IsEmpty() )
853  ImplInvalidateFrameRegion( &aRegion, nFlags ); // transparency is handled here, pOpaqueWindow not required
854  }
855 
856  if ( nFlags & InvalidateFlags::Update )
857  pOpaqueWindow->PaintImmediately(); // start painting at the opaque parent
858 }
859 
861  tools::Long nHorzScroll, tools::Long nVertScroll,
862  bool bChildren )
863 {
865  {
866  vcl::Region aTempRegion = mpWindowImpl->maInvalidateRegion;
867  aTempRegion.Intersect( rRect );
868  aTempRegion.Move( nHorzScroll, nVertScroll );
869  mpWindowImpl->maInvalidateRegion.Union( aTempRegion );
870  }
871 
872  if ( bChildren && (mpWindowImpl->mnPaintFlags & ImplPaintFlags::PaintChildren) )
873  {
874  vcl::Window* pWindow = mpWindowImpl->mpFirstChild;
875  while ( pWindow )
876  {
877  pWindow->ImplMoveInvalidateRegion( rRect, nHorzScroll, nVertScroll, true );
878  pWindow = pWindow->mpWindowImpl->mpNext;
879  }
880  }
881 }
882 
884  tools::Long nHorzScroll, tools::Long nVertScroll,
885  bool bChildren )
886 {
887  // also shift Paint-Region when paints need processing
888  ImplMoveInvalidateRegion( rRect, nHorzScroll, nVertScroll, bChildren );
889  // Paint-Region should be shifted, as drawn by the parents
890  if ( ImplIsOverlapWindow() )
891  return;
892 
893  vcl::Region aPaintAllRegion;
894  vcl::Window* pPaintAllWindow = this;
895  do
896  {
897  pPaintAllWindow = pPaintAllWindow->ImplGetParent();
898  if ( pPaintAllWindow->mpWindowImpl->mnPaintFlags & ImplPaintFlags::PaintAllChildren )
899  {
900  if ( pPaintAllWindow->mpWindowImpl->mnPaintFlags & ImplPaintFlags::PaintAll )
901  {
902  aPaintAllRegion.SetEmpty();
903  break;
904  }
905  else
906  aPaintAllRegion.Union( pPaintAllWindow->mpWindowImpl->maInvalidateRegion );
907  }
908  }
909  while ( !pPaintAllWindow->ImplIsOverlapWindow() );
910  if ( !aPaintAllRegion.IsEmpty() )
911  {
912  aPaintAllRegion.Move( nHorzScroll, nVertScroll );
914  if ( bChildren )
915  nPaintFlags |= InvalidateFlags::Children;
916  ImplInvalidateFrameRegion( &aPaintAllRegion, nPaintFlags );
917  }
918 }
919 
921 {
922  if ( !pRegion )
923  mpWindowImpl->maInvalidateRegion.SetEmpty();
924  else
925  {
926  // when all child windows have to be drawn we need to invalidate them before doing so
927  if ( (mpWindowImpl->mnPaintFlags & ImplPaintFlags::PaintAllChildren) && mpWindowImpl->mpFirstChild )
928  {
929  vcl::Region aChildRegion = mpWindowImpl->maInvalidateRegion;
930  if ( mpWindowImpl->mnPaintFlags & ImplPaintFlags::PaintAll )
931  {
932  aChildRegion = GetOutputRectPixel();
933  }
934  vcl::Window* pChild = mpWindowImpl->mpFirstChild;
935  while ( pChild )
936  {
938  pChild = pChild->mpWindowImpl->mpNext;
939  }
940  }
941  if ( mpWindowImpl->mnPaintFlags & ImplPaintFlags::PaintAll )
942  {
943  mpWindowImpl->maInvalidateRegion = GetOutputRectPixel();
944  }
945  mpWindowImpl->maInvalidateRegion.Exclude( *pRegion );
946  }
947  mpWindowImpl->mnPaintFlags &= ~ImplPaintFlags::PaintAll;
948 
949  if ( nFlags & ValidateFlags::Children )
950  {
951  vcl::Window* pChild = mpWindowImpl->mpFirstChild;
952  while ( pChild )
953  {
954  pChild->ImplValidateFrameRegion( pRegion, nFlags );
955  pChild = pChild->mpWindowImpl->mpNext;
956  }
957  }
958 }
959 
961 {
962  // assemble region
963  bool bValidateAll = true;
965  if ( GetStyle() & WB_CLIPCHILDREN )
966  nFlags |= ValidateFlags::NoChildren;
967  else
968  nFlags |= ValidateFlags::Children;
969  if ( (nFlags & ValidateFlags::NoChildren) && mpWindowImpl->mpFirstChild )
970  bValidateAll = false;
971  if ( bValidateAll )
972  ImplValidateFrameRegion( nullptr, nFlags );
973  else
974  {
975  vcl::Region aRegion( GetOutputRectPixel() );
976  ImplClipBoundaries( aRegion, true, true );
977  if ( nFlags & ValidateFlags::NoChildren )
978  {
979  nFlags &= ~ValidateFlags::Children;
980  if ( ImplClipChildren( aRegion ) )
981  nFlags |= ValidateFlags::Children;
982  }
983  if ( !aRegion.IsEmpty() )
984  ImplValidateFrameRegion( &aRegion, nFlags );
985  }
986 }
987 
989 {
990  if ( !mpWindowImpl || !mpWindowImpl->mbReallyVisible )
991  return;
992 
993  bool bFlush = false;
994  if ( mpWindowImpl->mpFrameWindow->mpWindowImpl->mbPaintFrame )
995  {
996  Point aPoint( 0, 0 );
997  vcl::Region aRegion( tools::Rectangle( aPoint, GetOutputSizePixel() ) );
999  if ( mpWindowImpl->mbFrame || (mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame) )
1000  bFlush = true;
1001  }
1002 
1003  // an update changes the OverlapWindow, such that for later paints
1004  // not too much has to be drawn, if ALLCHILDREN etc. is set
1006  pWindow->ImplCallOverlapPaint();
1007 
1008  if ( bFlush )
1009  GetOutDev()->Flush();
1010 }
1011 
1012 void Window::PrePaint(vcl::RenderContext& /*rRenderContext*/)
1013 {
1014 }
1015 
1016 void Window::PostPaint(vcl::RenderContext& /*rRenderContext*/)
1017 {
1018 }
1019 
1020 void Window::Paint(vcl::RenderContext& /*rRenderContext*/, const tools::Rectangle& rRect)
1021 {
1022  CallEventListeners(VclEventId::WindowPaint, const_cast<tools::Rectangle *>(&rRect));
1023 }
1024 
1025 void Window::SetPaintTransparent( bool bTransparent )
1026 {
1027  // transparency is not useful for frames as the background would have to be provided by a different frame
1028  if( bTransparent && mpWindowImpl->mbFrame )
1029  return;
1030 
1031  if ( mpWindowImpl->mpBorderWindow )
1032  mpWindowImpl->mpBorderWindow->SetPaintTransparent( bTransparent );
1033 
1034  mpWindowImpl->mbPaintTransparent = bTransparent;
1035 }
1036 
1038 {
1039 
1040  if ( mpWindowImpl->mpBorderWindow )
1041  mpWindowImpl->mpBorderWindow->SetWindowRegionPixel();
1042  else if( mpWindowImpl->mbFrame )
1043  {
1044  mpWindowImpl->maWinRegion = vcl::Region(true);
1045  mpWindowImpl->mbWinRegion = false;
1046  mpWindowImpl->mpFrame->ResetClipRegion();
1047  }
1048  else
1049  {
1050  if ( mpWindowImpl->mbWinRegion )
1051  {
1052  mpWindowImpl->maWinRegion = vcl::Region(true);
1053  mpWindowImpl->mbWinRegion = false;
1054  ImplSetClipFlag();
1055 
1056  if ( IsReallyVisible() )
1057  {
1058  vcl::Region aRegion( GetOutputRectPixel() );
1060  }
1061  }
1062  }
1063 }
1064 
1066 {
1067 
1068  if ( mpWindowImpl->mpBorderWindow )
1069  mpWindowImpl->mpBorderWindow->SetWindowRegionPixel( rRegion );
1070  else if( mpWindowImpl->mbFrame )
1071  {
1072  if( !rRegion.IsNull() )
1073  {
1074  mpWindowImpl->maWinRegion = rRegion;
1075  mpWindowImpl->mbWinRegion = ! rRegion.IsEmpty();
1076 
1077  if( mpWindowImpl->mbWinRegion )
1078  {
1079  // set/update ClipRegion
1080  RectangleVector aRectangles;
1081  mpWindowImpl->maWinRegion.GetRegionRectangles(aRectangles);
1082  mpWindowImpl->mpFrame->BeginSetClipRegion(aRectangles.size());
1083 
1084  for (auto const& rectangle : aRectangles)
1085  {
1086  mpWindowImpl->mpFrame->UnionClipRegion(
1087  rectangle.Left(),
1088  rectangle.Top(),
1089  rectangle.GetWidth(), // orig nWidth was ((R - L) + 1), same as GetWidth does
1090  rectangle.GetHeight()); // same for height
1091  }
1092 
1093  mpWindowImpl->mpFrame->EndSetClipRegion();
1094  }
1095  else
1097  }
1098  else
1100  }
1101  else
1102  {
1103  if ( rRegion.IsNull() )
1104  {
1105  if ( mpWindowImpl->mbWinRegion )
1106  {
1107  mpWindowImpl->maWinRegion = vcl::Region(true);
1108  mpWindowImpl->mbWinRegion = false;
1109  ImplSetClipFlag();
1110  }
1111  }
1112  else
1113  {
1114  mpWindowImpl->maWinRegion = rRegion;
1115  mpWindowImpl->mbWinRegion = true;
1116  ImplSetClipFlag();
1117  }
1118 
1119  if ( IsReallyVisible() )
1120  {
1121  vcl::Region aRegion( GetOutputRectPixel() );
1123  }
1124  }
1125 }
1126 
1128 {
1129 
1130  if ( mpWindowImpl->mpPaintRegion )
1131  {
1132  vcl::Region aRegion = *mpWindowImpl->mpPaintRegion;
1133  aRegion.Move( -GetOutDev()->mnOutOffX, -GetOutDev()->mnOutOffY );
1134  return PixelToLogic( aRegion );
1135  }
1136  else
1137  {
1138  vcl::Region aPaintRegion(true);
1139  return aPaintRegion;
1140  }
1141 }
1142 
1144 {
1145  if ( !comphelper::LibreOfficeKit::isActive() && (!GetOutDev()->IsDeviceOutputNecessary() || !GetOutDev()->mnOutWidth || !GetOutDev()->mnOutHeight) )
1146  return;
1147 
1148  ImplInvalidate( nullptr, nFlags );
1149  LogicInvalidate(nullptr);
1150 }
1151 
1153 {
1154  if ( !comphelper::LibreOfficeKit::isActive() && (!GetOutDev()->IsDeviceOutputNecessary() || !GetOutDev()->mnOutWidth || !GetOutDev()->mnOutHeight) )
1155  return;
1156 
1157  OutputDevice *pOutDev = GetOutDev();
1158  tools::Rectangle aRect = pOutDev->ImplLogicToDevicePixel( rRect );
1159  if ( !aRect.IsEmpty() )
1160  {
1161  vcl::Region aRegion( aRect );
1162  ImplInvalidate( &aRegion, nFlags );
1163  tools::Rectangle aLogicRectangle(rRect);
1164  LogicInvalidate(&aLogicRectangle);
1165  }
1166 }
1167 
1168 void Window::Invalidate( const vcl::Region& rRegion, InvalidateFlags nFlags )
1169 {
1170  if ( !comphelper::LibreOfficeKit::isActive() && (!GetOutDev()->IsDeviceOutputNecessary() || !GetOutDev()->mnOutWidth || !GetOutDev()->mnOutHeight) )
1171  return;
1172 
1173  if ( rRegion.IsNull() )
1174  {
1175  ImplInvalidate( nullptr, nFlags );
1176  LogicInvalidate(nullptr);
1177  }
1178  else
1179  {
1180  vcl::Region aRegion = GetOutDev()->ImplPixelToDevicePixel( LogicToPixel( rRegion ) );
1181  if ( !aRegion.IsEmpty() )
1182  {
1183  ImplInvalidate( &aRegion, nFlags );
1184  tools::Rectangle aLogicRectangle = rRegion.GetBoundRect();
1185  LogicInvalidate(&aLogicRectangle);
1186  }
1187  }
1188 }
1189 
1191 {
1192  if(pRectangle)
1193  {
1194  tools::Rectangle aRect = GetOutDev()->ImplLogicToDevicePixel( *pRectangle );
1195  PixelInvalidate(&aRect);
1196  }
1197  else
1198  PixelInvalidate(nullptr);
1199 }
1200 
1202 {
1204  return;
1205 
1206  Size aSize = GetSizePixel();
1207  if (aSize.IsEmpty())
1208  return;
1209 
1210  if (const vcl::ILibreOfficeKitNotifier* pNotifier = GetLOKNotifier())
1211  {
1212  // In case we are routing the window, notify the client
1213  std::vector<vcl::LOKPayloadItem> aPayload;
1214  if (pRectangle)
1215  aPayload.emplace_back("rectangle", pRectangle->toString());
1216  else
1217  {
1218  const tools::Rectangle aRect(Point(0, 0), aSize);
1219  aPayload.emplace_back("rectangle", aRect.toString());
1220  }
1221 
1222  pNotifier->notifyWindow(GetLOKWindowId(), "invalidate", aPayload);
1223  }
1224  // Added for dialog items. Pass invalidation to the parent window.
1225  else if (VclPtr<vcl::Window> pParent = GetParentWithLOKNotifier())
1226  {
1228  pParent->PixelInvalidate(&aRect);
1229  }
1230 }
1231 
1233 {
1234  if ( !comphelper::LibreOfficeKit::isActive() && (!GetOutDev()->IsDeviceOutputNecessary() || !GetOutDev()->mnOutWidth || !GetOutDev()->mnOutHeight) )
1235  return;
1236 
1237  ImplValidate();
1238 }
1239 
1241 {
1242 
1243  if ( !mpWindowImpl->mbReallyVisible )
1244  return false;
1245 
1246  if ( mpWindowImpl->mpFrameWindow->mpWindowImpl->mbPaintFrame )
1247  return true;
1248 
1249  if ( mpWindowImpl->mnPaintFlags & ImplPaintFlags::Paint )
1250  return true;
1251 
1252  if ( !ImplIsOverlapWindow() )
1253  {
1254  const vcl::Window* pTempWindow = this;
1255  do
1256  {
1257  pTempWindow = pTempWindow->ImplGetParent();
1258  if ( pTempWindow->mpWindowImpl->mnPaintFlags & (ImplPaintFlags::PaintChildren | ImplPaintFlags::PaintAllChildren) )
1259  return true;
1260  }
1261  while ( !pTempWindow->ImplIsOverlapWindow() );
1262  }
1263 
1264  return false;
1265 }
1266 
1268 {
1269  if (!mpWindowImpl)
1270  return;
1271 
1272  if ( mpWindowImpl->mpBorderWindow )
1273  {
1274  mpWindowImpl->mpBorderWindow->PaintImmediately();
1275  return;
1276  }
1277 
1278  if ( !mpWindowImpl->mbReallyVisible )
1279  return;
1280 
1281  bool bFlush = false;
1282  if ( mpWindowImpl->mpFrameWindow->mpWindowImpl->mbPaintFrame )
1283  {
1284  Point aPoint( 0, 0 );
1285  vcl::Region aRegion( tools::Rectangle( aPoint, GetOutputSizePixel() ) );
1287  if ( mpWindowImpl->mbFrame || (mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame) )
1288  bFlush = true;
1289  }
1290 
1291  // First we should skip all windows which are Paint-Transparent
1292  vcl::Window* pUpdateWindow = this;
1293  vcl::Window* pWindow = pUpdateWindow;
1294  while ( !pWindow->ImplIsOverlapWindow() )
1295  {
1296  if ( !pWindow->mpWindowImpl->mbPaintTransparent )
1297  {
1298  pUpdateWindow = pWindow;
1299  break;
1300  }
1301  pWindow = pWindow->ImplGetParent();
1302  }
1303  // In order to limit drawing, an update only draws the window which
1304  // has PAINTALLCHILDREN set
1305  pWindow = pUpdateWindow;
1306  do
1307  {
1308  if ( pWindow->mpWindowImpl->mnPaintFlags & ImplPaintFlags::PaintAllChildren )
1309  pUpdateWindow = pWindow;
1310  if ( pWindow->ImplIsOverlapWindow() )
1311  break;
1312  pWindow = pWindow->ImplGetParent();
1313  }
1314  while ( pWindow );
1315 
1316  // if there is something to paint, trigger a Paint
1317  if ( pUpdateWindow->mpWindowImpl->mnPaintFlags & (ImplPaintFlags::Paint | ImplPaintFlags::PaintChildren) )
1318  {
1319  VclPtr<vcl::Window> xWindow(this);
1320 
1321  // trigger an update also for system windows on top of us,
1322  // otherwise holes would remain
1323  vcl::Window* pUpdateOverlapWindow = ImplGetFirstOverlapWindow();
1324  if (pUpdateOverlapWindow->mpWindowImpl)
1325  pUpdateOverlapWindow = pUpdateOverlapWindow->mpWindowImpl->mpFirstOverlap;
1326  else
1327  pUpdateOverlapWindow = nullptr;
1328  while ( pUpdateOverlapWindow )
1329  {
1330  pUpdateOverlapWindow->PaintImmediately();
1331  pUpdateOverlapWindow = pUpdateOverlapWindow->mpWindowImpl->mpNext;
1332  }
1333 
1334  pUpdateWindow->ImplCallPaint(nullptr, pUpdateWindow->mpWindowImpl->mnPaintFlags);
1335 
1336  if (comphelper::LibreOfficeKit::isActive() && pUpdateWindow->GetParentDialog())
1337  pUpdateWindow->LogicInvalidate(nullptr);
1338 
1339  if (xWindow->isDisposed())
1340  return;
1341 
1342  bFlush = true;
1343  }
1344 
1345  if ( bFlush )
1346  GetOutDev()->Flush();
1347 }
1348 
1349 void Window::ImplPaintToDevice( OutputDevice* i_pTargetOutDev, const Point& i_rPos )
1350 {
1351  // Special drawing when called through LOKit
1352  // TODO: Move to its own method
1354  {
1355  VclPtrInstance<VirtualDevice> pDevice(*i_pTargetOutDev);
1356 
1357  Size aSize(GetOutputSizePixel());
1358  pDevice->SetOutputSizePixel(aSize);
1359 
1360  vcl::Font aCopyFont = GetFont();
1361  pDevice->SetFont(aCopyFont);
1362 
1363  pDevice->SetTextColor(GetTextColor());
1364  if (GetOutDev()->IsLineColor())
1365  pDevice->SetLineColor(GetOutDev()->GetLineColor());
1366  else
1367  pDevice->SetLineColor();
1368 
1369  if (GetOutDev()->IsFillColor())
1370  pDevice->SetFillColor(GetOutDev()->GetFillColor());
1371  else
1372  pDevice->SetFillColor();
1373 
1374  if (IsTextLineColor())
1375  pDevice->SetTextLineColor(GetTextLineColor());
1376  else
1377  pDevice->SetTextLineColor();
1378 
1379  if (IsOverlineColor())
1380  pDevice->SetOverlineColor(GetOverlineColor());
1381  else
1382  pDevice->SetOverlineColor();
1383 
1384  if (IsTextFillColor())
1385  pDevice->SetTextFillColor(GetTextFillColor());
1386  else
1387  pDevice->SetTextFillColor();
1388 
1389  pDevice->SetTextAlign(GetTextAlign());
1390  pDevice->SetRasterOp(GetOutDev()->GetRasterOp());
1391 
1392  tools::Rectangle aPaintRect(Point(), GetOutputSizePixel());
1393 
1394  vcl::Region aClipRegion(GetOutDev()->GetClipRegion());
1395  pDevice->SetClipRegion();
1396  aClipRegion.Intersect(aPaintRect);
1397  pDevice->SetClipRegion(aClipRegion);
1398 
1400  Erase(*pDevice);
1401 
1402  pDevice->SetMapMode(GetMapMode());
1403 
1405 
1406  i_pTargetOutDev->DrawOutDev(i_rPos, aSize, Point(), pDevice->PixelToLogic(aSize), *pDevice);
1407 
1408  // get rid of virtual device now so they don't pile up during recursive calls
1409  pDevice.disposeAndClear();
1410 
1411 
1412  for( vcl::Window* pChild = mpWindowImpl->mpFirstChild; pChild; pChild = pChild->mpWindowImpl->mpNext )
1413  {
1414  if( pChild->mpWindowImpl->mpFrame == mpWindowImpl->mpFrame && pChild->IsVisible() )
1415  {
1416  tools::Long nDeltaX = pChild->GetOutDev()->mnOutOffX - GetOutDev()->mnOutOffX;
1417  tools::Long nDeltaY = pChild->GetOutDev()->mnOutOffY - GetOutDev()->mnOutOffY;
1418 
1419  Point aPos( i_rPos );
1420  aPos += Point(nDeltaX, nDeltaY);
1421 
1422  pChild->ImplPaintToDevice( i_pTargetOutDev, aPos );
1423  }
1424  }
1425  return;
1426  }
1427 
1428 
1429  bool bRVisible = mpWindowImpl->mbReallyVisible;
1430  mpWindowImpl->mbReallyVisible = mpWindowImpl->mbVisible;
1431  bool bDevOutput = GetOutDev()->mbDevOutput;
1432  GetOutDev()->mbDevOutput = true;
1433 
1434  const OutputDevice *pOutDev = GetOutDev();
1435  tools::Long nOldDPIX = pOutDev->GetDPIX();
1436  tools::Long nOldDPIY = pOutDev->GetDPIY();
1437  GetOutDev()->mnDPIX = i_pTargetOutDev->GetDPIX();
1438  GetOutDev()->mnDPIY = i_pTargetOutDev->GetDPIY();
1439  bool bOutput = GetOutDev()->IsOutputEnabled();
1440  GetOutDev()->EnableOutput();
1441 
1442  SAL_WARN_IF( GetMapMode().GetMapUnit() != MapUnit::MapPixel, "vcl.window", "MapMode must be PIXEL based" );
1443  if ( GetMapMode().GetMapUnit() != MapUnit::MapPixel )
1444  return;
1445 
1446  // preserve graphicsstate
1447  GetOutDev()->Push();
1448  vcl::Region aClipRegion( GetOutDev()->GetClipRegion() );
1449  GetOutDev()->SetClipRegion();
1450 
1451  GDIMetaFile* pOldMtf = GetOutDev()->GetConnectMetaFile();
1452  GDIMetaFile aMtf;
1453  GetOutDev()->SetConnectMetaFile( &aMtf );
1454 
1455  // put a push action to metafile
1456  GetOutDev()->Push();
1457  // copy graphics state to metafile
1458  vcl::Font aCopyFont = GetFont();
1459  if( nOldDPIX != GetOutDev()->mnDPIX || nOldDPIY != GetOutDev()->mnDPIY )
1460  {
1461  aCopyFont.SetFontHeight( aCopyFont.GetFontHeight() * GetOutDev()->mnDPIY / nOldDPIY );
1462  aCopyFont.SetAverageFontWidth( aCopyFont.GetAverageFontWidth() * GetOutDev()->mnDPIX / nOldDPIX );
1463  }
1464  SetFont( aCopyFont );
1466  if( GetOutDev()->IsLineColor() )
1468  else
1469  GetOutDev()->SetLineColor();
1470  if( GetOutDev()->IsFillColor() )
1472  else
1473  GetOutDev()->SetFillColor();
1474  if( IsTextLineColor() )
1476  else
1477  SetTextLineColor();
1478  if( IsOverlineColor() )
1480  else
1481  SetOverlineColor();
1482  if( IsTextFillColor() )
1484  else
1485  SetTextFillColor();
1487  GetOutDev()->SetRasterOp( GetOutDev()->GetRasterOp() );
1488  if( GetOutDev()->IsRefPoint() )
1489  GetOutDev()->SetRefPoint( GetOutDev()->GetRefPoint() );
1490  else
1491  GetOutDev()->SetRefPoint();
1492  GetOutDev()->SetLayoutMode( GetOutDev()->GetLayoutMode() );
1493 
1494  GetOutDev()->SetDigitLanguage( GetOutDev()->GetDigitLanguage() );
1495  tools::Rectangle aPaintRect(Point(0, 0), GetOutputSizePixel());
1496  aClipRegion.Intersect( aPaintRect );
1497  GetOutDev()->SetClipRegion( aClipRegion );
1498 
1499  // do the actual paint
1500 
1501  // background
1503  {
1504  Erase(*GetOutDev());
1505  }
1506  // foreground
1507  Paint(*GetOutDev(), aPaintRect);
1508  // put a pop action to metafile
1509  GetOutDev()->Pop();
1510 
1511  GetOutDev()->SetConnectMetaFile( pOldMtf );
1512  GetOutDev()->EnableOutput( bOutput );
1513  mpWindowImpl->mbReallyVisible = bRVisible;
1514 
1515  // paint metafile to VDev
1516  VclPtrInstance<VirtualDevice> pMaskedDevice(*i_pTargetOutDev,
1519 
1520  pMaskedDevice->SetOutputSizePixel( GetOutputSizePixel() );
1521  pMaskedDevice->EnableRTL( IsRTLEnabled() );
1522  aMtf.WindStart();
1523  aMtf.Play(*pMaskedDevice);
1524  BitmapEx aBmpEx( pMaskedDevice->GetBitmapEx( Point( 0, 0 ), aPaintRect.GetSize() ) );
1525  i_pTargetOutDev->DrawBitmapEx( i_rPos, aBmpEx );
1526  // get rid of virtual device now so they don't pile up during recursive calls
1527  pMaskedDevice.disposeAndClear();
1528 
1529  for( vcl::Window* pChild = mpWindowImpl->mpFirstChild; pChild; pChild = pChild->mpWindowImpl->mpNext )
1530  {
1531  if( pChild->mpWindowImpl->mpFrame == mpWindowImpl->mpFrame && pChild->IsVisible() )
1532  {
1533  tools::Long nDeltaX = pChild->GetOutDev()->mnOutOffX - GetOutDev()->mnOutOffX;
1534 
1535  if( pOutDev->HasMirroredGraphics() )
1536  nDeltaX = GetOutDev()->mnOutWidth - nDeltaX - pChild->GetOutDev()->mnOutWidth;
1537  tools::Long nDeltaY = pChild->GetOutOffYPixel() - GetOutOffYPixel();
1538  Point aPos( i_rPos );
1539  Point aDelta( nDeltaX, nDeltaY );
1540  aPos += aDelta;
1541  pChild->ImplPaintToDevice( i_pTargetOutDev, aPos );
1542  }
1543  }
1544 
1545  // restore graphics state
1546  GetOutDev()->Pop();
1547 
1548  GetOutDev()->EnableOutput( bOutput );
1549  mpWindowImpl->mbReallyVisible = bRVisible;
1550  GetOutDev()->mbDevOutput = bDevOutput;
1551  GetOutDev()->mnDPIX = nOldDPIX;
1552  GetOutDev()->mnDPIY = nOldDPIY;
1553 }
1554 
1555 void Window::PaintToDevice(OutputDevice* pDev, const Point& rPos)
1556 {
1557  if( !mpWindowImpl )
1558  return;
1559 
1560  SAL_WARN_IF( pDev->HasMirroredGraphics(), "vcl.window", "PaintToDevice to mirroring graphics" );
1561  SAL_WARN_IF( pDev->IsRTLEnabled(), "vcl.window", "PaintToDevice to mirroring device" );
1562 
1563  vcl::Window* pRealParent = nullptr;
1564  if( ! mpWindowImpl->mbVisible )
1565  {
1566  vcl::Window* pTempParent = ImplGetDefaultWindow();
1567  pTempParent->EnableChildTransparentMode();
1568  pRealParent = GetParent();
1569  SetParent( pTempParent );
1570  // trigger correct visibility flags for children
1571  Show();
1572  Hide();
1573  }
1574 
1575  bool bVisible = mpWindowImpl->mbVisible;
1576  mpWindowImpl->mbVisible = true;
1577 
1578  if( mpWindowImpl->mpBorderWindow )
1579  mpWindowImpl->mpBorderWindow->ImplPaintToDevice( pDev, rPos );
1580  else
1581  ImplPaintToDevice( pDev, rPos );
1582 
1583  mpWindowImpl->mbVisible = bVisible;
1584 
1585  if( pRealParent )
1586  SetParent( pRealParent );
1587 }
1588 
1589 void Window::Erase(vcl::RenderContext& rRenderContext)
1590 {
1591  if (!GetOutDev()->IsDeviceOutputNecessary() || GetOutDev()->ImplIsRecordLayout())
1592  return;
1593 
1594  bool bNativeOK = false;
1595 
1597 
1598  if (aCtrlPart == ControlPart::Entire && IsControlBackground())
1599  {
1600  // nothing to do here; background is drawn in corresponding drawNativeControl implementation
1601  bNativeOK = true;
1602  }
1603  else if (aCtrlPart != ControlPart::NONE && ! IsControlBackground())
1604  {
1605  tools::Rectangle aCtrlRegion(Point(), GetOutputSizePixel());
1607 
1608  if (IsEnabled())
1609  nState |= ControlState::ENABLED;
1610 
1611  bNativeOK = rRenderContext.DrawNativeControl(ControlType::WindowBackground, aCtrlPart, aCtrlRegion,
1612  nState, ImplControlValue(), OUString());
1613  }
1614 
1615  if (GetOutDev()->mbBackground && !bNativeOK)
1616  {
1617  RasterOp eRasterOp = GetOutDev()->GetRasterOp();
1618  if (eRasterOp != RasterOp::OverPaint)
1620  rRenderContext.DrawWallpaper(0, 0, GetOutDev()->mnOutWidth, GetOutDev()->mnOutHeight, GetOutDev()->maBackground);
1621  if (eRasterOp != RasterOp::OverPaint)
1622  rRenderContext.SetRasterOp(eRasterOp);
1623  }
1624 
1625  if (GetOutDev()->mpAlphaVDev)
1626  GetOutDev()->mpAlphaVDev->Erase();
1627 }
1628 
1630  tools::Long nHorzScroll, tools::Long nVertScroll, ScrollFlags nFlags )
1631 {
1632  if ( !GetOutDev()->IsDeviceOutputNecessary() )
1633  return;
1634 
1635  nHorzScroll = GetOutDev()->ImplLogicWidthToDevicePixel( nHorzScroll );
1636  nVertScroll = GetOutDev()->ImplLogicHeightToDevicePixel( nVertScroll );
1637 
1638  if ( !nHorzScroll && !nVertScroll )
1639  return;
1640 
1641  if ( mpWindowImpl->mpCursor )
1642  mpWindowImpl->mpCursor->ImplSuspend();
1643 
1644  ScrollFlags nOrgFlags = nFlags;
1645  if ( !(nFlags & (ScrollFlags::Children | ScrollFlags::NoChildren)) )
1646  {
1647  if ( GetStyle() & WB_CLIPCHILDREN )
1648  nFlags |= ScrollFlags::NoChildren;
1649  else
1650  nFlags |= ScrollFlags::Children;
1651  }
1652 
1653  vcl::Region aInvalidateRegion;
1654  bool bScrollChildren(nFlags & ScrollFlags::Children);
1655 
1656  if ( !mpWindowImpl->mpFirstChild )
1657  bScrollChildren = false;
1658 
1659  OutputDevice *pOutDev = GetOutDev();
1660 
1661  // RTL: check if this window requires special action
1662  bool bReMirror = GetOutDev()->ImplIsAntiparallel();
1663 
1664  tools::Rectangle aRectMirror( rRect );
1665  if( bReMirror )
1666  {
1667  // make sure the invalidate region of this window is
1668  // computed in the same coordinate space as the one from the overlap windows
1669  pOutDev->ReMirror( aRectMirror );
1670  }
1671 
1672  // adapt paint areas
1673  ImplMoveAllInvalidateRegions( aRectMirror, nHorzScroll, nVertScroll, bScrollChildren );
1674 
1675  ImplCalcOverlapRegion( aRectMirror, aInvalidateRegion, !bScrollChildren, false );
1676 
1677  // if the scrolling on the device is performed in the opposite direction
1678  // then move the overlaps in that direction to compute the invalidate region
1679  // on the correct side, i.e., revert nHorzScroll
1680  if (!aInvalidateRegion.IsEmpty())
1681  {
1682  aInvalidateRegion.Move(bReMirror ? -nHorzScroll : nHorzScroll, nVertScroll);
1683  }
1684 
1685  tools::Rectangle aDestRect(aRectMirror);
1686  aDestRect.Move(bReMirror ? -nHorzScroll : nHorzScroll, nVertScroll);
1687  vcl::Region aWinInvalidateRegion(aRectMirror);
1688  if (!SupportsDoubleBuffering())
1689  {
1690  // There will be no CopyArea() call below, so invalidate the
1691  // whole visible area, not only the smaller one that was just
1692  // scrolled in.
1693  aWinInvalidateRegion.Exclude(aDestRect);
1694  }
1695 
1696  aInvalidateRegion.Union(aWinInvalidateRegion);
1697 
1698  vcl::Region aRegion( GetOutputRectPixel() );
1699  if ( nFlags & ScrollFlags::Clip )
1700  aRegion.Intersect( rRect );
1701  if ( mpWindowImpl->mbWinRegion )
1702  aRegion.Intersect( GetOutDev()->ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
1703 
1704  aRegion.Exclude( aInvalidateRegion );
1705 
1706  ImplClipBoundaries( aRegion, false, true );
1707  if ( !bScrollChildren )
1708  {
1709  if ( nOrgFlags & ScrollFlags::NoChildren )
1710  ImplClipAllChildren( aRegion );
1711  else
1712  ImplClipChildren( aRegion );
1713  }
1714  if ( GetOutDev()->mbClipRegion && (nFlags & ScrollFlags::UseClipRegion) )
1715  aRegion.Intersect( GetOutDev()->maRegion );
1716  if ( !aRegion.IsEmpty() )
1717  {
1718  if ( mpWindowImpl->mpWinData )
1719  {
1720  if ( mpWindowImpl->mbFocusVisible )
1721  ImplInvertFocus( *mpWindowImpl->mpWinData->mpFocusRect );
1722  if ( mpWindowImpl->mbTrackVisible && (mpWindowImpl->mpWinData->mnTrackFlags & ShowTrackFlags::TrackWindow) )
1723  InvertTracking( *mpWindowImpl->mpWinData->mpTrackRect, mpWindowImpl->mpWinData->mnTrackFlags );
1724  }
1725 #ifndef IOS
1726  // This seems completely unnecessary with tiled rendering, and
1727  // causes the "AquaSalGraphics::copyArea() for non-layered
1728  // graphics" message. Presumably we should bypass this on all
1729  // platforms when dealing with a "window" that uses tiled
1730  // rendering at the moment. Unclear how to figure that out,
1731  // though. Also unclear whether we actually could just not
1732  // create a "frame window", whatever that exactly is, in the
1733  // tiled rendering case, or at least for platforms where tiles
1734  // rendering is all there is.
1735 
1736  SalGraphics* pGraphics = ImplGetFrameGraphics();
1737  // The invalidation area contains the area what would be copied here,
1738  // so avoid copying in case of double buffering.
1739  if (pGraphics && !SupportsDoubleBuffering())
1740  {
1741  if( bReMirror )
1742  {
1743  pOutDev->ReMirror( aRegion );
1744  }
1745 
1746  pOutDev->SelectClipRegion( aRegion, pGraphics );
1747  pGraphics->CopyArea( rRect.Left()+nHorzScroll, rRect.Top()+nVertScroll,
1748  rRect.Left(), rRect.Top(),
1749  rRect.GetWidth(), rRect.GetHeight(),
1750  *GetOutDev() );
1751  }
1752 #endif
1753  if ( mpWindowImpl->mpWinData )
1754  {
1755  if ( mpWindowImpl->mbFocusVisible )
1756  ImplInvertFocus( *mpWindowImpl->mpWinData->mpFocusRect );
1757  if ( mpWindowImpl->mbTrackVisible && (mpWindowImpl->mpWinData->mnTrackFlags & ShowTrackFlags::TrackWindow) )
1758  InvertTracking( *mpWindowImpl->mpWinData->mpTrackRect, mpWindowImpl->mpWinData->mnTrackFlags );
1759  }
1760  }
1761 
1762  if ( !aInvalidateRegion.IsEmpty() )
1763  {
1764  // RTL: the invalidate region for this windows is already computed in frame coordinates
1765  // so it has to be re-mirrored before calling the Paint-handler
1766  mpWindowImpl->mnPaintFlags |= ImplPaintFlags::CheckRtl;
1767 
1768  if ( !bScrollChildren )
1769  {
1770  if ( nOrgFlags & ScrollFlags::NoChildren )
1771  ImplClipAllChildren( aInvalidateRegion );
1772  else
1773  ImplClipChildren( aInvalidateRegion );
1774  }
1776  }
1777 
1778  if ( bScrollChildren )
1779  {
1780  vcl::Window* pWindow = mpWindowImpl->mpFirstChild;
1781  while ( pWindow )
1782  {
1783  Point aPos = pWindow->GetPosPixel();
1784  aPos += Point( nHorzScroll, nVertScroll );
1785  pWindow->SetPosPixel( aPos );
1786 
1787  pWindow = pWindow->mpWindowImpl->mpNext;
1788  }
1789  }
1790 
1791  if ( nFlags & ScrollFlags::Update )
1792  PaintImmediately();
1793 
1794  if ( mpWindowImpl->mpCursor )
1795  mpWindowImpl->mpCursor->ImplResume();
1796 }
1797 
1798 } /* namespace vcl */
1799 
1800 
1801 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual Point GetPosPixel() const
Definition: window.cxx:2791
SAL_DLLPRIVATE void ImplMoveInvalidateRegion(const tools::Rectangle &rRect, tools::Long nHorzScroll, tools::Long nVertScroll, bool bChildren)
Definition: paint.cxx:860
void EnableOutput(bool bEnable=true)
Definition: outdev.cxx:334
vcl::Region GetClipRegion() const
The child windows are invalidated, too.
bool IsControlBackground() const
Definition: window2.cxx:1081
tools::Long GetOutOffYPixel() const
Definition: window3.cxx:124
virtual void Flush()
Definition: outdev.hxx:433
void SetDigitLanguage(LanguageType)
Definition: text.cxx:69
void SetBackground()
Definition: window3.cxx:100
tools::Rectangle m_aPaintRect
Definition: paint.cxx:171
const Wallpaper & GetBackground() const
Definition: outdev.hxx:531
SAL_DLLPRIVATE SalGraphics * ImplGetFrameGraphics() const
Definition: window.cxx:1286
vcl::LOKWindowId GetLOKWindowId() const
Definition: window.cxx:3253
bool bVisible
SAL_DLLPRIVATE vcl::Region & ImplGetWinChildClipRegion()
bool IsNull() const
Definition: region.hxx:99
PaintBufferGuard(ImplFrameData *pFrameData, vcl::Window *pWindow)
Definition: paint.cxx:45
tools::Long AdjustRight(tools::Long nHorzMoveDelta)
The parent window is invalidated, too.
virtual void ImplPaintToDevice(::OutputDevice *pTargetOutDev, const Point &rPos)
Definition: paint.cxx:1349
void SetAverageFontWidth(tools::Long nWidth)
Definition: font/font.cxx:856
void Move(tools::Long nHorzMove, tools::Long nVertMove)
Definition: region.cxx:399
bool IsBackground() const
Definition: window3.cxx:64
const Color & GetHighlightTextColor() const
bool IsTextLineColor() const
Definition: window3.cxx:112
InvalidateFlags
Definition: window.hxx:184
constexpr tools::Long Left() const
void DrawBitmapEx(const Point &rDestPt, const BitmapEx &rBitmapEx)
Definition: bitmapex.cxx:33
tools::Rectangle m_aSelectionRect
Definition: paint.cxx:170
void SetOverlineColor()
Definition: window3.cxx:95
void Union(const tools::Rectangle &rRegion)
Definition: region.cxx:505
const Color & GetTextLineColor() const
Definition: window3.cxx:110
VclPtr< vcl::Window > m_pWindow
Definition: paint.cxx:168
bool IsBackground() const
Definition: outdev.hxx:534
void InvertTracking(const tools::Rectangle &rRect, ShowTrackFlags nFlags)
Definition: window2.cxx:160
ValidateFlags
Definition: window.hxx:208
ImplPaintFlags GetPaintFlags() const
Definition: paint.cxx:199
void Erase(vcl::RenderContext &rRenderContext)
Definition: paint.cxx:1589
long Long
bool mbInBufferedPaint
PaintHelper is in the process of painting into this buffer.
Definition: window.h:174
void disposeAndClear()
Definition: vclptr.hxx:200
const StyleSettings & GetStyleSettings() const
void Push(vcl::PushFlags nFlags=vcl::PushFlags::ALL)
Definition: stack.cxx:33
bool IsOutputEnabled() const
Definition: outdev.hxx:484
ParentClipMode GetParentClipMode() const
sal_uInt8 GetLuminance() const
const Color & GetFaceColor() const
tools::Long GetOutOffXPixel() const
Definition: outdev.hxx:322
vcl::Region maInvalidateRegion
Definition: window.h:283
virtual Size GetSizePixel() const
Definition: window.cxx:2402
SAL_DLLPRIVATE WindowImpl * ImplGetWindowImpl() const
Definition: window.hxx:527
tools::Long mnOutOffY
Output offset for device output in pixel (pseudo window offset within window system's frames) ...
Definition: outdev.hxx:215
sal_Int32 mnDPIY
Definition: outdev.hxx:219
void SetTextFillColor()
Definition: text.cxx:732
vcl::Region GetPaintRegion() const
Definition: paint.cxx:1127
void SetPop()
Definition: paint.cxx:179
GDIMetaFile * GetConnectMetaFile() const
Definition: outdev.hxx:292
The invalidated area is updated immediately.
sal_Int32 mnDPIX
Definition: outdev.hxx:218
virtual void SetSettings(const AllSettings &rSettings)
Definition: outdev.cxx:217
The area is invalidated regardless of overlapping child windows.
constexpr::Color COL_LIGHTGRAY(0xC0, 0xC0, 0xC0)
SAL_DLLPRIVATE void ImplClipAllChildren(vcl::Region &rRegion) const
SAL_DLLPRIVATE void ImplUpdateAll()
Definition: paint.cxx:988
tools::Rectangle GetBoundRect() const
Definition: region.cxx:1217
void PaintImmediately()
Definition: paint.cxx:1267
VclPtr< VirtualDevice > mpBuffer
Buffer for the double-buffering.
Definition: window.h:173
SAL_DLLPRIVATE void ImplCallPaint(const vcl::Region *pRegion, ImplPaintFlags nPaintFlags)
Invoke the actual painting.
Definition: paint.cxx:579
bool IsRTLEnabled() const
Definition: window3.cxx:127
void PaintBuffer()
Paint the content of the buffer to the current m_pWindow.
Definition: paint.cxx:237
void SetMapMode()
Definition: map.cxx:594
std::unique_ptr< ImplWinData > mpWinData
Definition: window.h:221
void SetTextColor(const Color &rColor)
Definition: window3.cxx:108
Dialog * GetParentDialog() const
Definition: window2.cxx:976
bool IsTextFillColor() const
Definition: window3.cxx:116
~PaintBufferGuard() COVERITY_NOEXCEPT_FALSE
Definition: paint.cxx:109
const Color & GetHighlightColor() const
SAL_DLLPRIVATE void ImplInvalidateFrameRegion(const vcl::Region *pRegion, InvalidateFlags nFlags)
Definition: paint.cxx:689
bool GetRestoreCursor() const
Definition: paint.cxx:195
tools::Long GetFontHeight() const
Definition: font/font.cxx:855
ImplFrameData * mpFrameData
Definition: window.h:398
void SetTextLineColor()
Definition: window3.cxx:93
tools::Long mnOutOffY
Definition: window.h:404
bool SelectClipRegion(const vcl::Region &, SalGraphics *pGraphics=nullptr)
SAL_DLLPRIVATE bool ImplIsOverlapWindow() const
Definition: window2.cxx:920
std::vector< tools::Rectangle > RectangleVector
Definition: region.hxx:34
The invalidated area is painted with the background color/pattern.
SAL_DLLPRIVATE void ImplMoveAllInvalidateRegions(const tools::Rectangle &rRect, tools::Long nHorzScroll, tools::Long nVertScroll, bool bChildren)
Definition: paint.cxx:883
void DrawWallpaper(const tools::Rectangle &rRect, const Wallpaper &rWallpaper)
Definition: wallpaper.cxx:35
void SetBackground()
Definition: background.cxx:27
ScrollFlags
Definition: window.hxx:220
void SetOutOffYPixel(tools::Long nOutOffY)
Definition: outdev.cxx:394
SAL_DLLPRIVATE void ReMirror(Point &rPoint) const
Definition: outdev.cxx:678
Color GetFillColor(Color const &rColor, DrawModeFlags nDrawMode, StyleSettings const &rStyleSettings)
Definition: drawmode.cxx:64
VclPtr< vcl::Window > GetParentWithLOKNotifier()
Find the nearest parent with LOK Notifier; can be itself if this Window has LOK notifier set...
Definition: window.cxx:3258
const Color & GetOverlineColor() const
Definition: window3.cxx:118
SAL_DLLPRIVATE void ImplInvalidate(const vcl::Region *rRegion, InvalidateFlags nFlags)
Definition: paint.cxx:780
tools::Long mnOutOffX
Definition: window.h:403
void SetLayoutMode(vcl::text::ComplexTextLayoutFlags nTextLayoutMode)
Definition: text.cxx:58
SAL_DLLPRIVATE void ImplClipBoundaries(vcl::Region &rRegion, bool bThis, bool bOverlaps)
void Hide()
Definition: window.hxx:884
VclPtr< vcl::Window > mpLastChild
Definition: window.h:232
constexpr tools::Long GetWidth() const
vcl::RenderContext * GetRenderContext()
Returns either the frame's buffer or the window, in case of no buffering.
Definition: paint.cxx:156
void Pop()
Definition: stack.cxx:92
virtual OUString GetText() const
Definition: window.cxx:3055
void SetWindowRegionPixel()
Definition: paint.cxx:1037
void Play(GDIMetaFile &rMtf)
Definition: gdimtf.cxx:322
SAL_DLLPRIVATE void ImplValidate()
Definition: paint.cxx:960
static Color HSBtoRGB(sal_uInt16 nHue, sal_uInt16 nSaturation, sal_uInt16 nBrightness)
tools::Long AdjustBottom(tools::Long nVertMoveDelta)
void SetTextFillColor()
Definition: window3.cxx:97
void SetTextLineColor()
Definition: textline.cxx:881
void DrawRect(const tools::Rectangle &rRect)
Definition: rect.cxx:51
tools::Rectangle maBufferedRect
Rectangle in the buffer that has to be painted to the screen.
Definition: window.h:175
ImplPaintFlags
Definition: window.h:197
constexpr bool IsEmpty() const
const Color & GetControlForeground() const
Definition: window2.cxx:1066
bool IsEmpty() const
Definition: region.cxx:228
void SetLineColor()
Definition: line.cxx:36
void PaintToDevice(::OutputDevice *pDevice, const Point &rPos)
Definition: paint.cxx:1555
void SetRefPoint()
Definition: outdev.cxx:288
virtual void PrePaint(vcl::RenderContext &rRenderContext)
Definition: paint.cxx:1012
void SetConnectMetaFile(GDIMetaFile *pMtf)
Definition: outdev.cxx:212
bool IsRTLEnabled() const
Definition: outdev.hxx:1274
Point LogicToPixel(const Point &rLogicPt) const
Definition: window3.cxx:131
void StartBufferedPaint()
Start buffered paint: set it up to have the same settings as m_pWindow.
Definition: paint.cxx:227
bool IsEmpty() const
#define VCL_GL_INFO(stream)
Helper to do a SAL_INFO as well as a GL log.
ImplPaintFlags m_nPaintFlags
Definition: paint.cxx:173
bool IsClipRegion() const
Definition: outdev.hxx:563
bool IsDark() const
void DrawSelectionBackground(const tools::Rectangle &rRect, sal_uInt16 highlight, bool bChecked, bool bDrawBorder)
Definition: window.cxx:3458
void SetEmpty()
Definition: region.cxx:1420
const MapMode & GetMapMode() const
Definition: window3.cxx:99
virtual void EnableRTL(bool bEnable=true) override
Definition: virdev.cxx:392
void SetParent(vcl::Window *pNewParent)
Definition: stacking.cxx:831
bool SetOutputSizePixel(const Size &rNewSize, bool bErase=true)
Definition: virdev.cxx:404
virtual void ApplySettings(vcl::RenderContext &rRenderContext)
Definition: window.cxx:3843
void DrawTransparent(const tools::PolyPolygon &rPolyPoly, sal_uInt16 nTransparencePercent)
Any aHelper
SAL_DLLPRIVATE void ImplCallOverlapPaint()
Definition: paint.cxx:625
~PaintHelper()
Definition: paint.cxx:536
virtual void Invalidate(InvalidateFlags nFlags=InvalidateFlags::NONE)
Definition: paint.cxx:1143
SAL_DLLPRIVATE bool ImplIsAntiparallel() const
Definition: outdev.cxx:662
vcl::Region & GetPaintRegion()
Definition: paint.cxx:203
bool m_bPop
Definition: paint.cxx:174
bool m_bStartedBufferedPaint
This PaintHelper started a buffered paint, and should paint it on the screen when being destructed...
Definition: paint.cxx:176
virtual bool HasMirroredGraphics() const
Definition: outdev.cxx:710
std::unique_ptr< vcl::Region > m_pChildRegion
Definition: paint.cxx:169
void CopyArea(tools::Long nDestX, tools::Long nDestY, tools::Long nSrcX, tools::Long nSrcY, tools::Long nSrcWidth, tools::Long nSrcHeight, const OutputDevice &rOutDev)
SAL_DLLPRIVATE void PopPaintHelper(PaintHelper const *pHelper)
Definition: paint.cxx:520
void SetFillColor()
Definition: fill.cxx:29
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_GRAY
Some things multiple-inherit from VclAbstractDialog and OutputDevice, so we need to use virtual inher...
Definition: outdev.hxx:175
const AllSettings & GetSettings() const
Definition: window3.cxx:129
SAL_DLLPRIVATE tools::Long ImplLogicWidthToDevicePixel(tools::Long nWidth) const
Convert a logical width to a width in units of device pixels.
Definition: map.cxx:324
void SetTextColor(const Color &rColor)
Definition: text.cxx:714
bool HasPaintEvent() const
Definition: paint.cxx:1240
std::unique_ptr< WindowImpl > mpWindowImpl
Definition: window.hxx:483
void SetPaintRect(const tools::Rectangle &rRect)
Definition: paint.cxx:183
SAL_DLLPRIVATE vcl::Window * ImplGetParent() const
Definition: window2.cxx:854
constexpr tools::Long Top() const
virtual void PixelInvalidate(const tools::Rectangle *pRectangle)
Notification about some rectangle of the output device got invalidated.
Definition: paint.cxx:1201
void Intersect(const tools::Rectangle &rRegion)
Definition: region.cxx:581
void Validate()
Definition: paint.cxx:1232
void SetOverlineColor()
Definition: textline.cxx:906
bool DrawNativeControl(ControlType nType, ControlPart nPart, const tools::Rectangle &rControlRegion, ControlState nState, const ImplControlValue &aValue, const OUString &aCaption, const Color &rBackgroundColor=COL_AUTO)
Request rendering of a particular control and/or part.
SAL_DLLPRIVATE void ImplScroll(const tools::Rectangle &rRect, tools::Long nHorzScroll, tools::Long nVertScroll, ScrollFlags nFlags)
Definition: paint.cxx:1629
const AllSettings & GetSettings() const
Definition: outdev.hxx:295
void SetPaintTransparent(bool bTransparent)
Definition: paint.cxx:1025
MapUnit GetMapUnit() const
Definition: mapmod.cxx:138
Sets up the buffer to have settings matching the window, and restores the original state in the dtor...
Definition: window.h:396
PushFlags
Definition: State.hxx:39
Point PixelToLogic(const Point &rDevicePt) const
Definition: window3.cxx:161
void WindStart()
Definition: gdimtf.cxx:549
void SetTextAlign(TextAlign eAlign)
Definition: window3.cxx:120
RasterOp
Definition: RasterOp.hxx:22
ControlPart mnNativeBackground
Definition: window.h:290
tools::Rectangle GetOutputRectPixel() const
Definition: window3.cxx:91
vcl::Window * GetParent() const
Definition: window2.cxx:1091
SAL_DLLPRIVATE void ImplCalcOverlapRegion(const tools::Rectangle &rSourceRect, vcl::Region &rRegion, bool bChildren, bool bSiblings)
SAL_DLLPRIVATE void ImplInvalidateParentFrameRegion(const vcl::Region &rRegion)
Definition: paint.cxx:769
void SetPaintRect(const tools::Rectangle &rRectangle)
If this is called, then the dtor will also copy rRectangle to the window from the buffer...
Definition: paint.cxx:151
tools::Long GetOutOffYPixel() const
Definition: outdev.hxx:323
constexpr Point TopLeft() const
tools::Long AdjustTop(tools::Long nVertMoveDelta)
MapUnit GetMapUnit()
AllSettings maSettings
Definition: window.h:402
SAL_WARN_UNUSED_RESULT Point PixelToLogic(const Point &rDevicePt) const
Definition: map.cxx:1109
SAL_DLLPRIVATE void ImplValidateFrameRegion(const vcl::Region *rRegion, ValidateFlags nFlags)
Definition: paint.cxx:920
SAL_DLLPRIVATE vcl::Window * ImplGetFirstOverlapWindow()
Definition: window2.cxx:869
A construction helper for a temporary VclPtr.
Definition: vclptr.hxx:275
void SetSelectionRect(const tools::Rectangle &rRect)
Definition: paint.cxx:187
VclPtr< VirtualDevice > mpAlphaVDev
Definition: outdev.hxx:202
void Exclude(const tools::Rectangle &rRegion)
Definition: region.cxx:678
constexpr Size GetSize() const
SAL_DLLPRIVATE vcl::Region ImplPixelToDevicePixel(const vcl::Region &rRegion) const
Convert a region in pixel units to a region in device pixel units and coords.
Definition: map.cxx:576
void Erase()
Definition: wallpaper.cxx:96
def rectangle(l)
Color GetBackgroundColor() const
Definition: window3.cxx:214
tools::Rectangle & Union(const tools::Rectangle &rRect)
const Color & GetButtonTextColor() const
#define SAL_WARN_IF(condition, area, stream)
void DoPaint(const vcl::Region *pRegion)
Definition: paint.cxx:247
void SetFont(const vcl::Font &rNewFont)
Definition: outdev/font.cxx:53
SAL_DLLPRIVATE void ImplInvalidateOverlapFrameRegion(const vcl::Region &rRegion)
Definition: paint.cxx:750
Color GetLineColor(Color const &rColor, DrawModeFlags nDrawMode, StyleSettings const &rStyleSettings)
Definition: drawmode.cxx:30
tools::Rectangle m_aPaintRect
Definition: window.h:405
bool IsVisible() const
Definition: window2.cxx:1096
bool mbInitClipRegion
Definition: outdev.hxx:259
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_WHITE
::OutputDevice const * GetOutDev() const
Definition: window.cxx:568
if(aStr!=aBuf) UpdateName_Impl(m_xFollowLb.get()
void EnableChildTransparentMode(bool bEnable=true)
Definition: window2.cxx:1016
void SetRasterOp(RasterOp eRasterOp)
Definition: outdev.cxx:313
void SetOutOffXPixel(tools::Long nOutOffX)
Definition: outdev.cxx:389
SAL_DLLPRIVATE void PushPaintHelper(PaintHelper *pHelper, vcl::RenderContext &rRenderContext)
Definition: paint.cxx:476
const Color & GetTextColor() const
Definition: window3.cxx:109
virtual void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect)
Definition: paint.cxx:1020
const char * name
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_BLACK
const vcl::Font & GetFont() const
Definition: window3.cxx:58
RasterOp GetRasterOp() const
Definition: outdev.hxx:504
virtual void DrawOutDev(const Point &rDestPt, const Size &rDestSize, const Point &rSrcPt, const Size &rSrcSize)
Definition: outdev.cxx:424
SAL_DLLPRIVATE bool ImplSetClipFlag(bool bSysObjOnlySmaller=false)
TextAlign GetTextAlign() const
Definition: window3.cxx:128
Color GetTextFillColor() const
Definition: window3.cxx:114
tools::Long mnOutWidth
Definition: outdev.hxx:216
Size GetOutputSizePixel() const
Definition: window3.cxx:89
void SetFontHeight(tools::Long nHeight)
Definition: font/font.cxx:854
bool IsBitmap() const
Definition: wall.cxx:189
SAL_DLLPRIVATE bool ImplClipChildren(vcl::Region &rRegion) const
SAL_DLLPRIVATE tools::Rectangle ImplLogicToDevicePixel(const tools::Rectangle &rLogicRect) const
Convert a logical rectangle to a rectangle in physical device pixel units.
Definition: map.cxx:386
bool mbDevOutput
Definition: outdev.hxx:251
bool IsPaintTransparent() const
Definition: window2.cxx:1031
SAL_DLLPRIVATE void ImplInvertFocus(const tools::Rectangle &rRect)
Definition: mouse.cxx:176
BitmapEx GetBitmapEx(const Point &rSrcPt, const Size &rSize) const
Query extended bitmap (with alpha channel, if available).
Definition: bitmapex.cxx:149
void Move(tools::Long nHorzMoveDelta, tools::Long nVertMoveDelta)
reference_type * get() const
Get the body.
Definition: vclptr.hxx:143
bool IsEnabled() const
Definition: window2.cxx:1116
const vcl::ILibreOfficeKitNotifier * GetLOKNotifier() const
Definition: window.cxx:3248
tools::Long mnOutOffX
Output offset for device output in pixel (pseudo window offset within window system's frames) ...
Definition: outdev.hxx:213
tools::Long AdjustLeft(tools::Long nHorzMoveDelta)
#define SAL_WARN(area, stream)
WinBits GetStyle() const
Definition: window2.cxx:947
bool IsOverlineColor() const
Definition: window3.cxx:119
Definition: timer.hxx:26
SAL_DLLPRIVATE tools::Rectangle ImplDevicePixelToLogic(const tools::Rectangle &rPixelRect) const
Convert a rectangle in physical pixel units to a rectangle in physical pixel units and coords...
Definition: map.cxx:545
void SetFont(const vcl::Font &rNewFont)
Definition: window3.cxx:59
virtual void LogicInvalidate(const tools::Rectangle *pRectangle)
Notification about some rectangle of the output device got invalidated.Used for the main document win...
Definition: paint.cxx:1190
vcl::Region m_aPaintRegion
Definition: paint.cxx:172
virtual void PostPaint(vcl::RenderContext &rRenderContext)
Definition: paint.cxx:1016
void CallEventListeners(VclEventId nEvent, void *pData=nullptr)
Definition: event.cxx:218
bool IsReallyVisible() const
Definition: window2.cxx:1101
void SetRestoreCursor(bool bRestoreCursor)
Definition: paint.cxx:191
ImplPaintFlags mnPaintFlags
Definition: window.h:292
static void DrawSelectionBackground(vcl::RenderContext &rRenderContext, vcl::Window const &rWindow, const tools::Rectangle &rRect, sal_uInt16 nHighlight, bool bChecked, bool bDrawBorder, bool bDrawExtBorderOnly, Color *pSelectionTextColor=nullptr, tools::Long nCornerRadius=0, Color const *pPaintColor=nullptr)
Definition: paint.cxx:324
tools::Long GetOutOffXPixel() const
Definition: window3.cxx:123
rtl::OString toString() const
The parent window is not invalidated.
vcl::Window * ImplGetDefaultWindow()
Returns either the application window, or the default GL context window.
Definition: svdata.cxx:209
const Wallpaper & GetBackground() const
Definition: window3.cxx:63
IMPL_LINK_NOARG(QuickSelectionEngine_Data, SearchStringTimeout, Timer *, void)
SAL_DLLPRIVATE tools::Long ImplLogicHeightToDevicePixel(tools::Long nHeight) const
Convert a logical height to a height in units of device pixels.
Definition: map.cxx:332
bool SupportsDoubleBuffering() const
Can the widget derived from this Window do the double-buffering via RenderContext properly...
Definition: window.cxx:3853
SAL_DLLPRIVATE sal_Int32 GetDPIY() const
Get the output device's DPI y-axis value.
Definition: outdev.hxx:395
The child windows are not invalidated.
bool m_bRestoreCursor
Definition: paint.cxx:175
sal_Int32 h
WinBits const WB_CLIPCHILDREN
sal_Int32 nState
tools::Long GetAverageFontWidth() const
Definition: font/font.cxx:857
PaintHelper(vcl::Window *pWindow, ImplPaintFlags nPaintFlags)
Definition: paint.cxx:218
virtual void SetPosPixel(const Point &rNewPos)
Definition: window2.cxx:1251
bool isDisposed() const
VclPtr< vcl::Window > m_pWindow
Definition: window.h:399
bool mbTrackVisible
Definition: window.h:311
SAL_DLLPRIVATE sal_Int32 GetDPIX() const
Get the output device's DPI x-axis value.
Definition: outdev.hxx:389
void SetTextAlign(TextAlign eAlign)
Definition: text.cxx:772
constexpr tools::Long GetHeight() const
Wallpaper maBackground
Definition: window.h:401
void Show(bool bVisible=true, ShowFlags nFlags=ShowFlags::NONE)
Definition: window.cxx:2187