diff options
author | Armin Le Grand <Armin.Le.Grand@cib.de> | 2017-08-30 20:40:32 +0200 |
---|---|---|
committer | Armin Le Grand <Armin.Le.Grand@cib.de> | 2017-09-15 12:58:03 +0200 |
commit | a9c59cbfb9e16469b389db0b4d6befe196d0e2a0 (patch) | |
tree | a031682ae21ec46bb9c6e1e30b0110213e8e3dac /svx/source/dialog | |
parent | fe14ddf25003c0f79f9f8a249bc22d45f57a0068 (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
Diffstat (limited to 'svx/source/dialog')
-rw-r--r-- | svx/source/dialog/framelink.cxx | 153 | ||||
-rw-r--r-- | svx/source/dialog/framelinkarray.cxx | 411 |
2 files changed, 282 insertions, 282 deletions
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 |