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