summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2021-11-22 09:08:46 +0300
committerMike Kaganski <mike.kaganski@collabora.com>2021-11-22 11:25:38 +0100
commitde4cb026b5fe3ecd1c9557817565cff4ca4e8408 (patch)
tree90072778d17ffc45e394760dc765f5e8d79bffd6
parent003b2d0c36c62800257c688c65109bf2fc7d4f32 (diff)
Generalize DegreeN
This potentially allows to introduce other degree fractions easily, like Degree<sal_Int64, 60000>, with automatically defined conversion functions. Change-Id: Id1c32d9e029943844bdc833178c1f99387ff87fc Reviewed-on: https://gerrit.libreoffice.org/c/core/+/125640 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
-rw-r--r--filter/source/msfilter/msdffimp.cxx2
-rw-r--r--include/tools/degree.hxx29
-rw-r--r--sc/source/ui/view/output2.cxx2
-rw-r--r--svx/source/dialog/dialcontrol.cxx2
-rw-r--r--svx/source/svdraw/svdfmtf.cxx2
-rw-r--r--svx/source/svdraw/svdoashp.cxx2
-rw-r--r--svx/source/svdraw/svdograf.cxx2
-rw-r--r--svx/source/svdraw/svdpdf.cxx2
-rw-r--r--sw/source/core/draw/dflyobj.cxx4
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.cxx2
-rw-r--r--sw/source/uibase/shells/frmsh.cxx4
-rw-r--r--sw/source/uibase/shells/grfsh.cxx6
12 files changed, 36 insertions, 23 deletions
diff --git a/filter/source/msfilter/msdffimp.cxx b/filter/source/msfilter/msdffimp.cxx
index 74b7bece8644..8e35938ceb5c 100644
--- a/filter/source/msfilter/msdffimp.cxx
+++ b/filter/source/msfilter/msdffimp.cxx
@@ -1293,7 +1293,7 @@ static void ApplyRectangularGradientAsBitmap( const SvxMSDffManager& rManager, S
if ( bRotateWithShape )
{
// convert from 100th to 10th degrees
- aBitmapEx.Rotate( toDegree10(nFix16Angle), rShadeColors[ 0 ].aColor );
+ aBitmapEx.Rotate( to<Degree10>(nFix16Angle), rShadeColors[ 0 ].aColor );
BmpMirrorFlags nMirrorFlags = BmpMirrorFlags::NONE;
if ( rObjData.nSpFlags & ShapeFlag::FlipV )
diff --git a/include/tools/degree.hxx b/include/tools/degree.hxx
index 74a27a2c2d35..1f2b2e2f8853 100644
--- a/include/tools/degree.hxx
+++ b/include/tools/degree.hxx
@@ -13,17 +13,28 @@
#include <basegfx/numeric/ftools.hxx>
#include <sal/types.h>
#include <o3tl/strong_int.hxx>
+#include <o3tl/unit_conversion.hxx>
#include <cstdlib>
#include <math.h>
+#include <numeric>
+#include <utility>
+
+template <int N> struct FractionTag;
+// 1/Nth fraction of a degree
+template <typename I, int N> using Degree = o3tl::strong_int<I, FractionTag<N>>;
+
+template <typename I, int N> char (&NofDegree(Degree<I, N>))[N]; // helper
+// Nof<DegreeN> gives compile-time constant N, needed in templates
+template <class D> constexpr int Nof = sizeof(NofDegree(std::declval<D>()));
/** tenths of a Degree, normally rotation */
-typedef o3tl::strong_int<sal_Int16, struct Degree10Tag> Degree10;
+typedef Degree<sal_Int16, 10> Degree10;
/** custom literal */
constexpr Degree10 operator""_deg10(unsigned long long n) { return Degree10{ n }; }
/** hundredths of a Degree, normally rotation */
-typedef o3tl::strong_int<sal_Int32, struct Degree100Tag> Degree100;
+typedef Degree<sal_Int32, 100> Degree100;
// Android has trouble calling the correct overload of std::abs
#ifdef ANDROID
@@ -37,12 +48,14 @@ constexpr Degree100 operator""_deg100(unsigned long long n) { return Degree100{
/** conversion functions */
-inline Degree100 toDegree100(Degree10 x) { return Degree100(x.get() * 10); }
-inline double toRadians(Degree10 x) { return basegfx::deg2rad<10>(x.get()); }
-inline double toDegrees(Degree10 x) { return x.get() / 10.0; }
+template <class To, typename IofFrom, int NofFrom> inline To to(Degree<IofFrom, NofFrom> x)
+{
+ constexpr sal_Int64 m = Nof<To> / std::gcd(Nof<To>, NofFrom);
+ constexpr sal_Int64 d = NofFrom / std::gcd(Nof<To>, NofFrom);
+ return To{ o3tl::convert(x.get(), m, d) };
+}
-inline Degree10 toDegree10(Degree100 x) { return Degree10((x.get() + 5) / 10); }
-inline double toRadians(Degree100 x) { return basegfx::deg2rad<100>(x.get()); }
-inline double toDegrees(Degree100 x) { return x.get() / 100.0; }
+template <class D> inline double toRadians(D x) { return basegfx::deg2rad<Nof<D>>(x.get()); }
+template <class D> inline double toDegrees(D x) { return x.get() / static_cast<double>(Nof<D>); }
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx
index 31b0076bc0bc..7c8758bb75e1 100644
--- a/sc/source/ui/view/output2.cxx
+++ b/sc/source/ui/view/output2.cxx
@@ -5078,7 +5078,7 @@ void ScOutputData::DrawRotated(bool bPixelToLogic)
if ( nAttrRotate )
{
// attribute is 1/100, Font 1/10 degrees
- nOriVal = toDegree10(nAttrRotate);
+ nOriVal = to<Degree10>(nAttrRotate);
double nAddX = 0.0;
double nAddY = 0.0;
diff --git a/svx/source/dialog/dialcontrol.cxx b/svx/source/dialog/dialcontrol.cxx
index fe88a426649d..e6c7c8e43b3b 100644
--- a/svx/source/dialog/dialcontrol.cxx
+++ b/svx/source/dialog/dialcontrol.cxx
@@ -77,7 +77,7 @@ void DialControlBmp::DrawElements( const OUString& rText, Degree100 nAngle )
// rotated text
vcl::Font aFont( GetFont() );
aFont.SetColor( GetTextColor() );
- aFont.SetOrientation( toDegree10(nAngle) ); // Font uses 1/10 degrees
+ aFont.SetOrientation( to<Degree10>(nAngle) ); // Font uses 1/10 degrees
aFont.SetWeight( WEIGHT_BOLD );
SetFont( aFont );
diff --git a/svx/source/svdraw/svdfmtf.cxx b/svx/source/svdraw/svdfmtf.cxx
index 93c5da9278e1..94d54040cd03 100644
--- a/svx/source/svdraw/svdfmtf.cxx
+++ b/svx/source/svdraw/svdfmtf.cxx
@@ -1051,7 +1051,7 @@ void ImpSdrGDIMetaFileImport::ImportText( const Point& rPos, const OUString& rSt
aAttr.Put(XFillColorItem(OUString(), aFnt.GetFillColor()));
pText->SetMergedItemSet(aAttr);
}
- Degree100 nAngle = toDegree100(aFnt.GetOrientation());
+ Degree100 nAngle = to<Degree100>(aFnt.GetOrientation());
if ( nAngle )
pText->SdrAttrObj::NbcRotate(aPos,nAngle);
InsertObj( pText, false );
diff --git a/svx/source/svdraw/svdoashp.cxx b/svx/source/svdraw/svdoashp.cxx
index 3b1612b15f68..52625388a32e 100644
--- a/svx/source/svdraw/svdoashp.cxx
+++ b/svx/source/svdraw/svdoashp.cxx
@@ -1768,7 +1768,7 @@ void SdrObjCustomShape::ImpCheckCustomGluePointsAreAdded()
ShearPoint(aPoly[i],maRect.Center(), fTan );
}
if (maGeo.nRotationAngle)
- aPoly.Rotate( maRect.Center(), toDegree10(maGeo.nRotationAngle) );
+ aPoly.Rotate( maRect.Center(), to<Degree10>(maGeo.nRotationAngle) );
tools::Rectangle aBoundRect( aPoly.GetBoundRect() );
sal_Int32 nXDiff = aBoundRect.Left() - maRect.Left();
diff --git a/svx/source/svdraw/svdograf.cxx b/svx/source/svdraw/svdograf.cxx
index 027301bedb43..67bd14cc8622 100644
--- a/svx/source/svdraw/svdograf.cxx
+++ b/svx/source/svdraw/svdograf.cxx
@@ -435,7 +435,7 @@ GraphicAttr SdrGrafObj::GetGraphicAttr( SdrGrafObjTransformsAttrs nTransformFlag
}
if( bRotate )
- aActAttr.SetRotation( toDegree10(maGeo.nRotationAngle ) );
+ aActAttr.SetRotation( to<Degree10>(maGeo.nRotationAngle ) );
}
return aActAttr;
diff --git a/svx/source/svdraw/svdpdf.cxx b/svx/source/svdraw/svdpdf.cxx
index 789e5d360477..4fcfb21fca7a 100644
--- a/svx/source/svdraw/svdpdf.cxx
+++ b/svx/source/svdraw/svdpdf.cxx
@@ -834,7 +834,7 @@ void ImpSdrPdfImport::InsertTextObject(const Point& rPos, const Size& rSize, con
aAttr.Put(XFillColorItem(OUString(), aFont.GetFillColor()));
pText->SetMergedItemSet(aAttr);
}
- Degree100 nAngle = toDegree100(aFont.GetOrientation());
+ Degree100 nAngle = to<Degree100>(aFont.GetOrientation());
if (nAngle)
pText->SdrAttrObj::NbcRotate(aPosition, nAngle);
InsertObj(pText, false);
diff --git a/sw/source/core/draw/dflyobj.cxx b/sw/source/core/draw/dflyobj.cxx
index d5497f9f2098..5298f1a296ba 100644
--- a/sw/source/core/draw/dflyobj.cxx
+++ b/sw/source/core/draw/dflyobj.cxx
@@ -386,7 +386,7 @@ void SwVirtFlyDrawObj::Rotate(const Point& rRef, Degree100 nAngle100, double sn,
{
// RotGrfFlyFrame: Here is where the positively completed rotate interaction is executed.
// Rotation is in 1/100th degree and may be signed (!)
- Degree10 nAngle10 = toDegree10(nAngle100);
+ Degree10 nAngle10 = to<Degree10>(nAngle100);
while(nAngle10 < 0_deg10)
{
@@ -1174,7 +1174,7 @@ Degree100 SwVirtFlyDrawObj::GetRotateAngle() const
if(ContainsSwGrfNode())
{
Size aSize;
- return toDegree100(getPossibleRotationFromFraphicFrame(aSize));
+ return to<Degree100>(getPossibleRotationFromFraphicFrame(aSize));
}
else
{
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 40656f6e3bf7..bcdd1af1af4f 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -5143,7 +5143,7 @@ void DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode* pGrfNode, const Size
if (Degree10 nRot = rSet.Get(RES_GRFATR_ROTATION).GetValue())
{
// RES_GRFATR_ROTATION is in 10ths of degree; convert to 100ths for macro
- sal_uInt32 mOOXMLRot = oox::drawingml::ExportRotateClockwisify(toDegree100(nRot));
+ sal_uInt32 mOOXMLRot = oox::drawingml::ExportRotateClockwisify(to<Degree100>(nRot));
xFrameAttributes->add(XML_rot, OString::number(mOOXMLRot));
}
}
diff --git a/sw/source/uibase/shells/frmsh.cxx b/sw/source/uibase/shells/frmsh.cxx
index 05187b5964dc..4463908f4b22 100644
--- a/sw/source/uibase/shells/frmsh.cxx
+++ b/sw/source/uibase/shells/frmsh.cxx
@@ -400,7 +400,7 @@ void SwFrameShell::Execute(SfxRequest &rReq)
if (pArgs && SfxItemState::SET == pArgs->GetItemState(SID_ATTR_TRANSFORM_DELTA_ANGLE, false, &pItem))
{
- const Degree10 nDeltaRot = toDegree10(static_cast<const SdrAngleItem*>(pItem)->GetValue());
+ const Degree10 nDeltaRot = to<Degree10>(static_cast<const SdrAngleItem*>(pItem)->GetValue());
aMgr.SetRotation(nOldRot, nOldRot + nDeltaRot, rRotation.GetUnrotatedSize());
}
@@ -410,7 +410,7 @@ void SwFrameShell::Execute(SfxRequest &rReq)
// 100th degrees in SID_ATTR_TRANSFORM_ANGLE to 10th degrees in RES_GRFATR_ROTATION
if (pArgs && SfxItemState::SET == pArgs->GetItemState(SID_ATTR_TRANSFORM_ANGLE, false, &pItem))
{
- const Degree10 nNewRot = toDegree10(static_cast<const SdrAngleItem*>(pItem)->GetValue());
+ const Degree10 nNewRot = to<Degree10>(static_cast<const SdrAngleItem*>(pItem)->GetValue());
// RotGrfFlyFrame: Rotation change here, SwFlyFrameAttrMgr aMgr is available
aMgr.SetRotation(nOldRot, nNewRot, rRotation.GetUnrotatedSize());
diff --git a/sw/source/uibase/shells/grfsh.cxx b/sw/source/uibase/shells/grfsh.cxx
index 1aa4b210a8a2..fa293272d0b9 100644
--- a/sw/source/uibase/shells/grfsh.cxx
+++ b/sw/source/uibase/shells/grfsh.cxx
@@ -392,7 +392,7 @@ void SwGrfShell::Execute(SfxRequest &rReq)
const SwRotationGrf& rRotation = aTmpSet.Get(RES_GRFATR_ROTATION);
nCurrentRotation = rRotation.GetValue();
aUnrotatedSize = rRotation.GetUnrotatedSize();
- aSet.Put(SdrAngleItem(SID_ATTR_TRANSFORM_ANGLE, toDegree100(nCurrentRotation)));
+ aSet.Put(SdrAngleItem(SID_ATTR_TRANSFORM_ANGLE, to<Degree100>(nCurrentRotation)));
}
SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
@@ -507,7 +507,7 @@ void SwGrfShell::Execute(SfxRequest &rReq)
// RotGrfFlyFrame: Get and process evtl. changed RotationAngle
if ( SfxItemState::SET == pSet->GetItemState(SID_ATTR_TRANSFORM_ANGLE, false, &pItem ))
{
- const Degree10 aNewRotation = toDegree10(static_cast<const SdrAngleItem*>(pItem)->GetValue() % 36000_deg100);
+ const Degree10 aNewRotation = to<Degree10>(static_cast<const SdrAngleItem*>(pItem)->GetValue() % 36000_deg100);
// RotGrfFlyFrame: Possible rotation change here, SwFlyFrameAttrMgr aMgr is available
aMgr.SetRotation(nCurrentRotation, aNewRotation, aUnrotatedSize);
@@ -984,7 +984,7 @@ void SwGrfShell::GetAttrStateForRotation(SfxItemSet &rSet)
SfxItemSetFixed<RES_GRFATR_ROTATION, RES_GRFATR_ROTATION> aSet( rShell.GetAttrPool() );
rShell.GetCurAttr( aSet );
const SwRotationGrf& rRotation = aSet.Get(RES_GRFATR_ROTATION);
- rSet.Put(SdrAngleItem(SID_ATTR_TRANSFORM_ANGLE, toDegree100(rRotation.GetValue())));
+ rSet.Put(SdrAngleItem(SID_ATTR_TRANSFORM_ANGLE, to<Degree100>(rRotation.GetValue())));
break;
}
default: