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