diff options
Diffstat (limited to 'svx')
-rw-r--r-- | svx/source/dialog/framelink.cxx | 225 | ||||
-rw-r--r-- | svx/source/dialog/framelinkarray.cxx | 8 |
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, |