[Libreoffice-commits] core.git: Branch 'feature/RotateFlyFrame3' - sw/source

Armin Le Grand Armin.Le.Grand at cib.de
Wed Nov 8 14:27:21 UTC 2017


 sw/source/core/doc/notxtfrm.cxx  |   86 ++++++++++------------
 sw/source/core/inc/flyfrms.hxx   |   29 ++-----
 sw/source/core/inc/frame.hxx     |  121 ++++++++++++++++++++++++-------
 sw/source/core/inc/notxtfrm.hxx  |   30 ++-----
 sw/source/core/layout/flylay.cxx |   63 +++++++++-------
 sw/source/core/layout/wsfrm.cxx  |  151 +++++++++++++++++++++++++++------------
 6 files changed, 302 insertions(+), 178 deletions(-)

New commits:
commit 0f672315dbd335add6d2c6e141c21a5ecb7b3b8a
Author: Armin Le Grand <Armin.Le.Grand at cib.de>
Date:   Wed Nov 8 14:00:57 2017 +0100

    RotateFlyFrame3: Isolated functionality and automations
    
    Isolated tooling stuff for SwFrames that support Transformations
    to TransformableSwFrame, adapted all usages. Developed functionality
    to reset temporarily the already adapted SwFrame of the outer frame
    to non-rotated to mate the layouting work. Made the outer frame
    being layouted always first.
    
    Change-Id: Ia60a971b8eaa28859d0f2a5243eabf68fe949846

diff --git a/sw/source/core/doc/notxtfrm.cxx b/sw/source/core/doc/notxtfrm.cxx
index 1accccb8e492..b4fb5485d02e 100644
--- a/sw/source/core/doc/notxtfrm.cxx
+++ b/sw/source/core/doc/notxtfrm.cxx
@@ -144,8 +144,7 @@ static void lcl_PaintReplacement( const SwRect &rRect, const OUString &rText,
 
 SwNoTextFrame::SwNoTextFrame(SwNoTextNode * const pNode, SwFrame* pSib )
 :   SwContentFrame( pNode, pSib ),
-    maFrameAreaTransformation(),
-    maFramePrintAreaTransformation()
+    TransformableSwFrame()
 {
     mnFrameType = SwFrameType::NoTxt;
 }
@@ -472,11 +471,28 @@ const Size& SwNoTextFrame::GetSize() const
 
 void SwNoTextFrame::MakeAll(vcl::RenderContext* pRenderContext)
 {
-    if(GetUpper() && !GetUpper()->isFrameAreaDefinitionValid())
+    // RotateFlyFrame3 - inner frame. Get rotation and check if used
+    const double fRotation(getFrameRotation());
+    const bool bRotated(!basegfx::fTools::equalZero(fRotation));
+    SwFlyFreeFrame* pUpperFly(dynamic_cast< SwFlyFreeFrame* >(GetUpper()));
+
+    if(bRotated && pUpperFly && !pUpperFly->isFrameAreaDefinitionValid())
+    {
+        // RotateFlyFrame3: outer frame *needs* to be layouted first, force this by calling
+        // it's ::Calc directly
+        pUpperFly->Calc(pRenderContext);
+    }
+
+    if(bRotated && pUpperFly)
     {
-        // outer frame *needs* to be layouted first, force this by calling
-        // ::Calc directly
-        GetUpper()->Calc(pRenderContext);
+        // Reset outer frame to unrotated state. This is necessary to make the
+        // layouting below work as currently implemented in Writer. As expected
+        // using Transformations allows to do this on the fly due to all information
+        // being included there.
+        // The full solution would be to adapt the whole layouting
+        // process of Writer to take care of Transformations, but that
+        // is currently beyond scope
+        pUpperFly->resetAreaDefinitionsToUntransformed(*pUpperFly);
     }
 
     SwContentNotify aNotify( this );
@@ -504,66 +520,46 @@ void SwNoTextFrame::MakeAll(vcl::RenderContext* pRenderContext)
 
     // RotateFlyFrame3 - inner frame
     // After the unrotated layout is finished, apply possible set rotation to it
-    const double fRotation(getFrameRotation());
-
-    if(basegfx::fTools::equalZero(fRotation))
+    if(!bRotated)
     {
         // reset transformations to show that they are not used
-        maFrameAreaTransformation.identity();
-        maFramePrintAreaTransformation.identity();
+        resetLocalAreaTransformations();
     }
     else
     {
         const bool bMeValid(isFrameAreaDefinitionValid());
-        const bool bUpperValid(!GetUpper() || GetUpper()->isFrameAreaDefinitionValid());
 
-        if(bMeValid && bUpperValid)
+        if(pUpperFly)
+        {
+            // restore outer frame back to Transformed state, that means
+            // set the SwFrameAreaDefinition(s) back to BoundAreas of
+            // the transformed SwFrame. All needed information is part
+            // of the already correctly created Transformations of the
+            // upper frame, so it can bre re-created on the fly
+            pUpperFly->resetAreaDefinitionsToTransformed(*pUpperFly);
+        }
+
+        if(bMeValid)
         {
             // get center from outer frame (layout frame) to be on the safe side
             const Point aCenter(GetUpper() ? GetUpper()->getFrameArea().Center() : getFrameArea().Center());
             const basegfx::B2DPoint aB2DCenter(aCenter.X(), aCenter.Y());
 
-            updateTransformationsAndAreas(
+            updateTransformationsAndFrameAreaDefinitions(
+                *this,
                 fRotation,
                 aB2DCenter);
-
-            if(GetUpper())
-            {
-                SwFlyFreeFrame *pFly = dynamic_cast< SwFlyFreeFrame* >(GetUpper());
-
-                if(pFly)
-                {
-                    pFly->updateTransformationsAndAreas(
-                        fRotation,
-                        aB2DCenter);
-                }
-            }
         }
     }
 }
 
-void SwNoTextFrame::updateTransformationsAndAreas(
-    double fRotation,
-    const basegfx::B2DPoint& rCenter)
-{
-    createFrameAreaTransformations(
-        maFrameAreaTransformation,
-        maFramePrintAreaTransformation,
-        fRotation,
-        rCenter);
-
-    setFrameAreaDefinitionsToBoundRangesOfTransformations(
-        maFrameAreaTransformation,
-        maFramePrintAreaTransformation);
-}
-
 // RotateFlyFrame3 - Support for Transformations - outer frame
 basegfx::B2DHomMatrix SwNoTextFrame::getFrameAreaTransformation() const
 {
-    if(!maFrameAreaTransformation.isIdentity())
+    if(!getLocalFrameAreaTransformation().isIdentity())
     {
         // use pre-created transformation
-        return maFrameAreaTransformation;
+        return getLocalFrameAreaTransformation();
     }
 
     // call parent
@@ -572,10 +568,10 @@ basegfx::B2DHomMatrix SwNoTextFrame::getFrameAreaTransformation() const
 
 basegfx::B2DHomMatrix SwNoTextFrame::getFramePrintAreaTransformation() const
 {
-    if(!maFramePrintAreaTransformation.isIdentity())
+    if(!getLocalFramePrintAreaTransformation().isIdentity())
     {
         // use pre-created transformation
-        return maFramePrintAreaTransformation;
+        return getLocalFramePrintAreaTransformation();
     }
 
     // call parent
diff --git a/sw/source/core/inc/flyfrms.hxx b/sw/source/core/inc/flyfrms.hxx
index e202c9733d88..b4f66f9d22d3 100644
--- a/sw/source/core/inc/flyfrms.hxx
+++ b/sw/source/core/inc/flyfrms.hxx
@@ -26,9 +26,11 @@
 // #i28701#
 class SwFlyAtContentFrame;
 
+double getFrameRotation_from_SwNoTextFrame(const SwNoTextFrame& rNoTextFrame);
+
 // Base class for those Flys that can "move freely" or better that are not
 // bound in Content.
-class SwFlyFreeFrame : public SwFlyFrame
+class SwFlyFreeFrame : public SwFlyFrame, public TransformableSwFrame
 {
 private:
     // #i34753# - flag for at-page anchored Writer fly frames
@@ -41,12 +43,6 @@ private:
 
     SwRect maUnclippedFrame;
 
-    // RotateFlyFrame3 - Support for Transformations, hold
-    // FrameAreaTransformation and FramePrintAreaTransformation
-    // here when rotation is used
-    basegfx::B2DHomMatrix   maFrameAreaTransformation;
-    basegfx::B2DHomMatrix   maFramePrintAreaTransformation;
-
     void CheckClip( const SwFormatFrameSize &rSz );  //'Emergency' Clipping.
 
     /** determines, if direct environment of fly frame has 'auto' size
@@ -61,6 +57,11 @@ private:
     */
     bool HasEnvironmentAutoSize() const;
 
+    // RotateFlyFrame3 - Support for outer Frame of a SwGrfNode
+    // Only for local data extraction. To uniquely access information
+    // for local transformation, use getFrameArea(Print)Transformation
+    double getFrameRotation() const;
+
 protected:
     // #i28701# - new friend class <SwFlyNotify> for access to
     // method <NotifyBackground>
@@ -124,17 +125,9 @@ public:
     */
     virtual bool IsFormatPossible() const override;
 
-    // RotateFlyFrame3 - Support for Transformations for outer Frame of a SwGrfNode
-    basegfx::B2DHomMatrix getFrameAreaTransformation() const;
-    basegfx::B2DHomMatrix getFramePrintAreaTransformation() const;
-    void updateTransformationsAndAreas(
-        double fRotation,
-        const basegfx::B2DPoint& rCenter);
-
-    // RotateFlyFrame3 - Support for outer Frame of a SwGrfNode
-    // Only for local data extraction. To uniquely access information
-    // for local transformation, use getFrameArea(Print)Transformation
-    double getFrameRotation() const;
+    // RotateFlyFrame3 - Support for Transformations
+    virtual basegfx::B2DHomMatrix getFrameAreaTransformation() const override;
+    virtual basegfx::B2DHomMatrix getFramePrintAreaTransformation() 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 d02426976204..2d0a1c321372 100644
--- a/sw/source/core/inc/frame.hxx
+++ b/sw/source/core/inc/frame.hxx
@@ -144,20 +144,6 @@ protected:
     void setFrameAreaSizeValid(bool bNew);
     void setFramePrintAreaValid(bool bNew);
 
-    // helper method to create FrameAreaTransformations based on the
-    // curent FrameAreaDefinition
-    void createFrameAreaTransformations(
-        basegfx::B2DHomMatrix& rFrameAreaTransformation,
-        basegfx::B2DHomMatrix& rFramePrintAreaTransformation,
-        double fRotation,
-        const basegfx::B2DPoint& rCenter) const;
-
-    // helper method to set FrameAreaDefinitions based on given
-    // transformations
-    void setFrameAreaDefinitionsToBoundRangesOfTransformations(
-        const basegfx::B2DHomMatrix& rFrameAreaTransformation,
-        const basegfx::B2DHomMatrix& rFramePrintAreaTransformation);
-
 public:
     SwFrameAreaDefinition();
 
@@ -208,6 +194,102 @@ public:
         ~FramePrintAreaWriteAccess();
         void setSwRect(const SwRect& rNew) { *reinterpret_cast< SwRect* >(this) = rNew; }
     };
+
+    // RotateFlyFrame3 - Support for Transformations
+    // Hand out the Transformations for the current FrameAreaDefinition
+    // for the FrameArea and FramePrintArea.
+    // FramePrintArea is not relative to FrameArea in this
+    // transformation representation (to make it easier to use and understand).
+    // There is no 'set' method since SwFrame is a layout obejct. For
+    // some cases rotation will be included (used for SwGrfNode in inner
+    // SwFrame of a SwFlyFrame)
+    virtual basegfx::B2DHomMatrix getFrameAreaTransformation() const;
+    virtual basegfx::B2DHomMatrix getFramePrintAreaTransformation() const;
+};
+
+/// RotateFlyFrame3: Helper class when you want to make your SwFrame derivate
+/// transformable. It provides some tooling to do so. To use,
+/// derive your SwFrame from it
+class SW_DLLPUBLIC TransformableSwFrame
+{
+private:
+    // FrameAreaTransformation and FramePrintAreaTransformation
+    // here when more than translate/scale is used (e.g. rotation)
+    basegfx::B2DHomMatrix   maFrameAreaTransformation;
+    basegfx::B2DHomMatrix   maFramePrintAreaTransformation;
+
+    // helper method to create FrameAreaTransformations based on the
+    // curent FrameAreaDefinition
+    void createFrameAreaTransformations(
+        const SwFrameAreaDefinition& rSwFrameAreaDefinition,
+        double fRotation,
+        const basegfx::B2DPoint& rCenter);
+
+    // helper method to set FrameAreaDefinitions based on given
+    // transformations
+    void setFrameAreaDefinitionsToBoundRangesOfTransformations(
+        SwFrameAreaDefinition& rSwFrameAreaDefinition);
+
+protected:
+    // Full update of Transformations and BoundAreas:
+    // - Re-create Transformations based on SwRect(s) from the
+    //   given SwFrameAreaDefinition.
+    // - Based on that, create BoundRanges for the Transformations
+    //   and use as new SwRect(s) for the given SwFrameAreaDefinition.
+    void updateTransformationsAndFrameAreaDefinitions(
+        SwFrameAreaDefinition& rSwFrameAreaDefinition,
+        double fRotation,
+        const basegfx::B2DPoint& rCenter);
+
+    void setLocalFrameAreaTransformation(const basegfx::B2DHomMatrix& rNew)
+    {
+        maFrameAreaTransformation = rNew;
+    }
+
+    void setLocalFramePrintAreaTransformation(const basegfx::B2DHomMatrix& rNew)
+    {
+        maFramePrintAreaTransformation = rNew;
+    }
+
+    void resetLocalAreaTransformations()
+    {
+        maFrameAreaTransformation.identity();
+        maFramePrintAreaTransformation.identity();
+    }
+
+public:
+    TransformableSwFrame()
+    :   maFrameAreaTransformation(),
+        maFramePrintAreaTransformation()
+    {
+    }
+
+    // Support for Transformations for inner frame of a SwGrfNode
+    const basegfx::B2DHomMatrix& getLocalFrameAreaTransformation() const
+    {
+        return maFrameAreaTransformation;
+    }
+
+    const basegfx::B2DHomMatrix& getLocalFramePrintAreaTransformation() const
+    {
+        return maFramePrintAreaTransformation;
+    }
+
+    // This method allows to reset the SwRect(s) in the
+    // given SwFrameAreaDefinition which are already apapted to
+    // Transformation and thus have a changed BoundArea back to
+    // the untransformed state. Only the SwRect(s) are changed
+    // back, not the transformations. As expected from using
+    // Transformations, these contain all the necessary
+    // information
+    void resetAreaDefinitionsToUntransformed(
+        SwFrameAreaDefinition& rSwFrameAreaDefinition);
+
+    // Re-Creates the SwRect(s) as BoundAreas based on the current
+    // Transformations, useful to set back the SwRect(s) to Transformed
+    // state when itz was necessary to reset them temporarily (see above)
+    void resetAreaDefinitionsToTransformed(
+        SwFrameAreaDefinition& rSwFrameAreaDefinition);
 };
 
 /**
@@ -834,17 +916,6 @@ public:
     virtual void dumpAsXmlAttributes(xmlTextWriterPtr writer) const;
     void dumpChildrenAsXml(xmlTextWriterPtr writer) const;
     bool IsCollapse() const;
-
-    // RotateFlyFrame3 - Support for Transformations
-    // Hand out the Transformations for the current FrameAreaDefinition
-    // for the FrameArea and FramePrintArea.
-    // FramePrintArea is not relative to FrameArea in this
-    // transformation representation (to make it easier to use and understand).
-    // There is no 'set' method since SwFrame is a layout obejct. For
-    // some cases rotation will be included (used for SwGrfNode in inner
-    // SwFrame of a SwFlyFrame)
-    basegfx::B2DHomMatrix getFrameAreaTransformation() const;
-    basegfx::B2DHomMatrix getFramePrintAreaTransformation() const;
 };
 
 inline bool SwFrame::IsInDocBody() const
diff --git a/sw/source/core/inc/notxtfrm.hxx b/sw/source/core/inc/notxtfrm.hxx
index fa64a1be3214..43f020496599 100644
--- a/sw/source/core/inc/notxtfrm.hxx
+++ b/sw/source/core/inc/notxtfrm.hxx
@@ -26,17 +26,10 @@ class OutputDevice;
 class SwBorderAttrs;
 struct SwCursorMoveState;
 
-class SwNoTextFrame: public SwContentFrame
+class SwNoTextFrame: public SwContentFrame, public TransformableSwFrame
 {
 private:
     friend void FrameFinit();
-
-    // RotateFlyFrame3 - Support for Transformation, hold
-    // FrameAreaTransformation and FramePrintAreaTransformation
-    // here when rotation is used
-    basegfx::B2DHomMatrix   maFrameAreaTransformation;
-    basegfx::B2DHomMatrix   maFramePrintAreaTransformation;
-
     const Size& GetSize() const;
 
     void Format ( vcl::RenderContext* pRenderContext, const SwBorderAttrs *pAttrs = nullptr ) override;
@@ -45,9 +38,16 @@ private:
     virtual void DestroyImpl() override;
     virtual ~SwNoTextFrame() override;
 
+    // RotateFlyFrame3 - Support for inner frame of a SwGrfNode.
+    // Only for local data extraction. To uniquely access information
+    // for local transformation, use getFrameArea(Print)Transformation.
+    friend double getFrameRotation_from_SwNoTextFrame(const SwNoTextFrame& rNoTextFrame);
+    double getFrameRotation() const;
+
 protected:
     virtual void MakeAll(vcl::RenderContext* pRenderContext) override;
     virtual void Modify( const SfxPoolItem*, const SfxPoolItem* ) override;
+
 public:
     SwNoTextFrame( SwNoTextNode * const, SwFrame* );
 
@@ -65,17 +65,9 @@ public:
     void StopAnimation( OutputDevice* = nullptr ) const;
     bool HasAnimation()  const;
 
-    // RotateFlyFrame3 - Support for Transformations for inner frame of a SwGrfNode
-    basegfx::B2DHomMatrix getFrameAreaTransformation() const;
-    basegfx::B2DHomMatrix getFramePrintAreaTransformation() const;
-    void updateTransformationsAndAreas(
-        double fRotation,
-        const basegfx::B2DPoint& rCenter);
-
-    // RotateFlyFrame3 - Support for inner frame of a SwGrfNode.
-    // Only for local data extraction. To uniquely access information
-    // for local transformation, use getFrameArea(Print)Transformation.
-    double getFrameRotation() const;
+    // RotateFlyFrame3 - Support for Transformations
+    virtual basegfx::B2DHomMatrix getFrameAreaTransformation() const override;
+    virtual basegfx::B2DHomMatrix getFramePrintAreaTransformation() const override;
 };
 
 #endif
diff --git a/sw/source/core/layout/flylay.cxx b/sw/source/core/layout/flylay.cxx
index 3fcdb8f0ddff..eb04645ff2a8 100644
--- a/sw/source/core/layout/flylay.cxx
+++ b/sw/source/core/layout/flylay.cxx
@@ -46,14 +46,12 @@ using namespace ::com::sun::star;
 
 SwFlyFreeFrame::SwFlyFreeFrame( SwFlyFrameFormat *pFormat, SwFrame* pSib, SwFrame *pAnch )
 :   SwFlyFrame( pFormat, pSib, pAnch ),
+    TransformableSwFrame(),
     // #i34753#
     mbNoMakePos( false ),
     // #i37068#
     mbNoMoveOnCheckClip( false ),
-    maUnclippedFrame( ),
-    // RotateFlyFrame3
-    maFrameAreaTransformation(),
-    maFramePrintAreaTransformation()
+    maUnclippedFrame( )
 {
 }
 
@@ -110,9 +108,11 @@ void SwFlyFreeFrame::MakeAll(vcl::RenderContext* /*pRenderContext*/)
     }
 
     if ( !GetAnchorFrame() || IsLocked() || IsColLocked() )
+    {
         return;
+    }
 
-        // #i28701# - use new method <GetPageFrame()>
+    // #i28701# - use new method <GetPageFrame()>
     if( !GetPageFrame() && GetAnchorFrame() && GetAnchorFrame()->IsInFly() )
     {
         SwFlyFrame* pFly = AnchorFrame()->FindFlyFrame();
@@ -233,12 +233,29 @@ void SwFlyFreeFrame::MakeAll(vcl::RenderContext* /*pRenderContext*/)
     // Do not refresh transforms/Areas self here, this will be done
     // when inner and outer frame are layouted, in SwNoTextFrame::MakeAll
     const double fRotation(getFrameRotation());
+    const bool bRotated(!basegfx::fTools::equalZero(fRotation));
 
-    if(basegfx::fTools::equalZero(fRotation))
+    if(!bRotated)
     {
         // reset transformations to show that they are not used
-        maFrameAreaTransformation.identity();
-        maFramePrintAreaTransformation.identity();
+        resetLocalAreaTransformations();
+    }
+    else
+    {
+        // RotateFlyFrame3: Safe changes locally
+        const bool bMeValid(isFrameAreaDefinitionValid());
+
+        if(bMeValid)
+        {
+            // get center from outer frame (layout frame) to be on the safe side
+            const Point aCenter(getFrameArea().Center());
+            const basegfx::B2DPoint aB2DCenter(aCenter.X(), aCenter.Y());
+
+            updateTransformationsAndFrameAreaDefinitions(
+                *this,
+                fRotation,
+                aB2DCenter);
+        }
     }
 
     Unlock();
@@ -252,28 +269,13 @@ void SwFlyFreeFrame::MakeAll(vcl::RenderContext* /*pRenderContext*/)
 #endif
 }
 
-void SwFlyFreeFrame::updateTransformationsAndAreas(
-    double fRotation,
-    const basegfx::B2DPoint& rCenter)
-{
-    createFrameAreaTransformations(
-        maFrameAreaTransformation,
-        maFramePrintAreaTransformation,
-        fRotation,
-        rCenter);
-
-    setFrameAreaDefinitionsToBoundRangesOfTransformations(
-        maFrameAreaTransformation,
-        maFramePrintAreaTransformation);
-}
-
 // RotateFlyFrame3 - Support for Transformations - outer frame
 basegfx::B2DHomMatrix SwFlyFreeFrame::getFrameAreaTransformation() const
 {
-    if(!maFrameAreaTransformation.isIdentity())
+    if(!getLocalFrameAreaTransformation().isIdentity())
     {
         // use pre-created transformation
-        return maFrameAreaTransformation;
+        return getLocalFrameAreaTransformation();
     }
 
     // call parent
@@ -282,10 +284,10 @@ basegfx::B2DHomMatrix SwFlyFreeFrame::getFrameAreaTransformation() const
 
 basegfx::B2DHomMatrix SwFlyFreeFrame::getFramePrintAreaTransformation() const
 {
-    if(!maFramePrintAreaTransformation.isIdentity())
+    if(!getLocalFramePrintAreaTransformation().isIdentity())
     {
         // use pre-created transformation
-        return maFramePrintAreaTransformation;
+        return getLocalFramePrintAreaTransformation();
     }
 
     // call parent
@@ -293,6 +295,11 @@ basegfx::B2DHomMatrix SwFlyFreeFrame::getFramePrintAreaTransformation() const
 }
 
 // RotateFlyFrame3 - outer frame
+double getFrameRotation_from_SwNoTextFrame(const SwNoTextFrame& rNoTextFrame)
+{
+    return rNoTextFrame.getFrameRotation();
+}
+
 double SwFlyFreeFrame::getFrameRotation() const
 {
     // SwLayoutFrame::Lower() != SwFrame::GetLower(), but SwFrame::GetLower()
@@ -301,7 +308,7 @@ double SwFlyFreeFrame::getFrameRotation() const
 
     if(nullptr != pSwNoTextFrame)
     {
-        return pSwNoTextFrame->getFrameRotation();
+        return getFrameRotation_from_SwNoTextFrame(*pSwNoTextFrame);
     }
 
     // no rotation
diff --git a/sw/source/core/layout/wsfrm.cxx b/sw/source/core/layout/wsfrm.cxx
index 4b639d337e71..6b6e37ab9af5 100644
--- a/sw/source/core/layout/wsfrm.cxx
+++ b/sw/source/core/layout/wsfrm.cxx
@@ -105,11 +105,34 @@ SwFrameAreaDefinition::FramePrintAreaWriteAccess::~FramePrintAreaWriteAccess()
     }
 }
 
-void SwFrameAreaDefinition::createFrameAreaTransformations(
-    basegfx::B2DHomMatrix& rFrameAreaTransformation,
-    basegfx::B2DHomMatrix& rFramePrintAreaTransformation,
+// RotateFlyFrame3 - Support for Transformations
+basegfx::B2DHomMatrix SwFrameAreaDefinition::getFrameAreaTransformation() const
+{
+    // default implementation hands out FrameArea (outer frame)
+    const SwRect& rFrameArea(getFrameArea());
+
+    return basegfx::utils::createScaleTranslateB2DHomMatrix(
+        rFrameArea.Width(), rFrameArea.Height(),
+        rFrameArea.Left(), rFrameArea.Top());
+}
+
+basegfx::B2DHomMatrix SwFrameAreaDefinition::getFramePrintAreaTransformation() const
+{
+    // default implementation hands out FramePrintArea (outer frame)
+    // Take into account that FramePrintArea is relative to FrameArea
+    const SwRect& rFrameArea(getFrameArea());
+    const SwRect& rFramePrintArea(getFramePrintArea());
+
+    return basegfx::utils::createScaleTranslateB2DHomMatrix(
+        rFramePrintArea.Width(), rFramePrintArea.Height(),
+        rFramePrintArea.Left() + rFrameArea.Left(),
+        rFramePrintArea.Top() + rFrameArea.Top());
+}
+
+void TransformableSwFrame::createFrameAreaTransformations(
+    const SwFrameAreaDefinition& rSwFrameAreaDefinition,
     double fRotation,
-    const basegfx::B2DPoint& rCenter) const
+    const basegfx::B2DPoint& rCenter)
 {
     // save Transformations to rFrameAreaTransformation and
     // rFramePrintAreaTransformation. Do not forget that PrintArea
@@ -119,75 +142,117 @@ void SwFrameAreaDefinition::createFrameAreaTransformations(
             rCenter.getX(),
             rCenter.getY(),
             fRotation));
-    rFrameAreaTransformation = aRotateAroundCenter * basegfx::utils::createScaleTranslateB2DHomMatrix(
-        getFrameArea().Width(), getFrameArea().Height(),
-        getFrameArea().Left(), getFrameArea().Top());
-    rFramePrintAreaTransformation = aRotateAroundCenter * basegfx::utils::createScaleTranslateB2DHomMatrix(
-        getFramePrintArea().Width(), getFramePrintArea().Height(),
-        getFramePrintArea().Left() + getFrameArea().Left(), getFramePrintArea().Top() + getFrameArea().Top());
+    const SwRect& rFrameArea(rSwFrameAreaDefinition.getFrameArea());
+    const SwRect& rFramePrintArea(rSwFrameAreaDefinition.getFramePrintArea());
+
+    setLocalFrameAreaTransformation(
+        aRotateAroundCenter * basegfx::utils::createScaleTranslateB2DHomMatrix(
+            rFrameArea.Width(), rFrameArea.Height(),
+            rFrameArea.Left(), rFrameArea.Top()));
+    setLocalFramePrintAreaTransformation(
+        aRotateAroundCenter * basegfx::utils::createScaleTranslateB2DHomMatrix(
+            rFramePrintArea.Width(), rFramePrintArea.Height(),
+            rFramePrintArea.Left() + rFrameArea.Left(), rFramePrintArea.Top() + rFrameArea.Top()));
 }
 
-void SwFrameAreaDefinition::setFrameAreaDefinitionsToBoundRangesOfTransformations(
-    const basegfx::B2DHomMatrix& rFrameAreaTransformation,
-    const basegfx::B2DHomMatrix& rFramePrintAreaTransformation)
+void TransformableSwFrame::setFrameAreaDefinitionsToBoundRangesOfTransformations(
+    SwFrameAreaDefinition& rSwFrameAreaDefinition)
 {
-    if(!rFrameAreaTransformation.isIdentity())
+    if(!getLocalFrameAreaTransformation().isIdentity())
     {
         basegfx::B2DRange aRangeFrameArea(0.0, 0.0, 1.0, 1.0);
-
-        aRangeFrameArea.transform(rFrameAreaTransformation);
-
+        aRangeFrameArea.transform(getLocalFrameAreaTransformation());
         const SwRect aNewFrm(
             basegfx::fround(aRangeFrameArea.getMinX()), basegfx::fround(aRangeFrameArea.getMinY()),
             basegfx::fround(aRangeFrameArea.getWidth()), basegfx::fround(aRangeFrameArea.getHeight()));
 
-        if(aNewFrm != getFrameArea())
+        if(aNewFrm != rSwFrameAreaDefinition.getFrameArea())
         {
-            maFrameArea = aNewFrm;
+            SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(rSwFrameAreaDefinition);
+            aFrm.setSwRect(aNewFrm);
         }
     }
 
-    if(!rFramePrintAreaTransformation.isIdentity())
+    if(!getLocalFramePrintAreaTransformation().isIdentity())
     {
         basegfx::B2DRange aRangeFramePrintArea(0.0, 0.0, 1.0, 1.0);
-
-        aRangeFramePrintArea.transform(rFramePrintAreaTransformation);
-
+        aRangeFramePrintArea.transform(getLocalFramePrintAreaTransformation());
         const SwRect aNewPrt(
-            basegfx::fround(aRangeFramePrintArea.getMinX()) - getFrameArea().Left(),
-            basegfx::fround(aRangeFramePrintArea.getMinY()) - getFrameArea().Top(),
+            basegfx::fround(aRangeFramePrintArea.getMinX()) - rSwFrameAreaDefinition.getFrameArea().Left(),
+            basegfx::fround(aRangeFramePrintArea.getMinY()) - rSwFrameAreaDefinition.getFrameArea().Top(),
             basegfx::fround(aRangeFramePrintArea.getWidth()),
             basegfx::fround(aRangeFramePrintArea.getHeight()));
 
-        if(aNewPrt != getFramePrintArea())
+        if(aNewPrt != rSwFrameAreaDefinition.getFramePrintArea())
         {
-            maFramePrintArea = aNewPrt;
+            SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(rSwFrameAreaDefinition);
+            aPrt.setSwRect(aNewPrt);
         }
     }
 }
 
-// RotateFlyFrame3 - Support for Transformations
-basegfx::B2DHomMatrix SwFrame::getFrameAreaTransformation() const
+void TransformableSwFrame::updateTransformationsAndFrameAreaDefinitions(
+    SwFrameAreaDefinition& rSwFrameAreaDefinition,
+    double fRotation,
+    const basegfx::B2DPoint& rCenter)
 {
-    // default implementation hands out FrameArea (outer frame)
-    const SwRect& rFrameArea(getFrameArea());
+    createFrameAreaTransformations(
+        rSwFrameAreaDefinition,
+        fRotation,
+        rCenter);
 
-    return basegfx::utils::createScaleTranslateB2DHomMatrix(
-        rFrameArea.Width(), rFrameArea.Height(),
-        rFrameArea.Left(), rFrameArea.Top());
+    setFrameAreaDefinitionsToBoundRangesOfTransformations(
+        rSwFrameAreaDefinition);
 }
 
-basegfx::B2DHomMatrix SwFrame::getFramePrintAreaTransformation() const
+void TransformableSwFrame::resetAreaDefinitionsToUntransformed(
+    SwFrameAreaDefinition& rSwFrameAreaDefinition)
 {
-    // default implementation hands out FramePrintArea (outer frame)
-    // Take into account that FramePrintArea is relative to FrameArea
-    const SwRect& rFrameArea(getFrameArea());
-    const SwRect& rFramePrintArea(getFramePrintArea());
+    // calculate center of object
+    basegfx::B2DPoint aCenter(getLocalFrameAreaTransformation() * basegfx::B2DPoint(0.5, 0.5));
 
-    return basegfx::utils::createScaleTranslateB2DHomMatrix(
-        rFramePrintArea.Width(), rFramePrintArea.Height(),
-        rFramePrintArea.Left() + rFrameArea.Left(),
-        rFramePrintArea.Top() + rFrameArea.Top());
+    if(!getLocalFrameAreaTransformation().isIdentity())
+    {
+        basegfx::B2DTuple aScale, aTranslate;
+        double fRotate(0.0), fShearX(0.0);
+        getLocalFrameAreaTransformation().decompose(aScale, aTranslate, fRotate, fShearX);
+        const SwRect aNewFrm(
+            basegfx::fround(aCenter.getX() - (0.5 * aScale.getX())),
+            basegfx::fround(aCenter.getY() - (0.5 * aScale.getY())),
+            basegfx::fround(aScale.getX()),
+            basegfx::fround(aScale.getY()));
+
+        if(aNewFrm != rSwFrameAreaDefinition.getFrameArea())
+        {
+            SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(rSwFrameAreaDefinition);
+            aFrm.setSwRect(aNewFrm);
+        }
+    }
+
+    if(!getLocalFramePrintAreaTransformation().isIdentity())
+    {
+        basegfx::B2DTuple aScale, aTranslate;
+        double fRotate(0.0), fShearX(0.0);
+        getLocalFramePrintAreaTransformation().decompose(aScale, aTranslate, fRotate, fShearX);
+        const SwRect aNewPrt(
+            basegfx::fround(aCenter.getX() - (0.5 * aScale.getX())) - rSwFrameAreaDefinition.getFrameArea().Left(),
+            basegfx::fround(aCenter.getY() - (0.5 * aScale.getY())) - rSwFrameAreaDefinition.getFrameArea().Top(),
+            basegfx::fround(aScale.getX()),
+            basegfx::fround(aScale.getY()));
+
+        if(aNewPrt != rSwFrameAreaDefinition.getFramePrintArea())
+        {
+            SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(rSwFrameAreaDefinition);
+            aPrt.setSwRect(aNewPrt);
+        }
+    }
+}
+
+void TransformableSwFrame::resetAreaDefinitionsToTransformed(
+    SwFrameAreaDefinition& rSwFrameAreaDefinition)
+{
+    setFrameAreaDefinitionsToBoundRangesOfTransformations(
+        rSwFrameAreaDefinition);
 }
 
 SwFrame::SwFrame( SwModify *pMod, SwFrame* pSib )


More information about the Libreoffice-commits mailing list