diff options
Diffstat (limited to 'svx')
-rw-r--r-- | svx/source/dialog/framelink.cxx | 103 | ||||
-rw-r--r-- | svx/source/dialog/framelinkarray.cxx | 165 | ||||
-rw-r--r-- | svx/source/dialog/frmsel.cxx | 32 |
3 files changed, 217 insertions, 83 deletions
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() |