[Libreoffice-commits] core.git: Branch 'feature/borderline2' - drawinglayer/source svx/source

Armin Le Grand Armin.Le.Grand at cib.de
Fri Jul 21 15:33:55 UTC 2017


 drawinglayer/source/primitive2d/borderlineprimitive2d.cxx |    4 
 svx/source/dialog/framelink.cxx                           |  300 +++++++++++++-
 2 files changed, 301 insertions(+), 3 deletions(-)

New commits:
commit 0a17f1fd08a872804f25e09c0e5497d11690e0d1
Author: Armin Le Grand <Armin.Le.Grand at cib.de>
Date:   Fri Jul 21 17:34:40 2017 +0200

    borderline: first versionj with line end adaptions
    
    Added usage of defined extensions to the BorderLinePrimitive,
    also added a first version to detect all cuts with adjacent
    borders and produce the correct extensions, for single and
    double lines. Not completely happy with it, but a first
    version
    
    Change-Id: I4b12a6cc0a70278bd5c506e9b3b2c5c126930dad

diff --git a/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
index 9735cc1aa44d..eeed3d4f3995 100644
--- a/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
@@ -153,8 +153,8 @@ namespace drawinglayer
                     // single line, only inside values used, no vertical offsets
                     addPolygonStrokePrimitive2D(
                         rContainer,
-                        getStart(),
-                        getEnd(),
+                        getStart() - (aVector * getExtendLeftStart()),
+                        getEnd() + (aVector * getExtendLeftEnd()),
                         getRGBColorLeft(),
                         getLeftWidth(),
                         getStyle(),
diff --git a/svx/source/dialog/framelink.cxx b/svx/source/dialog/framelink.cxx
index 2aa0a85d936d..8700b665f33b 100644
--- a/svx/source/dialog/framelink.cxx
+++ b/svx/source/dialog/framelink.cxx
@@ -345,6 +345,153 @@ double lcl_GetExtent(
     return nCut;
 }
 
+void getOffsetsFromStyle(const Style& rStyle, std::vector< double >& offsets)
+{
+    if (rStyle.Prim())
+    {
+        if (rStyle.Dist() && rStyle.Secn())
+        {
+            // both lines used (or all three), push four values, from outer to inner
+            switch (rStyle.GetRefMode())
+            {
+            case RefMode::Centered:
+            {
+                const double fHalfFullWidth(rStyle.GetWidth() * 0.5);
+                offsets.push_back(-fHalfFullWidth);
+                offsets.push_back(rStyle.Prim() - fHalfFullWidth);
+                offsets.push_back((rStyle.Prim() + rStyle.Dist()) - fHalfFullWidth);
+                offsets.push_back(fHalfFullWidth);
+                break;
+            }
+            case RefMode::Begin:
+                offsets.push_back(0.0);
+                offsets.push_back(rStyle.Prim());
+                offsets.push_back(rStyle.Prim() + rStyle.Dist());
+                offsets.push_back(rStyle.GetWidth());
+                break;
+            default: // case RefMode::End:
+            {
+                const double fFullWidth(rStyle.GetWidth());
+                offsets.push_back(-fFullWidth);
+                offsets.push_back(rStyle.Prim() - fFullWidth);
+                offsets.push_back((rStyle.Prim() + rStyle.Dist()) - fFullWidth);
+                offsets.push_back(0.0);
+                break;
+            }
+            }
+        }
+        else
+        {
+            // one line used, push two values, from outer to inner
+            switch (rStyle.GetRefMode())
+            {
+            case RefMode::Centered:
+                offsets.push_back(rStyle.Prim() * -0.5);
+                offsets.push_back(rStyle.Prim() * 0.5);
+                break;
+            case RefMode::Begin:
+                offsets.push_back(0.0);
+                offsets.push_back(rStyle.Prim());
+                break;
+            default: // case RefMode::End:
+                offsets.push_back(-rStyle.Prim());
+                offsets.push_back(0.0);
+                break;
+            }
+        }
+    }
+}
+
+void compareToStyle(
+    const basegfx::B2DPoint& rOrigin,
+    const basegfx::B2DVector& rOtherVector,
+    const basegfx::B2DVector& rOtherUnifiedPerpendicular,
+    const std::vector< double >& rOtherOffsets,
+    const Style& rStyle,
+    const basegfx::B2DVector& rMyVector,
+    std::vector< std::vector< double >>& rOtherCuts)
+{
+    if (rStyle.Prim())
+    {
+        std::vector< double > myOffsets;
+
+        // get offsets from outer to inner (two or four, depending on style)
+        getOffsetsFromStyle(rStyle, myOffsets);
+
+        if (!myOffsets.empty())
+        {
+            const basegfx::B2DVector aMyUnifiedPerpendicular(basegfx::getNormalizedPerpendicular(rMyVector));
+
+            for (size_t a(0); a < rOtherOffsets.size(); a++)
+            {
+                const basegfx::B2DPoint aOtherPos(rOrigin + (rOtherUnifiedPerpendicular * rOtherOffsets[a]));
+
+                for (size_t b(0); b < myOffsets.size(); b++)
+                {
+                    const basegfx::B2DPoint aMyPos(rOrigin + (aMyUnifiedPerpendicular * myOffsets[b]));
+                    double fCut(0.0);
+                    basegfx::tools::findCut(
+                        aOtherPos,
+                        rOtherVector,
+                        aMyPos,
+                        rMyVector,
+                        CutFlagValue::LINE,
+                        &fCut);
+
+                    rOtherCuts[a].push_back(fCut);
+                }
+            }
+        }
+    }
+}
+
+double getMinMaxCut(bool bMin, const std::vector< double >& rVector)
+{
+    if (rVector.empty())
+    {
+        return 0.0;
+    }
+
+    if (1 == rVector.size())
+    {
+        return rVector[0];
+    }
+
+    double fRetval(rVector[0]);
+
+    for (size_t a(1); a < rVector.size(); a++)
+    {
+        fRetval = bMin ? std::min(fRetval, rVector[a]) : std::max(fRetval, rVector[a]);
+    }
+
+    return fRetval;
+}
+
+std::vector< double > getMinMaxCuts(bool bMin, const std::vector< std::vector< double >>& rCuts)
+{
+    std::vector< double > aRetval(rCuts.size());
+
+    for (size_t a(0); a < rCuts.size(); a++)
+    {
+        aRetval[a] = getMinMaxCut(bMin, rCuts[a]);
+    }
+
+    return aRetval;
+}
+
+bool areCutsEmpty(std::vector< std::vector< double >>& rCuts)
+{
+    for (const auto& rVec : rCuts)
+    {
+        if (!rVec.empty())
+        {
+            return false;
+        }
+    }
+
+    return true;
+}
+
 void CreateBorderPrimitives(
     drawinglayer::primitive2d::Primitive2DContainer& rTarget,
     const basegfx::B2DPoint& rOrigin,
@@ -363,7 +510,158 @@ void CreateBorderPrimitives(
     const DiagStyle& /*rRFromBL*/,
     const Color* pForceColor)
 {
-    if (rBorder.Prim() || rBorder.Secn())
+    static bool bCheckNewStuff(true);
+
+    if (bCheckNewStuff && rBorder.Prim())
+    {
+        double mfExtendLeftStart(0.0);
+        double mfExtendLeftEnd(0.0);
+        double mfExtendRightStart(0.0);
+        double mfExtendRightEnd(0.0);
+        std::vector< double > myOffsets;
+        getOffsetsFromStyle(rBorder, myOffsets);
+        const basegfx::B2DVector aPerpendX(basegfx::getNormalizedPerpendicular(rX));
+        const double fLength(rX.getLength());
+
+        if (2 == myOffsets.size())
+        {
+            std::vector< std::vector< double >> myCutsS(myOffsets.size());
+            compareToStyle(rOrigin, rX, aPerpendX, myOffsets, rLFromT, rY, myCutsS);
+            compareToStyle(rOrigin, rX, aPerpendX, myOffsets, rLFromB, rY, myCutsS);
+            std::vector< double > nMinCutsS(getMinMaxCuts(true, myCutsS));
+            mfExtendLeftStart = ((nMinCutsS[0] + nMinCutsS[1]) * 0.5) * -1.0 * fLength;
+
+            std::vector< std::vector< double >> myCutsE(myOffsets.size());
+            compareToStyle(rOrigin, rX, aPerpendX, myOffsets, rRFromT, rY, myCutsE);
+            compareToStyle(rOrigin, rX, aPerpendX, myOffsets, rRFromB, rY, myCutsE);
+            std::vector< double > nMinCutsE(getMinMaxCuts(false, myCutsE));
+            mfExtendLeftEnd = ((nMinCutsE[0] + nMinCutsE[1]) * 0.5) * fLength;
+
+        }
+        else if (4 == myOffsets.size())
+        {
+            {
+                std::vector< double > myOffsetsA;
+                myOffsetsA.push_back(myOffsets[0]);
+                myOffsetsA.push_back(myOffsets[1]);
+
+                std::vector< std::vector< double >> myCutsS(myOffsetsA.size());
+                std::vector< double > nMinCutsS;
+                compareToStyle(rOrigin, rX, aPerpendX, myOffsetsA, rLFromT, rY, myCutsS);
+
+                if (!areCutsEmpty(myCutsS))
+                {
+                    nMinCutsS = getMinMaxCuts(false, myCutsS);
+                }
+                else
+                {
+                    compareToStyle(rOrigin, rX, aPerpendX, myOffsetsA, rLFromB, rY, myCutsS);
+                    nMinCutsS = getMinMaxCuts(true, myCutsS);
+                }
+
+                mfExtendLeftStart = ((nMinCutsS[0] + nMinCutsS[1]) * 0.5) * -1.0 * fLength;
+
+                std::vector< std::vector< double >> myCutsE(myOffsetsA.size());
+                std::vector< double > nMinCutsE;
+                compareToStyle(rOrigin, rX, aPerpendX, myOffsetsA, rRFromT, rY, myCutsE);
+
+                if (!areCutsEmpty(myCutsE))
+                {
+                    nMinCutsE = getMinMaxCuts(true, myCutsE);
+                }
+                else
+                {
+                    compareToStyle(rOrigin, rX, aPerpendX, myOffsetsA, rRFromB, rY, myCutsE);
+                    nMinCutsE = getMinMaxCuts(false, myCutsE);
+                }
+
+                mfExtendLeftEnd = ((nMinCutsE[0] + nMinCutsE[1]) * 0.5) * fLength;
+            }
+
+            {
+                std::vector< double > myOffsetsB;
+                myOffsetsB.push_back(myOffsets[2]);
+                myOffsetsB.push_back(myOffsets[3]);
+
+                std::vector< std::vector< double >> myCutsS(myOffsetsB.size());
+                std::vector< double > nMinCutsS;
+                compareToStyle(rOrigin, rX, aPerpendX, myOffsetsB, rLFromB, rY, myCutsS);
+
+                if (!areCutsEmpty(myCutsS))
+                {
+                    nMinCutsS = getMinMaxCuts(false, myCutsS);
+                }
+                else
+                {
+                    compareToStyle(rOrigin, rX, aPerpendX, myOffsetsB, rLFromT, rY, myCutsS);
+                    nMinCutsS = getMinMaxCuts(true, myCutsS);
+                }
+
+                mfExtendRightStart = ((nMinCutsS[0] + nMinCutsS[1]) * 0.5) * -1.0 * fLength;
+
+                std::vector< std::vector< double >> myCutsE(myOffsetsB.size());
+                std::vector< double > nMinCutsE;
+                compareToStyle(rOrigin, rX, aPerpendX, myOffsetsB, rRFromB, rY, myCutsE);
+
+                if (!areCutsEmpty(myCutsE))
+                {
+                    nMinCutsE = getMinMaxCuts(true, myCutsE);
+                }
+                else
+                {
+                    compareToStyle(rOrigin, rX, aPerpendX, myOffsetsB, rRFromT, rY, myCutsE);
+                    nMinCutsE = getMinMaxCuts(false, myCutsE);
+                }
+
+                mfExtendRightEnd = ((nMinCutsE[0] + nMinCutsE[1]) * 0.5) * fLength;
+            }
+        }
+
+        // do not forget RefMode offset, primitive will assume RefMode::Centered
+        basegfx::B2DVector aRefModeOffset;
+
+        if (RefMode::Centered != rBorder.GetRefMode())
+        {
+            const basegfx::B2DVector aPerpendX(basegfx::getNormalizedPerpendicular(rX));
+            const double fHalfWidth(rBorder.GetWidth() * 0.5);
+
+            if (RefMode::Begin == rBorder.GetRefMode())
+            {
+                // move aligned below vector
+                aRefModeOffset = aPerpendX * fHalfWidth;
+            }
+            else if (RefMode::End == rBorder.GetRefMode())
+            {
+                // move aligned above vector
+                aRefModeOffset = aPerpendX * -fHalfWidth;
+            }
+        }
+
+        // create start/end for RefMode::Centered
+        const basegfx::B2DPoint aStart(rOrigin + aRefModeOffset);
+        const basegfx::B2DPoint aEnd(aStart + rX);
+
+        rTarget.append(
+            drawinglayer::primitive2d::Primitive2DReference(
+                new drawinglayer::primitive2d::BorderLinePrimitive2D(
+                    aStart,
+                    aEnd,
+                    rBorder.Prim(),
+                    rBorder.Dist(),
+                    rBorder.Secn(),
+                    mfExtendLeftStart,
+                    mfExtendLeftEnd,
+                    mfExtendRightStart,
+                    mfExtendRightEnd,
+                    (pForceColor ? *pForceColor : rBorder.GetColorSecn()).getBColor(),
+                    (pForceColor ? *pForceColor : rBorder.GetColorPrim()).getBColor(),
+                    (pForceColor ? *pForceColor : rBorder.GetColorGap()).getBColor(),
+                    rBorder.UseGapColor(),
+                    rBorder.Type(),
+                    rBorder.PatternScale())));
+    }
+
+    if (!bCheckNewStuff && (rBorder.Prim() || rBorder.Secn()))
     {
         basegfx::B2DPoint aStart(rOrigin);
         basegfx::B2DPoint aEnd(rOrigin + rX);


More information about the Libreoffice-commits mailing list