[Libreoffice-commits] core.git: canvas/source cppcanvas/source drawinglayer/source filter/source include/vcl sd/source svx/source sw/source toolkit/source vcl/aqua vcl/generic vcl/headless vcl/inc vcl/Library_vcl.mk vcl/source vcl/unx vcl/win

Armin Le Grand alg at apache.org
Wed Jun 12 06:31:49 PDT 2013


 canvas/source/vcl/canvashelper.cxx                      |    2 
 cppcanvas/source/mtfrenderer/implrenderer.cxx           |   16 
 drawinglayer/source/primitive2d/metafileprimitive2d.cxx |   20 
 filter/source/graphicfilter/eps/eps.cxx                 |  111 
 include/vcl/bmpacc.hxx                                  |    6 
 include/vcl/outdev.hxx                                  |   12 
 include/vcl/regband.hxx                                 |   23 
 include/vcl/region.hxx                                  |  167 
 sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx      |   23 
 svx/source/sdr/overlay/overlaymanagerbuffered.cxx       |   80 
 svx/source/sdr/properties/itemsettools.cxx              |    6 
 svx/source/svdraw/sdrpaintwindow.cxx                    |   47 
 svx/source/svdraw/svdfmtf.cxx                           |    4 
 svx/source/svdraw/svdpntv.cxx                           |   45 
 sw/source/core/view/viewsh.cxx                          |   20 
 toolkit/source/awt/vclxregion.cxx                       |   27 
 vcl/Library_vcl.mk                                      |    1 
 vcl/aqua/source/gdi/salgdicommon.cxx                    |   28 
 vcl/generic/fontmanager/fontsubst.cxx                   |    1 
 vcl/generic/print/genpspgraphics.cxx                    |   42 
 vcl/headless/svpgdi.cxx                                 |   63 
 vcl/inc/region.h                                        |  128 
 vcl/inc/regionband.hxx                                  |   83 
 vcl/source/gdi/bitmap.cxx                               |   72 
 vcl/source/gdi/bmpacc3.cxx                              |  129 
 vcl/source/gdi/gdimtf.cxx                               |   12 
 vcl/source/gdi/outdev.cxx                               |   55 
 vcl/source/gdi/outdev2.cxx                              |   75 
 vcl/source/gdi/outmap.cxx                               |  304 +
 vcl/source/gdi/pdfwriter_impl2.cxx                      |    4 
 vcl/source/gdi/regband.cxx                              |  106 
 vcl/source/gdi/region.cxx                               | 3571 +++++-----------
 vcl/source/gdi/regionband.cxx                           | 1377 ++++++
 vcl/source/gdi/salgdilayout.cxx                         |   41 
 vcl/source/window/window.cxx                            |  128 
 vcl/unx/generic/gdi/salgdi.cxx                          |   49 
 vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx                |   29 
 vcl/unx/gtk3/gdi/gtk3salnativewidgets-gtk.cxx           |    3 
 vcl/win/source/gdi/salgdi.cxx                           |  124 
 39 files changed, 3929 insertions(+), 3105 deletions(-)

New commits:
commit e717d1dcce7f8906311c5ccdbb2326b61a702630
Author: Armin Le Grand <alg at apache.org>
Date:   Tue Oct 23 12:46:28 2012 +0000

    Resolves: #i121237# Rework/Cleanup of Region code...
    
    due to missing complete support for B2DPolygon class
    
    (cherry picked from commit cab10eeb7878edf224a004fd7640bd4adf8d3c51)
    
    Conflicts:
    	cppcanvas/source/mtfrenderer/implrenderer.cxx
    	svx/source/sdr/overlay/overlaymanagerbuffered.cxx
    	svx/source/svdraw/svdpntv.cxx
    	vcl/aqua/source/gdi/salgdi.cxx
    	vcl/inc/region.h
    	vcl/inc/unx/gtk/gtkgdi.hxx
    	vcl/inc/vcl/regband.hxx
    	vcl/inc/vcl/region.hxx
    	vcl/os2/source/gdi/salgdi.cxx
    	vcl/source/gdi/bmpacc3.cxx
    	vcl/source/gdi/outdev2.cxx
    	vcl/source/gdi/outmap.cxx
    	vcl/source/gdi/regband.cxx
    	vcl/source/gdi/region.cxx
    	vcl/source/window/window.cxx
    	vcl/unx/generic/gdi/pspgraphics.cxx
    	vcl/unx/headless/svpgdi.cxx
    	vcl/unx/headless/svppspgraphics.cxx
    	vcl/win/source/gdi/salgdi.cxx
    
    Change-Id: Iee9a66ff431c3cecb7603e445147b67715de0f7d
    
    Remove unused variable to prevent compiler warning
    
    (cherry picked from commit 0ac65ccf079e3e22ac23cbe7ae546504c863c31f)
    
    Change-Id: Icbcaa9d576a7e560d96debc7360bdbe9090b3fd3
    
    Wrong comparison with bool corrected
    
    (cherry picked from commit 612cefdcf6176b6bb847ce899d89af40ef313a90)
    
    Change-Id: I1cf5de6734b588f78d8e870ba7b7860634b461ce

diff --git a/canvas/source/vcl/canvashelper.cxx b/canvas/source/vcl/canvashelper.cxx
index 0f3718f..10a6f53 100644
--- a/canvas/source/vcl/canvashelper.cxx
+++ b/canvas/source/vcl/canvashelper.cxx
@@ -1231,7 +1231,7 @@ namespace vclcanvas
         // accumulate non-empty clips into one region
         // ==========================================
 
-        Region aClipRegion( REGION_NULL );
+        Region aClipRegion(true);
 
         if( viewState.Clip.is() )
         {
diff --git a/cppcanvas/source/mtfrenderer/implrenderer.cxx b/cppcanvas/source/mtfrenderer/implrenderer.cxx
index 2fcff5a..a852391 100644
--- a/cppcanvas/source/mtfrenderer/implrenderer.cxx
+++ b/cppcanvas/source/mtfrenderer/implrenderer.cxx
@@ -1368,7 +1368,7 @@ namespace cppcanvas
                         }
                         else
                         {
-                            if( !pClipAction->GetRegion().HasPolyPolygon() )
+                            if( !pClipAction->GetRegion().HasPolyPolygonOrB2DPolyPolygon() )
                             {
                                 VERBOSE_TRACE( "ImplRenderer::createActions(): non-polygonal clip "
                                                "region encountered, falling back to bounding box!" );
@@ -1390,9 +1390,11 @@ namespace cppcanvas
                                 // with old one, just set it)
 
                                 // #121806# explicitly kept integer
+                                basegfx::B2DPolyPolygon aPolyPolygon(pClipAction->GetRegion().GetAsB2DPolyPolygon());
+
+                                aPolyPolygon.transform(rVDev.GetViewTransformation());
                                 updateClipping(
-                                    rVDev.LogicToPixel(
-                                        pClipAction->GetRegion().GetPolyPolygon() ).getB2DPolyPolygon(),
+                                    aPolyPolygon,
                                     rFactoryParms,
                                     false );
                             }
@@ -1422,7 +1424,7 @@ namespace cppcanvas
                     {
                         MetaISectRegionClipRegionAction* pClipAction = static_cast<MetaISectRegionClipRegionAction*>(pCurrAct);
 
-                        if( !pClipAction->GetRegion().HasPolyPolygon() )
+                        if( !pClipAction->GetRegion().HasPolyPolygonOrB2DPolyPolygon() )
                         {
                             VERBOSE_TRACE( "ImplRenderer::createActions(): non-polygonal clip "
                                            "region encountered, falling back to bounding box!" );
@@ -1442,9 +1444,11 @@ namespace cppcanvas
                             // intersect current clip with given clip polygon
 
                             // #121806# explicitly kept integer
+                            basegfx::B2DPolyPolygon aPolyPolygon(pClipAction->GetRegion().GetAsB2DPolyPolygon());
+
+                            aPolyPolygon.transform(rVDev.GetViewTransformation());
                             updateClipping(
-                                rVDev.LogicToPixel(
-                                    pClipAction->GetRegion().GetPolyPolygon() ).getB2DPolyPolygon(),
+                                aPolyPolygon,
                                 rFactoryParms,
                                 true );
                         }
diff --git a/drawinglayer/source/primitive2d/metafileprimitive2d.cxx b/drawinglayer/source/primitive2d/metafileprimitive2d.cxx
index 4a0719e..d08a8ed 100644
--- a/drawinglayer/source/primitive2d/metafileprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/metafileprimitive2d.cxx
@@ -380,26 +380,8 @@ namespace
         if(!rRegion.IsEmpty())
         {
             Region aRegion(rRegion);
-            aRetval = aRegion.GetB2DPolyPolygon();
 
-            if(!aRetval.count())
-            {
-                RegionHandle aRegionHandle(aRegion.BeginEnumRects());
-                Rectangle aRegionRectangle;
-
-                while(aRegion.GetEnumRects(aRegionHandle, aRegionRectangle))
-                {
-                    if(!aRegionRectangle.IsEmpty())
-                    {
-                        const basegfx::B2DRange aRegionRange(
-                            aRegionRectangle.Left(), aRegionRectangle.Top(),
-                            aRegionRectangle.Right(), aRegionRectangle.Bottom());
-                        aRetval.append(basegfx::tools::createPolygonFromRect(aRegionRange));
-                    }
-                }
-
-                aRegion.EndEnumRects(aRegionHandle);
-            }
+            aRetval = aRegion.GetAsB2DPolyPolygon();
         }
 
         return aRetval;
diff --git a/filter/source/graphicfilter/eps/eps.cxx b/filter/source/graphicfilter/eps/eps.cxx
index 454d683..12a18e6 100644
--- a/filter/source/graphicfilter/eps/eps.cxx
+++ b/filter/source/graphicfilter/eps/eps.cxx
@@ -1649,15 +1649,16 @@ void PSWriter::ImplSetClipRegion( Region& rClipRegion )
 {
     if ( !rClipRegion.IsEmpty() )
     {
-        Rectangle       aRect;
-        RegionHandle    hRegionHandle = rClipRegion.BeginEnumRects();
+        RectangleVector aRectangles;
+        rClipRegion.GetRegionRectangles(aRectangles);
 
-        while ( rClipRegion.GetNextEnumRect( hRegionHandle, aRect ) )
+        for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
         {
-            double nX1 = aRect.Left();
-            double nY1 = aRect.Top();
-            double nX2 = aRect.Right();
-            double nY2 = aRect.Bottom();
+            double nX1(aRectIter->Left());
+            double nY1(aRectIter->Top());
+            double nX2(aRectIter->Right());
+            double nY2(aRectIter->Bottom());
+
             ImplWriteDouble( nX1 );
             ImplWriteDouble( nY1 );
             ImplWriteByte( 'm' );
@@ -1673,8 +1674,34 @@ void PSWriter::ImplSetClipRegion( Region& rClipRegion )
             ImplWriteDouble( nX1 );
             ImplWriteDouble( nY1 );
             ImplWriteByte( 'l', PS_SPACE | PS_WRAP );
-        };
-        rClipRegion.EndEnumRects( hRegionHandle );
+        }
+
+        //Rectangle     aRect;
+        //RegionHandle  hRegionHandle = rClipRegion.BeginEnumRects();
+        //
+        //while ( rClipRegion.GetEnumRects( hRegionHandle, aRect ) )
+        //{
+        //  double nX1 = aRect.Left();
+        //  double nY1 = aRect.Top();
+        //  double nX2 = aRect.Right();
+        //  double nY2 = aRect.Bottom();
+        //  ImplWriteDouble( nX1 );
+        //  ImplWriteDouble( nY1 );
+        //  ImplWriteByte( 'm' );
+        //  ImplWriteDouble( nX2 );
+        //  ImplWriteDouble( nY1 );
+        //  ImplWriteByte( 'l' );
+        //  ImplWriteDouble( nX2 );
+        //  ImplWriteDouble( nY2 );
+        //  ImplWriteByte( 'l' );
+        //  ImplWriteDouble( nX1 );
+        //  ImplWriteDouble( nY2 );
+        //  ImplWriteByte( 'l' );
+        //  ImplWriteDouble( nX1 );
+        //  ImplWriteDouble( nY1 );
+        //  ImplWriteByte( 'l', PS_SPACE | PS_WRAP );
+        //};
+        //rClipRegion.EndEnumRects( hRegionHandle );
         ImplWriteLine( "eoclip newpath" );
     }
 }
@@ -1723,12 +1750,18 @@ void PSWriter::ImplBmp( Bitmap* pBitmap, Bitmap* pMaskBitmap, const Point & rPoi
                 aRect = Rectangle( Point( 0, nHeightOrg - nHeightLeft ), Size( (long)nWidth, (long)nHeight ) );
                 aRegion = Region( pMaskBitmap->CreateRegion( COL_BLACK, aRect ) );
 
-                if ( ( mnLevel == 1 ) && ( aRegion.GetRectCount() * 5 > 1000 ) )
+                if( mnLevel == 1 )
                 {
-                    nHeight >>= 1;
-                    if ( nHeight < 2 )
-                        return;
-                    continue;
+                    RectangleVector aRectangleVector;
+                    aRegion.GetRegionRectangles(aRectangleVector);
+
+                    if ( aRectangleVector.size() * 5 > 1000 )
+                    {
+                        nHeight >>= 1;
+                        if ( nHeight < 2 )
+                            return;
+                        continue;
+                    }
                 }
                 break;
             }
@@ -1743,26 +1776,50 @@ void PSWriter::ImplBmp( Bitmap* pBitmap, Bitmap* pMaskBitmap, const Point & rPoi
             ImplWriteLine( "gs\npum" );
             ImplTranslate( aSourcePos.X(), aSourcePos.Y() );
             ImplScale( nXWidth / nWidth,  nYHeight / nHeight );
-            RegionHandle    hRegionHandle = aRegion.BeginEnumRects();
 
-            while ( aRegion.GetNextEnumRect( hRegionHandle, aRect ) )
+            RectangleVector aRectangles;
+            aRegion.GetRegionRectangles(aRectangles);
+            const long nMoveVertical(nHeightLeft - nHeightOrg);
+
+            for(RectangleVector::iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
             {
-                aRect.Move( 0, - ( nHeightOrg - nHeightLeft ) );
-                ImplWriteLong( aRect.Left() );
-                ImplWriteLong( aRect.Top() );
+                aRectIter->Move(0, nMoveVertical);
+
+                ImplWriteLong( aRectIter->Left() );
+                ImplWriteLong( aRectIter->Top() );
                 ImplWriteByte( 'm' );
-                ImplWriteLong( aRect.Right() + 1 );
-                ImplWriteLong( aRect.Top() );
+                ImplWriteLong( aRectIter->Right() + 1 );
+                ImplWriteLong( aRectIter->Top() );
                 ImplWriteByte( 'l' );
-                ImplWriteLong( aRect.Right() + 1 );
-                ImplWriteLong( aRect.Bottom() + 1 );
+                ImplWriteLong( aRectIter->Right() + 1 );
+                ImplWriteLong( aRectIter->Bottom() + 1 );
                 ImplWriteByte( 'l' );
-                ImplWriteLong( aRect.Left() );
-                ImplWriteLong( aRect.Bottom() + 1 );
+                ImplWriteLong( aRectIter->Left() );
+                ImplWriteLong( aRectIter->Bottom() + 1 );
                 ImplWriteByte( 'l' );
                 ImplWriteByte( 'p', PS_SPACE | PS_WRAP );
-            };
-            aRegion.EndEnumRects( hRegionHandle );
+            }
+
+            //RegionHandle  hRegionHandle = aRegion.BeginEnumRects();
+            //
+            //while ( aRegion.GetEnumRects( hRegionHandle, aRect ) )
+            //{
+            //  aRect.Move( 0, - ( nHeightOrg - nHeightLeft ) );
+            //  ImplWriteLong( aRect.Left() );
+            //  ImplWriteLong( aRect.Top() );
+            //  ImplWriteByte( 'm' );
+            //  ImplWriteLong( aRect.Right() + 1 );
+            //  ImplWriteLong( aRect.Top() );
+            //  ImplWriteByte( 'l' );
+            //  ImplWriteLong( aRect.Right() + 1 );
+            //  ImplWriteLong( aRect.Bottom() + 1 );
+            //  ImplWriteByte( 'l' );
+            //  ImplWriteLong( aRect.Left() );
+            //  ImplWriteLong( aRect.Bottom() + 1 );
+            //  ImplWriteByte( 'l' );
+            //  ImplWriteByte( 'p', PS_SPACE | PS_WRAP );
+            //};
+            //aRegion.EndEnumRects( hRegionHandle );
             ImplWriteLine( "eoclip newpath" );
             ImplWriteLine( "pom" );
         }
diff --git a/include/vcl/bmpacc.hxx b/include/vcl/bmpacc.hxx
index 306f28a..f3f5301 100644
--- a/include/vcl/bmpacc.hxx
+++ b/include/vcl/bmpacc.hxx
@@ -195,6 +195,12 @@ public:
     void                        FillRect( const Rectangle& rRect );
     void                        DrawRect( const Rectangle& rRect );
 
+    void                        FillPolygon( const Polygon& rPoly );
+    void                        DrawPolygon( const Polygon& rPoly );
+
+    void                        FillPolyPolygon( const PolyPolygon& rPoly );
+    void                        DrawPolyPolygon( const PolyPolygon& rPolyPoly );
+
 private:
 
     BitmapColor*                mpLineColor;
diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx
index b3a2f9e..b76598f 100644
--- a/include/vcl/outdev.hxx
+++ b/include/vcl/outdev.hxx
@@ -965,6 +965,7 @@ public:
     Rectangle           LogicToPixel( const Rectangle& rLogicRect ) const;
     Polygon             LogicToPixel( const Polygon& rLogicPoly ) const;
     PolyPolygon         LogicToPixel( const PolyPolygon& rLogicPolyPoly ) const;
+    basegfx::B2DPolyPolygon LogicToPixel( const basegfx::B2DPolyPolygon& rLogicPolyPoly ) const;
     Region              LogicToPixel( const Region& rLogicRegion )const;
     Point               LogicToPixel( const Point& rLogicPt,
                                       const MapMode& rMapMode ) const;
@@ -974,12 +975,19 @@ public:
                                       const MapMode& rMapMode ) const;
     Polygon             LogicToPixel( const Polygon& rLogicPoly,
                                       const MapMode& rMapMode ) const;
+    basegfx::B2DPolygon LogicToPixel( const basegfx::B2DPolygon& rLogicPoly,
+                                          const MapMode& rMapMode ) const;
+    PolyPolygon         LogicToPixel( const PolyPolygon& rLogicPolyPoly,
+                                      const MapMode& rMapMode ) const;
     basegfx::B2DPolyPolygon LogicToPixel( const basegfx::B2DPolyPolygon& rLogicPolyPoly,
                                           const MapMode& rMapMode ) const;
+    Region              LogicToPixel( const Region& rLogicRegion,
+                                      const MapMode& rMapMode ) const;
     Point               PixelToLogic( const Point& rDevicePt ) const;
     Size                PixelToLogic( const Size& rDeviceSize ) const;
     Rectangle           PixelToLogic( const Rectangle& rDeviceRect ) const;
     Polygon             PixelToLogic( const Polygon& rDevicePoly ) const;
+    basegfx::B2DPolygon LogicToPixel( const basegfx::B2DPolygon& rLogicPoly ) const;
     PolyPolygon         PixelToLogic( const PolyPolygon& rDevicePolyPoly ) const;
     basegfx::B2DPolyPolygon PixelToLogic( const basegfx::B2DPolyPolygon& rDevicePolyPoly ) const;
     Region              PixelToLogic( const Region& rDeviceRegion ) const;
@@ -993,8 +1001,12 @@ public:
                                       const MapMode& rMapMode ) const;
     basegfx::B2DPolygon PixelToLogic( const basegfx::B2DPolygon& rDevicePoly,
                                       const MapMode& rMapMode ) const;
+    PolyPolygon         PixelToLogic( const PolyPolygon& rDevicePolyPoly,
+                                      const MapMode& rMapMode ) const;
     basegfx::B2DPolyPolygon PixelToLogic( const basegfx::B2DPolyPolygon& rDevicePolyPoly,
                                           const MapMode& rMapMode ) const;
+    Region              PixelToLogic( const Region& rDeviceRegion,
+                                      const MapMode& rMapMode ) const;
     Point               LogicToLogic( const Point&      rPtSource,
                                       const MapMode*    pMapModeSource,
                                       const MapMode*    pMapModeDest ) const;
diff --git a/include/vcl/regband.hxx b/include/vcl/regband.hxx
index 0b60a80..24fe758 100644
--- a/include/vcl/regband.hxx
+++ b/include/vcl/regband.hxx
@@ -49,7 +49,7 @@ struct ImplRegionBandSep
     ImplRegionBandSep*          mpNextSep;
     long                        mnXLeft;
     long                        mnXRight;
-    sal_Bool                        mbRemoved;
+    bool                        mbRemoved;
 };
 
 enum LineType { LINE_ASCENDING, LINE_DESCENDING, LINE_HORIZONTAL };
@@ -60,7 +60,7 @@ struct ImplRegionBandPoint
     ImplRegionBandPoint*        mpNextBandPoint;
     long                        mnX;
     long                        mnLineId;
-    sal_Bool                        mbEndPoint;
+    bool                        mbEndPoint;
     LineType                    meLineType;
 };
 
@@ -77,7 +77,9 @@ public:
     ImplRegionBandPoint*        mpFirstBandPoint;   // root of the list with lines
     long                        mnYTop;             // actual boundary of the band
     long                        mnYBottom;
-    sal_Bool                        mbTouched;
+
+    // bitfield
+    bool                        mbTouched : 1;
 
                                 // create y-band with boundaries
                                 ImplRegionBand( long nYTop, long nYBottom );
@@ -102,14 +104,14 @@ public:
     long                        GetXRightBoundary() const;
 
                                 // combine overlapping bands
-    sal_Bool                        OptimizeBand();
+    bool                        OptimizeBand();
 
                                 // generate separations from lines and process
                                 // union with existing separations
     void                        ProcessPoints();
                                 // insert point in the list for later processing
-    sal_Bool                        InsertPoint( long nX, long nLineID,
-                                             sal_Bool bEndPoint, LineType eLineType );
+    bool                        InsertPoint( long nX, long nLineID,
+                                             bool bEndPoint, LineType eLineType );
 
     void                        Union( long nXLeft, long nXRight );
     void                        Intersect( long nXLeft, long nXRight );
@@ -119,11 +121,14 @@ public:
     void                        MoveX( long nHorzMove );
     void                        ScaleX( double fHorzScale );
 
-    sal_Bool                        IsInside( long nX );
+    bool                        IsInside( long nX );
+    bool                        IsInside( long nLeft, long nRight );
+    bool                        IsOver( long nLeft, long nRight );
+
 
-    sal_Bool                        IsEmpty() const { return ((!mpFirstSep) && (!mpFirstBandPoint)); }
+    bool                        IsEmpty() const { return ((!mpFirstSep) && (!mpFirstBandPoint)); }
 
-    sal_Bool                        operator==( const ImplRegionBand& rRegionBand ) const;
+    bool                        operator==( const ImplRegionBand& rRegionBand ) const;
 
     /** Split the called band at the given vertical coordinate.  After the
         split the called band will cover the upper part not including nY.
diff --git a/include/vcl/region.hxx b/include/vcl/region.hxx
index 88c55ea..f2298e7 100644
--- a/include/vcl/region.hxx
+++ b/include/vcl/region.hxx
@@ -25,115 +25,96 @@
 #include <vcl/dllapi.h>
 
 #include <basegfx/polygon/b2dpolypolygon.hxx>
+#include <boost/shared_ptr.hpp>
 
-class ImplRegion;
 class ImplRegionBand;
+class RegionBand;
 class Polygon;
 class PolyPolygon;
-struct ImplRegionInfo;
 
-// --------------
-// - RegionType -
-// --------------
+//////////////////////////////////////////////////////////////////////////////
 
-enum RegionType { REGION_NULL, REGION_EMPTY, REGION_RECTANGLE, REGION_COMPLEX };
-enum RegionOverlapType { REGION_INSIDE, REGION_OVER, REGION_OUTSIDE };
+typedef boost::shared_ptr< RegionBand > RegionBandPtr;
+typedef boost::shared_ptr< PolyPolygon > PolyPolygonPtr;
+typedef boost::shared_ptr< basegfx::B2DPolyPolygon > B2DPolyPolygonPtr;
+typedef std::vector< Rectangle > RectangleVector;
 
-typedef sal_IntPtr RegionHandle;
-
-// ----------
-// - Region -
-// ----------
+//////////////////////////////////////////////////////////////////////////////
 
 class VCL_DLLPUBLIC Region
 {
+private:
     friend class OutputDevice;
     friend class Window;
     friend class Bitmap;
 
-private:
-    ImplRegion*         mpImplRegion;
-
-    SAL_DLLPRIVATE void             ImplCopyData();
-    SAL_DLLPRIVATE void             ImplCreateRectRegion( const Rectangle& rRect );
-    SAL_DLLPRIVATE void             ImplCreatePolyPolyRegion( const PolyPolygon& rPolyPoly );
-    SAL_DLLPRIVATE void             ImplCreatePolyPolyRegion( const basegfx::B2DPolyPolygon& rPolyPoly );
-    SAL_DLLPRIVATE void             ImplPolyPolyRegionToBandRegionFunc();
-    SAL_DLLPRIVATE inline void      ImplPolyPolyRegionToBandRegion();
-    SAL_DLLPRIVATE const ImplRegion*    ImplGetImplRegion() const { return mpImplRegion; }
-    SAL_DLLPRIVATE ImplRegion*      ImplGetImplRegion() { return mpImplRegion; }
-    SAL_DLLPRIVATE void             ImplBeginAddRect( );
-    SAL_DLLPRIVATE sal_Bool             ImplAddRect( const Rectangle& rRect );
-    SAL_DLLPRIVATE void             ImplEndAddRect( );
-    SAL_DLLPRIVATE void             ImplIntersectWithPolyPolygon( const Region& );
-    SAL_DLLPRIVATE void             ImplExcludePolyPolygon( const Region& );
-    SAL_DLLPRIVATE void             ImplUnionPolyPolygon( const Region& );
-    SAL_DLLPRIVATE void             ImplXOrPolyPolygon( const Region& );
-
-public: // public within vcl
-    VCL_PLUGIN_PUBLIC bool              ImplGetFirstRect( ImplRegionInfo& rImplRegionInfo,
-                                          long& nX, long& nY, long& nWidth, long& nHeight ) const;
-    VCL_PLUGIN_PUBLIC bool              ImplGetNextRect( ImplRegionInfo& rImplRegionInfo,
-                                         long& nX, long& nY, long& nWidth, long& nHeight ) const;
-#ifdef DBG_UTIL
-    friend const char*  ImplDbgTestRegion( const void* pObj );
-#endif
+    // possible contents
+    B2DPolyPolygonPtr           mpB2DPolyPolygon;
+    PolyPolygonPtr              mpPolyPolygon;
+    RegionBandPtr               mpRegionBand;
+
+    /// bitfield
+    bool                        mbIsNull : 1;
+
+    // helpers
+    SAL_DLLPRIVATE void ImplCreatePolyPolyRegion( const PolyPolygon& rPolyPoly );
+    SAL_DLLPRIVATE void ImplCreatePolyPolyRegion( const basegfx::B2DPolyPolygon& rPolyPoly );
+
+    SAL_DLLPRIVATE PolyPolygon ImplCreatePolyPolygonFromRegionBand() const;
+    SAL_DLLPRIVATE basegfx::B2DPolyPolygon ImplCreateB2DPolyPolygonFromRegionBand() const;
 
 public:
-    explicit        Region();
-    explicit        Region( RegionType eType );
-    explicit        Region( const Rectangle& rRect );
-    explicit        Region( const Polygon& rPolygon );
-    explicit        Region( const PolyPolygon& rPolyPoly );
-    explicit        Region( const basegfx::B2DPolyPolygon& );
-                    Region( const Region& rRegion );
-                    ~Region();
-
-    void            Move( long nHorzMove, long nVertMove );
-    void            Scale( double fScaleX, double fScaleY );
-    void            Union( const Rectangle& rRegion );
-    void            Intersect( const Rectangle& rRegion );
-    void            Exclude( const Rectangle& rRegion );
-    void            XOr( const Rectangle& rRegion );
-    void            Union( const Region& rRegion );
-    void            Intersect( const Region& rRegion );
-    void            Exclude( const Region& rRegion );
-    void            XOr( const Region& rRegion );
-
-    RegionType      GetType() const;
-    sal_Bool            IsEmpty() const { return GetType() == REGION_EMPTY; };
-    sal_Bool            IsNull() const { return GetType() == REGION_NULL; };
-
-    void            SetEmpty();
-    void            SetNull();
-
-    Rectangle       GetBoundRect() const;
-
-    sal_Bool            HasPolyPolygon() const;
-    PolyPolygon     GetPolyPolygon() const;
-    // returns an empty polypolygon in case HasPolyPolygon is sal_False
-    const basegfx::B2DPolyPolygon GetB2DPolyPolygon() const;
-    // returns a PolyPolygon either copied from the set PolyPolygon region
-    // or created from the constituent rectangles
-    basegfx::B2DPolyPolygon ConvertToB2DPolyPolygon();
-
-    sal_uLong           GetRectCount() const;
-    RegionHandle    BeginEnumRects();
-    sal_Bool            GetEnumRects( RegionHandle hRegionHandle, Rectangle& rRect );
-    sal_Bool            GetNextEnumRect( RegionHandle hRegionHandle, Rectangle& rRect )
-                        { return GetEnumRects( hRegionHandle, rRect ); }
-    void            EndEnumRects( RegionHandle hRegionHandle );
-
-    sal_Bool            IsInside( const Point& rPoint ) const;
-    sal_Bool            IsInside( const Rectangle& rRect ) const;
-    sal_Bool            IsOver( const Rectangle& rRect ) const;
-
-    Region&         operator=( const Region& rRegion );
-    Region&         operator=( const Rectangle& rRect );
-
-    sal_Bool            operator==( const Region& rRegion ) const;
-    sal_Bool            operator!=( const Region& rRegion ) const
-                        { return !(Region::operator==( rRegion )); }
+
+    explicit Region(bool bIsNull = false); // default creates empty region, with true a null region is created
+    explicit Region(const Rectangle& rRect);
+    explicit Region(const Polygon& rPolygon);
+    explicit Region(const PolyPolygon& rPolyPoly);
+    explicit Region(const basegfx::B2DPolyPolygon&);
+    Region(const Region& rRegion);
+    ~Region();
+
+    // direct access to contents
+    const basegfx::B2DPolyPolygon* getB2DPolyPolygon() const { return mpB2DPolyPolygon.get(); }
+    const PolyPolygon* getPolyPolygon() const { return mpPolyPolygon.get(); }
+    const RegionBand* getRegionBand() const { return mpRegionBand.get(); }
+
+    // access with converters, the asked data will be created from the most
+    // valuable data, buffered and returned
+    const PolyPolygon GetAsPolyPolygon() const;
+    const basegfx::B2DPolyPolygon GetAsB2DPolyPolygon() const;
+    const RegionBand* GetAsRegionBand() const;
+
+    // manipulators
+    void Move( long nHorzMove, long nVertMove );
+    void Scale( double fScaleX, double fScaleY );
+    bool Union( const Rectangle& rRegion );
+    bool Intersect( const Rectangle& rRegion );
+    bool Exclude( const Rectangle& rRegion );
+    bool XOr( const Rectangle& rRegion );
+    bool Union( const Region& rRegion );
+    bool Intersect( const Region& rRegion );
+    bool Exclude( const Region& rRegion );
+    bool XOr( const Region& rRegion );
+
+    bool IsEmpty() const;
+    bool IsNull() const;
+
+    void SetEmpty();
+    void SetNull();
+
+    Rectangle GetBoundRect() const;
+    bool HasPolyPolygonOrB2DPolyPolygon() const { return (getB2DPolyPolygon() || getPolyPolygon()); }
+    void GetRegionRectangles(RectangleVector& rTarget) const;
+
+    bool IsInside( const Point& rPoint ) const;
+    bool IsInside( const Rectangle& rRect ) const;
+    bool IsOver( const Rectangle& rRect ) const;
+
+    Region& operator=( const Region& rRegion );
+    Region& operator=( const Rectangle& rRect );
+
+    bool operator==( const Region& rRegion ) const;
+    bool operator!=( const Region& rRegion ) const { return !(Region::operator==( rRegion )); }
 
     friend VCL_DLLPUBLIC SvStream& operator>>( SvStream& rIStm, Region& rRegion );
     friend VCL_DLLPUBLIC SvStream& operator<<( SvStream& rOStm, const Region& rRegion );
diff --git a/sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx b/sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx
index 6015259..3575c24 100644
--- a/sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx
+++ b/sd/source/ui/slidesorter/view/SlsLayeredDevice.cxx
@@ -79,19 +79,26 @@ void DeviceCopy (
 void ForAllRectangles (const Region& rRegion, ::boost::function<void(const Rectangle&)> aFunction)
 {
     OSL_ASSERT(aFunction);
+    RectangleVector aRectangles;
+    rRegion.GetRegionRectangles(aRectangles);
 
-    if (rRegion.GetRectCount() <= 1)
+    if(0 == aRectangles.size())
     {
-        aFunction(rRegion.GetBoundRect());
+        aFunction(Rectangle());
     }
     else
     {
-        Region aMutableRegionCopy (rRegion);
-        RegionHandle aHandle(aMutableRegionCopy.BeginEnumRects());
-        Rectangle aBox;
-        while (aMutableRegionCopy.GetNextEnumRect(aHandle, aBox))
-            aFunction(aBox);
-        aMutableRegionCopy.EndEnumRects(aHandle);
+        for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
+        {
+            aFunction(*aRectIter);
+        }
+
+        //Region aMutableRegionCopy (rRegion);
+        //RegionHandle aHandle(aMutableRegionCopy.BeginEnumRects());
+        //Rectangle aBox;
+        //while (aMutableRegionCopy.GetEnumRects(aHandle, aBox))
+        //    aFunction(aBox);
+        //aMutableRegionCopy.EndEnumRects(aHandle);
     }
 }
 
diff --git a/svx/source/sdr/overlay/overlaymanagerbuffered.cxx b/svx/source/sdr/overlay/overlaymanagerbuffered.cxx
index 81b53b2..47d76f8 100644
--- a/svx/source/sdr/overlay/overlaymanagerbuffered.cxx
+++ b/svx/source/sdr/overlay/overlaymanagerbuffered.cxx
@@ -109,33 +109,33 @@ namespace sdr
 
         void OverlayManagerBuffered::ImpRestoreBackground(const Region& rRegionPixel) const
         {
-            // local region
-            Region aRegionPixel(rRegionPixel);
-            RegionHandle aRegionHandle(aRegionPixel.BeginEnumRects());
-            Rectangle aRegionRectanglePixel;
-
             // MapModes off
             const bool bMapModeWasEnabledDest(getOutputDevice().IsMapModeEnabled());
             const bool bMapModeWasEnabledSource(maBufferDevice.IsMapModeEnabled());
             getOutputDevice().EnableMapMode(false);
             ((OverlayManagerBuffered*)this)->maBufferDevice.EnableMapMode(false);
 
-            while(aRegionPixel.GetEnumRects(aRegionHandle, aRegionRectanglePixel))
+            // local region
+            RectangleVector aRectangles;
+            rRegionPixel.GetRegionRectangles(aRectangles);
+
+            for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
             {
 #ifdef DBG_UTIL
                 // #i72754# possible graphical region test only with non-pro
                 static bool bDoPaintForVisualControl(false);
+
                 if(bDoPaintForVisualControl)
                 {
                     getOutputDevice().SetLineColor(COL_LIGHTGREEN);
                     getOutputDevice().SetFillColor();
-                    getOutputDevice().DrawRect(aRegionRectanglePixel);
+                    getOutputDevice().DrawRect(*aRectIter);
                 }
 #endif
 
                 // restore the area
-                const Point aTopLeft(aRegionRectanglePixel.TopLeft());
-                const Size aSize(aRegionRectanglePixel.GetSize());
+                const Point aTopLeft(aRectIter->TopLeft());
+                const Size aSize(aRectIter->GetSize());
 
                 getOutputDevice().DrawOutDev(
                     aTopLeft, aSize, // destination
@@ -143,7 +143,33 @@ namespace sdr
                     maBufferDevice);
             }
 
-            aRegionPixel.EndEnumRects(aRegionHandle);
+            //Region aRegionPixel(rRegionPixel);
+            //RegionHandle aRegionHandle(aRegionPixel.BeginEnumRects());
+            //Rectangle aRegionRectanglePixel;
+            //
+            //while(aRegionPixel.GetEnumRects(aRegionHandle, aRegionRectanglePixel))
+            //{
+#ifdef DBG_U//TIL
+            //  // #i72754# possible graphical region test only with non-pro
+            //  static bool bDoPaintForVisualControl(false);
+            //  if(bDoPaintForVisualControl)
+            //  {
+            //      getOutputDevice().SetLineColor(COL_LIGHTGREEN);
+            //      getOutputDevice().SetFillColor();
+            //      getOutputDevice().DrawRect(aRegionRectanglePixel);
+            //  }
+#endif      //
+            //  // restore the area
+            //  const Point aTopLeft(aRegionRectanglePixel.TopLeft());
+            //  const Size aSize(aRegionRectanglePixel.GetSize());
+            //
+            //  getOutputDevice().DrawOutDev(
+            //      aTopLeft, aSize, // destination
+            //      aTopLeft, aSize, // source
+            //      maBufferDevice);
+            //}
+            //
+            //aRegionPixel.EndEnumRects(aRegionHandle);
 
             // restore MapModes
             getOutputDevice().EnableMapMode(bMapModeWasEnabledDest);
@@ -175,24 +201,24 @@ namespace sdr
             }
 
             // also limit to buffer size
-            const Rectangle aBufferDeviceRectanglePixel = Rectangle(Point(), maBufferDevice.GetOutputSizePixel());
+            const Rectangle aBufferDeviceRectanglePixel(Point(), maBufferDevice.GetOutputSizePixel());
             aRegion.Intersect(aBufferDeviceRectanglePixel);
 
-            // prepare to iterate over the rectangles from the region in pixels
-            RegionHandle aRegionHandle(aRegion.BeginEnumRects());
-            Rectangle aRegionRectanglePixel;
-
             // MapModes off
             const bool bMapModeWasEnabledDest(rSource.IsMapModeEnabled());
             const bool bMapModeWasEnabledSource(maBufferDevice.IsMapModeEnabled());
             rSource.EnableMapMode(false);
             maBufferDevice.EnableMapMode(false);
 
-            while(aRegion.GetEnumRects(aRegionHandle, aRegionRectanglePixel))
+            // prepare to iterate over the rectangles from the region in pixels
+            RectangleVector aRectangles;
+            aRegion.GetRegionRectangles(aRectangles);
+
+            for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
             {
                 // for each rectangle, save the area
-                Point aTopLeft(aRegionRectanglePixel.TopLeft());
-                Size aSize(aRegionRectanglePixel.GetSize());
+                const Point aTopLeft(aRectIter->TopLeft());
+                const Size aSize(aRectIter->GetSize());
 
                 maBufferDevice.DrawOutDev(
                     aTopLeft, aSize, // destination
@@ -200,7 +226,23 @@ namespace sdr
                     rSource);
             }
 
-            aRegion.EndEnumRects(aRegionHandle);
+            //RegionHandle aRegionHandle(aRegion.BeginEnumRects());
+            //Rectangle aRegionRectanglePixel;
+            //
+            //while(aRegion.GetEnumRects(aRegionHandle, aRegionRectanglePixel))
+            //{
+            //  // for each rectangle, save the area
+            //  Point aTopLeft(aRegionRectanglePixel.TopLeft());
+            //  Size aSize(aRegionRectanglePixel.GetSize());
+            //
+            //  maBufferDevice.DrawOutDev(
+            //      aTopLeft, aSize, // destination
+            //      aTopLeft, aSize, // source
+            //      rSource);
+            //
+            //}
+            //
+            //aRegion.EndEnumRects(aRegionHandle);
 
             // restore MapModes
             rSource.EnableMapMode(bMapModeWasEnabledDest);
diff --git a/svx/source/sdr/properties/itemsettools.cxx b/svx/source/sdr/properties/itemsettools.cxx
index b5f763a..cea89d0 100644
--- a/svx/source/sdr/properties/itemsettools.cxx
+++ b/svx/source/sdr/properties/itemsettools.cxx
@@ -21,10 +21,9 @@
 #include <tools/debug.hxx>
 #include <svl/itemset.hxx>
 #include <svl/whiter.hxx>
-
-#include <vector>
 #include <svx/svdogrp.hxx>
 #include <svx/svditer.hxx>
+#include <vcl/region.hxx>
 
 //////////////////////////////////////////////////////////////////////////////
 // class to remember broadcast start positions
@@ -33,9 +32,6 @@ namespace sdr
 {
     namespace properties
     {
-        // helper vector to remember rectangles
-        typedef ::std::vector< Rectangle > RectangleVector;
-
         ItemChangeBroadcaster::ItemChangeBroadcaster(const SdrObject& rObj)
         {
             if(rObj.ISA(SdrObjGroup))
diff --git a/svx/source/svdraw/sdrpaintwindow.cxx b/svx/source/svdraw/sdrpaintwindow.cxx
index 3df44a1..9651ae7 100644
--- a/svx/source/svdraw/sdrpaintwindow.cxx
+++ b/svx/source/svdraw/sdrpaintwindow.cxx
@@ -56,9 +56,9 @@ void SdrPreRenderDevice::PreparePreRenderDevice()
 void SdrPreRenderDevice::OutputPreRenderDevice(const Region& rExpandedRegion)
 {
     // region to pixels
-    Region aRegionPixel(mrOutputDevice.LogicToPixel(rExpandedRegion));
-    RegionHandle aRegionHandle(aRegionPixel.BeginEnumRects());
-    Rectangle aRegionRectanglePixel;
+    const Region aRegionPixel(mrOutputDevice.LogicToPixel(rExpandedRegion));
+    //RegionHandle aRegionHandle(aRegionPixel.BeginEnumRects());
+    //Rectangle aRegionRectanglePixel;
 
     // MapModes off
     sal_Bool bMapModeWasEnabledDest(mrOutputDevice.IsMapModeEnabled());
@@ -66,11 +66,14 @@ void SdrPreRenderDevice::OutputPreRenderDevice(const Region& rExpandedRegion)
     mrOutputDevice.EnableMapMode(sal_False);
     maPreRenderDevice.EnableMapMode(sal_False);
 
-    while(aRegionPixel.GetEnumRects(aRegionHandle, aRegionRectanglePixel))
+    RectangleVector aRectangles;
+    aRegionPixel.GetRegionRectangles(aRectangles);
+
+    for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
     {
         // for each rectangle, copy the area
-        const Point aTopLeft(aRegionRectanglePixel.TopLeft());
-        const Size aSize(aRegionRectanglePixel.GetSize());
+        const Point aTopLeft(aRectIter->TopLeft());
+        const Size aSize(aRectIter->GetSize());
 
         mrOutputDevice.DrawOutDev(
             aTopLeft, aSize,
@@ -80,17 +83,43 @@ void SdrPreRenderDevice::OutputPreRenderDevice(const Region& rExpandedRegion)
 #ifdef DBG_UTIL
         // #i74769#
         static bool bDoPaintForVisualControlRegion(false);
+
         if(bDoPaintForVisualControlRegion)
         {
-            Color aColor((((((rand()&0x7f)|0x80)<<8L)|((rand()&0x7f)|0x80))<<8L)|((rand()&0x7f)|0x80));
+            const Color aColor((((((rand()&0x7f)|0x80)<<8L)|((rand()&0x7f)|0x80))<<8L)|((rand()&0x7f)|0x80));
+
             mrOutputDevice.SetLineColor(aColor);
             mrOutputDevice.SetFillColor();
-            mrOutputDevice.DrawRect(aRegionRectanglePixel);
+            mrOutputDevice.DrawRect(*aRectIter);
         }
 #endif
     }
 
-    aRegionPixel.EndEnumRects(aRegionHandle);
+//  while(aRegionPixel.GetEnumRects(aRegionHandle, aRegionRectanglePixel))
+//  {
+//      // for each rectangle, copy the area
+//      const Point aTopLeft(aRegionRectanglePixel.TopLeft());
+//      const Size aSize(aRegionRectanglePixel.GetSize());
+//
+//      mrOutputDevice.DrawOutDev(
+//          aTopLeft, aSize,
+//          aTopLeft, aSize,
+//          maPreRenderDevice);
+//
+//#ifdef DBG_UTIL
+//      // #i74769#
+//      static bool bDoPaintForVisualControlRegion(false);
+//      if(bDoPaintForVisualControlRegion)
+//      {
+//          Color aColor((((((rand()&0x7f)|0x80)<<8L)|((rand()&0x7f)|0x80))<<8L)|((rand()&0x7f)|0x80));
+//          mrOutputDevice.SetLineColor(aColor);
+//          mrOutputDevice.SetFillColor();
+//          mrOutputDevice.DrawRect(aRegionRectanglePixel);
+//      }
+//#endif
+//  }
+//
+//  aRegionPixel.EndEnumRects(aRegionHandle);
 
     mrOutputDevice.EnableMapMode(bMapModeWasEnabledDest);
     maPreRenderDevice.EnableMapMode(bMapModeWasEnabledSource);
diff --git a/svx/source/svdraw/svdfmtf.cxx b/svx/source/svdraw/svdfmtf.cxx
index 0789a39..f6c4858 100644
--- a/svx/source/svdraw/svdfmtf.cxx
+++ b/svx/source/svdraw/svdfmtf.cxx
@@ -800,9 +800,7 @@ void ImpSdrGDIMetaFileImport::checkClip()
 {
     if(maVD.IsClipRegion())
     {
-        Region aRegion(maVD.GetClipRegion());
-
-        maClip = aRegion.ConvertToB2DPolyPolygon();
+        maClip = maVD.GetClipRegion().GetAsB2DPolyPolygon();
 
         if(isClip())
         {
diff --git a/svx/source/svdraw/svdpntv.cxx b/svx/source/svdraw/svdpntv.cxx
index db7feab..222b05c 100644
--- a/svx/source/svdraw/svdpntv.cxx
+++ b/svx/source/svdraw/svdpntv.cxx
@@ -617,19 +617,31 @@ void SdrPaintView::CompleteRedraw(OutputDevice* pOut, const Region& rReg, sdr::c
 #ifdef DBG_UTIL
                 // #i74769# test-paint repaint region
                 static bool bDoPaintForVisualControl(false);
+
                 if(bDoPaintForVisualControl)
                 {
-                    RegionHandle aRegionHandle(aOptimizedRepaintRegion.BeginEnumRects());
-                    Rectangle aRegionRectangle;
+                    RectangleVector aRectangles;
+                    aOptimizedRepaintRegion.GetRegionRectangles(aRectangles);
+
+                    pWindow->SetLineColor(COL_LIGHTGREEN);
+                    pWindow->SetFillColor();
 
-                    while(aOptimizedRepaintRegion.GetEnumRects(aRegionHandle, aRegionRectangle))
+                    for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
                     {
-                        pWindow->SetLineColor(COL_LIGHTGREEN);
-                        pWindow->SetFillColor();
-                        pWindow->DrawRect(aRegionRectangle);
+                        pWindow->DrawRect(*aRectIter);
                     }
 
-                    aOptimizedRepaintRegion.EndEnumRects(aRegionHandle);
+                    //RegionHandle aRegionHandle(aOptimizedRepaintRegion.BeginEnumRects());
+                    //Rectangle aRegionRectangle;
+                    //
+                    //while(aOptimizedRepaintRegion.GetEnumRects(aRegionHandle, aRegionRectangle))
+                    //{
+                    //  pWindow->SetLineColor(COL_LIGHTGREEN);
+                    //  pWindow->SetFillColor();
+                    //  pWindow->DrawRect(aRegionRectangle);
+                    //}
+                    //
+                    //aOptimizedRepaintRegion.EndEnumRects(aRegionHandle);
                 }
 #endif
             }
@@ -840,25 +852,6 @@ Region SdrPaintView::OptimizeDrawLayersRegion(OutputDevice* pOut, const Region&
             if(!pWindow->GetPaintRegion().IsEmpty())
             {
                 aOptimizedRepaintRegion.Intersect(pWindow->GetPaintRegion());
-
-#ifdef DBG_UTIL
-                // #i74769# test-paint repaint region
-                static bool bDoPaintForVisualControl(false);
-                if(bDoPaintForVisualControl)
-                {
-                    RegionHandle aRegionHandle(aOptimizedRepaintRegion.BeginEnumRects());
-                    Rectangle aRegionRectangle;
-
-                    while(aOptimizedRepaintRegion.GetEnumRects(aRegionHandle, aRegionRectangle))
-                    {
-                        pWindow->SetLineColor(COL_LIGHTGREEN);
-                        pWindow->SetFillColor();
-                        pWindow->DrawRect(aRegionRectangle);
-                    }
-
-                    aOptimizedRepaintRegion.EndEnumRects(aRegionHandle);
-                }
-#endif
             }
         }
     }
diff --git a/sw/source/core/view/viewsh.cxx b/sw/source/core/view/viewsh.cxx
index b1ac5c3..6dabfbc 100644
--- a/sw/source/core/view/viewsh.cxx
+++ b/sw/source/core/view/viewsh.cxx
@@ -1729,12 +1729,20 @@ void ViewShell::Paint(const Rectangle &rRect)
 
         if ( mbInEndAction && GetWin() )
         {
-            Region aRegion( GetWin()->GetPaintRegion() );
-            RegionHandle hHdl( aRegion.BeginEnumRects() );
-            Rectangle aRect;
-            while ( aRegion.GetNextEnumRect( hHdl, aRect ) )
-                Imp()->AddPaintRect( aRect );
-            aRegion.EndEnumRects( hHdl );
+            const Region aRegion(GetWin()->GetPaintRegion());
+            RectangleVector aRectangles;
+            aRegion.GetRegionRectangles(aRectangles);
+
+            for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
+            {
+                Imp()->AddPaintRect(*aRectIter);
+            }
+
+            //RegionHandle hHdl( aRegion.BeginEnumRects() );
+            //Rectangle aRect;
+            //while ( aRegion.GetEnumRects( hHdl, aRect ) )
+            //  Imp()->AddPaintRect( aRect );
+            //aRegion.EndEnumRects( hHdl );
         }
         else if ( SfxProgress::GetActiveProgress( GetDoc()->GetDocShell() ) &&
                   GetOut() == GetWin() )
diff --git a/toolkit/source/awt/vclxregion.cxx b/toolkit/source/awt/vclxregion.cxx
index 7ed03bf..2375bef 100644
--- a/toolkit/source/awt/vclxregion.cxx
+++ b/toolkit/source/awt/vclxregion.cxx
@@ -141,15 +141,24 @@ void VCLXRegion::xOrRegion( const ::com::sun::star::uno::Reference< ::com::sun::
 {
     ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
 
-    sal_uLong nRects = maRegion.GetRectCount();
-    ::com::sun::star::uno::Sequence< ::com::sun::star::awt::Rectangle > aRects( nRects );
-
-    Rectangle aRect;
-    sal_uInt32 nR = 0;
-    RegionHandle h = maRegion.BeginEnumRects();
-    while ( maRegion.GetNextEnumRect( h, aRect ) )
-        aRects.getArray()[nR++] = AWTRectangle( aRect );
-    maRegion.EndEnumRects( h );
+    RectangleVector aRectangles;
+    maRegion.GetRegionRectangles(aRectangles);
+
+//    sal_uLong nRects = maRegion.GetRectCount();
+    ::com::sun::star::uno::Sequence< ::com::sun::star::awt::Rectangle > aRects(aRectangles.size());
+    sal_uInt32 a(0);
+
+    for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
+    {
+        aRects.getArray()[a++] = AWTRectangle(*aRectIter);
+    }
+
+    //Rectangle aRect;
+    //sal_uInt32 nR = 0;
+    //RegionHandle h = maRegion.BeginEnumRects();
+    //while ( maRegion.GetEnumRects( h, aRect ) )
+    //  aRects.getArray()[nR++] = AWTRectangle( aRect );
+    //maRegion.EndEnumRects( h );
 
     return aRects;
 }
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 8daa5bb8..d9b19fa 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -246,6 +246,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
     vcl/source/gdi/print \
     vcl/source/gdi/regband \
     vcl/source/gdi/region \
+    vcl/source/gdi/regionband \
     vcl/source/gdi/salgdilayout \
     vcl/source/gdi/sallayout \
     vcl/source/gdi/salmisc \
diff --git a/vcl/aqua/source/gdi/salgdicommon.cxx b/vcl/aqua/source/gdi/salgdicommon.cxx
index afedd3b..ad484e2 100644
--- a/vcl/aqua/source/gdi/salgdicommon.cxx
+++ b/vcl/aqua/source/gdi/salgdicommon.cxx
@@ -27,7 +27,6 @@
 #include "aqua/salgdi.h"
 
 #include "fontsubset.hxx"
-#include "region.h"
 #include "sft.hxx"
 
 using namespace vcl;
@@ -1444,24 +1443,31 @@ bool AquaSalGraphics::setClipRegion( const Region& i_rClip )
     mxClipPath = CGPathCreateMutable();
 
     // set current path, either as polypolgon or sequence of rectangles
-    if( i_rClip.HasPolyPolygon() )
+    if(i_rClip.HasPolyPolygonOrB2DPolyPolygon())
     {
-        basegfx::B2DPolyPolygon aClip( const_cast<Region&>(i_rClip).ConvertToB2DPolyPolygon() );
+        const basegfx::B2DPolyPolygon aClip(i_rClip.GetAsB2DPolyPolygon());
+
         AddPolyPolygonToPath( mxClipPath, aClip, !getAntiAliasB2DDraw(), false );
     }
     else
     {
-        long nX, nY, nW, nH;
-        ImplRegionInfo aInfo;
-        bool bRegionRect = i_rClip.ImplGetFirstRect(aInfo, nX, nY, nW, nH );
-        while( bRegionRect )
+        RectangleVector aRectangles;
+        i_rClip.GetRegionRectangles(aRectangles);
+
+        for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
         {
-            if( nW && nH )
+            const long nW(aRectIter->Right() - aRectIter->Left() + 1); // uses +1 logic in original
+
+            if(nW)
             {
-                CGRect aRect = { { static_cast<CGFloat>(nX), static_cast<CGFloat>(nY) }, { static_cast<CGFloat>(nW), static_cast<CGFloat>(nH) } };
-                CGPathAddRect( mxClipPath, NULL, aRect );
+                const long nH(aRectIter->Bottom() - aRectIter->Top() + 1); // uses +1 logic in original
+
+                if(nH)
+                {
+                    CGRect aRect = {{ aRectIter->Left(), aRectIter->Top() }, { nW, nH }};
+                    CGPathAddRect( mxClipPath, NULL, aRect );
+                }
             }
-            bRegionRect = i_rClip.ImplGetNextRect( aInfo, nX, nY, nW, nH );
         }
     }
     // set the current path as clip region
diff --git a/vcl/generic/fontmanager/fontsubst.cxx b/vcl/generic/fontmanager/fontsubst.cxx
index 22b3d83..35f8294 100644
--- a/vcl/generic/fontmanager/fontsubst.cxx
+++ b/vcl/generic/fontmanager/fontsubst.cxx
@@ -30,7 +30,6 @@
 #include "outdev.h"
 #include "fontsubset.hxx"
 #include "salprn.hxx"
-#include "region.h"
 
 #include <unotools/fontdefs.hxx>
 #include <list>
diff --git a/vcl/generic/print/genpspgraphics.cxx b/vcl/generic/print/genpspgraphics.cxx
index 10af660..b9a1164 100644
--- a/vcl/generic/print/genpspgraphics.cxx
+++ b/vcl/generic/print/genpspgraphics.cxx
@@ -43,7 +43,6 @@
 #include "outfont.hxx"
 #include "fontsubset.hxx"
 #include "salprn.hxx"
-#include "region.h"
 #include "langboost.hxx"
 
 #include <config_graphite.h>
@@ -322,20 +321,45 @@ void GenPspGraphics::ResetClipRegion()
 bool GenPspGraphics::setClipRegion( const Region& i_rClip )
 {
     // TODO: support polygonal clipregions here
-    m_pPrinterGfx->BeginSetClipRegion( i_rClip.GetRectCount() );
+    RectangleVector aRectangles;
+    i_rClip.GetRegionRectangles(aRectangles);
+    m_pPrinterGfx->BeginSetClipRegion(aRectangles.size());
 
-    ImplRegionInfo aInfo;
-    long nX, nY, nW, nH;
-    bool bRegionRect = i_rClip.ImplGetFirstRect(aInfo, nX, nY, nW, nH );
-    while( bRegionRect )
+    for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
     {
-        if ( nW && nH )
+        const long nW(aRectIter->GetWidth());
+
+        if(nW)
         {
-            m_pPrinterGfx->UnionClipRegion( nX, nY, nW, nH );
+            const long nH(aRectIter->GetHeight());
+
+            if(nH)
+            {
+                m_pPrinterGfx->UnionClipRegion(
+                    aRectIter->Left(),
+                    aRectIter->Top(),
+                    nW,
+                    nH);
+            }
         }
-        bRegionRect = i_rClip.ImplGetNextRect( aInfo, nX, nY, nW, nH );
     }
+
     m_pPrinterGfx->EndSetClipRegion();
+
+    //m_pPrinterGfx->BeginSetClipRegion( i_rClip.GetRectCount() );
+    //
+    //ImplRegionInfo aInfo;
+    //long nX, nY, nW, nH;
+    //bool bRegionRect = i_rClip.ImplGetFirstRect(aInfo, nX, nY, nW, nH );
+    //while( bRegionRect )
+    //{
+    //    if ( nW && nH )
+    //    {
+    //        m_pPrinterGfx->UnionClipRegion( nX, nY, nW, nH );
+    //    }
+    //    bRegionRect = i_rClip.ImplGetNextRect( aInfo, nX, nY, nW, nH );
+    //}
+    //m_pPrinterGfx->EndSetClipRegion();
     return true;
 }
 
diff --git a/vcl/headless/svpgdi.cxx b/vcl/headless/svpgdi.cxx
index dbd233c..baab42e 100644
--- a/vcl/headless/svpgdi.cxx
+++ b/vcl/headless/svpgdi.cxx
@@ -37,7 +37,6 @@
 #include <sys/stat.h>
 #endif
 
-#include <region.h>
 #include <stdio.h>
 
 inline void dbgOut( const basebmp::BitmapDeviceSharedPtr&
@@ -165,21 +164,30 @@ void SvpSalGraphics::ensureClip()
     m_aClipMap = basebmp::createBitmapDevice( aSize, false, basebmp::Format::ONE_BIT_MSB_GREY );
     m_aClipMap->clear( basebmp::Color(0xFFFFFFFF) );
 
-    // fprintf( stderr, "non rect clip region set with %d rects:\n",
-    //         (int)m_aClipRegion.GetRectCount() );
-    ImplRegionInfo aInfo;
-    long nX, nY, nW, nH;
-    bool bRegionRect = m_aClipRegion.ImplGetFirstRect(aInfo, nX, nY, nW, nH );
-    while( bRegionRect )
+    RectangleVector aRectangles;
+    m_aClipRegion.GetRegionRectangles(aRectangles);
+
+    for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
     {
-        if ( nW && nH )
+        const long nW(aRectIter->GetWidth());
+        if(nW)
         {
-            basegfx::B2DPolyPolygon aFull;
-            aFull.append( basegfx::tools::createPolygonFromRect( basegfx::B2DRectangle( nX, nY, nX+nW, nY+nH ) ) );
-            m_aClipMap->fillPolyPolygon( aFull, basebmp::Color(0), basebmp::DrawMode_PAINT );
+            const long nH(aRectIter->GetHeight());
+
+            if(nH)
+            {
+                basegfx::B2DPolyPolygon aFull;
+
+                aFull.append(
+                    basegfx::tools::createPolygonFromRect(
+                        basegfx::B2DRectangle(
+                            aRectIter->Left(),
+                            aRectIter->Top(),
+                            aRectIter->Left() + nW,
+                            aRectIter->Top() + nH)));
+                m_aClipMap->fillPolyPolygon(aFull, basebmp::Color(0), basebmp::DrawMode_PAINT);
+            }
         }
-    //    fprintf( stderr, "\t %ld,%ld %ldx%ld\n", nX, nY, nW, nH );
-        bRegionRect = m_aClipRegion.ImplGetNextRect( aInfo, nX, nY, nW, nH );
     }
     m_bClipSetup = true;
 }
@@ -213,17 +221,17 @@ bool SvpSalGraphics::isClippedSetup( const basegfx::B2IBox &aRange, SvpSalGraphi
 
     // then see if we are overlapping with just one
     int nHit = 0;
-    Rectangle aIterRect, aHitRect;
-    RegionHandle aHnd = m_aClipRegion.BeginEnumRects();
-    while( m_aClipRegion.GetNextEnumRect( aHnd, aIterRect ) )
+    Rectangle aHitRect;
+    RectangleVector aRectangles;
+    m_aClipRegion.GetRegionRectangles(aRectangles);
+    for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
     {
-        if( aIterRect.IsOver( aRect ) )
+        if( aRectIter->IsOver( aRect ) )
         {
-            aHitRect = aIterRect;
+            aHitRect = *aRectIter;
             nHit++;
         }
     }
-    m_aClipRegion.EndEnumRects (aHnd);
 
     if( nHit == 0 ) // rendering outside any clipping region
     {
@@ -270,14 +278,23 @@ bool SvpSalGraphics::setClipRegion( const Region& i_rClip )
     m_aClipRegion = i_rClip;
     m_aClipMap.reset();
     if( i_rClip.IsEmpty() )
+    {
         m_bClipSetup = true;
+        return true;
+    }
+
+    RectangleVector aRectangles;
+    i_rClip.GetRegionRectangles(aRectangles);
 
-    else if( i_rClip.GetRectCount() == 1 )
+    if(1 == aRectangles.size())
     {
         m_aClipMap.reset();
-        Rectangle aBoundRect( i_rClip.GetBoundRect() );
-        m_aDevice = basebmp::subsetBitmapDevice( m_aOrigDevice,
-                                                 basegfx::B2IBox(aBoundRect.Left(),aBoundRect.Top(),aBoundRect.Right(),aBoundRect.Bottom()) );
+
+        const Rectangle& aBoundRect = aRectangles[0];
+        m_aDevice = basebmp::subsetBitmapDevice(
+            m_aOrigDevice,
+            basegfx::B2IBox(aBoundRect.Left(),aBoundRect.Top(),aBoundRect.Right(),aBoundRect.Bottom()) );
+
         m_bClipSetup = true;
     }
     else
diff --git a/vcl/inc/region.h b/vcl/inc/region.h
deleted file mode 100644
index 457bb1e..0000000
--- a/vcl/inc/region.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- *   Licensed to the Apache Software Foundation (ASF) under one or more
- *   contributor license agreements. See the NOTICE file distributed
- *   with this work for additional information regarding copyright
- *   ownership. The ASF licenses this file to you under the Apache
- *   License, Version 2.0 (the "License"); you may not use this file
- *   except in compliance with the License. You may obtain a copy of
- *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#ifndef _SV_REGION_H
-#define _SV_REGION_H
-
-#include <vcl/regband.hxx>
-#include <tools/poly.hxx>
-#include <vcl/region.hxx>
-
-// -----------------
-// - Hilfsmethoden -
-// -----------------
-
-#ifdef DBG_UTIL
-const char* ImplDbgTestRegion( const void* pObj );
-#endif
-
-// --------------------
-// - ImplRegionHandle -
-// --------------------
-
-struct ImplRegionHandle
-{
-    Region*             mpRegion;
-    ImplRegionBand*     mpCurrRectBand;
-    ImplRegionBandSep*  mpCurrRectBandSep;
-    sal_Bool                mbFirst;
-};
-
-// ------------------
-// - ImplRegionInfo -
-// ------------------
-
-struct ImplRegionInfo
-{
-    void*               mpVoidCurrRectBand;
-    void*               mpVoidCurrRectBandSep;
-};
-
-// --------------
-// - ImplRegion -
-// --------------
-
-struct ImplRegionBase
-{
-public:
-    ImplRegionBase( int nCount = 1 ); // TODO: replace manual refcounting
-    virtual ~ImplRegionBase();
-public:
-    sal_uIntPtr             mnRefCount;
-    sal_uIntPtr             mnRectCount;
-    PolyPolygon*        mpPolyPoly;
-    basegfx::B2DPolyPolygon* mpB2DPolyPoly;
-};
-
-class ImplRegion : public ImplRegionBase
-{
-    friend class Region;
-
-private:
-    ImplRegionBand*     mpFirstBand;        // root of the list with y-bands
-    ImplRegionBand*     mpLastCheckedBand;
-
-public:
-                        ImplRegion();
-                        ImplRegion( const PolyPolygon& rPolyPoly );
-                        ImplRegion( const basegfx::B2DPolyPolygon& );
-                        ImplRegion( const ImplRegion& rImplRegion );
-                        ~ImplRegion();
-
-    ImplRegionBand*     ImplGetFirstRegionBand() const { return mpFirstBand; }
-    PolyPolygon*        ImplGetPolyPoly() const { return mpPolyPoly; }
-
-    void                CreateBandRange( long nYTop, long nYBottom );
-    void                InsertBands( long nYTop, long nYBottom );
-    sal_Bool                InsertSingleBand( ImplRegionBand* mpImplRegionBand,
-                                          long nYBandPosition );
-    sal_Bool                InsertLine( const Point & rFirstPoint,
-                                    const Point & rSecondPoint,
-                                    long nLineID );
-    sal_Bool                InsertPoint( const Point &rPoint,
-                                     long nLineID,
-                                     sal_Bool bEndPoint, LineType eLineType );
-
-    /** Insert one band either after another band or as the first or only
-        band.  Both the forward as well as the backward links are updated.
-        @param pPreviousBand
-            When <NULL/> then pBandToInsert is inserted as first band or as
-            only band when there are no other bands.
-            When not <NULL/> then pBandToInsert is inserted directly after
-            pPreviousBand.
-        @param pBandToInsert
-            The band to insert.
-    */
-    void                InsertBand (ImplRegionBand* pPreviousBand,
-                                    ImplRegionBand* pBandToInsert);
-
-    void                Union( long nLeft, long nTop, long nRight, long nBottom );
-    void                Exclude( long nLeft, long nTop, long nRight, long nBottom );
-    void                XOr( long nLeft, long nTop, long nRight, long nBottom );
-
-                        // remove emtpy rects
-    sal_Bool                OptimizeBandList();
-
-    friend SvStream&    operator>>( SvStream& rIStm, Region& rRegion );
-    friend SvStream&    operator<<( SvStream& rOStm, const Region& rRegion );
-};
-
-#endif  // _SV_REGION_H
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/regionband.hxx b/vcl/inc/regionband.hxx
new file mode 100644
index 0000000..8965703
--- /dev/null
+++ b/vcl/inc/regionband.hxx
@@ -0,0 +1,83 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef _SV_REGIONBAND_HXX
+#define _SV_REGIONBAND_HXX
+
+#include <vcl/regband.hxx>
+#include <vcl/region.hxx>
+
+#ifdef DBG_UTIL
+const char* ImplDbgTestRegionBand(const void*);
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+
+class RegionBand
+{
+private:
+    friend const char* ImplDbgTestRegionBand(const void*);
+
+    ImplRegionBand*             mpFirstBand;        // root of the list with y-bands
+    ImplRegionBand*             mpLastCheckedBand;
+
+    void implReset();
+
+public:
+    RegionBand();
+    RegionBand(const RegionBand&);
+    RegionBand& operator=(const RegionBand&);
+    RegionBand(const Rectangle&);
+    ~RegionBand();
+
+    bool operator==( const RegionBand& rRegionBand ) const;
+    bool operator!=( const RegionBand& rRegionBand ) const { return !(RegionBand::operator==( rRegionBand )); }
+
+    void load(SvStream& rIStrm);
+    void save(SvStream& rIStrm) const;
+
+    bool isSingleRectangle() const;
+    ImplRegionBand* ImplGetFirstRegionBand() const { return mpFirstBand; }
+    void ImplAddMissingBands(const long nTop, const long nBottom);
+    void InsertBand(ImplRegionBand* pPreviousBand, ImplRegionBand* pBandToInsert);
+    void processPoints();
+    void CreateBandRange(long nYTop, long nYBottom);
+    bool InsertLine(const Point& rStartPt, const Point& rEndPt, long nLineId);
+    bool InsertPoint(const Point &rPoint, long nLineID, bool bEndPoint, LineType eLineType);
+    bool OptimizeBandList();
+    void Move(long nHorzMove, long nVertMove);
+    void Scale(double fScaleX, double fScaleY);
+    void InsertBands(long nTop, long nBottom);
+    bool InsertSingleBand(ImplRegionBand* pBand, long nYBandPosition);
+    void Union(long nLeft, long nTop, long nRight, long nBottom);
+    void Intersect(long nLeft, long nTop, long nRight, long nBottom);
+    void Union(const RegionBand& rSource);
+    void Exclude(long nLeft, long nTop, long nRight, long nBottom);
+    void XOr(long nLeft, long nTop, long nRight, long nBottom);
+    void Intersect(const RegionBand& rSource);
+    bool Exclude(const RegionBand& rSource);
+    void XOr(const RegionBand& rSource);
+    Rectangle GetBoundRect() const;
+    bool IsInside(const Point& rPoint) const;
+    sal_uInt32 getRectangleCount() const; // only users are Region::Intersect and PSWriter::ImplBmp
+    void GetRegionRectangles(RectangleVector& rTarget) const;
+};
+
+#endif  // _SV_REGIONBAND_HXX
+
+//////////////////////////////////////////////////////////////////////////////
+//eof
diff --git a/vcl/source/gdi/bitmap.cxx b/vcl/source/gdi/bitmap.cxx
index 2bb1a9d..7ba90c7 100644
--- a/vcl/source/gdi/bitmap.cxx
+++ b/vcl/source/gdi/bitmap.cxx
@@ -1281,38 +1281,92 @@ Region Bitmap::CreateRegion( const Color& rColor, const Rectangle& rRect ) const
 
     if( pReadAcc )
     {
-        Rectangle           aSubRect;
+        //Rectangle         aSubRect;
         const long          nLeft = aRect.Left();
         const long          nTop = aRect.Top();
         const long          nRight = aRect.Right();
         const long          nBottom = aRect.Bottom();
         const BitmapColor   aMatch( pReadAcc->GetBestMatchingColor( rColor ) );
 
-        aRegion.ImplBeginAddRect();
+        //RectangleVector aRectangles;
+        //aRegion.ImplBeginAddRect();
+        std::vector< long > aLine;
+        long nYStart(nTop);
+        long nY(nTop);
 
-        for( long nY = nTop; nY <= nBottom; nY++ )
+        for( ; nY <= nBottom; nY++ )
         {
-            aSubRect.Top() = aSubRect.Bottom() = nY;
+            //aSubRect.Top() = aSubRect.Bottom() = nY;
+            std::vector< long > aNewLine;
+            long nX(nLeft);
 
-            for( long nX = nLeft; nX <= nRight; )
+            for( ; nX <= nRight; )
             {
                 while( ( nX <= nRight ) && ( aMatch != pReadAcc->GetPixel( nY, nX ) ) )
                     nX++;
 
                 if( nX <= nRight )
                 {
-                    aSubRect.Left() = nX;
+                    aNewLine.push_back(nX);
+                    //aSubRect.Left() = nX;
 
                     while( ( nX <= nRight ) && ( aMatch == pReadAcc->GetPixel( nY, nX ) ) )
                         nX++;
 
-                    aSubRect.Right() = nX - 1L;
-                    aRegion.ImplAddRect( aSubRect );
+                    //aSubRect.Right() = nX - 1L;
+                    aNewLine.push_back(nX - 1);
+
+                    //aRegion.ImplAddRect( aSubRect );
+                    //aRectangles.push_back(aSubRect);
+                    //aRegion.Union(aSubRect);
                 }
             }
+
+            if(aNewLine != aLine)
+            {
+                // need to write aLine, it's different from the next line
+                if(aLine.size())
+                {
+                    Rectangle aSubRect;
+
+                    // enter y values and proceed ystart
+                    aSubRect.Top() = nYStart;
+                    aSubRect.Bottom() = nY ? nY - 1 : 0;
+
+                    for(sal_uInt32 a(0); a < aLine.size();)
+                    {
+                        aSubRect.Left() = aLine[a++];
+                        aSubRect.Right() = aLine[a++];
+                        aRegion.Union(aSubRect);
+                    }
+                }
+
+                // copy line as new line
+                aLine = aNewLine;
+                nYStart = nY;
+            }
         }
 
-        aRegion.ImplEndAddRect();
+        // write last line if used
+        if(aLine.size())
+        {
+            Rectangle aSubRect;
+
+            // enter y values
+            aSubRect.Top() = nYStart;
+            aSubRect.Bottom() = nY ? nY - 1 : 0;
+
+            for(sal_uInt32 a(0); a < aLine.size();)
+            {
+                aSubRect.Left() = aLine[a++];
+                aSubRect.Right() = aLine[a++];
+                aRegion.Union(aSubRect);
+            }
+        }
+
+        //aRegion.ImplEndAddRect();
+        //aRegion.SetRegionRectangles(aRectangles);
+
         ( (Bitmap*) this )->ReleaseAccess( pReadAcc );
     }
     else
diff --git a/vcl/source/gdi/bmpacc3.cxx b/vcl/source/gdi/bmpacc3.cxx
index 791a75d..c35f531 100644
--- a/vcl/source/gdi/bmpacc3.cxx
+++ b/vcl/source/gdi/bmpacc3.cxx
@@ -243,4 +243,133 @@ void BitmapWriteAccess::DrawRect( const Rectangle& rRect )
     }
 }
 
+// ------------------------------------------------------------------
+
+void BitmapWriteAccess::FillPolygon( const Polygon& rPoly )
+{
+    const sal_uInt16 nSize = rPoly.GetSize();
+
+    if( nSize && mpFillColor )
+    {
+        const BitmapColor&  rFillColor = *mpFillColor;
+        Region              aRegion( rPoly );
+//      Rectangle           aRect;
+
+        aRegion.Intersect( Rectangle( Point(), Size( Width(), Height() ) ) );
+
+        if( !aRegion.IsEmpty() )
+        {
+            RectangleVector aRectangles;
+            aRegion.GetRegionRectangles(aRectangles);
+
+            for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
+            {
+                for(long nY = aRectIter->Top(), nEndY = aRectIter->Bottom(); nY <= nEndY; nY++)
+                {
+                    for(long nX = aRectIter->Left(), nEndX = aRectIter->Right(); nX <= nEndX; nX++)
+                    {
+                        SetPixel(nY, nX, rFillColor);
+                    }
+                }
+            }
+
+            //RegionHandle aRegHandle( aRegion.BeginEnumRects() );
+            //
+            //while( aRegion.GetEnumRects( aRegHandle, aRect ) )
+            //  for( long nY = aRect.Top(), nEndY = aRect.Bottom(); nY <= nEndY; nY++ )
+            //      for( long nX = aRect.Left(), nEndX = aRect.Right(); nX <= nEndX; nX++ )
+            //          SetPixel( nY, nX, rFillColor );
+            //
+            //aRegion.EndEnumRects( aRegHandle );
+        }
+    }
+}
+
+// ------------------------------------------------------------------
+
+void BitmapWriteAccess::DrawPolygon( const Polygon& rPoly )
+{
+    if( mpFillColor )
+        FillPolygon( rPoly );
+
+    if( mpLineColor && ( !mpFillColor || ( *mpFillColor != *mpLineColor ) ) )
+    {
+        const sal_uInt16 nSize = rPoly.GetSize();
+
+        for( sal_uInt16 i = 0, nSize1 = nSize - 1; i < nSize1; i++ )
+            DrawLine( rPoly[ i ], rPoly[ i + 1 ] );
+
+        if( rPoly[ nSize - 1 ] != rPoly[ 0 ] )
+            DrawLine( rPoly[ nSize - 1 ], rPoly[ 0 ] );
+    }
+}
+
+// ------------------------------------------------------------------
+
+void BitmapWriteAccess::FillPolyPolygon( const PolyPolygon& rPolyPoly )
+{
+    const sal_uInt16 nCount = rPolyPoly.Count();
+
+    if( nCount && mpFillColor )
+    {
+        const BitmapColor&  rFillColor = *mpFillColor;
+        Region              aRegion( rPolyPoly );
+        //Rectangle         aRect;
+
+        aRegion.Intersect( Rectangle( Point(), Size( Width(), Height() ) ) );
+
+        if( !aRegion.IsEmpty() )
+        {
+            RectangleVector aRectangles;
+            aRegion.GetRegionRectangles(aRectangles);
+
+            for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
+            {
+                for(long nY = aRectIter->Top(), nEndY = aRectIter->Bottom(); nY <= nEndY; nY++)
+                {
+                    for(long nX = aRectIter->Left(), nEndX = aRectIter->Right(); nX <= nEndX; nX++)
+                    {
+                        SetPixel(nY, nX, rFillColor);
+                    }
+                }
+            }
+
+            //RegionHandle aRegHandle( aRegion.BeginEnumRects() );
+            //
+            //while( aRegion.GetEnumRects( aRegHandle, aRect ) )
+            //  for( long nY = aRect.Top(), nEndY = aRect.Bottom(); nY <= nEndY; nY++ )
+            //      for( long nX = aRect.Left(), nEndX = aRect.Right(); nX <= nEndX; nX++ )
+            //          SetPixel( nY, nX, rFillColor );
+            //
+            //aRegion.EndEnumRects( aRegHandle );
+        }
+    }
+}
+
+// ------------------------------------------------------------------
+
+void BitmapWriteAccess::DrawPolyPolygon( const PolyPolygon& rPolyPoly )
+{
+    if( mpFillColor )
+        FillPolyPolygon( rPolyPoly );
+
+    if( mpLineColor && ( !mpFillColor || ( *mpFillColor != *mpLineColor ) ) )
+    {
+        for( sal_uInt16 n = 0, nCount = rPolyPoly.Count(); n < nCount; )
+        {
+            const Polygon&  rPoly = rPolyPoly[ n++ ];
+            const sal_uInt16    nSize = rPoly.GetSize();
+
+            if( nSize )
+            {
+                for( sal_uInt16 i = 0, nSize1 = nSize - 1; i < nSize1; i++ )
+                    DrawLine( rPoly[ i ], rPoly[ i + 1 ] );
+
+                if( rPoly[ nSize - 1 ] != rPoly[ 0 ] )
+                    DrawLine( rPoly[ nSize - 1 ], rPoly[ 0 ] );
+            }
+        }
+    }
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/gdi/gdimtf.cxx b/vcl/source/gdi/gdimtf.cxx
index fce3d09..77a426f 100644
--- a/vcl/source/gdi/gdimtf.cxx
+++ b/vcl/source/gdi/gdimtf.cxx
@@ -1282,8 +1282,8 @@ void GDIMetaFile::Rotate( long nAngle10 )
                 {
                     MetaClipRegionAction* pAct = (MetaClipRegionAction*) pAction;
 
-                    if( pAct->IsClipping() && pAct->GetRegion().HasPolyPolygon() )
-                        aMtf.AddAction( new MetaClipRegionAction( Region( ImplGetRotatedPolyPolygon( pAct->GetRegion().GetPolyPolygon(), aRotAnchor, aRotOffset, fSin, fCos ) ), sal_True ) );
+                    if( pAct->IsClipping() && pAct->GetRegion().HasPolyPolygonOrB2DPolyPolygon() )
+                        aMtf.AddAction( new MetaClipRegionAction( Region( ImplGetRotatedPolyPolygon( pAct->GetRegion().GetAsPolyPolygon(), aRotAnchor, aRotOffset, fSin, fCos ) ), sal_True ) );
                     else
                     {
                         pAction->Duplicate();
@@ -1306,8 +1306,8 @@ void GDIMetaFile::Rotate( long nAngle10 )
                     MetaISectRegionClipRegionAction*    pAct = (MetaISectRegionClipRegionAction*) pAction;
                     const Region&                       rRegion = pAct->GetRegion();
 
-                    if( rRegion.HasPolyPolygon() )
-                        aMtf.AddAction( new MetaISectRegionClipRegionAction( Region( ImplGetRotatedPolyPolygon( rRegion.GetPolyPolygon(), aRotAnchor, aRotOffset, fSin, fCos ) ) ) );
+                    if( rRegion.HasPolyPolygonOrB2DPolyPolygon() )
+                        aMtf.AddAction( new MetaISectRegionClipRegionAction( Region( ImplGetRotatedPolyPolygon( rRegion.GetAsPolyPolygon(), aRotAnchor, aRotOffset, fSin, fCos ) ) ) );
                     else
                     {
                         pAction->Duplicate();
@@ -2600,12 +2600,12 @@ sal_uLong GDIMetaFile::GetChecksum() const
                 MetaClipRegionAction* pAct = dynamic_cast< MetaClipRegionAction* >(pAction);
                 const Region& rRegion = pAct->GetRegion();
 
-                if(rRegion.HasPolyPolygon())
+                if(rRegion.HasPolyPolygonOrB2DPolyPolygon())
                 {
                     // It has shown that this is a possible bottleneck for checksum calculation.
                     // In worst case a very expensive RegionHandle representation gets created.
                     // In this case it's cheaper to use the PolyPolygon
-                    const basegfx::B2DPolyPolygon aPolyPolygon(rRegion.GetB2DPolyPolygon());
+                    const basegfx::B2DPolyPolygon aPolyPolygon(rRegion.GetAsB2DPolyPolygon());
                     const sal_uInt32 nPolyCount(aPolyPolygon.count());
                     SVBT64 aSVBT64;
 
diff --git a/vcl/source/gdi/outdev.cxx b/vcl/source/gdi/outdev.cxx
index 65119b6..090f229 100644
--- a/vcl/source/gdi/outdev.cxx
+++ b/vcl/source/gdi/outdev.cxx
@@ -41,7 +41,6 @@
 #include <svdata.hxx>
 #include <window.h>
 #include <outdev.h>
-#include <region.h>
 #include <outdata.hxx>
 
 #include <basegfx/point/b2dpoint.hxx>
@@ -322,7 +321,7 @@ void OutputDevice::ImplDrawPolyPolygon( sal_uInt16 nPoly, const PolyPolygon& rPo
 // =======================================================================
 
 OutputDevice::OutputDevice() :
-    maRegion( REGION_NULL ),
+    maRegion(true),
     maFillColor( COL_WHITE ),
     maTextLineColor( COL_TRANSPARENT ),
     maSettings( Application::GetSettings() )
@@ -530,23 +529,35 @@ void    OutputDevice::ImplReMirror( Rectangle &rRect ) const
 }
 void    OutputDevice::ImplReMirror( Region &rRegion ) const
 {
-    long                nX;
-    long                nY;
-    long                nWidth;
-    long                nHeight;
-    ImplRegionInfo      aInfo;
-    sal_Bool                bRegionRect;
-    Region              aMirroredRegion;
+    RectangleVector aRectangles;
+    rRegion.GetRegionRectangles(aRectangles);
+    Region aMirroredRegion;
 
-    bRegionRect = rRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
-    while ( bRegionRect )
+    for(RectangleVector::iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
     {
-        Rectangle aRect( Point(nX, nY), Size(nWidth, nHeight) );
-        ImplReMirror( aRect );
-        aMirroredRegion.Union( aRect );
-        bRegionRect = rRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
+        ImplReMirror(*aRectIter);
+        aMirroredRegion.Union(*aRectIter);
     }
+
     rRegion = aMirroredRegion;
+
+//  long                nX;
+//  long                nY;
+//  long                nWidth;
+//  long                nHeight;
+//  ImplRegionInfo      aInfo;
+//  sal_Bool                bRegionRect;
+//    Region              aMirroredRegion;
+//
+//  bRegionRect = rRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
+//  while ( bRegionRect )
+//  {
+//        Rectangle aRect( Point(nX, nY), Size(nWidth, nHeight) );
+//        ImplReMirror( aRect );
+//        aMirroredRegion.Union( aRect );
+//      bRegionRect = rRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
+//  }
+//    rRegion = aMirroredRegion;
 }
 
 SalGraphics* OutputDevice::ImplGetGraphics() const
@@ -1004,7 +1015,7 @@ void OutputDevice::ImplSetClipRegion( const Region* pRegion )
     {
         if ( mbClipRegion )
         {
-            maRegion            = Region( REGION_NULL );
+            maRegion            = Region(true);
             mbClipRegion        = sal_False;
             mbInitClipRegion    = sal_True;
         }
@@ -1033,13 +1044,14 @@ void OutputDevice::SetClipRegion()
 void OutputDevice::SetClipRegion( const Region& rRegion )
 {
     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
-    DBG_CHKOBJ( &rRegion, Region, ImplDbgTestRegion );
 
     if ( mpMetaFile )
         mpMetaFile->AddAction( new MetaClipRegionAction( rRegion, sal_True ) );
 
-    if ( rRegion.GetType() == REGION_NULL )
+    if ( rRegion.IsNull() )
+    {
         ImplSetClipRegion( NULL );
+    }
     else
     {
         Region aRegion = LogicToPixel( rRegion );
@@ -1063,7 +1075,7 @@ Region OutputDevice::GetActiveClipRegion() const
 
     if ( GetOutDevType() == OUTDEV_WINDOW )
     {
-        Region aRegion( REGION_NULL );
+        Region aRegion(true);
         Window* pWindow = (Window*)this;
         if ( pWindow->mpWindowImpl->mbInPaint )
         {
@@ -1115,11 +1127,8 @@ void OutputDevice::IntersectClipRegion( const Rectangle& rRect )
 void OutputDevice::IntersectClipRegion( const Region& rRegion )
 {
     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
-    DBG_CHKOBJ( &rRegion, Region, ImplDbgTestRegion );
-
-    RegionType eType = rRegion.GetType();
 
-    if ( eType != REGION_NULL )
+    if(!rRegion.IsNull())
     {
         if ( mpMetaFile )
             mpMetaFile->AddAction( new MetaISectRegionClipRegionAction( rRegion ) );
diff --git a/vcl/source/gdi/outdev2.cxx b/vcl/source/gdi/outdev2.cxx
index e178426..915fb89 100644
--- a/vcl/source/gdi/outdev2.cxx
+++ b/vcl/source/gdi/outdev2.cxx
@@ -37,7 +37,6 @@
 #include <image.h>
 #include <outdev.h>
 #include <window.h>
-#include <region.h>
 #include <outdata.hxx>
 
 DBG_NAMEEX( OutputDevice )
@@ -1945,7 +1944,7 @@ void OutputDevice::ImplPrintTransparent( const Bitmap& rBmp, const Bitmap& rMask
 
         // do painting
         const long      nSrcWidth = aSrcRect.GetWidth(), nSrcHeight = aSrcRect.GetHeight();
-        long            nX, nY, nWorkX, nWorkY, nWorkWidth, nWorkHeight;
+        long            nX, nY; // , nWorkX, nWorkY, nWorkWidth, nWorkHeight;
         long*           pMapX = new long[ nSrcWidth + 1 ];
         long*           pMapY = new long[ nSrcHeight + 1 ];
         const bool      bOldMap = mbMap;
@@ -1960,22 +1959,38 @@ void OutputDevice::ImplPrintTransparent( const Bitmap& rBmp, const Bitmap& rMask
             pMapY[ nY ] = aDestPt.Y() + FRound( (double) aDestSz.Height() * nY / nSrcHeight );
 
         // walk through all rectangles of mask
-        Region          aWorkRgn( aMask.CreateRegion( COL_BLACK, Rectangle( Point(), aMask.GetSizePixel() ) ) );
-        ImplRegionInfo  aInfo;
-        bool            bRgnRect = aWorkRgn.ImplGetFirstRect( aInfo, nWorkX, nWorkY, nWorkWidth, nWorkHeight );
+        const Region aWorkRgn(aMask.CreateRegion(COL_BLACK, Rectangle(Point(), aMask.GetSizePixel())));
+        RectangleVector aRectangles;
+        aWorkRgn.GetRegionRectangles(aRectangles);
 
-        while( bRgnRect )
+        for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
         {
-            Bitmap          aBandBmp( aPaint );
-            const Rectangle aBandRect( Point( nWorkX, nWorkY ), Size( nWorkWidth, nWorkHeight ) );
-            const Point     aMapPt( pMapX[ nWorkX ], pMapY[ nWorkY ] );
-            const Size      aMapSz( pMapX[ nWorkX + nWorkWidth ] - aMapPt.X(), pMapY[ nWorkY + nWorkHeight ] - aMapPt.Y() );
-
-            aBandBmp.Crop( aBandRect );
-            ImplDrawBitmap( aMapPt, aMapSz, Point(), aBandBmp.GetSizePixel(), aBandBmp, META_BMPSCALEPART_ACTION );
-            bRgnRect = aWorkRgn.ImplGetNextRect( aInfo, nWorkX, nWorkY, nWorkWidth, nWorkHeight );
+            const Point aMapPt(pMapX[aRectIter->Left()], pMapY[aRectIter->Top()]);
+            const Size aMapSz(
+                pMapX[aRectIter->Right() + 1] - aMapPt.X(),      // pMapX[L + W] -> L + ((R - L) + 1) -> R + 1
+                pMapY[aRectIter->Bottom() + 1] - aMapPt.Y());    // same for Y
+            Bitmap aBandBmp(aPaint);
+
+            aBandBmp.Crop(*aRectIter);
+            ImplDrawBitmap(aMapPt, aMapSz, Point(), aBandBmp.GetSizePixel(), aBandBmp, META_BMPSCALEPART_ACTION);
         }
 
+        //Region          aWorkRgn( aMask.CreateRegion( COL_BLACK, Rectangle( Point(), aMask.GetSizePixel() ) ) );
+        //ImplRegionInfo    aInfo;
+        //sal_Bool            bRgnRect = aWorkRgn.ImplGetFirstRect( aInfo, nWorkX, nWorkY, nWorkWidth, nWorkHeight );
+        //
+        //while( bRgnRect )
+        //{
+        //  Bitmap          aBandBmp( aPaint );
+        //    const Rectangle aBandRect( Point( nWorkX, nWorkY ), Size( nWorkWidth, nWorkHeight ) );
+        //    const Point     aMapPt( pMapX[ nWorkX ], pMapY[ nWorkY ] );
+        //    const Size      aMapSz( pMapX[ nWorkX + nWorkWidth ] - aMapPt.X(), pMapY[ nWorkY + nWorkHeight ] - aMapPt.Y() );
+        //
+        //  aBandBmp.Crop( aBandRect );
+        //    ImplDrawBitmap( aMapPt, aMapSz, Point(), aBandBmp.GetSizePixel(), aBandBmp, META_BMPSCALEPART_ACTION );
+        //    bRgnRect = aWorkRgn.ImplGetNextRect( aInfo, nWorkX, nWorkY, nWorkWidth, nWorkHeight );
+        //}
+
         mbMap = bOldMap;
 
         delete[] pMapX;
@@ -2028,7 +2043,7 @@ void OutputDevice::ImplPrintMask( const Bitmap& rMask, const Color& rMaskColor,
 
         // do painting
         const long      nSrcWidth = aSrcRect.GetWidth(), nSrcHeight = aSrcRect.GetHeight();
-        long            nX, nY, nWorkX, nWorkY, nWorkWidth, nWorkHeight;
+        long            nX, nY; //, nWorkX, nWorkY, nWorkWidth, nWorkHeight;
         long*           pMapX = new long[ nSrcWidth + 1 ];
         long*           pMapY = new long[ nSrcHeight + 1 ];
         GDIMetaFile*    pOldMetaFile = mpMetaFile;
@@ -2050,19 +2065,33 @@ void OutputDevice::ImplPrintMask( const Bitmap& rMask, const Color& rMaskColor,
             pMapY[ nY ] = aDestPt.Y() + FRound( (double) aDestSz.Height() * nY / nSrcHeight );
 
         // walk through all rectangles of mask
-        Region          aWorkRgn( aMask.CreateRegion( COL_BLACK, Rectangle( Point(), aMask.GetSizePixel() ) ) );
-        ImplRegionInfo  aInfo;
-        bool            bRgnRect = aWorkRgn.ImplGetFirstRect( aInfo, nWorkX, nWorkY, nWorkWidth, nWorkHeight );
+        const Region aWorkRgn(aMask.CreateRegion(COL_BLACK, Rectangle(Point(), aMask.GetSizePixel())));
+        RectangleVector aRectangles;
+        aWorkRgn.GetRegionRectangles(aRectangles);
 
-        while( bRgnRect )
+        for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
         {
-            const Point aMapPt( pMapX[ nWorkX ], pMapY[ nWorkY ] );
-            const Size  aMapSz( pMapX[ nWorkX + nWorkWidth ] - aMapPt.X(), pMapY[ nWorkY + nWorkHeight ] - aMapPt.Y() );
+            const Point aMapPt(pMapX[aRectIter->Left()], pMapY[aRectIter->Top()]);
+            const Size aMapSz(
+                pMapX[aRectIter->Right() + 1] - aMapPt.X(),      // pMapX[L + W] -> L + ((R - L) + 1) -> R + 1
+                pMapY[aRectIter->Bottom() + 1] - aMapPt.Y());    // same for Y
 
-            DrawRect( Rectangle( aMapPt, aMapSz ) );
-            bRgnRect = aWorkRgn.ImplGetNextRect( aInfo, nWorkX, nWorkY, nWorkWidth, nWorkHeight );
+            DrawRect(Rectangle(aMapPt, aMapSz));
         }
 
+        //Region          aWorkRgn( aMask.CreateRegion( COL_BLACK, Rectangle( Point(), aMask.GetSizePixel() ) ) );
+        //ImplRegionInfo    aInfo;
+        //sal_Bool            bRgnRect = aWorkRgn.ImplGetFirstRect( aInfo, nWorkX, nWorkY, nWorkWidth, nWorkHeight );
+        //
+        //while( bRgnRect )
+        //{
+        //    const Point aMapPt( pMapX[ nWorkX ], pMapY[ nWorkY ] );
+        //    const Size  aMapSz( pMapX[ nWorkX + nWorkWidth ] - aMapPt.X(), pMapY[ nWorkY + nWorkHeight ] - aMapPt.Y() );
+        //
+        //  DrawRect( Rectangle( aMapPt, aMapSz ) );
+        //  bRgnRect = aWorkRgn.ImplGetNextRect( aInfo, nWorkX, nWorkY, nWorkWidth, nWorkHeight );
+        //}
+
         Pop();
         delete[] pMapX;
         delete[] pMapY;
diff --git a/vcl/source/gdi/outmap.cxx b/vcl/source/gdi/outmap.cxx
index 25cbb53..7ef70f8 100644
--- a/vcl/source/gdi/outmap.cxx
+++ b/vcl/source/gdi/outmap.cxx
@@ -34,7 +34,6 @@
 #include <vcl/outdev.hxx>
 
 #include <svdata.hxx>
-#include <region.h>
 #include <window.h>
 #include <outdev.h>
 #include <salgdi.hxx>
@@ -679,8 +678,6 @@ Rectangle OutputDevice::ImplDevicePixelToLogic( const Rectangle& rPixelRect ) co
 
 Region OutputDevice::ImplPixelToDevicePixel( const Region& rRegion ) const
 {
-    DBG_CHKOBJ( &rRegion, Region, ImplDbgTestRegion );
-
     if ( !mnOutOffX && !mnOutOffY )
         return rRegion;
 
@@ -1132,48 +1129,73 @@ PolyPolygon OutputDevice::LogicToPixel( const PolyPolygon& rLogicPolyPoly ) cons
 
 // -----------------------------------------------------------------------
 
+basegfx::B2DPolygon OutputDevice::LogicToPixel( const basegfx::B2DPolygon& rLogicPoly ) const
+{
+    basegfx::B2DPolygon aTransformedPoly = rLogicPoly;
+    const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetViewTransformation();
+    aTransformedPoly.transform( rTransformationMatrix );
+    return aTransformedPoly;
+}
+
+// -----------------------------------------------------------------------
+
+basegfx::B2DPolyPolygon OutputDevice::LogicToPixel( const basegfx::B2DPolyPolygon& rLogicPolyPoly ) const
+{
+    basegfx::B2DPolyPolygon aTransformedPoly = rLogicPolyPoly;
+    const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetViewTransformation();
+    aTransformedPoly.transform( rTransformationMatrix );
+    return aTransformedPoly;
+}
+
+// -----------------------------------------------------------------------
+
 Region OutputDevice::LogicToPixel( const Region& rLogicRegion ) const
 {
     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
-    DBG_CHKOBJ( &rLogicRegion, Region, ImplDbgTestRegion );
-
-    RegionType eType = rLogicRegion.GetType();
 
-    if ( !mbMap || (eType == REGION_EMPTY) || (eType == REGION_NULL) )
+    if(!mbMap || rLogicRegion.IsNull() || rLogicRegion.IsEmpty())
+    {
         return rLogicRegion;
+    }
 
-    Region          aRegion;
-    const ImplRegion& rImplRegion = *rLogicRegion.ImplGetImplRegion();
-    const PolyPolygon* pPolyPoly = rImplRegion.mpPolyPoly;
-    const basegfx::B2DPolyPolygon* pB2DPolyPoly = rImplRegion.mpB2DPolyPoly;
+    Region aRegion;
 
-    if ( pPolyPoly )
-        aRegion = Region( LogicToPixel( *pPolyPoly ) );
-    else if( pB2DPolyPoly )
+    if(rLogicRegion.getB2DPolyPolygon())
     {
-        basegfx::B2DPolyPolygon aTransformedPoly = *pB2DPolyPoly;
-        const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetViewTransformation();
-        aTransformedPoly.transform( rTransformationMatrix );
-        aRegion = Region( aTransformedPoly );
+        aRegion = Region(LogicToPixel(*rLogicRegion.getB2DPolyPolygon()));
     }
-    else
+    else if(rLogicRegion.getPolyPolygon())
+    {
+        aRegion = Region(LogicToPixel(*rLogicRegion.getPolyPolygon()));
+    }
+    else if(rLogicRegion.getRegionBand())
     {
-        long                nX;
-        long                nY;
-        long                nWidth;
-        long                nHeight;
-        ImplRegionInfo      aInfo;
-        sal_Bool                bRegionRect;
+        RectangleVector aRectangles;
+        rLogicRegion.GetRegionRectangles(aRectangles);
+        const RectangleVector& rRectangles(aRectangles); // needed to make the '!=' work
 
-        aRegion.ImplBeginAddRect();
-        bRegionRect = rLogicRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
-        while ( bRegionRect )
+        // make reverse run to fill new region bottom-up, this will speed it up due to the used data structuring
+        for(RectangleVector::const_reverse_iterator aRectIter(rRectangles.rbegin()); aRectIter != rRectangles.rend(); aRectIter++)
         {
-            Rectangle aRect( Point( nX, nY ), Size( nWidth, nHeight ) );
-            aRegion.ImplAddRect( LogicToPixel( aRect ) );
-            bRegionRect = rLogicRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
+            aRegion.Union(LogicToPixel(*aRectIter));
         }
-        aRegion.ImplEndAddRect();
+
+        //long nX(0);
+        //long nY(0);
+        //long nWidth(0);
+        //long nHeight(0);
+        //ImplRegionInfo aInfo;
+        //aRegion.ImplBeginAddRect();
+        //bool bRegionRect(rLogicRegion.ImplGetFirstRect(aInfo, nX, nY, nWidth, nHeight));
+        //
+        //while(bRegionRect)
+        //{
+        //  const Rectangle aRect(Point(nX, nY), Size(nWidth, nHeight));
+        //  aRegion.ImplAddRect(LogicToPixel(aRect));
+        //  bRegionRect = rLogicRegion.ImplGetNextRect(aInfo, nX, nY, nWidth, nHeight);
+        //}
+        //
+        //aRegion.ImplEndAddRect();
     }
 
     return aRegion;
@@ -1295,6 +1317,27 @@ Polygon OutputDevice::LogicToPixel( const Polygon& rLogicPoly,
 
 // -----------------------------------------------------------------------
 
+PolyPolygon OutputDevice::LogicToPixel( const PolyPolygon& rLogicPolyPoly,
+    const MapMode& rMapMode ) const
+{
+    DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+    DBG_CHKOBJ( &rLogicPolyPoly, PolyPolygon, NULL );
+
+    if ( rMapMode.IsDefault() )
+        return rLogicPolyPoly;
+
+    PolyPolygon aPolyPoly( rLogicPolyPoly );
+    sal_uInt16              nPoly = aPolyPoly.Count();
+    for( sal_uInt16 i = 0; i < nPoly; i++ )
+    {
+        Polygon& rPoly = aPolyPoly[i];
+        rPoly = LogicToPixel( rPoly, rMapMode );
+    }
+    return aPolyPoly;
+}
+
+// -----------------------------------------------------------------------
+
 basegfx::B2DPolyPolygon OutputDevice::LogicToPixel( const basegfx::B2DPolyPolygon& rLogicPolyPoly,
                                                     const MapMode& rMapMode ) const
 {
@@ -1306,6 +1349,71 @@ basegfx::B2DPolyPolygon OutputDevice::LogicToPixel( const basegfx::B2DPolyPolygo
 
 // -----------------------------------------------------------------------
 
+basegfx::B2DPolygon OutputDevice::LogicToPixel( const basegfx::B2DPolygon& rLogicPoly,
+                                                const MapMode& rMapMode ) const
+{
+    basegfx::B2DPolygon aTransformedPoly = rLogicPoly;
+    const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetViewTransformation( rMapMode );
+    aTransformedPoly.transform( rTransformationMatrix );
+    return aTransformedPoly;
+}
+
+// -----------------------------------------------------------------------
+
+Region OutputDevice::LogicToPixel( const Region& rLogicRegion, const MapMode& rMapMode ) const
+{
+    DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+    if(rMapMode.IsDefault() || rLogicRegion.IsNull() || rLogicRegion.IsEmpty())
+    {
+        return rLogicRegion;
+    }
+
+    Region aRegion;
+
+    if(rLogicRegion.getB2DPolyPolygon())
+    {
+        aRegion = Region(LogicToPixel(*rLogicRegion.getB2DPolyPolygon(), rMapMode));
+    }
+    else if(rLogicRegion.getPolyPolygon())
+    {
+        aRegion = Region(LogicToPixel(*rLogicRegion.getPolyPolygon(), rMapMode));
+    }
+    else if(rLogicRegion.getRegionBand())
+    {
+        RectangleVector aRectangles;
+        rLogicRegion.GetRegionRectangles(aRectangles);
+        const RectangleVector& rRectangles(aRectangles); // needed to make the '!=' work
+
+        // make reverse run to fill new region bottom-up, this will speed it up due to the used data structuring
+        for(RectangleVector::const_reverse_iterator aRectIter(rRectangles.rbegin()); aRectIter != rRectangles.rend(); aRectIter++)
+        {
+            aRegion.Union(LogicToPixel(*aRectIter, rMapMode));
+        }
+
+        //long nX(0);
+        //long nY(0);
+        //long nWidth(0);
+        //long nHeight(0);
+        //ImplRegionInfo aInfo;
+        //aRegion.ImplBeginAddRect();
+        //bool bRegionRect(rLogicRegion.ImplGetFirstRect(aInfo, nX, nY, nWidth, nHeight));
+        //
+        //while(bRegionRect)
+        //{
+        //  const Rectangle aRect(Point(nX, nY), Size(nWidth, nHeight));
+        //  aRegion.ImplAddRect(LogicToPixel(aRect, rMapMode));
+        //  bRegionRect = rLogicRegion.ImplGetNextRect(aInfo, nX, nY, nWidth, nHeight);
+        //}
+        //
+        //aRegion.ImplEndAddRect();
+    }
+
+    return aRegion;
+}
+
+// -----------------------------------------------------------------------
+
 Point OutputDevice::PixelToLogic( const Point& rDevicePt ) const
 {
     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
@@ -1427,43 +1535,50 @@ basegfx::B2DPolyPolygon OutputDevice::PixelToLogic( const basegfx::B2DPolyPolygo
 Region OutputDevice::PixelToLogic( const Region& rDeviceRegion ) const
 {
     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
-    DBG_CHKOBJ( &rDeviceRegion, Region, ImplDbgTestRegion );
-
-    RegionType eType = rDeviceRegion.GetType();
 
-    if ( !mbMap || (eType == REGION_EMPTY) || (eType == REGION_NULL) )
+    if(!mbMap || rDeviceRegion.IsNull() || rDeviceRegion.IsEmpty())
+    {
         return rDeviceRegion;
+    }
 
-    Region          aRegion;
-    basegfx::B2DPolyPolygon* pB2DPolyPoly = rDeviceRegion.ImplGetImplRegion()->mpB2DPolyPoly;
-    PolyPolygon* pPolyPoly = pB2DPolyPoly ? 0 : rDeviceRegion.ImplGetImplRegion()->mpPolyPoly;
+    Region aRegion;
 
-    if ( pB2DPolyPoly ) // conversion with B2DPolyPolygon lost polygon-based ClipRegion
+    if(rDeviceRegion.getB2DPolyPolygon())
     {
-        aRegion = Region( PixelToLogic( *pB2DPolyPoly ) );
+        aRegion = Region(PixelToLogic(*rDeviceRegion.getB2DPolyPolygon()));
     }
-    else if ( pPolyPoly )
+    else if(rDeviceRegion.getPolyPolygon())
     {
-        aRegion = Region( PixelToLogic( *pPolyPoly ) );
+        aRegion = Region(PixelToLogic(*rDeviceRegion.getPolyPolygon()));
     }
-    else
+    else if(rDeviceRegion.getRegionBand())
     {
-        long                nX;
-        long                nY;
-        long                nWidth;
-        long                nHeight;
-        ImplRegionInfo      aInfo;
-        sal_Bool                bRegionRect;
+        RectangleVector aRectangles;
+        rDeviceRegion.GetRegionRectangles(aRectangles);
+        const RectangleVector& rRectangles(aRectangles); // needed to make the '!=' work
 
-        aRegion.ImplBeginAddRect();
-        bRegionRect = rDeviceRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
-        while ( bRegionRect )
+        // make reverse run to fill new region bottom-up, this will speed it up due to the used data structuring
+        for(RectangleVector::const_reverse_iterator aRectIter(rRectangles.rbegin()); aRectIter != rRectangles.rend(); aRectIter++)
         {
-            Rectangle aRect( Point( nX, nY ), Size( nWidth, nHeight ) );
-            aRegion.ImplAddRect( PixelToLogic( aRect ) );
-            bRegionRect = rDeviceRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
+            aRegion.Union(PixelToLogic(*aRectIter));
         }
-        aRegion.ImplEndAddRect();
+
+        //long nX(0);
+        //long nY(0);
+        //long nWidth(0);
+        //long nHeight(0);
+        //ImplRegionInfo aInfo;
+        //aRegion.ImplBeginAddRect();
+        //bool bRegionRect(rDeviceRegion.ImplGetFirstRect(aInfo, nX, nY, nWidth, nHeight));
+        //
+        //while(bRegionRect)
+        //{
+        //  const Rectangle aRect(Point(nX, nY), Size(nWidth, nHeight));
+        //  aRegion.ImplAddRect(PixelToLogic(aRect));
+        //  bRegionRect = rDeviceRegion.ImplGetNextRect(aInfo, nX, nY, nWidth, nHeight);
+        //}
+        //
+        //aRegion.ImplEndAddRect();
     }
 
     return aRegion;
@@ -1589,6 +1704,27 @@ Polygon OutputDevice::PixelToLogic( const Polygon& rDevicePoly,
 
 // -----------------------------------------------------------------------
 
+PolyPolygon OutputDevice::PixelToLogic( const PolyPolygon& rDevicePolyPoly,
+    const MapMode& rMapMode ) const
+{
+    DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+    DBG_CHKOBJ( &rDevicePolyPoly, PolyPolygon, NULL );
+
+    if ( rMapMode.IsDefault() )
+        return rDevicePolyPoly;
+
+    PolyPolygon aPolyPoly( rDevicePolyPoly );
+    sal_uInt16      nPoly = aPolyPoly.Count();
+    for( sal_uInt16 i = 0; i < nPoly; i++ )
+    {
+        Polygon& rPoly = aPolyPoly[i];
+        rPoly = PixelToLogic( rPoly, rMapMode );
+    }
+    return aPolyPoly;
+}
+
+// -----------------------------------------------------------------------
+
 basegfx::B2DPolygon OutputDevice::PixelToLogic( const basegfx::B2DPolygon& rPixelPoly,
                                                 const MapMode& rMapMode ) const
 {
@@ -1611,6 +1747,60 @@ basegfx::B2DPolyPolygon OutputDevice::PixelToLogic( const basegfx::B2DPolyPolygo
 
 // -----------------------------------------------------------------------
 
+Region OutputDevice::PixelToLogic( const Region& rDeviceRegion, const MapMode& rMapMode ) const
+{
+    DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
+
+    if(rMapMode.IsDefault() || rDeviceRegion.IsNull() || rDeviceRegion.IsEmpty())
+    {
+        return rDeviceRegion;
+    }
+
+    Region aRegion;
+
+    if(rDeviceRegion.getB2DPolyPolygon())
+    {
+        aRegion = Region(PixelToLogic(*rDeviceRegion.getB2DPolyPolygon(), rMapMode));
+    }
+    else if(rDeviceRegion.getPolyPolygon())
+    {
+        aRegion = Region(PixelToLogic(*rDeviceRegion.getPolyPolygon(), rMapMode));
+    }
+    else if(rDeviceRegion.getRegionBand())
+    {
+        RectangleVector aRectangles;
+        rDeviceRegion.GetRegionRectangles(aRectangles);
+        const RectangleVector& rRectangles(aRectangles); // needed to make the '!=' work
+
+        // make reverse run to fill new region bottom-up, this will speed it up due to the used data structuring

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list