/src/libreoffice/svx/source/svdraw/svdglue.cxx
Line | Count | Source |
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 | | #include <tools/debug.hxx> |
21 | | #include <vcl/window.hxx> |
22 | | |
23 | | #include <svx/svdglue.hxx> |
24 | | #include <svx/svdobj.hxx> |
25 | | #include <svx/svdtrans.hxx> |
26 | | #include <comphelper/lok.hxx> |
27 | | |
28 | | const Size aGlueHalfSize(4,4); |
29 | | |
30 | | void SdrGluePoint::SetReallyAbsolute(bool bOn, const SdrObject& rObj) |
31 | 732k | { |
32 | 732k | if ( m_bReallyAbsolute == bOn ) |
33 | 366k | return; |
34 | | |
35 | 366k | if ( bOn ) |
36 | 366k | { |
37 | 366k | m_aPos=GetAbsolutePos(rObj); |
38 | 366k | m_bReallyAbsolute=bOn; |
39 | 366k | } |
40 | 0 | else |
41 | 0 | { |
42 | 0 | m_bReallyAbsolute=bOn; |
43 | 0 | Point aPt(m_aPos); |
44 | 0 | SetAbsolutePos(aPt,rObj); |
45 | 0 | } |
46 | 366k | } |
47 | | |
48 | | Point SdrGluePoint::GetAbsolutePos(const SdrObject& rObj) const |
49 | 732k | { |
50 | 732k | if (m_bReallyAbsolute) return m_aPos; |
51 | 732k | tools::Rectangle aSnap(rObj.GetSnapRect()); |
52 | 732k | tools::Rectangle aBound(rObj.GetSnapRect()); |
53 | 732k | Point aPt(m_aPos); |
54 | | |
55 | 732k | Point aOfs(aSnap.Center()); |
56 | 732k | switch (GetHorzAlign()) { |
57 | 732k | case SdrAlign::HORZ_LEFT : aOfs.setX(aSnap.Left() ); break; |
58 | 0 | case SdrAlign::HORZ_RIGHT : aOfs.setX(aSnap.Right() ); break; |
59 | 225 | default: break; |
60 | 732k | } |
61 | 732k | switch (GetVertAlign()) { |
62 | 732k | case SdrAlign::VERT_TOP : aOfs.setY(aSnap.Top() ); break; |
63 | 0 | case SdrAlign::VERT_BOTTOM: aOfs.setY(aSnap.Bottom() ); break; |
64 | 225 | default: break; |
65 | 732k | } |
66 | 732k | if (!m_bNoPercent) { |
67 | 0 | tools::Long nXMul=aSnap.Right()-aSnap.Left(); |
68 | 0 | tools::Long nYMul=aSnap.Bottom()-aSnap.Top(); |
69 | 0 | tools::Long nXDiv=10000; |
70 | 0 | tools::Long nYDiv=10000; |
71 | 0 | if (nXMul!=nXDiv) { |
72 | 0 | aPt.setX( aPt.X() * nXMul ); |
73 | 0 | aPt.setX( aPt.X() / nXDiv ); |
74 | 0 | } |
75 | 0 | if (nYMul!=nYDiv) { |
76 | 0 | aPt.setY( aPt.Y() * nYMul ); |
77 | 0 | aPt.setY( aPt.Y() / nYDiv ); |
78 | 0 | } |
79 | 0 | } |
80 | 732k | aPt+=aOfs; |
81 | | // Now limit to the BoundRect of the object |
82 | 732k | if (aPt.X()<aBound.Left ()) aPt.setX(aBound.Left () ); |
83 | 732k | if (aPt.X()>aBound.Right ()) aPt.setX(aBound.Right () ); |
84 | 732k | if (aPt.Y()<aBound.Top ()) aPt.setY(aBound.Top () ); |
85 | 732k | if (aPt.Y()>aBound.Bottom()) aPt.setY(aBound.Bottom() ); |
86 | 732k | return aPt; |
87 | 732k | } |
88 | | |
89 | | void SdrGluePoint::SetAbsolutePos(const Point& rNewPos, const SdrObject& rObj) |
90 | 366k | { |
91 | 366k | if (m_bReallyAbsolute) { |
92 | 0 | m_aPos=rNewPos; |
93 | 0 | return; |
94 | 0 | } |
95 | 366k | tools::Rectangle aSnap(rObj.GetSnapRect()); |
96 | 366k | Point aPt(rNewPos); |
97 | | |
98 | 366k | Point aOfs(aSnap.Center()); |
99 | 366k | switch (GetHorzAlign()) { |
100 | 315k | case SdrAlign::HORZ_LEFT : aOfs.setX(aSnap.Left() ); break; |
101 | 46.0k | case SdrAlign::HORZ_RIGHT : aOfs.setX(aSnap.Right() ); break; |
102 | 4.62k | default: break; |
103 | 366k | } |
104 | 366k | switch (GetVertAlign()) { |
105 | 233k | case SdrAlign::VERT_TOP : aOfs.setY(aSnap.Top() ); break; |
106 | 78.5k | case SdrAlign::VERT_BOTTOM: aOfs.setY(aSnap.Bottom() ); break; |
107 | 54.1k | default: break; |
108 | 366k | } |
109 | 366k | aPt-=aOfs; |
110 | 366k | if (!m_bNoPercent) { |
111 | 0 | tools::Long nXMul=aSnap.Right()-aSnap.Left(); |
112 | 0 | tools::Long nYMul=aSnap.Bottom()-aSnap.Top(); |
113 | 0 | if (nXMul==0) nXMul=1; |
114 | 0 | if (nYMul==0) nYMul=1; |
115 | 0 | tools::Long nXDiv=10000; |
116 | 0 | tools::Long nYDiv=10000; |
117 | 0 | if (nXMul!=nXDiv) { |
118 | 0 | aPt.setX( aPt.X() * nXDiv ); |
119 | 0 | aPt.setX( aPt.X() / nXMul ); |
120 | 0 | } |
121 | 0 | if (nYMul!=nYDiv) { |
122 | 0 | aPt.setY( aPt.Y() * nYDiv ); |
123 | 0 | aPt.setY( aPt.Y() / nYMul ); |
124 | 0 | } |
125 | 0 | } |
126 | 366k | m_aPos=aPt; |
127 | 366k | } |
128 | | |
129 | | Degree100 SdrGluePoint::GetAlignAngle() const |
130 | 366k | { |
131 | 366k | if (m_nAlign == (SdrAlign::HORZ_CENTER|SdrAlign::VERT_CENTER)) |
132 | 0 | return 0_deg100; // Invalid! |
133 | 366k | else if (m_nAlign == (SdrAlign::HORZ_RIGHT |SdrAlign::VERT_CENTER)) |
134 | 0 | return 0_deg100; |
135 | 366k | else if (m_nAlign == (SdrAlign::HORZ_RIGHT |SdrAlign::VERT_TOP)) |
136 | 0 | return 4500_deg100; |
137 | 366k | else if (m_nAlign == (SdrAlign::HORZ_CENTER|SdrAlign::VERT_TOP)) |
138 | 0 | return 9000_deg100; |
139 | 366k | else if (m_nAlign == (SdrAlign::HORZ_LEFT |SdrAlign::VERT_TOP)) |
140 | 366k | return 13500_deg100; |
141 | 0 | else if (m_nAlign == (SdrAlign::HORZ_LEFT |SdrAlign::VERT_CENTER)) |
142 | 0 | return 18000_deg100; |
143 | 0 | else if (m_nAlign == (SdrAlign::HORZ_LEFT |SdrAlign::VERT_BOTTOM)) |
144 | 0 | return 22500_deg100; |
145 | 0 | else if (m_nAlign == (SdrAlign::HORZ_CENTER|SdrAlign::VERT_BOTTOM)) |
146 | 0 | return 27000_deg100; |
147 | 0 | else if (m_nAlign == (SdrAlign::HORZ_RIGHT |SdrAlign::VERT_BOTTOM)) |
148 | 0 | return 31500_deg100; |
149 | 0 | return 0_deg100; |
150 | 366k | } |
151 | | |
152 | | void SdrGluePoint::SetAlignAngle(Degree100 nAngle) |
153 | 366k | { |
154 | 366k | nAngle=NormAngle36000(nAngle); |
155 | 366k | if (nAngle>=33750_deg100 || nAngle<2250_deg100) m_nAlign=SdrAlign::HORZ_RIGHT |SdrAlign::VERT_CENTER; |
156 | 365k | else if (nAngle< 6750_deg100) m_nAlign=SdrAlign::HORZ_RIGHT |SdrAlign::VERT_TOP ; |
157 | 324k | else if (nAngle<11250_deg100) m_nAlign=SdrAlign::HORZ_CENTER|SdrAlign::VERT_TOP ; |
158 | 321k | else if (nAngle<15750_deg100) m_nAlign=SdrAlign::HORZ_LEFT |SdrAlign::VERT_TOP ; |
159 | 132k | else if (nAngle<20250_deg100) m_nAlign=SdrAlign::HORZ_LEFT |SdrAlign::VERT_CENTER; |
160 | 78.5k | else if (nAngle<24750_deg100) m_nAlign=SdrAlign::HORZ_LEFT |SdrAlign::VERT_BOTTOM; |
161 | 5.58k | else if (nAngle<29250_deg100) m_nAlign=SdrAlign::HORZ_CENTER|SdrAlign::VERT_BOTTOM; |
162 | 4.84k | else if (nAngle<33750_deg100) m_nAlign=SdrAlign::HORZ_RIGHT |SdrAlign::VERT_BOTTOM; |
163 | 366k | } |
164 | | |
165 | | Degree100 SdrGluePoint::EscDirToAngle(SdrEscapeDirection nEsc) |
166 | 0 | { |
167 | 0 | switch (nEsc) { |
168 | 0 | case SdrEscapeDirection::RIGHT : return 0_deg100; |
169 | 0 | case SdrEscapeDirection::TOP : return 9000_deg100; |
170 | 0 | case SdrEscapeDirection::LEFT : return 18000_deg100; |
171 | 0 | case SdrEscapeDirection::BOTTOM: return 27000_deg100; |
172 | 0 | default: break; |
173 | 0 | } // switch |
174 | 0 | return 0_deg100; |
175 | 0 | } |
176 | | |
177 | | SdrEscapeDirection SdrGluePoint::EscAngleToDir(Degree100 nAngle) |
178 | 0 | { |
179 | 0 | nAngle=NormAngle36000(nAngle); |
180 | 0 | if (nAngle>=31500_deg100 || nAngle<4500_deg100) |
181 | 0 | return SdrEscapeDirection::RIGHT; |
182 | 0 | if (nAngle<13500_deg100) |
183 | 0 | return SdrEscapeDirection::TOP; |
184 | 0 | if (nAngle<22500_deg100) |
185 | 0 | return SdrEscapeDirection::LEFT; |
186 | | /* (nAngle<31500)*/ |
187 | 0 | return SdrEscapeDirection::BOTTOM; |
188 | 0 | } |
189 | | |
190 | | void SdrGluePoint::Rotate(const Point& rRef, Degree100 nAngle, double sn, double cs, const SdrObject* pObj) |
191 | 265k | { |
192 | 265k | Point aPt(pObj!=nullptr ? GetAbsolutePos(*pObj) : GetPos()); |
193 | 265k | RotatePoint(aPt,rRef,sn,cs); |
194 | | // rotate reference edge |
195 | 265k | if(m_nAlign != (SdrAlign::HORZ_CENTER|SdrAlign::VERT_CENTER)) |
196 | 265k | { |
197 | 265k | SetAlignAngle(GetAlignAngle()+nAngle); |
198 | 265k | } |
199 | | // rotate exit directions |
200 | 265k | SdrEscapeDirection nEscDir0=m_nEscDir; |
201 | 265k | SdrEscapeDirection nEscDir1=SdrEscapeDirection::SMART; |
202 | 265k | if (nEscDir0&SdrEscapeDirection::LEFT ) nEscDir1 |= EscAngleToDir(EscDirToAngle(SdrEscapeDirection::LEFT )+nAngle); |
203 | 265k | if (nEscDir0&SdrEscapeDirection::TOP ) nEscDir1 |= EscAngleToDir(EscDirToAngle(SdrEscapeDirection::TOP )+nAngle); |
204 | 265k | if (nEscDir0&SdrEscapeDirection::RIGHT ) nEscDir1 |= EscAngleToDir(EscDirToAngle(SdrEscapeDirection::RIGHT )+nAngle); |
205 | 265k | if (nEscDir0&SdrEscapeDirection::BOTTOM) nEscDir1 |= EscAngleToDir(EscDirToAngle(SdrEscapeDirection::BOTTOM)+nAngle); |
206 | 265k | m_nEscDir=nEscDir1; |
207 | 265k | if (pObj!=nullptr) SetAbsolutePos(aPt,*pObj); else SetPos(aPt); |
208 | 265k | } |
209 | | |
210 | | void SdrGluePoint::Mirror(const Point& rRef1, const Point& rRef2, Degree100 nAngle, const SdrObject* pObj) |
211 | 100k | { |
212 | 100k | Point aPt(pObj!=nullptr ? GetAbsolutePos(*pObj) : GetPos()); |
213 | 100k | MirrorPoint(aPt,rRef1,rRef2); |
214 | | // mirror reference edge |
215 | 100k | if(m_nAlign != (SdrAlign::HORZ_CENTER|SdrAlign::VERT_CENTER)) |
216 | 100k | { |
217 | 100k | Degree100 nAW=GetAlignAngle(); |
218 | 100k | nAW+=2_deg100*(nAngle-nAW); |
219 | 100k | SetAlignAngle(nAW); |
220 | 100k | } |
221 | | // mirror exit directions |
222 | 100k | SdrEscapeDirection nEscDir0=m_nEscDir; |
223 | 100k | SdrEscapeDirection nEscDir1=SdrEscapeDirection::SMART; |
224 | 100k | if (nEscDir0&SdrEscapeDirection::LEFT) { |
225 | 0 | Degree100 nEW=EscDirToAngle(SdrEscapeDirection::LEFT); |
226 | 0 | nEW+=2_deg100*(nAngle-nEW); |
227 | 0 | nEscDir1|=EscAngleToDir(nEW); |
228 | 0 | } |
229 | 100k | if (nEscDir0&SdrEscapeDirection::TOP) { |
230 | 0 | Degree100 nEW=EscDirToAngle(SdrEscapeDirection::TOP); |
231 | 0 | nEW+=2_deg100*(nAngle-nEW); |
232 | 0 | nEscDir1|=EscAngleToDir(nEW); |
233 | 0 | } |
234 | 100k | if (nEscDir0&SdrEscapeDirection::RIGHT) { |
235 | 0 | Degree100 nEW=EscDirToAngle(SdrEscapeDirection::RIGHT); |
236 | 0 | nEW+=2_deg100*(nAngle-nEW); |
237 | 0 | nEscDir1|=EscAngleToDir(nEW); |
238 | 0 | } |
239 | 100k | if (nEscDir0&SdrEscapeDirection::BOTTOM) { |
240 | 0 | Degree100 nEW=EscDirToAngle(SdrEscapeDirection::BOTTOM); |
241 | 0 | nEW+=2_deg100*(nAngle-nEW); |
242 | 0 | nEscDir1|=EscAngleToDir(nEW); |
243 | 0 | } |
244 | 100k | m_nEscDir=nEscDir1; |
245 | 100k | if (pObj!=nullptr) SetAbsolutePos(aPt,*pObj); else SetPos(aPt); |
246 | 100k | } |
247 | | |
248 | | void SdrGluePoint::Shear(const Point& rRef, double tn, bool bVShear, const SdrObject* pObj) |
249 | 0 | { |
250 | 0 | Point aPt(pObj!=nullptr ? GetAbsolutePos(*pObj) : GetPos()); |
251 | 0 | ShearPoint(aPt,rRef,tn,bVShear); |
252 | 0 | if (pObj!=nullptr) SetAbsolutePos(aPt,*pObj); else SetPos(aPt); |
253 | 0 | } |
254 | | |
255 | | void SdrGluePoint::Invalidate(vcl::Window& rWin, const SdrObject* pObj) const |
256 | 0 | { |
257 | 0 | if (comphelper::LibreOfficeKit::isActive()) |
258 | 0 | return; |
259 | 0 | bool bMapMode=rWin.IsMapModeEnabled(); |
260 | 0 | Point aPt(pObj!=nullptr ? GetAbsolutePos(*pObj) : GetPos()); |
261 | 0 | aPt=rWin.LogicToPixel(aPt); |
262 | 0 | rWin.EnableMapMode(false); |
263 | |
|
264 | 0 | Size aSiz( aGlueHalfSize ); |
265 | 0 | tools::Rectangle aRect(aPt.X()-aSiz.Width(),aPt.Y()-aSiz.Height(), |
266 | 0 | aPt.X()+aSiz.Width(),aPt.Y()+aSiz.Height()); |
267 | | |
268 | | // do not erase background, that causes flicker (!) |
269 | 0 | rWin.Invalidate(aRect, InvalidateFlags::NoErase); |
270 | |
|
271 | 0 | rWin.EnableMapMode(bMapMode); |
272 | 0 | } |
273 | | |
274 | | bool SdrGluePoint::IsHit(const Point& rPnt, const OutputDevice& rOut, const SdrObject* pObj) const |
275 | 0 | { |
276 | 0 | Point aPt(pObj!=nullptr ? GetAbsolutePos(*pObj) : GetPos()); |
277 | 0 | Size aSiz=rOut.PixelToLogic(aGlueHalfSize); |
278 | 0 | tools::Rectangle aRect(aPt.X()-aSiz.Width(),aPt.Y()-aSiz.Height(),aPt.X()+aSiz.Width(),aPt.Y()+aSiz.Height()); |
279 | 0 | return aRect.Contains(rPnt); |
280 | 0 | } |
281 | | |
282 | | |
283 | | SdrGluePointList& SdrGluePointList::operator=(const SdrGluePointList& rSrcList) |
284 | 45.0k | { |
285 | 45.0k | if (GetCount()!=0) m_aList.clear(); |
286 | 45.0k | sal_uInt16 nCount=rSrcList.GetCount(); |
287 | 2.24M | for (sal_uInt16 i=0; i<nCount; i++) { |
288 | 2.19M | Insert(rSrcList[i]); |
289 | 2.19M | } |
290 | 45.0k | return *this; |
291 | 45.0k | } |
292 | | |
293 | | // The ID's of the gluepoints always increase monotonously! |
294 | | // If an ID is taken already, the new gluepoint gets a new ID. ID 0 is reserved. |
295 | | sal_uInt16 SdrGluePointList::Insert(const SdrGluePoint& rGP) |
296 | 4.58M | { |
297 | 4.58M | SdrGluePoint aGP(rGP); |
298 | 4.58M | sal_uInt16 nId=aGP.GetId(); |
299 | 4.58M | sal_uInt16 nCount=GetCount(); |
300 | 4.58M | sal_uInt16 nInsPos=nCount; |
301 | 4.58M | sal_uInt16 nLastId=nCount!=0 ? m_aList[nCount-1].GetId() : 0; |
302 | 4.58M | DBG_ASSERT(nLastId>=nCount,"SdrGluePointList::Insert(): nLastId<nCount"); |
303 | 4.58M | bool bHole = nLastId>nCount; |
304 | 4.58M | if (nId<=nLastId) { |
305 | 189k | if (!bHole || nId==0) { |
306 | 189k | nId=nLastId+1; |
307 | 189k | } else { |
308 | 0 | bool bBrk = false; |
309 | 0 | for (sal_uInt16 nNum=0; nNum<nCount && !bBrk; nNum++) { |
310 | 0 | const auto& pGP2=m_aList[nNum]; |
311 | 0 | sal_uInt16 nTmpId=pGP2.GetId(); |
312 | 0 | if (nTmpId==nId) { |
313 | 0 | nId=nLastId+1; // already in use |
314 | 0 | bBrk = true; |
315 | 0 | } |
316 | 0 | if (nTmpId>nId) { |
317 | 0 | nInsPos=nNum; // insert here (sort) |
318 | 0 | bBrk = true; |
319 | 0 | } |
320 | 0 | } |
321 | 0 | } |
322 | 189k | aGP.SetId(nId); |
323 | 189k | } |
324 | 4.58M | m_aList.emplace(m_aList.begin()+nInsPos, aGP); |
325 | 4.58M | return nInsPos; |
326 | 4.58M | } |
327 | | |
328 | | void SdrGluePointList::Invalidate(vcl::Window& rWin, const SdrObject* pObj) const |
329 | 0 | { |
330 | 0 | if (comphelper::LibreOfficeKit::isActive()) |
331 | 0 | return; |
332 | 0 | for (auto& xGP : m_aList) |
333 | 0 | xGP.Invalidate(rWin,pObj); |
334 | 0 | } |
335 | | |
336 | | sal_uInt16 SdrGluePointList::FindGluePoint(sal_uInt16 nId) const |
337 | 303 | { |
338 | | // TODO: Implement a better search algorithm |
339 | | // List should be sorted at all times! |
340 | 303 | sal_uInt16 nCount=GetCount(); |
341 | 303 | sal_uInt16 nRet=SDRGLUEPOINT_NOTFOUND; |
342 | 957 | for (sal_uInt16 nNum=0; nNum<nCount && nRet==SDRGLUEPOINT_NOTFOUND; nNum++) { |
343 | 654 | const auto& pGP=m_aList[nNum]; |
344 | 654 | if (pGP.GetId()==nId) nRet=nNum; |
345 | 654 | } |
346 | 303 | return nRet; |
347 | 303 | } |
348 | | |
349 | | sal_uInt16 SdrGluePointList::HitTest(const Point& rPnt, const OutputDevice& rOut, const SdrObject* pObj) const |
350 | 0 | { |
351 | 0 | sal_uInt16 nCount = GetCount(); |
352 | 0 | sal_uInt16 nRet = SDRGLUEPOINT_NOTFOUND; |
353 | 0 | sal_uInt16 nNum = nCount; |
354 | 0 | while ((nNum>0) && nRet==SDRGLUEPOINT_NOTFOUND) { |
355 | 0 | nNum--; |
356 | 0 | const auto& pGP = m_aList[nNum]; |
357 | 0 | if (pGP.IsHit(rPnt,rOut,pObj)) |
358 | 0 | nRet = nNum; |
359 | 0 | } |
360 | 0 | return nRet; |
361 | 0 | } |
362 | | |
363 | | void SdrGluePointList::SetReallyAbsolute(bool bOn, const SdrObject& rObj) |
364 | 14.8k | { |
365 | 14.8k | for (auto& xGP : m_aList) |
366 | 732k | xGP.SetReallyAbsolute(bOn,rObj); |
367 | 14.8k | } |
368 | | |
369 | | void SdrGluePointList::Rotate(const Point& rRef, Degree100 nAngle, double sn, double cs, const SdrObject* pObj) |
370 | 5.27k | { |
371 | 5.27k | for (auto& xGP : m_aList) |
372 | 265k | xGP.Rotate(rRef,nAngle,sn,cs,pObj); |
373 | 5.27k | } |
374 | | |
375 | | void SdrGluePointList::Mirror(const Point& rRef1, const Point& rRef2, const SdrObject* pObj) |
376 | 2.13k | { |
377 | 2.13k | Point aPt(rRef2); aPt-=rRef1; |
378 | 2.13k | Degree100 nAngle=GetAngle(aPt); |
379 | 2.13k | Mirror(rRef1,rRef2,nAngle,pObj); |
380 | 2.13k | } |
381 | | |
382 | | void SdrGluePointList::Mirror(const Point& rRef1, const Point& rRef2, Degree100 nAngle, const SdrObject* pObj) |
383 | 2.13k | { |
384 | 2.13k | for (auto& xGP : m_aList) |
385 | 100k | xGP.Mirror(rRef1,rRef2,nAngle,pObj); |
386 | 2.13k | } |
387 | | |
388 | | void SdrGluePointList::Shear(const Point& rRef, double tn, bool bVShear, const SdrObject* pObj) |
389 | 0 | { |
390 | 0 | for (auto& xGP : m_aList) |
391 | 0 | xGP.Shear(rRef,tn,bVShear,pObj); |
392 | 0 | } |
393 | | |
394 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |