summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArmin Le Grand <Armin.Le.Grand@cib.de>2017-09-26 15:41:23 +0200
committerArmin Le Grand <Armin.Le.Grand@cib.de>2017-10-20 14:13:21 +0200
commit4ddd74e2d119eb7b25df75a65fcb214ce08ec672 (patch)
treefd350169e96105df255e27b793722e0ed47dba41
parenta42b0985c7619efdc934bb1cf19e5e2c2b6faea2 (diff)
RotGrfFlyFrame: Minimal working rotation solution
This version allows rotation (in 10th degrees) and perserves it over save/load cycles. Rotation of multiples of 90 degree behave close to original except not changing the contained Graphic and being adaptable to all kinds of graphic. The rotated Graphic is displayed centered and under preserved AspectRatio in the available frame space (so no rotation, 180 degree is identical, 90/-90 is identical with 1:1 ratio of the graphic) Change-Id: I54b3385f709ee0d34a55324aca919dcd2ce0c009
-rw-r--r--sw/source/core/doc/notxtfrm.cxx34
-rw-r--r--sw/source/uibase/frmdlg/frmmgr.cxx21
-rw-r--r--sw/source/uibase/inc/frmmgr.hxx2
-rw-r--r--sw/source/uibase/shells/grfsh.cxx23
4 files changed, 52 insertions, 28 deletions
diff --git a/sw/source/core/doc/notxtfrm.cxx b/sw/source/core/doc/notxtfrm.cxx
index a35f679d10be..42eac79c45ee 100644
--- a/sw/source/core/doc/notxtfrm.cxx
+++ b/sw/source/core/doc/notxtfrm.cxx
@@ -773,16 +773,36 @@ void paintGraphicUsingPrimitivesHelper(vcl::RenderContext & rOutputDevice,
// RotGrfFlyFrame: Take rotation into account. Rotation is in 10th degrees
if(0 != rGraphicAttr.GetRotation())
{
+ // Fit rotated graphic to center of available space, keeping page ratio:
+ // Adapt scaling ratio of unit object and rotate it
const double fRotate(static_cast< double >(-rGraphicAttr.GetRotation()) * (M_PI/1800.0));
- aTargetTransform.translate(-0.5, -0.5);
+ aTargetTransform.scale(1.0, aTargetRange.getHeight() / aTargetRange.getWidth());
aTargetTransform.rotate(fRotate);
- aTargetTransform.translate(0.5, 0.5);
- }
- // needed scale/translate
- aTargetTransform *= basegfx::utils::createScaleTranslateB2DHomMatrix(
- aTargetRange.getRange(),
- aTargetRange.getMinimum());
+ // get the range to see where we are in unit coordinates
+ basegfx::B2DRange aFullRange(0.0, 0.0, 1.0, 1.0);
+ aFullRange.transform(aTargetTransform);
+
+ // detect needed scales in X/Y and choose the smallest for staying inside the
+ // available space while keeping aspect ratio of the source
+ const double fScaleX(aTargetRange.getWidth() / aFullRange.getWidth());
+ const double fScaleY(aTargetRange.getHeight() / aFullRange.getHeight());
+ const double fScaleMin(std::min(fScaleX, fScaleY));
+
+ // TopLeft to zero, then scale, then move to center of available space
+ aTargetTransform.translate(-aFullRange.getMinX(), -aFullRange.getMinY());
+ aTargetTransform.scale(fScaleMin, fScaleMin);
+ aTargetTransform.translate(
+ aTargetRange.getCenterX() - (0.5 * fScaleMin * aFullRange.getWidth()),
+ aTargetRange.getCenterY() - (0.5 * fScaleMin * aFullRange.getHeight()));
+ }
+ else
+ {
+ // just scale/translate needed
+ aTargetTransform *= basegfx::utils::createScaleTranslateB2DHomMatrix(
+ aTargetRange.getRange(),
+ aTargetRange.getMinimum());
+ }
drawinglayer::primitive2d::Primitive2DContainer aContent(1);
bool bDone(false);
diff --git a/sw/source/uibase/frmdlg/frmmgr.cxx b/sw/source/uibase/frmdlg/frmmgr.cxx
index fdc883b6a22a..c73238be62ea 100644
--- a/sw/source/uibase/frmdlg/frmmgr.cxx
+++ b/sw/source/uibase/frmdlg/frmmgr.cxx
@@ -46,10 +46,15 @@
using namespace ::com::sun::star;
static sal_uInt16 aFrameMgrRange[] = {
- RES_FRMATR_BEGIN, RES_FRMATR_END-1,
+ RES_FRMATR_BEGIN, RES_FRMATR_END-1, // 87-129
+
+ // RotGrfFlyFrame: Support here, but seems not to be
+ // added in range of m_pOwnSh->GetFlyFrameAttr result
+ // (see below). Tried to find, but could not identify
+ RES_GRFATR_ROTATION, RES_GRFATR_ROTATION, // 132
// FillAttribute support
- XATTR_FILL_FIRST, XATTR_FILL_LAST,
+ XATTR_FILL_FIRST, XATTR_FILL_LAST, // 1014-1033
SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER,
FN_SET_FRM_NAME, FN_SET_FRM_NAME,
@@ -569,13 +574,17 @@ void SwFlyFrameAttrMgr::SetHeightSizeType( SwFrameSize eType )
m_aSet.Put( aSize );
}
-void SwFlyFrameAttrMgr::SetRotation(sal_uInt32 nOld, sal_uInt32 nNew, Size aUnrotatedSize)
+void SwFlyFrameAttrMgr::SetRotation(sal_uInt16 nOld, sal_uInt16 nNew, const Size& rUnrotatedSize)
{
- // RotGrfFlyFrame: Central handling of real change of rotation here. Adaption of pos/size
- // may be wanted in the future
+ // RotGrfFlyFrame: Central handling of real change of rotation here, all adaptions use this.
+ // Adaption of pos/size may be wanted in the future. Already tried to keep last SIze in
+ // UnrotatedSize in the SwRotationGrf Item, but this will lead to various problems. Also tried
+ // to use m_aSet.Put(...) as in other methods (also read methods for Rotation/UnrotatedSize) but
+ // somehow the needed ID (RES_GRFATR_ROTATION) is *not* in the SfxItemSet of the Frame, so for
+ // now set directly. Undo/Redo is preserved by AttributeChange
if(nOld != nNew)
{
- m_pOwnSh->SetAttrItem(SwRotationGrf(static_cast<sal_uInt16>(nNew), aUnrotatedSize));
+ m_pOwnSh->SetAttrItem(SwRotationGrf(nNew, rUnrotatedSize));
}
}
diff --git a/sw/source/uibase/inc/frmmgr.hxx b/sw/source/uibase/inc/frmmgr.hxx
index cdc3680ab894..e0f939ff2223 100644
--- a/sw/source/uibase/inc/frmmgr.hxx
+++ b/sw/source/uibase/inc/frmmgr.hxx
@@ -93,7 +93,7 @@ public:
void SetHeightSizeType(SwFrameSize eType);
// rotation
- void SetRotation(sal_uInt32 nOld, sal_uInt32 nNew, Size aUnrotatedSize);
+ void SetRotation(sal_uInt16 nOld, sal_uInt16 nNew, const Size& rUnrotatedSize);
// space to content
void SetLRSpace( long nLeft,
diff --git a/sw/source/uibase/shells/grfsh.cxx b/sw/source/uibase/shells/grfsh.cxx
index 7b2e034ae670..0914846b7857 100644
--- a/sw/source/uibase/shells/grfsh.cxx
+++ b/sw/source/uibase/shells/grfsh.cxx
@@ -893,12 +893,6 @@ void SwGrfShell::GetAttrState(SfxItemSet &rSet)
void SwGrfShell::ExecuteRotation(SfxRequest const &rReq)
{
// RotGrfFlyFrame: Modify rotation attribute instead of manipulating the graphic
- SwWrtShell& rShell = GetShell();
- SfxItemSet aSet( rShell.GetAttrPool(), svl::Items<
- RES_GRFATR_ROTATION, RES_GRFATR_ROTATION,
- SID_ATTR_TRANSFORM_ANGLE, SID_ATTR_TRANSFORM_ANGLE>{} );
- rShell.GetCurAttr( aSet );
- const SwRotationGrf& rRotation = static_cast<const SwRotationGrf&>(aSet.Get(RES_GRFATR_ROTATION));
sal_uInt16 aRotation(0);
if (rReq.GetSlot() == SID_ROTATE_GRAPHIC_LEFT)
@@ -916,22 +910,23 @@ void SwGrfShell::ExecuteRotation(SfxRequest const &rReq)
if (rReq.GetSlot() == SID_ROTATE_GRAPHIC_RESET || 0 != aRotation)
{
- rShell.StartAllAction();
- rShell.StartUndo(SwUndoId::START);
+ SwWrtShell& rShell = GetShell();
+ SfxItemSet aSet( rShell.GetAttrPool(), svl::Items<RES_GRFATR_ROTATION, RES_GRFATR_ROTATION>{} );
+ rShell.GetCurAttr( aSet );
+ const SwRotationGrf& rRotation = static_cast<const SwRotationGrf&>(aSet.Get(RES_GRFATR_ROTATION));
+ SwFlyFrameAttrMgr aMgr(false, &rShell, rShell.IsFrameSelected() ? Frmmgr_Type::NONE : Frmmgr_Type::GRF);
+ // RotGrfFlyFrame: Possible rotation change here, SwFlyFrameAttrMgr aMgr is available
if (rReq.GetSlot() == SID_ROTATE_GRAPHIC_RESET)
{
- rShell.SetAttrItem(SwRotationGrf(0, rRotation.GetUnrotatedSize()));
+ aMgr.SetRotation(rRotation.GetValue(), 0, rRotation.GetUnrotatedSize());
}
else if(0 != aRotation)
{
- sal_uInt16 aNewRotation((aRotation + rRotation.GetValue()) % 3600);
+ const sal_uInt16 aNewRotation((aRotation + rRotation.GetValue()) % 3600);
- rShell.SetAttrItem(SwRotationGrf(aNewRotation, rRotation.GetUnrotatedSize()));
+ aMgr.SetRotation(rRotation.GetValue(), aNewRotation, rRotation.GetUnrotatedSize());
}
-
- rShell.EndUndo(SwUndoId::END);
- rShell.EndAllAction();
}
}