LibreOffice Module svx (master)  1
polypolygoneditor.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 
23 
25 
26 namespace sdr {
27 
29 : maPolyPolygon( rPolyPolygon )
30 {
31 }
32 
34 {
35  bool bPolyPolyChanged = false;
36 
37  auto aIter( rAbsPoints.rbegin() );
38  for( ; aIter != rAbsPoints.rend(); ++aIter )
39  {
40  sal_uInt32 nPoly, nPnt;
41  if( GetRelativePolyPoint(maPolyPolygon,(*aIter), nPoly, nPnt) )
42  {
43  // remove point
45 
46  aCandidate.remove(nPnt);
47 
48 
49  if( aCandidate.count() < 2 )
50  {
51  maPolyPolygon.remove(nPoly);
52  }
53  else
54  {
55  maPolyPolygon.setB2DPolygon(nPoly, aCandidate);
56  }
57 
58  bPolyPolyChanged = true;
59  }
60  }
61 
62  return bPolyPolyChanged;
63 }
64 
66 {
67  bool bPolyPolyChanged = false;
68 
69  auto aIter( rAbsPoints.rbegin() );
70  for( ; aIter != rAbsPoints.rend(); ++aIter )
71  {
72  sal_uInt32 nPolyNum, nPntNum;
73 
74  if(PolyPolygonEditor::GetRelativePolyPoint(maPolyPolygon, (*aIter), nPolyNum, nPntNum))
75  {
76  // do change at aNewPolyPolygon. Take a look at edge.
77  basegfx::B2DPolygon aCandidate(maPolyPolygon.getB2DPolygon(nPolyNum));
78  const sal_uInt32 nCount(aCandidate.count());
79 
80  if(nCount && (nPntNum + 1 < nCount || aCandidate.isClosed()))
81  {
82  bool bCandidateChanged(false);
83 
84  // it's a valid edge, check control point usage
85  const sal_uInt32 nNextIndex((nPntNum + 1) % nCount);
86  const bool bContolUsed(aCandidate.areControlPointsUsed()
87  && (aCandidate.isNextControlPointUsed(nPntNum) || aCandidate.isPrevControlPointUsed(nNextIndex)));
88 
89  if(bContolUsed)
90  {
92  {
93  // remove control
94  aCandidate.resetNextControlPoint(nPntNum);
95  aCandidate.resetPrevControlPoint(nNextIndex);
96  bCandidateChanged = true;
97  }
98  }
99  else
100  {
102  {
103  // add control
104  const basegfx::B2DPoint aStart(aCandidate.getB2DPoint(nPntNum));
105  const basegfx::B2DPoint aEnd(aCandidate.getB2DPoint(nNextIndex));
106 
107  aCandidate.setNextControlPoint(nPntNum, interpolate(aStart, aEnd, (1.0 / 3.0)));
108  aCandidate.setPrevControlPoint(nNextIndex, interpolate(aStart, aEnd, (2.0 / 3.0)));
109  bCandidateChanged = true;
110  }
111  }
112 
113  if(bCandidateChanged)
114  {
115  maPolyPolygon.setB2DPolygon(nPolyNum, aCandidate);
116  bPolyPolyChanged = true;
117  }
118  }
119  }
120  }
121 
122  return bPolyPolyChanged;
123 }
124 
126 {
127  bool bPolyPolygonChanged(false);
128 
129  auto aIter( rAbsPoints.rbegin() );
130  for( ; aIter != rAbsPoints.rend(); ++aIter )
131  {
132  sal_uInt32 nPolyNum, nPntNum;
133 
134  if(PolyPolygonEditor::GetRelativePolyPoint(maPolyPolygon, (*aIter), nPolyNum, nPntNum))
135  {
136  // do change at aNewPolyPolygon...
137  basegfx::B2DPolygon aCandidate(maPolyPolygon.getB2DPolygon(nPolyNum));
138 
139  // set continuity in point, make sure there is a curve
140  bool bPolygonChanged = basegfx::utils::expandToCurveInPoint(aCandidate, nPntNum);
141  bPolygonChanged |= basegfx::utils::setContinuityInPoint(aCandidate, nPntNum, eFlags);
142 
143  if(bPolygonChanged)
144  {
145  maPolyPolygon.setB2DPolygon(nPolyNum, aCandidate);
146  bPolyPolygonChanged = true;
147  }
148  }
149  }
150 
151  return bPolyPolygonChanged;
152 }
153 
154 bool PolyPolygonEditor::GetRelativePolyPoint( const basegfx::B2DPolyPolygon& rPoly, sal_uInt32 nAbsPnt, sal_uInt32& rPolyNum, sal_uInt32& rPointNum )
155 {
156  const sal_uInt32 nPolyCount(rPoly.count());
157  sal_uInt32 nPolyNum(0);
158 
159  while(nPolyNum < nPolyCount)
160  {
161  const sal_uInt32 nPointCount(rPoly.getB2DPolygon(nPolyNum).count());
162 
163  if(nAbsPnt < nPointCount)
164  {
165  rPolyNum = nPolyNum;
166  rPointNum = nAbsPnt;
167 
168  return true;
169  }
170  else
171  {
172  nPolyNum++;
173  nAbsPnt -= nPointCount;
174  }
175  }
176 
177  return false;
178 }
179 
180 } // end of namespace sdr
181 
182 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void remove(sal_uInt32 nIndex, sal_uInt32 nCount=1)
bool setContinuityInPoint(B2DPolygon &rCandidate, sal_uInt32 nIndex, B2VectorContinuity eContinuity)
PolyPolygonEditor(const basegfx::B2DPolyPolygon &rPolyPolygon)
void setB2DPolygon(sal_uInt32 nIndex, const B2DPolygon &rPolygon)
HSLColor interpolate(const HSLColor &rFrom, const HSLColor &rTo, double t, bool bCCW)
B2DPolygon const & getB2DPolygon(sal_uInt32 nIndex) const
basegfx::B2DPolyPolygon maPolyPolygon
B2VectorContinuity
int nCount
bool DeletePoints(const o3tl::sorted_vector< sal_uInt16 > &rAbsPoints)
returns true if the B2DPolyPolygon was changed.
bool SetPointsSmooth(basegfx::B2VectorContinuity eFlags, const o3tl::sorted_vector< sal_uInt16 > &rAbsPoints)
returns true if the B2DPolyPolygon was changed.
static bool GetRelativePolyPoint(const basegfx::B2DPolyPolygon &rPoly, sal_uInt32 nAbsPnt, sal_uInt32 &rPolyNum, sal_uInt32 &rPointNum)
Outputs the relative position ( polygon number and point number in that polygon ) from the absolute p...
bool expandToCurveInPoint(B2DPolygon &rCandidate, sal_uInt32 nIndex)
void remove(sal_uInt32 nIndex, sal_uInt32 nCount=1)
bool SetSegmentsKind(SdrPathSegmentKind eKind, const o3tl::sorted_vector< sal_uInt16 > &rAbsPoints)
returns true if the B2DPolyPolygon was changed.
const_reverse_iterator rend() const
const_reverse_iterator rbegin() const
sal_uInt32 count() const
basegfx::B2DPolyPolygon maPolyPolygon
sal_uInt32 count() const