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 {
651  {
652  // Tiled rendering is used, idle paint does not need to do anything.
653  mpWindowImpl->mpFrameData->maPaintIdle.Stop();
654  return;
655  }
656 
657  comphelper::ProfileZone aZone("VCL idle re-paint");
658 
659  // save paint events until layout is done
660  if (IsSystemWindow() && static_cast<const SystemWindow*>(this)->hasPendingLayout())
661  {
662  mpWindowImpl->mpFrameData->maPaintIdle.Start();
663  return;
664  }
665 
666  // save paint events until resizing or initial sizing done
667  if (mpWindowImpl->mbFrame &&
668  mpWindowImpl->mpFrameData->maResizeIdle.IsActive())
669  {
670  mpWindowImpl->mpFrameData->maPaintIdle.Start();
671  }
672  else if ( mpWindowImpl->mbReallyVisible )
673  {
674  ImplCallOverlapPaint();
675  }
676 }
677 
678 IMPL_LINK_NOARG(Window, ImplHandleResizeTimerHdl, Timer *, void)
679 {
680  comphelper::ProfileZone aZone("VCL idle resize");
681 
682  if( mpWindowImpl->mbReallyVisible )
683  {
684  ImplCallResize();
685  if( mpWindowImpl->mpFrameData->maPaintIdle.IsActive() )
686  {
687  mpWindowImpl->mpFrameData->maPaintIdle.Stop();
688  mpWindowImpl->mpFrameData->maPaintIdle.Invoke( nullptr );
689  }
690  }
691 }
692 
694 {
696  {
697  // Tiled rendering is used, so there's no need to invalidate for idle painting.
698  return;
699  }
700 
701  // set PAINTCHILDREN for all parent windows till the first OverlapWindow
702  if ( !ImplIsOverlapWindow() )
703  {
704  vcl::Window* pTempWindow = this;
706  do
707  {
708  pTempWindow = pTempWindow->ImplGetParent();
709  if ( pTempWindow->mpWindowImpl->mnPaintFlags & ImplPaintFlags::PaintChildren )
710  break;
711  pTempWindow->mpWindowImpl->mnPaintFlags |= ImplPaintFlags::PaintChildren | nTranspPaint;
712  if( ! pTempWindow->IsPaintTransparent() )
713  nTranspPaint = ImplPaintFlags::NONE;
714  }
715  while ( !pTempWindow->ImplIsOverlapWindow() );
716  }
717 
718  // set Paint-Flags
719  mpWindowImpl->mnPaintFlags |= ImplPaintFlags::Paint;
720  if ( nFlags & InvalidateFlags::Children )
722  if ( !(nFlags & InvalidateFlags::NoErase) )
723  mpWindowImpl->mnPaintFlags |= ImplPaintFlags::Erase;
724 
725  if ( !pRegion )
726  mpWindowImpl->mnPaintFlags |= ImplPaintFlags::PaintAll;
727  else if ( !(mpWindowImpl->mnPaintFlags & ImplPaintFlags::PaintAll) )
728  {
729  // if not everything has to be redrawn, add the region to it
730  mpWindowImpl->maInvalidateRegion.Union( *pRegion );
731  }
732 
733  // Handle transparent windows correctly: invalidate must be done on the first opaque parent
735  && ImplGetParent() )
736  {
737  vcl::Window *pParent = ImplGetParent();
738  while( pParent && pParent->IsPaintTransparent() )
739  pParent = pParent->ImplGetParent();
740  if( pParent )
741  {
742  vcl::Region *pChildRegion;
743  if ( mpWindowImpl->mnPaintFlags & ImplPaintFlags::PaintAll )
744  // invalidate the whole child window region in the parent
745  pChildRegion = &ImplGetWinChildClipRegion();
746  else
747  // invalidate the same region in the parent that has to be repainted in the child
748  pChildRegion = &mpWindowImpl->maInvalidateRegion;
749 
750  nFlags |= InvalidateFlags::Children; // paint should also be done on all children
751  nFlags &= ~InvalidateFlags::NoErase; // parent should paint and erase to create proper background
752  pParent->ImplInvalidateFrameRegion( pChildRegion, nFlags );
753  }
754  }
755 
756  if ( !mpWindowImpl->mpFrameData->maPaintIdle.IsActive() )
757  mpWindowImpl->mpFrameData->maPaintIdle.Start();
758 }
759 
761 {
763  {
764  // Tiled rendering is used, so there's no need to invalidate for idle painting.
765  return;
766  }
767 
768  vcl::Region aRegion = rRegion;
769 
770  ImplClipBoundaries( aRegion, true, true );
771  if ( !aRegion.IsEmpty() )
773 
774  // now we invalidate the overlapping windows
775  vcl::Window* pTempWindow = mpWindowImpl->mpFirstOverlap;
776  while ( pTempWindow )
777  {
778  if ( pTempWindow->IsVisible() )
779  pTempWindow->ImplInvalidateOverlapFrameRegion( rRegion );
780 
781  pTempWindow = pTempWindow->mpWindowImpl->mpNext;
782  }
783 }
784 
786 {
787  if ( mpWindowImpl->mbOverlapWin )
788  mpWindowImpl->mpFrameWindow->ImplInvalidateOverlapFrameRegion( rRegion );
789  else
790  {
791  if( ImplGetParent() )
793  }
794 }
795 
796 void Window::ImplInvalidate( const vcl::Region* pRegion, InvalidateFlags nFlags )
797 {
799  {
800  // Tiled rendering is used, so there's no need to invalidate for idle painting.
801  return;
802  }
803 
804  // check what has to be redrawn
805  bool bInvalidateAll = !pRegion;
806 
807  // take Transparent-Invalidate into account
808  vcl::Window* pOpaqueWindow = this;
809  if ( (mpWindowImpl->mbPaintTransparent && !(nFlags & InvalidateFlags::NoTransparent)) || (nFlags & InvalidateFlags::Transparent) )
810  {
811  vcl::Window* pTempWindow = pOpaqueWindow->ImplGetParent();
812  while ( pTempWindow )
813  {
814  if ( !pTempWindow->IsPaintTransparent() )
815  {
816  pOpaqueWindow = pTempWindow;
817  nFlags |= InvalidateFlags::Children;
818  bInvalidateAll = false;
819  break;
820  }
821 
822  if ( pTempWindow->ImplIsOverlapWindow() )
823  break;
824 
825  pTempWindow = pTempWindow->ImplGetParent();
826  }
827  }
828 
829  // assemble region
830  InvalidateFlags nOrgFlags = nFlags;
832  {
833  if ( GetStyle() & WB_CLIPCHILDREN )
834  nFlags |= InvalidateFlags::NoChildren;
835  else
836  nFlags |= InvalidateFlags::Children;
837  }
838  if ( (nFlags & InvalidateFlags::NoChildren) && mpWindowImpl->mpFirstChild )
839  bInvalidateAll = false;
840  if ( bInvalidateAll )
841  ImplInvalidateFrameRegion( nullptr, nFlags );
842  else
843  {
844  vcl::Region aRegion( GetOutputRectPixel() );
845  if ( pRegion )
846  {
847  // RTL: remirror region before intersecting it
848  if ( GetOutDev()->ImplIsAntiparallel() )
849  {
850  const OutputDevice *pOutDev = GetOutDev();
851 
852  vcl::Region aRgn( *pRegion );
853  pOutDev->ReMirror( aRgn );
854  aRegion.Intersect( aRgn );
855  }
856  else
857  aRegion.Intersect( *pRegion );
858  }
859  ImplClipBoundaries( aRegion, true, true );
860  if ( nFlags & InvalidateFlags::NoChildren )
861  {
862  nFlags &= ~InvalidateFlags::Children;
863  if ( !(nFlags & InvalidateFlags::NoClipChildren) )
864  {
865  if ( nOrgFlags & InvalidateFlags::NoChildren )
866  ImplClipAllChildren( aRegion );
867  else
868  {
869  if ( ImplClipChildren( aRegion ) )
870  nFlags |= InvalidateFlags::Children;
871  }
872  }
873  }
874  if ( !aRegion.IsEmpty() )
875  ImplInvalidateFrameRegion( &aRegion, nFlags ); // transparency is handled here, pOpaqueWindow not required
876  }
877 
878  if ( nFlags & InvalidateFlags::Update )
879  pOpaqueWindow->PaintImmediately(); // start painting at the opaque parent
880 }
881 
883  tools::Long nHorzScroll, tools::Long nVertScroll,
884  bool bChildren )
885 {
887  {
888  vcl::Region aTempRegion = mpWindowImpl->maInvalidateRegion;
889  aTempRegion.Intersect( rRect );
890  aTempRegion.Move( nHorzScroll, nVertScroll );
891  mpWindowImpl->maInvalidateRegion.Union( aTempRegion );
892  }
893 
894  if ( bChildren && (mpWindowImpl->mnPaintFlags & ImplPaintFlags::PaintChildren) )
895  {
896  vcl::Window* pWindow = mpWindowImpl->mpFirstChild;
897  while ( pWindow )
898  {
899  pWindow->ImplMoveInvalidateRegion( rRect, nHorzScroll, nVertScroll, true );
900  pWindow = pWindow->mpWindowImpl->mpNext;
901  }
902  }
903 }
904 
906  tools::Long nHorzScroll, tools::Long nVertScroll,
907  bool bChildren )
908 {
909  // also shift Paint-Region when paints need processing
910  ImplMoveInvalidateRegion( rRect, nHorzScroll, nVertScroll, bChildren );
911  // Paint-Region should be shifted, as drawn by the parents
912  if ( ImplIsOverlapWindow() )
913  return;
914 
915  vcl::Region aPaintAllRegion;
916  vcl::Window* pPaintAllWindow = this;
917  do
918  {
919  pPaintAllWindow = pPaintAllWindow->ImplGetParent();
920  if ( pPaintAllWindow->mpWindowImpl->mnPaintFlags & ImplPaintFlags::PaintAllChildren )
921  {
922  if ( pPaintAllWindow->mpWindowImpl->mnPaintFlags & ImplPaintFlags::PaintAll )
923  {
924  aPaintAllRegion.SetEmpty();
925  break;
926  }
927  else
928  aPaintAllRegion.Union( pPaintAllWindow->mpWindowImpl->maInvalidateRegion );
929  }
930  }
931  while ( !pPaintAllWindow->ImplIsOverlapWindow() );
932  if ( !aPaintAllRegion.IsEmpty() )
933  {
934  aPaintAllRegion.Move( nHorzScroll, nVertScroll );
936  if ( bChildren )
937  nPaintFlags |= InvalidateFlags::Children;
938  ImplInvalidateFrameRegion( &aPaintAllRegion, nPaintFlags );
939  }
940 }
941 
943 {
944  if ( !pRegion )
945  mpWindowImpl->maInvalidateRegion.SetEmpty();
946  else
947  {
948  // when all child windows have to be drawn we need to invalidate them before doing so
949  if ( (mpWindowImpl->mnPaintFlags & ImplPaintFlags::PaintAllChildren) && mpWindowImpl->mpFirstChild )
950  {
951  vcl::Region aChildRegion = mpWindowImpl->maInvalidateRegion;
952  if ( mpWindowImpl->mnPaintFlags & ImplPaintFlags::PaintAll )
953  {
954  aChildRegion = GetOutputRectPixel();
955  }
956  vcl::Window* pChild = mpWindowImpl->mpFirstChild;
957  while ( pChild )
958  {
960  pChild = pChild->mpWindowImpl->mpNext;
961  }
962  }
963  if ( mpWindowImpl->mnPaintFlags & ImplPaintFlags::PaintAll )
964  {
965  mpWindowImpl->maInvalidateRegion = GetOutputRectPixel();
966  }
967  mpWindowImpl->maInvalidateRegion.Exclude( *pRegion );
968  }
969  mpWindowImpl->mnPaintFlags &= ~ImplPaintFlags::PaintAll;
970 
971  if ( nFlags & ValidateFlags::Children )
972  {
973  vcl::Window* pChild = mpWindowImpl->mpFirstChild;
974  while ( pChild )
975  {
976  pChild->ImplValidateFrameRegion( pRegion, nFlags );
977  pChild = pChild->mpWindowImpl->mpNext;
978  }
979  }
980 }
981 
983 {
984  // assemble region
985  bool bValidateAll = true;
987  if ( GetStyle() & WB_CLIPCHILDREN )
988  nFlags |= ValidateFlags::NoChildren;
989  else
990  nFlags |= ValidateFlags::Children;
991  if ( (nFlags & ValidateFlags::NoChildren) && mpWindowImpl->mpFirstChild )
992  bValidateAll = false;
993  if ( bValidateAll )
994  ImplValidateFrameRegion( nullptr, nFlags );
995  else
996  {
997  vcl::Region aRegion( GetOutputRectPixel() );
998  ImplClipBoundaries( aRegion, true, true );
999  if ( nFlags & ValidateFlags::NoChildren )
1000  {
1001  nFlags &= ~ValidateFlags::Children;
1002  if ( ImplClipChildren( aRegion ) )
1003  nFlags |= ValidateFlags::Children;
1004  }
1005  if ( !aRegion.IsEmpty() )
1006  ImplValidateFrameRegion( &aRegion, nFlags );
1007  }
1008 }
1009 
1011 {
1012  if ( !mpWindowImpl || !mpWindowImpl->mbReallyVisible )
1013  return;
1014 
1015  bool bFlush = false;
1016  if ( mpWindowImpl->mpFrameWindow->mpWindowImpl->mbPaintFrame )
1017  {
1018  Point aPoint( 0, 0 );
1019  vcl::Region aRegion( tools::Rectangle( aPoint, GetOutputSizePixel() ) );
1021  if ( mpWindowImpl->mbFrame || (mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame) )
1022  bFlush = true;
1023  }
1024 
1025  // an update changes the OverlapWindow, such that for later paints
1026  // not too much has to be drawn, if ALLCHILDREN etc. is set
1028  pWindow->ImplCallOverlapPaint();
1029 
1030  if ( bFlush )
1031  GetOutDev()->Flush();
1032 }
1033 
1034 void Window::PrePaint(vcl::RenderContext& /*rRenderContext*/)
1035 {
1036 }
1037 
1038 void Window::PostPaint(vcl::RenderContext& /*rRenderContext*/)
1039 {
1040 }
1041 
1042 void Window::Paint(vcl::RenderContext& /*rRenderContext*/, const tools::Rectangle& rRect)
1043 {
1044  CallEventListeners(VclEventId::WindowPaint, const_cast<tools::Rectangle *>(&rRect));
1045 }
1046 
1047 void Window::SetPaintTransparent( bool bTransparent )
1048 {
1049  // transparency is not useful for frames as the background would have to be provided by a different frame
1050  if( bTransparent && mpWindowImpl->mbFrame )
1051  return;
1052 
1053  if ( mpWindowImpl->mpBorderWindow )
1054  mpWindowImpl->mpBorderWindow->SetPaintTransparent( bTransparent );
1055 
1056  mpWindowImpl->mbPaintTransparent = bTransparent;
1057 }
1058 
1060 {
1061 
1062  if ( mpWindowImpl->mpBorderWindow )
1063  mpWindowImpl->mpBorderWindow->SetWindowRegionPixel();
1064  else if( mpWindowImpl->mbFrame )
1065  {
1066  mpWindowImpl->maWinRegion = vcl::Region(true);
1067  mpWindowImpl->mbWinRegion = false;
1068  mpWindowImpl->mpFrame->ResetClipRegion();
1069  }
1070  else
1071  {
1072  if ( mpWindowImpl->mbWinRegion )
1073  {
1074  mpWindowImpl->maWinRegion = vcl::Region(true);
1075  mpWindowImpl->mbWinRegion = false;
1076  ImplSetClipFlag();
1077 
1078  if ( IsReallyVisible() )
1079  {
1080  vcl::Region aRegion( GetOutputRectPixel() );
1082  }
1083  }
1084  }
1085 }
1086 
1088 {
1089 
1090  if ( mpWindowImpl->mpBorderWindow )
1091  mpWindowImpl->mpBorderWindow->SetWindowRegionPixel( rRegion );
1092  else if( mpWindowImpl->mbFrame )
1093  {
1094  if( !rRegion.IsNull() )
1095  {
1096  mpWindowImpl->maWinRegion = rRegion;
1097  mpWindowImpl->mbWinRegion = ! rRegion.IsEmpty();
1098 
1099  if( mpWindowImpl->mbWinRegion )
1100  {
1101  // set/update ClipRegion
1102  RectangleVector aRectangles;
1103  mpWindowImpl->maWinRegion.GetRegionRectangles(aRectangles);
1104  mpWindowImpl->mpFrame->BeginSetClipRegion(aRectangles.size());
1105 
1106  for (auto const& rectangle : aRectangles)
1107  {
1108  mpWindowImpl->mpFrame->UnionClipRegion(
1109  rectangle.Left(),
1110  rectangle.Top(),
1111  rectangle.GetWidth(), // orig nWidth was ((R - L) + 1), same as GetWidth does
1112  rectangle.GetHeight()); // same for height
1113  }
1114 
1115  mpWindowImpl->mpFrame->EndSetClipRegion();
1116  }
1117  else
1119  }
1120  else
1122  }
1123  else
1124  {
1125  if ( rRegion.IsNull() )
1126  {
1127  if ( mpWindowImpl->mbWinRegion )
1128  {
1129  mpWindowImpl->maWinRegion = vcl::Region(true);
1130  mpWindowImpl->mbWinRegion = false;
1131  ImplSetClipFlag();
1132  }
1133  }
1134  else
1135  {
1136  mpWindowImpl->maWinRegion = rRegion;
1137  mpWindowImpl->mbWinRegion = true;
1138  ImplSetClipFlag();
1139  }
1140 
1141  if ( IsReallyVisible() )
1142  {
1143  vcl::Region aRegion( GetOutputRectPixel() );
1145  }
1146  }
1147 }
1148 
1150 {
1151 
1152  if ( mpWindowImpl->mpPaintRegion )
1153  {
1154  vcl::Region aRegion = *mpWindowImpl->mpPaintRegion;
1155  aRegion.Move( -GetOutDev()->mnOutOffX, -GetOutDev()->mnOutOffY );
1156  return PixelToLogic( aRegion );
1157  }
1158  else
1159  {
1160  vcl::Region aPaintRegion(true);
1161  return aPaintRegion;
1162  }
1163 }
1164 
1166 {
1167  if ( !comphelper::LibreOfficeKit::isActive() && (!GetOutDev()->IsDeviceOutputNecessary() || !GetOutDev()->mnOutWidth || !GetOutDev()->mnOutHeight) )
1168  return;
1169 
1170  ImplInvalidate( nullptr, nFlags );
1171  LogicInvalidate(nullptr);
1172 }
1173 
1175 {
1176  if ( !comphelper::LibreOfficeKit::isActive() && (!GetOutDev()->IsDeviceOutputNecessary() || !GetOutDev()->mnOutWidth || !GetOutDev()->mnOutHeight) )
1177  return;
1178 
1179  OutputDevice *pOutDev = GetOutDev();
1180  tools::Rectangle aRect = pOutDev->ImplLogicToDevicePixel( rRect );
1181  if ( !aRect.IsEmpty() )
1182  {
1184  { // ImplInvalidate() immediately returns in LOK mode, skip useless Region construction
1185  vcl::Region aRegion( aRect );
1186  ImplInvalidate( &aRegion, nFlags );
1187  }
1188  tools::Rectangle aLogicRectangle(rRect);
1189  LogicInvalidate(&aLogicRectangle);
1190  }
1191 }
1192 
1193 void Window::Invalidate( const vcl::Region& rRegion, InvalidateFlags nFlags )
1194 {
1195  if ( !comphelper::LibreOfficeKit::isActive() && (!GetOutDev()->IsDeviceOutputNecessary() || !GetOutDev()->mnOutWidth || !GetOutDev()->mnOutHeight) )
1196  return;
1197 
1198  if ( rRegion.IsNull() )
1199  {
1200  ImplInvalidate( nullptr, nFlags );
1201  LogicInvalidate(nullptr);
1202  }
1203  else
1204  {
1205  vcl::Region aRegion = GetOutDev()->ImplPixelToDevicePixel( LogicToPixel( rRegion ) );
1206  if ( !aRegion.IsEmpty() )
1207  {
1208  ImplInvalidate( &aRegion, nFlags );
1209  tools::Rectangle aLogicRectangle = rRegion.GetBoundRect();
1210  LogicInvalidate(&aLogicRectangle);
1211  }
1212  }
1213 }
1214 
1216 {
1217  if(pRectangle)
1218  {
1219  tools::Rectangle aRect = GetOutDev()->ImplLogicToDevicePixel( *pRectangle );
1220  PixelInvalidate(&aRect);
1221  }
1222  else
1223  PixelInvalidate(nullptr);
1224 }
1225 
1227 {
1229  return;
1230 
1231  Size aSize = GetSizePixel();
1232  if (aSize.IsEmpty())
1233  return;
1234 
1235  if (const vcl::ILibreOfficeKitNotifier* pNotifier = GetLOKNotifier())
1236  {
1237  // In case we are routing the window, notify the client
1238  std::vector<vcl::LOKPayloadItem> aPayload;
1239  if (pRectangle)
1240  aPayload.emplace_back("rectangle", pRectangle->toString());
1241  else
1242  {
1243  const tools::Rectangle aRect(Point(0, 0), aSize);
1244  aPayload.emplace_back("rectangle", aRect.toString());
1245  }
1246 
1247  pNotifier->notifyWindow(GetLOKWindowId(), "invalidate", aPayload);
1248  }
1249  // Added for dialog items. Pass invalidation to the parent window.
1250  else if (VclPtr<vcl::Window> pParent = GetParentWithLOKNotifier())
1251  {
1253  pParent->PixelInvalidate(&aRect);
1254  }
1255 }
1256 
1258 {
1259  if ( !comphelper::LibreOfficeKit::isActive() && (!GetOutDev()->IsDeviceOutputNecessary() || !GetOutDev()->mnOutWidth || !GetOutDev()->mnOutHeight) )
1260  return;
1261 
1262  ImplValidate();
1263 }
1264 
1266 {
1267 
1268  if ( !mpWindowImpl->mbReallyVisible )
1269  return false;
1270 
1271  if ( mpWindowImpl->mpFrameWindow->mpWindowImpl->mbPaintFrame )
1272  return true;
1273 
1274  if ( mpWindowImpl->mnPaintFlags & ImplPaintFlags::Paint )
1275  return true;
1276 
1277  if ( !ImplIsOverlapWindow() )
1278  {
1279  const vcl::Window* pTempWindow = this;
1280  do
1281  {
1282  pTempWindow = pTempWindow->ImplGetParent();
1283  if ( pTempWindow->mpWindowImpl->mnPaintFlags & (ImplPaintFlags::PaintChildren | ImplPaintFlags::PaintAllChildren) )
1284  return true;
1285  }
1286  while ( !pTempWindow->ImplIsOverlapWindow() );
1287  }
1288 
1289  return false;
1290 }
1291 
1293 {
1294  if (!mpWindowImpl)
1295  return;
1296 
1297  if ( mpWindowImpl->mpBorderWindow )
1298  {
1299  mpWindowImpl->mpBorderWindow->PaintImmediately();
1300  return;
1301  }
1302 
1303  if ( !mpWindowImpl->mbReallyVisible )
1304  return;
1305 
1306  bool bFlush = false;
1307  if ( mpWindowImpl->mpFrameWindow->mpWindowImpl->mbPaintFrame )
1308  {
1309  Point aPoint( 0, 0 );
1310  vcl::Region aRegion( tools::Rectangle( aPoint, GetOutputSizePixel() ) );
1312  if ( mpWindowImpl->mbFrame || (mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame) )
1313  bFlush = true;
1314  }
1315 
1316  // First we should skip all windows which are Paint-Transparent
1317  vcl::Window* pUpdateWindow = this;
1318  vcl::Window* pWindow = pUpdateWindow;
1319  while ( !pWindow->ImplIsOverlapWindow() )
1320  {
1321  if ( !pWindow->mpWindowImpl->mbPaintTransparent )
1322  {
1323  pUpdateWindow = pWindow;
1324  break;
1325  }
1326  pWindow = pWindow->ImplGetParent();
1327  }
1328  // In order to limit drawing, an update only draws the window which
1329  // has PAINTALLCHILDREN set
1330  pWindow = pUpdateWindow;
1331  do
1332  {
1333  if ( pWindow->mpWindowImpl->mnPaintFlags & ImplPaintFlags::PaintAllChildren )
1334  pUpdateWindow = pWindow;
1335  if ( pWindow->ImplIsOverlapWindow() )
1336  break;
1337  pWindow = pWindow->ImplGetParent();
1338  }
1339  while ( pWindow );
1340 
1341  // if there is something to paint, trigger a Paint
1342  if ( pUpdateWindow->mpWindowImpl->mnPaintFlags & (ImplPaintFlags::Paint | ImplPaintFlags::PaintChildren) )
1343  {
1344  VclPtr<vcl::Window> xWindow(this);
1345 
1346  // trigger an update also for system windows on top of us,
1347  // otherwise holes would remain
1348  vcl::Window* pUpdateOverlapWindow = ImplGetFirstOverlapWindow();
1349  if (pUpdateOverlapWindow->mpWindowImpl)
1350  pUpdateOverlapWindow = pUpdateOverlapWindow->mpWindowImpl->mpFirstOverlap;
1351  else
1352  pUpdateOverlapWindow = nullptr;
1353  while ( pUpdateOverlapWindow )
1354  {
1355  pUpdateOverlapWindow->PaintImmediately();
1356  pUpdateOverlapWindow = pUpdateOverlapWindow->mpWindowImpl->mpNext;
1357  }
1358 
1359  pUpdateWindow->ImplCallPaint(nullptr, pUpdateWindow->mpWindowImpl->mnPaintFlags);
1360 
1361  if (comphelper::LibreOfficeKit::isActive() && pUpdateWindow->GetParentDialog())
1362  pUpdateWindow->LogicInvalidate(nullptr);
1363 
1364  if (xWindow->isDisposed())
1365  return;
1366 
1367  bFlush = true;
1368  }
1369 
1370  if ( bFlush )
1371  GetOutDev()->Flush();
1372 }
1373 
1374 void Window::ImplPaintToDevice( OutputDevice* i_pTargetOutDev, const Point& i_rPos )
1375 {
1376  // Special drawing when called through LOKit
1377  // TODO: Move to its own method
1379  {
1380  VclPtrInstance<VirtualDevice> pDevice(*i_pTargetOutDev);
1381 
1382  Size aSize(GetOutputSizePixel());
1383  pDevice->SetOutputSizePixel(aSize);
1384 
1385  vcl::Font aCopyFont = GetFont();
1386  pDevice->SetFont(aCopyFont);
1387 
1388  pDevice->SetTextColor(GetTextColor());
1389  if (GetOutDev()->IsLineColor())
1390  pDevice->SetLineColor(GetOutDev()->GetLineColor());
1391  else
1392  pDevice->SetLineColor();
1393 
1394  if (GetOutDev()->IsFillColor())
1395  pDevice->SetFillColor(GetOutDev()->GetFillColor());
1396  else
1397  pDevice->SetFillColor();
1398 
1399  if (IsTextLineColor())
1400  pDevice->SetTextLineColor(GetTextLineColor());
1401  else
1402  pDevice->SetTextLineColor();
1403 
1404  if (IsOverlineColor())
1405  pDevice->SetOverlineColor(GetOverlineColor());
1406  else
1407  pDevice->SetOverlineColor();
1408 
1409  if (IsTextFillColor())
1410  pDevice->SetTextFillColor(GetTextFillColor());
1411  else
1412  pDevice->SetTextFillColor();
1413 
1414  pDevice->SetTextAlign(GetTextAlign());
1415  pDevice->SetRasterOp(GetOutDev()->GetRasterOp());
1416 
1417  tools::Rectangle aPaintRect(Point(), GetOutputSizePixel());
1418 
1419  vcl::Region aClipRegion(GetOutDev()->GetClipRegion());
1420  pDevice->SetClipRegion();
1421  aClipRegion.Intersect(aPaintRect);
1422  pDevice->SetClipRegion(aClipRegion);
1423 
1425  Erase(*pDevice);
1426 
1427  pDevice->SetMapMode(GetMapMode());
1428 
1430 
1431  i_pTargetOutDev->DrawOutDev(i_rPos, aSize, Point(), pDevice->PixelToLogic(aSize), *pDevice);
1432 
1433  // get rid of virtual device now so they don't pile up during recursive calls
1434  pDevice.disposeAndClear();
1435 
1436 
1437  for( vcl::Window* pChild = mpWindowImpl->mpFirstChild; pChild; pChild = pChild->mpWindowImpl->mpNext )
1438  {
1439  if( pChild->mpWindowImpl->mpFrame == mpWindowImpl->mpFrame && pChild->IsVisible() )
1440  {
1441  tools::Long nDeltaX = pChild->GetOutDev()->mnOutOffX - GetOutDev()->mnOutOffX;
1442  tools::Long nDeltaY = pChild->GetOutDev()->mnOutOffY - GetOutDev()->mnOutOffY;
1443 
1444  Point aPos( i_rPos );
1445  aPos += Point(nDeltaX, nDeltaY);
1446 
1447  pChild->ImplPaintToDevice( i_pTargetOutDev, aPos );
1448  }
1449  }
1450  return;
1451  }
1452 
1453 
1454  bool bRVisible = mpWindowImpl->mbReallyVisible;
1455  mpWindowImpl->mbReallyVisible = mpWindowImpl->mbVisible;
1456  bool bDevOutput = GetOutDev()->mbDevOutput;
1457  GetOutDev()->mbDevOutput = true;
1458 
1459  const OutputDevice *pOutDev = GetOutDev();
1460  tools::Long nOldDPIX = pOutDev->GetDPIX();
1461  tools::Long nOldDPIY = pOutDev->GetDPIY();
1462  GetOutDev()->mnDPIX = i_pTargetOutDev->GetDPIX();
1463  GetOutDev()->mnDPIY = i_pTargetOutDev->GetDPIY();
1464  bool bOutput = GetOutDev()->IsOutputEnabled();
1465  GetOutDev()->EnableOutput();
1466 
1467  SAL_WARN_IF( GetMapMode().GetMapUnit() != MapUnit::MapPixel, "vcl.window", "MapMode must be PIXEL based" );
1468  if ( GetMapMode().GetMapUnit() != MapUnit::MapPixel )
1469  return;
1470 
1471  // preserve graphicsstate
1472  GetOutDev()->Push();
1473  vcl::Region aClipRegion( GetOutDev()->GetClipRegion() );
1474  GetOutDev()->SetClipRegion();
1475 
1476  GDIMetaFile* pOldMtf = GetOutDev()->GetConnectMetaFile();
1477  GDIMetaFile aMtf;
1478  GetOutDev()->SetConnectMetaFile( &aMtf );
1479 
1480  // put a push action to metafile
1481  GetOutDev()->Push();
1482  // copy graphics state to metafile
1483  vcl::Font aCopyFont = GetFont();
1484  if( nOldDPIX != GetOutDev()->mnDPIX || nOldDPIY != GetOutDev()->mnDPIY )
1485  {
1486  aCopyFont.SetFontHeight( aCopyFont.GetFontHeight() * GetOutDev()->mnDPIY / nOldDPIY );
1487  aCopyFont.SetAverageFontWidth( aCopyFont.GetAverageFontWidth() * GetOutDev()->mnDPIX / nOldDPIX );
1488  }
1489  SetFont( aCopyFont );
1491  if( GetOutDev()->IsLineColor() )
1493  else
1494  GetOutDev()->SetLineColor();
1495  if( GetOutDev()->IsFillColor() )
1497  else
1498  GetOutDev()->SetFillColor();
1499  if( IsTextLineColor() )
1501  else
1502  SetTextLineColor();
1503  if( IsOverlineColor() )
1505  else
1506  SetOverlineColor();
1507  if( IsTextFillColor() )
1509  else
1510  SetTextFillColor();
1512  GetOutDev()->SetRasterOp( GetOutDev()->GetRasterOp() );
1513  if( GetOutDev()->IsRefPoint() )
1514  GetOutDev()->SetRefPoint( GetOutDev()->GetRefPoint() );
1515  else
1516  GetOutDev()->SetRefPoint();
1517  GetOutDev()->SetLayoutMode( GetOutDev()->GetLayoutMode() );
1518 
1519  GetOutDev()->SetDigitLanguage( GetOutDev()->GetDigitLanguage() );
1520  tools::Rectangle aPaintRect(Point(0, 0), GetOutputSizePixel());
1521  aClipRegion.Intersect( aPaintRect );
1522  GetOutDev()->SetClipRegion( aClipRegion );
1523 
1524  // do the actual paint
1525 
1526  // background
1528  {
1529  Erase(*GetOutDev());
1530  }
1531  // foreground
1532  Paint(*GetOutDev(), aPaintRect);
1533  // put a pop action to metafile
1534  GetOutDev()->Pop();
1535 
1536  GetOutDev()->SetConnectMetaFile( pOldMtf );
1537  GetOutDev()->EnableOutput( bOutput );
1538  mpWindowImpl->mbReallyVisible = bRVisible;
1539 
1540  // paint metafile to VDev
1541  VclPtrInstance<VirtualDevice> pMaskedDevice(*i_pTargetOutDev,
1544 
1545  pMaskedDevice->SetOutputSizePixel( GetOutputSizePixel() );
1546  pMaskedDevice->EnableRTL( IsRTLEnabled() );
1547  aMtf.WindStart();
1548  aMtf.Play(*pMaskedDevice);
1549  BitmapEx aBmpEx( pMaskedDevice->GetBitmapEx( Point( 0, 0 ), aPaintRect.GetSize() ) );
1550  i_pTargetOutDev->DrawBitmapEx( i_rPos, aBmpEx );
1551  // get rid of virtual device now so they don't pile up during recursive calls
1552  pMaskedDevice.disposeAndClear();
1553 
1554  for( vcl::Window* pChild = mpWindowImpl->mpFirstChild; pChild; pChild = pChild->mpWindowImpl->mpNext )
1555  {
1556  if( pChild->mpWindowImpl->mpFrame == mpWindowImpl->mpFrame && pChild->IsVisible() )
1557  {
1558  tools::Long nDeltaX = pChild->GetOutDev()->mnOutOffX - GetOutDev()->mnOutOffX;
1559 
1560  if( pOutDev->HasMirroredGraphics() )
1561  nDeltaX = GetOutDev()->mnOutWidth - nDeltaX - pChild->GetOutDev()->mnOutWidth;
1562  tools::Long nDeltaY = pChild->GetOutOffYPixel() - GetOutOffYPixel();
1563  Point aPos( i_rPos );
1564  Point aDelta( nDeltaX, nDeltaY );
1565  aPos += aDelta;
1566  pChild->ImplPaintToDevice( i_pTargetOutDev, aPos );
1567  }
1568  }
1569 
1570  // restore graphics state
1571  GetOutDev()->Pop();
1572 
1573  GetOutDev()->EnableOutput( bOutput );
1574  mpWindowImpl->mbReallyVisible = bRVisible;
1575  GetOutDev()->mbDevOutput = bDevOutput;
1576  GetOutDev()->mnDPIX = nOldDPIX;
1577  GetOutDev()->mnDPIY = nOldDPIY;
1578 }
1579 
1580 void Window::PaintToDevice(OutputDevice* pDev, const Point& rPos)
1581 {
1582  if( !mpWindowImpl )
1583  return;
1584 
1585  SAL_WARN_IF( pDev->HasMirroredGraphics(), "vcl.window", "PaintToDevice to mirroring graphics" );
1586  SAL_WARN_IF( pDev->IsRTLEnabled(), "vcl.window", "PaintToDevice to mirroring device" );
1587 
1588  vcl::Window* pRealParent = nullptr;
1589  if( ! mpWindowImpl->mbVisible )
1590  {
1591  vcl::Window* pTempParent = ImplGetDefaultWindow();
1592  pTempParent->EnableChildTransparentMode();
1593  pRealParent = GetParent();
1594  SetParent( pTempParent );
1595  // trigger correct visibility flags for children
1596  Show();
1597  Hide();
1598  }
1599 
1600  bool bVisible = mpWindowImpl->mbVisible;
1601  mpWindowImpl->mbVisible = true;
1602 
1603  if( mpWindowImpl->mpBorderWindow )
1604  mpWindowImpl->mpBorderWindow->ImplPaintToDevice( pDev, rPos );
1605  else
1606  ImplPaintToDevice( pDev, rPos );
1607 
1608  mpWindowImpl->mbVisible = bVisible;
1609 
1610  if( pRealParent )
1611  SetParent( pRealParent );
1612 }
1613 
1614 void Window::Erase(vcl::RenderContext& rRenderContext)
1615 {
1616  if (!GetOutDev()->IsDeviceOutputNecessary() || GetOutDev()->ImplIsRecordLayout())
1617  return;
1618 
1619  bool bNativeOK = false;
1620 
1622 
1623  if (aCtrlPart == ControlPart::Entire && IsControlBackground())
1624  {
1625  // nothing to do here; background is drawn in corresponding drawNativeControl implementation
1626  bNativeOK = true;
1627  }
1628  else if (aCtrlPart != ControlPart::NONE && ! IsControlBackground())
1629  {
1630  tools::Rectangle aCtrlRegion(Point(), GetOutputSizePixel());
1632 
1633  if (IsEnabled())
1634  nState |= ControlState::ENABLED;
1635 
1636  bNativeOK = rRenderContext.DrawNativeControl(ControlType::WindowBackground, aCtrlPart, aCtrlRegion,
1637  nState, ImplControlValue(), OUString());
1638  }
1639 
1640  if (GetOutDev()->mbBackground && !bNativeOK)
1641  {
1642  RasterOp eRasterOp = GetOutDev()->GetRasterOp();
1643  if (eRasterOp != RasterOp::OverPaint)
1645  rRenderContext.DrawWallpaper(0, 0, GetOutDev()->mnOutWidth, GetOutDev()->mnOutHeight, GetOutDev()->maBackground);
1646  if (eRasterOp != RasterOp::OverPaint)
1647  rRenderContext.SetRasterOp(eRasterOp);
1648  }
1649 
1650  if (GetOutDev()->mpAlphaVDev)
1651  GetOutDev()->mpAlphaVDev->Erase();
1652 }
1653 
1655  tools::Long nHorzScroll, tools::Long nVertScroll, ScrollFlags nFlags )
1656 {
1657  if ( !GetOutDev()->IsDeviceOutputNecessary() )
1658  return;
1659 
1660  nHorzScroll = GetOutDev()->ImplLogicWidthToDevicePixel( nHorzScroll );
1661  nVertScroll = GetOutDev()->ImplLogicHeightToDevicePixel( nVertScroll );
1662 
1663  if ( !nHorzScroll && !nVertScroll )
1664  return;
1665 
1666  if ( mpWindowImpl->mpCursor )
1667  mpWindowImpl->mpCursor->ImplSuspend();
1668 
1669  ScrollFlags nOrgFlags = nFlags;
1670  if ( !(nFlags & (ScrollFlags::Children | ScrollFlags::NoChildren)) )
1671  {
1672  if ( GetStyle() & WB_CLIPCHILDREN )
1673  nFlags |= ScrollFlags::NoChildren;
1674  else
1675  nFlags |= ScrollFlags::Children;
1676  }
1677 
1678  vcl::Region aInvalidateRegion;
1679  bool bScrollChildren(nFlags & ScrollFlags::Children);
1680 
1681  if ( !mpWindowImpl->mpFirstChild )
1682  bScrollChildren = false;
1683 
1684  OutputDevice *pOutDev = GetOutDev();
1685 
1686  // RTL: check if this window requires special action
1687  bool bReMirror = GetOutDev()->ImplIsAntiparallel();
1688 
1689  tools::Rectangle aRectMirror( rRect );
1690  if( bReMirror )
1691  {
1692  // make sure the invalidate region of this window is
1693  // computed in the same coordinate space as the one from the overlap windows
1694  pOutDev->ReMirror( aRectMirror );
1695  }
1696 
1697  // adapt paint areas
1698  ImplMoveAllInvalidateRegions( aRectMirror, nHorzScroll, nVertScroll, bScrollChildren );
1699 
1700  ImplCalcOverlapRegion( aRectMirror, aInvalidateRegion, !bScrollChildren, false );
1701 
1702  // if the scrolling on the device is performed in the opposite direction
1703  // then move the overlaps in that direction to compute the invalidate region
1704  // on the correct side, i.e., revert nHorzScroll
1705  if (!aInvalidateRegion.IsEmpty())
1706  {
1707  aInvalidateRegion.Move(bReMirror ? -nHorzScroll : nHorzScroll, nVertScroll);
1708  }
1709 
1710  tools::Rectangle aDestRect(aRectMirror);
1711  aDestRect.Move(bReMirror ? -nHorzScroll : nHorzScroll, nVertScroll);
1712  vcl::Region aWinInvalidateRegion(aRectMirror);
1713  if (!SupportsDoubleBuffering())
1714  {
1715  // There will be no CopyArea() call below, so invalidate the
1716  // whole visible area, not only the smaller one that was just
1717  // scrolled in.
1718  aWinInvalidateRegion.Exclude(aDestRect);
1719  }
1720 
1721  aInvalidateRegion.Union(aWinInvalidateRegion);
1722 
1723  vcl::Region aRegion( GetOutputRectPixel() );
1724  if ( nFlags & ScrollFlags::Clip )
1725  aRegion.Intersect( rRect );
1726  if ( mpWindowImpl->mbWinRegion )
1727  aRegion.Intersect( GetOutDev()->ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
1728 
1729  aRegion.Exclude( aInvalidateRegion );
1730 
1731  ImplClipBoundaries( aRegion, false, true );
1732  if ( !bScrollChildren )
1733  {
1734  if ( nOrgFlags & ScrollFlags::NoChildren )
1735  ImplClipAllChildren( aRegion );
1736  else
1737  ImplClipChildren( aRegion );
1738  }
1739  if ( GetOutDev()->mbClipRegion && (nFlags & ScrollFlags::UseClipRegion) )
1740  aRegion.Intersect( GetOutDev()->maRegion );
1741  if ( !aRegion.IsEmpty() )
1742  {
1743  if ( mpWindowImpl->mpWinData )
1744  {
1745  if ( mpWindowImpl->mbFocusVisible )
1746  ImplInvertFocus( *mpWindowImpl->mpWinData->mpFocusRect );
1747  if ( mpWindowImpl->mbTrackVisible && (mpWindowImpl->mpWinData->mnTrackFlags & ShowTrackFlags::TrackWindow) )
1748  InvertTracking( *mpWindowImpl->mpWinData->mpTrackRect, mpWindowImpl->mpWinData->mnTrackFlags );
1749  }
1750 #ifndef IOS
1751  // This seems completely unnecessary with tiled rendering, and
1752  // causes the "AquaSalGraphics::copyArea() for non-layered
1753  // graphics" message. Presumably we should bypass this on all
1754  // platforms when dealing with a "window" that uses tiled
1755  // rendering at the moment. Unclear how to figure that out,
1756  // though. Also unclear whether we actually could just not
1757  // create a "frame window", whatever that exactly is, in the
1758  // tiled rendering case, or at least for platforms where tiles
1759  // rendering is all there is.
1760 
1761  SalGraphics* pGraphics = ImplGetFrameGraphics();
1762  // The invalidation area contains the area what would be copied here,
1763  // so avoid copying in case of double buffering.
1764  if (pGraphics && !SupportsDoubleBuffering())
1765  {
1766  if( bReMirror )
1767  {
1768  pOutDev->ReMirror( aRegion );
1769  }
1770 
1771  pOutDev->SelectClipRegion( aRegion, pGraphics );
1772  pGraphics->CopyArea( rRect.Left()+nHorzScroll, rRect.Top()+nVertScroll,
1773  rRect.Left(), rRect.Top(),
1774  rRect.GetWidth(), rRect.GetHeight(),
1775  *GetOutDev() );
1776  }
1777 #endif
1778  if ( mpWindowImpl->mpWinData )
1779  {
1780  if ( mpWindowImpl->mbFocusVisible )
1781  ImplInvertFocus( *mpWindowImpl->mpWinData->mpFocusRect );
1782  if ( mpWindowImpl->mbTrackVisible && (mpWindowImpl->mpWinData->mnTrackFlags & ShowTrackFlags::TrackWindow) )
1783  InvertTracking( *mpWindowImpl->mpWinData->mpTrackRect, mpWindowImpl->mpWinData->mnTrackFlags );
1784  }
1785  }
1786 
1787  if ( !aInvalidateRegion.IsEmpty() )
1788  {
1789  // RTL: the invalidate region for this windows is already computed in frame coordinates
1790  // so it has to be re-mirrored before calling the Paint-handler
1791  mpWindowImpl->mnPaintFlags |= ImplPaintFlags::CheckRtl;
1792 
1793  if ( !bScrollChildren )
1794  {
1795  if ( nOrgFlags & ScrollFlags::NoChildren )
1796  ImplClipAllChildren( aInvalidateRegion );
1797  else
1798  ImplClipChildren( aInvalidateRegion );
1799  }
1801  }
1802 
1803  if ( bScrollChildren )
1804  {
1805  vcl::Window* pWindow = mpWindowImpl->mpFirstChild;
1806  while ( pWindow )
1807  {
1808  Point aPos = pWindow->GetPosPixel();
1809  aPos += Point( nHorzScroll, nVertScroll );
1810  pWindow->SetPosPixel( aPos );
1811 
1812  pWindow = pWindow->mpWindowImpl->mpNext;
1813  }
1814  }
1815 
1816  if ( nFlags & ScrollFlags::Update )
1817  PaintImmediately();
1818 
1819  if ( mpWindowImpl->mpCursor )
1820  mpWindowImpl->mpCursor->ImplResume();
1821 }
1822 
1823 } /* namespace vcl */
1824 
1825 
1826 /* 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:882
void EnableOutput(bool bEnable=true)
Definition: outdev.cxx:333
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:425
void SetDigitLanguage(LanguageType)
Definition: text.cxx:68
void SetBackground()
Definition: window3.cxx:100
tools::Rectangle m_aPaintRect
Definition: paint.cxx:171
const Wallpaper & GetBackground() const
Definition: outdev.hxx:519
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:1374
void SetAverageFontWidth(tools::Long nWidth)
Definition: font/font.cxx:835
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:522
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:1614
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:476
ParentClipMode GetParentClipMode() const
sal_uInt8 GetLuminance() const
const Color & GetFaceColor() const
tools::Long GetOutOffXPixel() const
Definition: outdev.hxx:314
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:208
sal_Int32 mnDPIY
Definition: outdev.hxx:212
void SetTextFillColor()
Definition: text.cxx:706
vcl::Region GetPaintRegion() const
Definition: paint.cxx:1149
void SetPop()
Definition: paint.cxx:179
GDIMetaFile * GetConnectMetaFile() const
Definition: outdev.hxx:284
The invalidated area is updated immediately.
sal_Int32 mnDPIX
Definition: outdev.hxx:211
virtual void SetSettings(const AllSettings &rSettings)
Definition: outdev.cxx:216
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:1010
tools::Rectangle GetBoundRect() const
Definition: region.cxx:1217
void PaintImmediately()
Definition: paint.cxx:1292
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:693
bool GetRestoreCursor() const
Definition: paint.cxx:195
tools::Long GetFontHeight() const
Definition: font/font.cxx:834
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:905
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:381
SAL_DLLPRIVATE void ReMirror(Point &rPoint) const
Definition: outdev.cxx:665
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:796
tools::Long mnOutOffX
Definition: window.h:403
void SetLayoutMode(vcl::text::ComplexTextLayoutFlags nTextLayoutMode)
Definition: text.cxx:57
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:1059
void Play(GDIMetaFile &rMtf)
Definition: gdimtf.cxx:322
SAL_DLLPRIVATE void ImplValidate()
Definition: paint.cxx:982
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:1580
void SetRefPoint()
Definition: outdev.cxx:287
virtual void PrePaint(vcl::RenderContext &rRenderContext)
Definition: paint.cxx:1034
void SetConnectMetaFile(GDIMetaFile *pMtf)
Definition: outdev.cxx:211
bool IsRTLEnabled() const
Definition: outdev.hxx:1243
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:551
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:390
void SetParent(vcl::Window *pNewParent)
Definition: stacking.cxx:831
bool SetOutputSizePixel(const Size &rNewSize, bool bErase=true)
Definition: virdev.cxx:402
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:1165
SAL_DLLPRIVATE bool ImplIsAntiparallel() const
Definition: outdev.cxx:649
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:697
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:168
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:688
bool HasPaintEvent() const
Definition: paint.cxx:1265
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:1226
void Intersect(const tools::Rectangle &rRegion)
Definition: region.cxx:581
void Validate()
Definition: paint.cxx:1257
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:1654
const AllSettings & GetSettings() const
Definition: outdev.hxx:287
void SetPaintTransparent(bool bTransparent)
Definition: paint.cxx:1047
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:40
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:785
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:315
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:942
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:195
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:760
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:251
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:312
void SetOutOffXPixel(tools::Long nOutOffX)
Definition: outdev.cxx:376
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:1042
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:492
virtual void DrawOutDev(const Point &rDestPt, const Size &rDestSize, const Point &rSrcPt, const Size &rSrcSize)
Definition: outdev.cxx:411
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:209
Size GetOutputSizePixel() const
Definition: window3.cxx:89
void SetFontHeight(tools::Long nHeight)
Definition: font/font.cxx:833
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:243
bool IsPaintTransparent() const
Definition: window2.cxx:1031
SAL_DLLPRIVATE void ImplInvertFocus(const tools::Rectangle &rRect)
Definition: mouse.cxx:175
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:206
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:1215
vcl::Region m_aPaintRegion
Definition: paint.cxx:172
virtual void PostPaint(vcl::RenderContext &rRenderContext)
Definition: paint.cxx:1038
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:387
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:836
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:381
void SetTextAlign(TextAlign eAlign)
Definition: text.cxx:746
constexpr tools::Long GetHeight() const
Wallpaper maBackground
Definition: window.h:401
void Show(bool bVisible=true, ShowFlags nFlags=ShowFlags::NONE)
Definition: window.cxx:2187