662 lines
21 KiB
C++
662 lines
21 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
*/
|
|
|
|
|
|
#include <svx/svdpoev.hxx>
|
|
#include <math.h>
|
|
#include <svx/svdpagv.hxx>
|
|
#include <svx/svdpage.hxx>
|
|
#include <svx/svdopath.hxx>
|
|
#include <svx/svdundo.hxx>
|
|
#include <svx/strings.hrc>
|
|
#include <svx/dialmgr.hxx>
|
|
#include <svx/svdtrans.hxx>
|
|
#include <basegfx/polygon/b2dpolygon.hxx>
|
|
#include <basegfx/polygon/b2dpolygontools.hxx>
|
|
#include <tools/debug.hxx>
|
|
#include <tools/helpers.hxx>
|
|
|
|
#include <svx/polypolygoneditor.hxx>
|
|
|
|
using namespace sdr;
|
|
|
|
|
|
void SdrPolyEditView::ImpResetPolyPossibilityFlags()
|
|
{
|
|
m_eMarkedPointsSmooth=SdrPathSmoothKind::DontCare;
|
|
m_eMarkedSegmentsKind=SdrPathSegmentKind::DontCare;
|
|
m_bSetMarkedPointsSmoothPossible=false;
|
|
m_bSetMarkedSegmentsKindPossible=false;
|
|
}
|
|
|
|
SdrPolyEditView::SdrPolyEditView(
|
|
SdrModel& rSdrModel,
|
|
OutputDevice* pOut)
|
|
: SdrEditView(rSdrModel, pOut)
|
|
{
|
|
ImpResetPolyPossibilityFlags();
|
|
}
|
|
|
|
SdrPolyEditView::~SdrPolyEditView()
|
|
{
|
|
}
|
|
|
|
void SdrPolyEditView::ImpCheckPolyPossibilities()
|
|
{
|
|
const SdrMarkList& rMarkList = GetMarkedObjectList();
|
|
ImpResetPolyPossibilityFlags();
|
|
const size_t nMarkCount(rMarkList.GetMarkCount());
|
|
|
|
if(!nMarkCount || ImpIsFrameHandles())
|
|
return;
|
|
|
|
bool b1stSmooth(true);
|
|
bool b1stSegm(true);
|
|
bool bCurve(false);
|
|
bool bSmoothFuz(false);
|
|
bool bSegmFuz(false);
|
|
basegfx::B2VectorContinuity eSmooth = basegfx::B2VectorContinuity::NONE;
|
|
|
|
for(size_t nMarkNum = 0; nMarkNum < nMarkCount; ++nMarkNum)
|
|
{
|
|
SdrMark* pM = rMarkList.GetMark(nMarkNum);
|
|
CheckPolyPossibilitiesHelper( pM, b1stSmooth, b1stSegm, bCurve, bSmoothFuz, bSegmFuz, eSmooth );
|
|
}
|
|
}
|
|
|
|
void SdrPolyEditView::CheckPolyPossibilitiesHelper( SdrMark* pM, bool& b1stSmooth, bool& b1stSegm, bool& bCurve, bool& bSmoothFuz, bool& bSegmFuz, basegfx::B2VectorContinuity& eSmooth )
|
|
{
|
|
SdrObject* pObj = pM->GetMarkedSdrObj();
|
|
SdrPathObj* pPath = dynamic_cast<SdrPathObj*>( pObj );
|
|
|
|
if (!pPath)
|
|
return;
|
|
|
|
SdrUShortCont& rPts = pM->GetMarkedPoints();
|
|
if (rPts.empty())
|
|
return;
|
|
|
|
const bool bClosed(pPath->IsClosed());
|
|
m_bSetMarkedPointsSmoothPossible = true;
|
|
|
|
if (bClosed)
|
|
{
|
|
m_bSetMarkedSegmentsKindPossible = true;
|
|
}
|
|
|
|
for (const auto& rPt : rPts)
|
|
{
|
|
sal_uInt32 nNum(rPt);
|
|
sal_uInt32 nPolyNum, nPntNum;
|
|
|
|
if(PolyPolygonEditor::GetRelativePolyPoint(pPath->GetPathPoly(), nNum, nPolyNum, nPntNum))
|
|
{
|
|
const basegfx::B2DPolygon aLocalPolygon(pPath->GetPathPoly().getB2DPolygon(nPolyNum));
|
|
bool bCanSegment(bClosed || nPntNum < aLocalPolygon.count() - 1);
|
|
|
|
if(!m_bSetMarkedSegmentsKindPossible && bCanSegment)
|
|
{
|
|
m_bSetMarkedSegmentsKindPossible = true;
|
|
}
|
|
|
|
if(!bSmoothFuz)
|
|
{
|
|
if (b1stSmooth)
|
|
{
|
|
b1stSmooth = false;
|
|
eSmooth = basegfx::utils::getContinuityInPoint(aLocalPolygon, nPntNum);
|
|
}
|
|
else
|
|
{
|
|
bSmoothFuz = (eSmooth != basegfx::utils::getContinuityInPoint(aLocalPolygon, nPntNum));
|
|
}
|
|
}
|
|
|
|
if(!bSegmFuz && bCanSegment)
|
|
{
|
|
bool bCrv(aLocalPolygon.isNextControlPointUsed(nPntNum));
|
|
|
|
if(b1stSegm)
|
|
{
|
|
b1stSegm = false;
|
|
bCurve = bCrv;
|
|
}
|
|
else
|
|
{
|
|
bSegmFuz = (bCrv != bCurve);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(!b1stSmooth && !bSmoothFuz)
|
|
{
|
|
if(basegfx::B2VectorContinuity::NONE == eSmooth)
|
|
{
|
|
m_eMarkedPointsSmooth = SdrPathSmoothKind::Angular;
|
|
}
|
|
|
|
if(basegfx::B2VectorContinuity::C1 == eSmooth)
|
|
{
|
|
m_eMarkedPointsSmooth = SdrPathSmoothKind::Asymmetric;
|
|
}
|
|
|
|
if(basegfx::B2VectorContinuity::C2 == eSmooth)
|
|
{
|
|
m_eMarkedPointsSmooth = SdrPathSmoothKind::Symmetric;
|
|
}
|
|
}
|
|
|
|
if(!b1stSegm && !bSegmFuz)
|
|
{
|
|
m_eMarkedSegmentsKind = bCurve ? SdrPathSegmentKind::Curve : SdrPathSegmentKind::Line;
|
|
}
|
|
}
|
|
|
|
void SdrPolyEditView::SetMarkedPointsSmooth(SdrPathSmoothKind eKind)
|
|
{
|
|
basegfx::B2VectorContinuity eFlags;
|
|
|
|
if(SdrPathSmoothKind::Angular == eKind)
|
|
{
|
|
eFlags = basegfx::B2VectorContinuity::NONE;
|
|
}
|
|
else if(SdrPathSmoothKind::Asymmetric == eKind)
|
|
{
|
|
eFlags = basegfx::B2VectorContinuity::C1;
|
|
}
|
|
else if(SdrPathSmoothKind::Symmetric == eKind)
|
|
{
|
|
eFlags = basegfx::B2VectorContinuity::C2;
|
|
}
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
|
|
if(!HasMarkedPoints())
|
|
return;
|
|
|
|
const SdrMarkList& rMarkList = GetMarkedObjectList();
|
|
rMarkList.ForceSort();
|
|
|
|
const bool bUndo = IsUndoEnabled();
|
|
if( bUndo )
|
|
BegUndo(SvxResId(STR_EditSetPointsSmooth), rMarkList.GetPointMarkDescription());
|
|
const size_t nMarkCount(rMarkList.GetMarkCount());
|
|
|
|
for(size_t nMarkNum(nMarkCount); nMarkNum > 0;)
|
|
{
|
|
--nMarkNum;
|
|
SdrMark* pM = rMarkList.GetMark(nMarkNum);
|
|
SdrPathObj* pPath = dynamic_cast< SdrPathObj* >( pM->GetMarkedSdrObj() );
|
|
if (!pPath)
|
|
continue;
|
|
|
|
SdrUShortCont& rPts = pM->GetMarkedPoints();
|
|
PolyPolygonEditor aEditor(pPath->GetPathPoly());
|
|
if (aEditor.SetPointsSmooth(eFlags, rPts))
|
|
{
|
|
if( bUndo )
|
|
AddUndo(GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pPath));
|
|
pPath->SetPathPoly(aEditor.GetPolyPolygon());
|
|
}
|
|
}
|
|
|
|
if( bUndo )
|
|
EndUndo();
|
|
}
|
|
|
|
void SdrPolyEditView::SetMarkedSegmentsKind(SdrPathSegmentKind eKind)
|
|
{
|
|
if(!HasMarkedPoints())
|
|
return;
|
|
|
|
const SdrMarkList& rMarkList = GetMarkedObjectList();
|
|
rMarkList.ForceSort();
|
|
|
|
const bool bUndo = IsUndoEnabled();
|
|
if( bUndo )
|
|
BegUndo(SvxResId(STR_EditSetSegmentsKind), rMarkList.GetPointMarkDescription());
|
|
const size_t nMarkCount(rMarkList.GetMarkCount());
|
|
|
|
for(size_t nMarkNum=nMarkCount; nMarkNum > 0;)
|
|
{
|
|
--nMarkNum;
|
|
SdrMark* pM = rMarkList.GetMark(nMarkNum);
|
|
SdrPathObj* pPath = dynamic_cast< SdrPathObj* >( pM->GetMarkedSdrObj() );
|
|
if (!pPath)
|
|
continue;
|
|
SdrUShortCont& rPts = pM->GetMarkedPoints();
|
|
PolyPolygonEditor aEditor( pPath->GetPathPoly());
|
|
if (aEditor.SetSegmentsKind(eKind, rPts))
|
|
{
|
|
if( bUndo )
|
|
AddUndo(GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pPath));
|
|
pPath->SetPathPoly(aEditor.GetPolyPolygon());
|
|
}
|
|
}
|
|
|
|
if( bUndo )
|
|
EndUndo();
|
|
}
|
|
|
|
bool SdrPolyEditView::IsSetMarkedPointsSmoothPossible() const
|
|
{
|
|
ForcePossibilities();
|
|
return m_bSetMarkedPointsSmoothPossible;
|
|
}
|
|
|
|
SdrPathSmoothKind SdrPolyEditView::GetMarkedPointsSmooth() const
|
|
{
|
|
ForcePossibilities();
|
|
return m_eMarkedPointsSmooth;
|
|
}
|
|
|
|
bool SdrPolyEditView::IsSetMarkedSegmentsKindPossible() const
|
|
{
|
|
ForcePossibilities();
|
|
return m_bSetMarkedSegmentsKindPossible;
|
|
}
|
|
|
|
SdrPathSegmentKind SdrPolyEditView::GetMarkedSegmentsKind() const
|
|
{
|
|
ForcePossibilities();
|
|
return m_eMarkedSegmentsKind;
|
|
}
|
|
|
|
bool SdrPolyEditView::IsDeleteMarkedPointsPossible() const
|
|
{
|
|
return HasMarkedPoints();
|
|
}
|
|
|
|
void SdrPolyEditView::DeleteMarkedPoints()
|
|
{
|
|
if (!HasMarkedPoints())
|
|
return;
|
|
|
|
BrkAction();
|
|
const SdrMarkList& rMarkList = GetMarkedObjectList();
|
|
rMarkList.ForceSort();
|
|
const size_t nMarkCount=rMarkList.GetMarkCount();
|
|
|
|
const bool bUndo = IsUndoEnabled();
|
|
if( bUndo )
|
|
{
|
|
// Description
|
|
BegUndo(SvxResId(STR_EditDelete),rMarkList.GetPointMarkDescription(),SdrRepeatFunc::Delete);
|
|
}
|
|
|
|
for (size_t nMarkNum=nMarkCount; nMarkNum>0;)
|
|
{
|
|
--nMarkNum;
|
|
SdrMark* pM=rMarkList.GetMark(nMarkNum);
|
|
SdrPathObj* pPath = dynamic_cast< SdrPathObj* >( pM->GetMarkedSdrObj() );
|
|
if (!pPath)
|
|
continue;
|
|
|
|
SdrUShortCont& rPts = pM->GetMarkedPoints();
|
|
PolyPolygonEditor aEditor( pPath->GetPathPoly());
|
|
if (aEditor.DeletePoints(rPts))
|
|
{
|
|
if( aEditor.GetPolyPolygon().count() )
|
|
{
|
|
if (bUndo)
|
|
AddUndo(GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pPath));
|
|
pPath->SetPathPoly( aEditor.GetPolyPolygon() );
|
|
}
|
|
else
|
|
{
|
|
if (bUndo)
|
|
AddUndo(GetModel().GetSdrUndoFactory().CreateUndoDeleteObject(*pPath));
|
|
pM->GetPageView()->GetObjList()->RemoveObject(pPath->GetOrdNum());
|
|
}
|
|
}
|
|
}
|
|
|
|
if( bUndo )
|
|
EndUndo();
|
|
UnmarkAllPoints();
|
|
MarkListHasChanged();
|
|
}
|
|
|
|
void SdrPolyEditView::RipUpAtMarkedPoints()
|
|
{
|
|
if(!HasMarkedPoints())
|
|
return;
|
|
|
|
const SdrMarkList& rMarkList = GetMarkedObjectList();
|
|
rMarkList.ForceSort();
|
|
const size_t nMarkCount(rMarkList.GetMarkCount());
|
|
|
|
const bool bUndo = IsUndoEnabled();
|
|
if( bUndo )
|
|
BegUndo(SvxResId(STR_EditRipUp), rMarkList.GetPointMarkDescription());
|
|
|
|
for(size_t nMarkNum = nMarkCount; nMarkNum > 0;)
|
|
{
|
|
--nMarkNum;
|
|
SdrMark* pM = rMarkList.GetMark(nMarkNum);
|
|
SdrPathObj* pObj = dynamic_cast<SdrPathObj*>( pM->GetMarkedSdrObj() );
|
|
if (!pObj)
|
|
continue;
|
|
|
|
SdrUShortCont& rPts = pM->GetMarkedPoints();
|
|
|
|
if (bUndo)
|
|
AddUndo(GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pObj));
|
|
bool bCorrectionFlag(false);
|
|
sal_uInt32 nMax(pObj->GetHdlCount());
|
|
|
|
for(SdrUShortCont::const_reverse_iterator it = rPts.rbegin(); it != rPts.rend(); ++it)
|
|
{
|
|
sal_uInt32 nNewPt0Idx(0);
|
|
rtl::Reference<SdrPathObj> pNewObj = pObj->RipPoint(*it, nNewPt0Idx);
|
|
|
|
if(pNewObj)
|
|
{
|
|
pM->GetPageView()->GetObjList()->InsertObject(pNewObj.get(), pObj->GetOrdNum() + 1);
|
|
if (bUndo)
|
|
AddUndo(GetModel().GetSdrUndoFactory().CreateUndoNewObject(*pNewObj));
|
|
MarkObj(pNewObj.get(), pM->GetPageView(), false, true);
|
|
}
|
|
|
|
if(nNewPt0Idx)
|
|
{
|
|
// correction necessary?
|
|
DBG_ASSERT(!bCorrectionFlag,"Multiple index corrections at SdrPolyEditView::RipUp().");
|
|
if(!bCorrectionFlag)
|
|
{
|
|
bCorrectionFlag = true;
|
|
|
|
SdrUShortCont aReplaceSet;
|
|
for(const auto& rPt : rPts)
|
|
{
|
|
sal_uInt32 nPntNum(rPt);
|
|
nPntNum += nNewPt0Idx;
|
|
|
|
if(nPntNum >= nMax)
|
|
{
|
|
nPntNum -= nMax;
|
|
}
|
|
|
|
aReplaceSet.insert( static_cast<sal_uInt16>(nPntNum) );
|
|
}
|
|
rPts.swap(aReplaceSet);
|
|
|
|
it = rPts.rbegin();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
UnmarkAllPoints();
|
|
if( bUndo )
|
|
EndUndo();
|
|
MarkListHasChanged();
|
|
}
|
|
|
|
bool SdrPolyEditView::IsRipUpAtMarkedPointsPossible() const
|
|
{
|
|
bool bRetval(false);
|
|
const SdrMarkList& rMarkList = GetMarkedObjectList();
|
|
const size_t nMarkCount(rMarkList.GetMarkCount());
|
|
|
|
for(size_t a = 0; a < nMarkCount; ++a)
|
|
{
|
|
const SdrMark* pMark = rMarkList.GetMark(a);
|
|
const SdrPathObj* pMarkedPathObject = dynamic_cast< const SdrPathObj* >(pMark->GetMarkedSdrObj());
|
|
|
|
if (!pMarkedPathObject)
|
|
continue;
|
|
|
|
const SdrUShortCont& rSelectedPoints = pMark->GetMarkedPoints();
|
|
if (rSelectedPoints.empty())
|
|
continue;
|
|
|
|
const basegfx::B2DPolyPolygon& rPathPolyPolygon = pMarkedPathObject->GetPathPoly();
|
|
|
|
if(1 == rPathPolyPolygon.count())
|
|
{
|
|
// #i76617# Do not yet use basegfx::B2DPolygon since curve definitions
|
|
// are different and methods need to be changed thoroughly with interaction rework
|
|
const tools::Polygon aPathPolygon(rPathPolyPolygon.getB2DPolygon(0));
|
|
const sal_uInt16 nPointCount(aPathPolygon.GetSize());
|
|
|
|
if(nPointCount >= 3)
|
|
{
|
|
bRetval = pMarkedPathObject->IsClosedObj() // #i76617#
|
|
|| std::any_of(rSelectedPoints.begin(), rSelectedPoints.end(),
|
|
[nPointCount](const sal_uInt16 nMarkedPointNum) {
|
|
return nMarkedPointNum > 0 && nMarkedPointNum < nPointCount - 1;
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
return bRetval;
|
|
}
|
|
|
|
bool SdrPolyEditView::IsOpenCloseMarkedObjectsPossible() const
|
|
{
|
|
bool bRetval(false);
|
|
const SdrMarkList& rMarkList = GetMarkedObjectList();
|
|
const size_t nMarkCount(rMarkList.GetMarkCount());
|
|
|
|
for(size_t a = 0; a < nMarkCount; ++a)
|
|
{
|
|
const SdrMark* pMark = rMarkList.GetMark(a);
|
|
const SdrPathObj* pMarkedPathObject = dynamic_cast< const SdrPathObj* >(pMark->GetMarkedSdrObj());
|
|
|
|
if(pMarkedPathObject)
|
|
{
|
|
// #i76617# Do not yet use basegfx::B2DPolygon since curve definitions
|
|
// are different and methods need to be changed thoroughly with interaction rework
|
|
const tools::PolyPolygon aPathPolyPolygon(pMarkedPathObject->GetPathPoly());
|
|
const sal_uInt16 nPolygonCount(aPathPolyPolygon.Count());
|
|
|
|
for(sal_uInt16 b(0); !bRetval && b < nPolygonCount; b++)
|
|
{
|
|
const tools::Polygon& rPathPolygon = aPathPolyPolygon[b];
|
|
const sal_uInt16 nPointCount(rPathPolygon.GetSize());
|
|
|
|
bRetval = (nPointCount >= 3);
|
|
}
|
|
}
|
|
}
|
|
|
|
return bRetval;
|
|
}
|
|
|
|
SdrObjClosedKind SdrPolyEditView::GetMarkedObjectsClosedState() const
|
|
{
|
|
bool bOpen(false);
|
|
bool bClosed(false);
|
|
const SdrMarkList& rMarkList = GetMarkedObjectList();
|
|
const size_t nMarkCount(rMarkList.GetMarkCount());
|
|
|
|
for(size_t a = 0; !(bOpen && bClosed) && a < nMarkCount; ++a)
|
|
{
|
|
const SdrMark* pMark = rMarkList.GetMark(a);
|
|
const SdrPathObj* pMarkedPathObject = dynamic_cast< const SdrPathObj* >(pMark->GetMarkedSdrObj());
|
|
|
|
if(pMarkedPathObject)
|
|
{
|
|
if(pMarkedPathObject->IsClosedObj())
|
|
{
|
|
bClosed = true;
|
|
}
|
|
else
|
|
{
|
|
bOpen = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(bOpen && bClosed)
|
|
{
|
|
return SdrObjClosedKind::DontCare;
|
|
}
|
|
else if(bOpen)
|
|
{
|
|
return SdrObjClosedKind::Open;
|
|
}
|
|
else
|
|
{
|
|
return SdrObjClosedKind::Closed;
|
|
}
|
|
}
|
|
|
|
void SdrPolyEditView::ImpTransformMarkedPoints(PPolyTrFunc pTrFunc, const void* p1, const void* p2, const void* p3, const void* p4)
|
|
{
|
|
const bool bUndo = IsUndoEnabled();
|
|
|
|
const SdrMarkList& rMarkList = GetMarkedObjectList();
|
|
const size_t nMarkCount=rMarkList.GetMarkCount();
|
|
for (size_t nm=0; nm<nMarkCount; ++nm)
|
|
{
|
|
SdrMark* pM=rMarkList.GetMark(nm);
|
|
SdrObject* pObj=pM->GetMarkedSdrObj();
|
|
SdrPathObj* pPath=dynamic_cast<SdrPathObj*>( pObj );
|
|
if (!pPath)
|
|
continue;
|
|
|
|
const SdrUShortCont& rPts = pM->GetMarkedPoints();
|
|
if (rPts.empty())
|
|
continue;
|
|
|
|
if( bUndo )
|
|
AddUndo(GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pObj));
|
|
|
|
basegfx::B2DPolyPolygon aXPP(pPath->GetPathPoly());
|
|
|
|
for (const auto& rPt : rPts)
|
|
{
|
|
sal_uInt32 nPt = rPt;
|
|
sal_uInt32 nPolyNum, nPointNum;
|
|
|
|
if(PolyPolygonEditor::GetRelativePolyPoint(aXPP, nPt, nPolyNum, nPointNum))
|
|
{
|
|
//#i83671# used nLocalPointNum (which was the polygon point count)
|
|
// instead of the point index (nPointNum). This of course led
|
|
// to a wrong point access to the B2DPolygon.
|
|
basegfx::B2DPolygon aNewXP(aXPP.getB2DPolygon(nPolyNum));
|
|
Point aPos, aC1, aC2;
|
|
bool bC1(false);
|
|
bool bC2(false);
|
|
|
|
const basegfx::B2DPoint aB2DPos(aNewXP.getB2DPoint(nPointNum));
|
|
aPos = Point(basegfx::fround<tools::Long>(aB2DPos.getX()),
|
|
basegfx::fround<tools::Long>(aB2DPos.getY()));
|
|
|
|
if(aNewXP.isPrevControlPointUsed(nPointNum))
|
|
{
|
|
const basegfx::B2DPoint aB2DC1(aNewXP.getPrevControlPoint(nPointNum));
|
|
aC1 = Point(basegfx::fround<tools::Long>(aB2DC1.getX()),
|
|
basegfx::fround<tools::Long>(aB2DC1.getY()));
|
|
bC1 = true;
|
|
}
|
|
|
|
if(aNewXP.isNextControlPointUsed(nPointNum))
|
|
{
|
|
const basegfx::B2DPoint aB2DC2(aNewXP.getNextControlPoint(nPointNum));
|
|
aC2 = Point(basegfx::fround<tools::Long>(aB2DC2.getX()),
|
|
basegfx::fround<tools::Long>(aB2DC2.getY()));
|
|
bC2 = true;
|
|
}
|
|
|
|
(*pTrFunc)(aPos,&aC1,&aC2,p1,p2,p3,p4);
|
|
aNewXP.setB2DPoint(nPointNum, basegfx::B2DPoint(aPos.X(), aPos.Y()));
|
|
|
|
if (bC1)
|
|
{
|
|
aNewXP.setPrevControlPoint(nPointNum, basegfx::B2DPoint(aC1.X(), aC1.Y()));
|
|
}
|
|
|
|
if (bC2)
|
|
{
|
|
aNewXP.setNextControlPoint(nPointNum, basegfx::B2DPoint(aC2.X(), aC2.Y()));
|
|
}
|
|
|
|
aXPP.setB2DPolygon(nPolyNum, aNewXP);
|
|
}
|
|
}
|
|
|
|
pPath->SetPathPoly(aXPP);
|
|
}
|
|
}
|
|
|
|
|
|
static void ImpMove(Point& rPt, Point* pC1, Point* pC2, const void* p1, const void* /*p2*/, const void* /*p3*/, const void* /*p4*/)
|
|
{
|
|
rPt.Move(*static_cast<const Size*>(p1));
|
|
if (pC1!=nullptr) pC1->Move(*static_cast<const Size*>(p1));
|
|
if (pC2!=nullptr) pC2->Move(*static_cast<const Size*>(p1));
|
|
}
|
|
|
|
void SdrPolyEditView::MoveMarkedPoints(const Size& rSiz)
|
|
{
|
|
ForceUndirtyMrkPnt();
|
|
OUString aStr(SvxResId(STR_EditMove));
|
|
const SdrMarkList& rMarkList = GetMarkedObjectList();
|
|
BegUndo(aStr,rMarkList.GetPointMarkDescription(),SdrRepeatFunc::Move);
|
|
ImpTransformMarkedPoints(ImpMove,&rSiz);
|
|
EndUndo();
|
|
AdjustMarkHdl();
|
|
}
|
|
|
|
static void ImpResize(Point& rPt, Point* pC1, Point* pC2, const void* p1, const void* p2, const void* p3, const void* /*p4*/)
|
|
{
|
|
ResizePoint(rPt,*static_cast<const Point*>(p1),*static_cast<const Fraction*>(p2),*static_cast<const Fraction*>(p3));
|
|
if (pC1!=nullptr) ResizePoint(*pC1,*static_cast<const Point*>(p1),*static_cast<const Fraction*>(p2),*static_cast<const Fraction*>(p3));
|
|
if (pC2!=nullptr) ResizePoint(*pC2,*static_cast<const Point*>(p1),*static_cast<const Fraction*>(p2),*static_cast<const Fraction*>(p3));
|
|
}
|
|
|
|
void SdrPolyEditView::ResizeMarkedPoints(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
|
|
{
|
|
ForceUndirtyMrkPnt();
|
|
OUString aStr(SvxResId(STR_EditResize));
|
|
const SdrMarkList& rMarkList = GetMarkedObjectList();
|
|
BegUndo(aStr,rMarkList.GetPointMarkDescription(),SdrRepeatFunc::Resize);
|
|
ImpTransformMarkedPoints(ImpResize,&rRef,&xFact,&yFact);
|
|
EndUndo();
|
|
AdjustMarkHdl();
|
|
}
|
|
|
|
static void ImpRotate(Point& rPt, Point* pC1, Point* pC2, const void* p1, const void* /*p2*/, const void* p3, const void* p4)
|
|
{
|
|
RotatePoint(rPt,*static_cast<const Point*>(p1),*static_cast<const double*>(p3),*static_cast<const double*>(p4));
|
|
if (pC1!=nullptr) RotatePoint(*pC1,*static_cast<const Point*>(p1),*static_cast<const double*>(p3),*static_cast<const double*>(p4));
|
|
if (pC2!=nullptr) RotatePoint(*pC2,*static_cast<const Point*>(p1),*static_cast<const double*>(p3),*static_cast<const double*>(p4));
|
|
}
|
|
|
|
void SdrPolyEditView::RotateMarkedPoints(const Point& rRef, Degree100 nAngle)
|
|
{
|
|
ForceUndirtyMrkPnt();
|
|
OUString aStr(SvxResId(STR_EditResize));
|
|
const SdrMarkList& rMarkList = GetMarkedObjectList();
|
|
BegUndo(aStr,rMarkList.GetPointMarkDescription(),SdrRepeatFunc::Rotate);
|
|
double nSin = sin(toRadians(nAngle));
|
|
double nCos = cos(toRadians(nAngle));
|
|
ImpTransformMarkedPoints(ImpRotate,&rRef,&nAngle,&nSin,&nCos);
|
|
EndUndo();
|
|
AdjustMarkHdl();
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|