summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArmin Le Grand <Armin.Le.Grand@cib.de>2017-08-30 20:40:32 +0200
committerArmin Le Grand <Armin.Le.Grand@cib.de>2017-09-15 12:58:03 +0200
commita9c59cbfb9e16469b389db0b4d6befe196d0e2a0 (patch)
treea031682ae21ec46bb9c6e1e30b0110213e8e3dac
parentfe14ddf25003c0f79f9f8a249bc22d45f57a0068 (diff)
borderline: Preparing further to use CellCoordinateSystem
Multiple cleanups, made svx::frame::Style a std::shared_ptr class, preparing basing all border stuff on transformations, so it will need a CellCoordinateSystem. Added stuff to get this Coordinate System from the svx::frame::Cell using the Frame and knowledge about ownerships Change-Id: Ic2cb59cc92e648ac2fef72f22f8913479769d3e2
-rw-r--r--basegfx/source/matrix/b2dhommatrixtools.cxx14
-rw-r--r--include/basegfx/matrix/b2dhommatrixtools.hxx9
-rw-r--r--include/svx/framelink.hxx88
-rw-r--r--include/svx/framelinkarray.hxx3
-rw-r--r--svx/source/dialog/framelink.cxx153
-rw-r--r--svx/source/dialog/framelinkarray.cxx411
6 files changed, 364 insertions, 314 deletions
diff --git a/basegfx/source/matrix/b2dhommatrixtools.cxx b/basegfx/source/matrix/b2dhommatrixtools.cxx
index 645d4c7e261a..89ab91424706 100644
--- a/basegfx/source/matrix/b2dhommatrixtools.cxx
+++ b/basegfx/source/matrix/b2dhommatrixtools.cxx
@@ -398,6 +398,20 @@ namespace basegfx
return aRetval;
}
+ B2DHomMatrix createCoordinateSystemTransform(
+ const B2DPoint& rOrigin,
+ const B2DVector& rX,
+ const B2DVector& rY)
+ {
+ return basegfx::B2DHomMatrix(
+ rX.getX(), rY.getX(), rOrigin.getX(),
+ rX.getY(), rY.getY(), rOrigin.getY());
+ }
+
+ B2DTuple getColumn(const B2DHomMatrix& rMatrix, sal_uInt16 nCol)
+ {
+ return B2DTuple(rMatrix.get(0, nCol), rMatrix.get(1, nCol));
+ }
} // end of namespace tools
} // end of namespace basegfx
diff --git a/include/basegfx/matrix/b2dhommatrixtools.hxx b/include/basegfx/matrix/b2dhommatrixtools.hxx
index 5dcd1b47936d..aa3c047a20c5 100644
--- a/include/basegfx/matrix/b2dhommatrixtools.hxx
+++ b/include/basegfx/matrix/b2dhommatrixtools.hxx
@@ -131,6 +131,15 @@ namespace basegfx
const B2DRange& rSourceRange,
const B2DRange& rTargetRange);
+ /// create based on given CoordinateSystem which is defined by origin and x/yaxis
+ BASEGFX_DLLPUBLIC B2DHomMatrix createCoordinateSystemTransform(
+ const B2DPoint& rOrigin,
+ const B2DVector& rX,
+ const B2DVector& rY);
+
+ /// get column vector from B2dHomMatrix, e.g. to extract coordinate system origin and x/yaxis
+ BASEGFX_DLLPUBLIC B2DTuple getColumn(const B2DHomMatrix& rMatrix, sal_uInt16 nCol);
+
} // end of namespace tools
} // end of namespace basegfx
diff --git a/include/svx/framelink.hxx b/include/svx/framelink.hxx
index 973c401f5aec..d0fb165eef79 100644
--- a/include/svx/framelink.hxx
+++ b/include/svx/framelink.hxx
@@ -107,6 +107,43 @@ enum class RefMode
*/
class SAL_WARN_UNUSED SVX_DLLPUBLIC Style
{
+private:
+ class implStyle
+ {
+ private:
+ friend class Style;
+
+ Color maColorPrim;
+ Color maColorSecn;
+ Color maColorGap;
+ bool mbUseGapColor;
+ RefMode meRefMode; /// Reference point handling for this frame border.
+ double mfPrim; /// Width of primary (single, left, or top) line.
+ double mfDist; /// Distance between primary and secondary line.
+ double mfSecn; /// Width of secondary (right or bottom) line.
+ double mfPatternScale; /// Scale used for line pattern spacing.
+ SvxBorderLineStyle mnType;
+ const Cell* mpUsingCell;
+
+ public:
+ /** Constructs an invisible frame style. */
+ explicit implStyle() :
+ maColorPrim(),
+ maColorSecn(),
+ maColorGap(),
+ mbUseGapColor(false),
+ meRefMode(RefMode::Centered),
+ mfPrim(0.0),
+ mfDist(0.0),
+ mfSecn(0.0),
+ mfPatternScale(1.0),
+ mnType(SvxBorderLineStyle::SOLID),
+ mpUsingCell(nullptr)
+ {}
+ };
+
+ std::shared_ptr< implStyle > maImplStyle;
+
public:
/** Constructs an invisible frame style. */
explicit Style();
@@ -118,20 +155,20 @@ public:
/** Constructs a frame style from the passed SvxBorderLine struct. Clears the style, if pBorder is 0. */
explicit Style( const editeng::SvxBorderLine* pBorder, double fScale = 1.0 );
- RefMode GetRefMode() const { return meRefMode; }
- const Color& GetColorPrim() const { return maColorPrim; }
- const Color& GetColorSecn() const { return maColorSecn; }
- const Color& GetColorGap() const { return maColorGap; }
- bool UseGapColor() const { return mbUseGapColor; }
- double Prim() const { return mfPrim; }
- double Dist() const { return mfDist; }
- double Secn() const { return mfSecn; }
- double PatternScale() const { return mfPatternScale;}
- void SetPatternScale( double fScale );
- SvxBorderLineStyle Type() const { return mnType; }
+ RefMode GetRefMode() const { return maImplStyle->meRefMode; }
+ const Color& GetColorPrim() const { return maImplStyle->maColorPrim; }
+ const Color& GetColorSecn() const { return maImplStyle->maColorSecn; }
+ const Color& GetColorGap() const { return maImplStyle->maColorGap; }
+ bool UseGapColor() const { return maImplStyle->mbUseGapColor; }
+ double Prim() const { return maImplStyle->mfPrim; }
+ double Dist() const { return maImplStyle->mfDist; }
+ double Secn() const { return maImplStyle->mfSecn; }
+ double PatternScale() const { return maImplStyle->mfPatternScale;}
+ void SetPatternScale( double fScale ) { maImplStyle->mfPatternScale = fScale; }
+ SvxBorderLineStyle Type() const { return maImplStyle->mnType; }
/** Returns the total width of this frame style. */
- double GetWidth() const { return mfPrim + mfDist + mfSecn; }
+ double GetWidth() const;
/** Sets the frame style to invisible state. */
void Clear();
@@ -146,37 +183,24 @@ public:
void Set( const editeng::SvxBorderLine* pBorder, double fScale, sal_uInt16 nMaxWidth = SAL_MAX_UINT16 );
/** Sets a new reference point handling mode, does not modify other settings. */
- void SetRefMode( RefMode eRefMode ) { meRefMode = eRefMode; }
+ void SetRefMode( RefMode eRefMode ) { maImplStyle->meRefMode = eRefMode; }
/** Sets a new color, does not modify other settings. */
- void SetColorPrim( const Color& rColor ) { maColorPrim = rColor; }
- void SetColorSecn( const Color& rColor ) { maColorSecn = rColor; }
+ void SetColorPrim( const Color& rColor ) { maImplStyle->maColorPrim = rColor; }
+ void SetColorSecn( const Color& rColor ) { maImplStyle->maColorSecn = rColor; }
/** Sets whether to use dotted style for single hair lines. */
- void SetType( SvxBorderLineStyle nType ) { mnType = nType; }
+ void SetType( SvxBorderLineStyle nType ) { maImplStyle->mnType = nType; }
/** Mirrors this style (exchanges primary and secondary), if it is a double frame style. */
Style& MirrorSelf();
/** return the Cell using this style (if set) */
- const Cell* GetUsingCell() const { return mpUsingCell; }
+ const Cell* GetUsingCell() const;
private:
- Color maColorPrim;
- Color maColorSecn;
- Color maColorGap;
- bool mbUseGapColor;
- RefMode meRefMode; /// Reference point handling for this frame border.
- double mfPrim; /// Width of primary (single, left, or top) line.
- double mfDist; /// Distance between primary and secondary line.
- double mfSecn; /// Width of secondary (right or bottom) line.
- double mfPatternScale; /// Scale used for line pattern spacing.
- SvxBorderLineStyle mnType;
-
/// need information which cell this style info comes from due to needed
/// rotation info (which is in the cell). Rotation depends on the cell.
- /// Encapsulated using a single static friend method that is the single
- /// allowed instance to set/modify this value
- friend void exclusiveSetUsigCellAtStyle(Style& rStyle, const Cell* pCell);
- const Cell* mpUsingCell;
+ friend class Cell;
+ void SetUsingCell(const Cell* pCell);
};
bool operator==( const Style& rL, const Style& rR );
diff --git a/include/svx/framelinkarray.hxx b/include/svx/framelinkarray.hxx
index 4801db277147..78b95c8d0ab0 100644
--- a/include/svx/framelinkarray.hxx
+++ b/include/svx/framelinkarray.hxx
@@ -292,6 +292,7 @@ public:
/** Returns the output range of the cell (nCol,nRow).
Returns total output range of merged ranges. */
basegfx::B2DRange GetCellRange( size_t nCol, size_t nRow ) const;
+ basegfx::B2DRange GetCellRange( size_t nCellIndex ) const;
// mirroring --------------------------------------------------------------
@@ -311,6 +312,8 @@ public:
/** Draws the part of the array, that is inside the clipping range. */
void DrawArray(drawinglayer::processor2d::BaseProcessor2D& rProcessor) const;
+ // fill the Cell::maCellIndex entries to allow referencing back from Cell to Array Col/Row coordinates
+ void AddCellIndices() const;
private:
std::unique_ptr<ArrayImpl> mxImpl;
diff --git a/svx/source/dialog/framelink.cxx b/svx/source/dialog/framelink.cxx
index e5523fe5365e..cbabbcbc635b 100644
--- a/svx/source/dialog/framelink.cxx
+++ b/svx/source/dialog/framelink.cxx
@@ -41,64 +41,36 @@ using namespace editeng;
namespace svx {
namespace frame {
-
-namespace {
-
-/** Converts a width in twips to a width in another map unit (specified by fScale). */
-double lclScaleValue( double nValue, double fScale, sal_uInt16 nMaxWidth )
-{
- return std::min<double>(nValue * fScale, nMaxWidth);
-}
-
-} // namespace
-
-
// Classes
-
-
-#define SCALEVALUE( value ) lclScaleValue( value, fScale, nMaxWidth )
-
-Style::Style() :
- meRefMode(RefMode::Centered),
- mfPatternScale(1.0),
- mnType(SvxBorderLineStyle::SOLID),
- mpUsingCell(nullptr)
+Style::Style() : maImplStyle(new implStyle())
{
Clear();
}
-Style::Style( double nP, double nD, double nS, SvxBorderLineStyle nType ) :
- meRefMode(RefMode::Centered),
- mfPatternScale(1.0),
- mnType(nType),
- mpUsingCell(nullptr)
+Style::Style( double nP, double nD, double nS, SvxBorderLineStyle nType ) : maImplStyle(new implStyle())
{
+ maImplStyle->mnType = nType;
Clear();
Set( nP, nD, nS );
}
-Style::Style( const Color& rColorPrim, const Color& rColorSecn, const Color& rColorGap, bool bUseGapColor,
- double nP, double nD, double nS, SvxBorderLineStyle nType ) :
- meRefMode(RefMode::Centered),
- mfPatternScale(1.0),
- mnType(nType),
- mpUsingCell(nullptr)
+Style::Style( const Color& rColorPrim, const Color& rColorSecn, const Color& rColorGap, bool bUseGapColor, double nP, double nD, double nS, SvxBorderLineStyle nType ) : maImplStyle(new implStyle())
{
+ maImplStyle->mnType = nType;
Set( rColorPrim, rColorSecn, rColorGap, bUseGapColor, nP, nD, nS );
}
-Style::Style( const editeng::SvxBorderLine* pBorder, double fScale ) :
- meRefMode(RefMode::Centered),
- mfPatternScale(fScale),
- mpUsingCell(nullptr)
+Style::Style( const editeng::SvxBorderLine* pBorder, double fScale ) : maImplStyle(new implStyle())
{
+ maImplStyle->mfPatternScale = fScale;
Set( pBorder, fScale );
}
-
-void Style::SetPatternScale( double fScale )
+double Style::GetWidth() const
{
- mfPatternScale = fScale;
+ implStyle* pTarget = maImplStyle.get();
+
+ return pTarget->mfPrim + pTarget->mfDist + pTarget->mfSecn;
}
void Style::Clear()
@@ -115,66 +87,78 @@ void Style::Set( double nP, double nD, double nS )
>0 0 >0 nP 0 0
>0 >0 >0 nP nD nS
*/
- mfPrim = rtl::math::round(nP ? nP : nS, 2);
- mfDist = rtl::math::round((nP && nS) ? nD : 0, 2);
- mfSecn = rtl::math::round((nP && nD) ? nS : 0, 2);
+ implStyle* pTarget = maImplStyle.get();
+ pTarget->mfPrim = rtl::math::round(nP ? nP : nS, 2);
+ pTarget->mfDist = rtl::math::round((nP && nS) ? nD : 0, 2);
+ pTarget->mfSecn = rtl::math::round((nP && nD) ? nS : 0, 2);
}
void Style::Set( const Color& rColorPrim, const Color& rColorSecn, const Color& rColorGap, bool bUseGapColor, double nP, double nD, double nS )
{
- maColorPrim = rColorPrim;
- maColorSecn = rColorSecn;
- maColorGap = rColorGap;
- mbUseGapColor = bUseGapColor;
+ implStyle* pTarget = maImplStyle.get();
+ pTarget->maColorPrim = rColorPrim;
+ pTarget->maColorSecn = rColorSecn;
+ pTarget->maColorGap = rColorGap;
+ pTarget->mbUseGapColor = bUseGapColor;
Set( nP, nD, nS );
}
void Style::Set( const SvxBorderLine& rBorder, double fScale, sal_uInt16 nMaxWidth )
{
- maColorPrim = rBorder.GetColorOut();
- maColorSecn = rBorder.GetColorIn();
- maColorGap = rBorder.GetColorGap();
- mbUseGapColor = rBorder.HasGapColor();
+ implStyle* pTarget = maImplStyle.get();
+ pTarget->maColorPrim = rBorder.GetColorOut();
+ pTarget->maColorSecn = rBorder.GetColorIn();
+ pTarget->maColorGap = rBorder.GetColorGap();
+ pTarget->mbUseGapColor = rBorder.HasGapColor();
sal_uInt16 nPrim = rBorder.GetOutWidth();
sal_uInt16 nDist = rBorder.GetDistance();
sal_uInt16 nSecn = rBorder.GetInWidth();
- mnType = rBorder.GetBorderLineStyle();
+ pTarget->mnType = rBorder.GetBorderLineStyle();
if( !nSecn ) // no or single frame border
{
- Set( SCALEVALUE( nPrim ), 0, 0 );
+ Set( std::min<double>(nPrim * fScale, nMaxWidth), 0, 0 );
}
else
{
- Set( SCALEVALUE( nPrim ), SCALEVALUE( nDist ), SCALEVALUE( nSecn ) );
+ Set(std::min<double>(nPrim * fScale, nMaxWidth), std::min<double>(nDist * fScale, nMaxWidth), std::min<double>(nSecn * fScale, nMaxWidth));
// Enlarge the style if distance is too small due to rounding losses.
- double nPixWidth = SCALEVALUE( nPrim + nDist + nSecn );
+ double nPixWidth = std::min<double>((nPrim + nDist + nSecn) * fScale, nMaxWidth);
+
if( nPixWidth > GetWidth() )
- mfDist = nPixWidth - mfPrim - mfSecn;
+ {
+ pTarget->mfDist = nPixWidth - pTarget->mfPrim - pTarget->mfSecn;
+ }
+
// Shrink the style if it is too thick for the control.
while( GetWidth() > nMaxWidth )
{
// First decrease space between lines.
- if (mfDist)
- --mfDist;
+ if (pTarget->mfDist)
+ {
+ --(pTarget->mfDist);
+ continue;
+ }
+
// Still too thick? Decrease the line widths.
- if( GetWidth() > nMaxWidth )
+ if (pTarget->mfPrim != 0.0 && rtl::math::approxEqual(pTarget->mfPrim, pTarget->mfSecn))
{
- if (mfPrim != 0.0 && rtl::math::approxEqual(mfPrim, mfSecn))
- {
- // Both lines equal - decrease both to keep symmetry.
- --mfPrim;
- --mfSecn;
- }
- else
- {
- // Decrease each line for itself
- if (mfPrim)
- --mfPrim;
- if ((GetWidth() > nMaxWidth) && mfSecn != 0.0)
- --mfSecn;
- }
+ // Both lines equal - decrease both to keep symmetry.
+ --(pTarget->mfPrim);
+ --(pTarget->mfSecn);
+ continue;
+ }
+
+ // Decrease each line for itself
+ if (pTarget->mfPrim)
+ {
+ --(pTarget->mfPrim);
+ }
+
+ if ((GetWidth() > nMaxWidth) && pTarget->mfSecn != 0.0)
+ {
+ --(pTarget->mfSecn);
}
}
}
@@ -183,23 +167,36 @@ void Style::Set( const SvxBorderLine& rBorder, double fScale, sal_uInt16 nMaxWid
void Style::Set( const SvxBorderLine* pBorder, double fScale, sal_uInt16 nMaxWidth )
{
if( pBorder )
+ {
Set( *pBorder, fScale, nMaxWidth );
+ }
else
{
Clear();
- mnType = SvxBorderLineStyle::SOLID;
+ maImplStyle->mnType = SvxBorderLineStyle::SOLID;
}
}
Style& Style::MirrorSelf()
{
- if (mfSecn)
- std::swap( mfPrim, mfSecn );
- if( meRefMode != RefMode::Centered )
- meRefMode = (meRefMode == RefMode::Begin) ? RefMode::End : RefMode::Begin;
+ implStyle* pTarget = maImplStyle.get();
+
+ if (pTarget->mfSecn)
+ {
+ std::swap( pTarget->mfPrim, pTarget->mfSecn );
+ }
+
+ if( pTarget->meRefMode != RefMode::Centered )
+ {
+ pTarget->meRefMode = (pTarget->meRefMode == RefMode::Begin) ? RefMode::End : RefMode::Begin;
+ }
+
return *this;
}
+const Cell* Style::GetUsingCell() const { return maImplStyle->mpUsingCell; }
+void Style::SetUsingCell(const Cell* pCell) { maImplStyle->mpUsingCell = pCell; }
+
bool operator==( const Style& rL, const Style& rR )
{
return (rL.Prim() == rR.Prim()) && (rL.Dist() == rR.Dist()) && (rL.Secn() == rR.Secn()) &&
@@ -228,8 +225,6 @@ bool operator<( const Style& rL, const Style& rR )
return false;
}
-#undef SCALEVALUE
-
bool CheckFrameBorderConnectable( const Style& rLBorder, const Style& rRBorder,
const Style& rTFromTL, const Style& rTFromT, const Style& rTFromTR,
const Style& rBFromBL, const Style& rBFromB, const Style& rBFromBR )
diff --git a/svx/source/dialog/framelinkarray.cxx b/svx/source/dialog/framelinkarray.cxx
index ef6c410a7220..70a7175e7d96 100644
--- a/svx/source/dialog/framelinkarray.cxx
+++ b/svx/source/dialog/framelinkarray.cxx
@@ -24,14 +24,11 @@
#include <algorithm>
#include <vcl/outdev.hxx>
#include <drawinglayer/primitive2d/borderlineprimitive2d.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
namespace svx {
namespace frame {
-/// single exclusive friend method to change mpUsingCell at style when style
-/// is set at Cell, see friend definition for more info
-void exclusiveSetUsigCellAtStyle(Style& rStyle, const Cell* pCell) { rStyle.mpUsingCell = pCell; }
-
class Cell
{
private:
@@ -48,8 +45,10 @@ public:
long mnAddTop;
long mnAddBottom;
- SvxRotateMode meRotMode;
- double mfOrientation;
+ SvxRotateMode meRotMode;
+ double mfOrientation;
+ basegfx::B2DHomMatrix maCoordinateSystem;
+ size_t maCellIndex;
bool mbMergeOrig;
bool mbOverlapX;
@@ -58,12 +57,12 @@ public:
public:
explicit Cell();
- void SetStyleLeft(const Style& rStyle) { maLeft = rStyle; exclusiveSetUsigCellAtStyle(maLeft, this); }
- void SetStyleRight(const Style& rStyle) { maRight = rStyle; exclusiveSetUsigCellAtStyle(maRight, this); }
- void SetStyleTop(const Style& rStyle) { maTop = rStyle; exclusiveSetUsigCellAtStyle(maTop, this); }
- void SetStyleBottom(const Style& rStyle) { maBottom = rStyle; exclusiveSetUsigCellAtStyle(maBottom, this); }
- void SetStyleTLBR(const Style& rStyle) { maTLBR = rStyle; exclusiveSetUsigCellAtStyle(maTLBR, this); }
- void SetStyleBLTR(const Style& rStyle) { maBLTR = rStyle; exclusiveSetUsigCellAtStyle(maBLTR, this); }
+ void SetStyleLeft(const Style& rStyle) { maLeft = rStyle; maLeft.SetUsingCell(this); }
+ void SetStyleRight(const Style& rStyle) { maRight = rStyle; maRight.SetUsingCell(this); }
+ void SetStyleTop(const Style& rStyle) { maTop = rStyle; maTop.SetUsingCell(this); }
+ void SetStyleBottom(const Style& rStyle) { maBottom = rStyle; maBottom.SetUsingCell(this); }
+ void SetStyleTLBR(const Style& rStyle) { maTLBR = rStyle; maTLBR.SetUsingCell(this); }
+ void SetStyleBLTR(const Style& rStyle) { maBLTR = rStyle; maBLTR.SetUsingCell(this); }
const Style& GetStyleLeft() const { return maLeft; }
const Style& GetStyleRight() const { return maRight; }
@@ -76,11 +75,65 @@ public:
bool IsRotated() const { return mfOrientation != 0.0; }
void MirrorSelfX();
+
+ basegfx::B2DHomMatrix CreateCoordinateSystem(const Array& rArray) const;
};
typedef std::vector< long > LongVec;
typedef std::vector< Cell > CellVec;
+basegfx::B2DHomMatrix Cell::CreateCoordinateSystem(const Array& rArray) const
+{
+ if(!maCoordinateSystem.isIdentity())
+ {
+ return maCoordinateSystem;
+ }
+
+ if(-1 == maCellIndex)
+ {
+ rArray.AddCellIndices();
+ }
+
+ if(-1 != maCellIndex)
+ {
+ const basegfx::B2DRange aRange(rArray.GetCellRange(maCellIndex));
+ basegfx::B2DPoint aOrigin(aRange.getMinimum());
+ basegfx::B2DVector aX(aRange.getWidth(), 0.0);
+ basegfx::B2DVector aY(0.0, aRange.getHeight());
+
+ if (IsRotated() && SvxRotateMode::SVX_ROTATE_MODE_STANDARD != meRotMode)
+ {
+ // when rotated, adapt values. Get Skew (cos/sin == 1/tan)
+ const double fSkew(aY.getY() * (cos(mfOrientation) / sin(mfOrientation)));
+
+ switch (meRotMode)
+ {
+ case SvxRotateMode::SVX_ROTATE_MODE_TOP:
+ // shear Y-Axis
+ aY.setX(-fSkew);
+ break;
+ case SvxRotateMode::SVX_ROTATE_MODE_CENTER:
+ // shear origin half, Y full
+ aOrigin.setX(aOrigin.getX() + (fSkew * 0.5));
+ aY.setX(-fSkew);
+ break;
+ case SvxRotateMode::SVX_ROTATE_MODE_BOTTOM:
+ // shear origin full, Y full
+ aOrigin.setX(aOrigin.getX() + fSkew);
+ aY.setX(-fSkew);
+ break;
+ default: // SvxRotateMode::SVX_ROTATE_MODE_STANDARD, already excluded above
+ break;
+ }
+ }
+
+ // use column vectors as coordinate axes, homogen column for translation
+ const_cast<Cell*>(this)->maCoordinateSystem = basegfx::tools::createCoordinateSystemTransform(aOrigin, aX, aY);
+ }
+
+ return maCoordinateSystem;
+}
+
Cell::Cell() :
mnAddLeft( 0 ),
mnAddRight( 0 ),
@@ -88,6 +141,8 @@ Cell::Cell() :
mnAddBottom( 0 ),
meRotMode(SvxRotateMode::SVX_ROTATE_MODE_STANDARD ),
mfOrientation( 0.0 ),
+ maCoordinateSystem(),
+ maCellIndex(static_cast<size_t>(-1)),
mbMergeOrig( false ),
mbOverlapX( false ),
mbOverlapY( false )
@@ -101,6 +156,8 @@ void Cell::MirrorSelfX()
maLeft.MirrorSelf();
maRight.MirrorSelf();
mfOrientation = -mfOrientation;
+ maCoordinateSystem.identity();
+ maCellIndex = static_cast<size_t>(-1);
}
@@ -808,6 +865,11 @@ long Array::GetHeight() const
return GetRowPosition( mxImpl->mnHeight ) - GetRowPosition( 0 );
}
+basegfx::B2DRange Array::GetCellRange( size_t nCellIndex ) const
+{
+ return GetCellRange(nCellIndex % GetColCount(), nCellIndex / GetColCount());
+}
+
basegfx::B2DRange Array::GetCellRange( size_t nCol, size_t nRow ) const
{
size_t nFirstCol = mxImpl->GetMergedFirstCol( nCol, nRow );
@@ -866,46 +928,6 @@ void Array::MirrorSelfX()
}
// drawing
-
-void CreateCoordinateSystemForCell(
- const basegfx::B2DRange& rRange,
- const Cell& rCell,
- basegfx::B2DPoint& rOrigin,
- basegfx::B2DVector& rX,
- basegfx::B2DVector& rY)
-{
- // fill in defaults
- rOrigin = rRange.getMinimum();
- rX = basegfx::B2DVector(rRange.getWidth(), 0.0);
- rY = basegfx::B2DVector(0.0, rRange.getHeight());
-
- if (rCell.IsRotated() && SvxRotateMode::SVX_ROTATE_MODE_STANDARD != rCell.meRotMode)
- {
- // when rotated, adapt values. Get Skew (cos/sin == 1/tan)
- const double fSkew(rRange.getHeight() * (cos(rCell.mfOrientation) / sin(rCell.mfOrientation)));
-
- switch (rCell.meRotMode)
- {
- case SvxRotateMode::SVX_ROTATE_MODE_TOP:
- // shear Y-Axis
- rY.setX(-fSkew);
- break;
- case SvxRotateMode::SVX_ROTATE_MODE_CENTER:
- // shear origin half, Y full
- rOrigin.setX(rOrigin.getX() + (fSkew * 0.5));
- rY.setX(-fSkew);
- break;
- case SvxRotateMode::SVX_ROTATE_MODE_BOTTOM:
- // shear origin full, Y full
- rOrigin.setX(rOrigin.getX() + fSkew);
- rY.setX(-fSkew);
- break;
- default: // SvxRotateMode::SVX_ROTATE_MODE_STANDARD, already excluded above
- break;
- }
- }
-}
-
void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D& rProcessor,
size_t nFirstCol, size_t nFirstRow, size_t nLastCol, size_t nLastRow,
const Color* pForceColor ) const
@@ -942,17 +964,13 @@ void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D& rProcessor,
if (rTLBR.GetWidth() || rBLTR.GetWidth())
{
drawinglayer::primitive2d::Primitive2DContainer aSequence;
- basegfx::B2DPoint aOrigin;
- basegfx::B2DVector aX;
- basegfx::B2DVector aY;
-
- CreateCoordinateSystemForCell(aRange, rCell, aOrigin, aX, aY);
+ basegfx::B2DHomMatrix aCoordinateSystem(rCell.CreateCoordinateSystem(*this));
CreateDiagFrameBorderPrimitives(
aSequence,
- aOrigin,
- aX,
- aY,
+ basegfx::tools::getColumn(aCoordinateSystem, 2),
+ basegfx::tools::getColumn(aCoordinateSystem, 0),
+ basegfx::tools::getColumn(aCoordinateSystem, 1),
rTLBR,
rBLTR,
GetCellStyleLeft(_nFirstCol, _nFirstRow),
@@ -1016,54 +1034,40 @@ void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D& rProcessor,
if ((pStart->Prim() || pStart->Secn()) && (aStartPos.getX() <= aEndPos.getX()))
{
// prepare defaults for borderline coordinate system
- basegfx::B2DPoint aOrigin(aStartPos);
- basegfx::B2DVector aX(aEndPos - aStartPos);
- basegfx::B2DVector aY(0.0, 1.0);
const Cell* pCell = pStart->GetUsingCell();
- if (pCell && pCell->IsRotated())
+ if(pCell)
{
- // To apply the shear, we need to get the cell range. We have the defining cell,
- // but there is no call at it to directly get it's range. To get the correct one,
- // we need to take care if the borderline is at top or bottom, so use pointer
- // compare here to find out
+ basegfx::B2DHomMatrix aCoordinateSystem(pCell->CreateCoordinateSystem(*this));
const bool bUpper(&pCell->GetStyleTop() == pStart);
- const basegfx::B2DRange aRange(GetCellRange(nCol - 1, bUpper ? nRow : nRow - 1));
- // adapt to cell coordinate system, including shear
- CreateCoordinateSystemForCell(aRange, *pCell, aOrigin, aX, aY);
-
- if (!bUpper)
+ if(!bUpper)
{
// for the lower edge we need to translate to get to the
- // borderline coordinate system. For the upper one, all is
- // okay already
- aOrigin += aY;
+ // borderline coordinate system
+ aCoordinateSystem.set(0, 2, aCoordinateSystem.get(0, 2) + aCoordinateSystem.get(0, 1));
+ aCoordinateSystem.set(1, 2, aCoordinateSystem.get(1, 2) + aCoordinateSystem.get(1, 1));
}
-
- // borderline coordinate system uses normalized 2nd axis
- aY.normalize();
+ drawinglayer::primitive2d::Primitive2DContainer aSequence;
+ CreateBorderPrimitives(
+ aSequence,
+ basegfx::tools::getColumn(aCoordinateSystem, 2),
+ basegfx::tools::getColumn(aCoordinateSystem, 0),
+ basegfx::B2DVector(basegfx::tools::getColumn(aCoordinateSystem, 1)).normalize(),
+ *pStart,
+ aStartLFromTR,
+ *pStartLFromT,
+ *pStartLFromL,
+ *pStartLFromB,
+ aStartLFromBR,
+ aEndRFromTL,
+ *pEndRFromT,
+ *pEndRFromR,
+ *pEndRFromB,
+ aEndRFromBL,
+ pForceColor);
+ rProcessor.process(aSequence);
}
-
- drawinglayer::primitive2d::Primitive2DContainer aSequence;
- CreateBorderPrimitives(
- aSequence,
- aOrigin,
- aX,
- aY,
- *pStart,
- aStartLFromTR,
- *pStartLFromT,
- *pStartLFromL,
- *pStartLFromB,
- aStartLFromBR,
- aEndRFromTL,
- *pEndRFromT,
- *pEndRFromR,
- *pEndRFromB,
- aEndRFromBL,
- pForceColor);
- rProcessor.process(aSequence);
}
// re-init "*Start***" variables
@@ -1090,45 +1094,41 @@ void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D& rProcessor,
{
// for description of involved coordinate systems have a look at
// the first CreateBorderPrimitives call above
- basegfx::B2DPoint aOrigin(aStartPos);
- basegfx::B2DVector aX(aEndPos - aStartPos);
- basegfx::B2DVector aY(0.0, 1.0);
const Cell* pCell = pStart->GetUsingCell();
- if (pCell && pCell->IsRotated())
+ if(pCell)
{
+ basegfx::B2DHomMatrix aCoordinateSystem(pCell->CreateCoordinateSystem(*this));
const bool bUpper(&pCell->GetStyleTop() == pStart);
- const basegfx::B2DRange aRange(GetCellRange(nCol - 1, bUpper ? nRow : nRow - 1));
-
- CreateCoordinateSystemForCell(aRange, *pCell, aOrigin, aX, aY);
- if (!bUpper)
+ if(!bUpper)
{
- aOrigin += aY;
+ // for the lower edge we need to translate to get to the
+ // borderline coordinate system
+ aCoordinateSystem.set(0, 2, aCoordinateSystem.get(0, 2) + aCoordinateSystem.get(0, 1));
+ aCoordinateSystem.set(1, 2, aCoordinateSystem.get(1, 2) + aCoordinateSystem.get(1, 1));
}
- aY.normalize();
+ drawinglayer::primitive2d::Primitive2DContainer aSequence;
+ CreateBorderPrimitives(
+ aSequence,
+ basegfx::tools::getColumn(aCoordinateSystem, 2),
+ basegfx::tools::getColumn(aCoordinateSystem, 0),
+ basegfx::B2DVector(basegfx::tools::getColumn(aCoordinateSystem, 1)).normalize(),
+ *pStart,
+ aStartLFromTR,
+ *pStartLFromT,
+ *pStartLFromL,
+ *pStartLFromB,
+ aStartLFromBR,
+ aEndRFromTL,
+ *pEndRFromT,
+ *pEndRFromR,
+ *pEndRFromB,
+ aEndRFromBL,
+ pForceColor);
+ rProcessor.process(aSequence);
}
-
- drawinglayer::primitive2d::Primitive2DContainer aSequence;
- CreateBorderPrimitives(
- aSequence,
- aOrigin,
- aX,
- aY,
- *pStart,
- aStartLFromTR,
- *pStartLFromT,
- *pStartLFromL,
- *pStartLFromB,
- aStartLFromBR,
- aEndRFromTL,
- *pEndRFromT,
- *pEndRFromR,
- *pEndRFromB,
- aEndRFromBL,
- pForceColor);
- rProcessor.process(aSequence);
}
}
@@ -1177,59 +1177,57 @@ void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D& rProcessor,
{
// for description of involved coordinate systems have a look at
// the first CreateBorderPrimitives call above. Additionally adapt to vertical
- basegfx::B2DPoint aOrigin(aStartPos);
- basegfx::B2DVector aX(aEndPos - aStartPos);
- basegfx::B2DVector aY(-1.0, 0.0);
const Cell* pCell = pStart->GetUsingCell();
- if (pCell && pCell->IsRotated())
+ if(pCell)
{
+ basegfx::B2DHomMatrix aCoordinateSystem(pCell->CreateCoordinateSystem(*this));
const bool bLeft(&pCell->GetStyleLeft() == pStart);
- const basegfx::B2DRange aRange(GetCellRange(bLeft ? nCol : nCol - 1, nRow - 1));
- CreateCoordinateSystemForCell(aRange, *pCell, aOrigin, aX, aY);
-
- if (!bLeft)
+ if(!bLeft)
{
- aOrigin += aX;
+ // for the Right edge we need to translate to get to the
+ // borderline coordinate system
+ aCoordinateSystem.set(0, 2, aCoordinateSystem.get(0, 2) + aCoordinateSystem.get(0, 0));
+ aCoordinateSystem.set(1, 2, aCoordinateSystem.get(1, 2) + aCoordinateSystem.get(1, 0));
}
// The *coordinate system* of the edge has to be given, which for vertical
// lines uses the Y-Vector as X-Axis and the X-Vector as Y-Axis, so swap both
// and mirror aX to keep the same orientation (should be (-1.0, 0.0) for
// horizontal lines anyways, this could be used as test here, checked in debug mode)
- std::swap(aX, aY);
- aY.normalize();
- aY = -aY;
- }
+ const basegfx::B2DTuple aX(basegfx::tools::getColumn(aCoordinateSystem, 0));
+ const basegfx::B2DTuple aY(basegfx::tools::getColumn(aCoordinateSystem, 1));
+ aCoordinateSystem = basegfx::tools::createCoordinateSystemTransform(basegfx::tools::getColumn(aCoordinateSystem, 2), aY, -aX);
- drawinglayer::primitive2d::Primitive2DContainer aSequence;
- 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.
- aSequence,
- aOrigin,
- aX,
- aY,
- *pStart,
- aStartTFromBR,
- *pStartTFromR,
- *pStartTFromT,
- *pStartTFromL,
- aStartTFromBL,
- aEndBFromTR,
- *pEndBFromR,
- *pEndBFromB,
- *pEndBFromL,
- aEndBFromTL,
- pForceColor);
- rProcessor.process(aSequence);
+ drawinglayer::primitive2d::Primitive2DContainer aSequence;
+ 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.
+ aSequence,
+ basegfx::tools::getColumn(aCoordinateSystem, 2),
+ basegfx::tools::getColumn(aCoordinateSystem, 0),
+ basegfx::B2DVector(basegfx::tools::getColumn(aCoordinateSystem, 1)).normalize(),
+ *pStart,
+ aStartTFromBR,
+ *pStartTFromR,
+ *pStartTFromT,
+ *pStartTFromL,
+ aStartTFromBL,
+ aEndBFromTR,
+ *pEndBFromR,
+ *pEndBFromB,
+ *pEndBFromL,
+ aEndBFromTL,
+ pForceColor);
+ rProcessor.process(aSequence);
+ }
}
// re-init "*Start***" variables
@@ -1256,51 +1254,50 @@ void Array::DrawRange( drawinglayer::processor2d::BaseProcessor2D& rProcessor,
{
// for description of involved coordinate systems have a look at
// the first CreateBorderPrimitives call above, adapt to vertical
- basegfx::B2DPoint aOrigin(aStartPos);
- basegfx::B2DVector aX(aEndPos - aStartPos);
- basegfx::B2DVector aY(-1.0, 0.0);
const Cell* pCell = pStart->GetUsingCell();
- if (pCell && pCell->IsRotated())
+ if(pCell)
{
+ basegfx::B2DHomMatrix aCoordinateSystem(pCell->CreateCoordinateSystem(*this));
const bool bLeft(&pCell->GetStyleLeft() == pStart);
- const basegfx::B2DRange aRange(GetCellRange(bLeft ? nCol : nCol - 1, nRow - 1));
- CreateCoordinateSystemForCell(aRange, *pCell, aOrigin, aX, aY);
-
- if (!bLeft)
+ if(!bLeft)
{
- aOrigin += aX;
+ // for the Right edge we need to translate to get to the
+ // borderline coordinate system
+ aCoordinateSystem.set(0, 2, aCoordinateSystem.get(0, 2) + aCoordinateSystem.get(0, 0));
+ aCoordinateSystem.set(1, 2, aCoordinateSystem.get(1, 2) + aCoordinateSystem.get(1, 0));
}
// The *coordinate system* of the edge has to be given, which for vertical
// lines uses the Y-Vector as X-Axis and the X-Vector as Y-Axis, so swap both
- // and mirror aX to keep the same orientation (should be (-1.0, 0.0) for horizontal lines anyways)
- std::swap(aX, aY);
- aY.normalize();
- aY = -aY;
+ // and mirror aX to keep the same orientation (should be (-1.0, 0.0) for
+ // horizontal lines anyways, this could be used as test here, checked in debug mode)
+ const basegfx::B2DTuple aX(basegfx::tools::getColumn(aCoordinateSystem, 0));
+ const basegfx::B2DTuple aY(basegfx::tools::getColumn(aCoordinateSystem, 1));
+ aCoordinateSystem = basegfx::tools::createCoordinateSystemTransform(basegfx::tools::getColumn(aCoordinateSystem, 2), aY, -aX);
+
+ drawinglayer::primitive2d::Primitive2DContainer aSequence;
+ CreateBorderPrimitives(
+ // also reordered, see call to CreateBorderPrimitives above
+ aSequence,
+ basegfx::tools::getColumn(aCoordinateSystem, 2),
+ basegfx::tools::getColumn(aCoordinateSystem, 0),
+ basegfx::B2DVector(basegfx::tools::getColumn(aCoordinateSystem, 1)).normalize(),
+ *pStart,
+ aStartTFromBR,
+ *pStartTFromR,
+ *pStartTFromT,
+ *pStartTFromL,
+ aStartTFromBL,
+ aEndBFromTR,
+ *pEndBFromR,
+ *pEndBFromB,
+ *pEndBFromL,
+ aEndBFromTL,
+ pForceColor);
+ rProcessor.process(aSequence);
}
-
- drawinglayer::primitive2d::Primitive2DContainer aSequence;
- CreateBorderPrimitives(
- // also reordered, see call to CreateBorderPrimitives above
- aSequence,
- aOrigin,
- aX,
- aY,
- *pStart,
- aStartTFromBR,
- *pStartTFromR,
- *pStartTFromT,
- *pStartTFromL,
- aStartTFromBL,
- aEndBFromTR,
- *pEndBFromR,
- *pEndBFromB,
- *pEndBFromL,
- aEndBFromTL,
- pForceColor);
- rProcessor.process(aSequence);
}
}
}
@@ -1311,6 +1308,14 @@ void Array::DrawArray(drawinglayer::processor2d::BaseProcessor2D& rProcessor) co
DrawRange(rProcessor, 0, 0, mxImpl->mnWidth - 1, mxImpl->mnHeight - 1, nullptr);
}
+void Array::AddCellIndices() const
+{
+ for (size_t a(0); a < mxImpl->maCells.size(); a++)
+ {
+ const_cast<Array*>(this)->mxImpl->maCells[a].maCellIndex = a;
+ }
+}
+
#undef ORIGCELL
#undef CELLACC
#undef CELL