Blame SOURCES/0001-Related-fdo-87242-init-VirtualDevice-with-size-of-su.patch

ebc4bd
From bc839c159d4ee94ef8ca08975cf65be37378ae04 Mon Sep 17 00:00:00 2001
ebc4bd
From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com>
ebc4bd
Date: Thu, 11 Dec 2014 16:20:49 +0000
ebc4bd
Subject: [PATCH] Related: fdo#87242 init VirtualDevice with size of surface
ebc4bd
ebc4bd
otherwise vcl's clipping doesn't work quite right when the render text
ebc4bd
with vcl apis fallback is used.
ebc4bd
ebc4bd
Manually forced in my case, but it should happen in practice with vertical
ebc4bd
text, so if there is a bug about vertical text not appearing in slideshows then
ebc4bd
this is part of the fix for that.
ebc4bd
ebc4bd
Windows and Mac remain unchanged as initialized with 1, 1. If the same problem
ebc4bd
affects those platforms then they'll need to be adjusted to remember their
ebc4bd
height/widths from the ctor and those values plugged in here instead
ebc4bd
ebc4bd
(cherry picked from commit f95b0743da4239e047db8638c61f90f8bbe54306)
ebc4bd
(cherry picked from commit e2be2c23c1ad61b3bd640be6f16d66f5cd925d38)
ebc4bd
ebc4bd
Conflicts:
ebc4bd
	desktop/source/lib/init.cxx
ebc4bd
ebc4bd
Related: fdo#87242 merge duplicate clip setup code
ebc4bd
ebc4bd
favoring the vclcanvas one for the places where
ebc4bd
they diverge
ebc4bd
ebc4bd
(cherry picked from commit f88b5ab8692ee7ecf58b570e703d0e7f10cc2f0d)
ebc4bd
(cherry picked from commit e0e96579ce3a248ee5d3b07ecf90f38e2020c555)
ebc4bd
ebc4bd
Conflicts:
ebc4bd
	canvas/source/cairo/cairo_canvashelper_text.cxx
ebc4bd
	canvas/source/vcl/canvashelper.cxx
ebc4bd
ebc4bd
Resolves: fdo#87242 reuse vcl clip for cairo during animations
ebc4bd
ebc4bd
(cherry picked from commit 94d935eecbba0161de2616c2234b4a5d9d3cad88)
ebc4bd
(cherry picked from commit 3a108b0600ce61f7960d561cee9989ab3a48780f)
ebc4bd
ebc4bd
stray debugging code
ebc4bd
ebc4bd
(cherry picked from commit 067b560335195b24eeedc4514956029ea975fbbf)
ebc4bd
(cherry picked from commit fafc85559097166eceb67c4db4528cc9977e4184)
ebc4bd
ebc4bd
Change-Id: I2f82f0db0cf446d7db21f0a7ee4f8c15c7ebdb42
ebc4bd
18e3d4e7659ebd4cb90c86718c1b1035671b4be3
ebc4bd
0a26d4c4092226732620c3852b0402ee45d4fa1d
ebc4bd
953389e236739c01226365c33ab777fc3972b69d
ebc4bd
---
ebc4bd
 canvas/source/cairo/cairo_canvashelper.hxx      |   3 +
ebc4bd
 canvas/source/cairo/cairo_canvashelper_text.cxx | 117 ++++++++++--------------
ebc4bd
 canvas/source/cairo/cairo_quartz_cairo.cxx      |   2 +-
ebc4bd
 canvas/source/cairo/cairo_win32_cairo.cxx       |   2 +-
ebc4bd
 canvas/source/cairo/cairo_xlib_cairo.cxx        |   7 +-
ebc4bd
 canvas/source/tools/canvastools.cxx             |  75 +++++++++++++++
ebc4bd
 canvas/source/vcl/canvashelper.cxx              |  79 +---------------
ebc4bd
 include/canvas/canvastools.hxx                  |   6 ++
ebc4bd
 include/vcl/virdev.hxx                          |   3 +-
ebc4bd
 vcl/source/gdi/virdev.cxx                       |   6 +-
ebc4bd
 10 files changed, 147 insertions(+), 153 deletions(-)
ebc4bd
ebc4bd
diff --git a/canvas/source/cairo/cairo_canvashelper.hxx b/canvas/source/cairo/cairo_canvashelper.hxx
ebc4bd
index 9258e7c..ccb03ac 100644
ebc4bd
--- a/canvas/source/cairo/cairo_canvashelper.hxx
ebc4bd
+++ b/canvas/source/cairo/cairo_canvashelper.hxx
ebc4bd
@@ -310,6 +310,9 @@ namespace cairocanvas
ebc4bd
         ::cairo::CairoSharedPtr     mpCairo;
ebc4bd
         ::cairo::SurfaceSharedPtr   mpSurface;
ebc4bd
         ::basegfx::B2ISize maSize;
ebc4bd
+
ebc4bd
+        void clip_cairo_from_dev(::OutputDevice& rOutDev);
ebc4bd
+
ebc4bd
     };
ebc4bd
 
ebc4bd
     /// also needed from SpriteHelper
ebc4bd
diff --git a/canvas/source/cairo/cairo_canvashelper_text.cxx b/canvas/source/cairo/cairo_canvashelper_text.cxx
ebc4bd
index d65f2de..78a2ddf 100644
ebc4bd
--- a/canvas/source/cairo/cairo_canvashelper_text.cxx
ebc4bd
+++ b/canvas/source/cairo/cairo_canvashelper_text.cxx
ebc4bd
@@ -127,73 +127,7 @@ namespace cairocanvas
ebc4bd
 
ebc4bd
         // TODO(P2): Don't change clipping all the time, maintain current clip
ebc4bd
         // state and change only when update is necessary
ebc4bd
-
ebc4bd
-        // accumulate non-empty clips into one region
ebc4bd
-        // ==========================================
ebc4bd
-
ebc4bd
-        Region aClipRegion;
ebc4bd
-
ebc4bd
-        if( viewState.Clip.is() )
ebc4bd
-        {
ebc4bd
-            ::basegfx::B2DPolyPolygon aClipPoly(
ebc4bd
-                ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(
ebc4bd
-                    viewState.Clip) );
ebc4bd
-
ebc4bd
-            if( aClipPoly.count() )
ebc4bd
-            {
ebc4bd
-                // setup non-empty clipping
ebc4bd
-                ::basegfx::B2DHomMatrix aMatrix;
ebc4bd
-                aClipPoly.transform(
ebc4bd
-                    ::basegfx::unotools::homMatrixFromAffineMatrix( aMatrix,
ebc4bd
-                                                                    viewState.AffineTransform ) );
ebc4bd
-
ebc4bd
-                aClipRegion = Region::GetRegionFromPolyPolygon( ::PolyPolygon( aClipPoly ) );
ebc4bd
-            }
ebc4bd
-        }
ebc4bd
-
ebc4bd
-        if( renderState.Clip.is() )
ebc4bd
-        {
ebc4bd
-            ::basegfx::B2DPolyPolygon aClipPoly(
ebc4bd
-                ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(
ebc4bd
-                    renderState.Clip) );
ebc4bd
-
ebc4bd
-            ::basegfx::B2DHomMatrix aMatrix;
ebc4bd
-            aClipPoly.transform(
ebc4bd
-                ::canvas::tools::mergeViewAndRenderTransform( aMatrix,
ebc4bd
-                                                              viewState,
ebc4bd
-                                                              renderState ) );
ebc4bd
-
ebc4bd
-            if( aClipPoly.count() )
ebc4bd
-            {
ebc4bd
-                // setup non-empty clipping
ebc4bd
-                Region aRegion = Region::GetRegionFromPolyPolygon( ::PolyPolygon( aClipPoly ) );
ebc4bd
-
ebc4bd
-                if( aClipRegion.IsEmpty() )
ebc4bd
-                    aClipRegion = aRegion;
ebc4bd
-                else
ebc4bd
-                    aClipRegion.Intersect( aRegion );
ebc4bd
-            }
ebc4bd
-            else
ebc4bd
-            {
ebc4bd
-                // clip polygon is empty
ebc4bd
-                aClipRegion.SetEmpty();
ebc4bd
-            }
ebc4bd
-        }
ebc4bd
-
ebc4bd
-        // setup accumulated clip region. Note that setting an
ebc4bd
-        // empty clip region denotes "clip everything" on the
ebc4bd
-        // OutputDevice (which is why we translate that into
ebc4bd
-        // SetClipRegion() here). When both view and render clip
ebc4bd
-        // are empty, aClipRegion remains default-constructed,
ebc4bd
-        // i.e. empty, too.
ebc4bd
-        if( aClipRegion.IsEmpty() )
ebc4bd
-        {
ebc4bd
-            rOutDev.SetClipRegion();
ebc4bd
-        }
ebc4bd
-        else
ebc4bd
-        {
ebc4bd
-            rOutDev.SetClipRegion( aClipRegion );
ebc4bd
-        }
ebc4bd
+        ::canvas::tools::clipOutDev(viewState, renderState, rOutDev);
ebc4bd
 
ebc4bd
         if( eColorType != IGNORE_COLOR )
ebc4bd
         {
ebc4bd
@@ -238,6 +172,31 @@ namespace cairocanvas
ebc4bd
         return nTransparency;
ebc4bd
     }
ebc4bd
 
ebc4bd
+    class DeviceSettingsGuard
ebc4bd
+    {
ebc4bd
+    private:
ebc4bd
+        OutputDevice *mpVirtualDevice;
ebc4bd
+        cairo_t *mpCairo;
ebc4bd
+        bool mbMappingWasEnabled;
ebc4bd
+    public:
ebc4bd
+        DeviceSettingsGuard(OutputDevice *pVirtualDevice, cairo_t *pCairo)
ebc4bd
+            : mpVirtualDevice(pVirtualDevice)
ebc4bd
+            , mpCairo(pCairo)
ebc4bd
+            , mbMappingWasEnabled(mpVirtualDevice->IsMapModeEnabled())
ebc4bd
+        {
ebc4bd
+            cairo_save(mpCairo);
ebc4bd
+            mpVirtualDevice->Push();
ebc4bd
+            mpVirtualDevice->EnableMapMode(false);
ebc4bd
+        }
ebc4bd
+
ebc4bd
+        ~DeviceSettingsGuard()
ebc4bd
+        {
ebc4bd
+            mpVirtualDevice->EnableMapMode(mbMappingWasEnabled);
ebc4bd
+            mpVirtualDevice->Pop();
ebc4bd
+            cairo_restore(mpCairo);
ebc4bd
+        }
ebc4bd
+    };
ebc4bd
+
ebc4bd
     bool setupTextOutput( OutputDevice&                                     rOutDev,
ebc4bd
                           const rendering::XCanvas*                         pOwner,
ebc4bd
                           ::Point&                                          o_rOutPos,
ebc4bd
@@ -247,14 +206,12 @@ namespace cairocanvas
ebc4bd
     {
ebc4bd
         setupOutDevState( rOutDev, pOwner, viewState, renderState, TEXT_COLOR );
ebc4bd
 
ebc4bd
-        ::Font aVCLFont;
ebc4bd
-
ebc4bd
         CanvasFont* pFont = dynamic_cast< CanvasFont* >( xFont.get() );
ebc4bd
 
ebc4bd
         ENSURE_ARG_OR_THROW( pFont,
ebc4bd
                          "CanvasHelper::setupTextOutput(): Font not compatible with this canvas" );
ebc4bd
 
ebc4bd
-        aVCLFont = pFont->getVCLFont();
ebc4bd
+        ::Font aVCLFont = pFont->getVCLFont();
ebc4bd
 
ebc4bd
         Color aColor( COL_BLACK );
ebc4bd
 
ebc4bd
@@ -273,10 +230,20 @@ namespace cairocanvas
ebc4bd
 
ebc4bd
         rOutDev.SetFont( aVCLFont );
ebc4bd
 
ebc4bd
-
ebc4bd
         return true;
ebc4bd
     }
ebc4bd
 
ebc4bd
+    //set the clip of the rOutDev to the cairo surface
ebc4bd
+    void CanvasHelper::clip_cairo_from_dev(::OutputDevice& rOutDev)
ebc4bd
+    {
ebc4bd
+        Region aRegion(rOutDev.GetClipRegion());
ebc4bd
+        if (!aRegion.IsEmpty() && !aRegion.IsNull())
ebc4bd
+        {
ebc4bd
+            doPolyPolygonImplementation(aRegion.GetAsB2DPolyPolygon(), Clip, mpCairo.get(),
ebc4bd
+                                        NULL, mpSurfaceProvider, rendering::FillRule_EVEN_ODD);
ebc4bd
+        }
ebc4bd
+    }
ebc4bd
+
ebc4bd
     uno::Reference< rendering::XCachedPrimitive > CanvasHelper::drawText( const rendering::XCanvas*                         pOwner,
ebc4bd
                                                                           const rendering::StringContext&                   text,
ebc4bd
                                                                           const uno::Reference< rendering::XCanvasFont >&   xFont,
ebc4bd
@@ -297,6 +264,8 @@ namespace cairocanvas
ebc4bd
 
ebc4bd
         if( mpVirtualDevice )
ebc4bd
         {
ebc4bd
+            DeviceSettingsGuard aGuard(mpVirtualDevice.get(), mpCairo.get());
ebc4bd
+
ebc4bd
 #if defined CAIRO_HAS_WIN32_SURFACE
ebc4bd
             // FIXME: Some kind of work-araound...
ebc4bd
             cairo_rectangle (mpSurface->getCairo().get(), 0, 0, 0, 0);
ebc4bd
@@ -330,6 +299,8 @@ namespace cairocanvas
ebc4bd
             // TODO(F2): alpha
ebc4bd
             mpVirtualDevice->SetLayoutMode( nLayoutMode );
ebc4bd
 
ebc4bd
+            clip_cairo_from_dev(*mpVirtualDevice);
ebc4bd
+
ebc4bd
             OSL_TRACE(":cairocanvas::CanvasHelper::drawText(O,t,f,v,r,d): %s", OUStringToOString( text.Text.copy( text.StartPosition, text.Length ),
ebc4bd
                                                                                                          RTL_TEXTENCODING_UTF8 ).getStr());
ebc4bd
 
ebc4bd
@@ -357,6 +328,8 @@ namespace cairocanvas
ebc4bd
 
ebc4bd
             if( mpVirtualDevice )
ebc4bd
             {
ebc4bd
+                DeviceSettingsGuard aGuard(mpVirtualDevice.get(), mpCairo.get());
ebc4bd
+
ebc4bd
 #if defined CAIRO_HAS_WIN32_SURFACE
ebc4bd
                 // FIXME: Some kind of work-araound...
ebc4bd
                 cairo_rectangle( mpSurface->getCairo().get(), 0, 0, 0, 0);
ebc4bd
@@ -371,6 +344,8 @@ namespace cairocanvas
ebc4bd
                 if( !setupTextOutput( *mpVirtualDevice, pOwner, aOutpos, viewState, renderState, xLayoutedText->getFont() ) )
ebc4bd
                     return uno::Reference< rendering::XCachedPrimitive >(NULL); // no output necessary
ebc4bd
 
ebc4bd
+                clip_cairo_from_dev(*mpVirtualDevice);
ebc4bd
+
ebc4bd
                 // TODO(F2): What about the offset scalings?
ebc4bd
                 pTextLayout->draw( mpSurface, *mpVirtualDevice, aOutpos, viewState, renderState );
ebc4bd
             }
ebc4bd
diff --git a/canvas/source/cairo/cairo_quartz_cairo.cxx b/canvas/source/cairo/cairo_quartz_cairo.cxx
ebc4bd
index 07951ee..6b8b9aa 100644
ebc4bd
--- a/canvas/source/cairo/cairo_quartz_cairo.cxx
ebc4bd
+++ b/canvas/source/cairo/cairo_quartz_cairo.cxx
ebc4bd
@@ -269,7 +269,7 @@ namespace cairo
ebc4bd
         aSystemGraphicsData.nSize = sizeof(SystemGraphicsData);
ebc4bd
         aSystemGraphicsData.rCGContext = getCGContext();
ebc4bd
         return boost::shared_ptr<VirtualDevice>(
ebc4bd
-            new VirtualDevice( &aSystemGraphicsData, getDepth() ));
ebc4bd
+            new VirtualDevice( &aSystemGraphicsData, Size(1, 1), getDepth() ));
ebc4bd
     }
ebc4bd
 
ebc4bd
     /**
ebc4bd
diff --git a/canvas/source/cairo/cairo_win32_cairo.cxx b/canvas/source/cairo/cairo_win32_cairo.cxx
ebc4bd
index a70add9..8d53b4f 100644
ebc4bd
--- a/canvas/source/cairo/cairo_win32_cairo.cxx
ebc4bd
+++ b/canvas/source/cairo/cairo_win32_cairo.cxx
ebc4bd
@@ -197,7 +197,7 @@ namespace cairo
ebc4bd
         aSystemGraphicsData.hDC = cairo_win32_surface_get_dc( mpSurface.get() );
ebc4bd
 
ebc4bd
         return boost::shared_ptr<VirtualDevice>(
ebc4bd
-            new VirtualDevice( &aSystemGraphicsData, sal::static_int_cast<USHORT>(getDepth()) ));
ebc4bd
+            new VirtualDevice( &aSystemGraphicsData, Size(1, 1), sal::static_int_cast<USHORT>(getDepth()) ));
ebc4bd
     }
ebc4bd
 
ebc4bd
 
ebc4bd
diff --git a/canvas/source/cairo/cairo_xlib_cairo.cxx b/canvas/source/cairo/cairo_xlib_cairo.cxx
ebc4bd
index 9b49c7e..79ab2a5 100644
ebc4bd
--- a/canvas/source/cairo/cairo_xlib_cairo.cxx
ebc4bd
+++ b/canvas/source/cairo/cairo_xlib_cairo.cxx
ebc4bd
@@ -277,8 +277,13 @@ namespace cairo
ebc4bd
         aSystemGraphicsData.hDrawable = getDrawable();
ebc4bd
         aSystemGraphicsData.pXRenderFormat = getRenderFormat();
ebc4bd
 
ebc4bd
+        int width = cairo_xlib_surface_get_width(mpSurface.get());
ebc4bd
+        int height = cairo_xlib_surface_get_height(mpSurface.get());
ebc4bd
+
ebc4bd
         return boost::shared_ptr<VirtualDevice>(
ebc4bd
-            new VirtualDevice( &aSystemGraphicsData, std::max( getDepth(), 0 ) ));
ebc4bd
+            new VirtualDevice(&aSystemGraphicsData,
ebc4bd
+                              Size(width, height),
ebc4bd
+                              std::max(getDepth(), 0)));
ebc4bd
     }
ebc4bd
 
ebc4bd
     /**
ebc4bd
diff --git a/canvas/source/tools/canvastools.cxx b/canvas/source/tools/canvastools.cxx
ebc4bd
index ae79cc9..6698f58 100644
ebc4bd
--- a/canvas/source/tools/canvastools.cxx
ebc4bd
+++ b/canvas/source/tools/canvastools.cxx
ebc4bd
@@ -1290,6 +1290,81 @@ namespace canvas
ebc4bd
                                    nColorSteps ) );
ebc4bd
         }
ebc4bd
 
ebc4bd
+        void clipOutDev(const rendering::ViewState& viewState,
ebc4bd
+                        const rendering::RenderState& renderState,
ebc4bd
+                        OutputDevice& rOutDev,
ebc4bd
+                        OutputDevice* p2ndOutDev)
ebc4bd
+        {
ebc4bd
+            // accumulate non-empty clips into one region
ebc4bd
+            Region aClipRegion(true);
ebc4bd
+
ebc4bd
+            if( viewState.Clip.is() )
ebc4bd
+            {
ebc4bd
+                ::basegfx::B2DPolyPolygon aClipPoly(
ebc4bd
+                    ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(viewState.Clip) );
ebc4bd
+
ebc4bd
+                if( aClipPoly.count() )
ebc4bd
+                {
ebc4bd
+                    // setup non-empty clipping
ebc4bd
+                    ::basegfx::B2DHomMatrix aMatrix;
ebc4bd
+                    aClipPoly.transform(
ebc4bd
+                        ::basegfx::unotools::homMatrixFromAffineMatrix( aMatrix,
ebc4bd
+                                                                        viewState.AffineTransform ) );
ebc4bd
+
ebc4bd
+                    aClipRegion = Region::GetRegionFromPolyPolygon( PolyPolygon( aClipPoly ) );
ebc4bd
+                }
ebc4bd
+                else
ebc4bd
+                {
ebc4bd
+                    // clip polygon is empty
ebc4bd
+                    aClipRegion.SetEmpty();
ebc4bd
+                }
ebc4bd
+            }
ebc4bd
+
ebc4bd
+            if( renderState.Clip.is() )
ebc4bd
+            {
ebc4bd
+                ::basegfx::B2DPolyPolygon aClipPoly(
ebc4bd
+                    ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(renderState.Clip) );
ebc4bd
+
ebc4bd
+                ::basegfx::B2DHomMatrix aMatrix;
ebc4bd
+                aClipPoly.transform(
ebc4bd
+                    ::canvas::tools::mergeViewAndRenderTransform( aMatrix,
ebc4bd
+                                                                  viewState,
ebc4bd
+                                                                  renderState ) );
ebc4bd
+
ebc4bd
+                if( aClipPoly.count() )
ebc4bd
+                {
ebc4bd
+                    // setup non-empty clipping
ebc4bd
+                    Region aRegion = Region::GetRegionFromPolyPolygon( PolyPolygon( aClipPoly ) );
ebc4bd
+                    aClipRegion.Intersect( aRegion );
ebc4bd
+                }
ebc4bd
+                else
ebc4bd
+                {
ebc4bd
+                    // clip polygon is empty
ebc4bd
+                    aClipRegion.SetEmpty();
ebc4bd
+                }
ebc4bd
+            }
ebc4bd
+
ebc4bd
+            // setup accumulated clip region. Note that setting an
ebc4bd
+            // empty clip region denotes "clip everything" on the
ebc4bd
+            // OutputDevice (which is why we translate that into
ebc4bd
+            // SetClipRegion() here). When both view and render clip
ebc4bd
+            // are empty, aClipRegion remains default-constructed,
ebc4bd
+            // i.e. empty, too.
ebc4bd
+            if( aClipRegion.IsNull() )
ebc4bd
+            {
ebc4bd
+                rOutDev.SetClipRegion();
ebc4bd
+
ebc4bd
+                if( p2ndOutDev )
ebc4bd
+                    p2ndOutDev->SetClipRegion();
ebc4bd
+            }
ebc4bd
+            else
ebc4bd
+            {
ebc4bd
+                rOutDev.SetClipRegion( aClipRegion );
ebc4bd
+
ebc4bd
+                if( p2ndOutDev )
ebc4bd
+                    p2ndOutDev->SetClipRegion( aClipRegion );
ebc4bd
+            }
ebc4bd
+        }
ebc4bd
     } // namespace tools
ebc4bd
 
ebc4bd
 } // namespace canvas
ebc4bd
diff --git a/canvas/source/vcl/canvashelper.cxx b/canvas/source/vcl/canvashelper.cxx
ebc4bd
index 0bd3954..5424e9e 100644
ebc4bd
--- a/canvas/source/vcl/canvashelper.cxx
ebc4bd
+++ b/canvas/source/vcl/canvashelper.cxx
ebc4bd
@@ -1236,78 +1236,7 @@ namespace vclcanvas
ebc4bd
 
ebc4bd
         // TODO(P2): Don't change clipping all the time, maintain current clip
ebc4bd
         // state and change only when update is necessary
ebc4bd
-
ebc4bd
-        // accumulate non-empty clips into one region
ebc4bd
-        // ==========================================
ebc4bd
-
ebc4bd
-        Region aClipRegion(true);
ebc4bd
-
ebc4bd
-        if( viewState.Clip.is() )
ebc4bd
-        {
ebc4bd
-            ::basegfx::B2DPolyPolygon aClipPoly(
ebc4bd
-                ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(viewState.Clip) );
ebc4bd
-
ebc4bd
-            if( aClipPoly.count() )
ebc4bd
-            {
ebc4bd
-                // setup non-empty clipping
ebc4bd
-                ::basegfx::B2DHomMatrix aMatrix;
ebc4bd
-                aClipPoly.transform(
ebc4bd
-                    ::basegfx::unotools::homMatrixFromAffineMatrix( aMatrix,
ebc4bd
-                                                                    viewState.AffineTransform ) );
ebc4bd
-
ebc4bd
-                aClipRegion = Region::GetRegionFromPolyPolygon( ::PolyPolygon( aClipPoly ) );
ebc4bd
-            }
ebc4bd
-            else
ebc4bd
-            {
ebc4bd
-                // clip polygon is empty
ebc4bd
-                aClipRegion.SetEmpty();
ebc4bd
-            }
ebc4bd
-        }
ebc4bd
-
ebc4bd
-        if( renderState.Clip.is() )
ebc4bd
-        {
ebc4bd
-            ::basegfx::B2DPolyPolygon aClipPoly(
ebc4bd
-                ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(renderState.Clip) );
ebc4bd
-
ebc4bd
-            ::basegfx::B2DHomMatrix aMatrix;
ebc4bd
-            aClipPoly.transform(
ebc4bd
-                ::canvas::tools::mergeViewAndRenderTransform( aMatrix,
ebc4bd
-                                                              viewState,
ebc4bd
-                                                              renderState ) );
ebc4bd
-
ebc4bd
-            if( aClipPoly.count() )
ebc4bd
-            {
ebc4bd
-                // setup non-empty clipping
ebc4bd
-                Region aRegion = Region::GetRegionFromPolyPolygon( ::PolyPolygon( aClipPoly ) );
ebc4bd
-                aClipRegion.Intersect( aRegion );
ebc4bd
-            }
ebc4bd
-            else
ebc4bd
-            {
ebc4bd
-                // clip polygon is empty
ebc4bd
-                aClipRegion.SetEmpty();
ebc4bd
-            }
ebc4bd
-        }
ebc4bd
-
ebc4bd
-        // setup accumulated clip region. Note that setting an
ebc4bd
-        // empty clip region denotes "clip everything" on the
ebc4bd
-        // OutputDevice (which is why we translate that into
ebc4bd
-        // SetClipRegion() here). When both view and render clip
ebc4bd
-        // are empty, aClipRegion remains default-constructed,
ebc4bd
-        // i.e. empty, too.
ebc4bd
-        if( aClipRegion.IsNull() )
ebc4bd
-        {
ebc4bd
-            rOutDev.SetClipRegion();
ebc4bd
-
ebc4bd
-            if( p2ndOutDev )
ebc4bd
-                p2ndOutDev->SetClipRegion();
ebc4bd
-        }
ebc4bd
-        else
ebc4bd
-        {
ebc4bd
-            rOutDev.SetClipRegion( aClipRegion );
ebc4bd
-
ebc4bd
-            if( p2ndOutDev )
ebc4bd
-                p2ndOutDev->SetClipRegion( aClipRegion );
ebc4bd
-        }
ebc4bd
+        ::canvas::tools::clipOutDev(viewState, renderState, rOutDev, p2ndOutDev);
ebc4bd
 
ebc4bd
         Color aColor( COL_WHITE );
ebc4bd
 
ebc4bd
@@ -1373,18 +1302,16 @@ namespace vclcanvas
ebc4bd
         ENSURE_OR_THROW( mpOutDev.get(),
ebc4bd
                          "outdev null. Are we disposed?" );
ebc4bd
 
ebc4bd
-        setupOutDevState( viewState, renderState, TEXT_COLOR );
ebc4bd
-
ebc4bd
         OutputDevice& rOutDev( mpOutDev->getOutDev() );
ebc4bd
 
ebc4bd
-        ::Font aVCLFont;
ebc4bd
+        setupOutDevState( viewState, renderState, TEXT_COLOR );
ebc4bd
 
ebc4bd
         CanvasFont* pFont = dynamic_cast< CanvasFont* >( xFont.get() );
ebc4bd
 
ebc4bd
         ENSURE_ARG_OR_THROW( pFont,
ebc4bd
                              "Font not compatible with this canvas" );
ebc4bd
 
ebc4bd
-        aVCLFont = pFont->getVCLFont();
ebc4bd
+        ::Font aVCLFont = pFont->getVCLFont();
ebc4bd
 
ebc4bd
         Color aColor( COL_BLACK );
ebc4bd
 
ebc4bd
diff --git a/include/canvas/canvastools.hxx b/include/canvas/canvastools.hxx
ebc4bd
index de5a76c..3881537 100644
ebc4bd
--- a/include/canvas/canvastools.hxx
ebc4bd
+++ b/include/canvas/canvastools.hxx
ebc4bd
@@ -77,6 +77,7 @@ namespace com { namespace sun { namespace star { namespace awt
ebc4bd
 } } } }
ebc4bd
 
ebc4bd
 class Color;
ebc4bd
+class OutputDevice;
ebc4bd
 
ebc4bd
 namespace canvas
ebc4bd
 {
ebc4bd
@@ -579,6 +580,11 @@ namespace canvas
ebc4bd
             ::std::size_t       mnEntries;
ebc4bd
             bool                mbCaseSensitive;
ebc4bd
         };
ebc4bd
+
ebc4bd
+        CANVASTOOLS_DLLPUBLIC void clipOutDev(const css::rendering::ViewState& viewState,
ebc4bd
+                        const css::rendering::RenderState& renderState,
ebc4bd
+                        OutputDevice& rOutDev,
ebc4bd
+                        OutputDevice* p2ndOutDev=NULL);
ebc4bd
     }
ebc4bd
 }
ebc4bd
 
ebc4bd
diff --git a/include/vcl/virdev.hxx b/include/vcl/virdev.hxx
ebc4bd
index 87205c7..1c0a412 100644
ebc4bd
--- a/include/vcl/virdev.hxx
ebc4bd
+++ b/include/vcl/virdev.hxx
ebc4bd
@@ -110,7 +110,8 @@ public:
ebc4bd
         Any rendering will happen directly on the context and not on any intermediate bitmap.
ebc4bd
         Note: This might not be supported on all platforms !
ebc4bd
     */
ebc4bd
-    explicit            VirtualDevice( const SystemGraphicsData *pData, sal_uInt16 nBitCount );
ebc4bd
+    explicit            VirtualDevice(const SystemGraphicsData *pData, const Size &rSize,
ebc4bd
+                                      sal_uInt16 nBitCount);
ebc4bd
 
ebc4bd
     virtual             ~VirtualDevice();
ebc4bd
 
ebc4bd
diff --git a/vcl/source/gdi/virdev.cxx b/vcl/source/gdi/virdev.cxx
ebc4bd
index 6378785..9dcc286 100644
ebc4bd
--- a/vcl/source/gdi/virdev.cxx
ebc4bd
+++ b/vcl/source/gdi/virdev.cxx
ebc4bd
@@ -236,13 +236,15 @@ VirtualDevice::VirtualDevice( const OutputDevice& rCompDev, sal_uInt16 nBitCount
ebc4bd
     mnAlphaDepth = sal::static_int_cast<sal_Int8>(nAlphaBitCount);
ebc4bd
 }
ebc4bd
 
ebc4bd
-VirtualDevice::VirtualDevice( const SystemGraphicsData *pData, sal_uInt16 nBitCount )
ebc4bd
+VirtualDevice::VirtualDevice(const SystemGraphicsData *pData, const Size &rSize,
ebc4bd
+                             sal_uInt16 nBitCount)
ebc4bd
 :   mpVirDev( NULL ),
ebc4bd
     meRefDevMode( REFDEV_NONE )
ebc4bd
 {
ebc4bd
     SAL_INFO( "vcl.gdi", "VirtualDevice::VirtualDevice( " << nBitCount << " )" );
ebc4bd
 
ebc4bd
-    ImplInitVirDev( Application::GetDefaultDevice(), 1, 1, nBitCount, pData );
ebc4bd
+    ImplInitVirDev(Application::GetDefaultDevice(), rSize.Width(), rSize.Height(),
ebc4bd
+                   nBitCount, pData);
ebc4bd
 }
ebc4bd
 
ebc4bd
 VirtualDevice::~VirtualDevice()
ebc4bd
-- 
ebc4bd
1.9.3
ebc4bd