1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_basegfx.hxx"
26 #include <osl/diagnose.h>
27 #include <basegfx/polygon/b3dpolypolygon.hxx>
28 #include <basegfx/polygon/b3dpolygon.hxx>
29 #include <rtl/instance.hxx>
30 #include <basegfx/matrix/b2dhommatrix.hxx>
31 #include <basegfx/matrix/b3dhommatrix.hxx>
32 #include <functional>
33 #include <vector>
34 #include <algorithm>
35 
36 //////////////////////////////////////////////////////////////////////////////
37 
38 class ImplB3DPolyPolygon
39 {
40 	typedef ::std::vector< ::basegfx::B3DPolygon >	PolygonVector;
41 
42 	PolygonVector									maPolygons;
43 
44 public:
ImplB3DPolyPolygon()45 	ImplB3DPolyPolygon() : maPolygons()
46     {
47     }
48 
ImplB3DPolyPolygon(const::basegfx::B3DPolygon & rToBeCopied)49 	ImplB3DPolyPolygon(const ::basegfx::B3DPolygon& rToBeCopied) :
50         maPolygons(1,rToBeCopied)
51 	{
52 	}
53 
operator ==(const ImplB3DPolyPolygon & rPolygonList) const54 	bool operator==(const ImplB3DPolyPolygon& rPolygonList) const
55 	{
56 		// same polygon count?
57 		if(maPolygons.size() != rPolygonList.maPolygons.size())
58 			return false;
59 
60 		// compare polygon content
61 		if(maPolygons != rPolygonList.maPolygons)
62 			return false;
63 
64 		return true;
65 	}
66 
getB3DPolygon(sal_uInt32 nIndex) const67 	const ::basegfx::B3DPolygon& getB3DPolygon(sal_uInt32 nIndex) const
68 	{
69 		return maPolygons[nIndex];
70 	}
71 
setB3DPolygon(sal_uInt32 nIndex,const::basegfx::B3DPolygon & rPolygon)72 	void setB3DPolygon(sal_uInt32 nIndex, const ::basegfx::B3DPolygon& rPolygon)
73 	{
74 		maPolygons[nIndex] = rPolygon;
75 	}
76 
insert(sal_uInt32 nIndex,const::basegfx::B3DPolygon & rPolygon,sal_uInt32 nCount)77 	void insert(sal_uInt32 nIndex, const ::basegfx::B3DPolygon& rPolygon, sal_uInt32 nCount)
78 	{
79 		if(nCount)
80 		{
81 			// add nCount copies of rPolygon
82 			PolygonVector::iterator aIndex(maPolygons.begin());
83 			aIndex += nIndex;
84 			maPolygons.insert(aIndex, nCount, rPolygon);
85 		}
86 	}
87 
insert(sal_uInt32 nIndex,const::basegfx::B3DPolyPolygon & rPolyPolygon)88 	void insert(sal_uInt32 nIndex, const ::basegfx::B3DPolyPolygon& rPolyPolygon)
89 	{
90 		const sal_uInt32 nCount = rPolyPolygon.count();
91 
92 		if(nCount)
93 		{
94 			// add nCount polygons from rPolyPolygon
95 			maPolygons.reserve(maPolygons.size() + nCount);
96 			PolygonVector::iterator aIndex(maPolygons.begin());
97 			aIndex += nIndex;
98 
99 			for(sal_uInt32 a(0L); a < nCount; a++)
100 			{
101 				maPolygons.insert(aIndex, rPolyPolygon.getB3DPolygon(a));
102 				aIndex++;
103 			}
104 		}
105 	}
106 
remove(sal_uInt32 nIndex,sal_uInt32 nCount)107 	void remove(sal_uInt32 nIndex, sal_uInt32 nCount)
108 	{
109 		if(nCount)
110 		{
111 			// remove polygon data
112 			PolygonVector::iterator aStart(maPolygons.begin());
113 			aStart += nIndex;
114 			const PolygonVector::iterator aEnd(aStart + nCount);
115 
116 			maPolygons.erase(aStart, aEnd);
117 		}
118 	}
119 
count() const120 	sal_uInt32 count() const
121 	{
122 		return maPolygons.size();
123 	}
124 
setClosed(bool bNew)125 	void setClosed(bool bNew)
126 	{
127 		for(sal_uInt32 a(0L); a < maPolygons.size(); a++)
128 		{
129 			maPolygons[a].setClosed(bNew);
130 		}
131 	}
132 
flip()133 	void flip()
134 	{
135         std::for_each( maPolygons.begin(),
136                        maPolygons.end(),
137                        std::mem_fun_ref( &::basegfx::B3DPolygon::flip ));
138 	}
139 
removeDoublePoints()140 	void removeDoublePoints()
141 	{
142         std::for_each( maPolygons.begin(),
143                        maPolygons.end(),
144                        std::mem_fun_ref( &::basegfx::B3DPolygon::removeDoublePoints ));
145 	}
146 
transform(const::basegfx::B3DHomMatrix & rMatrix)147 	void transform(const ::basegfx::B3DHomMatrix& rMatrix)
148 	{
149 		for(sal_uInt32 a(0L); a < maPolygons.size(); a++)
150 		{
151 			maPolygons[a].transform(rMatrix);
152 		}
153 	}
154 
clearBColors()155 	void clearBColors()
156 	{
157 		for(sal_uInt32 a(0L); a < maPolygons.size(); a++)
158 		{
159 			maPolygons[a].clearBColors();
160 		}
161 	}
162 
transformNormals(const::basegfx::B3DHomMatrix & rMatrix)163 	void transformNormals(const ::basegfx::B3DHomMatrix& rMatrix)
164 	{
165 		for(sal_uInt32 a(0L); a < maPolygons.size(); a++)
166 		{
167 			maPolygons[a].transformNormals(rMatrix);
168 		}
169 	}
170 
clearNormals()171 	void clearNormals()
172 	{
173 		for(sal_uInt32 a(0L); a < maPolygons.size(); a++)
174 		{
175 			maPolygons[a].clearNormals();
176 		}
177 	}
178 
transformTextureCoordiantes(const::basegfx::B2DHomMatrix & rMatrix)179 	void transformTextureCoordiantes(const ::basegfx::B2DHomMatrix& rMatrix)
180 	{
181 		for(sal_uInt32 a(0L); a < maPolygons.size(); a++)
182 		{
183 			maPolygons[a].transformTextureCoordiantes(rMatrix);
184 		}
185 	}
186 
clearTextureCoordinates()187 	void clearTextureCoordinates()
188 	{
189 		for(sal_uInt32 a(0L); a < maPolygons.size(); a++)
190 		{
191 			maPolygons[a].clearTextureCoordinates();
192 		}
193 	}
194 
makeUnique()195     void makeUnique()
196     {
197         std::for_each( maPolygons.begin(),
198                        maPolygons.end(),
199                        std::mem_fun_ref( &::basegfx::B3DPolygon::makeUnique ));
200     }
201 };
202 
203 //////////////////////////////////////////////////////////////////////////////
204 
205 namespace basegfx
206 {
207     namespace { struct DefaultPolyPolygon : public rtl::Static<B3DPolyPolygon::ImplType,
208                                                                DefaultPolyPolygon> {}; }
209 
B3DPolyPolygon()210 	B3DPolyPolygon::B3DPolyPolygon() :
211         mpPolyPolygon(DefaultPolyPolygon::get())
212 	{
213 	}
214 
B3DPolyPolygon(const B3DPolyPolygon & rPolyPolygon)215 	B3DPolyPolygon::B3DPolyPolygon(const B3DPolyPolygon& rPolyPolygon) :
216         mpPolyPolygon(rPolyPolygon.mpPolyPolygon)
217 	{
218 	}
219 
B3DPolyPolygon(const B3DPolygon & rPolygon)220 	B3DPolyPolygon::B3DPolyPolygon(const B3DPolygon& rPolygon) :
221         mpPolyPolygon( ImplB3DPolyPolygon(rPolygon) )
222 	{
223 	}
224 
~B3DPolyPolygon()225 	B3DPolyPolygon::~B3DPolyPolygon()
226 	{
227 	}
228 
operator =(const B3DPolyPolygon & rPolyPolygon)229 	B3DPolyPolygon& B3DPolyPolygon::operator=(const B3DPolyPolygon& rPolyPolygon)
230 	{
231 		mpPolyPolygon = rPolyPolygon.mpPolyPolygon;
232 		return *this;
233 	}
234 
makeUnique()235     void B3DPolyPolygon::makeUnique()
236     {
237         mpPolyPolygon.make_unique();
238         mpPolyPolygon->makeUnique();
239     }
240 
operator ==(const B3DPolyPolygon & rPolyPolygon) const241 	bool B3DPolyPolygon::operator==(const B3DPolyPolygon& rPolyPolygon) const
242 	{
243 		if(mpPolyPolygon.same_object(rPolyPolygon.mpPolyPolygon))
244 			return true;
245 
246 		return ((*mpPolyPolygon) == (*rPolyPolygon.mpPolyPolygon));
247 	}
248 
operator !=(const B3DPolyPolygon & rPolyPolygon) const249 	bool B3DPolyPolygon::operator!=(const B3DPolyPolygon& rPolyPolygon) const
250 	{
251         return !(*this == rPolyPolygon);
252 	}
253 
count() const254 	sal_uInt32 B3DPolyPolygon::count() const
255 	{
256 		return mpPolyPolygon->count();
257 	}
258 
getB3DPolygon(sal_uInt32 nIndex) const259 	B3DPolygon B3DPolyPolygon::getB3DPolygon(sal_uInt32 nIndex) const
260 	{
261 		OSL_ENSURE(nIndex < mpPolyPolygon->count(), "B3DPolyPolygon access outside range (!)");
262 
263 		return mpPolyPolygon->getB3DPolygon(nIndex);
264 	}
265 
setB3DPolygon(sal_uInt32 nIndex,const B3DPolygon & rPolygon)266 	void B3DPolyPolygon::setB3DPolygon(sal_uInt32 nIndex, const B3DPolygon& rPolygon)
267 	{
268 		OSL_ENSURE(nIndex < mpPolyPolygon->count(), "B3DPolyPolygon access outside range (!)");
269 
270 		if(getB3DPolygon(nIndex) != rPolygon)
271 			mpPolyPolygon->setB3DPolygon(nIndex, rPolygon);
272 	}
273 
areBColorsUsed() const274 	bool B3DPolyPolygon::areBColorsUsed() const
275 	{
276 		for(sal_uInt32 a(0L); a < mpPolyPolygon->count(); a++)
277 		{
278 			if((mpPolyPolygon->getB3DPolygon(a)).areBColorsUsed())
279 			{
280 				return true;
281 			}
282 		}
283 
284 		return false;
285 	}
286 
clearBColors()287 	void B3DPolyPolygon::clearBColors()
288 	{
289 		if(areBColorsUsed())
290 			mpPolyPolygon->clearBColors();
291 	}
292 
transformNormals(const B3DHomMatrix & rMatrix)293 	void B3DPolyPolygon::transformNormals(const B3DHomMatrix& rMatrix)
294 	{
295 		if(!rMatrix.isIdentity())
296 			mpPolyPolygon->transformNormals(rMatrix);
297 	}
298 
areNormalsUsed() const299 	bool B3DPolyPolygon::areNormalsUsed() const
300 	{
301 		for(sal_uInt32 a(0L); a < mpPolyPolygon->count(); a++)
302 		{
303 			if((mpPolyPolygon->getB3DPolygon(a)).areNormalsUsed())
304 			{
305 				return true;
306 			}
307 		}
308 
309 		return false;
310 	}
311 
clearNormals()312 	void B3DPolyPolygon::clearNormals()
313 	{
314 		if(areNormalsUsed())
315 			mpPolyPolygon->clearNormals();
316 	}
317 
transformTextureCoordiantes(const B2DHomMatrix & rMatrix)318 	void B3DPolyPolygon::transformTextureCoordiantes(const B2DHomMatrix& rMatrix)
319 	{
320 		if(!rMatrix.isIdentity())
321 			mpPolyPolygon->transformTextureCoordiantes(rMatrix);
322 	}
323 
areTextureCoordinatesUsed() const324 	bool B3DPolyPolygon::areTextureCoordinatesUsed() const
325 	{
326 		for(sal_uInt32 a(0L); a < mpPolyPolygon->count(); a++)
327 		{
328 			if((mpPolyPolygon->getB3DPolygon(a)).areTextureCoordinatesUsed())
329 			{
330 				return true;
331 			}
332 		}
333 
334 		return false;
335 	}
336 
clearTextureCoordinates()337 	void B3DPolyPolygon::clearTextureCoordinates()
338 	{
339 		if(areTextureCoordinatesUsed())
340 			mpPolyPolygon->clearTextureCoordinates();
341 	}
342 
insert(sal_uInt32 nIndex,const B3DPolygon & rPolygon,sal_uInt32 nCount)343 	void B3DPolyPolygon::insert(sal_uInt32 nIndex, const B3DPolygon& rPolygon, sal_uInt32 nCount)
344 	{
345 		OSL_ENSURE(nIndex <= mpPolyPolygon->count(), "B3DPolyPolygon Insert outside range (!)");
346 
347 		if(nCount)
348 			mpPolyPolygon->insert(nIndex, rPolygon, nCount);
349 	}
350 
append(const B3DPolygon & rPolygon,sal_uInt32 nCount)351 	void B3DPolyPolygon::append(const B3DPolygon& rPolygon, sal_uInt32 nCount)
352 	{
353 		if(nCount)
354 			mpPolyPolygon->insert(mpPolyPolygon->count(), rPolygon, nCount);
355 	}
356 
insert(sal_uInt32 nIndex,const B3DPolyPolygon & rPolyPolygon)357 	void B3DPolyPolygon::insert(sal_uInt32 nIndex, const B3DPolyPolygon& rPolyPolygon)
358 	{
359 		OSL_ENSURE(nIndex <= mpPolyPolygon->count(), "B3DPolyPolygon Insert outside range (!)");
360 
361 		if(rPolyPolygon.count())
362 			mpPolyPolygon->insert(nIndex, rPolyPolygon);
363 	}
364 
append(const B3DPolyPolygon & rPolyPolygon)365 	void B3DPolyPolygon::append(const B3DPolyPolygon& rPolyPolygon)
366 	{
367 		if(rPolyPolygon.count())
368 			mpPolyPolygon->insert(mpPolyPolygon->count(), rPolyPolygon);
369 	}
370 
remove(sal_uInt32 nIndex,sal_uInt32 nCount)371 	void B3DPolyPolygon::remove(sal_uInt32 nIndex, sal_uInt32 nCount)
372 	{
373 		OSL_ENSURE(nIndex + nCount <= mpPolyPolygon->count(), "B3DPolyPolygon Remove outside range (!)");
374 
375 		if(nCount)
376 			mpPolyPolygon->remove(nIndex, nCount);
377 	}
378 
clear()379 	void B3DPolyPolygon::clear()
380 	{
381 		mpPolyPolygon = DefaultPolyPolygon::get();
382 	}
383 
isClosed() const384 	bool B3DPolyPolygon::isClosed() const
385 	{
386 		bool bRetval(true);
387 
388 		// PolyPOlygon is closed when all contained Polygons are closed or
389 		// no Polygon exists.
390 		for(sal_uInt32 a(0L); bRetval && a < mpPolyPolygon->count(); a++)
391 		{
392 			if(!(mpPolyPolygon->getB3DPolygon(a)).isClosed())
393 			{
394 				bRetval = false;
395 			}
396 		}
397 
398 		return bRetval;
399 	}
400 
setClosed(bool bNew)401 	void B3DPolyPolygon::setClosed(bool bNew)
402 	{
403 		if(bNew != isClosed())
404 			mpPolyPolygon->setClosed(bNew);
405 	}
406 
flip()407 	void B3DPolyPolygon::flip()
408 	{
409 		mpPolyPolygon->flip();
410 	}
411 
hasDoublePoints() const412 	bool B3DPolyPolygon::hasDoublePoints() const
413 	{
414 		bool bRetval(false);
415 
416 		for(sal_uInt32 a(0L); !bRetval && a < mpPolyPolygon->count(); a++)
417 		{
418 			if((mpPolyPolygon->getB3DPolygon(a)).hasDoublePoints())
419 			{
420 				bRetval = true;
421 			}
422 		}
423 
424 		return bRetval;
425 	}
426 
removeDoublePoints()427 	void B3DPolyPolygon::removeDoublePoints()
428 	{
429 		if(hasDoublePoints())
430 			mpPolyPolygon->removeDoublePoints();
431 	}
432 
transform(const B3DHomMatrix & rMatrix)433 	void B3DPolyPolygon::transform(const B3DHomMatrix& rMatrix)
434 	{
435 		if(mpPolyPolygon->count() && !rMatrix.isIdentity())
436 		{
437 			mpPolyPolygon->transform(rMatrix);
438 		}
439 	}
440 } // end of namespace basegfx
441 
442 // eof
443