[Libreoffice-commits] core.git: Branch 'feature/borderline' - 248 commits - accessibility/inc accessibility/source android/source basctl/source basegfx/source basic/source bin/findunusedcode bin/gbuild-to-ide bin/gbuild-to-ideNS bridges/source canvas/source chart2/qa chart2/source codemaker/source comphelper/source compilerplugins/clang configmgr/source configure.ac connectivity/source cppcanvas/source cppuhelper/source cppu/source cui/Library_cui.mk cui/source dbaccess/source desktop/source download.lst drawinglayer/Library_drawinglayer.mk drawinglayer/qa drawinglayer/source dtrans/source editeng/CppunitTest_editeng_core.mk editeng/inc editeng/qa editeng/source embeddedobj/source extensions/source extensions/uiconfig external/boost external/fontconfig external/graphite external/libxmlsec extras/source filter/qa filter/source forms/source formula/source fpicker/source framework/source helpcontent2 hwpfilter/source i18nlangtag/source i18npool/source i18nutil/source icon-themes/breeze icon-themes/g alaxy idlc/source idl/source include/comphelper include/cppcanvas include/drawinglayer include/editeng include/filter include/formula include/o3tl include/oox include/sax include/sfx2 include/svl include/svtools include/svx include/test include/tools include/unotools include/vcl include/xmloff io/source jvmfwk/source l10ntools/source libreofficekit/source lingucomponent/source linguistic/source lotuswordpro/source Makefile.in mysqlc/source offapi/com officecfg/registry oox/source package/source qadevOOo/Jar_OOoRunner.mk qadevOOo/objdsc qadevOOo/tests registry/source reportbuilder/java reportdesign/inc reportdesign/source rsc/source sal/osl sal/qa sal/rtl sal/textenc sax/qa sax/source scaddins/source sc/inc

Armin Le Grand Armin.Le.Grand at cib.de
Wed Jul 12 16:03:04 UTC 2017


Rebased ref, commits from common ancestor:
commit a8eb5d7175129d4dc9c12b83366b6b01ef6726b7
Author: Armin Le Grand <Armin.Le.Grand at cib.de>
Date:   Wed Jul 12 11:30:36 2017 +0200

    borderline: adapt cppunittest and clang
    
    Change-Id: Ib4eb28dc86ce05eb89b26517167305b994158ef8

diff --git a/drawinglayer/qa/unit/border.cxx b/drawinglayer/qa/unit/border.cxx
index 25264c46ee51..ce99965b13f9 100644
--- a/drawinglayer/qa/unit/border.cxx
+++ b/drawinglayer/qa/unit/border.cxx
@@ -17,6 +17,7 @@
 #include <drawinglayer/geometry/viewinformation2d.hxx>
 #include <drawinglayer/primitive2d/borderlineprimitive2d.hxx>
 #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
+#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
 #include <drawinglayer/processor2d/baseprocessor2d.hxx>
 #include <drawinglayer/processor2d/processorfromoutputdevice.hxx>
 #include <rtl/ref.hxx>
@@ -70,17 +71,15 @@ void DrawinglayerBorderTest::testDoubleDecompositionSolid()
     // Make sure it results in two borders as it's a double one.
     CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(2), aContainer.size());
 
-    // Get the inside line.
-    auto pInside = dynamic_cast<const drawinglayer::primitive2d::PolyPolygonColorPrimitive2D*>(aContainer[0].get());
+    // Get the inside line, now a PolygonStrokePrimitive2D
+    auto pInside = dynamic_cast<const drawinglayer::primitive2d::PolygonStrokePrimitive2D*>(aContainer[0].get());
     CPPUNIT_ASSERT(pInside);
 
     // Make sure the inside line's height is fLeftWidth.
-    const basegfx::B2DPolyPolygon& rPolyPolygon = pInside->getB2DPolyPolygon();
-    CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(1), rPolyPolygon.count());
-    const basegfx::B2DPolygon& rPolygon = rPolyPolygon.getB2DPolygon(0);
-    const basegfx::B2DRange& rRange = rPolygon.getB2DRange();
+    const double fLineWidthFromDecompose = pInside->getLineAttribute().getWidth();
+
     // This was 2.47, i.e. the width of the inner line was 1 unit (in the bugdoc's case: 1 pixel) wider than expected.
-    CPPUNIT_ASSERT_DOUBLES_EQUAL(fLeftWidth, rRange.getHeight(), basegfx::fTools::getSmallValue());
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(fLeftWidth, fLineWidthFromDecompose, basegfx::fTools::getSmallValue());
 }
 
 void DrawinglayerBorderTest::testDoublePixelProcessing()
@@ -100,7 +99,7 @@ void DrawinglayerBorderTest::testDoublePixelProcessing()
     basegfx::B2DPoint aEnd(100, 20);
     double const fLeftWidth = 1.47;
     double const fDistance = 1.47;
-    double fRightWidth = 1.47;
+    double const fRightWidth = 1.47;
     double const fExtendLeftStart = 0;
     double const fExtendLeftEnd = 0;
     double const fExtendRightStart = 0;
@@ -117,31 +116,33 @@ void DrawinglayerBorderTest::testDoublePixelProcessing()
     // Process the primitives.
     pProcessor->process(aPrimitives);
 
-    // Now assert the height of the outer (second) border polygon.
+    // Double line now gets decomposed in Metafile to painting four lines
+    // with width == 0 in a cross pattern due to real line width being between
+    // 1.0 and 2.0. Count created lines
     aMetaFile.Stop();
     aMetaFile.WindStart();
-    bool bFirst = true;
-    sal_Int32 nHeight = 0;
+    sal_uInt32 nPolyLineActionCount = 0;
+
     for (std::size_t nAction = 0; nAction < aMetaFile.GetActionSize(); ++nAction)
     {
         MetaAction* pAction = aMetaFile.GetAction(nAction);
-        if (pAction->GetType() == MetaActionType::POLYPOLYGON)
+
+        if (MetaActionType::POLYLINE == pAction->GetType())
         {
-            if (bFirst)
+            auto pMPLAction = static_cast<MetaPolyLineAction*>(pAction);
+
+            if (0 == pMPLAction->GetLineInfo().GetWidth() && LineStyle::Solid == pMPLAction->GetLineInfo().GetStyle())
             {
-                bFirst = false;
-                continue;
+                nPolyLineActionCount++;
             }
-
-            auto pMPPAction = static_cast<MetaPolyPolygonAction*>(pAction);
-            const tools::PolyPolygon& rPolyPolygon = pMPPAction->GetPolyPolygon();
-            nHeight = rPolyPolygon.GetBoundRect().getHeight();
         }
     }
-    sal_Int32 nExpectedHeight = std::round(fRightWidth);
-    // This was 2, and should be 1: if the logical requested width is 1.47,
-    // then that must be 1 px on the screen, not 2.
-    CPPUNIT_ASSERT_EQUAL(nExpectedHeight, nHeight);
+
+    // Check if all eight (2x four) simple lines with width == 0 and
+    // solid were created
+    const sal_uInt32 nExpectedNumPolyLineActions = 8;
+
+    CPPUNIT_ASSERT_EQUAL(nExpectedNumPolyLineActions, nPolyLineActionCount);
 }
 
 CPPUNIT_TEST_SUITE_REGISTRATION(DrawinglayerBorderTest);
diff --git a/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
index f9a3ce78f468..9735cc1aa44d 100644
--- a/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
@@ -257,7 +257,7 @@ namespace drawinglayer
                 // do this when 'double line with gap')
                 const double fNewDiscreteDistance(std::max(fDiscreteUnit, getDistance()));
 
-                if (fNewDiscreteDistance != mfDiscreteDistance)
+                if (!rtl::math::approxEqual(fNewDiscreteDistance, mfDiscreteDistance))
                 {
                     if (!getBuffered2DDecomposition().empty())
                     {
diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
index ebb0df14ca38..a93f85df4595 100644
--- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
@@ -70,34 +70,6 @@ T round(T x)
 
 using namespace com::sun::star;
 
-namespace {
-
-basegfx::B2DPolygon makeRectPolygon( double fX, double fY, double fW, double fH )
-{
-    basegfx::B2DPolygon aPoly;
-    aPoly.append(basegfx::B2DPoint(fX, fY));
-    aPoly.append(basegfx::B2DPoint(fX+fW, fY));
-    aPoly.append(basegfx::B2DPoint(fX+fW, fY+fH));
-    aPoly.append(basegfx::B2DPoint(fX, fY+fH));
-    aPoly.setClosed(true);
-    return aPoly;
-}
-
-void drawHairLine(
-    OutputDevice* pOutDev, double fX1, double fY1, double fX2, double fY2,
-    const basegfx::BColor& rColor )
-{
-    basegfx::B2DPolygon aTarget;
-    aTarget.append(basegfx::B2DPoint(fX1, fY1));
-    aTarget.append(basegfx::B2DPoint(fX2, fY2));
-
-    pOutDev->SetFillColor();
-    pOutDev->SetLineColor(Color(rColor));
-    pOutDev->DrawPolyLine(aTarget);
-}
-
-}
-
 namespace drawinglayer
 {
     namespace processor2d
commit fb6bde99f438c2d6c1ebe32c83f92c08f2d6a028
Author: Armin Le Grand <Armin.Le.Grand at cib.de>
Date:   Fri Jul 7 13:32:45 2017 +0200

    borderline: correct line dash visualization
    
    When a dashed line is used, a factor of 10.0 was applied in the
    original coded, added that. Also the orientation of vertical
    borders was inverted since it was simpler to exchange Start/End,
    but this also mirrors the line dash visualisation, corrected that
    
    Change-Id: I77418cc6c84ebb0632f8c3448976e82ce612d6b6

diff --git a/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
index 2bb7eb869289..f9a3ce78f468 100644
--- a/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
@@ -62,7 +62,7 @@ namespace drawinglayer
             aPolygon.append(rEnd);
 
             const attribute::LineAttribute aLineAttribute(rColor, fWidth);
-            static double fPatScFact(1.0); // 10.0 multiply, see old code
+            static double fPatScFact(10.0); // 10.0 multiply, see old code
             const std::vector<double> aDashing(svtools::GetLineDashing(aStyle, fPatternScale * fPatScFact));
 
             if (aDashing.empty())
diff --git a/svx/source/dialog/framelinkarray.cxx b/svx/source/dialog/framelinkarray.cxx
index 1b3406eafcdf..24f432e3b97d 100644
--- a/svx/source/dialog/framelinkarray.cxx
+++ b/svx/source/dialog/framelinkarray.cxx
@@ -1005,9 +1005,20 @@ void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D& rProcessor,
                     drawinglayer::primitive2d::Primitive2DContainer aSequence(1);
                     aSequence.append(
                         CreateBorderPrimitives(
-                            aStartPos, aEndPos, *pStart,
-                            aStartLFromTR, *pStartLFromT, *pStartLFromL, *pStartLFromB, aStartLFromBR,
-                            aEndRFromTL, *pEndRFromT, *pEndRFromR, *pEndRFromB, aEndRFromBL, pForceColor));
+                            aStartPos,
+                            aEndPos,
+                            *pStart,
+                            aStartLFromTR,
+                            *pStartLFromT,
+                            *pStartLFromL,
+                            *pStartLFromB,
+                            aStartLFromBR,
+                            aEndRFromTL,
+                            *pEndRFromT,
+                            *pEndRFromR,
+                            *pEndRFromB,
+                            aEndRFromBL,
+                            pForceColor));
                     rProcessor.process(aSequence);
                 }
 
@@ -1036,9 +1047,20 @@ void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D& rProcessor,
             drawinglayer::primitive2d::Primitive2DContainer aSequence(1);
             aSequence.append(
                 CreateBorderPrimitives(
-                    aStartPos, aEndPos, *pStart,
-                    aStartLFromTR, *pStartLFromT, *pStartLFromL, *pStartLFromB, aStartLFromBR,
-                    aEndRFromTL, *pEndRFromT, *pEndRFromR, *pEndRFromB, aEndRFromBL, pForceColor));
+                    aStartPos,
+                    aEndPos,
+                    *pStart,
+                    aStartLFromTR,
+                    *pStartLFromT,
+                    *pStartLFromL,
+                    *pStartLFromB,
+                    aStartLFromBR,
+                    aEndRFromTL,
+                    *pEndRFromT,
+                    *pEndRFromR,
+                    *pEndRFromB,
+                    aEndRFromBL,
+                    pForceColor));
             rProcessor.process(aSequence);
         }
     }
@@ -1095,9 +1117,28 @@ void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D& rProcessor,
                     drawinglayer::primitive2d::Primitive2DContainer aSequence(1);
                     aSequence.append(
                         CreateBorderPrimitives(
-                            aEndPos, aStartPos, *pStart,
-                            aEndBFromTL, *pEndBFromL, *pEndBFromB, *pEndBFromR, aEndBFromTR,
-                            aStartTFromBL, *pStartTFromL, *pStartTFromT, *pStartTFromR, aStartTFromBR, pForceColor));
+                            // This replaces DrawVerFrameBorder which went from top to bottom. To be able to use
+                            // the same method as for horizontal (CreateBorderPrimitives), the given borders
+                            // have to be rearranged. Best is to look at the explanations of parameters in
+                            // framelink.hxx and the former calls to DrawVerFrameBorder and it's parameters.
+                            // In principle, the order of the five TFrom and BFrom has to be
+                            // inverted to get the same orientation. Before, EndPos and StartPos were changed
+                            // which avoids the reordering, but also leads to inverted line patters for vertical
+                            // lines
+                            aStartPos,
+                            aEndPos,
+                            *pStart,
+                            aStartTFromBR,
+                            *pStartTFromR,
+                            *pStartTFromT,
+                            *pStartTFromL,
+                            aStartTFromBL,
+                            aEndBFromTR,
+                            *pEndBFromR,
+                            *pEndBFromB,
+                            *pEndBFromL,
+                            aEndBFromTL,
+                            pForceColor));
                     rProcessor.process(aSequence);
                 }
 
@@ -1125,9 +1166,22 @@ void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D& rProcessor,
         {
             drawinglayer::primitive2d::Primitive2DContainer aSequence(1);
             aSequence.append(
-                CreateBorderPrimitives(aEndPos, aStartPos, *pStart,
-                    aEndBFromTL, *pEndBFromL, *pEndBFromB, *pEndBFromR, aEndBFromTR,
-                    aStartTFromBL, *pStartTFromL, *pStartTFromT, *pStartTFromR, aStartTFromBR, pForceColor));
+                CreateBorderPrimitives(
+                    // also reordered, see call to CreateBorderPrimitives above
+                    aStartPos,
+                    aEndPos,
+                    *pStart,
+                    aStartTFromBR,
+                    *pStartTFromR,
+                    *pStartTFromT,
+                    *pStartTFromL,
+                    aStartTFromBL,
+                    aEndBFromTR,
+                    *pEndBFromR,
+                    *pEndBFromB,
+                    *pEndBFromL,
+                    aEndBFromTL,
+                    pForceColor));
             rProcessor.process(aSequence);
         }
     }
commit b82ef4d78c925cca4bb8c36ba7bc994397cb4579
Author: Armin Le Grand <Armin.Le.Grand at cib.de>
Date:   Thu Jul 6 17:29:12 2017 +0200

    borderline: Adapted previews to primitives
    
    Added code to use the primitive representation in
    all dialogs and apps using tables. The edit views
    use these mostly, so the preview should do that,
    too. Currently missing is a good visualization of
    diagonals, but this is also true for edit views.
    Checked all apps and table usages to not get worse
    
    Change-Id: I62369b4de58fb0264aeb710ec6983ceddca5701d

diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
index eb477f4aed16..ebb0df14ca38 100644
--- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
@@ -919,7 +919,10 @@ namespace drawinglayer
                 case PRIMITIVE2D_ID_BORDERLINEPRIMITIVE2D:
                 {
                     // process recursively, but switch off AntiAliasing for
-                    // horizontal/vertical lines (*not* diagonal lines)
+                    // horizontal/vertical lines (*not* diagonal lines).
+                    // Checked using AntialiasingFlags::PixelSnapHairline instead,
+                    // but with AntiAliasing on the display really is too 'ghosty' when
+                    // using fine stroking. Correct, but 'ghosty'.
                     const drawinglayer::primitive2d::BorderLinePrimitive2D& rBorder =
                         static_cast<const drawinglayer::primitive2d::BorderLinePrimitive2D&>(rCandidate);
 
diff --git a/include/svx/framelinkarray.hxx b/include/svx/framelinkarray.hxx
index a899caa7ee40..9208f67b46ae 100644
--- a/include/svx/framelinkarray.hxx
+++ b/include/svx/framelinkarray.hxx
@@ -331,7 +331,7 @@ public:
     /** Draws the part of the specified range, that is inside the clipping range.
         @param pForceColor
             If not NULL, only this color will be used to draw all frame borders. */
-    void                DrawRange( drawinglayer::processor2d::BaseProcessor2D* rDev,
+    void                DrawRange( drawinglayer::processor2d::BaseProcessor2D& rProcessor,
                             size_t nFirstCol, size_t nFirstRow,
                             size_t nLastCol, size_t nLastRow,
                             const Color* pForceColor ) const;
@@ -344,7 +344,10 @@ public:
                             size_t nLastCol, size_t nLastRow ) const;
 
     /** Draws the part of the array, that is inside the clipping range. */
-    void                DrawArray( OutputDevice& rDev ) const;
+    void                DrawArray(OutputDevice& rDev) const;
+
+    /** Draws the part of the array, that is inside the clipping range. */
+    void                DrawArray(drawinglayer::processor2d::BaseProcessor2D& rProcessor) const;
 
 
 private:
diff --git a/sc/source/ui/view/output.cxx b/sc/source/ui/view/output.cxx
index 059ed109c862..8c656ca45bb7 100644
--- a/sc/source/ui/view/output.cxx
+++ b/sc/source/ui/view/output.cxx
@@ -1458,7 +1458,7 @@ void ScOutputData::DrawFrame(vcl::RenderContext& rRenderContext)
         {
             size_t nRow2 = nRow1;
             while( (nRow2 + 1 <= nLastRow) && pRowInfo[ nRow2 + 1 ].bChanged ) ++nRow2;
-            rArray.DrawRange( pProcessor.get(), nFirstCol, nRow1, nLastCol, nRow2, pForceColor );
+            rArray.DrawRange( *pProcessor.get(), nFirstCol, nRow1, nLastCol, nRow2, pForceColor );
             nRow1 = nRow2 + 1;
         }
     }
diff --git a/svx/source/dialog/framelinkarray.cxx b/svx/source/dialog/framelinkarray.cxx
index dd30b93f6074..1b3406eafcdf 100644
--- a/svx/source/dialog/framelinkarray.cxx
+++ b/svx/source/dialog/framelinkarray.cxx
@@ -879,7 +879,7 @@ void Array::MirrorSelfX()
 }
 
 // drawing
-void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D* pProcessor,
+void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D& rProcessor,
         size_t nFirstCol, size_t nFirstRow, size_t nLastCol, size_t nLastRow,
         const Color* pForceColor ) const
 {
@@ -925,7 +925,7 @@ void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D* pProcessor,
                                 aTlbrStyle.UseGapColor(),
                                 aTlbrStyle.Type(),
                                 aTlbrStyle.PatternScale()));
-                        pProcessor->process(aSequence);
+                        rProcessor.process(aSequence);
                     }
 
                     const Style aBltrStyle = GetCellStyleBLTR( _nFirstCol, _nFirstRow );
@@ -946,7 +946,7 @@ void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D* pProcessor,
                                 aBltrStyle.UseGapColor(),
                                 aBltrStyle.Type(),
                                 aBltrStyle.PatternScale()));
-                        pProcessor->process(aSequence);
+                        rProcessor.process(aSequence);
                     }
                 }
             }
@@ -1008,7 +1008,7 @@ void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D* pProcessor,
                             aStartPos, aEndPos, *pStart,
                             aStartLFromTR, *pStartLFromT, *pStartLFromL, *pStartLFromB, aStartLFromBR,
                             aEndRFromTL, *pEndRFromT, *pEndRFromR, *pEndRFromB, aEndRFromBL, pForceColor));
-                    pProcessor->process(aSequence);
+                    rProcessor.process(aSequence);
                 }
 
                 // re-init "*Start***" variables
@@ -1039,7 +1039,7 @@ void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D* pProcessor,
                     aStartPos, aEndPos, *pStart,
                     aStartLFromTR, *pStartLFromT, *pStartLFromL, *pStartLFromB, aStartLFromBR,
                     aEndRFromTL, *pEndRFromT, *pEndRFromR, *pEndRFromB, aEndRFromBL, pForceColor));
-            pProcessor->process(aSequence);
+            rProcessor.process(aSequence);
         }
     }
 
@@ -1098,7 +1098,7 @@ void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D* pProcessor,
                             aEndPos, aStartPos, *pStart,
                             aEndBFromTL, *pEndBFromL, *pEndBFromB, *pEndBFromR, aEndBFromTR,
                             aStartTFromBL, *pStartTFromL, *pStartTFromT, *pStartTFromR, aStartTFromBR, pForceColor));
-                    pProcessor->process(aSequence);
+                    rProcessor.process(aSequence);
                 }
 
                 // re-init "*Start***" variables
@@ -1128,7 +1128,7 @@ void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D* pProcessor,
                 CreateBorderPrimitives(aEndPos, aStartPos, *pStart,
                     aEndBFromTL, *pEndBFromL, *pEndBFromB, *pEndBFromR, aEndBFromTR,
                     aStartTFromBL, *pStartTFromL, *pStartTFromT, *pStartTFromR, aStartTFromBR, pForceColor));
-            pProcessor->process(aSequence);
+            rProcessor.process(aSequence);
         }
     }
 }
@@ -1344,6 +1344,12 @@ void Array::DrawArray( OutputDevice& rDev ) const
         DrawRange( rDev, 0, 0, mxImpl->mnWidth - 1, mxImpl->mnHeight - 1 );
 }
 
+void Array::DrawArray(drawinglayer::processor2d::BaseProcessor2D& rProcessor) const
+{
+    if (mxImpl->mnWidth && mxImpl->mnHeight)
+        DrawRange(rProcessor, 0, 0, mxImpl->mnWidth - 1, mxImpl->mnHeight - 1, nullptr);
+}
+
 
 #undef ORIGCELL
 #undef CELLACC
diff --git a/svx/source/dialog/frmsel.cxx b/svx/source/dialog/frmsel.cxx
index 7886c117ddf8..02c9493b9d86 100644
--- a/svx/source/dialog/frmsel.cxx
+++ b/svx/source/dialog/frmsel.cxx
@@ -28,6 +28,7 @@
 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
 #include <vcl/settings.hxx>
+#include <drawinglayer/processor2d/processor2dtools.hxx>
 
 #include <svx/dialogs.hrc>
 #include "bitmaps.hlst"
@@ -671,7 +672,36 @@ void FrameSelectorImpl::DrawAllFrameBorders()
             maArray.SetCellStyleDiag( nCol, nRow, maTLBR.GetUIStyle(), maBLTR.GetUIStyle() );
 
     // Let the helper array draw itself
-    maArray.DrawArray( *mpVirDev.get() );
+    static bool bUsePrimitives(true);
+
+    if (bUsePrimitives)
+    {
+        // This is used in the dialog/control for 'Border' attributes. When using
+        // the original paint below instead of primitives, the advantage currently
+        // is the correct visualization of diagonal line(s) including overlaying,
+        // but the rest is bad. Since the edit views use primitives and the preview
+        // should be 'real' I opt for also changing this to primitives. I will
+        // keep the old solution and add a switch (above) based on a static bool so
+        // that interested people may test this out in the debugger.
+        // This is one more hint to enhance the primitive visualization further to
+        // support diagonals better - that's the way to go.
+        const drawinglayer::geometry::ViewInformation2D aNewViewInformation2D;
+        std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> pProcessor2D(
+            drawinglayer::processor2d::createPixelProcessor2DFromOutputDevice(
+                *mpVirDev.get(),
+                aNewViewInformation2D));
+
+        if (pProcessor2D)
+        {
+            maArray.DrawArray(*pProcessor2D.get());
+            pProcessor2D.reset();
+        }
+    }
+    else
+    {
+        // original paint
+        maArray.DrawArray(*mpVirDev.get());
+    }
 }
 
 void FrameSelectorImpl::DrawVirtualDevice()
commit 9dfdee5e9c5c1ea8d42ac17d86e832d3fb5eb53f
Author: Armin Le Grand <Armin.Le.Grand at cib.de>
Date:   Thu Jul 6 14:02:32 2017 +0200

    borderline: deep changes to BorderLine
    
    Found basic error in determining the offset values
    for BorderLinePrimitive creation, these were not
    centered on the lines. Corrected that. This makes
    it possible to remove the formally used clipping
    which seems to have been used to correct that. Also
    allows to go back to a 'normal' decomposition that
    creates line primitives as expected. That again can
    then be painted quite normally.
    Also added view-dependent case to the decomposition
    to guarantee a gap of one discrete unit (pixel).
    Removed the direct painter, too. Checked and corrected
    stroking.
    
    Change-Id: Ie95e246d5563360617a2a2213e4d5ec7d0e736b9

diff --git a/compilerplugins/clang/fpcomparison.cxx b/compilerplugins/clang/fpcomparison.cxx
index 1cc7616c887b..f85dba05cd1e 100644
--- a/compilerplugins/clang/fpcomparison.cxx
+++ b/compilerplugins/clang/fpcomparison.cxx
@@ -179,7 +179,6 @@ bool FpComparison::ignore(FunctionDecl* function)
         || dc.Function("create2DDecomposition").Class("ScenePrimitive2D").Namespace("primitive2d").Namespace("drawinglayer").GlobalNamespace()
         || dc.Function("createAtom").Class("SvgLinearGradientPrimitive2D").Namespace("primitive2d").Namespace("drawinglayer").GlobalNamespace()
         || dc.Function("createAtom").Class("SvgRadialGradientPrimitive2D").Namespace("primitive2d").Namespace("drawinglayer").GlobalNamespace()
-        || dc.Function("tryDrawBorderLinePrimitive2DDirect").Class("VclPixelProcessor2D").Namespace("processor2d").Namespace("drawinglayer").GlobalNamespace()
         || dc.Function("FoldConstantsBinaryNode").Class("SbiExprNode").GlobalNamespace()
         || dc.Function("Format").Class("SbxValue").GlobalNamespace()
         || dc.Function("Compare").Class("SbxValue").GlobalNamespace()
diff --git a/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
index c6ea4a5c41f7..2bb7eb869289 100644
--- a/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
@@ -42,282 +42,138 @@ T round(T x)
 }
 #endif
 
-namespace drawinglayer {
-
-namespace {
-
-void moveLine(basegfx::B2DPolygon& rPoly, double fGap, const basegfx::B2DVector& rVector)
-{
-    if (basegfx::fTools::equalZero(rVector.getX()))
-    {
-        basegfx::B2DHomMatrix aMat(1, 0, fGap, 0, 1, 0);
-        rPoly.transform(aMat);
-    }
-    else if (basegfx::fTools::equalZero(rVector.getY()))
-    {
-        basegfx::B2DHomMatrix aMat(1, 0, 0, 0, 1, fGap);
-        rPoly.transform(aMat);
-    }
-}
-
-primitive2d::Primitive2DReference makeHairLinePrimitive(
-    const basegfx::B2DPoint& rStart, const basegfx::B2DPoint& rEnd, const basegfx::B2DVector& rVector,
-    const basegfx::BColor& rColor, double fGap)
-{
-    basegfx::B2DPolygon aPolygon;
-    aPolygon.append(rStart);
-    aPolygon.append(rEnd);
-    moveLine(aPolygon, fGap, rVector);
-
-    return primitive2d::Primitive2DReference(new primitive2d::PolygonHairlinePrimitive2D(aPolygon, rColor));
-}
-
-primitive2d::Primitive2DReference makeSolidLinePrimitive(
-    const basegfx::B2DPolyPolygon& rClipRegion, const basegfx::B2DPoint& rStart, const basegfx::B2DPoint& rEnd,
-    const basegfx::B2DVector& rVector, const basegfx::BColor& rColor, double fLineWidth, double fGap)
+namespace drawinglayer
 {
-    const basegfx::B2DVector aPerpendicular = basegfx::getPerpendicular(rVector);
-    const basegfx::B2DVector aLineWidthOffset = (fLineWidth * 0.5) * aPerpendicular;
-
-    basegfx::B2DPolygon aPolygon;
-    aPolygon.append(rStart + aLineWidthOffset);
-    aPolygon.append(rEnd + aLineWidthOffset);
-    aPolygon.append(rEnd - aLineWidthOffset);
-    aPolygon.append(rStart - aLineWidthOffset);
-    aPolygon.setClosed(true);
-
-    moveLine(aPolygon, fGap, rVector);
-
-    basegfx::B2DPolyPolygon aClipped =
-        basegfx::tools::clipPolygonOnPolyPolygon(aPolygon, rClipRegion, true, false);
-
-    if (aClipped.count())
-        aPolygon = aClipped.getB2DPolygon(0);
-
-    return primitive2d::Primitive2DReference(
-        new primitive2d::PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(aPolygon), rColor));
-}
-
-}
-
-    // fdo#49438: heuristic pseudo hack
-    static bool lcl_UseHairline(double const fW,
-            basegfx::B2DPoint const& rStart, basegfx::B2DPoint const& rEnd,
-            geometry::ViewInformation2D const& rViewInformation)
-    {
-        basegfx::B2DTuple scale;
-        basegfx::B2DTuple translation;
-        double fRotation;
-        double fShear;
-        rViewInformation.getObjectToViewTransformation().decompose(
-                scale, translation, fRotation, fShear);
-        double const fScale(
-            (rEnd.getX() - rStart.getX() > rEnd.getY() - rStart.getY())
-                ? scale.getY() : scale.getX());
-        return (fW * fScale < 0.51);
-    }
-
-    static double lcl_GetCorrectedWidth(double const fW,
-            basegfx::B2DPoint const& rStart, basegfx::B2DPoint const& rEnd,
-            geometry::ViewInformation2D const& rViewInformation)
-    {
-        return (lcl_UseHairline(fW, rStart, rEnd, rViewInformation)) ? 0.0 : fW;
-    }
-
     namespace primitive2d
     {
-        double BorderLinePrimitive2D::getWidth(
-            geometry::ViewInformation2D const& rViewInformation) const
-        {
-            return lcl_GetCorrectedWidth(mfLeftWidth, getStart(), getEnd(),
-                        rViewInformation)
-                 + lcl_GetCorrectedWidth(mfDistance, getStart(), getEnd(),
-                         rViewInformation)
-                 + lcl_GetCorrectedWidth(mfRightWidth, getStart(), getEnd(),
-                         rViewInformation);
-        }
-
-        basegfx::B2DPolyPolygon BorderLinePrimitive2D::getClipPolygon(
-            geometry::ViewInformation2D const& rViewInformation) const
+        // helper to add a centered, maybe stroked line primitive to rContainer
+        void addPolygonStrokePrimitive2D(
+            Primitive2DContainer& rContainer,
+            const basegfx::B2DPoint& rStart,
+            const basegfx::B2DPoint& rEnd,
+            const basegfx::BColor& rColor,
+            double fWidth,
+            SvxBorderLineStyle aStyle,
+            double fPatternScale)
         {
-            basegfx::B2DPolygon clipPolygon;
-
-            // Get the vectors
-            basegfx::B2DVector aVector( getEnd() - getStart() );
-            aVector.normalize();
-            const basegfx::B2DVector aPerpendicular(basegfx::getPerpendicular(aVector));
-
-            // Get the points
-            const double fWidth(getWidth(rViewInformation));
-            const basegfx::B2DVector aLeftOff(
-                    aPerpendicular * (-0.5 * std::max(fWidth, 1.0)));
-            const basegfx::B2DVector aRightOff(
-                    aPerpendicular * (0.5 * std::max(fWidth, 1.0)));
+            basegfx::B2DPolygon aPolygon;
 
-            const basegfx::B2DVector aSLVector( aLeftOff - ( getExtendLeftStart() * aVector ) );
-            clipPolygon.append( basegfx::B2DPoint( getStart() + aSLVector * 2.0 ) );
+            aPolygon.append(rStart);
+            aPolygon.append(rEnd);
 
-            clipPolygon.append( getStart( ) );
+            const attribute::LineAttribute aLineAttribute(rColor, fWidth);
+            static double fPatScFact(1.0); // 10.0 multiply, see old code
+            const std::vector<double> aDashing(svtools::GetLineDashing(aStyle, fPatternScale * fPatScFact));
 
-            const basegfx::B2DVector aSRVector( aRightOff - ( getExtendRightStart() * aVector ) );
-            clipPolygon.append( basegfx::B2DPoint( getStart() + aSRVector * 2.0 ) );
-
-            const basegfx::B2DVector aERVector( aRightOff + ( getExtendRightEnd() * aVector ) );
-            clipPolygon.append( basegfx::B2DPoint( getEnd() + aERVector * 2.0 ) );
-
-            clipPolygon.append( getEnd( ) );
-
-            const basegfx::B2DVector aELVector( aLeftOff + ( getExtendLeftEnd() * aVector ) );
-            clipPolygon.append( basegfx::B2DPoint( getEnd() + aELVector * 2.0 ) );
-
-            clipPolygon.setClosed( true );
-
-            return basegfx::B2DPolyPolygon( clipPolygon );
-        }
+            if (aDashing.empty())
+            {
+                rContainer.push_back(
+                    new PolygonStrokePrimitive2D(
+                        aPolygon,
+                        aLineAttribute));
+            }
+            else
+            {
+                const attribute::StrokeAttribute aStrokeAttribute(aDashing);
 
-        void BorderLinePrimitive2D::create2DDecomposition(Primitive2DContainer& rContainer, const geometry::ViewInformation2D& rViewInformation) const
-        {
-            createDecomposition(rContainer, rViewInformation, false);
+                rContainer.push_back(
+                    new PolygonStrokePrimitive2D(
+                        aPolygon,
+                        aLineAttribute,
+                        aStrokeAttribute));
+            }
         }
 
-        void BorderLinePrimitive2D::createDecomposition(Primitive2DContainer& rContainer, const geometry::ViewInformation2D& rViewInformation, bool bPixelCorrection) const
+        void BorderLinePrimitive2D::create2DDecomposition(Primitive2DContainer& rContainer, const geometry::ViewInformation2D& /*rViewInformation*/) const
         {
-            if(!getStart().equal(getEnd()) && ( isInsideUsed() || isOutsideUsed() ) )
+            if (!getStart().equal(getEnd()) && (isInsideUsed() || isOutsideUsed()))
             {
                 // get data and vectors
                 basegfx::B2DVector aVector(getEnd() - getStart());
                 aVector.normalize();
                 const basegfx::B2DVector aPerpendicular(basegfx::getPerpendicular(aVector));
 
-                const basegfx::B2DPolyPolygon& aClipRegion =
-                    getClipPolygon(rViewInformation);
-
-                if(isOutsideUsed() && isInsideUsed())
+                if (isOutsideUsed() && isInsideUsed())
                 {
-                    const double fExt = getWidth(rViewInformation);  // Extend a lot: it'll be clipped later.
-                    const basegfx::B2DPoint aTmpStart(getStart() - (fExt * aVector));
-                    const basegfx::B2DPoint aTmpEnd(getEnd() + (fExt * aVector));
-
-                    double fLeftWidth = getLeftWidth();
-                    bool bLeftHairline = lcl_UseHairline(fLeftWidth, getStart(), getEnd(), rViewInformation);
-                    if (bLeftHairline)
-                        fLeftWidth = 0.0;
-
-                    double fRightWidth = getRightWidth();
-                    bool bRightHairline = lcl_UseHairline(fRightWidth, getStart(), getEnd(), rViewInformation);
-                    if (bRightHairline)
-                        fRightWidth = 0.0;
-
-                    // "inside" line
-
-                    if (bLeftHairline)
-                        rContainer.push_back(makeHairLinePrimitive(
-                            getStart(), getEnd(), aVector, getRGBColorLeft(), 0.0));
-                    else
+                    // double line with gap. Use mfDiscreteDistance (see get2DDecomposition) as distance.
+                    // That value is prepared to be at least one pixel (discrete unit) so that the
+                    // decomposition is view-dependent in this cases
+                    if (isInsideUsed())
                     {
-                        double fWidth = bPixelCorrection ? std::round(fLeftWidth) : fLeftWidth;
-                        rContainer.push_back(makeSolidLinePrimitive(
-                            aClipRegion, aTmpStart, aTmpEnd, aVector, getRGBColorLeft(), fWidth, -fLeftWidth/2.0));
+                        // inside line (left). Create stroke primitive centered on line width
+                        const double fDeltaY((mfDiscreteDistance + getLeftWidth()) * 0.5);
+                        const basegfx::B2DVector aDeltaY(aPerpendicular * fDeltaY);
+                        const basegfx::B2DPoint aStart(getStart() - (aVector * getExtendLeftStart()) - aDeltaY);
+                        const basegfx::B2DPoint aEnd(getEnd() + (aVector * getExtendLeftEnd()) - aDeltaY);
+
+                        addPolygonStrokePrimitive2D(
+                            rContainer,
+                            aStart,
+                            aEnd,
+                            getRGBColorLeft(),
+                            getLeftWidth(),
+                            getStyle(),
+                            getPatternScale());
                     }
 
-                    // "outside" line
-
-                    if (bRightHairline)
-                        rContainer.push_back(makeHairLinePrimitive(
-                            getStart(), getEnd(), aVector, getRGBColorRight(), fLeftWidth+mfDistance));
-                    else
+                    if (hasGapColor() && isDistanceUsed())
                     {
-                        double fWidth = bPixelCorrection ? std::round(fRightWidth) : fRightWidth;
-                        rContainer.push_back(makeSolidLinePrimitive(
-                            aClipRegion, aTmpStart, aTmpEnd, aVector, getRGBColorRight(), fWidth, mfDistance+fRightWidth/2.0));
+                        // gap (if visible, found no practicval usage).
+                        // Create stroke primitive on vector with given color
+                        addPolygonStrokePrimitive2D(
+                            rContainer,
+                            getStart(),
+                            getEnd(),
+                            getRGBColorGap(),
+                            mfDiscreteDistance,
+                            getStyle(),
+                            getPatternScale());
                     }
-                }
-                else
-                {
-                    // single line, create geometry
-                    basegfx::B2DPolygon aPolygon;
-                    const double fExt = getWidth(rViewInformation);  // Extend a lot: it'll be clipped after
-                    const basegfx::B2DPoint aTmpStart(getStart() - (fExt * aVector));
-                    const basegfx::B2DPoint aTmpEnd(getEnd() + (fExt * aVector));
 
-                    // Get which is the line to show
-                    bool bIsSolidline = mnStyle == SvxBorderLineStyle::SOLID;
-                    double nWidth = getLeftWidth();
-                    basegfx::BColor aColor = getRGBColorLeft();
-                    if ( basegfx::fTools::equal( 0.0, mfLeftWidth ) )
+                    if (isOutsideUsed())
                     {
-                        nWidth = getRightWidth();
-                        aColor = getRGBColorRight();
+                        // outside line (right). Create stroke primitive centered on line width
+                        const double fDeltaY((mfDiscreteDistance + getRightWidth()) * 0.5);
+                        const basegfx::B2DVector aDeltaY(aPerpendicular * fDeltaY);
+                        const basegfx::B2DPoint aStart(getStart() - (aVector * getExtendRightStart()) + aDeltaY);
+                        const basegfx::B2DPoint aEnd(getEnd() + (aVector * getExtendRightEnd()) + aDeltaY);
+
+                        addPolygonStrokePrimitive2D(
+                            rContainer,
+                            aStart,
+                            aEnd,
+                            getRGBColorRight(),
+                            getRightWidth(),
+                            getStyle(),
+                            getPatternScale());
                     }
-                    bool const bIsHairline = lcl_UseHairline(
-                            nWidth, getStart(), getEnd(), rViewInformation);
-                    nWidth = lcl_GetCorrectedWidth(nWidth,
-                                getStart(), getEnd(), rViewInformation);
-
-                    if(bIsHairline && bIsSolidline)
-                    {
-                        // create hairline primitive
-                        aPolygon.append( getStart() );
-                        aPolygon.append( getEnd() );
-
-                        rContainer.push_back(new PolygonHairlinePrimitive2D(
-                            aPolygon,
-                            aColor));
-                    }
-                    else
-                    {
-                        // create filled polygon primitive
-                        const basegfx::B2DVector aLineWidthOffset(((nWidth + 1) * 0.5) * aPerpendicular);
-
-                        aPolygon.append( aTmpStart );
-                        aPolygon.append( aTmpEnd );
-
-                        basegfx::B2DPolyPolygon aDashed =
-                            svtools::ApplyLineDashing(aPolygon, getStyle(), mfPatternScale*10.0);
-
-                        for (sal_uInt32 i = 0; i < aDashed.count(); i++ )
-                        {
-                            basegfx::B2DPolygon aDash = aDashed.getB2DPolygon( i );
-                            basegfx::B2DPoint aDashStart = aDash.getB2DPoint( 0 );
-                            basegfx::B2DPoint aDashEnd = aDash.getB2DPoint( aDash.count() - 1 );
-
-                            basegfx::B2DPolygon aDashPolygon;
-                            aDashPolygon.append( aDashStart + aLineWidthOffset );
-                            aDashPolygon.append( aDashEnd + aLineWidthOffset );
-                            aDashPolygon.append( aDashEnd - aLineWidthOffset );
-                            aDashPolygon.append( aDashStart - aLineWidthOffset );
-                            aDashPolygon.setClosed( true );
-
-                            basegfx::B2DPolyPolygon aClipped = basegfx::tools::clipPolygonOnPolyPolygon(
-                                aDashPolygon, aClipRegion, true, false );
+                }
+                else if(isInsideUsed())
+                {
+                    // single line, only inside values used, no vertical offsets
+                    addPolygonStrokePrimitive2D(
+                        rContainer,
+                        getStart(),
+                        getEnd(),
+                        getRGBColorLeft(),
+                        getLeftWidth(),
+                        getStyle(),
+                        getPatternScale());
+                }
+            }
+        }
 
-                            if ( aClipped.count() )
-                                aDashed.setB2DPolygon( i, aClipped.getB2DPolygon( 0 ) );
-                        }
+        bool BorderLinePrimitive2D::isHorizontalOrVertical(const geometry::ViewInformation2D& rViewInformation) const
+        {
+            if (!getStart().equal(getEnd()))
+            {
+                const basegfx::B2DHomMatrix& rOTVT = rViewInformation.getObjectToViewTransformation();
+                const basegfx::B2DVector aVector(rOTVT * getEnd() - rOTVT * getStart());
 
-                        sal_uInt32 n = aDashed.count();
-                        for (sal_uInt32 i = 0; i < n; ++i)
-                        {
-                            basegfx::B2DPolygon aDash = aDashed.getB2DPolygon(i);
-                            if (bIsHairline)
-                            {
-                                // Convert a rectangular polygon into a line.
-                                basegfx::B2DPolygon aDash2;
-                                basegfx::B2DRange aRange = aDash.getB2DRange();
-                                aDash2.append(basegfx::B2DPoint(aRange.getMinX(), aRange.getMinY()));
-                                aDash2.append(basegfx::B2DPoint(aRange.getMaxX(), aRange.getMinY()));
-                                rContainer.push_back(
-                                    new PolygonHairlinePrimitive2D(aDash2, aColor));
-                            }
-                            else
-                            {
-                                rContainer.push_back(
-                                    new PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(aDash), aColor));
-                            }
-                        }
-                    }
-                }
+                return basegfx::fTools::equalZero(aVector.getX()) || basegfx::fTools::equalZero(aVector.getY());
             }
+
+            return false;
         }
 
         BorderLinePrimitive2D::BorderLinePrimitive2D(
@@ -351,7 +207,8 @@ primitive2d::Primitive2DReference makeSolidLinePrimitive(
             maRGBColorGap(rRGBColorGap),
             mbHasGapColor(bHasGapColor),
             mnStyle(nStyle),
-            mfPatternScale(fPatternScale)
+            mfPatternScale(fPatternScale),
+            mfDiscreteDistance(0.0)
         {
         }
 
@@ -381,6 +238,42 @@ primitive2d::Primitive2DReference makeSolidLinePrimitive(
             return false;
         }
 
+        void BorderLinePrimitive2D::get2DDecomposition(Primitive2DDecompositionVisitor& rVisitor, const geometry::ViewInformation2D& rViewInformation) const
+        {
+            ::osl::MutexGuard aGuard(m_aMutex);
+
+            if (!getStart().equal(getEnd()) && isOutsideUsed() && isInsideUsed())
+            {
+                // Double line with gap. In this case, we want to be view-dependent.
+                // Get the current DiscreteUnit, look at X and Y and use the maximum
+                const basegfx::B2DVector aDiscreteVector(rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 1.0));
+                const double fDiscreteUnit(std::min(fabs(aDiscreteVector.getX()), fabs(aDiscreteVector.getY())));
+
+                // When discrete unit is bigger than distance (distance is less than one pixel),
+                // force distance to one pixel. Or expressed different, do not let the distance
+                // get smaller than one pixel. This is done for screen rendering and compatibility.
+                // This can also be done using DiscreteMetricDependentPrimitive2D as base class
+                // for this class, but specialization is better here for later buffering (only
+                // do this when 'double line with gap')
+                const double fNewDiscreteDistance(std::max(fDiscreteUnit, getDistance()));
+
+                if (fNewDiscreteDistance != mfDiscreteDistance)
+                {
+                    if (!getBuffered2DDecomposition().empty())
+                    {
+                        // conditions of last local decomposition have changed, delete
+                        const_cast< BorderLinePrimitive2D* >(this)->setBuffered2DDecomposition(Primitive2DContainer());
+                    }
+
+                    // remember value for usage in create2DDecomposition
+                    const_cast< BorderLinePrimitive2D* >(this)->mfDiscreteDistance = fNewDiscreteDistance;
+                }
+            }
+
+            // call base implementation
+            BufferedDecompositionPrimitive2D::get2DDecomposition(rVisitor, rViewInformation);
+        }
+
         // provide unique ID
         ImplPrimitive2DIDBlock(BorderLinePrimitive2D, PRIMITIVE2D_ID_BORDERLINEPRIMITIVE2D)
 
diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
index 4b5e45c7ef04..eb477f4aed16 100644
--- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
@@ -306,341 +306,6 @@ namespace drawinglayer
             return bTryWorked;
         }
 
-        bool VclPixelProcessor2D::tryDrawBorderLinePrimitive2DDirect(
-            const drawinglayer::primitive2d::BorderLinePrimitive2D& rSource)
-        {
-            const basegfx::B2DPoint& rS = rSource.getStart();
-            const basegfx::B2DPoint& rE = rSource.getEnd();
-
-            double fX1 = rS.getX();
-            double fY1 = rS.getY();
-            double fX2 = rE.getX();
-            double fY2 = rE.getY();
-
-            bool bHorizontal = false;
-            if (fX1 == fX2)
-            {
-                // Vertical line.
-            }
-            else if (fY1 == fY2)
-            {
-                // Horizontal line.
-                bHorizontal = true;
-            }
-            else
-                // Neither.  Bail out.
-                return false;
-
-            switch (rSource.getStyle())
-            {
-                case SvxBorderLineStyle::SOLID:
-                case SvxBorderLineStyle::DOUBLE_THIN:
-                {
-                    const basegfx::BColor aLineColor =
-                        maBColorModifierStack.getModifiedColor(rSource.getRGBColorLeft());
-                    double nThick = rtl::math::round(rSource.getLeftWidth());
-
-                    bool bDouble = rSource.getStyle() == SvxBorderLineStyle::DOUBLE_THIN;
-
-                    basegfx::B2DPolygon aTarget;
-
-                    if (bHorizontal)
-                    {
-                        // Horizontal line.  Draw it as a rectangle.
-
-                        aTarget = makeRectPolygon(fX1, fY1, fX2-fX1, nThick);
-                        aTarget.transform(maCurrentTransformation);
-
-                        basegfx::B2DRange aRange = aTarget.getB2DRange();
-                        double fH = aRange.getHeight();
-
-                        if (bDouble)
-                        {
-                            // Double line
-                            drawHairLine(
-                                mpOutputDevice, aRange.getMinX(), aRange.getMinY()-1.0, aRange.getMaxX(), aRange.getMinY()-1.0,
-                                aLineColor);
-
-                            drawHairLine(
-                                mpOutputDevice, aRange.getMinX(), aRange.getMinY()+1.0, aRange.getMaxX(), aRange.getMinY()+1.0,
-                                aLineColor);
-
-                            return true;
-                        }
-
-                        if (fH <= 1.0)
-                        {
-                            // Draw it as a line.
-                            drawHairLine(
-                                mpOutputDevice, aRange.getMinX(), aRange.getMinY(), aRange.getMaxX(), aRange.getMinY(),
-                                aLineColor);
-
-                            return true;
-                        }
-
-                        double fOffset = rtl::math::round(fH/2.0, 0, rtl_math_RoundingMode_Down);
-                        if (fOffset != 0.0)
-                        {
-                            // Move it up a bit to align it vertically centered.
-                            basegfx::B2DHomMatrix aMat;
-                            aMat.set(1, 2, -fOffset);
-                            aTarget.transform(aMat);
-                        }
-                    }
-                    else
-                    {
-                        // Vertical line.  Draw it as a rectangle.
-
-                        aTarget = makeRectPolygon(fX1, fY1, nThick, fY2-fY1);
-                        aTarget.transform(maCurrentTransformation);
-
-                        basegfx::B2DRange aRange = aTarget.getB2DRange();
-                        double fW = aRange.getWidth();
-
-                        if (bDouble)
-                        {
-                            // Draw it as a line.
-                            drawHairLine(
-                                mpOutputDevice, aRange.getMinX()-1.0, aRange.getMinY(), aRange.getMinX()-1.0, aRange.getMaxY(),
-                                aLineColor);
-
-                            drawHairLine(
-                                mpOutputDevice, aRange.getMinX()+1.0, aRange.getMinY(), aRange.getMinX()+1.0, aRange.getMaxY(),
-                                aLineColor);
-
-                            return true;
-                        }
-
-                        if (fW <= 1.0)
-                        {
-                            // Draw it as a line.
-                            drawHairLine(
-                                mpOutputDevice, aRange.getMinX(), aRange.getMinY(), aRange.getMinX(), aRange.getMaxY(),
-                                aLineColor);
-
-                            return true;
-                        }
-
-                        double fOffset = rtl::math::round(fW/2.0, 0, rtl_math_RoundingMode_Down);
-                        if (fOffset != 0.0)
-                        {
-                            // Move it to the left a bit to center it horizontally.
-                            basegfx::B2DHomMatrix aMat;
-                            aMat.set(0, 2, -fOffset);
-                            aTarget.transform(aMat);
-                        }
-                    }
-
-                    mpOutputDevice->SetFillColor(Color(aLineColor));
-                    mpOutputDevice->SetLineColor();
-                    mpOutputDevice->DrawPolygon(aTarget);
-                    return true;
-                }
-                break;
-                case SvxBorderLineStyle::DOTTED:
-                case SvxBorderLineStyle::DASHED:
-                case SvxBorderLineStyle::DASH_DOT:
-                case SvxBorderLineStyle::DASH_DOT_DOT:
-                case SvxBorderLineStyle::FINE_DASHED:
-                {
-                    std::vector<double> aPattern =
-                        svtools::GetLineDashing(rSource.getStyle(), rSource.getPatternScale()*10.0);
-
-                    if (aPattern.empty())
-                        // Failed to get pattern values.
-                        return false;
-
-                    double nThick = rtl::math::round(rSource.getLeftWidth());
-
-                    const basegfx::BColor aLineColor =
-                        maBColorModifierStack.getModifiedColor(rSource.getRGBColorLeft());
-
-                    // Transform the current line range before using it for rendering.
-                    basegfx::B2DRange aRange(fX1, fY1, fX2, fY2);
-                    aRange.transform(maCurrentTransformation);
-                    fX1 = aRange.getMinX();
-                    fX2 = aRange.getMaxX();
-                    fY1 = aRange.getMinY();
-                    fY2 = aRange.getMaxY();
-
-                    basegfx::B2DPolyPolygon aTarget;
-
-                    if (bHorizontal)
-                    {
-                        // Horizontal line.
-
-                        if (basegfx::fTools::equalZero(nThick))
-                        {
-                            // Dash line segment too small to draw.  Substitute it with a solid line.
-                            drawHairLine(mpOutputDevice, fX1, fY1, fX2, fY1, aLineColor);
-                            return true;
-                        }
-
-                        // Create a dash unit polygon set.
-                        basegfx::B2DPolyPolygon aDashes;
-                        std::vector<double>::const_iterator it = aPattern.begin(), itEnd = aPattern.end();
-                        for (; it != itEnd; ++it)
-                            aDashes.append(makeRectPolygon(0, 0, *it, nThick));
-
-                        aDashes.transform(maCurrentTransformation);
-                        rtl::math::setNan(&nThick);
-
-                        // Pixelize the dash unit.  We use the same height for
-                        // all dash polygons.
-                        basegfx::B2DPolyPolygon aDashesPix;
-
-                        for (sal_uInt32 i = 0, n = aDashes.count(); i < n; ++i)
-                        {
-                            basegfx::B2DPolygon aPoly = aDashes.getB2DPolygon(i);
-                            aRange = aPoly.getB2DRange();
-                            double fW = rtl::math::round(aRange.getWidth());
-                            if (basegfx::fTools::equalZero(fW))
-                            {
-                                // Dash line segment too small to draw.  Substitute it with a solid line.
-                                drawHairLine(mpOutputDevice, fX1, fY1, fX2, fY1, aLineColor);
-                                return true;
-                            }
-
-                            if (rtl::math::isNan(nThick))
-                                nThick = rtl::math::round(aRange.getHeight());
-
-                            aDashesPix.append(makeRectPolygon(0, 0, fW, nThick));
-                        }
-
-                        // Make all dash polygons and render them.
-                        double fX = fX1;
-                        bool bLine = true;
-                        sal_uInt32 i = 0, n = aDashesPix.count();
-                        while (fX <= fX2)
-                        {
-                            basegfx::B2DPolygon aPoly = aDashesPix.getB2DPolygon(i);
-                            aRange = aPoly.getB2DRange();
-                            if (bLine)
-                            {
-                                double fBlockW = aRange.getWidth();
-                                if (fX + fBlockW > fX2)
-                                    // Clip the right end in case it spills over the range.
-                                    fBlockW = fX2 - fX + 1;
-
-                                double fH = aRange.getHeight();
-                                if (basegfx::fTools::equalZero(fH))
-                                    fH = 1.0;
-
-                                aTarget.append(makeRectPolygon(fX, fY1, fBlockW, fH));
-                            }
-
-                            bLine = !bLine; // line and blank alternate.
-                            fX += aRange.getWidth();
-
-                            ++i;
-                            if (i >= n)
-                                i = 0;
-                        }
-
-                        double fOffset = rtl::math::round(nThick/2.0, 0, rtl_math_RoundingMode_Down);
-                        if (fOffset != 0.0)
-                        {
-                            // Move it up a bit to align it vertically centered.
-                            basegfx::B2DHomMatrix aMat;
-                            aMat.set(1, 2, -fOffset);
-                            aTarget.transform(aMat);
-                        }
-                    }
-                    else
-                    {
-                        // Vertical line.
-
-                        if (basegfx::fTools::equalZero(nThick))
-                        {
-                            // Dash line segment too small to draw.  Substitute it with a solid line.
-                            drawHairLine(mpOutputDevice, fX1, fY1, fX1, fY2, aLineColor);
-                            return true;
-                        }
-
-                        // Create a dash unit polygon set.
-                        basegfx::B2DPolyPolygon aDashes;
-                        std::vector<double>::const_iterator it = aPattern.begin(), itEnd = aPattern.end();
-                        for (; it != itEnd; ++it)
-                            aDashes.append(makeRectPolygon(0, 0, nThick, *it));
-
-                        aDashes.transform(maCurrentTransformation);
-                        rtl::math::setNan(&nThick);
-
-                        // Pixelize the dash unit.  We use the same width for
-                        // all dash polygons.
-                        basegfx::B2DPolyPolygon aDashesPix;
-
-                        for (sal_uInt32 i = 0, n = aDashes.count(); i < n; ++i)
-                        {
-                            basegfx::B2DPolygon aPoly = aDashes.getB2DPolygon(i);
-                            aRange = aPoly.getB2DRange();
-                            double fH = rtl::math::round(aRange.getHeight());
-                            if (basegfx::fTools::equalZero(fH))
-                            {
-                                // Dash line segment too small to draw.  Substitute it with a solid line.
-                                drawHairLine(mpOutputDevice, fX1, fY1, fX1, fY2, aLineColor);
-                                return true;
-                            }
-
-                            if (rtl::math::isNan(nThick))
-                                nThick = rtl::math::round(aRange.getWidth());
-
-                            aDashesPix.append(makeRectPolygon(0, 0, nThick, fH));
-                        }
-
-                        // Make all dash polygons and render them.
-                        double fY = fY1;
-                        bool bLine = true;
-                        sal_uInt32 i = 0, n = aDashesPix.count();
-                        while (fY <= fY2)
-                        {
-                            basegfx::B2DPolygon aPoly = aDashesPix.getB2DPolygon(i);
-                            aRange = aPoly.getB2DRange();
-                            if (bLine)
-                            {
-                                double fBlockH = aRange.getHeight();
-                                if (fY + fBlockH > fY2)
-                                    // Clip the bottom end in case it spills over the range.
-                                    fBlockH = fY2 - fY + 1;
-
-                                double fW = aRange.getWidth();
-                                if (basegfx::fTools::equalZero(fW))
-                                    fW = 1.0;
-
-                                aTarget.append(makeRectPolygon(fX1, fY, fW, fBlockH));
-                            }
-
-                            bLine = !bLine; // line and blank alternate.
-                            fY += aRange.getHeight();
-
-                            ++i;
-                            if (i >= n)
-                                i = 0;
-                        }
-
-                        double fOffset = rtl::math::round(nThick/2.0, 0, rtl_math_RoundingMode_Down);
-                        if (fOffset != 0.0)
-                        {
-                            // Move it to the left a bit to center it horizontally.
-                            basegfx::B2DHomMatrix aMat;
-                            aMat.set(0, 2, -fOffset);
-                            aTarget.transform(aMat);
-                        }
-                    }
-
-                    mpOutputDevice->SetFillColor(Color(aLineColor));
-                    mpOutputDevice->SetLineColor();
-                    mpOutputDevice->DrawPolyPolygon(aTarget);
-
-                    return true;
-                }
-                break;
-                default:
-                    ;
-            }
-            return false;
-        }
-
         void VclPixelProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate)
         {
             switch(rCandidate.getPrimitive2DID())
@@ -1253,28 +918,23 @@ namespace drawinglayer
                 }
                 case PRIMITIVE2D_ID_BORDERLINEPRIMITIVE2D:
                 {
-                    // process recursively, but turn off anti-aliasing. Border
-                    // lines are always rectangular, and look horrible when
-                    // the anti-aliasing is enabled.
-                    AntialiasingFlags nAntiAliasing = mpOutputDevice->GetAntialiasing();
-                    mpOutputDevice->SetAntialiasing(nAntiAliasing & ~AntialiasingFlags::EnableB2dDraw);
-
+                    // process recursively, but switch off AntiAliasing for
+                    // horizontal/vertical lines (*not* diagonal lines)
                     const drawinglayer::primitive2d::BorderLinePrimitive2D& rBorder =
                         static_cast<const drawinglayer::primitive2d::BorderLinePrimitive2D&>(rCandidate);
 
-                    if (!tryDrawBorderLinePrimitive2DDirect(rBorder))
+                    if (rBorder.isHorizontalOrVertical(getViewInformation2D()))
                     {
-                        if (rBorder.getStyle() == SvxBorderLineStyle::DOUBLE)
-                        {
-                            primitive2d::Primitive2DContainer aContainer;
-                            rBorder.createDecomposition(aContainer, getViewInformation2D(), true);
-                            process(aContainer);
-                        }
-                        else
-                            process(rCandidate);
-                    }
+                        AntialiasingFlags nAntiAliasing = mpOutputDevice->GetAntialiasing();
+                        mpOutputDevice->SetAntialiasing(nAntiAliasing & ~AntialiasingFlags::EnableB2dDraw);
 
-                    mpOutputDevice->SetAntialiasing(nAntiAliasing);
+                        process(rCandidate);
+                        mpOutputDevice->SetAntialiasing(nAntiAliasing);
+                    }
+                    else
+                    {
+                        process(rCandidate);
+                    }
                     break;
                 }
                 default :
diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.hxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.hxx
index 0a8e97d748b8..19c0282ffc5a 100644
--- a/drawinglayer/source/processor2d/vclpixelprocessor2d.hxx
+++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.hxx
@@ -64,7 +64,6 @@ namespace drawinglayer
             bool tryDrawPolyPolygonColorPrimitive2DDirect(const drawinglayer::primitive2d::PolyPolygonColorPrimitive2D& rSource, double fTransparency);
             bool tryDrawPolygonHairlinePrimitive2DDirect(const drawinglayer::primitive2d::PolygonHairlinePrimitive2D& rSource, double fTransparency);
             bool tryDrawPolygonStrokePrimitive2DDirect(const drawinglayer::primitive2d::PolygonStrokePrimitive2D& rSource, double fTransparency);
-            bool tryDrawBorderLinePrimitive2DDirect(const drawinglayer::primitive2d::BorderLinePrimitive2D& rSource);
 
         public:
             /// constructor/destructor
diff --git a/include/drawinglayer/primitive2d/borderlineprimitive2d.hxx b/include/drawinglayer/primitive2d/borderlineprimitive2d.hxx
index 4ac0a1045585..4645bde2a2c5 100644
--- a/include/drawinglayer/primitive2d/borderlineprimitive2d.hxx
+++ b/include/drawinglayer/primitive2d/borderlineprimitive2d.hxx
@@ -66,27 +66,29 @@ namespace drawinglayer
             bool                                            mbHasGapColor;
 
             SvxBorderLineStyle                              mnStyle;
-
             double                                          mfPatternScale;
 
-            /// local helpers
-            double getWidth(
-                    const geometry::ViewInformation2D& rViewInformation) const;
+            // for view dependent decomposition in the case with distance (gap),
+            // remember the last used concrete mfDistance, see get2DDecomposition
+            // implementation
+            double                                          mfDiscreteDistance;
 
+            /// local helpers
             bool isInsideUsed() const
             {
                 return !basegfx::fTools::equalZero(mfLeftWidth);
             }
 
+            bool isDistanceUsed() const
+            {
+                return !basegfx::fTools::equalZero(mfDistance);
+            }
+
             bool isOutsideUsed() const
             {
                 return !basegfx::fTools::equalZero(mfRightWidth);
             }
 
-        protected:
-            virtual basegfx::B2DPolyPolygon getClipPolygon(
-                    const geometry::ViewInformation2D& rViewInformation) const;
-
             /// create local decomposition
             virtual void create2DDecomposition(Primitive2DContainer& rContainer, const geometry::ViewInformation2D& rViewInformation) const override;
 
@@ -125,12 +127,16 @@ namespace drawinglayer
             bool hasGapColor( ) const { return mbHasGapColor; }
             SvxBorderLineStyle getStyle () const { return mnStyle; }
             double getPatternScale() const { return mfPatternScale; }
-            /// Same as create2DDecomposition(), but can do pixel correction if requested.
-            void createDecomposition(Primitive2DContainer& rContainer, const geometry::ViewInformation2D& rViewInformation, bool bPixelCorrection) const;
+
+            /// helper to decide if AntiAliasing should be used
+            bool isHorizontalOrVertical(const geometry::ViewInformation2D& rViewInformation) const;
 
             /// compare operator
             virtual bool operator==(const BasePrimitive2D& rPrimitive) const override;
 
+            /// Override standard getDecomposition to be view-dependent here
+            virtual void get2DDecomposition(Primitive2DDecompositionVisitor& rVisitor, const geometry::ViewInformation2D& rViewInformation) const override;
+
             /// provide unique ID
             DeclPrimitive2DIDBlock()
         };
diff --git a/svx/source/dialog/framelink.cxx b/svx/source/dialog/framelink.cxx
index 3da2af55fb46..d2a1e1ffd06e 100644
--- a/svx/source/dialog/framelink.cxx
+++ b/svx/source/dialog/framelink.cxx
@@ -1348,9 +1348,34 @@ bool CheckFrameBorderConnectable( const Style& rLBorder, const Style& rRBorder,
 
 // Drawing functions
 
+// get offset to center of line in question
+double lcl_getCenterOfLineOffset(const Style& rBorder, bool bLeftEdge)
+{
+    const bool bPrimUsed(!basegfx::fTools::equalZero(rBorder.Prim())); // left
+    const bool bDistUsed(!basegfx::fTools::equalZero(rBorder.Dist())); // distance
+    const bool bSecnUsed(!basegfx::fTools::equalZero(rBorder.Secn())); // right
+
+    if (bDistUsed || bSecnUsed)
+    {
+        // double line, get center by adding half ditance and half line width.
+        // bLeftEdge defines which line to use
+        return (rBorder.Dist() + (bLeftEdge ? rBorder.Prim() : rBorder.Secn())) * 0.5;
+    }
+    else if (bPrimUsed)
+    {
+        // single line, get center
+        return rBorder.Prim() * 0.5;
+    }
+
+    // no line width at all, stay on unit vector
+    return 0.0;
+}
 
-double lcl_GetExtent( const Style& rBorder, const Style& rSide, const Style& rOpposite,
-                      long nAngleSide, long nAngleOpposite )
+double lcl_GetExtent(
+    const Style& rBorder, const Style& rSide, const Style& rOpposite,
+    long nAngleSide, long nAngleOpposite,
+    bool bLeftEdge,     // left or right of rBorder
+    bool bOtherLeft )   // left or right of rSide/rOpposite
 {
     Style aOtherBorder = rSide;
     long nOtherAngle = nAngleSide;
@@ -1369,7 +1394,8 @@ double lcl_GetExtent( const Style& rBorder, const Style& rSide, const Style& rOp
 
     // Let's assume the border we are drawing is horizontal and compute all the angles / distances from this
     basegfx::B2DVector aBaseVector( 1.0, 0.0 );
-    basegfx::B2DPoint aBasePoint( 0.0, static_cast<double>( rBorder.GetWidth() / 2 ) );
+    // added support to get the distances to the centers of the line, *not* the outre edge
+    basegfx::B2DPoint aBasePoint(0.0, lcl_getCenterOfLineOffset(rBorder, bLeftEdge));
 
     basegfx::B2DHomMatrix aRotation;
     aRotation.rotate( double( nOtherAngle ) * M_PI / 18000.0 );
@@ -1377,7 +1403,8 @@ double lcl_GetExtent( const Style& rBorder, const Style& rSide, const Style& rOp
     basegfx::B2DVector aOtherVector = aRotation * aBaseVector;
     // Compute a line shifted by half the width of the other border
     basegfx::B2DVector aPerpendicular = basegfx::getNormalizedPerpendicular( aOtherVector );
-    basegfx::B2DPoint aOtherPoint = basegfx::B2DPoint() + aPerpendicular * aOtherBorder.GetWidth() / 2;
+    // added support to get the distances to the centers of the line, *not* the outre edge
+    basegfx::B2DPoint aOtherPoint = basegfx::B2DPoint() + aPerpendicular * lcl_getCenterOfLineOffset(aOtherBorder, bOtherLeft);
 
     // Find the cut between the two lines
     double nCut = 0.0;
@@ -1403,10 +1430,10 @@ drawinglayer::primitive2d::Primitive2DReference CreateBorderPrimitives(
             rBorder.Prim(),
             rBorder.Dist(),
             rBorder.Secn(),
-            lcl_GetExtent( rBorder, rLFromT, rLFromB, nRotateT, - nRotateB ),
-            lcl_GetExtent( rBorder, rRFromT, rRFromB, 18000 - nRotateT, nRotateB - 18000 ),
-            lcl_GetExtent( rBorder, rLFromB, rLFromT, nRotateB, - nRotateT ),
-            lcl_GetExtent( rBorder, rRFromB, rRFromT, 18000 - nRotateB, nRotateT - 18000 ),
+            lcl_GetExtent( rBorder, rLFromT, rLFromB, nRotateT, - nRotateB, true, false ),                  // top-left, so left for rBorder and right for left outer
+            lcl_GetExtent( rBorder, rRFromT, rRFromB, 18000 - nRotateT, nRotateB - 18000, true, true ),     // top-right
+            lcl_GetExtent( rBorder, rLFromB, rLFromT, nRotateB, - nRotateT, false, false ),                 // bottom-left
+            lcl_GetExtent( rBorder, rRFromB, rRFromT, 18000 - nRotateB, nRotateT - 18000, false, true ),    // bottom-right
             rBorder.GetColorSecn().getBColor(),
             rBorder.GetColorPrim().getBColor(),
             rBorder.GetColorGap().getBColor(),
commit 6e545e10121370b6eb4a54aee1300698cae44ab5
Author: Armin Le Grand <Armin.Le.Grand at cib.de>
Date:   Tue Jul 4 16:28:58 2017 +0200

    borderline: correct problems with border display
    
    Borderline display with direct paint and with primitive direct
    paint has quite some errors in the current state. Started to
    unify usages, check deeper with creation/usage.
    
    Change-Id: I4c1b380a76cb37389fab1259a53fb7cc9da982d1

diff --git a/drawinglayer/Library_drawinglayer.mk b/drawinglayer/Library_drawinglayer.mk
index 8c431c8ec08f..32daccd9d43e 100644
--- a/drawinglayer/Library_drawinglayer.mk
+++ b/drawinglayer/Library_drawinglayer.mk
@@ -67,7 +67,6 @@ $(eval $(call gb_Library_add_exception_objects,drawinglayer,\
     drawinglayer/source/primitive2d/baseprimitive2d \
     drawinglayer/source/primitive2d/bitmapprimitive2d \
     drawinglayer/source/primitive2d/borderlineprimitive2d \
-    drawinglayer/source/primitive2d/clippedborderlineprimitive2d \
     drawinglayer/source/primitive2d/controlprimitive2d \
 	drawinglayer/source/primitive2d/cropprimitive2d \
     drawinglayer/source/primitive2d/discretebitmapprimitive2d \
diff --git a/drawinglayer/source/primitive2d/clippedborderlineprimitive2d.cxx b/drawinglayer/source/primitive2d/clippedborderlineprimitive2d.cxx
deleted file mode 100644
index ca44a2838909..000000000000
--- a/drawinglayer/source/primitive2d/clippedborderlineprimitive2d.cxx
+++ /dev/null
@@ -1,64 +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/.
- */
-
-#include <drawinglayer/primitive2d/clippedborderlineprimitive2d.hxx>
-#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
-
-namespace drawinglayer
-{
-    namespace primitive2d
-    {
-        basegfx::B2DPolyPolygon ClippedBorderLinePrimitive2D::getClipPolygon(
-            SAL_UNUSED_PARAMETER geometry::ViewInformation2D const&) const
-        {
-            basegfx::B2DPolyPolygon aPolyPolygon;
-            aPolyPolygon.append( maIntersection );
-            return aPolyPolygon;
-        }
-
-        ClippedBorderLinePrimitive2D::ClippedBorderLinePrimitive2D(
-            const basegfx::B2DPoint& rStart,
-            const basegfx::B2DPoint& rEnd,
-            double fLeftWidth,
-            double fDistance,
-            double fRightWidth,
-            const basegfx::B2DPolygon& rIntersection,
-            const basegfx::BColor& rRGBColorRight,
-            const basegfx::BColor& rRGBColorLeft,
-            const basegfx::BColor& rRGBColorGap,
-            bool bHasGapColor,
-            SvxBorderLineStyle nStyle,
-            double fPatternScale)
-        :   BorderLinePrimitive2D( rStart, rEnd, fLeftWidth,fDistance, fRightWidth,
-                        0.0, 0.0, 0.0, 0.0, rRGBColorRight, rRGBColorLeft,
-                        rRGBColorGap, bHasGapColor, nStyle, fPatternScale),
-            maIntersection( rIntersection )
-        {
-        }
-
-        bool ClippedBorderLinePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
-        {
-            if(BorderLinePrimitive2D::operator==(rPrimitive))
-            {
-                const ClippedBorderLinePrimitive2D& rCompare = static_cast<const ClippedBorderLinePrimitive2D&>(rPrimitive);
-
-                return maIntersection == rCompare.maIntersection;
-            }
-
-            return false;
-        }
-
-        // provide unique ID
-        ImplPrimitive2DIDBlock(ClippedBorderLinePrimitive2D, PRIMITIVE2D_ID_CLIPPEDBORDERLINEPRIMITIVE2D)
-
-
-    } // namespace primitive2d
-} // namespace drawinglayer
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/drawinglayer/primitive2d/clippedborderlineprimitive2d.hxx b/include/drawinglayer/primitive2d/clippedborderlineprimitive2d.hxx
deleted file mode 100644
index 3fe2813be9a9..000000000000
--- a/include/drawinglayer/primitive2d/clippedborderlineprimitive2d.hxx
+++ /dev/null
@@ -1,65 +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/.
- */
-
-#ifndef INCLUDED_DRAWINGLAYER_PRIMITIVE2D_CLIPPEDBORDERLINEPRIMITIVE2D_HXX
-#define INCLUDED_DRAWINGLAYER_PRIMITIVE2D_CLIPPEDBORDERLINEPRIMITIVE2D_HXX
-
-#include <drawinglayer/drawinglayerdllapi.h>
-
-#include <drawinglayer/primitive2d/borderlineprimitive2d.hxx>
-#include <basegfx/polygon/b2dpolypolygon.hxx>
-#include <basegfx/polygon/b2dpolygon.hxx>
-
-
-namespace drawinglayer
-{
-    namespace primitive2d
-    {
-        /** BorderLinePrimitive2D clipped by the intersection with a provided
-            polygon.
-         */
-        class DRAWINGLAYER_DLLPUBLIC ClippedBorderLinePrimitive2D : public BorderLinePrimitive2D
-        {
-        private:
-            const basegfx::B2DPolygon maIntersection;
-
-        protected:
-            virtual basegfx::B2DPolyPolygon getClipPolygon(
-                    const geometry::ViewInformation2D& rViewInformation) const override;
-
-        public:
-            /// constructor
-            ClippedBorderLinePrimitive2D(
-                const basegfx::B2DPoint& rStart,
-                const basegfx::B2DPoint& rEnd,
-                double fLeftWidth,
-                double fDistance,
-                double fRightWidth,
-                const basegfx::B2DPolygon& rIntersection,
-                const basegfx::BColor& rRGBColorRight,
-                const basegfx::BColor& rRGBColorLeft,
-                const basegfx::BColor& rRGBColorGap,
-                bool bHasGapColor,
-                SvxBorderLineStyle nStyle,
-                double fPatternScale );
-
-            /// compare operator
-            virtual bool operator==(const BasePrimitive2D& rPrimitive) const override;
-
-            /// provide unique ID
-            DeclPrimitive2DIDBlock()
-        };
-    } // end of namespace primitive2d
-} // end of namespace drawinglayer
-
-
-#endif //INCLUDED_DRAWINGLAYER_PRIMITIVE2D_CLIPPEDBORDERLINEPRIMITIVE2D_HXX
-
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/svx/framelink.hxx b/include/svx/framelink.hxx
index 20ef1dbc6dcc..d5a962acdb1d 100644
--- a/include/svx/framelink.hxx
+++ b/include/svx/framelink.hxx
@@ -429,7 +429,7 @@ SVX_DLLPUBLIC bool CheckFrameBorderConnectable(
                     |       \                       /       |
                  rLFromB      \                   /      rRFromB
  */
-SVX_DLLPUBLIC drawinglayer::primitive2d::Primitive2DContainer CreateBorderPrimitives(
+SVX_DLLPUBLIC drawinglayer::primitive2d::Primitive2DReference CreateBorderPrimitives(
     const Point&        rLPos,          /// Reference point for left end of the processed frame border.
     const Point&        rRPos,          /// Reference point for right end of the processed frame border.
     const Style&        rBorder,        /// Style of the processed frame border.
@@ -451,7 +451,7 @@ SVX_DLLPUBLIC drawinglayer::primitive2d::Primitive2DContainer CreateBorderPrimit
     const long          rRotationB = 9000  /// Angle of the bottom slanted frames in 100th of degree
 );
 
-SVX_DLLPUBLIC drawinglayer::primitive2d::Primitive2DContainer CreateBorderPrimitives(
+SVX_DLLPUBLIC drawinglayer::primitive2d::Primitive2DReference CreateBorderPrimitives(
     const Point&        rLPos,          /// Reference point for left end of the processed frame border.
     const Point&        rRPos,          /// Reference point for right end of the processed frame border.
     const Style&        rBorder,        /// Style of the processed frame border.
@@ -469,10 +469,6 @@ SVX_DLLPUBLIC drawinglayer::primitive2d::Primitive2DContainer CreateBorderPrimit
     const long          rRotationB = 9000  /// Angle of the bottom slanted frame in 100th of degrees
 );
 
-SVX_DLLPUBLIC drawinglayer::primitive2d::Primitive2DContainer CreateClippedBorderPrimitives (
-        const Point& rStart, const Point& rEnd, const Style& rBorder,
-        const tools::Rectangle& rClipRect );
-
 /** Draws a horizontal frame border, regards all connected frame styles.
 
     The frame style to draw is passed as parameter rBorder. The function
diff --git a/sc/source/ui/view/output.cxx b/sc/source/ui/view/output.cxx
index a1d4db5e12e5..059ed109c862 100644
--- a/sc/source/ui/view/output.cxx
+++ b/sc/source/ui/view/output.cxx
@@ -1759,58 +1759,70 @@ void ScOutputData::DrawRotatedFrame(vcl::RenderContext& rRenderContext, const Co
                         if (aTopLine.Prim() || aTopLine.Secn())
                         {
                             long nUpperRotate = lcl_getRotate( mpDoc, nTab, nX, nY - 1 );
-                            pProcessor->process( svx::frame::CreateBorderPrimitives(
-                                        aPoints[bLayoutRTL?1:0], aPoints[bLayoutRTL?0:1], aTopLine,
-                                        svx::frame::Style(),
-                                        svx::frame::Style(),
-                                        aLeftLine,
-                                        svx::frame::Style(),
-                                        svx::frame::Style(),
-                                        aRightLine,
-                                        pForceColor, nUpperRotate, nAttrRotate ) );
+                            drawinglayer::primitive2d::Primitive2DContainer aSequence(1);
+                            aSequence.append(
+                                svx::frame::CreateBorderPrimitives(
+                                    aPoints[bLayoutRTL?1:0], aPoints[bLayoutRTL?0:1], aTopLine,
+                                    svx::frame::Style(),
+                                    svx::frame::Style(),
+                                    aLeftLine,
+                                    svx::frame::Style(),
+                                    svx::frame::Style(),
+                                    aRightLine,
+                                    pForceColor, nUpperRotate, nAttrRotate ) );
+                            pProcessor->process(aSequence);
                         }
 
                         if (aBottomLine.Prim() || aBottomLine.Secn())
                         {
                             long nLowerRotate = lcl_getRotate( mpDoc, nTab, nX, nY + 1 );
-                            pProcessor->process( svx::frame::CreateBorderPrimitives(
-                                        aPoints[bLayoutRTL?2:3], aPoints[bLayoutRTL?3:2], aBottomLine,
-                                        aLeftLine,
-                                        svx::frame::Style(),
-                                        svx::frame::Style(),
-                                        aRightLine,
-                                        svx::frame::Style(),
-                                        svx::frame::Style(),
-                                        pForceColor, 18000 - nAttrRotate, 18000 - nLowerRotate ) );
+                            drawinglayer::primitive2d::Primitive2DContainer aSequence(1);
+                            aSequence.append(
+                                svx::frame::CreateBorderPrimitives(
+                                    aPoints[bLayoutRTL?2:3], aPoints[bLayoutRTL?3:2], aBottomLine,
+                                    aLeftLine,
+                                    svx::frame::Style(),
+                                    svx::frame::Style(),
+                                    aRightLine,
+                                    svx::frame::Style(),
+                                    svx::frame::Style(),
+                                    pForceColor, 18000 - nAttrRotate, 18000 - nLowerRotate ) );
+                            pProcessor->process(aSequence);
                         }
 
                         // Vertical slanted lines
                         if (aLeftLine.Prim() || aLeftLine.Secn())
                         {
                             long nLeftRotate = lcl_getRotate( mpDoc, nTab, nX - 1, nY );
-                            pProcessor->process( svx::frame::CreateBorderPrimitives(
-                                        aPoints[0], aPoints[3], aLeftLine,
-                                        aTopLine,
-                                        svx::frame::Style(),
-                                        svx::frame::Style(),
-                                        aBottomLine,
-                                        svx::frame::Style(),
-                                        svx::frame::Style(),
-                                        pForceColor, nAttrRotate, nLeftRotate ) );
+                            drawinglayer::primitive2d::Primitive2DContainer aSequence(1);
+                            aSequence.append(
+                                svx::frame::CreateBorderPrimitives(
+                                    aPoints[0], aPoints[3], aLeftLine,
+                                    aTopLine,
+                                    svx::frame::Style(),
+                                    svx::frame::Style(),
+                                    aBottomLine,
+                                    svx::frame::Style(),
+                                    svx::frame::Style(),
+                                    pForceColor, nAttrRotate, nLeftRotate ) );
+                            pProcessor->process(aSequence);
                         }
 
                         if (aRightLine.Prim() || aRightLine.Secn())
                         {
                             long nRightRotate = lcl_getRotate( mpDoc, nTab, nX + 1, nY );
-                            pProcessor->process( svx::frame::CreateBorderPrimitives(
-                                        aPoints[1], aPoints[2], aRightLine,
-                                        svx::frame::Style(),
-                                        svx::frame::Style(),
-                                        aTopLine,
-                                        svx::frame::Style(),
-                                        svx::frame::Style(),
-                                        aBottomLine,
-                                        pForceColor, 18000 - nRightRotate, 18000 - nAttrRotate ) );
+                            drawinglayer::primitive2d::Primitive2DContainer aSequence(1);
+                            aSequence.append(
+                                svx::frame::CreateBorderPrimitives(
+                                    aPoints[1], aPoints[2], aRightLine,
+                                    svx::frame::Style(),
+                                    svx::frame::Style(),
+                                    aTopLine,
+                                    svx::frame::Style(),
+                                    svx::frame::Style(),
+                                    aBottomLine,
+                                    pForceColor, 18000 - nRightRotate, 18000 - nAttrRotate ) );
+                            pProcessor->process(aSequence);
                         }
                     }
                 }
diff --git a/svx/source/dialog/framelink.cxx b/svx/source/dialog/framelink.cxx
index 2de6d3dae281..3da2af55fb46 100644
--- a/svx/source/dialog/framelink.cxx
+++ b/svx/source/dialog/framelink.cxx
@@ -33,7 +33,6 @@
 #include <basegfx/polygon/b2dpolygontools.hxx>
 
 #include <drawinglayer/primitive2d/borderlineprimitive2d.hxx>
-#include <drawinglayer/primitive2d/clippedborderlineprimitive2d.hxx>
 
 
 using namespace ::com::sun::star;
@@ -1389,67 +1388,32 @@ double lcl_GetExtent( const Style& rBorder, const Style& rSide, const Style& rOp
     return nCut;
 }
 
-basegfx::B2DPoint lcl_PointToB2DPoint( const Point& rPoint )
-{
-    return basegfx::B2DPoint(rPoint.getX(), rPoint.getY());
-}
-
-drawinglayer::primitive2d::Primitive2DContainer CreateClippedBorderPrimitives (
-        const Point& rStart, const Point& rEnd, const Style& rBorder,
-        const tools::Rectangle& rClipRect )
-{
-    drawinglayer::primitive2d::Primitive2DContainer aSequence( 1 );
-    basegfx::B2DPolygon aPolygon;
-    aPolygon.append( lcl_PointToB2DPoint( rClipRect.TopLeft( ) ) );
-    aPolygon.append( lcl_PointToB2DPoint( rClipRect.TopRight( ) ) );
-    aPolygon.append( lcl_PointToB2DPoint( rClipRect.BottomRight( ) ) );
-    aPolygon.append( lcl_PointToB2DPoint( rClipRect.BottomLeft( ) ) );
-    aPolygon.setClosed( true );
-
-    aSequence[0] = new drawinglayer::primitive2d::ClippedBorderLinePrimitive2D(
-        lcl_PointToB2DPoint( rStart ),
-        lcl_PointToB2DPoint( rEnd ),
-        rBorder.Prim(),
-        rBorder.Dist(),
-        rBorder.Secn(),
-        aPolygon,
-        rBorder.GetColorSecn().getBColor(),
-        rBorder.GetColorPrim().getBColor(),
-        rBorder.GetColorGap().getBColor(),
-        rBorder.UseGapColor(), rBorder.Type(), rBorder.PatternScale() );
-
-    return aSequence;
-}
-
-drawinglayer::primitive2d::Primitive2DContainer CreateBorderPrimitives(
+drawinglayer::primitive2d::Primitive2DReference CreateBorderPrimitives(
         const Point& rLPos, const Point& rRPos, const Style& rBorder,
         const DiagStyle& /*rLFromTR*/, const Style& rLFromT, const Style& /*rLFromL*/, const Style& rLFromB, const DiagStyle& /*rLFromBR*/,
         const DiagStyle& /*rRFromTL*/, const Style& rRFromT, const Style& /*rRFromR*/, const Style& rRFromB, const DiagStyle& /*rRFromBL*/,
         const Color* /*pForceColor*/, long nRotateT, long nRotateB )
 {
-    drawinglayer::primitive2d::Primitive2DContainer aSequence( 1 );
-
     basegfx::B2DPoint aStart( rLPos.getX(), rLPos.getY() );
     basegfx::B2DPoint aEnd( rRPos.getX(), rRPos.getY() );
 
-    aSequence[0] = new drawinglayer::primitive2d::BorderLinePrimitive2D(
-        aStart, aEnd,
-        rBorder.Prim(),
-        rBorder.Dist(),
-        rBorder.Secn(),
-        lcl_GetExtent( rBorder, rLFromT, rLFromB, nRotateT, - nRotateB ),
-        lcl_GetExtent( rBorder, rRFromT, rRFromB, 18000 - nRotateT, nRotateB - 18000 ),
-        lcl_GetExtent( rBorder, rLFromB, rLFromT, nRotateB, - nRotateT ),
-        lcl_GetExtent( rBorder, rRFromB, rRFromT, 18000 - nRotateB, nRotateT - 18000 ),
-        rBorder.GetColorSecn().getBColor(),
-        rBorder.GetColorPrim().getBColor(),
-        rBorder.GetColorGap().getBColor(),
-        rBorder.UseGapColor(), rBorder.Type(), rBorder.PatternScale() );
-
-    return aSequence;
+    return drawinglayer::primitive2d::Primitive2DReference(
+        new drawinglayer::primitive2d::BorderLinePrimitive2D(
+            aStart, aEnd,
+            rBorder.Prim(),
+            rBorder.Dist(),
+            rBorder.Secn(),
+            lcl_GetExtent( rBorder, rLFromT, rLFromB, nRotateT, - nRotateB ),
+            lcl_GetExtent( rBorder, rRFromT, rRFromB, 18000 - nRotateT, nRotateB - 18000 ),
+            lcl_GetExtent( rBorder, rLFromB, rLFromT, nRotateB, - nRotateT ),
+            lcl_GetExtent( rBorder, rRFromB, rRFromT, 18000 - nRotateB, nRotateT - 18000 ),
+            rBorder.GetColorSecn().getBColor(),
+            rBorder.GetColorPrim().getBColor(),
+            rBorder.GetColorGap().getBColor(),
+            rBorder.UseGapColor(), rBorder.Type(), rBorder.PatternScale()));
 }
 
-drawinglayer::primitive2d::Primitive2DContainer CreateBorderPrimitives(
+drawinglayer::primitive2d::Primitive2DReference CreateBorderPrimitives(
         const Point& rLPos, const Point& rRPos, const Style& rBorder,
         const Style& rLFromT, const Style& rLFromL, const Style& rLFromB,
         const Style& rRFromT, const Style& rRFromR, const Style& rRFromB,
diff --git a/svx/source/dialog/framelinkarray.cxx b/svx/source/dialog/framelinkarray.cxx
index 079a12b9acb3..dd30b93f6074 100644
--- a/svx/source/dialog/framelinkarray.cxx
+++ b/svx/source/dialog/framelinkarray.cxx
@@ -23,6 +23,7 @@
 #include <vector>
 #include <algorithm>
 #include <vcl/outdev.hxx>
+#include <drawinglayer/primitive2d/borderlineprimitive2d.hxx>
 
 namespace svx {
 namespace frame {
@@ -907,23 +908,52 @@ void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D* pProcessor,
                     size_t _nFirstRow = mxImpl->GetMergedFirstRow( nCol, nRow );
 
                     const Style aTlbrStyle = GetCellStyleTLBR( _nFirstCol, _nFirstRow );
-                    if ( aTlbrStyle.GetWidth( ) )
-                        pProcessor->process( CreateClippedBorderPrimitives(
-                                    aRect.TopLeft(), aRect.BottomRight(),
-                                    aTlbrStyle, aRect ) );
+                    if (aTlbrStyle.GetWidth())
+                    {
+                        drawinglayer::primitive2d::Primitive2DContainer aSequence(1);
+                        aSequence.append(
+                            new drawinglayer::primitive2d::BorderLinePrimitive2D(
+                                basegfx::B2DPoint(aRect.Left(), aRect.Top()),
+                                basegfx::B2DPoint(aRect.Right(), aRect.Bottom()),
+                                aTlbrStyle.Prim(),
+                                aTlbrStyle.Dist(),
+                                aTlbrStyle.Secn(),
+                                0.0, 0.0, 0.0, 0.0,
+                                aTlbrStyle.GetColorSecn().getBColor(),
+                                aTlbrStyle.GetColorPrim().getBColor(),
+                                aTlbrStyle.GetColorGap().getBColor(),
+                                aTlbrStyle.UseGapColor(),
+                                aTlbrStyle.Type(),
+                                aTlbrStyle.PatternScale()));
+                        pProcessor->process(aSequence);
+                    }
 
                     const Style aBltrStyle = GetCellStyleBLTR( _nFirstCol, _nFirstRow );
-                    if ( aBltrStyle.GetWidth( ) )
-                        pProcessor->process( CreateClippedBorderPrimitives(
-                                    aRect.BottomLeft(), aRect.TopRight(),
-                                    aBltrStyle, aRect ) );
+                    if (aBltrStyle.GetWidth())
+                    {
+                        drawinglayer::primitive2d::Primitive2DContainer aSequence(1);
+                        aSequence.append(
+                            new drawinglayer::primitive2d::BorderLinePrimitive2D(
+                                basegfx::B2DPoint(aRect.Left(), aRect.Bottom()),
+                                basegfx::B2DPoint(aRect.Right(), aRect.Top()),
+                                aBltrStyle.Prim(),
+                                aBltrStyle.Dist(),
+                                aBltrStyle.Secn(),
+                                0.0, 0.0, 0.0, 0.0,
+                                aBltrStyle.GetColorSecn().getBColor(),
+                                aBltrStyle.GetColorPrim().getBColor(),
+                                aBltrStyle.GetColorGap().getBColor(),
+                                aBltrStyle.UseGapColor(),
+                                aBltrStyle.Type(),
+                                aBltrStyle.PatternScale()));
+                        pProcessor->process(aSequence);
+                    }
                 }
             }
         }
     }
 
     // *** horizontal frame borders ***
-
     for( nRow = nFirstRow; nRow <= nLastRow + 1; ++nRow )
     {
         double fAngle = mxImpl->GetHorDiagAngle( nFirstCol, nRow );
@@ -970,10 +1000,16 @@ void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D* pProcessor,
             {
                 // draw previous frame border
                 Point aEndPos( mxImpl->GetColPosition( nCol ), aStartPos.Y() );
-                if( pStart->Prim() && (aStartPos.X() <= aEndPos.X()) )
-                   pProcessor->process( CreateBorderPrimitives( aStartPos, aEndPos, *pStart,
-                        aStartLFromTR, *pStartLFromT, *pStartLFromL, *pStartLFromB, aStartLFromBR,
-                        aEndRFromTL, *pEndRFromT, *pEndRFromR, *pEndRFromB, aEndRFromBL, pForceColor ) );
+                if (pStart->Prim() && (aStartPos.X() <= aEndPos.X()))
+                {
+                    drawinglayer::primitive2d::Primitive2DContainer aSequence(1);
+                    aSequence.append(
+                        CreateBorderPrimitives(
+                            aStartPos, aEndPos, *pStart,
+                            aStartLFromTR, *pStartLFromT, *pStartLFromL, *pStartLFromB, aStartLFromBR,
+                            aEndRFromTL, *pEndRFromT, *pEndRFromR, *pEndRFromB, aEndRFromBL, pForceColor));
+                    pProcessor->process(aSequence);
+                }
 
                 // re-init "*Start***" variables
                 aStartPos = aEndPos;
@@ -995,10 +1031,16 @@ void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D* pProcessor,
 
         // draw last frame border
         Point aEndPos( mxImpl->GetColPosition( nCol ), aStartPos.Y() );
-        if( pStart->Prim() && (aStartPos.X() <= aEndPos.X()) )
-            pProcessor->process( CreateBorderPrimitives( aStartPos, aEndPos, *pStart,
-                aStartLFromTR, *pStartLFromT, *pStartLFromL, *pStartLFromB, aStartLFromBR,
-                aEndRFromTL, *pEndRFromT, *pEndRFromR, *pEndRFromB, aEndRFromBL, pForceColor ) );
+        if (pStart->Prim() && (aStartPos.X() <= aEndPos.X()))
+        {
+            drawinglayer::primitive2d::Primitive2DContainer aSequence(1);
+            aSequence.append(
+                CreateBorderPrimitives(
+                    aStartPos, aEndPos, *pStart,
+                    aStartLFromTR, *pStartLFromT, *pStartLFromL, *pStartLFromB, aStartLFromBR,
+                    aEndRFromTL, *pEndRFromT, *pEndRFromR, *pEndRFromB, aEndRFromBL, pForceColor));
+            pProcessor->process(aSequence);
+        }
     }
 
     // *** vertical frame borders ***
@@ -1048,10 +1090,16 @@ void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D* pProcessor,
             {
                 // draw previous frame border
                 Point aEndPos( aStartPos.X(), mxImpl->GetRowPosition( nRow ) );
-                if( pStart->Prim() && (aStartPos.Y() <= aEndPos.Y()) )
-                    pProcessor->process( CreateBorderPrimitives( aEndPos, aStartPos, *pStart,
-                        aEndBFromTL, *pEndBFromL, *pEndBFromB, *pEndBFromR, aEndBFromTR,
-                        aStartTFromBL, *pStartTFromL, *pStartTFromT, *pStartTFromR, aStartTFromBR, pForceColor ) );
+                if (pStart->Prim() && (aStartPos.Y() <= aEndPos.Y()))
+                {
+                    drawinglayer::primitive2d::Primitive2DContainer aSequence(1);
+                    aSequence.append(
+                        CreateBorderPrimitives(
+                            aEndPos, aStartPos, *pStart,
+                            aEndBFromTL, *pEndBFromL, *pEndBFromB, *pEndBFromR, aEndBFromTR,
+                            aStartTFromBL, *pStartTFromL, *pStartTFromT, *pStartTFromR, aStartTFromBR, pForceColor));
+                    pProcessor->process(aSequence);
+                }
 
                 // re-init "*Start***" variables
                 aStartPos = aEndPos;
@@ -1073,10 +1121,15 @@ void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D* pProcessor,
 
         // draw last frame border
         Point aEndPos( aStartPos.X(), mxImpl->GetRowPosition( nRow ) );
-        if( pStart->Prim() && (aStartPos.Y() <= aEndPos.Y()) )
-            pProcessor->process( CreateBorderPrimitives( aEndPos, aStartPos, *pStart,
-                aEndBFromTL, *pEndBFromL, *pEndBFromB, *pEndBFromR, aEndBFromTR,

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list