summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--basegfx/source/numeric/ftools.cxx34
-rw-r--r--include/basegfx/numeric/ftools.hxx20
-rw-r--r--sw/source/core/doc/notxtfrm.cxx59
-rw-r--r--sw/source/core/inc/flyfrms.hxx3
-rw-r--r--sw/source/core/inc/frame.hxx14
-rw-r--r--sw/source/core/inc/notxtfrm.hxx3
-rw-r--r--sw/source/core/layout/flylay.cxx51
-rw-r--r--sw/source/core/layout/wsfrm.cxx51
8 files changed, 235 insertions, 0 deletions
diff --git a/basegfx/source/numeric/ftools.cxx b/basegfx/source/numeric/ftools.cxx
index a67bc56bd74e..994bd29e30eb 100644
--- a/basegfx/source/numeric/ftools.cxx
+++ b/basegfx/source/numeric/ftools.cxx
@@ -44,6 +44,40 @@ namespace basegfx
}
}
}
+
+ double normalizeToRange(double v, const double fRange)
+ {
+ if(fTools::lessOrEqual(fRange, 0.0))
+ {
+ // with a zero (or less) range, all normalizes to 0.0
+ return 0.0;
+ }
+
+ const bool bNegative(fTools::less(v, 0.0));
+
+ if(bNegative)
+ {
+ if(fTools::moreOrEqual(v, -fRange))
+ {
+ // in range [-fRange, 0.0[, shift one step
+ return v + fRange;
+ }
+
+ // re-calculate
+ return v - (floor(v/fRange)*fRange);
+ }
+ else
+ {
+ if(fTools::less(v, fRange))
+ {
+ // already in range [0.0, fRange[, nothing to do
+ return v;
+ }
+
+ // re-calculate
+ return v - (floor(v/fRange)*fRange);
+ }
+ }
} // end of namespace basegfx
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/numeric/ftools.hxx b/include/basegfx/numeric/ftools.hxx
index 19e8e101987c..eb030b2530d1 100644
--- a/include/basegfx/numeric/ftools.hxx
+++ b/include/basegfx/numeric/ftools.hxx
@@ -152,6 +152,26 @@ namespace basegfx
*/
BASEGFX_DLLPUBLIC double snapToNearestMultiple(double v, const double fStep);
+ /** RotateFlyFrame3: Normalize to range defined by [0.0 ... fRange[, independent
+ if v is positive or negative.
+
+ Examples:
+
+ normalizeToRange(0.5, -1.0) = 0.0
+ normalizeToRange(0.5, 0.0) = 0.0
+ normalizeToRange(0.5, 1.0) = 0.5
+ normalizeToRange(-0.5, 1.0) = 0.5
+ normalizeToRange(-0.3, 1.0) = 0.7
+ normalizeToRange(-0.7, 1.0) = 0.3
+ normalizeToRange(3.5, 1.0) = 0.5
+ normalizeToRange(3.3, 1.0) = 0.3
+ normalizeToRange(3.7, 1.0) = 0.7
+ normalizeToRange(-3.5, 1.0) = 0.5
+ normalizeToRange(-3.3, 1.0) = 0.7
+ normalizeToRange(-3.7, 1.0) = 0.3
+ */
+ BASEGFX_DLLPUBLIC double normalizeToRange(double v, const double fRange);
+
class BASEGFX_DLLPUBLIC fTools
{
public:
diff --git a/sw/source/core/doc/notxtfrm.cxx b/sw/source/core/doc/notxtfrm.cxx
index e4c3f751e41d..4631dbb7a2e3 100644
--- a/sw/source/core/doc/notxtfrm.cxx
+++ b/sw/source/core/doc/notxtfrm.cxx
@@ -492,6 +492,56 @@ void SwNoTextFrame::MakeAll(vcl::RenderContext* /*pRenderContext*/)
Format(getRootFrame()->GetCurrShell()->GetOut());
}
}
+
+ // RotateFlyFrame3 - inner frame
+ // After the layout is finished, apply possible set rotation to it
+ const double fRotation(getRotation());
+
+ if(0.0 != fRotation)
+ {
+ SwRect aFrameArea(getFrameArea());
+ SwRect aFramePrintArea(getFramePrintArea());
+ const Point aCenter(aFrameArea.Center());
+
+ // apply rotation and re-set the FrameArea definitions
+ rotateFrameAreaDefinitionAroundPoint(aFrameArea, aFramePrintArea, aCenter, fRotation);
+
+ if(aFrameArea != getFrameArea())
+ {
+ SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this);
+ aFrm.setSwRect(aFrameArea);
+ }
+
+ if(aFramePrintArea != getFramePrintArea())
+ {
+ SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(*this);
+ aPrt.setSwRect(aFramePrintArea);
+ }
+ }
+}
+
+// RotateFlyFrame3 - inner frame
+// Check if we contain a SwGrfNode and get possible rotation from it
+double SwNoTextFrame::getRotation() const
+{
+ const SwNoTextNode* pSwNoTextNode(nullptr != GetNode() ? GetNode()->GetNoTextNode() : nullptr);
+
+ if(nullptr != pSwNoTextNode)
+ {
+ const SwGrfNode* pSwGrfNode(pSwNoTextNode->GetGrfNode());
+
+ if(nullptr != pSwGrfNode)
+ {
+ const SwAttrSet& rSwAttrSet(pSwGrfNode->GetSwAttrSet());
+ const SwRotationGrf& rSwRotationGrf(rSwAttrSet.GetRotationGrf());
+ const double fRotate(static_cast< double >(-rSwRotationGrf.GetValue()) * (M_PI/1800.0));
+
+ return basegfx::normalizeToRange(fRotate, F_2PI);
+ }
+ }
+
+ // call parent
+ return SwContentFrame::getRotation();
}
/** Calculate the Bitmap's site, if needed */
@@ -649,6 +699,15 @@ void SwNoTextFrame::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew )
pDrawView->AdjustMarkHdl(nullptr);
}
}
+
+ // RotateFlyFrame3 - invalidate needed for ContentFrame (inner, this)
+ // and LayoutFrame (outer, GetUpper)
+ InvalidateAll_();
+
+ if(GetUpper())
+ {
+ GetUpper()->InvalidateAll_();
+ }
}
}
break;
diff --git a/sw/source/core/inc/flyfrms.hxx b/sw/source/core/inc/flyfrms.hxx
index 719eb01f07bd..91b4188fb48a 100644
--- a/sw/source/core/inc/flyfrms.hxx
+++ b/sw/source/core/inc/flyfrms.hxx
@@ -116,6 +116,9 @@ public:
and its anchor frame isn't inside another Writer fly frame.
*/
virtual bool IsFormatPossible() const override;
+
+ // RotateFlyFrame3 - Support for outer Frame of a SwGrfNode
+ virtual double getRotation() const override;
};
// Flys that are bound to LayoutFrames and not to Content
diff --git a/sw/source/core/inc/frame.hxx b/sw/source/core/inc/frame.hxx
index b69b942ad40e..dbef917b206e 100644
--- a/sw/source/core/inc/frame.hxx
+++ b/sw/source/core/inc/frame.hxx
@@ -196,6 +196,15 @@ public:
};
};
+// RotateFlyFrame3 - Helper method that rotates a FrameAreaDefinition content
+// around a given point. It takes care for FramePrintArea being relative to
+// FrameArea and creates the rotated BoundRects
+void rotateFrameAreaDefinitionAroundPoint(
+ SwRect& rFrameArea,
+ SwRect& rFramePrintArea,
+ const Point& rCenter,
+ double fRotation);
+
/**
* Base class of the Writer layout elements.
*
@@ -820,6 +829,11 @@ public:
virtual void dumpAsXmlAttributes(xmlTextWriterPtr writer) const;
void dumpChildrenAsXml(xmlTextWriterPtr writer) const;
bool IsCollapse() const;
+
+ // RotateFlyFrame3 - Support for handing out a rotation, currently
+ // only used for SwGrfNode in inner SwFrame of a SwFlyFrame, but may
+ // be used in the future. Default returns 0.0 (no rotation)
+ virtual double getRotation() const;
};
inline bool SwFrame::IsInDocBody() const
diff --git a/sw/source/core/inc/notxtfrm.hxx b/sw/source/core/inc/notxtfrm.hxx
index 802c737eeb21..a1936193af44 100644
--- a/sw/source/core/inc/notxtfrm.hxx
+++ b/sw/source/core/inc/notxtfrm.hxx
@@ -57,6 +57,9 @@ public:
void StopAnimation( OutputDevice* = nullptr ) const;
bool HasAnimation() const;
+
+ // RotateFlyFrame3 - Support for inner frame of a SwGrfNode
+ virtual double getRotation() const override;
};
#endif
diff --git a/sw/source/core/layout/flylay.cxx b/sw/source/core/layout/flylay.cxx
index f0ef660adb88..69fa2615a733 100644
--- a/sw/source/core/layout/flylay.cxx
+++ b/sw/source/core/layout/flylay.cxx
@@ -26,6 +26,7 @@
#include <frmtool.hxx>
#include <hints.hxx>
#include <sectfrm.hxx>
+#include <notxtfrm.hxx>
#include <svx/svdpage.hxx>
#include <editeng/ulspitem.hxx>
@@ -220,6 +221,40 @@ void SwFlyFreeFrame::MakeAll(vcl::RenderContext* /*pRenderContext*/)
else
nLoopControlRuns = 0;
}
+
+ // RotateFlyFrame3 - inner frame
+ const double fRotation(getRotation());
+
+ if(0.0 != fRotation)
+ {
+ SwRect aFrameArea(getFrameArea());
+ SwRect aFramePrintArea(getFramePrintArea());
+ Point aCenter(aFrameArea.Center());
+
+ if(GetUpper())
+ {
+ // get center from outer frame (layout frame)
+ const SwRect aUpperFrameArea(GetUpper()->getFrameArea());
+
+ aCenter = aUpperFrameArea.Center();
+ }
+
+ // apply rotation and re-set the FrameArea definitions
+ rotateFrameAreaDefinitionAroundPoint(aFrameArea, aFramePrintArea, aCenter, fRotation);
+
+ if(aFrameArea != getFrameArea())
+ {
+ SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this);
+ aFrm.setSwRect(aFrameArea);
+ }
+
+ if(aFramePrintArea != getFramePrintArea())
+ {
+ SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(*this);
+ aPrt.setSwRect(aFramePrintArea);
+ }
+ }
+
Unlock();
#if OSL_DEBUG_LEVEL > 0
@@ -231,6 +266,22 @@ void SwFlyFreeFrame::MakeAll(vcl::RenderContext* /*pRenderContext*/)
#endif
}
+// RotateFlyFrame3
+double SwFlyFreeFrame::getRotation() const
+{
+ // SwLayoutFrame::Lower() != SwFrame::GetLower(), but SwFrame::GetLower()
+ // calls SwLayoutFrame::Lower() when it's a SwLayoutFrame - so use GetLower()
+ const SwNoTextFrame* pSwNoTextFrame(dynamic_cast< const SwNoTextFrame* >(GetLower()));
+
+ if(nullptr != pSwNoTextFrame)
+ {
+ return pSwNoTextFrame->getRotation();
+ }
+
+ // call parent
+ return SwFlyFrame::getRotation();
+}
+
/** determines, if direct environment of fly frame has 'auto' size
#i17297#
diff --git a/sw/source/core/layout/wsfrm.cxx b/sw/source/core/layout/wsfrm.cxx
index 16cb40082a14..dbe44b5084e6 100644
--- a/sw/source/core/layout/wsfrm.cxx
+++ b/sw/source/core/layout/wsfrm.cxx
@@ -51,6 +51,9 @@
#include <editeng/frmdiritem.hxx>
#include <sortedobjs.hxx>
+// RotateFlyFrame3
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+
using namespace ::com::sun::star;
SwFrameAreaDefinition::SwFrameAreaDefinition()
@@ -102,6 +105,54 @@ SwFrameAreaDefinition::FramePrintAreaWriteAccess::~FramePrintAreaWriteAccess()
}
}
+void rotateFrameAreaDefinitionAroundPoint(
+ SwRect& rFrameArea,
+ SwRect& rFramePrintArea,
+ const Point& rCenter,
+ double fRotation)
+{
+ if(!basegfx::fTools::equalZero(fRotation) && rFrameArea.HasArea())
+ {
+ basegfx::B2DRange aFrameRange(
+ rFrameArea.Left(),
+ rFrameArea.Top(),
+ rFrameArea.Right(),
+ rFrameArea.Bottom());
+ const basegfx::B2DPoint aOldTopLeft(aFrameRange.getMinimum());
+ const basegfx::B2DHomMatrix aRotateAroundCenter(basegfx::utils::createRotateAroundPoint(rCenter.X(), rCenter.Y(), fRotation));
+
+ aFrameRange.transform(aRotateAroundCenter);
+ rFrameArea = SwRect(
+ basegfx::fround(aFrameRange.getMinX()),
+ basegfx::fround(aFrameRange.getMinY()),
+ basegfx::fround(aFrameRange.getWidth()),
+ basegfx::fround(aFrameRange.getHeight()));
+
+ if(rFramePrintArea.HasArea())
+ {
+ basegfx::B2DRange aFramePrintRange(
+ rFramePrintArea.Left() + aOldTopLeft.getX(),
+ rFramePrintArea.Top() + aOldTopLeft.getY(),
+ rFramePrintArea.Right() + aOldTopLeft.getX(),
+ rFramePrintArea.Bottom() + aOldTopLeft.getY());
+ const basegfx::B2DPoint aNewTopLeft(aFrameRange.getMinimum());
+
+ aFramePrintRange.transform(aRotateAroundCenter);
+ rFramePrintArea = SwRect(
+ basegfx::fround(aFramePrintRange.getMinX() - aNewTopLeft.getX()),
+ basegfx::fround(aFramePrintRange.getMinY() - aNewTopLeft.getY()),
+ basegfx::fround(aFramePrintRange.getWidth()),
+ basegfx::fround(aFramePrintRange.getHeight()));
+ }
+ }
+}
+
+// RotateFlyFrame3 - get a possible rotation from SwFrame, default returns 0.0 (no rotation)
+double SwFrame::getRotation() const
+{
+ return 0.0;
+}
+
SwFrame::SwFrame( SwModify *pMod, SwFrame* pSib )
: SwFrameAreaDefinition(),
SwClient( pMod ),