[Libreoffice-commits] core.git: Branch 'feature/RotateFlyFrame3' - sw/source
Armin Le Grand
Armin.Le.Grand at cib.de
Thu Nov 16 17:49:51 UTC 2017
sw/source/core/draw/dflyobj.cxx | 8 -
sw/source/core/frmedt/fefly1.cxx | 2
sw/source/core/inc/flyfrms.hxx | 7 -
sw/source/core/layout/fly.cxx | 219 +++++++++++++++++++++-----------------
sw/source/core/layout/flylay.cxx | 42 +++++++
sw/source/core/layout/frmtool.cxx | 20 ++-
sw/source/core/text/txtfly.cxx | 17 ++
7 files changed, 206 insertions(+), 109 deletions(-)
New commits:
commit 255147eae820b26a8522814711066a1d883a7106
Author: Armin Le Grand <Armin.Le.Grand at cib.de>
Date: Thu Nov 16 18:47:29 2017 +0100
RotateFlyFrame3: add support for AutoContour
For transformed FlyFrames with no Border and no Padding it
would be nice to immediately start using AutoContour, added
first implementation to do so
Change-Id: I9f82d6ff3be8e1b8fb39b33836935b32879f405c
diff --git a/sw/source/core/draw/dflyobj.cxx b/sw/source/core/draw/dflyobj.cxx
index a4466f1f9085..2dd8cffbf300 100644
--- a/sw/source/core/draw/dflyobj.cxx
+++ b/sw/source/core/draw/dflyobj.cxx
@@ -632,9 +632,9 @@ void SwVirtFlyDrawObj::NbcSetLogicRect(const tools::Rectangle& )
// SwVirtFlyDrawObj::Move() and Resize()
void SwVirtFlyDrawObj::NbcMove(const Size& rSiz)
{
- if(GetFlyFrame()->IsFlyFreeFrame() && static_cast<SwFlyFreeFrame*>(GetFlyFrame())->isTransformableSwFrame())
+ if(GetFlyFrame()->IsFlyFreeFrame() && static_cast< SwFlyFreeFrame* >(GetFlyFrame())->isTransformableSwFrame())
{
- // When we have a change and are in transformed state (e.g. rotation used),
+ // RotateFlyFrame3: When we have a change and are in transformed state (e.g. rotation used),
// we need to fall back to the un-transformed state to keep the old code below
// working properly. Restore FrameArea and use aOutRect from old FrameArea.
TransformableSwFrame* pTransformableSwFrame(static_cast<SwFlyFreeFrame*>(GetFlyFrame())->getTransformableSwFrame());
@@ -825,7 +825,7 @@ void SwVirtFlyDrawObj::NbcCrop(const basegfx::B2DPoint& rRef, double fxFact, dou
const bool bIsTransformableSwFrame(
GetFlyFrame()->IsFlyFreeFrame() &&
- static_cast<SwFlyFreeFrame*>(GetFlyFrame())->isTransformableSwFrame());
+ static_cast< SwFlyFreeFrame* >(GetFlyFrame())->isTransformableSwFrame());
if(bIsTransformableSwFrame)
{
@@ -977,7 +977,7 @@ void SwVirtFlyDrawObj::NbcResize(const Point& rRef, const Fraction& xFact, const
const bool bUseRightEdge((bVertX && !bVertL2RX ) || bRTL);
const bool bIsTransformableSwFrame(
GetFlyFrame()->IsFlyFreeFrame() &&
- static_cast<SwFlyFreeFrame*>(GetFlyFrame())->isTransformableSwFrame());
+ static_cast< SwFlyFreeFrame* >(GetFlyFrame())->isTransformableSwFrame());
if(bIsTransformableSwFrame)
{
diff --git a/sw/source/core/frmedt/fefly1.cxx b/sw/source/core/frmedt/fefly1.cxx
index 105689dbf848..ece412fde57c 100644
--- a/sw/source/core/frmedt/fefly1.cxx
+++ b/sw/source/core/frmedt/fefly1.cxx
@@ -369,7 +369,7 @@ void SwFEShell::SetFlyPos( const Point& rAbsPos )
// Anchor and new RelPos will be calculated and set by the Fly
if ( pFly->IsFlyAtContentFrame() )
{
- if(pFly->IsFlyFreeFrame() && static_cast<SwFlyFreeFrame*>(pFly)->isTransformableSwFrame())
+ if(pFly->IsFlyFreeFrame() && static_cast< SwFlyFreeFrame* >(pFly)->isTransformableSwFrame())
{
// RotateFlyFrame3: When we have a change and are in transformed state (e.g. rotation used),
// we need to correct the absolute position (rAbsPos) which was created in
diff --git a/sw/source/core/inc/flyfrms.hxx b/sw/source/core/inc/flyfrms.hxx
index eaae5b89059d..1bde38f6784b 100644
--- a/sw/source/core/inc/flyfrms.hxx
+++ b/sw/source/core/inc/flyfrms.hxx
@@ -37,10 +37,10 @@ private:
// #i34753# - flag for at-page anchored Writer fly frames
// to prevent a positioning - call of method <MakeObjPos()> -, if Writer
// fly frame is already clipped during its format by the object formatter.
- bool mbNoMakePos;
+ bool mbNoMakePos : 1;
// #i37068# - flag to prevent move in method <CheckClip(..)>
- bool mbNoMoveOnCheckClip;
+ bool mbNoMoveOnCheckClip : 1;
SwRect maUnclippedFrame;
@@ -134,6 +134,9 @@ public:
TransformableSwFrame* getTransformableSwFrame() { return mpTransformableSwFrame.get(); }
const TransformableSwFrame* getTransformableSwFrame() const { return mpTransformableSwFrame.get(); }
+ // RotateFlyFrame3 - Support for AutoContour
+ bool supportsAutoContour() const;
+
// RotateFlyFrame3 - Support for Transformations
virtual basegfx::B2DHomMatrix getFrameAreaTransformation() const override;
virtual basegfx::B2DHomMatrix getFramePrintAreaTransformation() const override;
diff --git a/sw/source/core/layout/fly.cxx b/sw/source/core/layout/fly.cxx
index 5163fbb3f3c4..4e7639411062 100644
--- a/sw/source/core/layout/fly.cxx
+++ b/sw/source/core/layout/fly.cxx
@@ -2303,8 +2303,18 @@ void SwFlyFrame::NotifyDrawObj()
pObj->SetRectsDirty();
pObj->SetChanged();
pObj->BroadcastObjectChange();
+
if ( GetFormat()->GetSurround().IsContour() )
+ {
+ ClrContourCache( pObj );
+ }
+ else if(IsFlyFreeFrame() && static_cast< const SwFlyFreeFrame* >(this)->supportsAutoContour())
+ {
+ // RotateFlyFrame3: Also need to clear when changes happen
+ // Caution: isTransformableSwFrame is already reset when resetting rotation, so
+ // *additionally* reset in SwFlyFreeFrame::MakeAll when no more rotation
ClrContourCache( pObj );
+ }
}
Size SwFlyFrame::CalcRel( const SwFormatFrameSize &rSz ) const
@@ -2435,120 +2445,135 @@ bool SwFlyFrame::GetContour( tools::PolyPolygon& rContour,
bool bRet = false;
const bool bIsCandidate(Lower() && Lower()->IsNoTextFrame());
- if(bIsCandidate && GetFormat()->GetSurround().IsContour())
+ if(bIsCandidate)
{
- SwNoTextNode *pNd = const_cast<SwNoTextNode*>(static_cast<const SwNoTextNode*>(static_cast<const SwContentFrame*>(Lower())->GetNode()));
- // OD 16.04.2003 #i13147# - determine <GraphicObject> instead of <Graphic>
- // in order to avoid load of graphic, if <SwNoTextNode> contains a graphic
- // node and method is called for paint.
- const GraphicObject* pGrfObj = nullptr;
- bool bGrfObjCreated = false;
- const SwGrfNode* pGrfNd = pNd->GetGrfNode();
- if ( pGrfNd && _bForPaint )
- {
- pGrfObj = &(pGrfNd->GetGrfObj());
- }
- else
- {
- pGrfObj = new GraphicObject( pNd->GetGraphic() );
- bGrfObjCreated = true;
- }
- OSL_ENSURE( pGrfObj, "SwFlyFrame::GetContour() - No Graphic/GraphicObject found at <SwNoTextNode>." );
- if ( pGrfObj && pGrfObj->GetType() != GraphicType::NONE )
+ if(GetFormat()->GetSurround().IsContour())
{
- if( !pNd->HasContour() )
+ SwNoTextNode *pNd = const_cast<SwNoTextNode*>(static_cast<const SwNoTextNode*>(static_cast<const SwContentFrame*>(Lower())->GetNode()));
+ // OD 16.04.2003 #i13147# - determine <GraphicObject> instead of <Graphic>
+ // in order to avoid load of graphic, if <SwNoTextNode> contains a graphic
+ // node and method is called for paint.
+ const GraphicObject* pGrfObj = nullptr;
+ bool bGrfObjCreated = false;
+ const SwGrfNode* pGrfNd = pNd->GetGrfNode();
+ if ( pGrfNd && _bForPaint )
{
- // OD 16.04.2003 #i13147# - no <CreateContour> for a graphic
- // during paint. Thus, return (value of <bRet> should be <false>).
- if ( pGrfNd && _bForPaint )
+ pGrfObj = &(pGrfNd->GetGrfObj());
+ }
+ else
+ {
+ pGrfObj = new GraphicObject( pNd->GetGraphic() );
+ bGrfObjCreated = true;
+ }
+ OSL_ENSURE( pGrfObj, "SwFlyFrame::GetContour() - No Graphic/GraphicObject found at <SwNoTextNode>." );
+ if ( pGrfObj && pGrfObj->GetType() != GraphicType::NONE )
+ {
+ if( !pNd->HasContour() )
{
- OSL_FAIL( "SwFlyFrame::GetContour() - No Contour found at <SwNoTextNode> during paint." );
- return bRet;
+ // OD 16.04.2003 #i13147# - no <CreateContour> for a graphic
+ // during paint. Thus, return (value of <bRet> should be <false>).
+ if ( pGrfNd && _bForPaint )
+ {
+ OSL_FAIL( "SwFlyFrame::GetContour() - No Contour found at <SwNoTextNode> during paint." );
+ return bRet;
+ }
+ pNd->CreateContour();
}
- pNd->CreateContour();
- }
- pNd->GetContour( rContour );
- // The Node holds the Polygon matching the original size of the graphic
- // We need to include the scaling here
- SwRect aClip;
- SwRect aOrig;
- Lower()->Calc(pRenderContext);
- static_cast<const SwNoTextFrame*>(Lower())->GetGrfArea( aClip, &aOrig );
- // OD 16.04.2003 #i13147# - copy method code <SvxContourDlg::ScaleContour(..)>
- // in order to avoid that graphic has to be loaded for contour scale.
- //SvxContourDlg::ScaleContour( rContour, aGrf, MapUnit::MapTwip, aOrig.SSize() );
- {
- OutputDevice* pOutDev = Application::GetDefaultDevice();
- const MapMode aDispMap( MapUnit::MapTwip );
- const MapMode aGrfMap( pGrfObj->GetPrefMapMode() );
- const Size aGrfSize( pGrfObj->GetPrefSize() );
- Size aOrgSize;
- Point aNewPoint;
- bool bPixelMap = aGrfMap.GetMapUnit() == MapUnit::MapPixel;
-
- if ( bPixelMap )
- aOrgSize = pOutDev->PixelToLogic( aGrfSize, aDispMap );
- else
- aOrgSize = OutputDevice::LogicToLogic( aGrfSize, aGrfMap, aDispMap );
-
- if ( aOrgSize.Width() && aOrgSize.Height() )
+ pNd->GetContour( rContour );
+ // The Node holds the Polygon matching the original size of the graphic
+ // We need to include the scaling here
+ SwRect aClip;
+ SwRect aOrig;
+ Lower()->Calc(pRenderContext);
+ static_cast<const SwNoTextFrame*>(Lower())->GetGrfArea( aClip, &aOrig );
+ // OD 16.04.2003 #i13147# - copy method code <SvxContourDlg::ScaleContour(..)>
+ // in order to avoid that graphic has to be loaded for contour scale.
+ //SvxContourDlg::ScaleContour( rContour, aGrf, MapUnit::MapTwip, aOrig.SSize() );
{
- double fScaleX = (double) aOrig.Width() / aOrgSize.Width();
- double fScaleY = (double) aOrig.Height() / aOrgSize.Height();
+ OutputDevice* pOutDev = Application::GetDefaultDevice();
+ const MapMode aDispMap( MapUnit::MapTwip );
+ const MapMode aGrfMap( pGrfObj->GetPrefMapMode() );
+ const Size aGrfSize( pGrfObj->GetPrefSize() );
+ Size aOrgSize;
+ Point aNewPoint;
+ bool bPixelMap = aGrfMap.GetMapUnit() == MapUnit::MapPixel;
+
+ if ( bPixelMap )
+ aOrgSize = pOutDev->PixelToLogic( aGrfSize, aDispMap );
+ else
+ aOrgSize = OutputDevice::LogicToLogic( aGrfSize, aGrfMap, aDispMap );
- for ( sal_uInt16 j = 0, nPolyCount = rContour.Count(); j < nPolyCount; j++ )
+ if ( aOrgSize.Width() && aOrgSize.Height() )
{
- tools::Polygon& rPoly = rContour[ j ];
+ double fScaleX = (double) aOrig.Width() / aOrgSize.Width();
+ double fScaleY = (double) aOrig.Height() / aOrgSize.Height();
- for ( sal_uInt16 i = 0, nCount = rPoly.GetSize(); i < nCount; i++ )
+ for ( sal_uInt16 j = 0, nPolyCount = rContour.Count(); j < nPolyCount; j++ )
{
- if ( bPixelMap )
- aNewPoint = pOutDev->PixelToLogic( rPoly[ i ], aDispMap );
- else
- aNewPoint = OutputDevice::LogicToLogic( rPoly[ i ], aGrfMap, aDispMap );
+ tools::Polygon& rPoly = rContour[ j ];
- rPoly[ i ] = Point( FRound( aNewPoint.getX() * fScaleX ), FRound( aNewPoint.getY() * fScaleY ) );
+ for ( sal_uInt16 i = 0, nCount = rPoly.GetSize(); i < nCount; i++ )
+ {
+ if ( bPixelMap )
+ aNewPoint = pOutDev->PixelToLogic( rPoly[ i ], aDispMap );
+ else
+ aNewPoint = OutputDevice::LogicToLogic( rPoly[ i ], aGrfMap, aDispMap );
+
+ rPoly[ i ] = Point( FRound( aNewPoint.getX() * fScaleX ), FRound( aNewPoint.getY() * fScaleY ) );
+ }
}
}
}
+ // OD 17.04.2003 #i13147# - destroy created <GraphicObject>.
+ if ( bGrfObjCreated )
+ {
+ delete pGrfObj;
+ }
+ rContour.Move( aOrig.Left(), aOrig.Top() );
+ if( !aClip.Width() )
+ aClip.Width( 1 );
+ if( !aClip.Height() )
+ aClip.Height( 1 );
+ rContour.Clip( aClip.SVRect() );
+ rContour.Optimize(PolyOptimizeFlags::CLOSE);
+ bRet = true;
}
- // OD 17.04.2003 #i13147# - destroy created <GraphicObject>.
- if ( bGrfObjCreated )
- {
- delete pGrfObj;
- }
- rContour.Move( aOrig.Left(), aOrig.Top() );
- if( !aClip.Width() )
- aClip.Width( 1 );
- if( !aClip.Height() )
- aClip.Height( 1 );
- rContour.Clip( aClip.SVRect() );
- rContour.Optimize(PolyOptimizeFlags::CLOSE);
- bRet = true;
}
- }
+ else
+ {
+ const SwFlyFreeFrame* pSwFlyFreeFrame(static_cast< const SwFlyFreeFrame* >(this));
- if(bRet &&
- rContour.Count() &&
- IsFlyFreeFrame() &&
- static_cast<const SwFlyFreeFrame*>(this)->isTransformableSwFrame())
- {
- // RotateFlyFrame: Need to adapt contour to transformation
- basegfx::B2DVector aScale, aTranslate;
- double fRotate, fShearX;
- getFrameAreaTransformation().decompose(aScale, aTranslate, fRotate, fShearX);
-
- if(!basegfx::fTools::equalZero(fRotate))
- {
- basegfx::B2DPolyPolygon aSource(rContour.getB2DPolyPolygon());
- const basegfx::B2DPoint aCenter(getFrameAreaTransformation() * basegfx::B2DPoint(0.5, 0.5));
- const basegfx::B2DHomMatrix aRotateAroundCenter(
- basegfx::utils::createRotateAroundPoint(
- aCenter.getX(),
- aCenter.getY(),
- fRotate));
- aSource.transform(aRotateAroundCenter);
- rContour = tools::PolyPolygon(aSource);
+ if(nullptr != pSwFlyFreeFrame && pSwFlyFreeFrame->supportsAutoContour())
+ {
+ // RotateFlyFrame: use untransformed SwFrame to allow text floating around.
+ // Will be transformed below
+ const TransformableSwFrame* pTransformableSwFrame(pSwFlyFreeFrame->getTransformableSwFrame());
+ const SwRect aFrameArea(pTransformableSwFrame->getUntransformedFrameArea());
+ rContour = tools::PolyPolygon(tools::Polygon(aFrameArea.SVRect()));
+
+ if(0 != rContour.Count())
+ {
+ // Need to adapt contour to transformation
+ basegfx::B2DVector aScale, aTranslate;
+ double fRotate, fShearX;
+ getFrameAreaTransformation().decompose(aScale, aTranslate, fRotate, fShearX);
+
+ if(!basegfx::fTools::equalZero(fRotate))
+ {
+ basegfx::B2DPolyPolygon aSource(rContour.getB2DPolyPolygon());
+ const basegfx::B2DPoint aCenter(getFrameAreaTransformation() * basegfx::B2DPoint(0.5, 0.5));
+ const basegfx::B2DHomMatrix aRotateAroundCenter(
+ basegfx::utils::createRotateAroundPoint(
+ aCenter.getX(),
+ aCenter.getY(),
+ fRotate));
+ aSource.transform(aRotateAroundCenter);
+ rContour = tools::PolyPolygon(aSource);
+ }
+
+ bRet = true;
+ }
+ }
}
}
diff --git a/sw/source/core/layout/flylay.cxx b/sw/source/core/layout/flylay.cxx
index 8a8c714ef351..c3cf51baa343 100644
--- a/sw/source/core/layout/flylay.cxx
+++ b/sw/source/core/layout/flylay.cxx
@@ -27,6 +27,7 @@
#include <hints.hxx>
#include <sectfrm.hxx>
#include <notxtfrm.hxx>
+#include <txtfly.hxx>
#include <svx/svdpage.hxx>
#include <editeng/ulspitem.hxx>
@@ -87,6 +88,8 @@ void SwFlyFreeFrame::DestroyImpl()
SwFlyFreeFrame::~SwFlyFreeFrame()
{
+ // we are possibly in ContourCache, make sure we vanish
+ ::ClrContourCache(GetVirtDrawObj());
}
// #i28701#
@@ -268,6 +271,14 @@ void SwFlyFreeFrame::MakeAll(vcl::RenderContext* /*pRenderContext*/)
}
else
{
+ // RotateFlyFrame3: Also need to clear ContourCache (if used),
+ // usually done in SwFlyFrame::NotifyDrawObj, but there relies on
+ // being in transform mode which is already resetted then
+ if(isTransformableSwFrame())
+ {
+ ::ClrContourCache(GetVirtDrawObj());
+ }
+
// reset transformations to show that they are not used
mpTransformableSwFrame.reset();
}
@@ -283,6 +294,37 @@ void SwFlyFreeFrame::MakeAll(vcl::RenderContext* /*pRenderContext*/)
#endif
}
+bool SwFlyFreeFrame::supportsAutoContour() const
+{
+ if(!isTransformableSwFrame())
+ {
+ // support only when transformed, else there is no free space
+ return false;
+ }
+
+ // Check for Borders. If we have Borders, do (currently) not support,
+ // since borders do not transform with the object.
+ // (Will need to be enhanced to take into account if we have Borders and if these
+ // transform with the object)
+ SwBorderAttrAccess aAccess(SwFrame::GetCache(), this);
+ const SwBorderAttrs &rAttrs(*aAccess.Get());
+
+ if(rAttrs.IsLine())
+ {
+ return false;
+ }
+
+ // Check for Padding. Do not support when padding is used, this will
+ // produce a covered space around the object (filled with fill defines)
+
+
+
+
+
+ // else, support
+ return true;
+}
+
// RotateFlyFrame3 - Support for Transformations - outer frame
basegfx::B2DHomMatrix SwFlyFreeFrame::getFrameAreaTransformation() const
{
diff --git a/sw/source/core/layout/frmtool.cxx b/sw/source/core/layout/frmtool.cxx
index 7144ee460dcd..2276f7fa2b99 100644
--- a/sw/source/core/layout/frmtool.cxx
+++ b/sw/source/core/layout/frmtool.cxx
@@ -2740,11 +2740,23 @@ void Notify( SwFlyFrame *pFly, SwPageFrame *pOld, const SwRect &rOld,
pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD );
}
}
- else if ( pOldPrt && *pOldPrt != pFly->getFramePrintArea() &&
- pFly->GetFormat()->GetSurround().IsContour() )
+ else if(pOldPrt && *pOldPrt != pFly->getFramePrintArea())
{
- // #i24097#
- pFly->NotifyBackground( pFly->FindPageFrame(), aFrame, PREP_FLY_ARRIVE );
+ bool bNotifyBackground(pFly->GetFormat()->GetSurround().IsContour());
+
+ if(!bNotifyBackground &&
+ pFly->IsFlyFreeFrame() &&
+ static_cast< const SwFlyFreeFrame* >(pFly)->supportsAutoContour())
+ {
+ // RotateFlyFrame3: Also notify for FlyFrames which allow AutoContour
+ bNotifyBackground = true;
+ }
+
+ if(bNotifyBackground)
+ {
+ // #i24097#
+ pFly->NotifyBackground( pFly->FindPageFrame(), aFrame, PREP_FLY_ARRIVE );
+ }
}
}
diff --git a/sw/source/core/text/txtfly.cxx b/sw/source/core/text/txtfly.cxx
index fff55186d725..2fb5c47a38a4 100644
--- a/sw/source/core/text/txtfly.cxx
+++ b/sw/source/core/text/txtfly.cxx
@@ -177,7 +177,22 @@ const SwRect SwContourCache::CalcBoundRect( const SwAnchoredObject* pAnchoredObj
{
SwRect aRet;
const SwFrameFormat* pFormat = &(pAnchoredObj->GetFrameFormat());
- if( pFormat->GetSurround().IsContour() &&
+ bool bHandleContour(pFormat->GetSurround().IsContour());
+
+ if(!bHandleContour)
+ {
+ // RotateFlyFrame3: Object has no set contour, but for rotated
+ // FlyFrames we can create a 'default' contour to make text
+ // flow around the free, non-covered
+ const SwFlyFreeFrame* pSwFlyFreeFrame(dynamic_cast< const SwFlyFreeFrame* >(pAnchoredObj));
+
+ if(nullptr != pSwFlyFreeFrame && pSwFlyFreeFrame->supportsAutoContour())
+ {
+ bHandleContour = true;
+ }
+ }
+
+ if( bHandleContour &&
( dynamic_cast< const SwFlyFrame *>( pAnchoredObj ) == nullptr ||
( static_cast<const SwFlyFrame*>(pAnchoredObj)->Lower() &&
static_cast<const SwFlyFrame*>(pAnchoredObj)->Lower()->IsNoTextFrame() ) ) )
More information about the Libreoffice-commits
mailing list