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