summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArmin Le Grand <Armin.Le.Grand@cib.de>2017-09-14 16:45:56 +0200
committerArmin Le Grand <Armin.Le.Grand@cib.de>2017-09-15 12:58:04 +0200
commitab65fe804cf3a97bd172b5551b553b9bcde6d756 (patch)
tree3c956b067379cc1e3fddd5eb2ce341eab52a5f0e
parent2f16219741aba016677103e4b22738d055c39a91 (diff)
borderline: Extended decompose
Decompose of BorderLinePrimitive2D extended to take care of non-perpendicular line endings for matching. Improved matching, one error in calc fixed Change-Id: I869a75385711b58e6725daba0f22be8a98158ad9
-rw-r--r--drawinglayer/source/primitive2d/borderlineprimitive2d.cxx121
-rw-r--r--include/drawinglayer/primitive2d/borderlineprimitive2d.hxx4
-rw-r--r--sc/source/ui/view/output.cxx2
-rw-r--r--svx/source/dialog/framelink.cxx51
4 files changed, 150 insertions, 28 deletions
diff --git a/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
index 6295d4673c36..0b6dda423adf 100644
--- a/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
@@ -149,15 +149,118 @@ namespace drawinglayer
if(!candidate.isGap())
{
const basegfx::B2DVector aDeltaY(aPerpendicular * (fOffset + (fWidth * 0.5)));
- const basegfx::B2DPoint aStart(getStart() - (aVector * candidate.getStartAverage()) + aDeltaY);
- const basegfx::B2DPoint aEnd(getEnd() + (aVector * candidate.getEndAverage()) + aDeltaY);
-
- addPolygonStrokePrimitive2D(
- rContainer,
- aStart,
- aEnd,
- candidate.getLineAttribute(),
- getStrokeAttribute());
+ const basegfx::B2DPoint aStart(getStart() + aDeltaY);
+ const basegfx::B2DPoint aEnd(getEnd() + aDeltaY);
+ const bool bStartPerpendicular(rtl::math::approxEqual(candidate.getStartLeft(), candidate.getStartRight()));
+ const bool bEndPerpendicular(rtl::math::approxEqual(candidate.getEndLeft(), candidate.getEndRight()));
+
+ if(bStartPerpendicular && bEndPerpendicular)
+ {
+ // start and end extends lead to an edge perpendicular to the line, so we can just use
+ // a PolygonStrokePrimitive2D for representation
+ addPolygonStrokePrimitive2D(
+ rContainer,
+ aStart - (aVector * candidate.getStartLeft()),
+ aEnd + (aVector * candidate.getEndLeft()),
+ candidate.getLineAttribute(),
+ getStrokeAttribute());
+ }
+ else
+ {
+ // start and/or end extensions lead to a lineStart/End that is *not*
+ // perpendicular to the line itself
+ if(getStrokeAttribute().isDefault() || 0.0 == getStrokeAttribute().getFullDotDashLen())
+ {
+ // without stroke, we can simply represent that using a filled polygon
+ const basegfx::B2DVector aHalfLineOffset(aPerpendicular * (candidate.getLineAttribute().getWidth() * 0.5));
+ basegfx::B2DPolygon aPolygon;
+
+ aPolygon.append(aStart - aHalfLineOffset - (aVector * candidate.getStartLeft()));
+ aPolygon.append(aEnd - aHalfLineOffset + (aVector * candidate.getEndLeft()));
+ aPolygon.append(aEnd + aHalfLineOffset + (aVector * candidate.getEndRight()));
+ aPolygon.append(aStart + aHalfLineOffset - (aVector * candidate.getStartRight()));
+
+ rContainer.push_back(
+ new PolyPolygonColorPrimitive2D(
+ basegfx::B2DPolyPolygon(aPolygon),
+ candidate.getLineAttribute().getColor()));
+ }
+ else
+ {
+ // with stroke, we have a problem - a filled polygon would lose the
+ // stroke. Let's represent the start and/or end as triangles, the main
+ // line still as PolygonStrokePrimitive2D.
+ // Fill default line Start/End for stroke, so we need no adaptions in else pathes
+ basegfx::B2DPoint aStrokeStart(aStart - (aVector * candidate.getStartLeft()));
+ basegfx::B2DPoint aStrokeEnd(aEnd + (aVector * candidate.getEndLeft()));
+ const basegfx::B2DVector aHalfLineOffset(aPerpendicular * (candidate.getLineAttribute().getWidth() * 0.5));
+
+ if(!bStartPerpendicular)
+ {
+ const double fMin(std::min(candidate.getStartLeft(), candidate.getStartRight()));
+ const double fMax(std::max(candidate.getStartLeft(), candidate.getStartRight()));
+ basegfx::B2DPolygon aPolygon;
+
+ // create a triangle with min/max values for LineStart and add
+ if(rtl::math::approxEqual(candidate.getStartLeft(), fMax))
+ {
+ aPolygon.append(aStart - aHalfLineOffset - (aVector * candidate.getStartLeft()));
+ }
+
+ aPolygon.append(aStart - aHalfLineOffset - (aVector * fMin));
+ aPolygon.append(aStart + aHalfLineOffset - (aVector * fMin));
+
+ if(rtl::math::approxEqual(candidate.getStartRight(), fMax))
+ {
+ aPolygon.append(aStart + aHalfLineOffset - (aVector * candidate.getStartRight()));
+ }
+
+ rContainer.push_back(
+ new PolyPolygonColorPrimitive2D(
+ basegfx::B2DPolyPolygon(aPolygon),
+ candidate.getLineAttribute().getColor()));
+
+ // Adapt StrokeStart accordingly
+ aStrokeStart = aStart - (aVector * fMin);
+ }
+
+ if(!bEndPerpendicular)
+ {
+ const double fMin(std::min(candidate.getEndLeft(), candidate.getEndRight()));
+ const double fMax(std::max(candidate.getEndLeft(), candidate.getEndRight()));
+ basegfx::B2DPolygon aPolygon;
+
+ // create a triangle with min/max values for LineEnd and add
+ if(rtl::math::approxEqual(candidate.getEndLeft(), fMax))
+ {
+ aPolygon.append(aEnd - aHalfLineOffset + (aVector * candidate.getEndLeft()));
+ }
+
+ if(rtl::math::approxEqual(candidate.getEndRight(), fMax))
+ {
+ aPolygon.append(aEnd + aHalfLineOffset + (aVector * candidate.getEndRight()));
+ }
+
+ aPolygon.append(aEnd + aHalfLineOffset + (aVector * fMin));
+ aPolygon.append(aEnd - aHalfLineOffset + (aVector * fMin));
+
+ rContainer.push_back(
+ new PolyPolygonColorPrimitive2D(
+ basegfx::B2DPolyPolygon(aPolygon),
+ candidate.getLineAttribute().getColor()));
+
+ // Adapt StrokeEnd accordingly
+ aStrokeEnd = aEnd + (aVector * fMin);
+ }
+
+ addPolygonStrokePrimitive2D(
+ rContainer,
+ aStrokeStart,
+ aStrokeEnd,
+ candidate.getLineAttribute(),
+ getStrokeAttribute());
+ }
+ }
}
fOffset += fWidth;
diff --git a/include/drawinglayer/primitive2d/borderlineprimitive2d.hxx b/include/drawinglayer/primitive2d/borderlineprimitive2d.hxx
index b6634f6ce64e..cb57e40fbe8a 100644
--- a/include/drawinglayer/primitive2d/borderlineprimitive2d.hxx
+++ b/include/drawinglayer/primitive2d/borderlineprimitive2d.hxx
@@ -79,10 +79,6 @@ namespace drawinglayer
/// helper to get adapted width (maximum)
double getAdaptedWidth(double fMinWidth) const;
- /// helper to get average values Start/End
- double getStartAverage() const { return 0.5 * (mfStartLeft + mfStartRight); }
- double getEndAverage() const { return 0.5 * (mfEndLeft + mfEndRight); }
-
/// compare operator
bool operator==(const BorderLine& rBorderLine) const;
};
diff --git a/sc/source/ui/view/output.cxx b/sc/source/ui/view/output.cxx
index da4c342d44d6..858ea99ef83f 100644
--- a/sc/source/ui/view/output.cxx
+++ b/sc/source/ui/view/output.cxx
@@ -660,7 +660,7 @@ void ScOutputData::SetCellRotations()
const double fOrient((bLayoutRTL ? -1.0 : 1.0) * nAttrRotate * F_PI18000); // 1/100th degrees -> [0..2PI]
svx::frame::Array& rArray = mrTabInfo.maArray;
- rArray.SetCellRotation(nY+1, nX+1, eRotMode, fOrient);
+ rArray.SetCellRotation(nX+1, nY+1, eRotMode, fOrient);
}
}
}
diff --git a/svx/source/dialog/framelink.cxx b/svx/source/dialog/framelink.cxx
index ea5b33315cfc..e205560df33c 100644
--- a/svx/source/dialog/framelink.cxx
+++ b/svx/source/dialog/framelink.cxx
@@ -550,12 +550,15 @@ void getAllCutSets(
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;
+ if(0xff != rOtherOffset.maColor.GetTransparency())
+ {
+ 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);
+ getCutSet(aCutSet, rLeft, rRight, rX, aOtherLeft, aOtherRight, rStyleVectorCombination.getB2DVector());
+ rCutSets.push_back(aCutSet);
+ }
}
}
}
@@ -586,22 +589,42 @@ CutSet getMinMaxCutSet(
{
const CutSet& rCandidate(rCutSets[a]);
const double fCandidate(rCandidate.mfOLML + rCandidate.mfORML + rCandidate.mfOLMR + rCandidate.mfORMR);
+ bool bCopy(false);
- if(bMin)
+ if(basegfx::fTools::equalZero(fCandidate - fRetval))
{
- if(fCandidate < fRetval)
+ // both are equal (use basegfx::fTools::equalZero and *not* rtl::math::approxEqual here, that is too precise)
+ const bool bPerpendR(rtl::math::approxEqual(aRetval.mfOLML, aRetval.mfOLMR) || rtl::math::approxEqual(aRetval.mfORML, aRetval.mfORMR));
+ const bool bPerpendC(rtl::math::approxEqual(rCandidate.mfOLML, rCandidate.mfOLMR) || rtl::math::approxEqual(rCandidate.mfORML, rCandidate.mfORMR));
+
+ if(!bPerpendR && !bPerpendC)
+ {
+ // when both are not perpend, create medium cut
+ const double fNewOLML(std::max(std::min(rCandidate.mfOLML, rCandidate.mfORML), std::min(aRetval.mfOLML, aRetval.mfORML)));
+ const double fNewORML(std::min(std::max(rCandidate.mfOLML, rCandidate.mfORML), std::max(aRetval.mfOLML, aRetval.mfORML)));
+ const double fNewOLMR(std::max(std::min(rCandidate.mfOLMR, rCandidate.mfORMR), std::min(aRetval.mfOLMR, aRetval.mfORMR)));
+ const double fNewORMR(std::min(std::max(rCandidate.mfOLMR, rCandidate.mfORMR), std::max(aRetval.mfOLMR, aRetval.mfORMR)));
+ aRetval.mfOLML = fNewOLML;
+ aRetval.mfORML = fNewORML;
+ aRetval.mfOLMR = fNewOLMR;
+ aRetval.mfORMR = fNewORMR;
+ fRetval = aRetval.mfOLML + aRetval.mfORML + aRetval.mfOLMR + aRetval.mfORMR;
+ }
+ else
{
- fRetval = fCandidate;
- aRetval = rCandidate;
+ // if equal and perpend differs, perpend one is assumed smaller
+ bCopy = ((bMin && bPerpendC && !bPerpendR) || (!bMin && !bPerpendC && bPerpendR));
}
}
else
{
- if(fCandidate > fRetval)
- {
- fRetval = fCandidate;
- aRetval = rCandidate;
- }
+ bCopy = ((bMin && fCandidate < fRetval) || (!bMin && fCandidate > fRetval));
+ }
+
+ if(bCopy)
+ {
+ fRetval = fCandidate;
+ aRetval = rCandidate;
}
}