[Libreoffice-commits] core.git: 4 commits - include/svx sal/osl svx/source sw/source

Michael Stahl mstahl at redhat.com
Mon Jun 24 11:23:28 PDT 2013


 include/svx/sdrpaintwindow.hxx                    |    6 +
 sal/osl/unx/profile.c                             |   70 ++++++++++++++++------
 svx/source/sdr/overlay/overlaymanagerbuffered.cxx |   16 ++---
 svx/source/svdraw/sdrpaintwindow.cxx              |   27 ++++++++
 sw/source/core/view/viewsh.cxx                    |   49 +++++----------
 5 files changed, 108 insertions(+), 60 deletions(-)

New commits:
commit 38dcfadda85058a0ee87292c8943aec82e34b81e
Author: Michael Stahl <mstahl at redhat.com>
Date:   Mon Jun 24 19:50:30 2013 +0200

    fdo#58029: replace quadratic child window loop with linear
    
    ... which should speed things up without introducing problems.
    
    (Window::GetChild(n) is inefficient because the children are a linked
    list)
    
    Change-Id: I343d51a6866c5014cbca4c256b0c15f938958c39

diff --git a/include/svx/sdrpaintwindow.hxx b/include/svx/sdrpaintwindow.hxx
index bf8620c..d1694ee 100644
--- a/include/svx/sdrpaintwindow.hxx
+++ b/include/svx/sdrpaintwindow.hxx
@@ -41,6 +41,12 @@ namespace sdr
 #endif
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 
+/// paint the transparent children of rWin that overlap rPixelRect
+/// (for example, transparent form controls like check boxes)
+void SVX_DLLPUBLIC
+PaintTransparentChildren(Window & rWindow, Rectangle const& rPixelRect);
+
+
 class SdrPreRenderDevice
 {
     // The original OutputDevice
diff --git a/svx/source/sdr/overlay/overlaymanagerbuffered.cxx b/svx/source/sdr/overlay/overlaymanagerbuffered.cxx
index ecc2c68..1ff7cb9 100644
--- a/svx/source/sdr/overlay/overlaymanagerbuffered.cxx
+++ b/svx/source/sdr/overlay/overlaymanagerbuffered.cxx
@@ -18,6 +18,7 @@
  */
 
 #include <svx/sdr/overlay/overlaymanagerbuffered.hxx>
+#include <svx/sdrpaintwindow.hxx>
 #include <vcl/outdev.hxx>
 #include <basegfx/point/b2dpoint.hxx>
 #include <basegfx/range/b2drange.hxx>
@@ -392,28 +393,12 @@ namespace sdr
                 {
                     Window& rWindow = static_cast< Window& >(rmOutputDevice);
 
-                    if(rWindow.IsChildTransparentModeEnabled() && rWindow.GetChildCount())
-                    {
-                        const Rectangle aRegionRectanglePixel(
-                            maBufferRememberedRangePixel.getMinX(), maBufferRememberedRangePixel.getMinY(),
-                            maBufferRememberedRangePixel.getMaxX(), maBufferRememberedRangePixel.getMaxY());
-
-                        for(sal_uInt16 a(0); a < rWindow.GetChildCount(); a++)
-                        {
-                            Window* pCandidate = rWindow.GetChild(a);
-
-                            if(pCandidate && pCandidate->IsPaintTransparent())
-                            {
-                                const Rectangle aCandidatePosSizePixel(pCandidate->GetPosPixel(), pCandidate->GetSizePixel());
-
-                                if(aCandidatePosSizePixel.IsOver(aRegionRectanglePixel))
-                                {
-                                    pCandidate->Invalidate(INVALIDATE_NOTRANSPARENT|INVALIDATE_CHILDREN);
-                                    pCandidate->Update();
-                                }
-                            }
-                        }
-                    }
+                    const Rectangle aRegionRectanglePixel(
+                        maBufferRememberedRangePixel.getMinX(),
+                        maBufferRememberedRangePixel.getMinY(),
+                        maBufferRememberedRangePixel.getMaxX(),
+                        maBufferRememberedRangePixel.getMaxY());
+                    PaintTransparentChildren(rWindow, aRegionRectanglePixel);
                 }
 
                 // #i80730# restore visibility of VCL cursor
diff --git a/svx/source/svdraw/sdrpaintwindow.cxx b/svx/source/svdraw/sdrpaintwindow.cxx
index a550c9e..6abacc5 100644
--- a/svx/source/svdraw/sdrpaintwindow.cxx
+++ b/svx/source/svdraw/sdrpaintwindow.cxx
@@ -23,6 +23,33 @@
 #include <vcl/gdimtf.hxx>
 #include <vcl/svapp.hxx>
 
+
+void PaintTransparentChildren(Window & rWindow, Rectangle const& rPixelRect)
+{
+    if (rWindow.IsChildTransparentModeEnabled())
+    {
+        Window * pCandidate = rWindow.GetWindow( WINDOW_FIRSTCHILD );
+        while (pCandidate)
+        {
+            if (pCandidate->IsPaintTransparent())
+            {
+                const Rectangle aCandidatePosSizePixel(
+                                pCandidate->GetPosPixel(),
+                                pCandidate->GetSizePixel());
+
+                if (aCandidatePosSizePixel.IsOver(rPixelRect))
+                {
+                    pCandidate->Invalidate(
+                        INVALIDATE_NOTRANSPARENT|INVALIDATE_CHILDREN );
+                    // important: actually paint the child here!
+                    pCandidate->Update();
+                }
+            }
+            pCandidate = pCandidate->GetWindow( WINDOW_NEXT );
+        }
+    }
+}
+
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 
 SdrPreRenderDevice::SdrPreRenderDevice(OutputDevice& rOriginal)
diff --git a/sw/source/core/view/viewsh.cxx b/sw/source/core/view/viewsh.cxx
index dd9aa93..2bae711 100644
--- a/sw/source/core/view/viewsh.cxx
+++ b/sw/source/core/view/viewsh.cxx
@@ -107,32 +107,8 @@ lcl_PaintTransparentFormControls(ViewShell & rShell, SwRect const& rRect)
     if (rShell.GetWin())
     {
         Window& rWindow = *(rShell.GetWin());
-        if (rWindow.IsChildTransparentModeEnabled())
-        {
-            Window * pCandidate = rWindow.GetWindow( WINDOW_FIRSTCHILD );
-            if (pCandidate)
-            {
-                const Rectangle aRectanglePixel(
-                            rWindow.LogicToPixel(rRect.SVRect()));
-                while (pCandidate)
-                {
-                    if (pCandidate->IsPaintTransparent())
-                    {
-                        const Rectangle aCandidatePosSizePixel(
-                                        pCandidate->GetPosPixel(),
-                                        pCandidate->GetSizePixel());
-
-                        if (aCandidatePosSizePixel.IsOver(aRectanglePixel))
-                        {
-                            pCandidate->Invalidate(
-                                INVALIDATE_NOTRANSPARENT|INVALIDATE_CHILDREN );
-                            pCandidate->Update();
-                        }
-                    }
-                    pCandidate = pCandidate->GetWindow( WINDOW_NEXT );
-                }
-            }
-        }
+        const Rectangle aRectanglePixel(rWindow.LogicToPixel(rRect.SVRect()));
+        PaintTransparentChildren(rWindow, aRectanglePixel);
     }
 }
 
commit f022f39638fbe970f1b839c757dcccd3baa69445
Author: Michael Stahl <mstahl at redhat.com>
Date:   Mon Jun 24 19:05:45 2013 +0200

    fdo#60444: Revert "fdo#58029 - substantially accelerate re-rendering..."
    
    This reverts commit 6c98ad71478cb72b51634b32d6e553ccaec30190.
    
    This breaks selection of transparent form controls (fdo#60444), because
    the Update method is not called on the children.
    
    Change-Id: Id0b6a34a15aa1ed7bd5aa0d7b5626e60bee57e30

diff --git a/svx/source/sdr/overlay/overlaymanagerbuffered.cxx b/svx/source/sdr/overlay/overlaymanagerbuffered.cxx
index 309fabe..ecc2c68 100644
--- a/svx/source/sdr/overlay/overlaymanagerbuffered.cxx
+++ b/svx/source/sdr/overlay/overlaymanagerbuffered.cxx
@@ -391,15 +391,28 @@ namespace sdr
                 if(bTargetIsWindow)
                 {
                     Window& rWindow = static_cast< Window& >(rmOutputDevice);
-                    if(rWindow.IsChildTransparentModeEnabled())
+
+                    if(rWindow.IsChildTransparentModeEnabled() && rWindow.GetChildCount())
                     {
-                        // Get VCL to invalidate it's children - more efficiently. fdo#58029
                         const Rectangle aRegionRectanglePixel(
                             maBufferRememberedRangePixel.getMinX(), maBufferRememberedRangePixel.getMinY(),
                             maBufferRememberedRangePixel.getMaxX(), maBufferRememberedRangePixel.getMaxY());
 
-                        rWindow.Invalidate(aRegionRectanglePixel,
-                                           INVALIDATE_NOTRANSPARENT|INVALIDATE_CHILDREN|INVALIDATE_UPDATE);
+                        for(sal_uInt16 a(0); a < rWindow.GetChildCount(); a++)
+                        {
+                            Window* pCandidate = rWindow.GetChild(a);
+
+                            if(pCandidate && pCandidate->IsPaintTransparent())
+                            {
+                                const Rectangle aCandidatePosSizePixel(pCandidate->GetPosPixel(), pCandidate->GetSizePixel());
+
+                                if(aCandidatePosSizePixel.IsOver(aRegionRectanglePixel))
+                                {
+                                    pCandidate->Invalidate(INVALIDATE_NOTRANSPARENT|INVALIDATE_CHILDREN);
+                                    pCandidate->Update();
+                                }
+                            }
+                        }
                     }
                 }
 
commit cfa994ccbd6ee681f5ab3648ce068c4881b495f5
Author: Michael Stahl <mstahl at redhat.com>
Date:   Mon Jun 24 18:09:35 2013 +0200

    fdo#43765, fdo#57884, fdo#58052, fdo#63949: disappearing form controls
    
    Transparent form controls in Writer may not be painted properly, if
    painted from ViewShell::ImplUnlockPaint(true), called from
    SwLayIdle::SwLayIdle.
    
    The problem is that SdrPaintWindow::OutputPreRenderDevice will paint
    the background of the transparent form controls (thus over-painting the
    controls), so it has to be followed by painting the controls themselves.
    
    Change-Id: Icda4ad835a398bbd50139be32ff5014a34f23bd5

diff --git a/sw/source/core/view/viewsh.cxx b/sw/source/core/view/viewsh.cxx
index 19da338..dd9aa93 100644
--- a/sw/source/core/view/viewsh.cxx
+++ b/sw/source/core/view/viewsh.cxx
@@ -99,6 +99,43 @@ void ViewShell::ToggleHeaderFooterEdit()
     GetWin()->Invalidate();
 }
 
+static void
+lcl_PaintTransparentFormControls(ViewShell & rShell, SwRect const& rRect)
+{
+    // Direct paint has been performed: the background of transparent child
+    // windows has been painted, so need to paint the child windows now.
+    if (rShell.GetWin())
+    {
+        Window& rWindow = *(rShell.GetWin());
+        if (rWindow.IsChildTransparentModeEnabled())
+        {
+            Window * pCandidate = rWindow.GetWindow( WINDOW_FIRSTCHILD );
+            if (pCandidate)
+            {
+                const Rectangle aRectanglePixel(
+                            rWindow.LogicToPixel(rRect.SVRect()));
+                while (pCandidate)
+                {
+                    if (pCandidate->IsPaintTransparent())
+                    {
+                        const Rectangle aCandidatePosSizePixel(
+                                        pCandidate->GetPosPixel(),
+                                        pCandidate->GetSizePixel());
+
+                        if (aCandidatePosSizePixel.IsOver(aRectanglePixel))
+                        {
+                            pCandidate->Invalidate(
+                                INVALIDATE_NOTRANSPARENT|INVALIDATE_CHILDREN );
+                            pCandidate->Update();
+                        }
+                    }
+                    pCandidate = pCandidate->GetWindow( WINDOW_NEXT );
+                }
+            }
+        }
+    }
+}
+
 // #i72754# 2nd set of Pre/PostPaints
 // This time it uses the lock counter (mPrePostPaintRegions empty/non-empty) to allow only one activation
 // and deactivation and mpPrePostOutDev to remember the OutDev from the BeginDrawLayers
@@ -356,39 +393,7 @@ void ViewShell::ImplEndAction( const sal_Bool bIdleEnd )
                         DLPostPaint2(true);
                     }
 
-                    // #i107365#
-                    // Direct paint has been performed. Thus, take care of
-                    // transparent child windows.
-                    if ( GetWin() )
-                    {
-                        Window& rWindow = *(GetWin());
-                        if (rWindow.IsChildTransparentModeEnabled())
-                        {
-                            Window* pCandidate = rWindow.GetWindow( WINDOW_FIRSTCHILD );
-                            if (pCandidate)
-                            {
-                                const Rectangle aRectanglePixel(rWindow.LogicToPixel(aRect.SVRect()));
-
-                                while (pCandidate)
-                                {
-                                    if ( pCandidate->IsPaintTransparent() )
-                                    {
-                                        const Rectangle aCandidatePosSizePixel(
-                                                        pCandidate->GetPosPixel(),
-                                                        pCandidate->GetSizePixel());
-
-                                        if ( aCandidatePosSizePixel.IsOver(aRectanglePixel) )
-                                        {
-                                            pCandidate->Invalidate( INVALIDATE_NOTRANSPARENT|INVALIDATE_CHILDREN );
-                                            pCandidate->Update();
-                                        }
-                                    }
-
-                                    pCandidate = pCandidate->GetWindow( WINDOW_NEXT );
-                                }
-                            }
-                        }
-                    }
+                    lcl_PaintTransparentFormControls(*this, aRect); // i#107365
                 }
 
                 delete pVout;
@@ -471,6 +476,8 @@ void ViewShell::ImplUnlockPaint( sal_Bool bVirDev )
 
                 // #i72754# end Pre/PostPaint encapsulation when mpOut is back and content is painted
                 DLPostPaint2(true);
+
+                lcl_PaintTransparentFormControls(*this, VisArea()); // fdo#63949
             }
             else
             {
commit 52066e4726436cb560098856af2d6f976199f5f4
Author: Norbert Thiebaud <nthiebaud at gmail.com>
Date:   Thu Jun 20 14:26:49 2013 -0500

    coverity#706154 : Destination buffer too small
    
    Change-Id: I27bc8803353047a057caaf2353f10cdab08e81e9

diff --git a/sal/osl/unx/profile.c b/sal/osl/unx/profile.c
index d27dda7..acfd91c 100644
--- a/sal/osl/unx/profile.c
+++ b/sal/osl/unx/profile.c
@@ -144,7 +144,7 @@ static sal_Bool releaseProfile(osl_TProfileImpl* pProfile);
 static sal_Bool writeProfileImpl (osl_TFile* pFile);
 static osl_TFile* osl_openTmpProfileImpl(osl_TProfileImpl*);
 static sal_Bool osl_ProfileSwapProfileNames(osl_TProfileImpl*);
-static void osl_ProfileGenerateExtension(sal_Char* pszFileName, sal_Char* pszExtension, sal_Char* pszTmpName);
+static void osl_ProfileGenerateExtension(const sal_Char* pszFileName, const sal_Char* pszExtension, sal_Char* pszTmpName, int BufferMaxLen);
 static oslProfile SAL_CALL osl_psz_openProfile(const sal_Char *pszProfileName, oslProfileOption Flags);
 
 /* implemented in file.c */
@@ -2008,7 +2008,7 @@ static osl_TFile* osl_openTmpProfileImpl(osl_TProfileImpl* pProfile)
     pszTmpName[0] = '\0';
 
     /* generate tmp profilename */
-    osl_ProfileGenerateExtension(pProfile->m_FileName,pszExtension,pszTmpName);
+    osl_ProfileGenerateExtension(pProfile->m_FileName, pszExtension, pszTmpName, PATH_MAX);
 
     if ( pszTmpName[0] == 0 )
     {
@@ -2030,41 +2030,75 @@ static osl_TFile* osl_openTmpProfileImpl(osl_TProfileImpl* pProfile)
 
 static sal_Bool osl_ProfileSwapProfileNames(osl_TProfileImpl* pProfile)
 {
-      sal_Bool bRet = sal_False;
+    sal_Bool bRet = sal_False;
 
-      sal_Char pszBakFile[PATH_MAX];
-      sal_Char pszTmpFile[PATH_MAX];
-      sal_Char pszIniFile[PATH_MAX];
+    sal_Char pszBakFile[PATH_MAX];
+    sal_Char pszTmpFile[PATH_MAX];
+    sal_Char pszIniFile[PATH_MAX];
 
     pszBakFile[0] = '\0';
     pszTmpFile[0] = '\0';
     pszIniFile[0] = '\0';
 
-      osl_ProfileGenerateExtension(pProfile->m_FileName,"bak",pszBakFile);
+    osl_ProfileGenerateExtension(pProfile->m_FileName, "bak", pszBakFile, PATH_MAX);
 
     strcpy(pszIniFile,pProfile->m_FileName);
 
-    osl_ProfileGenerateExtension(pProfile->m_FileName,"tmp",pszTmpFile);
+    osl_ProfileGenerateExtension(pProfile->m_FileName, "tmp", pszTmpFile, PATH_MAX);
 
-      /* unlink bak */
-      unlink( pszBakFile );
+    /* unlink bak */
+    unlink( pszBakFile );
 
-      /* rename ini bak */
-      rename( pszIniFile, pszBakFile );
+    /* rename ini bak */
+    rename( pszIniFile, pszBakFile );
 
-      /* rename tmp ini */
-      rename( pszTmpFile, pszIniFile );
+    /* rename tmp ini */
+    rename( pszTmpFile, pszIniFile );
 
     return bRet;
 }
 
 
-static void osl_ProfileGenerateExtension(sal_Char* pszFileName, sal_Char* pszExtension, sal_Char* pszTmpName)
+static void osl_ProfileGenerateExtension(const sal_Char* pszFileName, const sal_Char* pszExtension, sal_Char* pszTmpName, int BufferMaxLen)
 {
+    sal_Char* cursor = pszTmpName;
+    int len;
 
-    strcpy(pszTmpName,pszFileName);
-    strcat(pszTmpName,".");
-    strcat(pszTmpName,pszExtension);
+    /* concatenate filename + "." + extension, limited to the size of the
+     * output buffer; in case of overrun, data is truncated at the end...
+     * and the result is always 0-terminated.
+     */
+    len = strlen(pszFileName);
+    if(len < BufferMaxLen)
+    {
+        memcpy(cursor, pszFileName, len);
+        cursor += len;
+        BufferMaxLen -= len;
+    }
+    else
+    {
+        memcpy(cursor, pszFileName, BufferMaxLen - 1);
+        cursor += BufferMaxLen - 1;
+        BufferMaxLen = 1;
+    }
+    if(BufferMaxLen > 1)
+    {
+        *cursor++ = '.';
+        BufferMaxLen -= 1;
+    }
+    len = strlen(pszExtension);
+    if(len < BufferMaxLen)
+    {
+        memcpy(cursor, pszExtension, len);
+        cursor += len;
+    }
+    else
+    {
+        memcpy(cursor, pszExtension, BufferMaxLen - 1);
+        cursor += BufferMaxLen - 1;
+        BufferMaxLen = 1;
+    }
+    *cursor = 0;
 
     return;
 }


More information about the Libreoffice-commits mailing list