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 <osl/diagnose.h> 21 #include <basegfx/polygon/b3dpolypolygon.hxx> 22 #include <basegfx/polygon/b3dpolygon.hxx> 23 #include <basegfx/matrix/b2dhommatrix.hxx> 24 #include <basegfx/matrix/b3dhommatrix.hxx> 25 #include <vector> 26 27 class ImplB3DPolyPolygon 28 { 29 typedef std::vector< ::basegfx::B3DPolygon > PolygonVector; 30 31 PolygonVector maPolygons; 32 33 public: ImplB3DPolyPolygon()34 ImplB3DPolyPolygon() : maPolygons() 35 { 36 } 37 ImplB3DPolyPolygon(const::basegfx::B3DPolygon & rToBeCopied)38 explicit ImplB3DPolyPolygon(const ::basegfx::B3DPolygon& rToBeCopied) : 39 maPolygons(1,rToBeCopied) 40 { 41 } 42 operator ==(const ImplB3DPolyPolygon & rPolygonList) const43 bool operator==(const ImplB3DPolyPolygon& rPolygonList) const 44 { 45 // same polygon count? 46 if(maPolygons.size() != rPolygonList.maPolygons.size()) 47 return false; 48 49 // compare polygon content 50 if(maPolygons != rPolygonList.maPolygons) 51 return false; 52 53 return true; 54 } 55 getB3DPolygon(sal_uInt32 nIndex) const56 const ::basegfx::B3DPolygon& getB3DPolygon(sal_uInt32 nIndex) const 57 { 58 return maPolygons[nIndex]; 59 } 60 setB3DPolygon(sal_uInt32 nIndex,const::basegfx::B3DPolygon & rPolygon)61 void setB3DPolygon(sal_uInt32 nIndex, const ::basegfx::B3DPolygon& rPolygon) 62 { 63 maPolygons[nIndex] = rPolygon; 64 } 65 insert(sal_uInt32 nIndex,const::basegfx::B3DPolygon & rPolygon,sal_uInt32 nCount)66 void insert(sal_uInt32 nIndex, const ::basegfx::B3DPolygon& rPolygon, sal_uInt32 nCount) 67 { 68 if(nCount) 69 { 70 // add nCount copies of rPolygon 71 PolygonVector::iterator aIndex(maPolygons.begin()); 72 if( nIndex ) 73 aIndex += nIndex; 74 maPolygons.insert(aIndex, nCount, rPolygon); 75 } 76 } 77 insert(sal_uInt32 nIndex,const::basegfx::B3DPolyPolygon & rPolyPolygon)78 void insert(sal_uInt32 nIndex, const ::basegfx::B3DPolyPolygon& rPolyPolygon) 79 { 80 // add all polygons from rPolyPolygon 81 PolygonVector::iterator aIndex(maPolygons.begin()); 82 if( nIndex ) 83 aIndex += nIndex; 84 maPolygons.insert(aIndex, rPolyPolygon.begin(), rPolyPolygon.end()); 85 } 86 remove(sal_uInt32 nIndex,sal_uInt32 nCount)87 void remove(sal_uInt32 nIndex, sal_uInt32 nCount) 88 { 89 if(nCount) 90 { 91 // remove polygon data 92 PolygonVector::iterator aStart(maPolygons.begin()); 93 aStart += nIndex; 94 const PolygonVector::iterator aEnd(aStart + nCount); 95 96 maPolygons.erase(aStart, aEnd); 97 } 98 } 99 count() const100 sal_uInt32 count() const 101 { 102 return maPolygons.size(); 103 } 104 flip()105 void flip() 106 { 107 for (auto& aPolygon : maPolygons) 108 aPolygon.flip(); 109 } 110 removeDoublePoints()111 void removeDoublePoints() 112 { 113 for (auto& aPolygon : maPolygons) 114 aPolygon.removeDoublePoints(); 115 } 116 transform(const::basegfx::B3DHomMatrix & rMatrix)117 void transform(const ::basegfx::B3DHomMatrix& rMatrix) 118 { 119 for (auto& aPolygon : maPolygons) 120 aPolygon.transform(rMatrix); 121 } 122 clearBColors()123 void clearBColors() 124 { 125 for (auto& aPolygon : maPolygons) 126 aPolygon.clearBColors(); 127 } 128 transformNormals(const::basegfx::B3DHomMatrix & rMatrix)129 void transformNormals(const ::basegfx::B3DHomMatrix& rMatrix) 130 { 131 for (auto& aPolygon : maPolygons) 132 aPolygon.transformNormals(rMatrix); 133 } 134 clearNormals()135 void clearNormals() 136 { 137 for (auto& aPolygon : maPolygons) 138 aPolygon.clearNormals(); 139 } 140 transformTextureCoordinates(const::basegfx::B2DHomMatrix & rMatrix)141 void transformTextureCoordinates(const ::basegfx::B2DHomMatrix& rMatrix) 142 { 143 for (auto& aPolygon : maPolygons) 144 aPolygon.transformTextureCoordinates(rMatrix); 145 } 146 clearTextureCoordinates()147 void clearTextureCoordinates() 148 { 149 for (auto& aPolygon : maPolygons) 150 aPolygon.clearTextureCoordinates(); 151 } 152 begin() const153 const basegfx::B3DPolygon* begin() const 154 { 155 if (maPolygons.empty()) 156 return nullptr; 157 else 158 return maPolygons.data(); 159 } 160 end() const161 const basegfx::B3DPolygon* end() const 162 { 163 if (maPolygons.empty()) 164 return nullptr; 165 else 166 return maPolygons.data() + maPolygons.size(); 167 } 168 begin()169 basegfx::B3DPolygon* begin() 170 { 171 if (maPolygons.empty()) 172 return nullptr; 173 else 174 return maPolygons.data(); 175 } 176 end()177 basegfx::B3DPolygon* end() 178 { 179 if (maPolygons.empty()) 180 return nullptr; 181 else 182 return maPolygons.data() + maPolygons.size(); 183 } 184 }; 185 186 namespace basegfx 187 { 188 namespace { 189 getDefaultPolyPolygon()190 B3DPolyPolygon::ImplType const & getDefaultPolyPolygon() { 191 static B3DPolyPolygon::ImplType const singleton; 192 return singleton; 193 } 194 195 } 196 B3DPolyPolygon()197 B3DPolyPolygon::B3DPolyPolygon() : 198 mpPolyPolygon(getDefaultPolyPolygon()) 199 { 200 } 201 202 B3DPolyPolygon::B3DPolyPolygon(const B3DPolyPolygon&) = default; 203 204 B3DPolyPolygon::B3DPolyPolygon(B3DPolyPolygon&&) = default; 205 B3DPolyPolygon(const B3DPolygon & rPolygon)206 B3DPolyPolygon::B3DPolyPolygon(const B3DPolygon& rPolygon) : 207 mpPolyPolygon( ImplB3DPolyPolygon(rPolygon) ) 208 { 209 } 210 211 B3DPolyPolygon::~B3DPolyPolygon() = default; 212 213 B3DPolyPolygon& B3DPolyPolygon::operator=(const B3DPolyPolygon&) = default; 214 215 B3DPolyPolygon& B3DPolyPolygon::operator=(B3DPolyPolygon&&) = default; 216 operator ==(const B3DPolyPolygon & rPolyPolygon) const217 bool B3DPolyPolygon::operator==(const B3DPolyPolygon& rPolyPolygon) const 218 { 219 if(mpPolyPolygon.same_object(rPolyPolygon.mpPolyPolygon)) 220 return true; 221 222 return ((*mpPolyPolygon) == (*rPolyPolygon.mpPolyPolygon)); 223 } 224 operator !=(const B3DPolyPolygon & rPolyPolygon) const225 bool B3DPolyPolygon::operator!=(const B3DPolyPolygon& rPolyPolygon) const 226 { 227 return !(*this == rPolyPolygon); 228 } 229 count() const230 sal_uInt32 B3DPolyPolygon::count() const 231 { 232 return mpPolyPolygon->count(); 233 } 234 getB3DPolygon(sal_uInt32 nIndex) const235 B3DPolygon const & B3DPolyPolygon::getB3DPolygon(sal_uInt32 nIndex) const 236 { 237 OSL_ENSURE(nIndex < mpPolyPolygon->count(), "B3DPolyPolygon access outside range (!)"); 238 239 return mpPolyPolygon->getB3DPolygon(nIndex); 240 } 241 setB3DPolygon(sal_uInt32 nIndex,const B3DPolygon & rPolygon)242 void B3DPolyPolygon::setB3DPolygon(sal_uInt32 nIndex, const B3DPolygon& rPolygon) 243 { 244 OSL_ENSURE(nIndex < mpPolyPolygon->count(), "B3DPolyPolygon access outside range (!)"); 245 246 if(getB3DPolygon(nIndex) != rPolygon) 247 mpPolyPolygon->setB3DPolygon(nIndex, rPolygon); 248 } 249 areBColorsUsed() const250 bool B3DPolyPolygon::areBColorsUsed() const 251 { 252 for(sal_uInt32 a(0); a < mpPolyPolygon->count(); a++) 253 { 254 if(mpPolyPolygon->getB3DPolygon(a).areBColorsUsed()) 255 { 256 return true; 257 } 258 } 259 260 return false; 261 } 262 clearBColors()263 void B3DPolyPolygon::clearBColors() 264 { 265 if(areBColorsUsed()) 266 mpPolyPolygon->clearBColors(); 267 } 268 transformNormals(const B3DHomMatrix & rMatrix)269 void B3DPolyPolygon::transformNormals(const B3DHomMatrix& rMatrix) 270 { 271 if(!rMatrix.isIdentity()) 272 mpPolyPolygon->transformNormals(rMatrix); 273 } 274 areNormalsUsed() const275 bool B3DPolyPolygon::areNormalsUsed() const 276 { 277 for(sal_uInt32 a(0); a < mpPolyPolygon->count(); a++) 278 { 279 if(mpPolyPolygon->getB3DPolygon(a).areNormalsUsed()) 280 { 281 return true; 282 } 283 } 284 285 return false; 286 } 287 clearNormals()288 void B3DPolyPolygon::clearNormals() 289 { 290 if(areNormalsUsed()) 291 mpPolyPolygon->clearNormals(); 292 } 293 transformTextureCoordinates(const B2DHomMatrix & rMatrix)294 void B3DPolyPolygon::transformTextureCoordinates(const B2DHomMatrix& rMatrix) 295 { 296 if(!rMatrix.isIdentity()) 297 mpPolyPolygon->transformTextureCoordinates(rMatrix); 298 } 299 areTextureCoordinatesUsed() const300 bool B3DPolyPolygon::areTextureCoordinatesUsed() const 301 { 302 for(sal_uInt32 a(0); a < mpPolyPolygon->count(); a++) 303 { 304 if(mpPolyPolygon->getB3DPolygon(a).areTextureCoordinatesUsed()) 305 { 306 return true; 307 } 308 } 309 310 return false; 311 } 312 clearTextureCoordinates()313 void B3DPolyPolygon::clearTextureCoordinates() 314 { 315 if(areTextureCoordinatesUsed()) 316 mpPolyPolygon->clearTextureCoordinates(); 317 } 318 append(const B3DPolygon & rPolygon,sal_uInt32 nCount)319 void B3DPolyPolygon::append(const B3DPolygon& rPolygon, sal_uInt32 nCount) 320 { 321 if(nCount) 322 mpPolyPolygon->insert(mpPolyPolygon->count(), rPolygon, nCount); 323 } 324 append(const B3DPolyPolygon & rPolyPolygon)325 void B3DPolyPolygon::append(const B3DPolyPolygon& rPolyPolygon) 326 { 327 if(rPolyPolygon.count()) 328 mpPolyPolygon->insert(mpPolyPolygon->count(), rPolyPolygon); 329 } 330 remove(sal_uInt32 nIndex,sal_uInt32 nCount)331 void B3DPolyPolygon::remove(sal_uInt32 nIndex, sal_uInt32 nCount) 332 { 333 OSL_ENSURE(nIndex + nCount <= mpPolyPolygon->count(), "B3DPolyPolygon Remove outside range (!)"); 334 335 if(nCount) 336 mpPolyPolygon->remove(nIndex, nCount); 337 } 338 clear()339 void B3DPolyPolygon::clear() 340 { 341 mpPolyPolygon = getDefaultPolyPolygon(); 342 } 343 flip()344 void B3DPolyPolygon::flip() 345 { 346 mpPolyPolygon->flip(); 347 } 348 hasDoublePoints() const349 bool B3DPolyPolygon::hasDoublePoints() const 350 { 351 bool bRetval(false); 352 353 for(sal_uInt32 a(0); !bRetval && a < mpPolyPolygon->count(); a++) 354 { 355 if(mpPolyPolygon->getB3DPolygon(a).hasDoublePoints()) 356 { 357 bRetval = true; 358 } 359 } 360 361 return bRetval; 362 } 363 removeDoublePoints()364 void B3DPolyPolygon::removeDoublePoints() 365 { 366 if(hasDoublePoints()) 367 mpPolyPolygon->removeDoublePoints(); 368 } 369 transform(const B3DHomMatrix & rMatrix)370 void B3DPolyPolygon::transform(const B3DHomMatrix& rMatrix) 371 { 372 if(mpPolyPolygon->count() && !rMatrix.isIdentity()) 373 { 374 mpPolyPolygon->transform(rMatrix); 375 } 376 } 377 begin() const378 const B3DPolygon* B3DPolyPolygon::begin() const 379 { 380 return mpPolyPolygon->begin(); 381 } 382 end() const383 const B3DPolygon* B3DPolyPolygon::end() const 384 { 385 return mpPolyPolygon->end(); 386 } 387 begin()388 B3DPolygon* B3DPolyPolygon::begin() 389 { 390 return mpPolyPolygon->begin(); 391 } 392 end()393 B3DPolygon* B3DPolyPolygon::end() 394 { 395 return mpPolyPolygon->end(); 396 } 397 } // end of namespace basegfx 398 399 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 400