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