Kaydet (Commit) ab65fe80 authored tarafından Armin Le Grand's avatar Armin Le Grand

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
üst 2f162197
......@@ -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;
......
......@@ -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;
};
......
......@@ -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);
}
}
}
......
......@@ -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;
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment