summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArmin Le Grand <Armin.Le.Grand@cib.de>2017-07-21 17:34:40 +0200
committerArmin Le Grand <Armin.Le.Grand@cib.de>2017-07-28 17:51:56 +0200
commitbc47d7138a8d8dd239831a38bb2eca9db13addb6 (patch)
tree8108764902d60d5d34eea60ba64caf7b7e1a7c2c
parente32c12a444e5bd0c6735db8e8008340c29a7e25e (diff)
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
-rw-r--r--drawinglayer/source/primitive2d/borderlineprimitive2d.cxx4
-rw-r--r--svx/source/dialog/framelink.cxx300
2 files changed, 301 insertions, 3 deletions
diff --git a/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
index 84ea9fff10ca..a9822d6bcd06 100644
--- a/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
@@ -144,8 +144,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 c193285b1a25..de93c9372d88 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);