diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2021-11-22 09:08:46 +0300 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2021-11-22 11:25:38 +0100 |
commit | de4cb026b5fe3ecd1c9557817565cff4ca4e8408 (patch) | |
tree | 90072778d17ffc45e394760dc765f5e8d79bffd6 | |
parent | 003b2d0c36c62800257c688c65109bf2fc7d4f32 (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.cxx | 2 | ||||
-rw-r--r-- | include/tools/degree.hxx | 29 | ||||
-rw-r--r-- | sc/source/ui/view/output2.cxx | 2 | ||||
-rw-r--r-- | svx/source/dialog/dialcontrol.cxx | 2 | ||||
-rw-r--r-- | svx/source/svdraw/svdfmtf.cxx | 2 | ||||
-rw-r--r-- | svx/source/svdraw/svdoashp.cxx | 2 | ||||
-rw-r--r-- | svx/source/svdraw/svdograf.cxx | 2 | ||||
-rw-r--r-- | svx/source/svdraw/svdpdf.cxx | 2 | ||||
-rw-r--r-- | sw/source/core/draw/dflyobj.cxx | 4 | ||||
-rw-r--r-- | sw/source/filter/ww8/docxattributeoutput.cxx | 2 | ||||
-rw-r--r-- | sw/source/uibase/shells/frmsh.cxx | 4 | ||||
-rw-r--r-- | sw/source/uibase/shells/grfsh.cxx | 6 |
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: |