[Libreoffice-commits] core.git: Branch 'libreoffice-4-4' - sw/inc sw/source

Michael Stahl mstahl at redhat.com
Sat Apr 11 13:23:18 PDT 2015


 sw/inc/IDocumentSettingAccess.hxx             |    2 
 sw/source/core/doc/DocumentSettingManager.cxx |    6 
 sw/source/core/doc/notxtfrm.cxx               |    3 
 sw/source/core/inc/DocumentSettingManager.hxx |    1 
 sw/source/core/inc/frmtool.hxx                |    3 
 sw/source/core/layout/paintfrm.cxx            |  430 +++++++++++++-------------
 sw/source/filter/xml/xmlimp.cxx               |    7 
 sw/source/uibase/uno/SwXDocumentSettings.cxx  |   19 +
 8 files changed, 264 insertions(+), 207 deletions(-)

New commits:
commit 312fc74f5bb49da4066ace46558179a03e164556
Author: Michael Stahl <mstahl at redhat.com>
Date:   Fri Apr 10 23:02:01 2015 +0200

    tdf#86578: sw: fix rendering of legacy documents with fly achored at fly
    
    Resurrect the special hack "lcl_SubtractFlys" that effectively paints
    "lower" flys on top of "higher" flys, defying the z-ordering, if the
    lower fly is *anchored* in or at the higher fly.
    
    It turns out that this is not obvious to emulate in any other way that it
    is currently implemented:
    
    One idea would be to split up painting of the fly background from the
    foreground, by creating 2 different view objects per fly as children
    of the SdrPage when decomposing it in svx; but the problem is, they will
    be ordered in z-order of the flys, and the point would be to paint the
    backgrounds first and in a different order, call it "anchoring order".
    
    What that order should be is hard to tell, there is a conflict between
    the defined z-order and the flys that are part of one "anchoring
    hierarchy" and should have their backgrounds re-ordered, because
    entirely unrelated flys that could belong to different "anchoring
    hierarchies" but overlap the first ones may result in a cyclic ordering.
    
    Painting one "anchoring hierarchy" recursively would not get
    z-order of flys from different anchoring hierarchies right.
    
    Another difficulty is that heaven-layer backgrounds would need to be
    painted before hell-layer ones.
    
    Another aspect of the lcl_SubtractFlys is that it entirely ignores
    drawing shapes; only Writer's own flys are handled.
    
    Since none of the above makes much sense, we clearly want to
    deprecate the lcl_SubtractFlys rendering.
    
    Introduce a new compatibility flag "SubtractFlysAnchoredAtFlys" so that
    the legacy rendering is only active for legacy documents, while new ones
    remain free from its taint.
    
    (regression from 6e61ecd09679a66060f932835622821d39e92f01)
    
    (cherry picked from commit c5cf8824a619401627f18abc7b3049551c71ac2a)
    
    Conflicts:
    	sw/inc/IDocumentSettingAccess.hxx
    	sw/source/core/doc/DocumentSettingManager.cxx
    	sw/source/core/layout/paintfrm.cxx
    
    Change-Id: I710fe79710b89c8f865ebb7162e14713aac6cc4a
    Reviewed-on: https://gerrit.libreoffice.org/15238
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/sw/inc/IDocumentSettingAccess.hxx b/sw/inc/IDocumentSettingAccess.hxx
index f0e941e..ba0508a 100644
--- a/sw/inc/IDocumentSettingAccess.hxx
+++ b/sw/inc/IDocumentSettingAccess.hxx
@@ -28,6 +28,7 @@
 class SvxForbiddenCharactersTable;
 namespace com { namespace sun { namespace star { namespace i18n { struct ForbiddenCharacters; } } } }
 
+
  /** Provides access to settings of a document
  */
  class IDocumentSettingAccess
@@ -80,6 +81,7 @@ namespace com { namespace sun { namespace star { namespace i18n { struct Forbidd
          // MS Word still wraps text around objects with less space than LO would.
          SURROUND_TEXT_WRAP_SMALL,
          PROP_LINE_SPACING_SHRINKS_FIRST_LINE,
+         SUBTRACT_FLYS,
          // COMPATIBILITY FLAGS END
 
          BROWSE_MODE,
diff --git a/sw/source/core/doc/DocumentSettingManager.cxx b/sw/source/core/doc/DocumentSettingManager.cxx
index 95dca59..e35e9ab 100644
--- a/sw/source/core/doc/DocumentSettingManager.cxx
+++ b/sw/source/core/doc/DocumentSettingManager.cxx
@@ -81,6 +81,7 @@ sw::DocumentSettingManager::DocumentSettingManager(SwDoc &rDoc)
     mbTabOverMargin(false),
     mbSurroundTextWrapSmall(false),
     mbPropLineSpacingShrinksFirstLine(true),
+    mbSubtractFlys(false),
     mApplyParagraphMarkFormatToNumbering(false),
     mbLastBrowseMode( false )
 
@@ -156,6 +157,7 @@ bool sw::DocumentSettingManager::get(/*[in]*/ DocumentSettingId id) const
         case TAB_OVER_MARGIN: return mbTabOverMargin;
         case SURROUND_TEXT_WRAP_SMALL: return mbSurroundTextWrapSmall;
         case PROP_LINE_SPACING_SHRINKS_FIRST_LINE: return mbPropLineSpacingShrinksFirstLine;
+        case SUBTRACT_FLYS: return mbSubtractFlys;
 
         case BROWSE_MODE: return mbLastBrowseMode; // Attention: normally the SwViewShell has to be asked!
         case HTML_MODE: return mbHTMLMode;
@@ -322,6 +324,10 @@ void sw::DocumentSettingManager::set(/*[in]*/ DocumentSettingId id, /*[in]*/ boo
             mbPropLineSpacingShrinksFirstLine = value;
             break;
 
+        case SUBTRACT_FLYS:
+            mbSubtractFlys = value;
+            break;
+
         // COMPATIBILITY FLAGS END
 
         case BROWSE_MODE: //can be used temporary (load/save) when no SwViewShell is available
diff --git a/sw/source/core/doc/notxtfrm.cxx b/sw/source/core/doc/notxtfrm.cxx
index 55c690b..aa0d2e1 100644
--- a/sw/source/core/doc/notxtfrm.cxx
+++ b/sw/source/core/doc/notxtfrm.cxx
@@ -190,7 +190,8 @@ static void lcl_ClearArea( const SwFrm &rFrm,
 
         if ( rFrm.GetBackgroundBrush( aFillAttributes, pItem, pCol, aOrigRect, false ) )
         {
-            const bool bDone(::DrawFillAttributes(aFillAttributes, aOrigRect, rPtArea, rOut));
+            SwRegionRects const region(rPtArea);
+            const bool bDone(::DrawFillAttributes(aFillAttributes, aOrigRect, region, rOut));
 
             if(!bDone)
             {
diff --git a/sw/source/core/inc/DocumentSettingManager.hxx b/sw/source/core/inc/DocumentSettingManager.hxx
index 4057b6f..853ad75 100644
--- a/sw/source/core/inc/DocumentSettingManager.hxx
+++ b/sw/source/core/inc/DocumentSettingManager.hxx
@@ -148,6 +148,7 @@ class DocumentSettingManager :
     bool mbTabOverMargin;
     bool mbSurroundTextWrapSmall;
     bool mbPropLineSpacingShrinksFirstLine; // fdo#79602
+    bool mbSubtractFlys; // tdf#86578
     bool mApplyParagraphMarkFormatToNumbering;
 
     bool mbLastBrowseMode                           : 1;
diff --git a/sw/source/core/inc/frmtool.hxx b/sw/source/core/inc/frmtool.hxx
index 04b7053..1d51315 100644
--- a/sw/source/core/inc/frmtool.hxx
+++ b/sw/source/core/inc/frmtool.hxx
@@ -45,6 +45,7 @@ class GraphicObject;
 class GraphicAttr;
 class SwPageDesc;
 class SwFrmFmts;
+class SwRegionRects;
 
 #define FAR_AWAY LONG_MAX - 20000  // initial position of a Fly
 #define BROWSE_HEIGHT 56700L * 10L // 10 Meters
@@ -68,7 +69,7 @@ void DrawGraphic(
 bool DrawFillAttributes(
     const drawinglayer::attribute::SdrAllFillAttributesHelperPtr& rFillAttributes,
     const SwRect& rOriginalLayoutRect,
-    const SwRect& rPaintRect,
+    const SwRegionRects& rPaintRegion,
     OutputDevice& rOut);
 
 void paintGraphicUsingPrimitivesHelper(
diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx
index 4371b04..5557de3 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -82,6 +82,7 @@
 #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
 #include <drawinglayer/primitive2d/borderlineprimitive2d.hxx>
 #include <drawinglayer/primitive2d/discreteshadowprimitive2d.hxx>
+#include <drawinglayer/primitive2d/maskprimitive2d.hxx>
 #include <drawinglayer/primitive2d/textprimitive2d.hxx>
 #include <drawinglayer/primitive2d/textlayoutdevice.hxx>
 #include <drawinglayer/processor2d/processorfromoutputdevice.hxx>
@@ -1526,172 +1527,168 @@ static void lcl_ExtendLeftAndRight( SwRect&                _rRect,
     }
 }
 
-//static void lcl_SubtractFlys( const SwFrm *pFrm, const SwPageFrm *pPage,
-//                           const SwRect &rRect, SwRegionRects &rRegion )
-//{
-//    const SwSortedObjs& rObjs = *pPage->GetSortedObjs();
-//    const SwFlyFrm* pSelfFly = pFrm->IsInFly() ? pFrm->FindFlyFrm() : gProp.pSRetoucheFly2;
-//    if ( !gProp.pSRetoucheFly )
-//        gProp.pSRetoucheFly = gProp.pSRetoucheFly2;
-//
-//    for ( sal_uInt16 j = 0; (j < rObjs.Count()) && !rRegion.empty(); ++j )
-//    {
-//        const SwAnchoredObject* pAnchoredObj = rObjs[j];
-//        const SdrObject* pSdrObj = pAnchoredObj->GetDrawObj();
-//
-//        // Do not consider invisible objects
-//        if ( !pPage->GetFmt()->GetDoc()->IsVisibleLayerId( pSdrObj->GetLayer() ) )
-//            continue;
-//
-//        if ( !pAnchoredObj->ISA(SwFlyFrm) )
-//            continue;
-//
-//        const SwFlyFrm *pFly = static_cast<const SwFlyFrm*>(pAnchoredObj);
-//
-//        if ( pSelfFly == pFly || gProp.pSRetoucheFly == pFly || !rRect.IsOver( pFly->Frm() ) )
-//            continue;
-//
-//        if ( !pFly->GetFmt()->GetPrint().GetValue() &&
-//                (OUTDEV_PRINTER == gProp.pSGlobalShell->GetOut()->GetOutDevType() ||
-//                gProp.pSGlobalShell->IsPreview()))
-//            continue;
-//
-//        const bool bLowerOfSelf = pSelfFly && pFly->IsLowerOf( pSelfFly );
-//
-//        //For character bound Flys only examine those Flys in which it is not
-//        //anchored itself.
-//        //Why only for character bound ones you may ask? It never makes sense to
-//        //subtract frames in which it is anchored itself right?
-//        if ( pSelfFly && pSelfFly->IsLowerOf( pFly ) )
-//            continue;
-//
-//        //Any why does it not apply for the RetoucheFly too?
-//        if ( gProp.pSRetoucheFly && gProp.pSRetoucheFly->IsLowerOf( pFly ) )
-//            continue;
-//
-//#if OSL_DEBUG_LEVEL > 0
-//        //Flys who are anchored inside their own one, must have a bigger OrdNum
-//        //or be character bound.
-//        if ( pSelfFly && bLowerOfSelf )
-//        {
-//            OSL_ENSURE( pFly->IsFlyInCntFrm() ||
-//                    pSdrObj->GetOrdNumDirect() > pSelfFly->GetVirtDrawObj()->GetOrdNumDirect(),
-//                    "Fly with wrong z-Order" );
-//        }
-//#endif
-//
-//        bool bStopOnHell = true;
-//        if ( pSelfFly )
-//        {
-//            const SdrObject *pTmp = pSelfFly->GetVirtDrawObj();
-//            if ( pSdrObj->GetLayer() == pTmp->GetLayer() )
-//            {
-//                if ( pSdrObj->GetOrdNumDirect() < pTmp->GetOrdNumDirect() )
-//                    //In the same layer we only observe those that are above.
-//                    continue;
-//            }
-//            else
-//            {
-//                if ( !bLowerOfSelf && !pFly->GetFmt()->GetOpaque().GetValue() )
-//                    //From other layers we are only interested in non
-//                    //transparent ones or those that are internal
-//                    continue;
-//                bStopOnHell = false;
-//            }
-//        }
-//        if ( gProp.pSRetoucheFly )
-//        {
-//            const SdrObject *pTmp = gProp.pSRetoucheFly->GetVirtDrawObj();
-//            if ( pSdrObj->GetLayer() == pTmp->GetLayer() )
-//            {
-//                if ( pSdrObj->GetOrdNumDirect() < pTmp->GetOrdNumDirect() )
-//                    //In the same layer we only observe those that are above.
-//                    continue;
-//            }
-//            else
-//            {
-//                if ( !pFly->IsLowerOf( gProp.pSRetoucheFly ) && !pFly->GetFmt()->GetOpaque().GetValue() )
-//                    //From other layers we are only interested in non
-//                    //transparent ones or those that are internal
-//                    continue;
-//                bStopOnHell = false;
-//            }
-//        }
-//
-//        //If the content of the Fly is transparent, we subtract it only if it's
-//        //contained in the hell layer.
-//        const IDocumentDrawModelAccess* pIDDMA = pFly->GetFmt()->getIDocumentDrawModelAccess();
-//        bool bHell = pSdrObj->GetLayer() == pIDDMA->GetHellId();
-//        if ( (bStopOnHell && bHell) ||
-//             /// Change internal order of condition
-//             ///    first check "!bHell", then "..->Lower()" and "..->IsNoTxtFrm()"
-//             ///    have not to be performed, if frame is in "Hell"
-//             ( !bHell && pFly->Lower() && pFly->Lower()->IsNoTxtFrm() &&
-//               ( ((SwNoTxtFrm*)pFly->Lower())->IsTransparent() ||
-//                 ((SwNoTxtFrm*)pFly->Lower())->HasAnimation() ||
-//                 pFly->GetFmt()->GetSurround().IsContour()
-//               )
-//             )
-//           )
-//            continue;
-//
-//        // Own if-statements for transparent background/shadow of fly frames
-//        // in order to handle special conditions.
-//        if ( pFly->IsBackgroundTransparent() )
-//        {
-//            // Background <pFly> is transparent drawn. Thus normally, its region
-//            // have not to be subtracted from given region.
-//            // But, if method is called for a fly frame and
-//            // <pFly> is a direct lower of this fly frame and
-//            // <pFly> inherites its transparent background brush from its parent,
-//            // then <pFly> frame area have to be subtracted from given region.
-//            // NOTE: Because in Status Quo transparent backgrounds can only be
-//            //     assigned to fly frames, the handle of this special case
-//            //     avoids drawing of transparent areas more than once, if
-//            //     a fly frame inherites a transparent background from its
-//            //     parent fly frame.
-//            if ( pFrm->IsFlyFrm() &&
-//                 (pFly->GetAnchorFrm()->FindFlyFrm() == pFrm) &&
-//                 static_cast<const SwFlyFrmFmt*>(pFly->GetFmt())->IsBackgroundBrushInherited()
-//               )
-//            {
-//                SwRect aRect;
-//                SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)pFly );
-//                const SwBorderAttrs &rAttrs = *aAccess.Get();
-//                ::lcl_CalcBorderRect( aRect, pFly, rAttrs, true );
-//                rRegion -= aRect;
-//                continue;
-//            }
-//            else
-//            {
-//                continue;
-//            }
-//        }
-//        if ( pFly->IsShadowTransparent() )
-//        {
-//            continue;
-//        }
-//
-//        if ( bHell && pFly->GetAnchorFrm()->IsInFly() )
-//        {
-//            //So the border won't get dismantled by the background of the other
-//            //Fly.
-//            SwRect aRect;
-//            SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)pFly );
-//            const SwBorderAttrs &rAttrs = *aAccess.Get();
-//            ::lcl_CalcBorderRect( aRect, pFly, rAttrs, true );
-//            rRegion -= aRect;
-//        }
-//        else
-//        {
-//            SwRect aRect( pFly->Prt() );
-//            aRect += pFly->Frm().Pos();
-//            rRegion -= aRect;
-//        }
-//    }
-//    if ( gProp.pSRetoucheFly == gProp.pSRetoucheFly2 )
-//        gProp.pSRetoucheFly = 0;
-//}
+static void lcl_SubtractFlys( const SwFrm *pFrm, const SwPageFrm *pPage,
+   const SwRect &rRect, SwRegionRects &rRegion)
+{
+    const SwSortedObjs& rObjs = *pPage->GetSortedObjs();
+    const SwFlyFrm* pSelfFly = pFrm->IsInFly() ? pFrm->FindFlyFrm() : gProp.pSRetoucheFly2;
+    if (!gProp.pSRetoucheFly)
+        gProp.pSRetoucheFly = gProp.pSRetoucheFly2;
+
+    for (size_t j = 0; (j < rObjs.size()) && !rRegion.empty(); ++j)
+    {
+        const SwAnchoredObject* pAnchoredObj = rObjs[j];
+        const SdrObject* pSdrObj = pAnchoredObj->GetDrawObj();
+
+        // Do not consider invisible objects
+        if (!pPage->GetFmt()->GetDoc()->getIDocumentDrawModelAccess().IsVisibleLayerId(pSdrObj->GetLayer()))
+            continue;
+
+        if (!pAnchoredObj->ISA(SwFlyFrm))
+            continue;
+
+        const SwFlyFrm *pFly = static_cast<const SwFlyFrm*>(pAnchoredObj);
+
+        if (pSelfFly == pFly || gProp.pSRetoucheFly == pFly || !rRect.IsOver(pFly->Frm()))
+            continue;
+
+        if (!pFly->GetFmt()->GetPrint().GetValue() &&
+                (OUTDEV_PRINTER == gProp.pSGlobalShell->GetOut()->GetOutDevType() ||
+                gProp.pSGlobalShell->IsPreview()))
+            continue;
+
+        const bool bLowerOfSelf = pSelfFly && pFly->IsLowerOf( pSelfFly );
+
+        //For character bound Flys only examine those Flys in which it is not
+        //anchored itself.
+        //Why only for character bound ones you may ask? It never makes sense to
+        //subtract frames in which it is anchored itself right?
+        if (pSelfFly && pSelfFly->IsLowerOf(pFly))
+            continue;
+
+        //Any why does it not apply for the RetoucheFly too?
+        if (gProp.pSRetoucheFly && gProp.pSRetoucheFly->IsLowerOf(pFly))
+            continue;
+
+#if OSL_DEBUG_LEVEL > 0
+        //Flys who are anchored inside their own one, must have a bigger OrdNum
+        //or be character bound.
+        if (pSelfFly && bLowerOfSelf)
+        {
+            OSL_ENSURE( pFly->IsFlyInCntFrm() ||
+                    pSdrObj->GetOrdNumDirect() > pSelfFly->GetVirtDrawObj()->GetOrdNumDirect(),
+                    "Fly with wrong z-Order" );
+        }
+#endif
+
+        bool bStopOnHell = true;
+        if (pSelfFly)
+        {
+            const SdrObject *pTmp = pSelfFly->GetVirtDrawObj();
+            if (pSdrObj->GetLayer() == pTmp->GetLayer())
+            {
+                if (pSdrObj->GetOrdNumDirect() < pTmp->GetOrdNumDirect())
+                    //In the same layer we only observe those that are above.
+                    continue;
+            }
+            else
+            {
+                if (!bLowerOfSelf && !pFly->GetFmt()->GetOpaque().GetValue())
+                    //From other layers we are only interested in non
+                    //transparent ones or those that are internal
+                    continue;
+                bStopOnHell = false;
+            }
+        }
+        if (gProp.pSRetoucheFly)
+        {
+            const SdrObject *pTmp = gProp.pSRetoucheFly->GetVirtDrawObj();
+            if ( pSdrObj->GetLayer() == pTmp->GetLayer() )
+            {
+                if ( pSdrObj->GetOrdNumDirect() < pTmp->GetOrdNumDirect() )
+                    //In the same layer we only observe those that are above.
+                    continue;
+            }
+            else
+            {
+                if (!pFly->IsLowerOf( gProp.pSRetoucheFly ) && !pFly->GetFmt()->GetOpaque().GetValue())
+                    //From other layers we are only interested in non
+                    //transparent ones or those that are internal
+                    continue;
+                bStopOnHell = false;
+            }
+        }
+
+        //If the content of the Fly is transparent, we subtract it only if it's
+        //contained in the hell layer.
+        const IDocumentDrawModelAccess* pIDDMA = pFly->GetFmt()->getIDocumentDrawModelAccess();
+        bool bHell = pSdrObj->GetLayer() == pIDDMA->GetHellId();
+        if ( (bStopOnHell && bHell) ||
+             /// Change internal order of condition
+             ///    first check "!bHell", then "..->Lower()" and "..->IsNoTxtFrm()"
+             ///    have not to be performed, if frame is in "Hell"
+             ( !bHell && pFly->Lower() && pFly->Lower()->IsNoTxtFrm() &&
+               (static_cast<SwNoTxtFrm const*>(pFly->Lower())->IsTransparent() ||
+                static_cast<SwNoTxtFrm const*>(pFly->Lower())->HasAnimation() ||
+                 pFly->GetFmt()->GetSurround().IsContour()
+               )
+             )
+           )
+            continue;
+
+        // Own if-statements for transparent background/shadow of fly frames
+        // in order to handle special conditions.
+        if (pFly->IsBackgroundTransparent())
+        {
+            // Background <pFly> is transparent drawn. Thus normally, its region
+            // have not to be subtracted from given region.
+            // But, if method is called for a fly frame and
+            // <pFly> is a direct lower of this fly frame and
+            // <pFly> inherites its transparent background brush from its parent,
+            // then <pFly> frame area have to be subtracted from given region.
+            // NOTE: Because in Status Quo transparent backgrounds can only be
+            //     assigned to fly frames, the handle of this special case
+            //     avoids drawing of transparent areas more than once, if
+            //     a fly frame inherites a transparent background from its
+            //     parent fly frame.
+            if (pFrm->IsFlyFrm() &&
+                (pFly->GetAnchorFrm()->FindFlyFrm() == pFrm) &&
+                static_cast<const SwFlyFrmFmt*>(pFly->GetFmt())->IsBackgroundBrushInherited()
+               )
+            {
+                SwRect aRect;
+                SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)pFly );
+                const SwBorderAttrs &rAttrs = *aAccess.Get();
+                ::lcl_CalcBorderRect( aRect, pFly, rAttrs, true );
+                rRegion -= aRect;
+                continue;
+            }
+            else
+            {
+                continue;
+            }
+        }
+
+        if (bHell && pFly->GetAnchorFrm()->IsInFly())
+        {
+            //So the border won't get dismantled by the background of the other
+            //Fly.
+            SwRect aRect;
+            SwBorderAttrAccess aAccess( SwFrm::GetCache(), (SwFrm*)pFly );
+            const SwBorderAttrs &rAttrs = *aAccess.Get();
+            ::lcl_CalcBorderRect( aRect, pFly, rAttrs, true );
+            rRegion -= aRect;
+        }
+        else
+        {
+            SwRect aRect( pFly->Prt() );
+            aRect += pFly->Frm().Pos();
+            rRegion -= aRect;
+        }
+    }
+    if (gProp.pSRetoucheFly == gProp.pSRetoucheFly2)
+        gProp.pSRetoucheFly = 0;
+}
 
 static void lcl_implDrawGraphicBackgrd( const SvxBrushItem& _rBackgrdBrush,
                                  OutputDevice* _pOut,
@@ -1850,16 +1847,16 @@ static void lcl_DrawGraphic( const SvxBrushItem& rBrush, OutputDevice *pOut,
 bool DrawFillAttributes(
     const drawinglayer::attribute::SdrAllFillAttributesHelperPtr& rFillAttributes,
     const SwRect& rOriginalLayoutRect,
-    const SwRect& rPaintRect,
+    const SwRegionRects& rPaintRegion,
     OutputDevice& rOut)
 {
     if(rFillAttributes.get() && rFillAttributes->isUsed())
     {
         basegfx::B2DRange aPaintRange(
-            rPaintRect.Left(),
-            rPaintRect.Top(),
-            rPaintRect.Right(),
-            rPaintRect.Bottom());
+            rPaintRegion.GetOrigin().Left(),
+            rPaintRegion.GetOrigin().Top(),
+            rPaintRegion.GetOrigin().Right(),
+            rPaintRegion.GetOrigin().Bottom());
 
         if(!aPaintRange.isEmpty() &&
             !basegfx::fTools::equalZero(aPaintRange.getWidth()) &&
@@ -1906,6 +1903,26 @@ bool DrawFillAttributes(
 
             if(rSequence.getLength())
             {
+                drawinglayer::primitive2d::Primitive2DSequence const*
+                    pPrimitives(&rSequence);
+                drawinglayer::primitive2d::Primitive2DSequence primitives;
+                // tdf#86578 the awful lcl_SubtractFlys hack
+                if (rPaintRegion.size() > 1 || rPaintRegion[0] != rPaintRegion.GetOrigin())
+                {
+                    tools::PolyPolygon tempRegion;
+                    for (size_t i = 0; i < rPaintRegion.size(); ++i)
+                    {
+                        tempRegion.Insert(Polygon(rPaintRegion[i].SVRect()));
+                    }
+                    basegfx::B2DPolyPolygon const maskRegion(
+                            tempRegion.getB2DPolyPolygon());
+                    primitives.realloc(1);
+                    primitives[0] = new drawinglayer::primitive2d::MaskPrimitive2D(
+                            maskRegion, rSequence);
+                    pPrimitives = &primitives;
+                }
+                assert(pPrimitives && pPrimitives->getLength());
+
                 const drawinglayer::geometry::ViewInformation2D aViewInformation2D(
                     basegfx::B2DHomMatrix(),
                     rOut.GetViewTransformation(),
@@ -1919,7 +1936,7 @@ bool DrawFillAttributes(
 
                 if(pProcessor)
                 {
-                    pProcessor->process(rSequence);
+                    pProcessor->process(*pPrimitives);
 
                     delete pProcessor;
 
@@ -4196,7 +4213,8 @@ void SwFlyFrm::Paint(SwRect const& rRect, SwPrintData const*const) const
         // parent fly frame area and the paint area <aRect>
         const IDocumentDrawModelAccess* pIDDMA = GetFmt()->getIDocumentDrawModelAccess();
 
-        if ( bIsGraphicTransparent &&
+        if (bIsGraphicTransparent &&
+            GetFmt()->GetDoc()->getIDocumentSettingAccess().get(IDocumentSettingAccess::SUBTRACT_FLYS) &&
             GetVirtDrawObj()->GetLayer() == pIDDMA->GetHellId() &&
             GetAnchorFrm()->FindFlyFrm() )
         {
@@ -4651,7 +4669,7 @@ void SwFrm::PaintShadow( const SwRect& rRect, SwRect& rOutRect,
 
 void SwFrm::PaintBorderLine( const SwRect& rRect,
                              const SwRect& rOutRect,
-                             const SwPageFrm * /*pPage*/,
+                             const SwPageFrm * pPage,
                              const Color *pColor,
                              const SvxBorderStyle nStyle ) const
 {
@@ -4671,14 +4689,15 @@ void SwFrm::PaintBorderLine( const SwRect& rRect,
         pColor = &SwViewOption::GetFontColor();
     }
 
-    //if ( pPage->GetSortedObjs() )
-    //{
-    //    SwRegionRects aRegion( aOut, 4 );
-    //    ::lcl_SubtractFlys( this, pPage, aOut, aRegion );
-    //    for ( size_t i = 0; i < aRegion.size(); ++i )
-    //        gProp.pSLines->AddLineRect( aRegion[i], pColor, nStyle, pTab, nSubCol );
-    //}
-    //else
+    if (pPage->GetSortedObjs() &&
+        pPage->GetFmt()->GetDoc()->getIDocumentSettingAccess().get(IDocumentSettingAccess::SUBTRACT_FLYS))
+    {
+        SwRegionRects aRegion( aOut, 4 );
+        ::lcl_SubtractFlys( this, pPage, aOut, aRegion );
+        for ( size_t i = 0; i < aRegion.size(); ++i )
+            gProp.pSLines->AddLineRect( aRegion[i], pColor, nStyle, pTab, nSubCol );
+    }
+    else
         gProp.pSLines->AddLineRect( aOut, pColor, nStyle, pTab, nSubCol );
 }
 
@@ -6563,7 +6582,6 @@ void SwFrm::PaintBackground( const SwRect &rRect, const SwPageFrm *pPage,
             if ( aRect.HasArea() )
             {
                 SvxBrushItem* pNewItem = 0;
-                //SwRegionRects aRegion( aRect );
 
                 if( pCol )
                 {
@@ -6574,10 +6592,12 @@ void SwFrm::PaintBackground( const SwRect &rRect, const SwPageFrm *pPage,
                     aFillAttributes.reset(new drawinglayer::attribute::SdrAllFillAttributesHelper(*pCol));
                 }
 
-                //if ( pPage->GetSortedObjs() )
-                //{
-                //    ::lcl_SubtractFlys( this, pPage, aRect, aRegion );
-                //}
+                SwRegionRects aRegion( aRect );
+                if (pPage->GetSortedObjs() &&
+                    pSh->GetDoc()->getIDocumentSettingAccess().get(IDocumentSettingAccess::SUBTRACT_FLYS))
+                {
+                    ::lcl_SubtractFlys( this, pPage, aRect, aRegion );
+                }
 
                 // OD 06.08.2002 #99657# - determine, if background transparency
                 //     have to be considered for drawing.
@@ -6593,7 +6613,7 @@ void SwFrm::PaintBackground( const SwRect &rRect, const SwPageFrm *pPage,
                     if(aFillAttributes->isUsed())
                     {
                         // check if really something is painted
-                        bDone = DrawFillAttributes(aFillAttributes, aOrigBackRect, aRect, *pOut);
+                        bDone = DrawFillAttributes(aFillAttributes, aOrigBackRect, aRegion, *pOut);
                     }
 
                     if(!bDone)
@@ -6613,27 +6633,27 @@ void SwFrm::PaintBackground( const SwRect &rRect, const SwPageFrm *pPage,
 
                 if(!bDone)
                 {
-                    //for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i )
-                    //{
-                    //    if ( 1 < aRegion.Count() )
-                    //    {
-                    //        ::SwAlignRect( aRegion[i], gProp.pSGlobalShell );
-                    //        if( !aRegion[i].HasArea() )
-                    //          continue;
-                    //    }
+                    for (size_t i = 0; i < aRegion.size(); ++i)
+                    {
+                        if (1 < aRegion.size())
+                        {
+                            ::SwAlignRect( aRegion[i], gProp.pSGlobalShell );
+                            if( !aRegion[i].HasArea() )
+                              continue;
+                        }
                     // OD 06.08.2002 #99657# - add 6th parameter to indicate, if
                     //     background transparency have to be considered
                     //     Set missing 5th parameter to the default value GRFNUM_NO
                     //         - see declaration in /core/inc/frmtool.hxx.
-                    if (IsTxtFrm() || !bOnlyTxtBackground)
-                        ::DrawGraphic(
-                            pItem,
-                            pOut,
-                            aOrigBackRect,
-                            aRect, // aRegion[i],
-                            GRFNUM_NO,
-                            bConsiderBackgroundTransparency );
-                    //}
+                        if (IsTxtFrm() || !bOnlyTxtBackground)
+                            ::DrawGraphic(
+                                pItem,
+                                pOut,
+                                aOrigBackRect,
+                                aRegion[i],
+                                GRFNUM_NO,
+                                bConsiderBackgroundTransparency );
+                    }
                 }
                 if( pCol )
                     delete pNewItem;
diff --git a/sw/source/filter/xml/xmlimp.cxx b/sw/source/filter/xml/xmlimp.cxx
index b5027d5..ee30818 100644
--- a/sw/source/filter/xml/xmlimp.cxx
+++ b/sw/source/filter/xml/xmlimp.cxx
@@ -1117,6 +1117,7 @@ void SwXMLImport::SetConfigurationSettings(const Sequence < PropertyValue > & aC
     aSet.insert("BackgroundParaOverDrawings");
     aSet.insert("TabOverMargin");
     aSet.insert("PropLineSpacingShrinksFirstLine");
+    aSet.insert("SubtractFlysAnchoredAtFlys");
 
     sal_Int32 nCount = aConfigProps.getLength();
     const PropertyValue* pValues = aConfigProps.getConstArray();
@@ -1152,6 +1153,7 @@ void SwXMLImport::SetConfigurationSettings(const Sequence < PropertyValue > & aC
     bool bBackgroundParaOverDrawings = false;
     bool bTabOverMargin = false;
     bool bPropLineSpacingShrinksFirstLine = false;
+    bool bSubtractFlysAnchoredAtFlys = false;
 
     const PropertyValue* currentDatabaseDataSource = NULL;
     const PropertyValue* currentDatabaseCommand = NULL;
@@ -1241,6 +1243,8 @@ void SwXMLImport::SetConfigurationSettings(const Sequence < PropertyValue > & aC
                     bTabOverMargin = true;
                 else if ( pValues->Name == "PropLineSpacingShrinksFirstLine" )
                     bPropLineSpacingShrinksFirstLine = true;
+                else if (pValues->Name == "SubtractFlysAnchoredAtFlys")
+                    bSubtractFlysAnchoredAtFlys = true;
             }
             catch( Exception& )
             {
@@ -1419,6 +1423,9 @@ void SwXMLImport::SetConfigurationSettings(const Sequence < PropertyValue > & aC
     if (!bPropLineSpacingShrinksFirstLine)
         xProps->setPropertyValue("PropLineSpacingShrinksFirstLine", makeAny(false));
 
+    if (!bSubtractFlysAnchoredAtFlys)
+        xProps->setPropertyValue("SubtractFlysAnchoredAtFlys", makeAny(true));
+
     SwDoc *pDoc = getDoc();
     SfxPrinter *pPrinter = pDoc->getIDocumentDeviceAccess().getPrinter( false );
     if( pPrinter )
diff --git a/sw/source/uibase/uno/SwXDocumentSettings.cxx b/sw/source/uibase/uno/SwXDocumentSettings.cxx
index aceed1f..33def9c 100644
--- a/sw/source/uibase/uno/SwXDocumentSettings.cxx
+++ b/sw/source/uibase/uno/SwXDocumentSettings.cxx
@@ -128,6 +128,7 @@ enum SwDocumentSettingsPropertyHandles
     HANDLE_SURROUND_TEXT_WRAP_SMALL,
     HANDLE_APPLY_PARAGRAPH_MARK_FORMAT_TO_NUMBERING,
     HANDLE_PROP_LINE_SPACING_SHRINKS_FIRST_LINE,
+    HANDLE_SUBTRACT_FLYS,
 };
 
 static MasterPropertySetInfo * lcl_createSettingsInfo()
@@ -200,6 +201,7 @@ static MasterPropertySetInfo * lcl_createSettingsInfo()
         { OUString("SurroundTextWrapSmall"), HANDLE_SURROUND_TEXT_WRAP_SMALL, cppu::UnoType<bool>::get(), 0, 0},
         { OUString("ApplyParagraphMarkFormatToNumbering"), HANDLE_APPLY_PARAGRAPH_MARK_FORMAT_TO_NUMBERING, cppu::UnoType<bool>::get(), 0, 0},
         { OUString("PropLineSpacingShrinksFirstLine"),       HANDLE_PROP_LINE_SPACING_SHRINKS_FIRST_LINE,         cppu::UnoType<bool>::get(),           0,   0},
+        { OUString("SubtractFlysAnchoredAtFlys"),       HANDLE_SUBTRACT_FLYS,         cppu::UnoType<bool>::get(),           0,   0},
 /*
  * As OS said, we don't have a view when we need to set this, so I have to
  * find another solution before adding them to this property set - MTG
@@ -817,6 +819,16 @@ void SwXDocumentSettings::_setSingleValue( const comphelper::PropertyInfo & rInf
             }
         }
         break;
+        case HANDLE_SUBTRACT_FLYS:
+        {
+            bool bTmp;
+            if (rValue >>= bTmp)
+            {
+                mpDoc->getIDocumentSettingAccess().set(
+                    IDocumentSettingAccess::SUBTRACT_FLYS, bTmp);
+            }
+        }
+        break;
         default:
             throw UnknownPropertyException();
     }
@@ -1253,6 +1265,13 @@ void SwXDocumentSettings::_getSingleValue( const comphelper::PropertyInfo & rInf
             rValue <<= bTmp;
         }
         break;
+        case HANDLE_SUBTRACT_FLYS:
+        {
+            bool const bTmp(mpDoc->getIDocumentSettingAccess().get(
+                IDocumentSettingAccess::SUBTRACT_FLYS));
+            rValue <<= bTmp;
+        }
+        break;
         default:
             throw UnknownPropertyException();
     }


More information about the Libreoffice-commits mailing list