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 ...@@ -149,15 +149,118 @@ namespace drawinglayer
if(!candidate.isGap()) if(!candidate.isGap())
{ {
const basegfx::B2DVector aDeltaY(aPerpendicular * (fOffset + (fWidth * 0.5))); const basegfx::B2DVector aDeltaY(aPerpendicular * (fOffset + (fWidth * 0.5)));
const basegfx::B2DPoint aStart(getStart() - (aVector * candidate.getStartAverage()) + aDeltaY); const basegfx::B2DPoint aStart(getStart() + aDeltaY);
const basegfx::B2DPoint aEnd(getEnd() + (aVector * candidate.getEndAverage()) + aDeltaY); const basegfx::B2DPoint aEnd(getEnd() + aDeltaY);
const bool bStartPerpendicular(rtl::math::approxEqual(candidate.getStartLeft(), candidate.getStartRight()));
addPolygonStrokePrimitive2D( const bool bEndPerpendicular(rtl::math::approxEqual(candidate.getEndLeft(), candidate.getEndRight()));
rContainer,
aStart, if(bStartPerpendicular && bEndPerpendicular)
aEnd, {
candidate.getLineAttribute(), // start and end extends lead to an edge perpendicular to the line, so we can just use
getStrokeAttribute()); // 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; fOffset += fWidth;
......
...@@ -79,10 +79,6 @@ namespace drawinglayer ...@@ -79,10 +79,6 @@ namespace drawinglayer
/// helper to get adapted width (maximum) /// helper to get adapted width (maximum)
double getAdaptedWidth(double fMinWidth) const; 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 /// compare operator
bool operator==(const BorderLine& rBorderLine) const; bool operator==(const BorderLine& rBorderLine) const;
}; };
......
...@@ -660,7 +660,7 @@ void ScOutputData::SetCellRotations() ...@@ -660,7 +660,7 @@ void ScOutputData::SetCellRotations()
const double fOrient((bLayoutRTL ? -1.0 : 1.0) * nAttrRotate * F_PI18000); // 1/100th degrees -> [0..2PI] const double fOrient((bLayoutRTL ? -1.0 : 1.0) * nAttrRotate * F_PI18000); // 1/100th degrees -> [0..2PI]
svx::frame::Array& rArray = mrTabInfo.maArray; 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( ...@@ -550,12 +550,15 @@ void getAllCutSets(
for(const auto& rOtherOffset : otherOffsets) for(const auto& rOtherOffset : otherOffsets)
{ {
const basegfx::B2DPoint aOtherLeft(rOrigin + (aOtherPerpend * (rOtherOffset.mfOffset - rOtherOffset.mfHalfWidth))); if(0xff != rOtherOffset.maColor.GetTransparency())
const basegfx::B2DPoint aOtherRight(rOrigin + (aOtherPerpend * (rOtherOffset.mfOffset + rOtherOffset.mfHalfWidth))); {
CutSet aCutSet; 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()); getCutSet(aCutSet, rLeft, rRight, rX, aOtherLeft, aOtherRight, rStyleVectorCombination.getB2DVector());
rCutSets.push_back(aCutSet); rCutSets.push_back(aCutSet);
}
} }
} }
} }
...@@ -586,22 +589,42 @@ CutSet getMinMaxCutSet( ...@@ -586,22 +589,42 @@ CutSet getMinMaxCutSet(
{ {
const CutSet& rCandidate(rCutSets[a]); const CutSet& rCandidate(rCutSets[a]);
const double fCandidate(rCandidate.mfOLML + rCandidate.mfORML + rCandidate.mfOLMR + rCandidate.mfORMR); 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; // if equal and perpend differs, perpend one is assumed smaller
aRetval = rCandidate; bCopy = ((bMin && bPerpendC && !bPerpendR) || (!bMin && !bPerpendC && bPerpendR));
} }
} }
else else
{ {
if(fCandidate > fRetval) bCopy = ((bMin && fCandidate < fRetval) || (!bMin && fCandidate > fRetval));
{ }
fRetval = fCandidate;
aRetval = rCandidate; 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