Resolves: fdo#81598 #i125300# enhanced handling of multiple ClipRegions...

in MetafileProcessor

(cherry picked from commit 02e2c7b225036c6478a1f7e8315a9c8361025a7f)

Change-Id: Iefefc36c040507795bc2c25fe8d4a610eb12adb9
diff --git a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
index d6e1e7a..e592f9c 100644
--- a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
@@ -1765,17 +1765,52 @@ namespace drawinglayer

                            if(maClipPolyPolygon.count())
                            {
                                // there is already a clip polygon set; build clipped union of
                                // current mask polygon and new one
                                maClipPolyPolygon = basegfx::tools::clipPolyPolygonOnPolyPolygon(
                                    aMask,
                                    maClipPolyPolygon,
                                    true, // #i106516# we want the inside of aMask, not the outside
                                    false);
                                // due to the cost of PolyPolygon clipping and numerical reasons try first if the current
                                // and the new ClipRegion are ranges. If yes, processing can be simplified
                                if(basegfx::tools::isRectangle(aMask)
                                    && basegfx::tools::isRectangle(maClipPolyPolygon))
                                {
                                    // both ClipPolygons are rectangles
                                    if(aMask.getB2DRange().equal(maClipPolyPolygon.getB2DRange()))
                                    {
                                        // equal -> no change in ClipRegion needed, leave
                                        // maClipPolyPolygon unchanged
                                    }
                                    else
                                    {
                                        // not equal -> create new ClipRegion from the two ranges
                                        basegfx::B2DRange aClipRange(aMask.getB2DRange());

                                        aClipRange.intersect(maClipPolyPolygon.getB2DRange());

                                        if(aClipRange.isEmpty())
                                        {
                                            // no common ClipRegion -> set empty ClipRegion, no content to show
                                            maClipPolyPolygon.clear();
                                        }
                                        else
                                        {
                                            // use common ClipRegion as new ClipRegion
                                            maClipPolyPolygon = basegfx::B2DPolyPolygon(
                                                basegfx::tools::createPolygonFromRect(aClipRange));
                                        }
                                    }
                                }
                                else
                                {
                                    // The current ClipRegion or the new one is not a rectangle;
                                    // there is already a clip polygon set; build clipped union of
                                    // current mask polygon and new one
                                    maClipPolyPolygon = basegfx::tools::clipPolyPolygonOnPolyPolygon(
                                        aMask,
                                        maClipPolyPolygon,
                                        true, // #i106516# we want the inside of aMask, not the outside
                                        false);
                                }
                            }
                            else
                            {
                                // use mask directly
                                // use new mask directly as ClipRegion
                                maClipPolyPolygon = aMask;
                            }

@@ -1784,8 +1819,13 @@ namespace drawinglayer
                                // set VCL clip region; subdivide before conversion to tools polygon. Subdivision necessary (!)
                                // Removed subdivision and fixed in Region::ImplPolyPolyRegionToBandRegionFunc() in VCL where
                                // the ClipRegion is built from the Polygon. A AdaptiveSubdivide on the source polygon was missing there
                                mpOutputDevice->Push(PUSH_CLIPREGION);
                                mpOutputDevice->SetClipRegion(Region(maClipPolyPolygon));
                                const bool bNewClipRegion(maClipPolyPolygon != aLastClipPolyPolygon);

                                if(bNewClipRegion)
                                {
                                    mpOutputDevice->Push(PUSH_CLIPREGION);
                                    mpOutputDevice->SetClipRegion(Region(maClipPolyPolygon));
                                }

                                // recursively paint content
                                // #i121267# Only need to process sub-content when clip polygon is *not* empty.
@@ -1793,7 +1833,10 @@ namespace drawinglayer
                                process(rMaskCandidate.getChildren());

                                // restore VCL clip region
                                mpOutputDevice->Pop();
                                if(bNewClipRegion)
                                {
                                    mpOutputDevice->Pop();
                                }
                            }

                            // restore to rescued clip polygon