summaryrefslogtreecommitdiff
path: root/svx
diff options
context:
space:
mode:
authorArmin Le Grand <Armin.Le.Grand@cib.de>2017-07-04 16:28:58 +0200
committerArmin Le Grand <Armin.Le.Grand@cib.de>2017-07-12 21:01:20 +0200
commitf65cbae8947c0462b35c8d3c3d5124e431b100b6 (patch)
treee8248f034f7a97e1716f9477937b55ae31038a76 /svx
parentfc55711f01af172eb3a034454405fa941454c781 (diff)
borderline: correct problems with border display
Borderline display with direct paint and with primitive direct paint has quite some errors in the current state. Started to unify usages, check deeper with creation/usage. borderline: deep changes to BorderLine Found basic error in determining the offset values for BorderLinePrimitive creation, these were not centered on the lines. Corrected that. This makes it possible to remove the formally used clipping which seems to have been used to correct that. Also allows to go back to a 'normal' decomposition that creates line primitives as expected. That again can then be painted quite normally. Also added view-dependent case to the decomposition to guarantee a gap of one discrete unit (pixel). Removed the direct painter, too. Checked and corrected stroking. borderline: Adapted previews to primitives Added code to use the primitive representation in all dialogs and apps using tables. The edit views use these mostly, so the preview should do that, too. Currently missing is a good visualization of diagonals, but this is also true for edit views. Checked all apps and table usages to not get worse borderline: correct line dash visualization When a dashed line is used, a factor of 10.0 was applied in the original coded, added that. Also the orientation of vertical borders was inverted since it was simpler to exchange Start/End, but this also mirrors the line dash visualisation, corrected that Change-Id: I4c1b380a76cb37389fab1259a53fb7cc9da982d1 e95e246d5563360617a2a2213e4d5ec7d0e736b9 62369b4de58fb0264aeb710ec6983ceddca5701d 77418cc6c84ebb0632f8c3448976e82ce612d6b6 b4eb28dc86ce05eb89b26517167305b994158ef8 borderline: adapt cppunittest and clang
Diffstat (limited to 'svx')
-rw-r--r--svx/source/dialog/framelink.cxx103
-rw-r--r--svx/source/dialog/framelinkarray.cxx165
-rw-r--r--svx/source/dialog/frmsel.cxx32
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()