summaryrefslogtreecommitdiff
path: root/svx
diff options
context:
space:
mode:
authorArmin Le Grand <Armin.Le.Grand@cib.de>2017-09-13 18:37:02 +0200
committerArmin Le Grand <Armin.Le.Grand@cib.de>2017-09-15 12:58:04 +0200
commit16fd7af90a9be159ebc7eab09083f1ef7eb64645 (patch)
tree2068f7b64609b6a231a803859297e108509ed428 /svx
parent1f02af4dbd13d79647549e1269722e2c0b67fa90 (diff)
borderline: extended the expand logic
Extended and checked the expand logic for creating the line extends. Now creating quite the right lines, will need to check some speccial cases. Also some cleanups. Change-Id: I3a3bd4d23c7017ecd873147df2d93af61de39fa6
Diffstat (limited to 'svx')
-rw-r--r--svx/source/dialog/framelink.cxx225
-rw-r--r--svx/source/dialog/framelinkarray.cxx8
2 files changed, 203 insertions, 30 deletions
diff --git a/svx/source/dialog/framelink.cxx b/svx/source/dialog/framelink.cxx
index c7a6377ab3e8..b7554436bf48 100644
--- a/svx/source/dialog/framelink.cxx
+++ b/svx/source/dialog/framelink.cxx
@@ -380,6 +380,7 @@ double getOffsetAndHalfWidthAndColorFromStyle(
Color aSecn(rStyle.GetColorSecn());
double fPrim(rStyle.Prim());
double fSecn(rStyle.Secn());
+ const bool bSecnUsed(0.0 != fSecn);
if(bMirrored)
{
@@ -389,8 +390,12 @@ double getOffsetAndHalfWidthAndColorFromStyle(
case RefMode::End: aRefMode = RefMode::Begin; break;
default: break;
}
- std::swap(aPrim, aSecn);
- std::swap(fPrim, fSecn);
+
+ if(bSecnUsed)
+ {
+ std::swap(aPrim, aSecn);
+ std::swap(fPrim, fSecn);
+ }
}
if (RefMode::Centered != aRefMode)
@@ -409,7 +414,7 @@ double getOffsetAndHalfWidthAndColorFromStyle(
}
}
- if (rStyle.Dist() && fSecn)
+ if (bSecnUsed)
{
// both or all three lines used
const bool bPrimTransparent(0xff == rStyle.GetColorPrim().GetTransparency());
@@ -503,6 +508,103 @@ void getCutSet(
&rCutSet.mfORMR);
}
+void getAllCutSets(
+ std::vector< CutSet >& rCutSets,
+ const basegfx::B2DPoint& rOrigin,
+ const basegfx::B2DPoint& rLeft,
+ const basegfx::B2DPoint& rRight,
+ const basegfx::B2DVector& rX,
+ const StyleVectorTable& rStyleVectorTable,
+ bool bUpper,
+ bool bLower)
+{
+ for(const auto& rStyleVectorCombination : rStyleVectorTable)
+ {
+ if(bUpper || bLower)
+ {
+ // use only upper or lower vectors compared to rX
+ const double fCross(rX.cross(rStyleVectorCombination.getB2DVector()));
+
+ if(bUpper && fCross > 0.0)
+ {
+ // upper vectors wanted, but is lower
+ continue;
+ }
+
+ if(bLower && fCross < 0.0)
+ {
+ // lower vectors wanted, but is upper
+ continue;
+ }
+ }
+
+ std::vector< OffsetAndHalfWidthAndColor > otherOffsets;
+ getOffsetAndHalfWidthAndColorFromStyle(rStyleVectorCombination.getStyle(), nullptr, rStyleVectorCombination.isMirrored(), otherOffsets);
+
+ if(!otherOffsets.empty())
+ {
+ const basegfx::B2DVector aOtherPerpend(basegfx::getNormalizedPerpendicular(rStyleVectorCombination.getB2DVector()));
+
+ for(const auto& rOtherOffset : otherOffsets)
+ {
+ const basegfx::B2DPoint aOtherLeft(rOrigin + (aOtherPerpend * (rOtherOffset.mfOffset - rOtherOffset.mfHalfWidth)));
+ const basegfx::B2DPoint aOtherRight(rOrigin + (aOtherPerpend * (rOtherOffset.mfOffset + rOtherOffset.mfHalfWidth)));
+ CutSet aCutSet;
+
+ getCutSet(aCutSet, rLeft, rRight, rX, aOtherLeft, aOtherRight, rStyleVectorCombination.getB2DVector());
+ rCutSets.push_back(aCutSet);
+ }
+ }
+ }
+}
+
+CutSet getMinMaxCutSet(
+ bool bMin,
+ const std::vector< CutSet >& rCutSets)
+{
+ if(rCutSets.empty())
+ {
+ CutSet aRetval;
+ aRetval.mfOLML = aRetval.mfORML = aRetval.mfOLMR = aRetval.mfORMR = 0.0;
+ return aRetval;
+ }
+
+ const size_t aSize(rCutSets.size());
+
+ if(1 == aSize)
+ {
+ return rCutSets[0];
+ }
+
+ CutSet aRetval(rCutSets[0]);
+ double fRetval(aRetval.mfOLML + aRetval.mfORML + aRetval.mfOLMR + aRetval.mfORMR);
+
+ for(size_t a(1); a < aSize; a++)
+ {
+ const CutSet& rCandidate(rCutSets[a]);
+ const double fCandidate(rCandidate.mfOLML + rCandidate.mfORML + rCandidate.mfOLMR + rCandidate.mfORMR);
+
+ if(bMin)
+ {
+ if(fCandidate < fRetval)
+ {
+ fRetval = fCandidate;
+ aRetval = rCandidate;
+ }
+ }
+ else
+ {
+ if(fCandidate > fRetval)
+ {
+ fRetval = fCandidate;
+ aRetval = rCandidate;
+ }
+ }
+ }
+
+ return aRetval;
+}
+
void getExtends(
std::vector<ExtendSet>& rExtendSet, // target Left/Right values to fill
const basegfx::B2DPoint& rOrigin, // own vector start
@@ -518,41 +620,99 @@ void getExtends(
for(size_t a(0); a < nOffsets; a++)
{
const OffsetAndHalfWidthAndColor& rOffset(rOffsets[a]);
- ExtendSet& rExt(rExtendSet[a]);
- bool bExtSet(false);
- const basegfx::B2DPoint aLeft(rOrigin + (rPerpendX * (rOffset.mfOffset - rOffset.mfHalfWidth)));
- const basegfx::B2DPoint aRight(rOrigin + (rPerpendX * (rOffset.mfOffset + rOffset.mfHalfWidth)));
- for(const auto& rStyleVectorCombination : rStyleVectorTable)
+ if(0xff != rOffset.maColor.GetTransparency())
{
- std::vector< OffsetAndHalfWidthAndColor > otherOffsets;
- getOffsetAndHalfWidthAndColorFromStyle(rStyleVectorCombination.getStyle(), nullptr, rStyleVectorCombination.isMirrored(), otherOffsets);
+ const basegfx::B2DPoint aLeft(rOrigin + (rPerpendX * (rOffset.mfOffset - rOffset.mfHalfWidth)));
+ const basegfx::B2DPoint aRight(rOrigin + (rPerpendX * (rOffset.mfOffset + rOffset.mfHalfWidth)));
+ std::vector< CutSet > aCutSets;
+ CutSet aResult;
+ bool bResultSet(false);
+
+ if(1 == nOffsets)
+ {
+ // single line:
+ // - get all CutSets
+ // - get minimum values as extension (biggest possible overlap)
+ getAllCutSets(aCutSets, rOrigin, aLeft, aRight, rX, rStyleVectorTable, false, false);
- if(!otherOffsets.empty())
+ if(!aCutSets.empty())
+ {
+ aResult = getMinMaxCutSet(true, aCutSets);
+ bResultSet = true;
+ }
+ }
+ else
{
- const basegfx::B2DVector aOtherPerpend(basegfx::getNormalizedPerpendicular(rStyleVectorCombination.getB2DVector()));
+ // multiple lines
+ const bool bUpper(a < (nOffsets >> 1));
+ const bool bLower(a > (nOffsets >> 1));
- for(const auto& rOtherOffset : otherOffsets)
+ if(bUpper)
{
- const basegfx::B2DPoint aOtherLeft(rOrigin + (aOtherPerpend * (rOtherOffset.mfOffset - rOtherOffset.mfHalfWidth)));
- const basegfx::B2DPoint aOtherRight(rOrigin + (aOtherPerpend * (rOtherOffset.mfOffset + rOtherOffset.mfHalfWidth)));
- CutSet aCutSet;
+ getAllCutSets(aCutSets, rOrigin, aLeft, aRight, rX, rStyleVectorTable, true, false);
+
+ if(!aCutSets.empty())
+ {
+ aResult = getMinMaxCutSet(false, aCutSets);
+ bResultSet = true;
+ }
+ else
+ {
+ getAllCutSets(aCutSets, rOrigin, aLeft, aRight, rX, rStyleVectorTable, false, true);
- getCutSet(aCutSet, aLeft, aRight, rX, aOtherLeft, aOtherRight, rStyleVectorCombination.getB2DVector());
+ if(!aCutSets.empty())
+ {
+ aResult = getMinMaxCutSet(true, aCutSets);
+ bResultSet = true;
+ }
+ }
+ }
+ else if(bLower)
+ {
+ getAllCutSets(aCutSets, rOrigin, aLeft, aRight, rX, rStyleVectorTable, false, true);
- if(!bExtSet)
+ if(!aCutSets.empty())
{
- rExt.mfExtLeft = std::min(aCutSet.mfOLML, aCutSet.mfORML);
- rExt.mfExtRight = std::min(aCutSet.mfOLMR, aCutSet.mfORMR);
- bExtSet = true;
+ aResult = getMinMaxCutSet(false, aCutSets);
+ bResultSet = true;
}
else
{
- rExt.mfExtLeft = std::min(rExt.mfExtLeft , std::min(aCutSet.mfOLML, aCutSet.mfORML));
- rExt.mfExtRight = std::min(rExt.mfExtRight , std::min(aCutSet.mfOLMR, aCutSet.mfORMR));
+ getAllCutSets(aCutSets, rOrigin, aLeft, aRight, rX, rStyleVectorTable, true, false);
+
+ if(!aCutSets.empty())
+ {
+ aResult = getMinMaxCutSet(true, aCutSets);
+ bResultSet = true;
+ }
+ }
+ }
+ else // middle line
+ {
+ getAllCutSets(aCutSets, rOrigin, aLeft, aRight, rX, rStyleVectorTable, false, false);
+
+ if(!aCutSets.empty())
+ {
+ const CutSet aResultMin(getMinMaxCutSet(true, aCutSets));
+ const CutSet aResultMax(getMinMaxCutSet(false, aCutSets));
+
+ aResult.mfOLML = (aResultMin.mfOLML + aResultMax.mfOLML) * 0.5;
+ aResult.mfORML = (aResultMin.mfORML + aResultMax.mfORML) * 0.5;
+ aResult.mfOLMR = (aResultMin.mfOLMR + aResultMax.mfOLMR) * 0.5;
+ aResult.mfORMR = (aResultMin.mfORMR + aResultMax.mfORMR) * 0.5;
+ bResultSet = true;
}
}
}
+
+ if(bResultSet)
+ {
+ ExtendSet& rExt(rExtendSet[a]);
+
+ rExt.mfExtLeft = std::min(aResult.mfOLML, aResult.mfORML);
+ rExt.mfExtRight = std::min(aResult.mfOLMR, aResult.mfORMR);
+ }
}
}
}
@@ -588,9 +748,22 @@ void CreateBorderPrimitives(
if(bHasEndStyles)
{
- // create extends for line ends, use inverse point/vector and inverse offsets
- std::reverse(myOffsets.begin(), myOffsets.end());
- getExtends(aExtendSetEnd, rOrigin + rX, -rX, -aPerpendX, myOffsets, rEndStyleVectorTable);
+ // Create extends for line ends, use inverse point/vector and inverse offsets.
+ // Offsets need to be inverted for different width of lines. To invert, change
+ // order, but also sign of offset. Do this on a copy since myOffsets will be
+ // used below to create the primitives
+ std::vector< OffsetAndHalfWidthAndColor > myInverseOffsets(myOffsets);
+ std::reverse(myInverseOffsets.begin(), myInverseOffsets.end());
+
+ for(auto& offset : myInverseOffsets)
+ {
+ offset.mfOffset *= -1;
+ }
+
+ getExtends(aExtendSetEnd, rOrigin + rX, -rX, -aPerpendX, myInverseOffsets, rEndStyleVectorTable);
+
+ // also need to reverse the result to apply to the correct lines
+ std::reverse(aExtendSetEnd.begin(), aExtendSetEnd.end());
}
std::vector< drawinglayer::primitive2d::BorderLine > aBorderlines;
diff --git a/svx/source/dialog/framelinkarray.cxx b/svx/source/dialog/framelinkarray.cxx
index db54294640c5..5a526145cd54 100644
--- a/svx/source/dialog/framelinkarray.cxx
+++ b/svx/source/dialog/framelinkarray.cxx
@@ -988,7 +988,7 @@ void HelperCreateVerticalEntry(
if(rStartFromBR.IsUsed()) aStart.push_back(StyleVectorCombination(rStartFromBR, rX + rY, false));
if(rStartTFromR.IsUsed()) aStart.push_back(StyleVectorCombination(rStartTFromR, rX, false));
- if(rStartTFromT.IsUsed()) aStart.push_back(StyleVectorCombination(rStartTFromT, rY, true));
+ if(rStartTFromT.IsUsed()) aStart.push_back(StyleVectorCombination(rStartTFromT, -rY, true));
if(rStartTFromL.IsUsed()) aStart.push_back(StyleVectorCombination(rStartTFromL, -rX, true));
if(rStartFromBL.IsUsed()) aStart.push_back(StyleVectorCombination(rStartFromBL, rY - rX, true));
@@ -1002,9 +1002,9 @@ void HelperCreateVerticalEntry(
if(rEndFromTR.IsUsed()) aEnd.push_back(StyleVectorCombination(rEndFromTR, rX - rY, false));
if(rEndBFromR.IsUsed()) aEnd.push_back(StyleVectorCombination(rEndBFromR, rX, false));
- if(rEndBFromB.IsUsed()) aEnd.push_back(StyleVectorCombination(rEndBFromB, -rY, false));
- if(rEndBFromL.IsUsed()) aEnd.push_back(StyleVectorCombination(rEndBFromL, rX, true));
- if(rEndFromTL.IsUsed()) aEnd.push_back(StyleVectorCombination(rEndFromTL, rX + rY, true));
+ if(rEndBFromB.IsUsed()) aEnd.push_back(StyleVectorCombination(rEndBFromB, rY, false));
+ if(rEndBFromL.IsUsed()) aEnd.push_back(StyleVectorCombination(rEndBFromL, -rX, true));
+ if(rEndFromTL.IsUsed()) aEnd.push_back(StyleVectorCombination(rEndFromTL, -rX - rY, true));
CreateBorderPrimitives(
rSequence,