1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_svx.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygon.hxx> 32*cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygontools.hxx> 33*cdf0e10cSrcweir 34*cdf0e10cSrcweir #include "svx/polypolygoneditor.hxx" 35*cdf0e10cSrcweir 36*cdf0e10cSrcweir namespace sdr { 37*cdf0e10cSrcweir 38*cdf0e10cSrcweir PolyPolygonEditor::PolyPolygonEditor( const basegfx::B2DPolyPolygon& rPolyPolygon, bool bClosed ) 39*cdf0e10cSrcweir : maPolyPolygon( rPolyPolygon ) 40*cdf0e10cSrcweir , mbIsClosed( bClosed ) 41*cdf0e10cSrcweir { 42*cdf0e10cSrcweir } 43*cdf0e10cSrcweir 44*cdf0e10cSrcweir bool PolyPolygonEditor::DeletePoints( const std::set< sal_uInt16 >& rAbsPoints ) 45*cdf0e10cSrcweir { 46*cdf0e10cSrcweir bool bPolyPolyChanged = false; 47*cdf0e10cSrcweir 48*cdf0e10cSrcweir std::set< sal_uInt16 >::const_reverse_iterator aIter;( rAbsPoints.rbegin() ); 49*cdf0e10cSrcweir for( aIter = rAbsPoints.rbegin(); aIter != rAbsPoints.rend(); aIter++ ) 50*cdf0e10cSrcweir { 51*cdf0e10cSrcweir sal_uInt32 nPoly, nPnt; 52*cdf0e10cSrcweir if( GetRelativePolyPoint(maPolyPolygon,(*aIter), nPoly, nPnt) ) 53*cdf0e10cSrcweir { 54*cdf0e10cSrcweir // remove point 55*cdf0e10cSrcweir basegfx::B2DPolygon aCandidate(maPolyPolygon.getB2DPolygon(nPoly)); 56*cdf0e10cSrcweir 57*cdf0e10cSrcweir aCandidate.remove(nPnt); 58*cdf0e10cSrcweir 59*cdf0e10cSrcweir if( ( mbIsClosed && aCandidate.count() < 3L) || (aCandidate.count() < 2L) ) 60*cdf0e10cSrcweir { 61*cdf0e10cSrcweir maPolyPolygon.remove(nPoly); 62*cdf0e10cSrcweir } 63*cdf0e10cSrcweir else 64*cdf0e10cSrcweir { 65*cdf0e10cSrcweir maPolyPolygon.setB2DPolygon(nPoly, aCandidate); 66*cdf0e10cSrcweir } 67*cdf0e10cSrcweir 68*cdf0e10cSrcweir bPolyPolyChanged = true; 69*cdf0e10cSrcweir } 70*cdf0e10cSrcweir } 71*cdf0e10cSrcweir 72*cdf0e10cSrcweir return bPolyPolyChanged; 73*cdf0e10cSrcweir } 74*cdf0e10cSrcweir 75*cdf0e10cSrcweir bool PolyPolygonEditor::SetSegmentsKind(SdrPathSegmentKind eKind, const std::set< sal_uInt16 >& rAbsPoints ) 76*cdf0e10cSrcweir { 77*cdf0e10cSrcweir bool bPolyPolyChanged = false; 78*cdf0e10cSrcweir 79*cdf0e10cSrcweir std::set< sal_uInt16 >::const_reverse_iterator aIter;( rAbsPoints.rbegin() ); 80*cdf0e10cSrcweir for( aIter = rAbsPoints.rbegin(); aIter != rAbsPoints.rend(); aIter++ ) 81*cdf0e10cSrcweir { 82*cdf0e10cSrcweir sal_uInt32 nPolyNum, nPntNum; 83*cdf0e10cSrcweir 84*cdf0e10cSrcweir if(PolyPolygonEditor::GetRelativePolyPoint(maPolyPolygon, (*aIter), nPolyNum, nPntNum)) 85*cdf0e10cSrcweir { 86*cdf0e10cSrcweir // do change at aNewPolyPolygon. Take a look at edge. 87*cdf0e10cSrcweir basegfx::B2DPolygon aCandidate(maPolyPolygon.getB2DPolygon(nPolyNum)); 88*cdf0e10cSrcweir bool bCandidateChanged(false); 89*cdf0e10cSrcweir const sal_uInt32 nCount(aCandidate.count()); 90*cdf0e10cSrcweir 91*cdf0e10cSrcweir if(nCount && (nPntNum + 1 < nCount || aCandidate.isClosed())) 92*cdf0e10cSrcweir { 93*cdf0e10cSrcweir // it's a valid edge, check control point usage 94*cdf0e10cSrcweir const sal_uInt32 nNextIndex((nPntNum + 1) % nCount); 95*cdf0e10cSrcweir const bool bContolUsed(aCandidate.areControlPointsUsed() 96*cdf0e10cSrcweir && (aCandidate.isNextControlPointUsed(nPntNum) || aCandidate.isPrevControlPointUsed(nNextIndex))); 97*cdf0e10cSrcweir 98*cdf0e10cSrcweir if(bContolUsed) 99*cdf0e10cSrcweir { 100*cdf0e10cSrcweir if(SDRPATHSEGMENT_TOGGLE == eKind || SDRPATHSEGMENT_LINE == eKind) 101*cdf0e10cSrcweir { 102*cdf0e10cSrcweir // remove control 103*cdf0e10cSrcweir aCandidate.resetNextControlPoint(nPntNum); 104*cdf0e10cSrcweir aCandidate.resetPrevControlPoint(nNextIndex); 105*cdf0e10cSrcweir bCandidateChanged = true; 106*cdf0e10cSrcweir } 107*cdf0e10cSrcweir } 108*cdf0e10cSrcweir else 109*cdf0e10cSrcweir { 110*cdf0e10cSrcweir if(SDRPATHSEGMENT_TOGGLE == eKind || SDRPATHSEGMENT_CURVE == eKind) 111*cdf0e10cSrcweir { 112*cdf0e10cSrcweir // add control 113*cdf0e10cSrcweir const basegfx::B2DPoint aStart(aCandidate.getB2DPoint(nPntNum)); 114*cdf0e10cSrcweir const basegfx::B2DPoint aEnd(aCandidate.getB2DPoint(nNextIndex)); 115*cdf0e10cSrcweir 116*cdf0e10cSrcweir aCandidate.setNextControlPoint(nPntNum, interpolate(aStart, aEnd, (1.0 / 3.0))); 117*cdf0e10cSrcweir aCandidate.setPrevControlPoint(nNextIndex, interpolate(aStart, aEnd, (2.0 / 3.0))); 118*cdf0e10cSrcweir bCandidateChanged = true; 119*cdf0e10cSrcweir } 120*cdf0e10cSrcweir } 121*cdf0e10cSrcweir 122*cdf0e10cSrcweir if(bCandidateChanged) 123*cdf0e10cSrcweir { 124*cdf0e10cSrcweir maPolyPolygon.setB2DPolygon(nPolyNum, aCandidate); 125*cdf0e10cSrcweir bPolyPolyChanged = true; 126*cdf0e10cSrcweir } 127*cdf0e10cSrcweir } 128*cdf0e10cSrcweir } 129*cdf0e10cSrcweir } 130*cdf0e10cSrcweir 131*cdf0e10cSrcweir return bPolyPolyChanged; 132*cdf0e10cSrcweir } 133*cdf0e10cSrcweir 134*cdf0e10cSrcweir bool PolyPolygonEditor::SetPointsSmooth( basegfx::B2VectorContinuity eFlags, const std::set< sal_uInt16 >& rAbsPoints) 135*cdf0e10cSrcweir { 136*cdf0e10cSrcweir bool bPolyPolygonChanged(false); 137*cdf0e10cSrcweir 138*cdf0e10cSrcweir std::set< sal_uInt16 >::const_reverse_iterator aIter;( rAbsPoints.rbegin() ); 139*cdf0e10cSrcweir for( aIter = rAbsPoints.rbegin(); aIter != rAbsPoints.rend(); aIter++ ) 140*cdf0e10cSrcweir { 141*cdf0e10cSrcweir sal_uInt32 nPolyNum, nPntNum; 142*cdf0e10cSrcweir 143*cdf0e10cSrcweir if(PolyPolygonEditor::GetRelativePolyPoint(maPolyPolygon, (*aIter), nPolyNum, nPntNum)) 144*cdf0e10cSrcweir { 145*cdf0e10cSrcweir // do change at aNewPolyPolygon... 146*cdf0e10cSrcweir basegfx::B2DPolygon aCandidate(maPolyPolygon.getB2DPolygon(nPolyNum)); 147*cdf0e10cSrcweir 148*cdf0e10cSrcweir // set continuity in point, make sure there is a curve 149*cdf0e10cSrcweir bool bPolygonChanged(false); 150*cdf0e10cSrcweir bPolygonChanged = basegfx::tools::expandToCurveInPoint(aCandidate, nPntNum); 151*cdf0e10cSrcweir bPolygonChanged |= basegfx::tools::setContinuityInPoint(aCandidate, nPntNum, eFlags); 152*cdf0e10cSrcweir 153*cdf0e10cSrcweir if(bPolygonChanged) 154*cdf0e10cSrcweir { 155*cdf0e10cSrcweir maPolyPolygon.setB2DPolygon(nPolyNum, aCandidate); 156*cdf0e10cSrcweir bPolyPolygonChanged = true; 157*cdf0e10cSrcweir } 158*cdf0e10cSrcweir } 159*cdf0e10cSrcweir } 160*cdf0e10cSrcweir 161*cdf0e10cSrcweir return bPolyPolygonChanged; 162*cdf0e10cSrcweir } 163*cdf0e10cSrcweir 164*cdf0e10cSrcweir bool PolyPolygonEditor::GetRelativePolyPoint( const basegfx::B2DPolyPolygon& rPoly, sal_uInt32 nAbsPnt, sal_uInt32& rPolyNum, sal_uInt32& rPointNum ) 165*cdf0e10cSrcweir { 166*cdf0e10cSrcweir const sal_uInt32 nPolyCount(rPoly.count()); 167*cdf0e10cSrcweir sal_uInt32 nPolyNum(0L); 168*cdf0e10cSrcweir 169*cdf0e10cSrcweir while(nPolyNum < nPolyCount) 170*cdf0e10cSrcweir { 171*cdf0e10cSrcweir const sal_uInt32 nPointCount(rPoly.getB2DPolygon(nPolyNum).count()); 172*cdf0e10cSrcweir 173*cdf0e10cSrcweir if(nAbsPnt < nPointCount) 174*cdf0e10cSrcweir { 175*cdf0e10cSrcweir rPolyNum = nPolyNum; 176*cdf0e10cSrcweir rPointNum = nAbsPnt; 177*cdf0e10cSrcweir 178*cdf0e10cSrcweir return true; 179*cdf0e10cSrcweir } 180*cdf0e10cSrcweir else 181*cdf0e10cSrcweir { 182*cdf0e10cSrcweir nPolyNum++; 183*cdf0e10cSrcweir nAbsPnt -= nPointCount; 184*cdf0e10cSrcweir } 185*cdf0e10cSrcweir } 186*cdf0e10cSrcweir 187*cdf0e10cSrcweir return false; 188*cdf0e10cSrcweir } 189*cdf0e10cSrcweir 190*cdf0e10cSrcweir } // end of namespace sdr 191