[Libreoffice-commits] core.git: 3 commits - include/vcl vcl/source

Miklos Vajna vmiklos at collabora.co.uk
Tue Aug 4 02:30:05 PDT 2015


 include/vcl/outdev.hxx       |    3 
 vcl/source/outdev/outdev.cxx |   10 ++
 vcl/source/window/paint.cxx  |  152 +++++++++++++++++++++++++------------------
 3 files changed, 103 insertions(+), 62 deletions(-)

New commits:
commit 28e465d2611adee62aac984a9c0bf731adcb793b
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Tue Aug 4 09:48:11 2015 +0200

    tdf#92982 vcl rendercontext: let PaintBufferGuard also manage pixel offset
    
    Change-Id: Ifd6a75c4312f93c815f5d137f515724f3629fa0d

diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx
index 3dab4e0..3eb6300 100644
--- a/include/vcl/outdev.hxx
+++ b/include/vcl/outdev.hxx
@@ -319,7 +319,6 @@ namespace vcl {
 
 class VCL_DLLPUBLIC OutputDevice
 {
-    friend class PaintHelper;
     friend class Printer;
     friend class VirtualDevice;
     friend class vcl::Window;
@@ -500,6 +499,8 @@ public:
     long                        GetOutputHeightPixel() const { return mnOutHeight; }
     long                        GetOutOffXPixel() const { return mnOutOffX; }
     long                        GetOutOffYPixel() const { return mnOutOffY; }
+    void                        SetOutOffXPixel(long nOutOffX);
+    void                        SetOutOffYPixel(long nOutOffY);
 
     Size                        GetOutputSize() const
                                     { return PixelToLogic( GetOutputSizePixel() ); }
diff --git a/vcl/source/outdev/outdev.cxx b/vcl/source/outdev/outdev.cxx
index ecc6c8f..7ccaf32 100644
--- a/vcl/source/outdev/outdev.cxx
+++ b/vcl/source/outdev/outdev.cxx
@@ -426,6 +426,16 @@ sal_uInt16 OutputDevice::GetBitCount() const
     return (sal_uInt16)mpGraphics->GetBitCount();
 }
 
+void OutputDevice::SetOutOffXPixel(long nOutOffX)
+{
+    mnOutOffX = nOutOffX;
+}
+
+void OutputDevice::SetOutOffYPixel(long nOutOffY)
+{
+    mnOutOffY = nOutOffY;
+}
+
 sal_uLong OutputDevice::GetColorCount() const
 {
 
diff --git a/vcl/source/window/paint.cxx b/vcl/source/window/paint.cxx
index 75c5128..68ae997 100644
--- a/vcl/source/window/paint.cxx
+++ b/vcl/source/window/paint.cxx
@@ -47,10 +47,14 @@ class PaintBufferGuard
     bool mbBackground;
     Wallpaper maBackground;
     AllSettings maSettings;
+    long mnOutOffX;
+    long mnOutOffY;
 public:
     PaintBufferGuard(ImplFrameData* pFrameData, vcl::Window* pWindow)
         : mpFrameData(pFrameData),
-        mbBackground(false)
+        mbBackground(false),
+        mnOutOffX(0),
+        mnOutOffY(0)
     {
         // transfer various settings
         // FIXME: this must disappear as we move to RenderContext only,
@@ -97,10 +101,18 @@ public:
         pFrameData->mpBuffer->SetRasterOp(pWindow->GetRasterOp());
         pFrameData->mpBuffer->SetLayoutMode(pWindow->GetLayoutMode());
         pFrameData->mpBuffer->SetDigitLanguage(pWindow->GetDigitLanguage());
+
+        mnOutOffX = pFrameData->mpBuffer->GetOutOffXPixel();
+        mnOutOffY = pFrameData->mpBuffer->GetOutOffYPixel();
+        pFrameData->mpBuffer->SetOutOffXPixel(pWindow->GetOutOffXPixel());
+        pFrameData->mpBuffer->SetOutOffYPixel(pWindow->GetOutOffYPixel());
     }
     ~PaintBufferGuard()
     {
         // Restore buffer state.
+        mpFrameData->mpBuffer->SetOutOffXPixel(mnOutOffX);
+        mpFrameData->mpBuffer->SetOutOffYPixel(mnOutOffY);
+
         mpFrameData->mpBuffer->Pop();
         mpFrameData->mpBuffer->SetSettings(maSettings);
         if (mbBackground)
@@ -183,16 +195,13 @@ void PaintHelper::StartBufferedPaint()
     // painting over, as VirtualDevice::ImplInitVirDev() would do.
     // The painted area is m_aPaintRect, or in case it's empty, then the whole window.
     pFrameData->mpBuffer->SetBackground(Wallpaper(Color(COL_WHITE)));
-    long nOutOffX = pFrameData->mpBuffer->GetOutOffXPixel();
-    long nOutOffY = pFrameData->mpBuffer->GetOutOffYPixel();
-    pFrameData->mpBuffer->mnOutOffX = m_pWindow->GetOutOffXPixel();
-    pFrameData->mpBuffer->mnOutOffY = m_pWindow->GetOutOffYPixel();
-    if (m_aPaintRect.IsEmpty())
-        pFrameData->mpBuffer->Erase(Rectangle(Point(0, 0), m_pWindow->GetOutputSize()));
-    else
-        pFrameData->mpBuffer->Erase(m_aPaintRect);
-    pFrameData->mpBuffer->mnOutOffX = nOutOffX;
-    pFrameData->mpBuffer->mnOutOffY = nOutOffY;
+    {
+        PaintBufferGuard g(pFrameData, m_pWindow);
+        if (m_aPaintRect.IsEmpty())
+            pFrameData->mpBuffer->Erase(Rectangle(Point(0, 0), m_pWindow->GetOutputSize()));
+        else
+            pFrameData->mpBuffer->Erase(m_aPaintRect);
+    }
 
     pFrameData->mbInBufferedPaint = true;
     m_bStartedBufferedPaint = true;
@@ -232,13 +241,8 @@ void PaintHelper::PaintBuffer()
             aPaintRectSize = m_pWindow->PixelToLogic(aRectanglePixel.GetSize());
         }
 
-        long nOutOffX = pFrameData->mpBuffer->GetOutOffXPixel();
-        long nOutOffY = pFrameData->mpBuffer->GetOutOffYPixel();
-        pFrameData->mpBuffer->mnOutOffX = m_pWindow->GetOutOffXPixel();
-        pFrameData->mpBuffer->mnOutOffY = m_pWindow->GetOutOffYPixel();
+        PaintBufferGuard g(pFrameData, m_pWindow);
         m_pWindow->DrawOutDev(m_aPaintRect.TopLeft(), aPaintRectSize, m_aPaintRect.TopLeft(), aPaintRectSize, *pFrameData->mpBuffer.get());
-        pFrameData->mpBuffer->mnOutOffX = nOutOffX;
-        pFrameData->mpBuffer->mnOutOffY = nOutOffY;
     }
 }
 
@@ -289,14 +293,8 @@ void PaintHelper::DoPaint(const vcl::Region* pRegion)
             PaintBufferGuard g(pFrameData, m_pWindow);
             m_pWindow->ApplySettings(*pFrameData->mpBuffer.get());
 
-            long nOutOffX = pFrameData->mpBuffer->mnOutOffX;
-            long nOutOffY = pFrameData->mpBuffer->mnOutOffY;
-            pFrameData->mpBuffer->mnOutOffX = m_pWindow->GetOutOffXPixel();
-            pFrameData->mpBuffer->mnOutOffY = m_pWindow->GetOutOffYPixel();
             m_pWindow->PushPaintHelper(this, *pFrameData->mpBuffer.get());
             m_pWindow->Paint(*pFrameData->mpBuffer.get(), m_aPaintRect);
-            pFrameData->mpBuffer->mnOutOffX = nOutOffX;
-            pFrameData->mpBuffer->mnOutOffY = nOutOffY;
         }
         else
         {
commit c36a00b811471b81abf189d80e07b5ff96243288
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Tue Aug 4 09:24:46 2015 +0200

    tdf#92982 vcl rendercontext: PaintHelper: restore set buffer properties
    
    If the buffer is persistent, then any member we change on it, so it suit
    our needs have to be undone once we're done with the painting.
    
    Change-Id: I7c5491b3b27601fb367af0856ac95cc3f845647a

diff --git a/vcl/source/window/paint.cxx b/vcl/source/window/paint.cxx
index 4545ae9..75c5128 100644
--- a/vcl/source/window/paint.cxx
+++ b/vcl/source/window/paint.cxx
@@ -40,6 +40,76 @@
 #define IMPL_PAINT_ERASE            ((sal_uInt16)0x0010)
 #define IMPL_PAINT_CHECKRTL         ((sal_uInt16)0x0020)
 
+/// Sets up the buffer to have settings matching the window, and restore the original state in the dtor.
+class PaintBufferGuard
+{
+    ImplFrameData* mpFrameData;
+    bool mbBackground;
+    Wallpaper maBackground;
+    AllSettings maSettings;
+public:
+    PaintBufferGuard(ImplFrameData* pFrameData, vcl::Window* pWindow)
+        : mpFrameData(pFrameData),
+        mbBackground(false)
+    {
+        // transfer various settings
+        // FIXME: this must disappear as we move to RenderContext only,
+        // the painting must become state-less, so that no actual
+        // vcl::Window setting affects this
+        mbBackground = pFrameData->mpBuffer->IsBackground();
+        if (pWindow->IsBackground())
+        {
+            maBackground = pFrameData->mpBuffer->GetBackground();
+            pFrameData->mpBuffer->SetBackground(pWindow->GetBackground());
+        }
+        //else
+            //SAL_WARN("vcl.doublebuffering", "the root of the double-buffering hierarchy should not have a transparent background");
+
+        PushFlags nFlags = PushFlags::NONE;
+        nFlags |= PushFlags::CLIPREGION;
+        nFlags |= PushFlags::FILLCOLOR;
+        nFlags |= PushFlags::FONT;
+        nFlags |= PushFlags::LINECOLOR;
+        nFlags |= PushFlags::MAPMODE;
+        maSettings = pFrameData->mpBuffer->GetSettings();
+        nFlags |= PushFlags::REFPOINT;
+        nFlags |= PushFlags::TEXTCOLOR;
+        nFlags |= PushFlags::TEXTLINECOLOR;
+        nFlags |= PushFlags::OVERLINECOLOR;
+        nFlags |= PushFlags::TEXTFILLCOLOR;
+        nFlags |= PushFlags::TEXTALIGN;
+        nFlags |= PushFlags::RASTEROP;
+        nFlags |= PushFlags::TEXTLAYOUTMODE;
+        nFlags |= PushFlags::TEXTLANGUAGE;
+        pFrameData->mpBuffer->Push(nFlags);
+        pFrameData->mpBuffer->SetClipRegion(pWindow->GetClipRegion());
+        pFrameData->mpBuffer->SetFillColor(pWindow->GetFillColor());
+        pFrameData->mpBuffer->SetFont(pWindow->GetFont());
+        pFrameData->mpBuffer->SetLineColor(pWindow->GetLineColor());
+        pFrameData->mpBuffer->SetMapMode(pWindow->GetMapMode());
+        pFrameData->mpBuffer->SetRefPoint(pWindow->GetRefPoint());
+        pFrameData->mpBuffer->SetSettings(pWindow->GetSettings());
+        pFrameData->mpBuffer->SetTextColor(pWindow->GetTextColor());
+        pFrameData->mpBuffer->SetTextLineColor(pWindow->GetTextLineColor());
+        pFrameData->mpBuffer->SetOverlineColor(pWindow->GetOverlineColor());
+        pFrameData->mpBuffer->SetTextFillColor(pWindow->GetTextFillColor());
+        pFrameData->mpBuffer->SetTextAlign(pWindow->GetTextAlign());
+        pFrameData->mpBuffer->SetRasterOp(pWindow->GetRasterOp());
+        pFrameData->mpBuffer->SetLayoutMode(pWindow->GetLayoutMode());
+        pFrameData->mpBuffer->SetDigitLanguage(pWindow->GetDigitLanguage());
+    }
+    ~PaintBufferGuard()
+    {
+        // Restore buffer state.
+        mpFrameData->mpBuffer->Pop();
+        mpFrameData->mpBuffer->SetSettings(maSettings);
+        if (mbBackground)
+            mpFrameData->mpBuffer->SetBackground(maBackground);
+        else
+            mpFrameData->mpBuffer->SetBackground();
+    }
+};
+
 class PaintHelper
 {
 private:
@@ -88,9 +158,6 @@ public:
     /// Start buffered paint: set it up to have the same settings as m_pWindow.
     void StartBufferedPaint();
 
-    /// Setup the buffer according to the settings of the current m_pWindow.
-    void SetupBuffer();
-
     /// Paint the content of the buffer to the current m_pWindow.
     void PaintBuffer();
 
@@ -134,35 +201,6 @@ void PaintHelper::StartBufferedPaint()
     m_aPaintRectMapMode = m_pWindow->GetMapMode();
 }
 
-void PaintHelper::SetupBuffer()
-{
-    ImplFrameData* pFrameData = m_pWindow->mpWindowImpl->mpFrameData;
-    // transfer various settings
-    // FIXME: this must disappear as we move to RenderContext only,
-    // the painting must become state-less, so that no actual
-    // vcl::Window setting affects this
-    if (m_pWindow->IsBackground())
-        pFrameData->mpBuffer->SetBackground(m_pWindow->GetBackground());
-    //else
-        //SAL_WARN("vcl.doublebuffering", "the root of the double-buffering hierarchy should not have a transparent background");
-
-    pFrameData->mpBuffer->SetClipRegion(m_pWindow->GetClipRegion());
-    pFrameData->mpBuffer->SetFillColor(m_pWindow->GetFillColor());
-    pFrameData->mpBuffer->SetFont(m_pWindow->GetFont());
-    pFrameData->mpBuffer->SetLineColor(m_pWindow->GetLineColor());
-    pFrameData->mpBuffer->SetMapMode(m_pWindow->GetMapMode());
-    pFrameData->mpBuffer->SetRefPoint(m_pWindow->GetRefPoint());
-    pFrameData->mpBuffer->SetSettings(m_pWindow->GetSettings());
-    pFrameData->mpBuffer->SetTextColor(m_pWindow->GetTextColor());
-    pFrameData->mpBuffer->SetTextLineColor(m_pWindow->GetTextLineColor());
-    pFrameData->mpBuffer->SetOverlineColor(m_pWindow->GetOverlineColor());
-    pFrameData->mpBuffer->SetTextFillColor(m_pWindow->GetTextFillColor());
-    pFrameData->mpBuffer->SetTextAlign(m_pWindow->GetTextAlign());
-    pFrameData->mpBuffer->SetRasterOp(m_pWindow->GetRasterOp());
-    pFrameData->mpBuffer->SetLayoutMode(m_pWindow->GetLayoutMode());
-    pFrameData->mpBuffer->SetDigitLanguage(m_pWindow->GetDigitLanguage());
-}
-
 void PaintHelper::PaintBuffer()
 {
     ImplFrameData* pFrameData = m_pWindow->mpWindowImpl->mpFrameData;
@@ -248,7 +286,7 @@ void PaintHelper::DoPaint(const vcl::Region* pRegion)
         if (pFrameData->mbInBufferedPaint && m_pWindow->SupportsDoubleBuffering())
         {
             // double-buffering
-            SetupBuffer();
+            PaintBufferGuard g(pFrameData, m_pWindow);
             m_pWindow->ApplySettings(*pFrameData->mpBuffer.get());
 
             long nOutOffX = pFrameData->mpBuffer->mnOutOffX;
commit 94a6daa068f75c7196e79a8a4295c2a069ff4530
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Tue Aug 4 08:48:08 2015 +0200

    tdf#92982 vcl rendercontext: set correct offset for the frame-level buffer
    
    In case we had a toplevel window W1, the paint was triggered for window
    W2 and we had a sub-widget W3, then previously the buffer was created
    for W2, so the pixel offsets had to be set relative to W2 when rendering
    W3. As a consequence, if a single window was painted, then it was
    always painted in the top left corner.
    
    Now that the buffer is persistent and is always created for W1, make
    sure that we paint to the correct offset, and W3 is always painted at
    the same offset, regardless if it was painted directly, or just because
    it's a child of W2.
    
    With this, the buffer conents is closer to what is on the screen, even
    if it's not perfect yet.
    
    Change-Id: Ibf0e89ad18e5763bd2a01e69d91da163c24a309d

diff --git a/vcl/source/window/paint.cxx b/vcl/source/window/paint.cxx
index b4965e5..4545ae9 100644
--- a/vcl/source/window/paint.cxx
+++ b/vcl/source/window/paint.cxx
@@ -116,24 +116,22 @@ void PaintHelper::StartBufferedPaint()
     // painting over, as VirtualDevice::ImplInitVirDev() would do.
     // The painted area is m_aPaintRect, or in case it's empty, then the whole window.
     pFrameData->mpBuffer->SetBackground(Wallpaper(Color(COL_WHITE)));
+    long nOutOffX = pFrameData->mpBuffer->GetOutOffXPixel();
+    long nOutOffY = pFrameData->mpBuffer->GetOutOffYPixel();
+    pFrameData->mpBuffer->mnOutOffX = m_pWindow->GetOutOffXPixel();
+    pFrameData->mpBuffer->mnOutOffY = m_pWindow->GetOutOffYPixel();
     if (m_aPaintRect.IsEmpty())
         pFrameData->mpBuffer->Erase(Rectangle(Point(0, 0), m_pWindow->GetOutputSize()));
     else
         pFrameData->mpBuffer->Erase(m_aPaintRect);
+    pFrameData->mpBuffer->mnOutOffX = nOutOffX;
+    pFrameData->mpBuffer->mnOutOffY = nOutOffY;
 
     pFrameData->mbInBufferedPaint = true;
     m_bStartedBufferedPaint = true;
 
     // Remember what was the map mode of m_aPaintRect.
     m_aPaintRectMapMode = m_pWindow->GetMapMode();
-
-    // we need to remember the mnOutOffX / mnOutOffY, but actually really
-    // set it just temporarily for the subwidgets - so we are setting it here
-    // only to remember the value & to be able to pass it to the descendants
-    // FIXME: once everything's double-buffered, this is (hopefully) not
-    // necessary as the buffer is always created for the main window.
-    pFrameData->mpBuffer->mnOutOffX = m_pWindow->GetOutOffXPixel();
-    pFrameData->mpBuffer->mnOutOffY = m_pWindow->GetOutOffYPixel();
 }
 
 void PaintHelper::SetupBuffer()
@@ -171,9 +169,6 @@ void PaintHelper::PaintBuffer()
     assert(pFrameData->mbInBufferedPaint);
     assert(m_bStartedBufferedPaint);
 
-    pFrameData->mpBuffer->mnOutOffX = 0;
-    pFrameData->mpBuffer->mnOutOffY = 0;
-
     // copy the buffer content to the actual window
     // export VCL_DOUBLEBUFFERING_AVOID_PAINT=1 to see where we are
     // painting directly instead of using Invalidate()
@@ -199,7 +194,13 @@ void PaintHelper::PaintBuffer()
             aPaintRectSize = m_pWindow->PixelToLogic(aRectanglePixel.GetSize());
         }
 
+        long nOutOffX = pFrameData->mpBuffer->GetOutOffXPixel();
+        long nOutOffY = pFrameData->mpBuffer->GetOutOffYPixel();
+        pFrameData->mpBuffer->mnOutOffX = m_pWindow->GetOutOffXPixel();
+        pFrameData->mpBuffer->mnOutOffY = m_pWindow->GetOutOffYPixel();
         m_pWindow->DrawOutDev(m_aPaintRect.TopLeft(), aPaintRectSize, m_aPaintRect.TopLeft(), aPaintRectSize, *pFrameData->mpBuffer.get());
+        pFrameData->mpBuffer->mnOutOffX = nOutOffX;
+        pFrameData->mpBuffer->mnOutOffY = nOutOffY;
     }
 }
 
@@ -250,19 +251,12 @@ void PaintHelper::DoPaint(const vcl::Region* pRegion)
             SetupBuffer();
             m_pWindow->ApplySettings(*pFrameData->mpBuffer.get());
 
-            // temporarily decrease the mnOutOffX/Y of the buffer for the
-            // subwidgets (because the buffer is our base here)
-            // FIXME: once everything's double-buffered, this is (hopefully) not
-            // necessary as the buffer is always created for the main window.
             long nOutOffX = pFrameData->mpBuffer->mnOutOffX;
             long nOutOffY = pFrameData->mpBuffer->mnOutOffY;
-            pFrameData->mpBuffer->mnOutOffX = m_pWindow->GetOutOffXPixel() - pFrameData->mpBuffer->mnOutOffX;
-            pFrameData->mpBuffer->mnOutOffY = m_pWindow->GetOutOffYPixel() - pFrameData->mpBuffer->mnOutOffY;
-
+            pFrameData->mpBuffer->mnOutOffX = m_pWindow->GetOutOffXPixel();
+            pFrameData->mpBuffer->mnOutOffY = m_pWindow->GetOutOffYPixel();
             m_pWindow->PushPaintHelper(this, *pFrameData->mpBuffer.get());
             m_pWindow->Paint(*pFrameData->mpBuffer.get(), m_aPaintRect);
-
-            // restore the mnOutOffX/Y value
             pFrameData->mpBuffer->mnOutOffX = nOutOffX;
             pFrameData->mpBuffer->mnOutOffY = nOutOffY;
         }


More information about the Libreoffice-commits mailing list