summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--compilerplugins/clang/fpcomparison.cxx1
-rw-r--r--drawinglayer/Library_drawinglayer.mk1
-rw-r--r--drawinglayer/qa/unit/border.cxx47
-rw-r--r--drawinglayer/source/primitive2d/borderlineprimitive2d.cxx389
-rw-r--r--drawinglayer/source/primitive2d/clippedborderlineprimitive2d.cxx64
-rw-r--r--drawinglayer/source/processor2d/vclpixelprocessor2d.cxx395
-rw-r--r--drawinglayer/source/processor2d/vclpixelprocessor2d.hxx1
-rw-r--r--include/drawinglayer/primitive2d/borderlineprimitive2d.hxx26
-rw-r--r--include/drawinglayer/primitive2d/clippedborderlineprimitive2d.hxx65
-rw-r--r--include/svx/framelink.hxx8
-rw-r--r--include/svx/framelinkarray.hxx7
-rw-r--r--sc/source/ui/view/output.cxx86
-rw-r--r--svx/source/dialog/framelink.cxx103
-rw-r--r--svx/source/dialog/framelinkarray.cxx165
-rw-r--r--svx/source/dialog/frmsel.cxx32
-rw-r--r--sw/source/core/layout/paintfrm.cxx52
16 files changed, 497 insertions, 945 deletions
diff --git a/compilerplugins/clang/fpcomparison.cxx b/compilerplugins/clang/fpcomparison.cxx
index 1cc7616c887b..f85dba05cd1e 100644
--- a/compilerplugins/clang/fpcomparison.cxx
+++ b/compilerplugins/clang/fpcomparison.cxx
@@ -179,7 +179,6 @@ bool FpComparison::ignore(FunctionDecl* function)
|| dc.Function("create2DDecomposition").Class("ScenePrimitive2D").Namespace("primitive2d").Namespace("drawinglayer").GlobalNamespace()
|| dc.Function("createAtom").Class("SvgLinearGradientPrimitive2D").Namespace("primitive2d").Namespace("drawinglayer").GlobalNamespace()
|| dc.Function("createAtom").Class("SvgRadialGradientPrimitive2D").Namespace("primitive2d").Namespace("drawinglayer").GlobalNamespace()
- || dc.Function("tryDrawBorderLinePrimitive2DDirect").Class("VclPixelProcessor2D").Namespace("processor2d").Namespace("drawinglayer").GlobalNamespace()
|| dc.Function("FoldConstantsBinaryNode").Class("SbiExprNode").GlobalNamespace()
|| dc.Function("Format").Class("SbxValue").GlobalNamespace()
|| dc.Function("Compare").Class("SbxValue").GlobalNamespace()
diff --git a/drawinglayer/Library_drawinglayer.mk b/drawinglayer/Library_drawinglayer.mk
index 8c431c8ec08f..32daccd9d43e 100644
--- a/drawinglayer/Library_drawinglayer.mk
+++ b/drawinglayer/Library_drawinglayer.mk
@@ -67,7 +67,6 @@ $(eval $(call gb_Library_add_exception_objects,drawinglayer,\
drawinglayer/source/primitive2d/baseprimitive2d \
drawinglayer/source/primitive2d/bitmapprimitive2d \
drawinglayer/source/primitive2d/borderlineprimitive2d \
- drawinglayer/source/primitive2d/clippedborderlineprimitive2d \
drawinglayer/source/primitive2d/controlprimitive2d \
drawinglayer/source/primitive2d/cropprimitive2d \
drawinglayer/source/primitive2d/discretebitmapprimitive2d \
diff --git a/drawinglayer/qa/unit/border.cxx b/drawinglayer/qa/unit/border.cxx
index 25264c46ee51..ce99965b13f9 100644
--- a/drawinglayer/qa/unit/border.cxx
+++ b/drawinglayer/qa/unit/border.cxx
@@ -17,6 +17,7 @@
#include <drawinglayer/geometry/viewinformation2d.hxx>
#include <drawinglayer/primitive2d/borderlineprimitive2d.hxx>
#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
+#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
#include <drawinglayer/processor2d/baseprocessor2d.hxx>
#include <drawinglayer/processor2d/processorfromoutputdevice.hxx>
#include <rtl/ref.hxx>
@@ -70,17 +71,15 @@ void DrawinglayerBorderTest::testDoubleDecompositionSolid()
// Make sure it results in two borders as it's a double one.
CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(2), aContainer.size());
- // Get the inside line.
- auto pInside = dynamic_cast<const drawinglayer::primitive2d::PolyPolygonColorPrimitive2D*>(aContainer[0].get());
+ // Get the inside line, now a PolygonStrokePrimitive2D
+ auto pInside = dynamic_cast<const drawinglayer::primitive2d::PolygonStrokePrimitive2D*>(aContainer[0].get());
CPPUNIT_ASSERT(pInside);
// Make sure the inside line's height is fLeftWidth.
- const basegfx::B2DPolyPolygon& rPolyPolygon = pInside->getB2DPolyPolygon();
- CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(1), rPolyPolygon.count());
- const basegfx::B2DPolygon& rPolygon = rPolyPolygon.getB2DPolygon(0);
- const basegfx::B2DRange& rRange = rPolygon.getB2DRange();
+ const double fLineWidthFromDecompose = pInside->getLineAttribute().getWidth();
+
// This was 2.47, i.e. the width of the inner line was 1 unit (in the bugdoc's case: 1 pixel) wider than expected.
- CPPUNIT_ASSERT_DOUBLES_EQUAL(fLeftWidth, rRange.getHeight(), basegfx::fTools::getSmallValue());
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(fLeftWidth, fLineWidthFromDecompose, basegfx::fTools::getSmallValue());
}
void DrawinglayerBorderTest::testDoublePixelProcessing()
@@ -100,7 +99,7 @@ void DrawinglayerBorderTest::testDoublePixelProcessing()
basegfx::B2DPoint aEnd(100, 20);
double const fLeftWidth = 1.47;
double const fDistance = 1.47;
- double fRightWidth = 1.47;
+ double const fRightWidth = 1.47;
double const fExtendLeftStart = 0;
double const fExtendLeftEnd = 0;
double const fExtendRightStart = 0;
@@ -117,31 +116,33 @@ void DrawinglayerBorderTest::testDoublePixelProcessing()
// Process the primitives.
pProcessor->process(aPrimitives);
- // Now assert the height of the outer (second) border polygon.
+ // Double line now gets decomposed in Metafile to painting four lines
+ // with width == 0 in a cross pattern due to real line width being between
+ // 1.0 and 2.0. Count created lines
aMetaFile.Stop();
aMetaFile.WindStart();
- bool bFirst = true;
- sal_Int32 nHeight = 0;
+ sal_uInt32 nPolyLineActionCount = 0;
+
for (std::size_t nAction = 0; nAction < aMetaFile.GetActionSize(); ++nAction)
{
MetaAction* pAction = aMetaFile.GetAction(nAction);
- if (pAction->GetType() == MetaActionType::POLYPOLYGON)
+
+ if (MetaActionType::POLYLINE == pAction->GetType())
{
- if (bFirst)
+ auto pMPLAction = static_cast<MetaPolyLineAction*>(pAction);
+
+ if (0 == pMPLAction->GetLineInfo().GetWidth() && LineStyle::Solid == pMPLAction->GetLineInfo().GetStyle())
{
- bFirst = false;
- continue;
+ nPolyLineActionCount++;
}
-
- auto pMPPAction = static_cast<MetaPolyPolygonAction*>(pAction);
- const tools::PolyPolygon& rPolyPolygon = pMPPAction->GetPolyPolygon();
- nHeight = rPolyPolygon.GetBoundRect().getHeight();
}
}
- sal_Int32 nExpectedHeight = std::round(fRightWidth);
- // This was 2, and should be 1: if the logical requested width is 1.47,
- // then that must be 1 px on the screen, not 2.
- CPPUNIT_ASSERT_EQUAL(nExpectedHeight, nHeight);
+
+ // Check if all eight (2x four) simple lines with width == 0 and
+ // solid were created
+ const sal_uInt32 nExpectedNumPolyLineActions = 8;
+
+ CPPUNIT_ASSERT_EQUAL(nExpectedNumPolyLineActions, nPolyLineActionCount);
}
CPPUNIT_TEST_SUITE_REGISTRATION(DrawinglayerBorderTest);
diff --git a/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
index c6ea4a5c41f7..9735cc1aa44d 100644
--- a/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
@@ -42,282 +42,138 @@ T round(T x)
}
#endif
-namespace drawinglayer {
-
-namespace {
-
-void moveLine(basegfx::B2DPolygon& rPoly, double fGap, const basegfx::B2DVector& rVector)
-{
- if (basegfx::fTools::equalZero(rVector.getX()))
- {
- basegfx::B2DHomMatrix aMat(1, 0, fGap, 0, 1, 0);
- rPoly.transform(aMat);
- }
- else if (basegfx::fTools::equalZero(rVector.getY()))
- {
- basegfx::B2DHomMatrix aMat(1, 0, 0, 0, 1, fGap);
- rPoly.transform(aMat);
- }
-}
-
-primitive2d::Primitive2DReference makeHairLinePrimitive(
- const basegfx::B2DPoint& rStart, const basegfx::B2DPoint& rEnd, const basegfx::B2DVector& rVector,
- const basegfx::BColor& rColor, double fGap)
-{
- basegfx::B2DPolygon aPolygon;
- aPolygon.append(rStart);
- aPolygon.append(rEnd);
- moveLine(aPolygon, fGap, rVector);
-
- return primitive2d::Primitive2DReference(new primitive2d::PolygonHairlinePrimitive2D(aPolygon, rColor));
-}
-
-primitive2d::Primitive2DReference makeSolidLinePrimitive(
- const basegfx::B2DPolyPolygon& rClipRegion, const basegfx::B2DPoint& rStart, const basegfx::B2DPoint& rEnd,
- const basegfx::B2DVector& rVector, const basegfx::BColor& rColor, double fLineWidth, double fGap)
+namespace drawinglayer
{
- const basegfx::B2DVector aPerpendicular = basegfx::getPerpendicular(rVector);
- const basegfx::B2DVector aLineWidthOffset = (fLineWidth * 0.5) * aPerpendicular;
-
- basegfx::B2DPolygon aPolygon;
- aPolygon.append(rStart + aLineWidthOffset);
- aPolygon.append(rEnd + aLineWidthOffset);
- aPolygon.append(rEnd - aLineWidthOffset);
- aPolygon.append(rStart - aLineWidthOffset);
- aPolygon.setClosed(true);
-
- moveLine(aPolygon, fGap, rVector);
-
- basegfx::B2DPolyPolygon aClipped =
- basegfx::tools::clipPolygonOnPolyPolygon(aPolygon, rClipRegion, true, false);
-
- if (aClipped.count())
- aPolygon = aClipped.getB2DPolygon(0);
-
- return primitive2d::Primitive2DReference(
- new primitive2d::PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(aPolygon), rColor));
-}
-
-}
-
- // fdo#49438: heuristic pseudo hack
- static bool lcl_UseHairline(double const fW,
- basegfx::B2DPoint const& rStart, basegfx::B2DPoint const& rEnd,
- geometry::ViewInformation2D const& rViewInformation)
- {
- basegfx::B2DTuple scale;
- basegfx::B2DTuple translation;
- double fRotation;
- double fShear;
- rViewInformation.getObjectToViewTransformation().decompose(
- scale, translation, fRotation, fShear);
- double const fScale(
- (rEnd.getX() - rStart.getX() > rEnd.getY() - rStart.getY())
- ? scale.getY() : scale.getX());
- return (fW * fScale < 0.51);
- }
-
- static double lcl_GetCorrectedWidth(double const fW,
- basegfx::B2DPoint const& rStart, basegfx::B2DPoint const& rEnd,
- geometry::ViewInformation2D const& rViewInformation)
- {
- return (lcl_UseHairline(fW, rStart, rEnd, rViewInformation)) ? 0.0 : fW;
- }
-
namespace primitive2d
{
- double BorderLinePrimitive2D::getWidth(
- geometry::ViewInformation2D const& rViewInformation) const
- {
- return lcl_GetCorrectedWidth(mfLeftWidth, getStart(), getEnd(),
- rViewInformation)
- + lcl_GetCorrectedWidth(mfDistance, getStart(), getEnd(),
- rViewInformation)
- + lcl_GetCorrectedWidth(mfRightWidth, getStart(), getEnd(),
- rViewInformation);
- }
-
- basegfx::B2DPolyPolygon BorderLinePrimitive2D::getClipPolygon(
- geometry::ViewInformation2D const& rViewInformation) const
+ // helper to add a centered, maybe stroked line primitive to rContainer
+ void addPolygonStrokePrimitive2D(
+ Primitive2DContainer& rContainer,
+ const basegfx::B2DPoint& rStart,
+ const basegfx::B2DPoint& rEnd,
+ const basegfx::BColor& rColor,
+ double fWidth,
+ SvxBorderLineStyle aStyle,
+ double fPatternScale)
{
- basegfx::B2DPolygon clipPolygon;
-
- // Get the vectors
- basegfx::B2DVector aVector( getEnd() - getStart() );
- aVector.normalize();
- const basegfx::B2DVector aPerpendicular(basegfx::getPerpendicular(aVector));
-
- // Get the points
- const double fWidth(getWidth(rViewInformation));
- const basegfx::B2DVector aLeftOff(
- aPerpendicular * (-0.5 * std::max(fWidth, 1.0)));
- const basegfx::B2DVector aRightOff(
- aPerpendicular * (0.5 * std::max(fWidth, 1.0)));
+ basegfx::B2DPolygon aPolygon;
- const basegfx::B2DVector aSLVector( aLeftOff - ( getExtendLeftStart() * aVector ) );
- clipPolygon.append( basegfx::B2DPoint( getStart() + aSLVector * 2.0 ) );
+ aPolygon.append(rStart);
+ aPolygon.append(rEnd);
- clipPolygon.append( getStart( ) );
+ const attribute::LineAttribute aLineAttribute(rColor, fWidth);
+ static double fPatScFact(10.0); // 10.0 multiply, see old code
+ const std::vector<double> aDashing(svtools::GetLineDashing(aStyle, fPatternScale * fPatScFact));
- const basegfx::B2DVector aSRVector( aRightOff - ( getExtendRightStart() * aVector ) );
- clipPolygon.append( basegfx::B2DPoint( getStart() + aSRVector * 2.0 ) );
-
- const basegfx::B2DVector aERVector( aRightOff + ( getExtendRightEnd() * aVector ) );
- clipPolygon.append( basegfx::B2DPoint( getEnd() + aERVector * 2.0 ) );
-
- clipPolygon.append( getEnd( ) );
-
- const basegfx::B2DVector aELVector( aLeftOff + ( getExtendLeftEnd() * aVector ) );
- clipPolygon.append( basegfx::B2DPoint( getEnd() + aELVector * 2.0 ) );
-
- clipPolygon.setClosed( true );
-
- return basegfx::B2DPolyPolygon( clipPolygon );
- }
+ if (aDashing.empty())
+ {
+ rContainer.push_back(
+ new PolygonStrokePrimitive2D(
+ aPolygon,
+ aLineAttribute));
+ }
+ else
+ {
+ const attribute::StrokeAttribute aStrokeAttribute(aDashing);
- void BorderLinePrimitive2D::create2DDecomposition(Primitive2DContainer& rContainer, const geometry::ViewInformation2D& rViewInformation) const
- {
- createDecomposition(rContainer, rViewInformation, false);
+ rContainer.push_back(
+ new PolygonStrokePrimitive2D(
+ aPolygon,
+ aLineAttribute,
+ aStrokeAttribute));
+ }
}
- void BorderLinePrimitive2D::createDecomposition(Primitive2DContainer& rContainer, const geometry::ViewInformation2D& rViewInformation, bool bPixelCorrection) const
+ void BorderLinePrimitive2D::create2DDecomposition(Primitive2DContainer& rContainer, const geometry::ViewInformation2D& /*rViewInformation*/) const
{
- if(!getStart().equal(getEnd()) && ( isInsideUsed() || isOutsideUsed() ) )
+ if (!getStart().equal(getEnd()) && (isInsideUsed() || isOutsideUsed()))
{
// get data and vectors
basegfx::B2DVector aVector(getEnd() - getStart());
aVector.normalize();
const basegfx::B2DVector aPerpendicular(basegfx::getPerpendicular(aVector));
- const basegfx::B2DPolyPolygon& aClipRegion =
- getClipPolygon(rViewInformation);
-
- if(isOutsideUsed() && isInsideUsed())
+ if (isOutsideUsed() && isInsideUsed())
{
- const double fExt = getWidth(rViewInformation); // Extend a lot: it'll be clipped later.
- const basegfx::B2DPoint aTmpStart(getStart() - (fExt * aVector));
- const basegfx::B2DPoint aTmpEnd(getEnd() + (fExt * aVector));
-
- double fLeftWidth = getLeftWidth();
- bool bLeftHairline = lcl_UseHairline(fLeftWidth, getStart(), getEnd(), rViewInformation);
- if (bLeftHairline)
- fLeftWidth = 0.0;
-
- double fRightWidth = getRightWidth();
- bool bRightHairline = lcl_UseHairline(fRightWidth, getStart(), getEnd(), rViewInformation);
- if (bRightHairline)
- fRightWidth = 0.0;
-
- // "inside" line
-
- if (bLeftHairline)
- rContainer.push_back(makeHairLinePrimitive(
- getStart(), getEnd(), aVector, getRGBColorLeft(), 0.0));
- else
+ // double line with gap. Use mfDiscreteDistance (see get2DDecomposition) as distance.
+ // That value is prepared to be at least one pixel (discrete unit) so that the
+ // decomposition is view-dependent in this cases
+ if (isInsideUsed())
{
- double fWidth = bPixelCorrection ? std::round(fLeftWidth) : fLeftWidth;
- rContainer.push_back(makeSolidLinePrimitive(
- aClipRegion, aTmpStart, aTmpEnd, aVector, getRGBColorLeft(), fWidth, -fLeftWidth/2.0));
+ // inside line (left). Create stroke primitive centered on line width
+ const double fDeltaY((mfDiscreteDistance + getLeftWidth()) * 0.5);
+ const basegfx::B2DVector aDeltaY(aPerpendicular * fDeltaY);
+ const basegfx::B2DPoint aStart(getStart() - (aVector * getExtendLeftStart()) - aDeltaY);
+ const basegfx::B2DPoint aEnd(getEnd() + (aVector * getExtendLeftEnd()) - aDeltaY);
+
+ addPolygonStrokePrimitive2D(
+ rContainer,
+ aStart,
+ aEnd,
+ getRGBColorLeft(),
+ getLeftWidth(),
+ getStyle(),
+ getPatternScale());
}
- // "outside" line
-
- if (bRightHairline)
- rContainer.push_back(makeHairLinePrimitive(
- getStart(), getEnd(), aVector, getRGBColorRight(), fLeftWidth+mfDistance));
- else
+ if (hasGapColor() && isDistanceUsed())
{
- double fWidth = bPixelCorrection ? std::round(fRightWidth) : fRightWidth;
- rContainer.push_back(makeSolidLinePrimitive(
- aClipRegion, aTmpStart, aTmpEnd, aVector, getRGBColorRight(), fWidth, mfDistance+fRightWidth/2.0));
+ // gap (if visible, found no practicval usage).
+ // Create stroke primitive on vector with given color
+ addPolygonStrokePrimitive2D(
+ rContainer,
+ getStart(),
+ getEnd(),
+ getRGBColorGap(),
+ mfDiscreteDistance,
+ getStyle(),
+ getPatternScale());
}
- }
- else
- {
- // single line, create geometry
- basegfx::B2DPolygon aPolygon;
- const double fExt = getWidth(rViewInformation); // Extend a lot: it'll be clipped after
- const basegfx::B2DPoint aTmpStart(getStart() - (fExt * aVector));
- const basegfx::B2DPoint aTmpEnd(getEnd() + (fExt * aVector));
- // Get which is the line to show
- bool bIsSolidline = mnStyle == SvxBorderLineStyle::SOLID;
- double nWidth = getLeftWidth();
- basegfx::BColor aColor = getRGBColorLeft();
- if ( basegfx::fTools::equal( 0.0, mfLeftWidth ) )
+ if (isOutsideUsed())
{
- nWidth = getRightWidth();
- aColor = getRGBColorRight();
+ // outside line (right). Create stroke primitive centered on line width
+ const double fDeltaY((mfDiscreteDistance + getRightWidth()) * 0.5);
+ const basegfx::B2DVector aDeltaY(aPerpendicular * fDeltaY);
+ const basegfx::B2DPoint aStart(getStart() - (aVector * getExtendRightStart()) + aDeltaY);
+ const basegfx::B2DPoint aEnd(getEnd() + (aVector * getExtendRightEnd()) + aDeltaY);
+
+ addPolygonStrokePrimitive2D(
+ rContainer,
+ aStart,
+ aEnd,
+ getRGBColorRight(),
+ getRightWidth(),
+ getStyle(),
+ getPatternScale());
}
- bool const bIsHairline = lcl_UseHairline(
- nWidth, getStart(), getEnd(), rViewInformation);
- nWidth = lcl_GetCorrectedWidth(nWidth,
- getStart(), getEnd(), rViewInformation);
-
- if(bIsHairline && bIsSolidline)
- {
- // create hairline primitive
- aPolygon.append( getStart() );
- aPolygon.append( getEnd() );
-
- rContainer.push_back(new PolygonHairlinePrimitive2D(
- aPolygon,
- aColor));
- }
- else
- {
- // create filled polygon primitive
- const basegfx::B2DVector aLineWidthOffset(((nWidth + 1) * 0.5) * aPerpendicular);
-
- aPolygon.append( aTmpStart );
- aPolygon.append( aTmpEnd );
-
- basegfx::B2DPolyPolygon aDashed =
- svtools::ApplyLineDashing(aPolygon, getStyle(), mfPatternScale*10.0);
-
- for (sal_uInt32 i = 0; i < aDashed.count(); i++ )
- {
- basegfx::B2DPolygon aDash = aDashed.getB2DPolygon( i );
- basegfx::B2DPoint aDashStart = aDash.getB2DPoint( 0 );
- basegfx::B2DPoint aDashEnd = aDash.getB2DPoint( aDash.count() - 1 );
-
- basegfx::B2DPolygon aDashPolygon;
- aDashPolygon.append( aDashStart + aLineWidthOffset );
- aDashPolygon.append( aDashEnd + aLineWidthOffset );
- aDashPolygon.append( aDashEnd - aLineWidthOffset );
- aDashPolygon.append( aDashStart - aLineWidthOffset );
- aDashPolygon.setClosed( true );
-
- basegfx::B2DPolyPolygon aClipped = basegfx::tools::clipPolygonOnPolyPolygon(
- aDashPolygon, aClipRegion, true, false );
+ }
+ else if(isInsideUsed())
+ {
+ // single line, only inside values used, no vertical offsets
+ addPolygonStrokePrimitive2D(
+ rContainer,
+ getStart(),
+ getEnd(),
+ getRGBColorLeft(),
+ getLeftWidth(),
+ getStyle(),
+ getPatternScale());
+ }
+ }
+ }
- if ( aClipped.count() )
- aDashed.setB2DPolygon( i, aClipped.getB2DPolygon( 0 ) );
- }
+ bool BorderLinePrimitive2D::isHorizontalOrVertical(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ if (!getStart().equal(getEnd()))
+ {
+ const basegfx::B2DHomMatrix& rOTVT = rViewInformation.getObjectToViewTransformation();
+ const basegfx::B2DVector aVector(rOTVT * getEnd() - rOTVT * getStart());
- sal_uInt32 n = aDashed.count();
- for (sal_uInt32 i = 0; i < n; ++i)
- {
- basegfx::B2DPolygon aDash = aDashed.getB2DPolygon(i);
- if (bIsHairline)
- {
- // Convert a rectangular polygon into a line.
- basegfx::B2DPolygon aDash2;
- basegfx::B2DRange aRange = aDash.getB2DRange();
- aDash2.append(basegfx::B2DPoint(aRange.getMinX(), aRange.getMinY()));
- aDash2.append(basegfx::B2DPoint(aRange.getMaxX(), aRange.getMinY()));
- rContainer.push_back(
- new PolygonHairlinePrimitive2D(aDash2, aColor));
- }
- else
- {
- rContainer.push_back(
- new PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(aDash), aColor));
- }
- }
- }
- }
+ return basegfx::fTools::equalZero(aVector.getX()) || basegfx::fTools::equalZero(aVector.getY());
}
+
+ return false;
}
BorderLinePrimitive2D::BorderLinePrimitive2D(
@@ -351,7 +207,8 @@ primitive2d::Primitive2DReference makeSolidLinePrimitive(
maRGBColorGap(rRGBColorGap),
mbHasGapColor(bHasGapColor),
mnStyle(nStyle),
- mfPatternScale(fPatternScale)
+ mfPatternScale(fPatternScale),
+ mfDiscreteDistance(0.0)
{
}
@@ -381,6 +238,42 @@ primitive2d::Primitive2DReference makeSolidLinePrimitive(
return false;
}
+ void BorderLinePrimitive2D::get2DDecomposition(Primitive2DDecompositionVisitor& rVisitor, const geometry::ViewInformation2D& rViewInformation) const
+ {
+ ::osl::MutexGuard aGuard(m_aMutex);
+
+ if (!getStart().equal(getEnd()) && isOutsideUsed() && isInsideUsed())
+ {
+ // Double line with gap. In this case, we want to be view-dependent.
+ // Get the current DiscreteUnit, look at X and Y and use the maximum
+ const basegfx::B2DVector aDiscreteVector(rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 1.0));
+ const double fDiscreteUnit(std::min(fabs(aDiscreteVector.getX()), fabs(aDiscreteVector.getY())));
+
+ // When discrete unit is bigger than distance (distance is less than one pixel),
+ // force distance to one pixel. Or expressed different, do not let the distance
+ // get smaller than one pixel. This is done for screen rendering and compatibility.
+ // This can also be done using DiscreteMetricDependentPrimitive2D as base class
+ // for this class, but specialization is better here for later buffering (only
+ // do this when 'double line with gap')
+ const double fNewDiscreteDistance(std::max(fDiscreteUnit, getDistance()));
+
+ if (!rtl::math::approxEqual(fNewDiscreteDistance, mfDiscreteDistance))
+ {
+ if (!getBuffered2DDecomposition().empty())
+ {
+ // conditions of last local decomposition have changed, delete
+ const_cast< BorderLinePrimitive2D* >(this)->setBuffered2DDecomposition(Primitive2DContainer());
+ }
+
+ // remember value for usage in create2DDecomposition
+ const_cast< BorderLinePrimitive2D* >(this)->mfDiscreteDistance = fNewDiscreteDistance;
+ }
+ }
+
+ // call base implementation
+ BufferedDecompositionPrimitive2D::get2DDecomposition(rVisitor, rViewInformation);
+ }
+
// provide unique ID
ImplPrimitive2DIDBlock(BorderLinePrimitive2D, PRIMITIVE2D_ID_BORDERLINEPRIMITIVE2D)
diff --git a/drawinglayer/source/primitive2d/clippedborderlineprimitive2d.cxx b/drawinglayer/source/primitive2d/clippedborderlineprimitive2d.cxx
deleted file mode 100644
index ca44a2838909..000000000000
--- a/drawinglayer/source/primitive2d/clippedborderlineprimitive2d.cxx
+++ /dev/null
@@ -1,64 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-#include <drawinglayer/primitive2d/clippedborderlineprimitive2d.hxx>
-#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
-
-namespace drawinglayer
-{
- namespace primitive2d
- {
- basegfx::B2DPolyPolygon ClippedBorderLinePrimitive2D::getClipPolygon(
- SAL_UNUSED_PARAMETER geometry::ViewInformation2D const&) const
- {
- basegfx::B2DPolyPolygon aPolyPolygon;
- aPolyPolygon.append( maIntersection );
- return aPolyPolygon;
- }
-
- ClippedBorderLinePrimitive2D::ClippedBorderLinePrimitive2D(
- const basegfx::B2DPoint& rStart,
- const basegfx::B2DPoint& rEnd,
- double fLeftWidth,
- double fDistance,
- double fRightWidth,
- const basegfx::B2DPolygon& rIntersection,
- const basegfx::BColor& rRGBColorRight,
- const basegfx::BColor& rRGBColorLeft,
- const basegfx::BColor& rRGBColorGap,
- bool bHasGapColor,
- SvxBorderLineStyle nStyle,
- double fPatternScale)
- : BorderLinePrimitive2D( rStart, rEnd, fLeftWidth,fDistance, fRightWidth,
- 0.0, 0.0, 0.0, 0.0, rRGBColorRight, rRGBColorLeft,
- rRGBColorGap, bHasGapColor, nStyle, fPatternScale),
- maIntersection( rIntersection )
- {
- }
-
- bool ClippedBorderLinePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
- {
- if(BorderLinePrimitive2D::operator==(rPrimitive))
- {
- const ClippedBorderLinePrimitive2D& rCompare = static_cast<const ClippedBorderLinePrimitive2D&>(rPrimitive);
-
- return maIntersection == rCompare.maIntersection;
- }
-
- return false;
- }
-
- // provide unique ID
- ImplPrimitive2DIDBlock(ClippedBorderLinePrimitive2D, PRIMITIVE2D_ID_CLIPPEDBORDERLINEPRIMITIVE2D)
-
-
- } // namespace primitive2d
-} // namespace drawinglayer
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
index 4b5e45c7ef04..a93f85df4595 100644
--- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
@@ -70,34 +70,6 @@ T round(T x)
using namespace com::sun::star;
-namespace {
-
-basegfx::B2DPolygon makeRectPolygon( double fX, double fY, double fW, double fH )
-{
- basegfx::B2DPolygon aPoly;
- aPoly.append(basegfx::B2DPoint(fX, fY));
- aPoly.append(basegfx::B2DPoint(fX+fW, fY));
- aPoly.append(basegfx::B2DPoint(fX+fW, fY+fH));
- aPoly.append(basegfx::B2DPoint(fX, fY+fH));
- aPoly.setClosed(true);
- return aPoly;
-}
-
-void drawHairLine(
- OutputDevice* pOutDev, double fX1, double fY1, double fX2, double fY2,
- const basegfx::BColor& rColor )
-{
- basegfx::B2DPolygon aTarget;
- aTarget.append(basegfx::B2DPoint(fX1, fY1));
- aTarget.append(basegfx::B2DPoint(fX2, fY2));
-
- pOutDev->SetFillColor();
- pOutDev->SetLineColor(Color(rColor));
- pOutDev->DrawPolyLine(aTarget);
-}
-
-}
-
namespace drawinglayer
{
namespace processor2d
@@ -306,341 +278,6 @@ namespace drawinglayer
return bTryWorked;
}
- bool VclPixelProcessor2D::tryDrawBorderLinePrimitive2DDirect(
- const drawinglayer::primitive2d::BorderLinePrimitive2D& rSource)
- {
- const basegfx::B2DPoint& rS = rSource.getStart();
- const basegfx::B2DPoint& rE = rSource.getEnd();
-
- double fX1 = rS.getX();
- double fY1 = rS.getY();
- double fX2 = rE.getX();
- double fY2 = rE.getY();
-
- bool bHorizontal = false;
- if (fX1 == fX2)
- {
- // Vertical line.
- }
- else if (fY1 == fY2)
- {
- // Horizontal line.
- bHorizontal = true;
- }
- else
- // Neither. Bail out.
- return false;
-
- switch (rSource.getStyle())
- {
- case SvxBorderLineStyle::SOLID:
- case SvxBorderLineStyle::DOUBLE_THIN:
- {
- const basegfx::BColor aLineColor =
- maBColorModifierStack.getModifiedColor(rSource.getRGBColorLeft());
- double nThick = rtl::math::round(rSource.getLeftWidth());
-
- bool bDouble = rSource.getStyle() == SvxBorderLineStyle::DOUBLE_THIN;
-
- basegfx::B2DPolygon aTarget;
-
- if (bHorizontal)
- {
- // Horizontal line. Draw it as a rectangle.
-
- aTarget = makeRectPolygon(fX1, fY1, fX2-fX1, nThick);
- aTarget.transform(maCurrentTransformation);
-
- basegfx::B2DRange aRange = aTarget.getB2DRange();
- double fH = aRange.getHeight();
-
- if (bDouble)
- {
- // Double line
- drawHairLine(
- mpOutputDevice, aRange.getMinX(), aRange.getMinY()-1.0, aRange.getMaxX(), aRange.getMinY()-1.0,
- aLineColor);
-
- drawHairLine(
- mpOutputDevice, aRange.getMinX(), aRange.getMinY()+1.0, aRange.getMaxX(), aRange.getMinY()+1.0,
- aLineColor);
-
- return true;
- }
-
- if (fH <= 1.0)
- {
- // Draw it as a line.
- drawHairLine(
- mpOutputDevice, aRange.getMinX(), aRange.getMinY(), aRange.getMaxX(), aRange.getMinY(),
- aLineColor);
-
- return true;
- }
-
- double fOffset = rtl::math::round(fH/2.0, 0, rtl_math_RoundingMode_Down);
- if (fOffset != 0.0)
- {
- // Move it up a bit to align it vertically centered.
- basegfx::B2DHomMatrix aMat;
- aMat.set(1, 2, -fOffset);
- aTarget.transform(aMat);
- }
- }
- else
- {
- // Vertical line. Draw it as a rectangle.
-
- aTarget = makeRectPolygon(fX1, fY1, nThick, fY2-fY1);
- aTarget.transform(maCurrentTransformation);
-
- basegfx::B2DRange aRange = aTarget.getB2DRange();
- double fW = aRange.getWidth();
-
- if (bDouble)
- {
- // Draw it as a line.
- drawHairLine(
- mpOutputDevice, aRange.getMinX()-1.0, aRange.getMinY(), aRange.getMinX()-1.0, aRange.getMaxY(),
- aLineColor);
-
- drawHairLine(
- mpOutputDevice, aRange.getMinX()+1.0, aRange.getMinY(), aRange.getMinX()+1.0, aRange.getMaxY(),
- aLineColor);
-
- return true;
- }
-
- if (fW <= 1.0)
- {
- // Draw it as a line.
- drawHairLine(
- mpOutputDevice, aRange.getMinX(), aRange.getMinY(), aRange.getMinX(), aRange.getMaxY(),
- aLineColor);
-
- return true;
- }
-
- double fOffset = rtl::math::round(fW/2.0, 0, rtl_math_RoundingMode_Down);
- if (fOffset != 0.0)
- {
- // Move it to the left a bit to center it horizontally.
- basegfx::B2DHomMatrix aMat;
- aMat.set(0, 2, -fOffset);
- aTarget.transform(aMat);
- }
- }
-
- mpOutputDevice->SetFillColor(Color(aLineColor));
- mpOutputDevice->SetLineColor();
- mpOutputDevice->DrawPolygon(aTarget);
- return true;
- }
- break;
- case SvxBorderLineStyle::DOTTED:
- case SvxBorderLineStyle::DASHED:
- case SvxBorderLineStyle::DASH_DOT:
- case SvxBorderLineStyle::DASH_DOT_DOT:
- case SvxBorderLineStyle::FINE_DASHED:
- {
- std::vector<double> aPattern =
- svtools::GetLineDashing(rSource.getStyle(), rSource.getPatternScale()*10.0);
-
- if (aPattern.empty())
- // Failed to get pattern values.
- return false;
-
- double nThick = rtl::math::round(rSource.getLeftWidth());
-
- const basegfx::BColor aLineColor =
- maBColorModifierStack.getModifiedColor(rSource.getRGBColorLeft());
-
- // Transform the current line range before using it for rendering.
- basegfx::B2DRange aRange(fX1, fY1, fX2, fY2);
- aRange.transform(maCurrentTransformation);
- fX1 = aRange.getMinX();
- fX2 = aRange.getMaxX();
- fY1 = aRange.getMinY();
- fY2 = aRange.getMaxY();
-
- basegfx::B2DPolyPolygon aTarget;
-
- if (bHorizontal)
- {
- // Horizontal line.
-
- if (basegfx::fTools::equalZero(nThick))
- {
- // Dash line segment too small to draw. Substitute it with a solid line.
- drawHairLine(mpOutputDevice, fX1, fY1, fX2, fY1, aLineColor);
- return true;
- }
-
- // Create a dash unit polygon set.
- basegfx::B2DPolyPolygon aDashes;
- std::vector<double>::const_iterator it = aPattern.begin(), itEnd = aPattern.end();
- for (; it != itEnd; ++it)
- aDashes.append(makeRectPolygon(0, 0, *it, nThick));
-
- aDashes.transform(maCurrentTransformation);
- rtl::math::setNan(&nThick);
-
- // Pixelize the dash unit. We use the same height for
- // all dash polygons.
- basegfx::B2DPolyPolygon aDashesPix;
-
- for (sal_uInt32 i = 0, n = aDashes.count(); i < n; ++i)
- {
- basegfx::B2DPolygon aPoly = aDashes.getB2DPolygon(i);
- aRange = aPoly.getB2DRange();
- double fW = rtl::math::round(aRange.getWidth());
- if (basegfx::fTools::equalZero(fW))
- {
- // Dash line segment too small to draw. Substitute it with a solid line.
- drawHairLine(mpOutputDevice, fX1, fY1, fX2, fY1, aLineColor);
- return true;
- }
-
- if (rtl::math::isNan(nThick))
- nThick = rtl::math::round(aRange.getHeight());
-
- aDashesPix.append(makeRectPolygon(0, 0, fW, nThick));
- }
-
- // Make all dash polygons and render them.
- double fX = fX1;
- bool bLine = true;
- sal_uInt32 i = 0, n = aDashesPix.count();
- while (fX <= fX2)
- {
- basegfx::B2DPolygon aPoly = aDashesPix.getB2DPolygon(i);
- aRange = aPoly.getB2DRange();
- if (bLine)
- {
- double fBlockW = aRange.getWidth();
- if (fX + fBlockW > fX2)
- // Clip the right end in case it spills over the range.
- fBlockW = fX2 - fX + 1;
-
- double fH = aRange.getHeight();
- if (basegfx::fTools::equalZero(fH))
- fH = 1.0;
-
- aTarget.append(makeRectPolygon(fX, fY1, fBlockW, fH));
- }
-
- bLine = !bLine; // line and blank alternate.
- fX += aRange.getWidth();
-
- ++i;
- if (i >= n)
- i = 0;
- }
-
- double fOffset = rtl::math::round(nThick/2.0, 0, rtl_math_RoundingMode_Down);
- if (fOffset != 0.0)
- {
- // Move it up a bit to align it vertically centered.
- basegfx::B2DHomMatrix aMat;
- aMat.set(1, 2, -fOffset);
- aTarget.transform(aMat);
- }
- }
- else
- {
- // Vertical line.
-
- if (basegfx::fTools::equalZero(nThick))
- {
- // Dash line segment too small to draw. Substitute it with a solid line.
- drawHairLine(mpOutputDevice, fX1, fY1, fX1, fY2, aLineColor);
- return true;
- }
-
- // Create a dash unit polygon set.
- basegfx::B2DPolyPolygon aDashes;
- std::vector<double>::const_iterator it = aPattern.begin(), itEnd = aPattern.end();
- for (; it != itEnd; ++it)
- aDashes.append(makeRectPolygon(0, 0, nThick, *it));
-
- aDashes.transform(maCurrentTransformation);
- rtl::math::setNan(&nThick);
-
- // Pixelize the dash unit. We use the same width for
- // all dash polygons.
- basegfx::B2DPolyPolygon aDashesPix;
-
- for (sal_uInt32 i = 0, n = aDashes.count(); i < n; ++i)
- {
- basegfx::B2DPolygon aPoly = aDashes.getB2DPolygon(i);
- aRange = aPoly.getB2DRange();
- double fH = rtl::math::round(aRange.getHeight());
- if (basegfx::fTools::equalZero(fH))
- {
- // Dash line segment too small to draw. Substitute it with a solid line.
- drawHairLine(mpOutputDevice, fX1, fY1, fX1, fY2, aLineColor);
- return true;
- }
-
- if (rtl::math::isNan(nThick))
- nThick = rtl::math::round(aRange.getWidth());
-
- aDashesPix.append(makeRectPolygon(0, 0, nThick, fH));
- }
-
- // Make all dash polygons and render them.
- double fY = fY1;
- bool bLine = true;
- sal_uInt32 i = 0, n = aDashesPix.count();
- while (fY <= fY2)
- {
- basegfx::B2DPolygon aPoly = aDashesPix.getB2DPolygon(i);
- aRange = aPoly.getB2DRange();
- if (bLine)
- {
- double fBlockH = aRange.getHeight();
- if (fY + fBlockH > fY2)
- // Clip the bottom end in case it spills over the range.
- fBlockH = fY2 - fY + 1;
-
- double fW = aRange.getWidth();
- if (basegfx::fTools::equalZero(fW))
- fW = 1.0;
-
- aTarget.append(makeRectPolygon(fX1, fY, fW, fBlockH));
- }
-
- bLine = !bLine; // line and blank alternate.
- fY += aRange.getHeight();
-
- ++i;
- if (i >= n)
- i = 0;
- }
-
- double fOffset = rtl::math::round(nThick/2.0, 0, rtl_math_RoundingMode_Down);
- if (fOffset != 0.0)
- {
- // Move it to the left a bit to center it horizontally.
- basegfx::B2DHomMatrix aMat;
- aMat.set(0, 2, -fOffset);
- aTarget.transform(aMat);
- }
- }
-
- mpOutputDevice->SetFillColor(Color(aLineColor));
- mpOutputDevice->SetLineColor();
- mpOutputDevice->DrawPolyPolygon(aTarget);
-
- return true;
- }
- break;
- default:
- ;
- }
- return false;
- }
-
void VclPixelProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate)
{
switch(rCandidate.getPrimitive2DID())
@@ -1253,28 +890,26 @@ namespace drawinglayer
}
case PRIMITIVE2D_ID_BORDERLINEPRIMITIVE2D:
{
- // process recursively, but turn off anti-aliasing. Border
- // lines are always rectangular, and look horrible when
- // the anti-aliasing is enabled.
- AntialiasingFlags nAntiAliasing = mpOutputDevice->GetAntialiasing();
- mpOutputDevice->SetAntialiasing(nAntiAliasing & ~AntialiasingFlags::EnableB2dDraw);
-
+ // process recursively, but switch off AntiAliasing for
+ // horizontal/vertical lines (*not* diagonal lines).
+ // Checked using AntialiasingFlags::PixelSnapHairline instead,
+ // but with AntiAliasing on the display really is too 'ghosty' when
+ // using fine stroking. Correct, but 'ghosty'.
const drawinglayer::primitive2d::BorderLinePrimitive2D& rBorder =
static_cast<const drawinglayer::primitive2d::BorderLinePrimitive2D&>(rCandidate);
- if (!tryDrawBorderLinePrimitive2DDirect(rBorder))
+ if (rBorder.isHorizontalOrVertical(getViewInformation2D()))
{
- if (rBorder.getStyle() == SvxBorderLineStyle::DOUBLE)
- {
- primitive2d::Primitive2DContainer aContainer;
- rBorder.createDecomposition(aContainer, getViewInformation2D(), true);
- process(aContainer);
- }
- else
- process(rCandidate);
- }
+ AntialiasingFlags nAntiAliasing = mpOutputDevice->GetAntialiasing();
+ mpOutputDevice->SetAntialiasing(nAntiAliasing & ~AntialiasingFlags::EnableB2dDraw);
- mpOutputDevice->SetAntialiasing(nAntiAliasing);
+ process(rCandidate);
+ mpOutputDevice->SetAntialiasing(nAntiAliasing);
+ }
+ else
+ {
+ process(rCandidate);
+ }
break;
}
default :
diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.hxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.hxx
index 0a8e97d748b8..19c0282ffc5a 100644
--- a/drawinglayer/source/processor2d/vclpixelprocessor2d.hxx
+++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.hxx
@@ -64,7 +64,6 @@ namespace drawinglayer
bool tryDrawPolyPolygonColorPrimitive2DDirect(const drawinglayer::primitive2d::PolyPolygonColorPrimitive2D& rSource, double fTransparency);
bool tryDrawPolygonHairlinePrimitive2DDirect(const drawinglayer::primitive2d::PolygonHairlinePrimitive2D& rSource, double fTransparency);
bool tryDrawPolygonStrokePrimitive2DDirect(const drawinglayer::primitive2d::PolygonStrokePrimitive2D& rSource, double fTransparency);
- bool tryDrawBorderLinePrimitive2DDirect(const drawinglayer::primitive2d::BorderLinePrimitive2D& rSource);
public:
/// constructor/destructor
diff --git a/include/drawinglayer/primitive2d/borderlineprimitive2d.hxx b/include/drawinglayer/primitive2d/borderlineprimitive2d.hxx
index 4ac0a1045585..4645bde2a2c5 100644
--- a/include/drawinglayer/primitive2d/borderlineprimitive2d.hxx
+++ b/include/drawinglayer/primitive2d/borderlineprimitive2d.hxx
@@ -66,27 +66,29 @@ namespace drawinglayer
bool mbHasGapColor;
SvxBorderLineStyle mnStyle;
-
double mfPatternScale;
- /// local helpers
- double getWidth(
- const geometry::ViewInformation2D& rViewInformation) const;
+ // for view dependent decomposition in the case with distance (gap),
+ // remember the last used concrete mfDistance, see get2DDecomposition
+ // implementation
+ double mfDiscreteDistance;
+ /// local helpers
bool isInsideUsed() const
{
return !basegfx::fTools::equalZero(mfLeftWidth);
}
+ bool isDistanceUsed() const
+ {
+ return !basegfx::fTools::equalZero(mfDistance);
+ }
+
bool isOutsideUsed() const
{
return !basegfx::fTools::equalZero(mfRightWidth);
}
- protected:
- virtual basegfx::B2DPolyPolygon getClipPolygon(
- const geometry::ViewInformation2D& rViewInformation) const;
-
/// create local decomposition
virtual void create2DDecomposition(Primitive2DContainer& rContainer, const geometry::ViewInformation2D& rViewInformation) const override;
@@ -125,12 +127,16 @@ namespace drawinglayer
bool hasGapColor( ) const { return mbHasGapColor; }
SvxBorderLineStyle getStyle () const { return mnStyle; }
double getPatternScale() const { return mfPatternScale; }
- /// Same as create2DDecomposition(), but can do pixel correction if requested.
- void createDecomposition(Primitive2DContainer& rContainer, const geometry::ViewInformation2D& rViewInformation, bool bPixelCorrection) const;
+
+ /// helper to decide if AntiAliasing should be used
+ bool isHorizontalOrVertical(const geometry::ViewInformation2D& rViewInformation) const;
/// compare operator
virtual bool operator==(const BasePrimitive2D& rPrimitive) const override;
+ /// Override standard getDecomposition to be view-dependent here
+ virtual void get2DDecomposition(Primitive2DDecompositionVisitor& rVisitor, const geometry::ViewInformation2D& rViewInformation) const override;
+
/// provide unique ID
DeclPrimitive2DIDBlock()
};
diff --git a/include/drawinglayer/primitive2d/clippedborderlineprimitive2d.hxx b/include/drawinglayer/primitive2d/clippedborderlineprimitive2d.hxx
deleted file mode 100644
index 3fe2813be9a9..000000000000
--- a/include/drawinglayer/primitive2d/clippedborderlineprimitive2d.hxx
+++ /dev/null
@@ -1,65 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-#ifndef INCLUDED_DRAWINGLAYER_PRIMITIVE2D_CLIPPEDBORDERLINEPRIMITIVE2D_HXX
-#define INCLUDED_DRAWINGLAYER_PRIMITIVE2D_CLIPPEDBORDERLINEPRIMITIVE2D_HXX
-
-#include <drawinglayer/drawinglayerdllapi.h>
-
-#include <drawinglayer/primitive2d/borderlineprimitive2d.hxx>
-#include <basegfx/polygon/b2dpolypolygon.hxx>
-#include <basegfx/polygon/b2dpolygon.hxx>
-
-
-namespace drawinglayer
-{
- namespace primitive2d
- {
- /** BorderLinePrimitive2D clipped by the intersection with a provided
- polygon.
- */
- class DRAWINGLAYER_DLLPUBLIC ClippedBorderLinePrimitive2D : public BorderLinePrimitive2D
- {
- private:
- const basegfx::B2DPolygon maIntersection;
-
- protected:
- virtual basegfx::B2DPolyPolygon getClipPolygon(
- const geometry::ViewInformation2D& rViewInformation) const override;
-
- public:
- /// constructor
- ClippedBorderLinePrimitive2D(
- const basegfx::B2DPoint& rStart,
- const basegfx::B2DPoint& rEnd,
- double fLeftWidth,
- double fDistance,
- double fRightWidth,
- const basegfx::B2DPolygon& rIntersection,
- const basegfx::BColor& rRGBColorRight,
- const basegfx::BColor& rRGBColorLeft,
- const basegfx::BColor& rRGBColorGap,
- bool bHasGapColor,
- SvxBorderLineStyle nStyle,
- double fPatternScale );
-
- /// compare operator
- virtual bool operator==(const BasePrimitive2D& rPrimitive) const override;
-
- /// provide unique ID
- DeclPrimitive2DIDBlock()
- };
- } // end of namespace primitive2d
-} // end of namespace drawinglayer
-
-
-#endif //INCLUDED_DRAWINGLAYER_PRIMITIVE2D_CLIPPEDBORDERLINEPRIMITIVE2D_HXX
-
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/svx/framelink.hxx b/include/svx/framelink.hxx
index 20ef1dbc6dcc..d5a962acdb1d 100644
--- a/include/svx/framelink.hxx
+++ b/include/svx/framelink.hxx
@@ -429,7 +429,7 @@ SVX_DLLPUBLIC bool CheckFrameBorderConnectable(
| \ / |
rLFromB \ / rRFromB
*/
-SVX_DLLPUBLIC drawinglayer::primitive2d::Primitive2DContainer CreateBorderPrimitives(
+SVX_DLLPUBLIC drawinglayer::primitive2d::Primitive2DReference CreateBorderPrimitives(
const Point& rLPos, /// Reference point for left end of the processed frame border.
const Point& rRPos, /// Reference point for right end of the processed frame border.
const Style& rBorder, /// Style of the processed frame border.
@@ -451,7 +451,7 @@ SVX_DLLPUBLIC drawinglayer::primitive2d::Primitive2DContainer CreateBorderPrimit
const long rRotationB = 9000 /// Angle of the bottom slanted frames in 100th of degree
);
-SVX_DLLPUBLIC drawinglayer::primitive2d::Primitive2DContainer CreateBorderPrimitives(
+SVX_DLLPUBLIC drawinglayer::primitive2d::Primitive2DReference CreateBorderPrimitives(
const Point& rLPos, /// Reference point for left end of the processed frame border.
const Point& rRPos, /// Reference point for right end of the processed frame border.
const Style& rBorder, /// Style of the processed frame border.
@@ -469,10 +469,6 @@ SVX_DLLPUBLIC drawinglayer::primitive2d::Primitive2DContainer CreateBorderPrimit
const long rRotationB = 9000 /// Angle of the bottom slanted frame in 100th of degrees
);
-SVX_DLLPUBLIC drawinglayer::primitive2d::Primitive2DContainer CreateClippedBorderPrimitives (
- const Point& rStart, const Point& rEnd, const Style& rBorder,
- const tools::Rectangle& rClipRect );
-
/** Draws a horizontal frame border, regards all connected frame styles.
The frame style to draw is passed as parameter rBorder. The function
diff --git a/include/svx/framelinkarray.hxx b/include/svx/framelinkarray.hxx
index a899caa7ee40..9208f67b46ae 100644
--- a/include/svx/framelinkarray.hxx
+++ b/include/svx/framelinkarray.hxx
@@ -331,7 +331,7 @@ public:
/** Draws the part of the specified range, that is inside the clipping range.
@param pForceColor
If not NULL, only this color will be used to draw all frame borders. */
- void DrawRange( drawinglayer::processor2d::BaseProcessor2D* rDev,
+ void DrawRange( drawinglayer::processor2d::BaseProcessor2D& rProcessor,
size_t nFirstCol, size_t nFirstRow,
size_t nLastCol, size_t nLastRow,
const Color* pForceColor ) const;
@@ -344,7 +344,10 @@ public:
size_t nLastCol, size_t nLastRow ) const;
/** Draws the part of the array, that is inside the clipping range. */
- void DrawArray( OutputDevice& rDev ) const;
+ void DrawArray(OutputDevice& rDev) const;
+
+ /** Draws the part of the array, that is inside the clipping range. */
+ void DrawArray(drawinglayer::processor2d::BaseProcessor2D& rProcessor) const;
private:
diff --git a/sc/source/ui/view/output.cxx b/sc/source/ui/view/output.cxx
index a1d4db5e12e5..8c656ca45bb7 100644
--- a/sc/source/ui/view/output.cxx
+++ b/sc/source/ui/view/output.cxx
@@ -1458,7 +1458,7 @@ void ScOutputData::DrawFrame(vcl::RenderContext& rRenderContext)
{
size_t nRow2 = nRow1;
while( (nRow2 + 1 <= nLastRow) && pRowInfo[ nRow2 + 1 ].bChanged ) ++nRow2;
- rArray.DrawRange( pProcessor.get(), nFirstCol, nRow1, nLastCol, nRow2, pForceColor );
+ rArray.DrawRange( *pProcessor.get(), nFirstCol, nRow1, nLastCol, nRow2, pForceColor );
nRow1 = nRow2 + 1;
}
}
@@ -1759,58 +1759,70 @@ void ScOutputData::DrawRotatedFrame(vcl::RenderContext& rRenderContext, const Co
if (aTopLine.Prim() || aTopLine.Secn())
{
long nUpperRotate = lcl_getRotate( mpDoc, nTab, nX, nY - 1 );
- pProcessor->process( svx::frame::CreateBorderPrimitives(
- aPoints[bLayoutRTL?1:0], aPoints[bLayoutRTL?0:1], aTopLine,
- svx::frame::Style(),
- svx::frame::Style(),
- aLeftLine,
- svx::frame::Style(),
- svx::frame::Style(),
- aRightLine,
- pForceColor, nUpperRotate, nAttrRotate ) );
+ drawinglayer::primitive2d::Primitive2DContainer aSequence(1);
+ aSequence.append(
+ svx::frame::CreateBorderPrimitives(
+ aPoints[bLayoutRTL?1:0], aPoints[bLayoutRTL?0:1], aTopLine,
+ svx::frame::Style(),
+ svx::frame::Style(),
+ aLeftLine,
+ svx::frame::Style(),
+ svx::frame::Style(),
+ aRightLine,
+ pForceColor, nUpperRotate, nAttrRotate ) );
+ pProcessor->process(aSequence);
}
if (aBottomLine.Prim() || aBottomLine.Secn())
{
long nLowerRotate = lcl_getRotate( mpDoc, nTab, nX, nY + 1 );
- pProcessor->process( svx::frame::CreateBorderPrimitives(
- aPoints[bLayoutRTL?2:3], aPoints[bLayoutRTL?3:2], aBottomLine,
- aLeftLine,
- svx::frame::Style(),
- svx::frame::Style(),
- aRightLine,
- svx::frame::Style(),
- svx::frame::Style(),
- pForceColor, 18000 - nAttrRotate, 18000 - nLowerRotate ) );
+ drawinglayer::primitive2d::Primitive2DContainer aSequence(1);
+ aSequence.append(
+ svx::frame::CreateBorderPrimitives(
+ aPoints[bLayoutRTL?2:3], aPoints[bLayoutRTL?3:2], aBottomLine,
+ aLeftLine,
+ svx::frame::Style(),
+ svx::frame::Style(),
+ aRightLine,
+ svx::frame::Style(),
+ svx::frame::Style(),
+ pForceColor, 18000 - nAttrRotate, 18000 - nLowerRotate ) );
+ pProcessor->process(aSequence);
}
// Vertical slanted lines
if (aLeftLine.Prim() || aLeftLine.Secn())
{
long nLeftRotate = lcl_getRotate( mpDoc, nTab, nX - 1, nY );
- pProcessor->process( svx::frame::CreateBorderPrimitives(
- aPoints[0], aPoints[3], aLeftLine,
- aTopLine,
- svx::frame::Style(),
- svx::frame::Style(),
- aBottomLine,
- svx::frame::Style(),
- svx::frame::Style(),
- pForceColor, nAttrRotate, nLeftRotate ) );
+ drawinglayer::primitive2d::Primitive2DContainer aSequence(1);
+ aSequence.append(
+ svx::frame::CreateBorderPrimitives(
+ aPoints[0], aPoints[3], aLeftLine,
+ aTopLine,
+ svx::frame::Style(),
+ svx::frame::Style(),
+ aBottomLine,
+ svx::frame::Style(),
+ svx::frame::Style(),
+ pForceColor, nAttrRotate, nLeftRotate ) );
+ pProcessor->process(aSequence);
}
if (aRightLine.Prim() || aRightLine.Secn())
{
long nRightRotate = lcl_getRotate( mpDoc, nTab, nX + 1, nY );
- pProcessor->process( svx::frame::CreateBorderPrimitives(
- aPoints[1], aPoints[2], aRightLine,
- svx::frame::Style(),
- svx::frame::Style(),
- aTopLine,
- svx::frame::Style(),
- svx::frame::Style(),
- aBottomLine,
- pForceColor, 18000 - nRightRotate, 18000 - nAttrRotate ) );
+ drawinglayer::primitive2d::Primitive2DContainer aSequence(1);
+ aSequence.append(
+ svx::frame::CreateBorderPrimitives(
+ aPoints[1], aPoints[2], aRightLine,
+ svx::frame::Style(),
+ svx::frame::Style(),
+ aTopLine,
+ svx::frame::Style(),
+ svx::frame::Style(),
+ aBottomLine,
+ pForceColor, 18000 - nRightRotate, 18000 - nAttrRotate ) );
+ pProcessor->process(aSequence);
}
}
}
diff --git a/svx/source/dialog/framelink.cxx b/svx/source/dialog/framelink.cxx
index 2de6d3dae281..d2a1e1ffd06e 100644
--- a/svx/source/dialog/framelink.cxx
+++ b/svx/source/dialog/framelink.cxx
@@ -33,7 +33,6 @@
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <drawinglayer/primitive2d/borderlineprimitive2d.hxx>
-#include <drawinglayer/primitive2d/clippedborderlineprimitive2d.hxx>
using namespace ::com::sun::star;
@@ -1349,9 +1348,34 @@ bool CheckFrameBorderConnectable( const Style& rLBorder, const Style& rRBorder,
// Drawing functions
+// get offset to center of line in question
+double lcl_getCenterOfLineOffset(const Style& rBorder, bool bLeftEdge)
+{
+ const bool bPrimUsed(!basegfx::fTools::equalZero(rBorder.Prim())); // left
+ const bool bDistUsed(!basegfx::fTools::equalZero(rBorder.Dist())); // distance
+ const bool bSecnUsed(!basegfx::fTools::equalZero(rBorder.Secn())); // right
+
+ if (bDistUsed || bSecnUsed)
+ {
+ // double line, get center by adding half ditance and half line width.
+ // bLeftEdge defines which line to use
+ return (rBorder.Dist() + (bLeftEdge ? rBorder.Prim() : rBorder.Secn())) * 0.5;
+ }
+ else if (bPrimUsed)
+ {
+ // single line, get center
+ return rBorder.Prim() * 0.5;
+ }
+
+ // no line width at all, stay on unit vector
+ return 0.0;
+}
-double lcl_GetExtent( const Style& rBorder, const Style& rSide, const Style& rOpposite,
- long nAngleSide, long nAngleOpposite )
+double lcl_GetExtent(
+ const Style& rBorder, const Style& rSide, const Style& rOpposite,
+ long nAngleSide, long nAngleOpposite,
+ bool bLeftEdge, // left or right of rBorder
+ bool bOtherLeft ) // left or right of rSide/rOpposite
{
Style aOtherBorder = rSide;
long nOtherAngle = nAngleSide;
@@ -1370,7 +1394,8 @@ double lcl_GetExtent( const Style& rBorder, const Style& rSide, const Style& rOp
// Let's assume the border we are drawing is horizontal and compute all the angles / distances from this
basegfx::B2DVector aBaseVector( 1.0, 0.0 );
- basegfx::B2DPoint aBasePoint( 0.0, static_cast<double>( rBorder.GetWidth() / 2 ) );
+ // added support to get the distances to the centers of the line, *not* the outre edge
+ basegfx::B2DPoint aBasePoint(0.0, lcl_getCenterOfLineOffset(rBorder, bLeftEdge));
basegfx::B2DHomMatrix aRotation;
aRotation.rotate( double( nOtherAngle ) * M_PI / 18000.0 );
@@ -1378,7 +1403,8 @@ double lcl_GetExtent( const Style& rBorder, const Style& rSide, const Style& rOp
basegfx::B2DVector aOtherVector = aRotation * aBaseVector;
// Compute a line shifted by half the width of the other border
basegfx::B2DVector aPerpendicular = basegfx::getNormalizedPerpendicular( aOtherVector );
- basegfx::B2DPoint aOtherPoint = basegfx::B2DPoint() + aPerpendicular * aOtherBorder.GetWidth() / 2;
+ // added support to get the distances to the centers of the line, *not* the outre edge
+ basegfx::B2DPoint aOtherPoint = basegfx::B2DPoint() + aPerpendicular * lcl_getCenterOfLineOffset(aOtherBorder, bOtherLeft);
// Find the cut between the two lines
double nCut = 0.0;
@@ -1389,67 +1415,32 @@ double lcl_GetExtent( const Style& rBorder, const Style& rSide, const Style& rOp
return nCut;
}
-basegfx::B2DPoint lcl_PointToB2DPoint( const Point& rPoint )
-{
- return basegfx::B2DPoint(rPoint.getX(), rPoint.getY());
-}
-
-drawinglayer::primitive2d::Primitive2DContainer CreateClippedBorderPrimitives (
- const Point& rStart, const Point& rEnd, const Style& rBorder,
- const tools::Rectangle& rClipRect )
-{
- drawinglayer::primitive2d::Primitive2DContainer aSequence( 1 );
- basegfx::B2DPolygon aPolygon;
- aPolygon.append( lcl_PointToB2DPoint( rClipRect.TopLeft( ) ) );
- aPolygon.append( lcl_PointToB2DPoint( rClipRect.TopRight( ) ) );
- aPolygon.append( lcl_PointToB2DPoint( rClipRect.BottomRight( ) ) );
- aPolygon.append( lcl_PointToB2DPoint( rClipRect.BottomLeft( ) ) );
- aPolygon.setClosed( true );
-
- aSequence[0] = new drawinglayer::primitive2d::ClippedBorderLinePrimitive2D(
- lcl_PointToB2DPoint( rStart ),
- lcl_PointToB2DPoint( rEnd ),
- rBorder.Prim(),
- rBorder.Dist(),
- rBorder.Secn(),
- aPolygon,
- rBorder.GetColorSecn().getBColor(),
- rBorder.GetColorPrim().getBColor(),
- rBorder.GetColorGap().getBColor(),
- rBorder.UseGapColor(), rBorder.Type(), rBorder.PatternScale() );
-
- return aSequence;
-}
-
-drawinglayer::primitive2d::Primitive2DContainer CreateBorderPrimitives(
+drawinglayer::primitive2d::Primitive2DReference CreateBorderPrimitives(
const Point& rLPos, const Point& rRPos, const Style& rBorder,
const DiagStyle& /*rLFromTR*/, const Style& rLFromT, const Style& /*rLFromL*/, const Style& rLFromB, const DiagStyle& /*rLFromBR*/,
const DiagStyle& /*rRFromTL*/, const Style& rRFromT, const Style& /*rRFromR*/, const Style& rRFromB, const DiagStyle& /*rRFromBL*/,
const Color* /*pForceColor*/, long nRotateT, long nRotateB )
{
- drawinglayer::primitive2d::Primitive2DContainer aSequence( 1 );
-
basegfx::B2DPoint aStart( rLPos.getX(), rLPos.getY() );
basegfx::B2DPoint aEnd( rRPos.getX(), rRPos.getY() );
- aSequence[0] = new drawinglayer::primitive2d::BorderLinePrimitive2D(
- aStart, aEnd,
- rBorder.Prim(),
- rBorder.Dist(),
- rBorder.Secn(),
- lcl_GetExtent( rBorder, rLFromT, rLFromB, nRotateT, - nRotateB ),
- lcl_GetExtent( rBorder, rRFromT, rRFromB, 18000 - nRotateT, nRotateB - 18000 ),
- lcl_GetExtent( rBorder, rLFromB, rLFromT, nRotateB, - nRotateT ),
- lcl_GetExtent( rBorder, rRFromB, rRFromT, 18000 - nRotateB, nRotateT - 18000 ),
- rBorder.GetColorSecn().getBColor(),
- rBorder.GetColorPrim().getBColor(),
- rBorder.GetColorGap().getBColor(),
- rBorder.UseGapColor(), rBorder.Type(), rBorder.PatternScale() );
-
- return aSequence;
+ return drawinglayer::primitive2d::Primitive2DReference(
+ new drawinglayer::primitive2d::BorderLinePrimitive2D(
+ aStart, aEnd,
+ rBorder.Prim(),
+ rBorder.Dist(),
+ rBorder.Secn(),
+ lcl_GetExtent( rBorder, rLFromT, rLFromB, nRotateT, - nRotateB, true, false ), // top-left, so left for rBorder and right for left outer
+ lcl_GetExtent( rBorder, rRFromT, rRFromB, 18000 - nRotateT, nRotateB - 18000, true, true ), // top-right
+ lcl_GetExtent( rBorder, rLFromB, rLFromT, nRotateB, - nRotateT, false, false ), // bottom-left
+ lcl_GetExtent( rBorder, rRFromB, rRFromT, 18000 - nRotateB, nRotateT - 18000, false, true ), // bottom-right
+ rBorder.GetColorSecn().getBColor(),
+ rBorder.GetColorPrim().getBColor(),
+ rBorder.GetColorGap().getBColor(),
+ rBorder.UseGapColor(), rBorder.Type(), rBorder.PatternScale()));
}
-drawinglayer::primitive2d::Primitive2DContainer CreateBorderPrimitives(
+drawinglayer::primitive2d::Primitive2DReference CreateBorderPrimitives(
const Point& rLPos, const Point& rRPos, const Style& rBorder,
const Style& rLFromT, const Style& rLFromL, const Style& rLFromB,
const Style& rRFromT, const Style& rRFromR, const Style& rRFromB,
diff --git a/svx/source/dialog/framelinkarray.cxx b/svx/source/dialog/framelinkarray.cxx
index 079a12b9acb3..24f432e3b97d 100644
--- a/svx/source/dialog/framelinkarray.cxx
+++ b/svx/source/dialog/framelinkarray.cxx
@@ -23,6 +23,7 @@
#include <vector>
#include <algorithm>
#include <vcl/outdev.hxx>
+#include <drawinglayer/primitive2d/borderlineprimitive2d.hxx>
namespace svx {
namespace frame {
@@ -878,7 +879,7 @@ void Array::MirrorSelfX()
}
// drawing
-void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D* pProcessor,
+void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D& rProcessor,
size_t nFirstCol, size_t nFirstRow, size_t nLastCol, size_t nLastRow,
const Color* pForceColor ) const
{
@@ -907,23 +908,52 @@ void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D* pProcessor,
size_t _nFirstRow = mxImpl->GetMergedFirstRow( nCol, nRow );
const Style aTlbrStyle = GetCellStyleTLBR( _nFirstCol, _nFirstRow );
- if ( aTlbrStyle.GetWidth( ) )
- pProcessor->process( CreateClippedBorderPrimitives(
- aRect.TopLeft(), aRect.BottomRight(),
- aTlbrStyle, aRect ) );
+ if (aTlbrStyle.GetWidth())
+ {
+ drawinglayer::primitive2d::Primitive2DContainer aSequence(1);
+ aSequence.append(
+ new drawinglayer::primitive2d::BorderLinePrimitive2D(
+ basegfx::B2DPoint(aRect.Left(), aRect.Top()),
+ basegfx::B2DPoint(aRect.Right(), aRect.Bottom()),
+ aTlbrStyle.Prim(),
+ aTlbrStyle.Dist(),
+ aTlbrStyle.Secn(),
+ 0.0, 0.0, 0.0, 0.0,
+ aTlbrStyle.GetColorSecn().getBColor(),
+ aTlbrStyle.GetColorPrim().getBColor(),
+ aTlbrStyle.GetColorGap().getBColor(),
+ aTlbrStyle.UseGapColor(),
+ aTlbrStyle.Type(),
+ aTlbrStyle.PatternScale()));
+ rProcessor.process(aSequence);
+ }
const Style aBltrStyle = GetCellStyleBLTR( _nFirstCol, _nFirstRow );
- if ( aBltrStyle.GetWidth( ) )
- pProcessor->process( CreateClippedBorderPrimitives(
- aRect.BottomLeft(), aRect.TopRight(),
- aBltrStyle, aRect ) );
+ if (aBltrStyle.GetWidth())
+ {
+ drawinglayer::primitive2d::Primitive2DContainer aSequence(1);
+ aSequence.append(
+ new drawinglayer::primitive2d::BorderLinePrimitive2D(
+ basegfx::B2DPoint(aRect.Left(), aRect.Bottom()),
+ basegfx::B2DPoint(aRect.Right(), aRect.Top()),
+ aBltrStyle.Prim(),
+ aBltrStyle.Dist(),
+ aBltrStyle.Secn(),
+ 0.0, 0.0, 0.0, 0.0,
+ aBltrStyle.GetColorSecn().getBColor(),
+ aBltrStyle.GetColorPrim().getBColor(),
+ aBltrStyle.GetColorGap().getBColor(),
+ aBltrStyle.UseGapColor(),
+ aBltrStyle.Type(),
+ aBltrStyle.PatternScale()));
+ rProcessor.process(aSequence);
+ }
}
}
}
}
// *** horizontal frame borders ***
-
for( nRow = nFirstRow; nRow <= nLastRow + 1; ++nRow )
{
double fAngle = mxImpl->GetHorDiagAngle( nFirstCol, nRow );
@@ -970,10 +1000,27 @@ void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D* pProcessor,
{
// draw previous frame border
Point aEndPos( mxImpl->GetColPosition( nCol ), aStartPos.Y() );
- if( pStart->Prim() && (aStartPos.X() <= aEndPos.X()) )
- pProcessor->process( CreateBorderPrimitives( aStartPos, aEndPos, *pStart,
- aStartLFromTR, *pStartLFromT, *pStartLFromL, *pStartLFromB, aStartLFromBR,
- aEndRFromTL, *pEndRFromT, *pEndRFromR, *pEndRFromB, aEndRFromBL, pForceColor ) );
+ if (pStart->Prim() && (aStartPos.X() <= aEndPos.X()))
+ {
+ drawinglayer::primitive2d::Primitive2DContainer aSequence(1);
+ aSequence.append(
+ CreateBorderPrimitives(
+ aStartPos,
+ aEndPos,
+ *pStart,
+ aStartLFromTR,
+ *pStartLFromT,
+ *pStartLFromL,
+ *pStartLFromB,
+ aStartLFromBR,
+ aEndRFromTL,
+ *pEndRFromT,
+ *pEndRFromR,
+ *pEndRFromB,
+ aEndRFromBL,
+ pForceColor));
+ rProcessor.process(aSequence);
+ }
// re-init "*Start***" variables
aStartPos = aEndPos;
@@ -995,10 +1042,27 @@ void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D* pProcessor,
// draw last frame border
Point aEndPos( mxImpl->GetColPosition( nCol ), aStartPos.Y() );
- if( pStart->Prim() && (aStartPos.X() <= aEndPos.X()) )
- pProcessor->process( CreateBorderPrimitives( aStartPos, aEndPos, *pStart,
- aStartLFromTR, *pStartLFromT, *pStartLFromL, *pStartLFromB, aStartLFromBR,
- aEndRFromTL, *pEndRFromT, *pEndRFromR, *pEndRFromB, aEndRFromBL, pForceColor ) );
+ if (pStart->Prim() && (aStartPos.X() <= aEndPos.X()))
+ {
+ drawinglayer::primitive2d::Primitive2DContainer aSequence(1);
+ aSequence.append(
+ CreateBorderPrimitives(
+ aStartPos,
+ aEndPos,
+ *pStart,
+ aStartLFromTR,
+ *pStartLFromT,
+ *pStartLFromL,
+ *pStartLFromB,
+ aStartLFromBR,
+ aEndRFromTL,
+ *pEndRFromT,
+ *pEndRFromR,
+ *pEndRFromB,
+ aEndRFromBL,
+ pForceColor));
+ rProcessor.process(aSequence);
+ }
}
// *** vertical frame borders ***
@@ -1048,10 +1112,35 @@ void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D* pProcessor,
{
// draw previous frame border
Point aEndPos( aStartPos.X(), mxImpl->GetRowPosition( nRow ) );
- if( pStart->Prim() && (aStartPos.Y() <= aEndPos.Y()) )
- pProcessor->process( CreateBorderPrimitives( aEndPos, aStartPos, *pStart,
- aEndBFromTL, *pEndBFromL, *pEndBFromB, *pEndBFromR, aEndBFromTR,
- aStartTFromBL, *pStartTFromL, *pStartTFromT, *pStartTFromR, aStartTFromBR, pForceColor ) );
+ if (pStart->Prim() && (aStartPos.Y() <= aEndPos.Y()))
+ {
+ drawinglayer::primitive2d::Primitive2DContainer aSequence(1);
+ aSequence.append(
+ CreateBorderPrimitives(
+ // This replaces DrawVerFrameBorder which went from top to bottom. To be able to use
+ // the same method as for horizontal (CreateBorderPrimitives), the given borders
+ // have to be rearranged. Best is to look at the explanations of parameters in
+ // framelink.hxx and the former calls to DrawVerFrameBorder and it's parameters.
+ // In principle, the order of the five TFrom and BFrom has to be
+ // inverted to get the same orientation. Before, EndPos and StartPos were changed
+ // which avoids the reordering, but also leads to inverted line patters for vertical
+ // lines
+ aStartPos,
+ aEndPos,
+ *pStart,
+ aStartTFromBR,
+ *pStartTFromR,
+ *pStartTFromT,
+ *pStartTFromL,
+ aStartTFromBL,
+ aEndBFromTR,
+ *pEndBFromR,
+ *pEndBFromB,
+ *pEndBFromL,
+ aEndBFromTL,
+ pForceColor));
+ rProcessor.process(aSequence);
+ }
// re-init "*Start***" variables
aStartPos = aEndPos;
@@ -1073,10 +1162,28 @@ void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D* pProcessor,
// draw last frame border
Point aEndPos( aStartPos.X(), mxImpl->GetRowPosition( nRow ) );
- if( pStart->Prim() && (aStartPos.Y() <= aEndPos.Y()) )
- pProcessor->process( CreateBorderPrimitives( aEndPos, aStartPos, *pStart,
- aEndBFromTL, *pEndBFromL, *pEndBFromB, *pEndBFromR, aEndBFromTR,
- aStartTFromBL, *pStartTFromL, *pStartTFromT, *pStartTFromR, aStartTFromBR, pForceColor ) );
+ if (pStart->Prim() && (aStartPos.Y() <= aEndPos.Y()))
+ {
+ drawinglayer::primitive2d::Primitive2DContainer aSequence(1);
+ aSequence.append(
+ CreateBorderPrimitives(
+ // also reordered, see call to CreateBorderPrimitives above
+ aStartPos,
+ aEndPos,
+ *pStart,
+ aStartTFromBR,
+ *pStartTFromR,
+ *pStartTFromT,
+ *pStartTFromL,
+ aStartTFromBL,
+ aEndBFromTR,
+ *pEndBFromR,
+ *pEndBFromB,
+ *pEndBFromL,
+ aEndBFromTL,
+ pForceColor));
+ rProcessor.process(aSequence);
+ }
}
}
@@ -1291,6 +1398,12 @@ void Array::DrawArray( OutputDevice& rDev ) const
DrawRange( rDev, 0, 0, mxImpl->mnWidth - 1, mxImpl->mnHeight - 1 );
}
+void Array::DrawArray(drawinglayer::processor2d::BaseProcessor2D& rProcessor) const
+{
+ if (mxImpl->mnWidth && mxImpl->mnHeight)
+ DrawRange(rProcessor, 0, 0, mxImpl->mnWidth - 1, mxImpl->mnHeight - 1, nullptr);
+}
+
#undef ORIGCELL
#undef CELLACC
diff --git a/svx/source/dialog/frmsel.cxx b/svx/source/dialog/frmsel.cxx
index 7886c117ddf8..02c9493b9d86 100644
--- a/svx/source/dialog/frmsel.cxx
+++ b/svx/source/dialog/frmsel.cxx
@@ -28,6 +28,7 @@
#include <com/sun/star/accessibility/AccessibleEventId.hpp>
#include <com/sun/star/accessibility/AccessibleStateType.hpp>
#include <vcl/settings.hxx>
+#include <drawinglayer/processor2d/processor2dtools.hxx>
#include <svx/dialogs.hrc>
#include "bitmaps.hlst"
@@ -671,7 +672,36 @@ void FrameSelectorImpl::DrawAllFrameBorders()
maArray.SetCellStyleDiag( nCol, nRow, maTLBR.GetUIStyle(), maBLTR.GetUIStyle() );
// Let the helper array draw itself
- maArray.DrawArray( *mpVirDev.get() );
+ static bool bUsePrimitives(true);
+
+ if (bUsePrimitives)
+ {
+ // This is used in the dialog/control for 'Border' attributes. When using
+ // the original paint below instead of primitives, the advantage currently
+ // is the correct visualization of diagonal line(s) including overlaying,
+ // but the rest is bad. Since the edit views use primitives and the preview
+ // should be 'real' I opt for also changing this to primitives. I will
+ // keep the old solution and add a switch (above) based on a static bool so
+ // that interested people may test this out in the debugger.
+ // This is one more hint to enhance the primitive visualization further to
+ // support diagonals better - that's the way to go.
+ const drawinglayer::geometry::ViewInformation2D aNewViewInformation2D;
+ std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> pProcessor2D(
+ drawinglayer::processor2d::createPixelProcessor2DFromOutputDevice(
+ *mpVirDev.get(),
+ aNewViewInformation2D));
+
+ if (pProcessor2D)
+ {
+ maArray.DrawArray(*pProcessor2D.get());
+ pProcessor2D.reset();
+ }
+ }
+ else
+ {
+ // original paint
+ maArray.DrawArray(*mpVirDev.get());
+ }
}
void FrameSelectorImpl::DrawVirtualDevice()
diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx
index c0ddb50d4ad1..2b45cba8fb22 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -2747,33 +2747,37 @@ void SwTabFramePainter::PaintLines(OutputDevice& rDev, const SwRect& rRect) cons
if (bHori)
{
- mrTabFrame.ProcessPrimitives( svx::frame::CreateBorderPrimitives(
- aPaintStart,
- aPaintEnd,
- aStyles[ 0 ], // current style
- aStyles[ 1 ], // aLFromT
- aStyles[ 2 ], // aLFromL
- aStyles[ 3 ], // aLFromB
- aStyles[ 4 ], // aRFromT
- aStyles[ 5 ], // aRFromR
- aStyles[ 6 ], // aRFromB
- pTmpColor)
- );
+ drawinglayer::primitive2d::Primitive2DContainer aSequence(1);
+ aSequence.append(
+ svx::frame::CreateBorderPrimitives(
+ aPaintStart,
+ aPaintEnd,
+ aStyles[ 0 ], // current style
+ aStyles[ 1 ], // aLFromT
+ aStyles[ 2 ], // aLFromL
+ aStyles[ 3 ], // aLFromB
+ aStyles[ 4 ], // aRFromT
+ aStyles[ 5 ], // aRFromR
+ aStyles[ 6 ], // aRFromB
+ pTmpColor));
+ mrTabFrame.ProcessPrimitives(aSequence);
}
else
{
- mrTabFrame.ProcessPrimitives( svx::frame::CreateBorderPrimitives(
- aPaintEnd,
- aPaintStart,
- aStyles[ 0 ], // current style
- aStyles[ 4 ], // aBFromL
- aStyles[ 5 ], // aBFromB
- aStyles[ 6 ], // aBFromR
- aStyles[ 1 ], // aTFromL
- aStyles[ 2 ], // aTFromT
- aStyles[ 3 ], // aTFromR
- pTmpColor)
- );
+ drawinglayer::primitive2d::Primitive2DContainer aSequence(1);
+ aSequence.append(
+ svx::frame::CreateBorderPrimitives(
+ aPaintEnd,
+ aPaintStart,
+ aStyles[ 0 ], // current style
+ aStyles[ 4 ], // aBFromL
+ aStyles[ 5 ], // aBFromB
+ aStyles[ 6 ], // aBFromR
+ aStyles[ 1 ], // aTFromL
+ aStyles[ 2 ], // aTFromT
+ aStyles[ 3 ], // aTFromR
+ pTmpColor));
+ mrTabFrame.ProcessPrimitives(aSequence);
}
}