Kaydet (Commit) a9c59cbf authored tarafından Armin Le Grand's avatar Armin Le Grand

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
üst fe14ddf2
......@@ -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
......
......@@ -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
......
......@@ -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 );
......
......@@ -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;
......
......@@ -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 )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment