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