[Libreoffice-commits] core.git: sw/inc sw/source

Luboš Luňák (via logerrit) logerrit at kemper.freedesktop.org
Sun Sep 19 07:33:21 UTC 2021


 sw/inc/swregion.hxx                |   20 +++++++++++++++++---
 sw/source/core/bastyp/swregion.cxx |   15 +++++++++++++--
 sw/source/core/crsr/viscrs.cxx     |    6 +++---
 sw/source/core/view/viewimp.cxx    |    5 +++--
 sw/source/core/view/viewsh.cxx     |    7 ++-----
 5 files changed, 38 insertions(+), 15 deletions(-)

New commits:
commit 5a3c60f7c76fc0eca21f0fd468783e0ae48e3129
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Fri Sep 17 00:22:49 2021 +0200
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Sun Sep 19 09:32:48 2021 +0200

    do not double-invert SwRegionRects
    
    The usual way to use SwRegionRects seems to be to set it to the full
    area (origin) and then use operator-= to remove parts. But operator-=
    is slower than operator+=, so if that all is followed by Invert()
    and Compress(), it's essentially inverting the operation twice,
    making it both slower and (IMO) more complicated. Make it possible
    to simply use operator+=, collect all rectangles and then
    post-process once using LimitToOrigin()+Compress().
    
    I'm not entirely happy about the SwRegionRects constructor, but
    I don't have a better idea that wouldn't silently break backwards
    compatibility for backporting.
    
    Change-Id: If3c83e32729e5d02b9d97b66c93fac04d4fb3ecc
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122215
    Tested-by: Jenkins
    Reviewed-by: Luboš Luňák <l.lunak at collabora.com>

diff --git a/sw/inc/swregion.hxx b/sw/inc/swregion.hxx
index 7ba3ffdee024..1aa190712a8f 100644
--- a/sw/inc/swregion.hxx
+++ b/sw/inc/swregion.hxx
@@ -25,22 +25,36 @@
 
 typedef std::vector<SwRect> SwRects;
 
+// A collection of rectangles within a given area (origin).
+// One way to use is to initially set rStartRect, which will set the origin
+// and the rectangles to rStartRect, and then use operator-= to punch holes.
+// Other way to use is to use empty constructor, call ChangeOrigin() and
+// then use operator+= to add rectangles, possibly followed by final
+// LimitToOrigin() and Compress(). The second way should be faster than
+// the first way followed by Invert().
 class SwRegionRects : public SwRects
 {
-    SwRect m_aOrigin; // Copy of StartRect.
+    SwRect m_aOrigin; // Origin area, limits the total area e.g. for Invert()
 
     inline void InsertRect( const SwRect &rRect, const sal_uInt16 nPos, bool &rDel);
 
 public:
-    SwRegionRects( const SwRect& rStartRect, sal_uInt16 nInit = 20 );
+    // Sets rStartRect as the first element and also the origin area.
+    explicit SwRegionRects( const SwRect& rStartRect, sal_uInt16 nInit = 20 );
+    // Empty constructor, does not set elements or origin area. You may
+    // most likely want to call ChangeOrigin() afterwards.
+    explicit SwRegionRects( sal_uInt16 nInit = 20 );
 
     // For punching from aOrigin.
     void operator-=( const SwRect& rRect );
     void operator+=( const SwRect& rRect );
 
-    // From holes to areas, from areas to holes.
+    // From holes to areas, from areas to holes, within the origin area.
     void Invert();
 
+    // Ensures all rectangles are within the origin area.
+    void LimitToOrigin();
+
     // Combine adjacent rectangles.
     void Compress();
 
diff --git a/sw/source/core/bastyp/swregion.cxx b/sw/source/core/bastyp/swregion.cxx
index 19ab3c3c988d..a2e3c405707d 100644
--- a/sw/source/core/bastyp/swregion.cxx
+++ b/sw/source/core/bastyp/swregion.cxx
@@ -28,6 +28,12 @@ SwRegionRects::SwRegionRects( const SwRect &rStartRect, sal_uInt16 nInit ) :
     push_back( m_aOrigin );
 }
 
+SwRegionRects::SwRegionRects( sal_uInt16 nInit ) :
+    m_aOrigin()
+{
+    reserve(nInit);
+}
+
 // If <rDel> is true then this Rect will be overwritten by <rRect> at
 // position <nPos>. Otherwise <rRect> is attached at the end.
 inline void SwRegionRects::InsertRect( const SwRect &rRect,
@@ -46,8 +52,7 @@ inline void SwRegionRects::InsertRect( const SwRect &rRect,
 
 void SwRegionRects::operator+=( const SwRect &rRect )
 {
-    bool f = false;
-    InsertRect( rRect, 0, f );
+    push_back( rRect );
 }
 
 /** Delete all overlaps of the Rects in array with the given <rRect>
@@ -140,6 +145,12 @@ static inline SwTwips CalcArea( const SwRect &rRect )
     return rRect.Width() * rRect.Height();
 }
 
+void SwRegionRects::LimitToOrigin()
+{
+    for (size_type i = 0; i < size(); ++i )
+        (*this)[ i ].Intersection( m_aOrigin );
+}
+
 // combine all adjacent rectangles
 void SwRegionRects::Compress()
 {
diff --git a/sw/source/core/crsr/viscrs.cxx b/sw/source/core/crsr/viscrs.cxx
index e8eab007038d..7d8064719228 100644
--- a/sw/source/core/crsr/viscrs.cxx
+++ b/sw/source/core/crsr/viscrs.cxx
@@ -836,9 +836,9 @@ void SwShellTableCursor::FillRects()
         return;
 
     bool bStart = true;
-    SwRegionRects aReg( GetShell()->VisArea() );
-    if (comphelper::LibreOfficeKit::isActive())
-        aReg = GetShell()->getIDocumentLayoutAccess().GetCurrentLayout()->getFrameArea();
+    SwRegionRects aReg( comphelper::LibreOfficeKit::isActive()
+        ? GetShell()->getIDocumentLayoutAccess().GetCurrentLayout()->getFrameArea()
+        : GetShell()->VisArea() );
     SwNodes& rNds = GetDoc().GetNodes();
     SwFrame* pEndFrame = nullptr;
     for (size_t n = 0; n < m_SelectedBoxes.size(); ++n)
diff --git a/sw/source/core/view/viewimp.cxx b/sw/source/core/view/viewimp.cxx
index 16657bb0849a..50304b384020 100644
--- a/sw/source/core/view/viewimp.cxx
+++ b/sw/source/core/view/viewimp.cxx
@@ -129,9 +129,10 @@ bool SwViewShellImp::AddPaintRect( const SwRect &rRect )
             // In case of normal rendering, this makes sure only visible rectangles are painted.
             // Otherwise get the rectangle of the full document, so all paint rectangles are invalidated.
             const SwRect& rArea = comphelper::LibreOfficeKit::isActive() ? m_pShell->GetLayout()->getFrameArea() : m_pShell->VisArea();
-            m_pRegion.reset(new SwRegionRects(rArea));
+            m_pRegion.reset(new SwRegionRects);
+            m_pRegion->ChangeOrigin(rArea);
         }
-        (*m_pRegion) -= rRect;
+        (*m_pRegion) += rRect;
         return true;
     }
     return false;
diff --git a/sw/source/core/view/viewsh.cxx b/sw/source/core/view/viewsh.cxx
index 0670e8e102b4..c78ea43516b1 100644
--- a/sw/source/core/view/viewsh.cxx
+++ b/sw/source/core/view/viewsh.cxx
@@ -329,9 +329,7 @@ void SwViewShell::ImplEndAction( const bool bIdleEnd )
             {
                 SwRootFrame* pCurrentLayout = GetLayout();
 
-                //First Invert then Compress, never the other way round!
-                pRegion->Invert();
-
+                pRegion->LimitToOrigin();
                 pRegion->Compress();
 
                 ScopedVclPtr<VirtualDevice> pVout;
@@ -1667,8 +1665,7 @@ bool SwViewShell::CheckInvalidForPaint( const SwRect &rRect )
 
         if ( pRegion )
         {
-            //First Invert then Compress, never the other way round!
-            pRegion->Invert();
+            pRegion->LimitToOrigin();
             pRegion->Compress();
             bRet = false;
             if ( !pRegion->empty() )


More information about the Libreoffice-commits mailing list