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 
68  PushFlags nFlags = PushFlags::NONE;
69  nFlags |= PushFlags::CLIPREGION;
70  nFlags |= PushFlags::FILLCOLOR;
71  nFlags |= PushFlags::FONT;
72  nFlags |= PushFlags::LINECOLOR;
73  nFlags |= PushFlags::MAPMODE;
74  maSettings = pFrameData->mpBuffer->GetSettings();
75  nFlags |= PushFlags::REFPOINT;
76  nFlags |= PushFlags::TEXTCOLOR;
77  nFlags |= PushFlags::TEXTLINECOLOR;
78  nFlags |= PushFlags::OVERLINECOLOR;
79  nFlags |= PushFlags::TEXTFILLCOLOR;
80  nFlags |= PushFlags::TEXTALIGN;
81  nFlags |= PushFlags::RASTEROP;
82  nFlags |= PushFlags::TEXTLAYOUTMODE;
83  nFlags |= PushFlags::TEXTLANGUAGE;
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 (mpWindowImpl->mbPaintDisabled)
599  {
600  if (mpWindowImpl->mnPaintFlags & ImplPaintFlags::PaintAll)
602  else if ( pRegion )
604 
605  // call PostPaint before returning
606  PostPaint(*GetOutDev());
607 
608  return;
609  }
610 
611  nPaintFlags = mpWindowImpl->mnPaintFlags & ~ImplPaintFlags::Paint;
612 
613  PaintHelper aHelper(this, nPaintFlags);
614 
615  if (mpWindowImpl->mnPaintFlags & ImplPaintFlags::Paint)
616  aHelper.DoPaint(pRegion);
617  else
618  mpWindowImpl->mnPaintFlags = ImplPaintFlags::NONE;
619 
620  // call PostPaint
621  PostPaint(*GetOutDev());
622 }
623 
625 {
626  if (!mpWindowImpl)
627  return;
628 
629  // emit overlapping windows first
630  vcl::Window* pTempWindow = mpWindowImpl->mpFirstOverlap;
631  while ( pTempWindow )
632  {
633  if ( pTempWindow->mpWindowImpl->mbReallyVisible )
634  pTempWindow->ImplCallOverlapPaint();
635  pTempWindow = pTempWindow->mpWindowImpl->mpNext;
636  }
637 
638  // only then ourself
640  {
641  // RTL: notify ImplCallPaint to check for re-mirroring
642  // because we were called from the Sal layer
643  ImplCallPaint(nullptr, mpWindowImpl->mnPaintFlags /*| ImplPaintFlags::CheckRtl */);
644  }
645 }
646 
647 IMPL_LINK_NOARG(Window, ImplHandlePaintHdl, Timer *, void)
648 {
649 #ifndef IOS
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 #endif
673 }
674 
675 IMPL_LINK_NOARG(Window, ImplHandleResizeTimerHdl, Timer *, void)
676 {
677  comphelper::ProfileZone aZone("VCL idle resize");
678 
679  if( mpWindowImpl->mbReallyVisible )
680  {
681  ImplCallResize();
682  if( mpWindowImpl->mpFrameData->maPaintIdle.IsActive() )
683  {
684  mpWindowImpl->mpFrameData->maPaintIdle.Stop();
685  mpWindowImpl->mpFrameData->maPaintIdle.Invoke( nullptr );
686  }
687  }
688 }
689 
691 {
692  // set PAINTCHILDREN for all parent windows till the first OverlapWindow
693  if ( !ImplIsOverlapWindow() )
694  {
695  vcl::Window* pTempWindow = this;
697  do
698  {
699  pTempWindow = pTempWindow->ImplGetParent();
700  if ( pTempWindow->mpWindowImpl->mnPaintFlags & ImplPaintFlags::PaintChildren )
701  break;
702  pTempWindow->mpWindowImpl->mnPaintFlags |= ImplPaintFlags::PaintChildren | nTranspPaint;
703  if( ! pTempWindow->IsPaintTransparent() )
704  nTranspPaint = ImplPaintFlags::NONE;
705  }
706  while ( !pTempWindow->ImplIsOverlapWindow() );
707  }
708 
709  // set Paint-Flags
710  mpWindowImpl->mnPaintFlags |= ImplPaintFlags::Paint;
711  if ( nFlags & InvalidateFlags::Children )
713  if ( !(nFlags & InvalidateFlags::NoErase) )
714  mpWindowImpl->mnPaintFlags |= ImplPaintFlags::Erase;
715 
716  if ( !pRegion )
717  mpWindowImpl->mnPaintFlags |= ImplPaintFlags::PaintAll;
718  else if ( !(mpWindowImpl->mnPaintFlags & ImplPaintFlags::PaintAll) )
719  {
720  // if not everything has to be redrawn, add the region to it
721  mpWindowImpl->maInvalidateRegion.Union( *pRegion );
722  }
723 
724  // Handle transparent windows correctly: invalidate must be done on the first opaque parent
726  && ImplGetParent() )
727  {
728  vcl::Window *pParent = ImplGetParent();
729  while( pParent && pParent->IsPaintTransparent() )
730  pParent = pParent->ImplGetParent();
731  if( pParent )
732  {
733  vcl::Region *pChildRegion;
734  if ( mpWindowImpl->mnPaintFlags & ImplPaintFlags::PaintAll )
735  // invalidate the whole child window region in the parent
736  pChildRegion = &ImplGetWinChildClipRegion();
737  else
738  // invalidate the same region in the parent that has to be repainted in the child
739  pChildRegion = &mpWindowImpl->maInvalidateRegion;
740 
741  nFlags |= InvalidateFlags::Children; // paint should also be done on all children
742  nFlags &= ~InvalidateFlags::NoErase; // parent should paint and erase to create proper background
743  pParent->ImplInvalidateFrameRegion( pChildRegion, nFlags );
744  }
745  }
746 
747  if ( !mpWindowImpl->mpFrameData->maPaintIdle.IsActive() )
748  mpWindowImpl->mpFrameData->maPaintIdle.Start();
749 }
750 
752 {
753  vcl::Region aRegion = rRegion;
754 
755  ImplClipBoundaries( aRegion, true, true );
756  if ( !aRegion.IsEmpty() )
758 
759  // now we invalidate the overlapping windows
760  vcl::Window* pTempWindow = mpWindowImpl->mpFirstOverlap;
761  while ( pTempWindow )
762  {
763  if ( pTempWindow->IsVisible() )
764  pTempWindow->ImplInvalidateOverlapFrameRegion( rRegion );
765 
766  pTempWindow = pTempWindow->mpWindowImpl->mpNext;
767  }
768 }
769 
771 {
772  if ( mpWindowImpl->mbOverlapWin )
773  mpWindowImpl->mpFrameWindow->ImplInvalidateOverlapFrameRegion( rRegion );
774  else
775  {
776  if( ImplGetParent() )
778  }
779 }
780 
781 void Window::ImplInvalidate( const vcl::Region* pRegion, InvalidateFlags nFlags )
782 {
783  // check what has to be redrawn
784  bool bInvalidateAll = !pRegion;
785 
786  // take Transparent-Invalidate into account
787  vcl::Window* pOpaqueWindow = this;
788  if ( (mpWindowImpl->mbPaintTransparent && !(nFlags & InvalidateFlags::NoTransparent)) || (nFlags & InvalidateFlags::Transparent) )
789  {
790  vcl::Window* pTempWindow = pOpaqueWindow->ImplGetParent();
791  while ( pTempWindow )
792  {
793  if ( !pTempWindow->IsPaintTransparent() )
794  {
795  pOpaqueWindow = pTempWindow;
796  nFlags |= InvalidateFlags::Children;
797  bInvalidateAll = false;
798  break;
799  }
800 
801  if ( pTempWindow->ImplIsOverlapWindow() )
802  break;
803 
804  pTempWindow = pTempWindow->ImplGetParent();
805  }
806  }
807 
808  // assemble region
809  InvalidateFlags nOrgFlags = nFlags;
811  {
812  if ( GetStyle() & WB_CLIPCHILDREN )
813  nFlags |= InvalidateFlags::NoChildren;
814  else
815  nFlags |= InvalidateFlags::Children;
816  }
817  if ( (nFlags & InvalidateFlags::NoChildren) && mpWindowImpl->mpFirstChild )
818  bInvalidateAll = false;
819  if ( bInvalidateAll )
820  ImplInvalidateFrameRegion( nullptr, nFlags );
821  else
822  {
823  vcl::Region aRegion( GetOutputRectPixel() );
824  if ( pRegion )
825  {
826  // RTL: remirror region before intersecting it
827  if ( GetOutDev()->ImplIsAntiparallel() )
828  {
829  const OutputDevice *pOutDev = GetOutDev();
830 
831  vcl::Region aRgn( *pRegion );
832  pOutDev->ReMirror( aRgn );
833  aRegion.Intersect( aRgn );
834  }
835  else
836  aRegion.Intersect( *pRegion );
837  }
838  ImplClipBoundaries( aRegion, true, true );
839  if ( nFlags & InvalidateFlags::NoChildren )
840  {
841  nFlags &= ~InvalidateFlags::Children;
842  if ( !(nFlags & InvalidateFlags::NoClipChildren) )
843  {
844  if ( nOrgFlags & InvalidateFlags::NoChildren )
845  ImplClipAllChildren( aRegion );
846  else
847  {
848  if ( ImplClipChildren( aRegion ) )
849  nFlags |= InvalidateFlags::Children;
850  }
851  }
852  }
853  if ( !aRegion.IsEmpty() )
854  ImplInvalidateFrameRegion( &aRegion, nFlags ); // transparency is handled here, pOpaqueWindow not required
855  }
856 
857  if ( nFlags & InvalidateFlags::Update )
858  pOpaqueWindow->PaintImmediately(); // start painting at the opaque parent
859 }
860 
862  tools::Long nHorzScroll, tools::Long nVertScroll,
863  bool bChildren )
864 {
866  {
867  vcl::Region aTempRegion = mpWindowImpl->maInvalidateRegion;
868  aTempRegion.Intersect( rRect );
869  aTempRegion.Move( nHorzScroll, nVertScroll );
870  mpWindowImpl->maInvalidateRegion.Union( aTempRegion );
871  }
872 
873  if ( bChildren && (mpWindowImpl->mnPaintFlags & ImplPaintFlags::PaintChildren) )
874  {
875  vcl::Window* pWindow = mpWindowImpl->mpFirstChild;
876  while ( pWindow )
877  {
878  pWindow->ImplMoveInvalidateRegion( rRect, nHorzScroll, nVertScroll, true );
879  pWindow = pWindow->mpWindowImpl->mpNext;
880  }
881  }
882 }
883 
885  tools::Long nHorzScroll, tools::Long nVertScroll,
886  bool bChildren )
887 {
888  // also shift Paint-Region when paints need processing
889  ImplMoveInvalidateRegion( rRect, nHorzScroll, nVertScroll, bChildren );
890  // Paint-Region should be shifted, as drawn by the parents
891  if ( ImplIsOverlapWindow() )
892  return;
893 
894  vcl::Region aPaintAllRegion;
895  vcl::Window* pPaintAllWindow = this;
896  do
897  {
898  pPaintAllWindow = pPaintAllWindow->ImplGetParent();
899  if ( pPaintAllWindow->mpWindowImpl->mnPaintFlags & ImplPaintFlags::PaintAllChildren )
900  {
901  if ( pPaintAllWindow->mpWindowImpl->mnPaintFlags & ImplPaintFlags::PaintAll )
902  {
903  aPaintAllRegion.SetEmpty();
904  break;
905  }
906  else
907  aPaintAllRegion.Union( pPaintAllWindow->mpWindowImpl->maInvalidateRegion );
908  }
909  }
910  while ( !pPaintAllWindow->ImplIsOverlapWindow() );
911  if ( !aPaintAllRegion.IsEmpty() )
912  {
913  aPaintAllRegion.Move( nHorzScroll, nVertScroll );
915  if ( bChildren )
916  nPaintFlags |= InvalidateFlags::Children;
917  ImplInvalidateFrameRegion( &aPaintAllRegion, nPaintFlags );
918  }
919 }
920 
922 {
923  if ( !pRegion )
924  mpWindowImpl->maInvalidateRegion.SetEmpty();
925  else
926  {
927  // when all child windows have to be drawn we need to invalidate them before doing so
928  if ( (mpWindowImpl->mnPaintFlags & ImplPaintFlags::PaintAllChildren) && mpWindowImpl->mpFirstChild )
929  {
930  vcl::Region aChildRegion = mpWindowImpl->maInvalidateRegion;
931  if ( mpWindowImpl->mnPaintFlags & ImplPaintFlags::PaintAll )
932  {
933  aChildRegion = GetOutputRectPixel();
934  }
935  vcl::Window* pChild = mpWindowImpl->mpFirstChild;
936  while ( pChild )
937  {
939  pChild = pChild->mpWindowImpl->mpNext;
940  }
941  }
942  if ( mpWindowImpl->mnPaintFlags & ImplPaintFlags::PaintAll )
943  {
944  mpWindowImpl->maInvalidateRegion = GetOutputRectPixel();
945  }
946  mpWindowImpl->maInvalidateRegion.Exclude( *pRegion );
947  }
948  mpWindowImpl->mnPaintFlags &= ~ImplPaintFlags::PaintAll;
949 
950  if ( nFlags & ValidateFlags::Children )
951  {
952  vcl::Window* pChild = mpWindowImpl->mpFirstChild;
953  while ( pChild )
954  {
955  pChild->ImplValidateFrameRegion( pRegion, nFlags );
956  pChild = pChild->mpWindowImpl->mpNext;
957  }
958  }
959 }
960 
962 {
963  // assemble region
964  bool bValidateAll = true;
966  if ( GetStyle() & WB_CLIPCHILDREN )
967  nFlags |= ValidateFlags::NoChildren;
968  else
969  nFlags |= ValidateFlags::Children;
970  if ( (nFlags & ValidateFlags::NoChildren) && mpWindowImpl->mpFirstChild )
971  bValidateAll = false;
972  if ( bValidateAll )
973  ImplValidateFrameRegion( nullptr, nFlags );
974  else
975  {
976  vcl::Region aRegion( GetOutputRectPixel() );
977  ImplClipBoundaries( aRegion, true, true );
978  if ( nFlags & ValidateFlags::NoChildren )
979  {
980  nFlags &= ~ValidateFlags::Children;
981  if ( ImplClipChildren( aRegion ) )
982  nFlags |= ValidateFlags::Children;
983  }
984  if ( !aRegion.IsEmpty() )
985  ImplValidateFrameRegion( &aRegion, nFlags );
986  }
987 }
988 
990 {
991  if ( !mpWindowImpl || !mpWindowImpl->mbReallyVisible )
992  return;
993 
994  bool bFlush = false;
995  if ( mpWindowImpl->mpFrameWindow->mpWindowImpl->mbPaintFrame )
996  {
997  Point aPoint( 0, 0 );
998  vcl::Region aRegion( tools::Rectangle( aPoint, GetOutputSizePixel() ) );
1000  if ( mpWindowImpl->mbFrame || (mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame) )
1001  bFlush = true;
1002  }
1003 
1004  // an update changes the OverlapWindow, such that for later paints
1005  // not too much has to be drawn, if ALLCHILDREN etc. is set
1007  pWindow->ImplCallOverlapPaint();
1008 
1009  if ( bFlush )
1010  GetOutDev()->Flush();
1011 }
1012 
1013 void Window::PrePaint(vcl::RenderContext& /*rRenderContext*/)
1014 {
1015 }
1016 
1017 void Window::PostPaint(vcl::RenderContext& /*rRenderContext*/)
1018 {
1019 }
1020 
1021 void Window::Paint(vcl::RenderContext& /*rRenderContext*/, const tools::Rectangle& rRect)
1022 {
1023  CallEventListeners(VclEventId::WindowPaint, const_cast<tools::Rectangle *>(&rRect));
1024 }
1025 
1026 void Window::SetPaintTransparent( bool bTransparent )
1027 {
1028  // transparency is not useful for frames as the background would have to be provided by a different frame
1029  if( bTransparent && mpWindowImpl->mbFrame )
1030  return;
1031 
1032  if ( mpWindowImpl->mpBorderWindow )
1033  mpWindowImpl->mpBorderWindow->SetPaintTransparent( bTransparent );
1034 
1035  mpWindowImpl->mbPaintTransparent = bTransparent;
1036 }
1037 
1039 {
1040 
1041  if ( mpWindowImpl->mpBorderWindow )
1042  mpWindowImpl->mpBorderWindow->SetWindowRegionPixel();
1043  else if( mpWindowImpl->mbFrame )
1044  {
1045  mpWindowImpl->maWinRegion = vcl::Region(true);
1046  mpWindowImpl->mbWinRegion = false;
1047  mpWindowImpl->mpFrame->ResetClipRegion();
1048  }
1049  else
1050  {
1051  if ( mpWindowImpl->mbWinRegion )
1052  {
1053  mpWindowImpl->maWinRegion = vcl::Region(true);
1054  mpWindowImpl->mbWinRegion = false;
1055  ImplSetClipFlag();
1056 
1057  if ( IsReallyVisible() )
1058  {
1059  vcl::Region aRegion( GetOutputRectPixel() );
1061  }
1062  }
1063  }
1064 }
1065 
1067 {
1068 
1069  if ( mpWindowImpl->mpBorderWindow )
1070  mpWindowImpl->mpBorderWindow->SetWindowRegionPixel( rRegion );
1071  else if( mpWindowImpl->mbFrame )
1072  {
1073  if( !rRegion.IsNull() )
1074  {
1075  mpWindowImpl->maWinRegion = rRegion;
1076  mpWindowImpl->mbWinRegion = ! rRegion.IsEmpty();
1077 
1078  if( mpWindowImpl->mbWinRegion )
1079  {
1080  // set/update ClipRegion
1081  RectangleVector aRectangles;
1082  mpWindowImpl->maWinRegion.GetRegionRectangles(aRectangles);
1083  mpWindowImpl->mpFrame->BeginSetClipRegion(aRectangles.size());
1084 
1085  for (auto const& rectangle : aRectangles)
1086  {
1087  mpWindowImpl->mpFrame->UnionClipRegion(
1088  rectangle.Left(),
1089  rectangle.Top(),
1090  rectangle.GetWidth(), // orig nWidth was ((R - L) + 1), same as GetWidth does
1091  rectangle.GetHeight()); // same for height
1092  }
1093 
1094  mpWindowImpl->mpFrame->EndSetClipRegion();
1095  }
1096  else
1098  }
1099  else
1101  }
1102  else
1103  {
1104  if ( rRegion.IsNull() )
1105  {
1106  if ( mpWindowImpl->mbWinRegion )
1107  {
1108  mpWindowImpl->maWinRegion = vcl::Region(true);
1109  mpWindowImpl->mbWinRegion = false;
1110  ImplSetClipFlag();
1111  }
1112  }
1113  else
1114  {
1115  mpWindowImpl->maWinRegion = rRegion;
1116  mpWindowImpl->mbWinRegion = true;
1117  ImplSetClipFlag();
1118  }
1119 
1120  if ( IsReallyVisible() )
1121  {
1122  vcl::Region aRegion( GetOutputRectPixel() );
1124  }
1125  }
1126 }
1127 
1129 {
1130 
1131  if ( mpWindowImpl->mpPaintRegion )
1132  {
1133  vcl::Region aRegion = *mpWindowImpl->mpPaintRegion;
1134  aRegion.Move( -GetOutDev()->mnOutOffX, -GetOutDev()->mnOutOffY );
1135  return PixelToLogic( aRegion );
1136  }
1137  else
1138  {
1139  vcl::Region aPaintRegion(true);
1140  return aPaintRegion;
1141  }
1142 }
1143 
1145 {
1146  if ( !comphelper::LibreOfficeKit::isActive() && (!GetOutDev()->IsDeviceOutputNecessary() || !GetOutDev()->mnOutWidth || !GetOutDev()->mnOutHeight) )
1147  return;
1148 
1149  ImplInvalidate( nullptr, nFlags );
1150  LogicInvalidate(nullptr);
1151 }
1152 
1154 {
1155  if ( !comphelper::LibreOfficeKit::isActive() && (!GetOutDev()->IsDeviceOutputNecessary() || !GetOutDev()->mnOutWidth || !GetOutDev()->mnOutHeight) )
1156  return;
1157 
1158  OutputDevice *pOutDev = GetOutDev();
1159  tools::Rectangle aRect = pOutDev->ImplLogicToDevicePixel( rRect );
1160  if ( !aRect.IsEmpty() )
1161  {
1162  vcl::Region aRegion( aRect );
1163  ImplInvalidate( &aRegion, nFlags );
1164  tools::Rectangle aLogicRectangle(rRect);
1165  LogicInvalidate(&aLogicRectangle);
1166  }
1167 }
1168 
1169 void Window::Invalidate( const vcl::Region& rRegion, InvalidateFlags nFlags )
1170 {
1171  if ( !comphelper::LibreOfficeKit::isActive() && (!GetOutDev()->IsDeviceOutputNecessary() || !GetOutDev()->mnOutWidth || !GetOutDev()->mnOutHeight) )
1172  return;
1173 
1174  if ( rRegion.IsNull() )
1175  {
1176  ImplInvalidate( nullptr, nFlags );
1177  LogicInvalidate(nullptr);
1178  }
1179  else
1180  {
1181  vcl::Region aRegion = GetOutDev()->ImplPixelToDevicePixel( LogicToPixel( rRegion ) );
1182  if ( !aRegion.IsEmpty() )
1183  {
1184  ImplInvalidate( &aRegion, nFlags );
1185  tools::Rectangle aLogicRectangle = rRegion.GetBoundRect();
1186  LogicInvalidate(&aLogicRectangle);
1187  }
1188  }
1189 }
1190 
1192 {
1193  if(pRectangle)
1194  {
1195  tools::Rectangle aRect = GetOutDev()->ImplLogicToDevicePixel( *pRectangle );
1196  PixelInvalidate(&aRect);
1197  }
1198  else
1199  PixelInvalidate(nullptr);
1200 }
1201 
1203 {
1205  return;
1206 
1207  Size aSize = GetSizePixel();
1208  if (aSize.IsEmpty())
1209  return;
1210 
1211  if (const vcl::ILibreOfficeKitNotifier* pNotifier = GetLOKNotifier())
1212  {
1213  // In case we are routing the window, notify the client
1214  std::vector<vcl::LOKPayloadItem> aPayload;
1215  if (pRectangle)
1216  aPayload.emplace_back("rectangle", pRectangle->toString());
1217  else
1218  {
1219  const tools::Rectangle aRect(Point(0, 0), aSize);
1220  aPayload.emplace_back("rectangle", aRect.toString());
1221  }
1222 
1223  pNotifier->notifyWindow(GetLOKWindowId(), "invalidate", aPayload);
1224  }
1225  // Added for dialog items. Pass invalidation to the parent window.
1226  else if (VclPtr<vcl::Window> pParent = GetParentWithLOKNotifier())
1227  {
1229  pParent->PixelInvalidate(&aRect);
1230  }
1231 }
1232 
1234 {
1235  if ( !comphelper::LibreOfficeKit::isActive() && (!GetOutDev()->IsDeviceOutputNecessary() || !GetOutDev()->mnOutWidth || !GetOutDev()->mnOutHeight) )
1236  return;
1237 
1238  ImplValidate();
1239 }
1240 
1242 {
1243 
1244  if ( !mpWindowImpl->mbReallyVisible )
1245  return false;
1246 
1247  if ( mpWindowImpl->mpFrameWindow->mpWindowImpl->mbPaintFrame )
1248  return true;
1249 
1250  if ( mpWindowImpl->mnPaintFlags & ImplPaintFlags::Paint )
1251  return true;
1252 
1253  if ( !ImplIsOverlapWindow() )
1254  {
1255  const vcl::Window* pTempWindow = this;
1256  do
1257  {
1258  pTempWindow = pTempWindow->ImplGetParent();
1259  if ( pTempWindow->mpWindowImpl->mnPaintFlags & (ImplPaintFlags::PaintChildren | ImplPaintFlags::PaintAllChildren) )
1260  return true;
1261  }
1262  while ( !pTempWindow->ImplIsOverlapWindow() );
1263  }
1264 
1265  return false;
1266 }
1267 
1269 {
1270  if (!mpWindowImpl)
1271  return;
1272 
1273  if ( mpWindowImpl->mpBorderWindow )
1274  {
1275  mpWindowImpl->mpBorderWindow->PaintImmediately();
1276  return;
1277  }
1278 
1279  if ( !mpWindowImpl->mbReallyVisible )
1280  return;
1281 
1282  bool bFlush = false;
1283  if ( mpWindowImpl->mpFrameWindow->mpWindowImpl->mbPaintFrame )
1284  {
1285  Point aPoint( 0, 0 );
1286  vcl::Region aRegion( tools::Rectangle( aPoint, GetOutputSizePixel() ) );
1288  if ( mpWindowImpl->mbFrame || (mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame) )
1289  bFlush = true;
1290  }
1291 
1292  // First we should skip all windows which are Paint-Transparent
1293  vcl::Window* pUpdateWindow = this;
1294  vcl::Window* pWindow = pUpdateWindow;
1295  while ( !pWindow->ImplIsOverlapWindow() )
1296  {
1297  if ( !pWindow->mpWindowImpl->mbPaintTransparent )
1298  {
1299  pUpdateWindow = pWindow;
1300  break;
1301  }
1302  pWindow = pWindow->ImplGetParent();
1303  }
1304  // In order to limit drawing, an update only draws the window which
1305  // has PAINTALLCHILDREN set
1306  pWindow = pUpdateWindow;
1307  do
1308  {
1309  if ( pWindow->mpWindowImpl->mnPaintFlags & ImplPaintFlags::PaintAllChildren )
1310  pUpdateWindow = pWindow;
1311  if ( pWindow->ImplIsOverlapWindow() )
1312  break;
1313  pWindow = pWindow->ImplGetParent();
1314  }
1315  while ( pWindow );
1316 
1317  // if there is something to paint, trigger a Paint
1318  if ( pUpdateWindow->mpWindowImpl->mnPaintFlags & (ImplPaintFlags::Paint | ImplPaintFlags::PaintChildren) )
1319  {
1320  VclPtr<vcl::Window> xWindow(this);
1321 
1322  // trigger an update also for system windows on top of us,
1323  // otherwise holes would remain
1324  vcl::Window* pUpdateOverlapWindow = ImplGetFirstOverlapWindow();
1325  if (pUpdateOverlapWindow->mpWindowImpl)
1326  pUpdateOverlapWindow = pUpdateOverlapWindow->mpWindowImpl->mpFirstOverlap;
1327  else
1328  pUpdateOverlapWindow = nullptr;
1329  while ( pUpdateOverlapWindow )
1330  {
1331  pUpdateOverlapWindow->PaintImmediately();
1332  pUpdateOverlapWindow = pUpdateOverlapWindow->mpWindowImpl->mpNext;
1333  }
1334 
1335  pUpdateWindow->ImplCallPaint(nullptr, pUpdateWindow->mpWindowImpl->mnPaintFlags);
1336 
1337  if (comphelper::LibreOfficeKit::isActive() && pUpdateWindow->GetParentDialog())
1338  pUpdateWindow->LogicInvalidate(nullptr);
1339 
1340  if (xWindow->isDisposed())
1341  return;
1342 
1343  bFlush = true;
1344  }
1345 
1346  if ( bFlush )
1347  GetOutDev()->Flush();
1348 }
1349 
1350 void Window::ImplPaintToDevice( OutputDevice* i_pTargetOutDev, const Point& i_rPos )
1351 {
1352  // Special drawing when called through LOKit
1353  // TODO: Move to its own method
1355  {
1356  VclPtrInstance<VirtualDevice> pDevice(*i_pTargetOutDev);
1357 
1358  Size aSize(GetOutputSizePixel());
1359  pDevice->SetOutputSizePixel(aSize);
1360 
1361  vcl::Font aCopyFont = GetFont();
1362  pDevice->SetFont(aCopyFont);
1363 
1364  pDevice->SetTextColor(GetTextColor());
1365  if (GetOutDev()->IsLineColor())
1366  pDevice->SetLineColor(GetOutDev()->GetLineColor());
1367  else
1368  pDevice->SetLineColor();
1369 
1370  if (GetOutDev()->IsFillColor())
1371  pDevice->SetFillColor(GetOutDev()->GetFillColor());
1372  else
1373  pDevice->SetFillColor();
1374 
1375  if (IsTextLineColor())
1376  pDevice->SetTextLineColor(GetTextLineColor());
1377  else
1378  pDevice->SetTextLineColor();
1379 
1380  if (IsOverlineColor())
1381  pDevice->SetOverlineColor(GetOverlineColor());
1382  else
1383  pDevice->SetOverlineColor();
1384 
1385  if (IsTextFillColor())
1386  pDevice->SetTextFillColor(GetTextFillColor());
1387  else
1388  pDevice->SetTextFillColor();
1389 
1390  pDevice->SetTextAlign(GetTextAlign());
1391  pDevice->SetRasterOp(GetOutDev()->GetRasterOp());
1392 
1393  tools::Rectangle aPaintRect(Point(), GetOutputSizePixel());
1394 
1395  vcl::Region aClipRegion(GetOutDev()->GetClipRegion());
1396  pDevice->SetClipRegion();
1397  aClipRegion.Intersect(aPaintRect);
1398  pDevice->SetClipRegion(aClipRegion);
1399 
1401  Erase(*pDevice);
1402 
1403  pDevice->SetMapMode(GetMapMode());
1404 
1406 
1407  i_pTargetOutDev->DrawOutDev(i_rPos, aSize, Point(), pDevice->PixelToLogic(aSize), *pDevice);
1408 
1409  // get rid of virtual device now so they don't pile up during recursive calls
1410  pDevice.disposeAndClear();
1411 
1412 
1413  for( vcl::Window* pChild = mpWindowImpl->mpFirstChild; pChild; pChild = pChild->mpWindowImpl->mpNext )
1414  {
1415  if( pChild->mpWindowImpl->mpFrame == mpWindowImpl->mpFrame && pChild->IsVisible() )
1416  {
1417  tools::Long nDeltaX = pChild->GetOutDev()->mnOutOffX - GetOutDev()->mnOutOffX;
1418  tools::Long nDeltaY = pChild->GetOutDev()->mnOutOffY - GetOutDev()->mnOutOffY;
1419 
1420  Point aPos( i_rPos );
1421  aPos += Point(nDeltaX, nDeltaY);
1422 
1423  pChild->ImplPaintToDevice( i_pTargetOutDev, aPos );
1424  }
1425  }
1426  return;
1427  }
1428 
1429 
1430  bool bRVisible = mpWindowImpl->mbReallyVisible;
1431  mpWindowImpl->mbReallyVisible = mpWindowImpl->mbVisible;
1432  bool bDevOutput = GetOutDev()->mbDevOutput;
1433  GetOutDev()->mbDevOutput = true;
1434 
1435  const OutputDevice *pOutDev = GetOutDev();
1436  tools::Long nOldDPIX = pOutDev->GetDPIX();
1437  tools::Long nOldDPIY = pOutDev->GetDPIY();
1438  GetOutDev()->mnDPIX = i_pTargetOutDev->GetDPIX();
1439  GetOutDev()->mnDPIY = i_pTargetOutDev->GetDPIY();
1440  bool bOutput = GetOutDev()->IsOutputEnabled();
1441  GetOutDev()->EnableOutput();
1442 
1443  SAL_WARN_IF( GetMapMode().GetMapUnit() != MapUnit::MapPixel, "vcl.window", "MapMode must be PIXEL based" );
1444  if ( GetMapMode().GetMapUnit() != MapUnit::MapPixel )
1445  return;
1446 
1447  // preserve graphicsstate
1448  GetOutDev()->Push();
1449  vcl::Region aClipRegion( GetOutDev()->GetClipRegion() );
1450  GetOutDev()->SetClipRegion();
1451 
1452  GDIMetaFile* pOldMtf = GetOutDev()->GetConnectMetaFile();
1453  GDIMetaFile aMtf;
1454  GetOutDev()->SetConnectMetaFile( &aMtf );
1455 
1456  // put a push action to metafile
1457  GetOutDev()->Push();
1458  // copy graphics state to metafile
1459  vcl::Font aCopyFont = GetFont();
1460  if( nOldDPIX != GetOutDev()->mnDPIX || nOldDPIY != GetOutDev()->mnDPIY )
1461  {
1462  aCopyFont.SetFontHeight( aCopyFont.GetFontHeight() * GetOutDev()->mnDPIY / nOldDPIY );
1463  aCopyFont.SetAverageFontWidth( aCopyFont.GetAverageFontWidth() * GetOutDev()->mnDPIX / nOldDPIX );
1464  }
1465  SetFont( aCopyFont );
1467  if( GetOutDev()->IsLineColor() )
1468  GetOutDev()->SetLineColor( GetOutDev()->GetLineColor() );
1469  else
1470  GetOutDev()->SetLineColor();
1471  if( GetOutDev()->IsFillColor() )
1472  GetOutDev()->SetFillColor( GetOutDev()->GetFillColor() );
1473  else
1474  GetOutDev()->SetFillColor();
1475  if( IsTextLineColor() )
1477  else
1478  SetTextLineColor();
1479  if( IsOverlineColor() )
1481  else
1482  SetOverlineColor();
1483  if( IsTextFillColor() )
1485  else
1486  SetTextFillColor();
1488  GetOutDev()->SetRasterOp( GetOutDev()->GetRasterOp() );
1489  if( GetOutDev()->IsRefPoint() )
1490  GetOutDev()->SetRefPoint( GetOutDev()->GetRefPoint() );
1491  else
1492  GetOutDev()->SetRefPoint();
1493  GetOutDev()->SetLayoutMode( GetOutDev()->GetLayoutMode() );
1494 
1495  GetOutDev()->SetDigitLanguage( GetOutDev()->GetDigitLanguage() );
1496  tools::Rectangle aPaintRect(Point(0, 0), GetOutputSizePixel());
1497  aClipRegion.Intersect( aPaintRect );
1498  GetOutDev()->SetClipRegion( aClipRegion );
1499 
1500  // do the actual paint
1501 
1502  // background
1504  {
1505  Erase(*GetOutDev());
1506  }
1507  // foreground
1508  Paint(*GetOutDev(), aPaintRect);
1509  // put a pop action to metafile
1510  GetOutDev()->Pop();
1511 
1512  GetOutDev()->SetConnectMetaFile( pOldMtf );
1513  GetOutDev()->EnableOutput( bOutput );
1514  mpWindowImpl->mbReallyVisible = bRVisible;
1515 
1516  // paint metafile to VDev
1517  VclPtrInstance<VirtualDevice> pMaskedDevice(*i_pTargetOutDev,
1520 
1521  pMaskedDevice->SetOutputSizePixel( GetOutputSizePixel() );
1522  pMaskedDevice->EnableRTL( IsRTLEnabled() );
1523  aMtf.WindStart();
1524  aMtf.Play(*pMaskedDevice);
1525  BitmapEx aBmpEx( pMaskedDevice->GetBitmapEx( Point( 0, 0 ), aPaintRect.GetSize() ) );
1526  i_pTargetOutDev->DrawBitmapEx( i_rPos, aBmpEx );
1527  // get rid of virtual device now so they don't pile up during recursive calls
1528  pMaskedDevice.disposeAndClear();
1529 
1530  for( vcl::Window* pChild = mpWindowImpl->mpFirstChild; pChild; pChild = pChild->mpWindowImpl->mpNext )
1531  {
1532  if( pChild->mpWindowImpl->mpFrame == mpWindowImpl->mpFrame && pChild->IsVisible() )
1533  {
1534  tools::Long nDeltaX = pChild->GetOutDev()->mnOutOffX - GetOutDev()->mnOutOffX;
1535 
1536  if( pOutDev->HasMirroredGraphics() )
1537  nDeltaX = GetOutDev()->mnOutWidth - nDeltaX - pChild->GetOutDev()->mnOutWidth;
1538  tools::Long nDeltaY = pChild->GetOutOffYPixel() - GetOutOffYPixel();
1539  Point aPos( i_rPos );
1540  Point aDelta( nDeltaX, nDeltaY );
1541  aPos += aDelta;
1542  pChild->ImplPaintToDevice( i_pTargetOutDev, aPos );
1543  }
1544  }
1545 
1546  // restore graphics state
1547  GetOutDev()->Pop();
1548 
1549  GetOutDev()->EnableOutput( bOutput );
1550  mpWindowImpl->mbReallyVisible = bRVisible;
1551  GetOutDev()->mbDevOutput = bDevOutput;
1552  GetOutDev()->mnDPIX = nOldDPIX;
1553  GetOutDev()->mnDPIY = nOldDPIY;
1554 }
1555 
1556 void Window::PaintToDevice(OutputDevice* pDev, const Point& rPos)
1557 {
1558  if( !mpWindowImpl )
1559  return;
1560 
1561  SAL_WARN_IF( pDev->HasMirroredGraphics(), "vcl.window", "PaintToDevice to mirroring graphics" );
1562  SAL_WARN_IF( pDev->IsRTLEnabled(), "vcl.window", "PaintToDevice to mirroring device" );
1563 
1564  vcl::Window* pRealParent = nullptr;
1565  if( ! mpWindowImpl->mbVisible )
1566  {
1567  vcl::Window* pTempParent = ImplGetDefaultWindow();
1568  pTempParent->EnableChildTransparentMode();
1569  pRealParent = GetParent();
1570  SetParent( pTempParent );
1571  // trigger correct visibility flags for children
1572  Show();
1573  Hide();
1574  }
1575 
1576  bool bVisible = mpWindowImpl->mbVisible;
1577  mpWindowImpl->mbVisible = true;
1578 
1579  if( mpWindowImpl->mpBorderWindow )
1580  mpWindowImpl->mpBorderWindow->ImplPaintToDevice( pDev, rPos );
1581  else
1582  ImplPaintToDevice( pDev, rPos );
1583 
1584  mpWindowImpl->mbVisible = bVisible;
1585 
1586  if( pRealParent )
1587  SetParent( pRealParent );
1588 }
1589 
1590 void Window::Erase(vcl::RenderContext& rRenderContext)
1591 {
1592  if (!GetOutDev()->IsDeviceOutputNecessary() || GetOutDev()->ImplIsRecordLayout())
1593  return;
1594 
1595  bool bNativeOK = false;
1596 
1598 
1599  if (aCtrlPart == ControlPart::Entire && IsControlBackground())
1600  {
1601  // nothing to do here; background is drawn in corresponding drawNativeControl implementation
1602  bNativeOK = true;
1603  }
1604  else if (aCtrlPart != ControlPart::NONE && ! IsControlBackground())
1605  {
1606  tools::Rectangle aCtrlRegion(Point(), GetOutputSizePixel());
1608 
1609  if (IsEnabled())
1610  nState |= ControlState::ENABLED;
1611 
1612  bNativeOK = rRenderContext.DrawNativeControl(ControlType::WindowBackground, aCtrlPart, aCtrlRegion,
1613  nState, ImplControlValue(), OUString());
1614  }
1615 
1616  if (GetOutDev()->mbBackground && !bNativeOK)
1617  {
1618  RasterOp eRasterOp = GetOutDev()->GetRasterOp();
1619  if (eRasterOp != RasterOp::OverPaint)
1621  rRenderContext.DrawWallpaper(0, 0, GetOutDev()->mnOutWidth, GetOutDev()->mnOutHeight, GetOutDev()->maBackground);
1622  if (eRasterOp != RasterOp::OverPaint)
1623  rRenderContext.SetRasterOp(eRasterOp);
1624  }
1625 
1626  if (GetOutDev()->mpAlphaVDev)
1627  GetOutDev()->mpAlphaVDev->Erase();
1628 }
1629 
1631  tools::Long nHorzScroll, tools::Long nVertScroll, ScrollFlags nFlags )
1632 {
1633  if ( !GetOutDev()->IsDeviceOutputNecessary() )
1634  return;
1635 
1636  nHorzScroll = GetOutDev()->ImplLogicWidthToDevicePixel( nHorzScroll );
1637  nVertScroll = GetOutDev()->ImplLogicHeightToDevicePixel( nVertScroll );
1638 
1639  if ( !nHorzScroll && !nVertScroll )
1640  return;
1641 
1642  if ( mpWindowImpl->mpCursor )
1643  mpWindowImpl->mpCursor->ImplSuspend();
1644 
1645  ScrollFlags nOrgFlags = nFlags;
1646  if ( !(nFlags & (ScrollFlags::Children | ScrollFlags::NoChildren)) )
1647  {
1648  if ( GetStyle() & WB_CLIPCHILDREN )
1649  nFlags |= ScrollFlags::NoChildren;
1650  else
1651  nFlags |= ScrollFlags::Children;
1652  }
1653 
1654  vcl::Region aInvalidateRegion;
1655  bool bScrollChildren(nFlags & ScrollFlags::Children);
1656 
1657  if ( !mpWindowImpl->mpFirstChild )
1658  bScrollChildren = false;
1659 
1660  OutputDevice *pOutDev = GetOutDev();
1661 
1662  // RTL: check if this window requires special action
1663  bool bReMirror = GetOutDev()->ImplIsAntiparallel();
1664 
1665  tools::Rectangle aRectMirror( rRect );
1666  if( bReMirror )
1667  {
1668  // make sure the invalidate region of this window is
1669  // computed in the same coordinate space as the one from the overlap windows
1670  pOutDev->ReMirror( aRectMirror );
1671  }
1672 
1673  // adapt paint areas
1674  ImplMoveAllInvalidateRegions( aRectMirror, nHorzScroll, nVertScroll, bScrollChildren );
1675 
1676  ImplCalcOverlapRegion( aRectMirror, aInvalidateRegion, !bScrollChildren, false );
1677 
1678  // if the scrolling on the device is performed in the opposite direction
1679  // then move the overlaps in that direction to compute the invalidate region
1680  // on the correct side, i.e., revert nHorzScroll
1681  if (!aInvalidateRegion.IsEmpty())
1682  {
1683  aInvalidateRegion.Move(bReMirror ? -nHorzScroll : nHorzScroll, nVertScroll);
1684  }
1685 
1686  tools::Rectangle aDestRect(aRectMirror);
1687  aDestRect.Move(bReMirror ? -nHorzScroll : nHorzScroll, nVertScroll);
1688  vcl::Region aWinInvalidateRegion(aRectMirror);
1689  if (!SupportsDoubleBuffering())
1690  {
1691  // There will be no CopyArea() call below, so invalidate the
1692  // whole visible area, not only the smaller one that was just
1693  // scrolled in.
1694  aWinInvalidateRegion.Exclude(aDestRect);
1695  }
1696 
1697  aInvalidateRegion.Union(aWinInvalidateRegion);
1698 
1699  vcl::Region aRegion( GetOutputRectPixel() );
1700  if ( nFlags & ScrollFlags::Clip )
1701  aRegion.Intersect( rRect );
1702  if ( mpWindowImpl->mbWinRegion )
1703  aRegion.Intersect( GetOutDev()->ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
1704 
1705  aRegion.Exclude( aInvalidateRegion );
1706 
1707  ImplClipBoundaries( aRegion, false, true );
1708  if ( !bScrollChildren )
1709  {
1710  if ( nOrgFlags & ScrollFlags::NoChildren )
1711  ImplClipAllChildren( aRegion );
1712  else
1713  ImplClipChildren( aRegion );
1714  }
1715  if ( GetOutDev()->mbClipRegion && (nFlags & ScrollFlags::UseClipRegion) )
1716  aRegion.Intersect( GetOutDev()->maRegion );
1717  if ( !aRegion.IsEmpty() )
1718  {
1719  if ( mpWindowImpl->mpWinData )
1720  {
1721  if ( mpWindowImpl->mbFocusVisible )
1722  ImplInvertFocus( *mpWindowImpl->mpWinData->mpFocusRect );
1723  if ( mpWindowImpl->mbTrackVisible && (mpWindowImpl->mpWinData->mnTrackFlags & ShowTrackFlags::TrackWindow) )
1724  InvertTracking( *mpWindowImpl->mpWinData->mpTrackRect, mpWindowImpl->mpWinData->mnTrackFlags );
1725  }
1726 #ifndef IOS
1727  // This seems completely unnecessary with tiled rendering, and
1728  // causes the "AquaSalGraphics::copyArea() for non-layered
1729  // graphics" message. Presumably we should bypass this on all
1730  // platforms when dealing with a "window" that uses tiled
1731  // rendering at the moment. Unclear how to figure that out,
1732  // though. Also unclear whether we actually could just not
1733  // create a "frame window", whatever that exactly is, in the
1734  // tiled rendering case, or at least for platforms where tiles
1735  // rendering is all there is.
1736 
1737  SalGraphics* pGraphics = ImplGetFrameGraphics();
1738  // The invalidation area contains the area what would be copied here,
1739  // so avoid copying in case of double buffering.
1740  if (pGraphics && !SupportsDoubleBuffering())
1741  {
1742  if( bReMirror )
1743  {
1744  pOutDev->ReMirror( aRegion );
1745  }
1746 
1747  pOutDev->SelectClipRegion( aRegion, pGraphics );
1748  pGraphics->CopyArea( rRect.Left()+nHorzScroll, rRect.Top()+nVertScroll,
1749  rRect.Left(), rRect.Top(),
1750  rRect.GetWidth(), rRect.GetHeight(),
1751  *GetOutDev() );
1752  }
1753 #endif
1754  if ( mpWindowImpl->mpWinData )
1755  {
1756  if ( mpWindowImpl->mbFocusVisible )
1757  ImplInvertFocus( *mpWindowImpl->mpWinData->mpFocusRect );
1758  if ( mpWindowImpl->mbTrackVisible && (mpWindowImpl->mpWinData->mnTrackFlags & ShowTrackFlags::TrackWindow) )
1759  InvertTracking( *mpWindowImpl->mpWinData->mpTrackRect, mpWindowImpl->mpWinData->mnTrackFlags );
1760  }
1761  }
1762 
1763  if ( !aInvalidateRegion.IsEmpty() )
1764  {
1765  // RTL: the invalidate region for this windows is already computed in frame coordinates
1766  // so it has to be re-mirrored before calling the Paint-handler
1767  mpWindowImpl->mnPaintFlags |= ImplPaintFlags::CheckRtl;
1768 
1769  if ( !bScrollChildren )
1770  {
1771  if ( nOrgFlags & ScrollFlags::NoChildren )
1772  ImplClipAllChildren( aInvalidateRegion );
1773  else
1774  ImplClipChildren( aInvalidateRegion );
1775  }
1777  }
1778 
1779  if ( bScrollChildren )
1780  {
1781  vcl::Window* pWindow = mpWindowImpl->mpFirstChild;
1782  while ( pWindow )
1783  {
1784  Point aPos = pWindow->GetPosPixel();
1785  aPos += Point( nHorzScroll, nVertScroll );
1786  pWindow->SetPosPixel( aPos );
1787 
1788  pWindow = pWindow->mpWindowImpl->mpNext;
1789  }
1790  }
1791 
1792  if ( nFlags & ScrollFlags::Update )
1793  PaintImmediately();
1794 
1795  if ( mpWindowImpl->mpCursor )
1796  mpWindowImpl->mpCursor->ImplResume();
1797 }
1798 
1799 } /* namespace vcl */
1800 
1801 
1802 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual Point GetPosPixel() const
Definition: window.cxx:2780
SAL_DLLPRIVATE void ImplMoveInvalidateRegion(const tools::Rectangle &rRect, tools::Long nHorzScroll, tools::Long nVertScroll, bool bChildren)
Definition: paint.cxx:861
void EnableOutput(bool bEnable=true)
vcl::Region GetClipRegion() const
The child windows are invalidated, too.
bool IsControlBackground() const
Definition: window2.cxx:1086
tools::Long GetOutOffYPixel() const
Definition: window3.cxx:124
virtual void Flush()
Definition: outdev.hxx:418
void SetDigitLanguage(LanguageType)
void SetBackground()
Definition: window3.cxx:100
tools::Rectangle m_aPaintRect
Definition: paint.cxx:171
const Wallpaper & GetBackground() const
Definition: outdev.hxx:517
SAL_DLLPRIVATE SalGraphics * ImplGetFrameGraphics() const
Definition: window.cxx:1276
vcl::LOKWindowId GetLOKWindowId() const
Definition: window.cxx:3242
bool bVisible
SAL_DLLPRIVATE vcl::Region & ImplGetWinChildClipRegion()
bool IsNull() const
Definition: region.hxx:102
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:1350
void SetAverageFontWidth(tools::Long nWidth)
Definition: font/font.cxx:835
void Move(tools::Long nHorzMove, tools::Long nVertMove)
Definition: region.cxx:414
bool IsBackground() const
Definition: window3.cxx:64
const Color & GetHighlightTextColor() const
bool IsTextLineColor() const
Definition: window3.cxx:112
InvalidateFlags
Definition: window.hxx:184
void DrawBitmapEx(const Point &rDestPt, const BitmapEx &rBitmapEx)
This is an overloaded member function, provided for convenience. It differs from the above function o...
tools::Rectangle m_aSelectionRect
Definition: paint.cxx:170
void SetOverlineColor()
Definition: window3.cxx:95
void Union(const tools::Rectangle &rRegion)
Definition: region.cxx:508
const Color & GetTextLineColor() const
Definition: window3.cxx:110
VclPtr< vcl::Window > m_pWindow
Definition: paint.cxx:168
bool IsBackground() const
Definition: outdev.hxx:520
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:1590
long Long
bool mbInBufferedPaint
PaintHelper is in the process of painting into this buffer.
Definition: window.h:175
void disposeAndClear()
Definition: vclptr.hxx:200
const StyleSettings & GetStyleSettings() const
bool IsOutputEnabled() const
Definition: outdev.hxx:474
ParentClipMode GetParentClipMode() const
sal_uInt8 GetLuminance() const
const Color & GetFaceColor() const
tools::Long GetOutOffXPixel() const
Definition: outdev.hxx:307
vcl::Region maInvalidateRegion
Definition: window.h:284
virtual Size GetSizePixel() const
Definition: window.cxx:2391
SAL_DLLPRIVATE WindowImpl * ImplGetWindowImpl() const
Definition: window.hxx:540
tools::Long mnOutOffY
Output offset for device output in pixel (pseudo window offset within window system's frames) ...
Definition: outdev.hxx:205
sal_Int32 mnDPIY
Definition: outdev.hxx:209
void SetTextFillColor()
Definition: text.cxx:697
vcl::Region GetPaintRegion() const
Definition: paint.cxx:1128
void SetLayoutMode(ComplexTextLayoutFlags nTextLayoutMode)
void SetPop()
Definition: paint.cxx:179
GDIMetaFile * GetConnectMetaFile() const
Definition: outdev.hxx:277
The invalidated area is updated immediately.
sal_Int32 mnDPIX
Definition: outdev.hxx:208
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:989
tools::Rectangle GetBoundRect() const
Definition: region.cxx:1214
void PaintImmediately()
Definition: paint.cxx:1268
VclPtr< VirtualDevice > mpBuffer
Buffer for the double-buffering.
Definition: window.h:174
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:551
std::unique_ptr< ImplWinData > mpWinData
Definition: window.h:222
void SetTextColor(const Color &rColor)
Definition: window3.cxx:108
Dialog * GetParentDialog() const
Definition: window2.cxx:981
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:690
bool GetRestoreCursor() const
Definition: paint.cxx:195
tools::Long GetFontHeight() const
Definition: font/font.cxx:834
ImplFrameData * mpFrameData
Definition: window.h:399
void SetTextLineColor()
Definition: window3.cxx:93
tools::Long mnOutOffY
Definition: window.h:405
bool SelectClipRegion(const vcl::Region &, SalGraphics *pGraphics=nullptr)
SAL_DLLPRIVATE bool ImplIsOverlapWindow() const
Definition: window2.cxx:925
std::vector< tools::Rectangle > RectangleVector
Definition: region.hxx:37
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:884
void DrawWallpaper(const tools::Rectangle &rRect, const Wallpaper &rWallpaper)
Definition: wallpaper.cxx:42
void SetBackground()
ScrollFlags
Definition: window.hxx:220
void SetOutOffYPixel(tools::Long nOutOffY)
Definition: outdev.cxx:330
SAL_DLLPRIVATE void ReMirror(Point &rPoint) const
Definition: outdev.cxx:614
tools::Long Left() const
VclPtr< vcl::Window > GetParentWithLOKNotifier()
Find the nearest parent with LOK Notifier; can be itself if this Window has LOK notifier set...
Definition: window.cxx:3247
const Color & GetOverlineColor() const
Definition: window3.cxx:118
SAL_DLLPRIVATE void ImplInvalidate(const vcl::Region *rRegion, InvalidateFlags nFlags)
Definition: paint.cxx:781
SAL_DLLPRIVATE void ImplInvalidateParentFrameRegion(vcl::Region &rRegion)
Definition: paint.cxx:770
RasterOp
Definition: vclenum.hxx:192
tools::Long mnOutOffX
Definition: window.h:404
SAL_DLLPRIVATE void ImplClipBoundaries(vcl::Region &rRegion, bool bThis, bool bOverlaps)
void Hide()
Definition: window.hxx:897
VclPtr< vcl::Window > mpLastChild
Definition: window.h:233
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
PushFlags
Definition: outdevstate.hxx:38
virtual OUString GetText() const
Definition: window.cxx:3044
void SetWindowRegionPixel()
Definition: paint.cxx:1038
void Play(GDIMetaFile &rMtf)
Definition: gdimtf.cxx:323
SAL_DLLPRIVATE void ImplValidate()
Definition: paint.cxx:961
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:863
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:176
ImplPaintFlags
Definition: window.h:198
constexpr bool IsEmpty() const
const Color & GetControlForeground() const
Definition: window2.cxx:1071
bool IsEmpty() const
Definition: region.cxx:228
void SetLineColor()
void PaintToDevice(::OutputDevice *pDevice, const Point &rPos)
Definition: paint.cxx:1556
void SetRefPoint()
Definition: outdev.cxx:288
virtual void PrePaint(vcl::RenderContext &rRenderContext)
Definition: paint.cxx:1013
void SetConnectMetaFile(GDIMetaFile *pMtf)
Definition: outdev.cxx:212
bool IsRTLEnabled() const
Definition: outdev.hxx:1238
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:549
bool IsDark() const
void DrawSelectionBackground(const tools::Rectangle &rRect, sal_uInt16 highlight, bool bChecked, bool bDrawBorder)
Definition: window.cxx:3447
void SetEmpty()
Definition: region.cxx:1417
const MapMode & GetMapMode() const
Definition: window3.cxx:99
virtual void EnableRTL(bool bEnable=true) override
Definition: virdev.cxx:384
void SetParent(vcl::Window *pNewParent)
Definition: stacking.cxx:831
bool SetOutputSizePixel(const Size &rNewSize, bool bErase=true)
Definition: virdev.cxx:396
virtual void ApplySettings(vcl::RenderContext &rRenderContext)
Definition: window.cxx:3832
void DrawTransparent(const tools::PolyPolygon &rPolyPoly, sal_uInt16 nTransparencePercent)
Any aHelper
SAL_DLLPRIVATE void ImplCallOverlapPaint()
Definition: paint.cxx:624
~PaintHelper()
Definition: paint.cxx:536
virtual void Invalidate(InvalidateFlags nFlags=InvalidateFlags::NONE)
Definition: paint.cxx:1144
SAL_DLLPRIVATE bool ImplIsAntiparallel() const
Definition: outdev.cxx:598
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:646
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()
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:162
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:314
void SetTextColor(const Color &rColor)
Definition: text.cxx:662
bool HasPaintEvent() const
Definition: paint.cxx:1241
std::unique_ptr< WindowImpl > mpWindowImpl
Definition: window.hxx:496
void SetPaintRect(const tools::Rectangle &rRect)
Definition: paint.cxx:183
SAL_DLLPRIVATE vcl::Window * ImplGetParent() const
Definition: window2.cxx:859
virtual void PixelInvalidate(const tools::Rectangle *pRectangle)
Notification about some rectangle of the output device got invalidated.
Definition: paint.cxx:1202
void Intersect(const tools::Rectangle &rRegion)
Definition: region.cxx:584
void Validate()
Definition: paint.cxx:1233
void SetOverlineColor()
Definition: textline.cxx:912
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:1630
const AllSettings & GetSettings() const
Definition: outdev.hxx:280
void SetPaintTransparent(bool bTransparent)
Definition: paint.cxx:1026
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:397
Point PixelToLogic(const Point &rDevicePt) const
Definition: window3.cxx:161
void WindStart()
Definition: gdimtf.cxx:550
void SetTextAlign(TextAlign eAlign)
Definition: window3.cxx:120
tools::Long Top() const
ControlPart mnNativeBackground
Definition: window.h:291
tools::Rectangle GetOutputRectPixel() const
Definition: window3.cxx:91
vcl::Window * GetParent() const
Definition: window2.cxx:1096
SAL_DLLPRIVATE void ImplCalcOverlapRegion(const tools::Rectangle &rSourceRect, vcl::Region &rRegion, bool bChildren, bool bSiblings)
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:308
constexpr Point TopLeft() const
tools::Long AdjustTop(tools::Long nVertMoveDelta)
MapUnit GetMapUnit()
AllSettings maSettings
Definition: window.h:403
SAL_WARN_UNUSED_RESULT Point PixelToLogic(const Point &rDevicePt) const
Definition: map.cxx:1066
SAL_DLLPRIVATE void ImplValidateFrameRegion(const vcl::Region *rRegion, ValidateFlags nFlags)
Definition: paint.cxx:921
SAL_DLLPRIVATE vcl::Window * ImplGetFirstOverlapWindow()
Definition: window2.cxx:874
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:192
void Exclude(const tools::Rectangle &rRegion)
Definition: region.cxx:675
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:533
void Erase()
Definition: wallpaper.cxx:103
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)
SAL_DLLPRIVATE void ImplInvalidateOverlapFrameRegion(const vcl::Region &rRegion)
Definition: paint.cxx:751
tools::Rectangle m_aPaintRect
Definition: window.h:406
bool IsVisible() const
Definition: window2.cxx:1101
bool mbInitClipRegion
Definition: outdev.hxx:248
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_WHITE
::OutputDevice const * GetOutDev() const
Definition: window.cxx:565
if(aStr!=aBuf) UpdateName_Impl(m_xFollowLb.get()
void EnableChildTransparentMode(bool bEnable=true)
Definition: window2.cxx:1021
void SetRasterOp(RasterOp eRasterOp)
void SetOutOffXPixel(tools::Long nOutOffX)
Definition: outdev.cxx:325
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:1021
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:490
virtual void DrawOutDev(const Point &rDestPt, const Size &rDestSize, const Point &rSrcPt, const Size &rSrcSize)
Definition: outdev.cxx:360
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:206
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:376
bool mbDevOutput
Definition: outdev.hxx:240
bool IsPaintTransparent() const
Definition: window2.cxx:1036
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).
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:1121
const vcl::ILibreOfficeKitNotifier * GetLOKNotifier() const
Definition: window.cxx:3237
tools::Long mnOutOffX
Output offset for device output in pixel (pseudo window offset within window system's frames) ...
Definition: outdev.hxx:203
tools::Long AdjustLeft(tools::Long nHorzMoveDelta)
#define SAL_WARN(area, stream)
WinBits GetStyle() const
Definition: window2.cxx:952
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:502
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:1191
vcl::Region m_aPaintRegion
Definition: paint.cxx:172
virtual void PostPaint(vcl::RenderContext &rRenderContext)
Definition: paint.cxx:1017
void CallEventListeners(VclEventId nEvent, void *pData=nullptr)
Definition: event.cxx:218
bool IsReallyVisible() const
Definition: window2.cxx:1106
void SetRestoreCursor(bool bRestoreCursor)
Definition: paint.cxx:191
ImplPaintFlags mnPaintFlags
Definition: window.h:293
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:210
const Wallpaper & GetBackground() const
Definition: window3.cxx:63
IMPL_LINK_NOARG(QuickSelectionEngine_Data, SearchStringTimeout, Timer *, void)
void Push(PushFlags nFlags=PushFlags::ALL)
Definition: outdevstate.cxx:59
SAL_DLLPRIVATE tools::Long ImplLogicHeightToDevicePixel(tools::Long nHeight) const
Convert a logical height to a height in units of device pixels.
Definition: map.cxx:322
bool SupportsDoubleBuffering() const
Can the widget derived from this Window do the double-buffering via RenderContext properly...
Definition: window.cxx:3842
SAL_DLLPRIVATE sal_Int32 GetDPIY() const
Get the output device's DPI y-axis value.
Definition: outdev.hxx:380
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:1256
bool isDisposed() const
VclPtr< vcl::Window > m_pWindow
Definition: window.h:400
bool mbTrackVisible
Definition: window.h:312
SAL_DLLPRIVATE sal_Int32 GetDPIX() const
Get the output device's DPI x-axis value.
Definition: outdev.hxx:374
void SetTextAlign(TextAlign eAlign)
Definition: text.cxx:763
constexpr tools::Long GetHeight() const
Wallpaper maBackground
Definition: window.h:402
void Show(bool bVisible=true, ShowFlags nFlags=ShowFlags::NONE)
Definition: window.cxx:2177