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_drawinglayer.hxx" 30 31 #include <drawinglayer/geometry/viewinformation2d.hxx> 32 #include <basegfx/matrix/b2dhommatrix.hxx> 33 #include <basegfx/range/b2drange.hxx> 34 #include <osl/mutex.hxx> 35 #include <basegfx/tools/canvastools.hxx> 36 #include <com/sun/star/geometry/AffineMatrix2D.hpp> 37 #include <com/sun/star/geometry/RealRectangle2D.hpp> 38 39 ////////////////////////////////////////////////////////////////////////////// 40 41 using namespace com::sun::star; 42 43 ////////////////////////////////////////////////////////////////////////////// 44 45 namespace drawinglayer 46 { 47 namespace geometry 48 { 49 class ImpViewInformation2D 50 { 51 private: 52 // ViewInformation2D implementation can change refcount, so we have only 53 // two memory regions for pairs of ViewInformation2D/ImpViewInformation2D 54 friend class ::drawinglayer::geometry::ViewInformation2D; 55 56 // the refcounter. 0 means exclusively used 57 sal_uInt32 mnRefCount; 58 59 protected: 60 // the object transformation 61 basegfx::B2DHomMatrix maObjectTransformation; 62 63 // the view transformation 64 basegfx::B2DHomMatrix maViewTransformation; 65 66 // the ObjectToView and it's inverse, both on demand from ObjectTransformation 67 // and ViewTransformation 68 basegfx::B2DHomMatrix maObjectToViewTransformation; 69 basegfx::B2DHomMatrix maInverseObjectToViewTransformation; 70 71 // the visible range and the on-demand one in ViewCoordinates 72 basegfx::B2DRange maViewport; 73 basegfx::B2DRange maDiscreteViewport; 74 75 // the DrawPage which is target of visualisation. This is needed e.g. for 76 // the view-dependent decomposition of PageNumber TextFields. 77 // This parameter is buffered here, but mainly resides in mxExtendedInformation, 78 // so it will be interpreted, but held there. It will also not be added 79 // to mxExtendedInformation in impFillViewInformationFromContent (it's there already) 80 uno::Reference< drawing::XDrawPage > mxVisualizedPage; 81 82 // the point in time 83 double mfViewTime; 84 85 // bitfield 86 bool mbReducedDisplayQuality : 1; 87 88 // the complete PropertyValue representation (if already created) 89 uno::Sequence< beans::PropertyValue > mxViewInformation; 90 91 // the extra PropertyValues; not represented by ViewTransformation, 92 // Viewport, VisualizedPage or ViewTime 93 uno::Sequence< beans::PropertyValue > mxExtendedInformation; 94 95 // the local UNO API strings 96 const ::rtl::OUString& getNamePropertyObjectTransformation() 97 { 98 static ::rtl::OUString s_sNameProperty(RTL_CONSTASCII_USTRINGPARAM("ObjectTransformation")); 99 return s_sNameProperty; 100 } 101 102 const ::rtl::OUString& getNamePropertyViewTransformation() 103 { 104 static ::rtl::OUString s_sNameProperty(RTL_CONSTASCII_USTRINGPARAM("ViewTransformation")); 105 return s_sNameProperty; 106 } 107 108 const ::rtl::OUString& getNamePropertyViewport() 109 { 110 static ::rtl::OUString s_sNameProperty(RTL_CONSTASCII_USTRINGPARAM("Viewport")); 111 return s_sNameProperty; 112 } 113 114 const ::rtl::OUString& getNamePropertyTime() 115 { 116 static ::rtl::OUString s_sNameProperty(RTL_CONSTASCII_USTRINGPARAM("Time")); 117 return s_sNameProperty; 118 } 119 120 const ::rtl::OUString& getNamePropertyVisualizedPage() 121 { 122 static ::rtl::OUString s_sNameProperty(RTL_CONSTASCII_USTRINGPARAM("VisualizedPage")); 123 return s_sNameProperty; 124 } 125 126 const ::rtl::OUString& getNamePropertyReducedDisplayQuality() 127 { 128 static ::rtl::OUString s_sNameProperty(RTL_CONSTASCII_USTRINGPARAM("ReducedDisplayQuality")); 129 return s_sNameProperty; 130 } 131 132 void impInterpretPropertyValues(const uno::Sequence< beans::PropertyValue >& rViewParameters) 133 { 134 if(rViewParameters.hasElements()) 135 { 136 const sal_Int32 nCount(rViewParameters.getLength()); 137 sal_Int32 nExtendedInsert(0); 138 139 // prepare extended information for filtering. Maximum size is nCount 140 mxExtendedInformation.realloc(nCount); 141 142 for(sal_Int32 a(0); a < nCount; a++) 143 { 144 const beans::PropertyValue& rProp = rViewParameters[a]; 145 146 if(rProp.Name == getNamePropertyReducedDisplayQuality()) 147 { 148 // extra information; add to filtered information 149 mxExtendedInformation[nExtendedInsert++] = rProp; 150 151 // for performance reasons, also cache content locally 152 sal_Bool bSalBool(false); 153 rProp.Value >>= bSalBool; 154 mbReducedDisplayQuality = bSalBool; 155 } 156 else if(rProp.Name == getNamePropertyObjectTransformation()) 157 { 158 com::sun::star::geometry::AffineMatrix2D aAffineMatrix2D; 159 rProp.Value >>= aAffineMatrix2D; 160 basegfx::unotools::homMatrixFromAffineMatrix(maObjectTransformation, aAffineMatrix2D); 161 } 162 else if(rProp.Name == getNamePropertyViewTransformation()) 163 { 164 com::sun::star::geometry::AffineMatrix2D aAffineMatrix2D; 165 rProp.Value >>= aAffineMatrix2D; 166 basegfx::unotools::homMatrixFromAffineMatrix(maViewTransformation, aAffineMatrix2D); 167 } 168 else if(rProp.Name == getNamePropertyViewport()) 169 { 170 com::sun::star::geometry::RealRectangle2D aViewport; 171 rProp.Value >>= aViewport; 172 maViewport = basegfx::unotools::b2DRectangleFromRealRectangle2D(aViewport); 173 } 174 else if(rProp.Name == getNamePropertyTime()) 175 { 176 rProp.Value >>= mfViewTime; 177 } 178 else if(rProp.Name == getNamePropertyVisualizedPage()) 179 { 180 rProp.Value >>= mxVisualizedPage; 181 } 182 else 183 { 184 // extra information; add to filtered information 185 mxExtendedInformation[nExtendedInsert++] = rProp; 186 } 187 } 188 189 // extra information size is now known; realloc to final size 190 mxExtendedInformation.realloc(nExtendedInsert); 191 } 192 } 193 194 void impFillViewInformationFromContent() 195 { 196 uno::Sequence< beans::PropertyValue > xRetval; 197 const bool bObjectTransformationUsed(!maObjectTransformation.isIdentity()); 198 const bool bViewTransformationUsed(!maViewTransformation.isIdentity()); 199 const bool bViewportUsed(!maViewport.isEmpty()); 200 const bool bTimeUsed(0.0 < mfViewTime); 201 const bool bVisualizedPageUsed(mxVisualizedPage.is()); 202 const bool bReducedDisplayQualityUsed(true == mbReducedDisplayQuality); 203 const bool bExtraInformation(mxExtendedInformation.hasElements()); 204 sal_uInt32 nIndex(0); 205 const sal_uInt32 nCount( 206 (bObjectTransformationUsed ? 1 : 0) + 207 (bViewTransformationUsed ? 1 : 0) + 208 (bViewportUsed ? 1 : 0) + 209 (bTimeUsed ? 1 : 0) + 210 (bVisualizedPageUsed ? 1 : 0) + 211 (bReducedDisplayQualityUsed ? 1 : 0) + 212 (bExtraInformation ? mxExtendedInformation.getLength() : 0)); 213 214 mxViewInformation.realloc(nCount); 215 216 if(bObjectTransformationUsed) 217 { 218 com::sun::star::geometry::AffineMatrix2D aAffineMatrix2D; 219 basegfx::unotools::affineMatrixFromHomMatrix(aAffineMatrix2D, maObjectTransformation); 220 mxViewInformation[nIndex].Name = getNamePropertyObjectTransformation(); 221 mxViewInformation[nIndex].Value <<= aAffineMatrix2D; 222 nIndex++; 223 } 224 225 if(bViewTransformationUsed) 226 { 227 com::sun::star::geometry::AffineMatrix2D aAffineMatrix2D; 228 basegfx::unotools::affineMatrixFromHomMatrix(aAffineMatrix2D, maViewTransformation); 229 mxViewInformation[nIndex].Name = getNamePropertyViewTransformation(); 230 mxViewInformation[nIndex].Value <<= aAffineMatrix2D; 231 nIndex++; 232 } 233 234 if(bViewportUsed) 235 { 236 const com::sun::star::geometry::RealRectangle2D aViewport(basegfx::unotools::rectangle2DFromB2DRectangle(maViewport)); 237 mxViewInformation[nIndex].Name = getNamePropertyViewport(); 238 mxViewInformation[nIndex].Value <<= aViewport; 239 nIndex++; 240 } 241 242 if(bTimeUsed) 243 { 244 mxViewInformation[nIndex].Name = getNamePropertyTime(); 245 mxViewInformation[nIndex].Value <<= mfViewTime; 246 nIndex++; 247 } 248 249 if(bVisualizedPageUsed) 250 { 251 mxViewInformation[nIndex].Name = getNamePropertyVisualizedPage(); 252 mxViewInformation[nIndex].Value <<= mxVisualizedPage; 253 nIndex++; 254 } 255 256 if(bExtraInformation) 257 { 258 const sal_Int32 nExtra(mxExtendedInformation.getLength()); 259 260 for(sal_Int32 a(0); a < nExtra; a++) 261 { 262 mxViewInformation[nIndex++] = mxExtendedInformation[a]; 263 } 264 } 265 } 266 267 public: 268 ImpViewInformation2D( 269 const basegfx::B2DHomMatrix& rObjectTransformation, 270 const basegfx::B2DHomMatrix& rViewTransformation, 271 const basegfx::B2DRange& rViewport, 272 const uno::Reference< drawing::XDrawPage >& rxDrawPage, 273 double fViewTime, 274 const uno::Sequence< beans::PropertyValue >& rExtendedParameters) 275 : mnRefCount(0), 276 maObjectTransformation(rObjectTransformation), 277 maViewTransformation(rViewTransformation), 278 maObjectToViewTransformation(), 279 maInverseObjectToViewTransformation(), 280 maViewport(rViewport), 281 maDiscreteViewport(), 282 mxVisualizedPage(rxDrawPage), 283 mfViewTime(fViewTime), 284 mbReducedDisplayQuality(false), 285 mxViewInformation(), 286 mxExtendedInformation() 287 { 288 impInterpretPropertyValues(rExtendedParameters); 289 } 290 291 ImpViewInformation2D(const uno::Sequence< beans::PropertyValue >& rViewParameters) 292 : mnRefCount(0), 293 maObjectTransformation(), 294 maViewTransformation(), 295 maObjectToViewTransformation(), 296 maInverseObjectToViewTransformation(), 297 maViewport(), 298 maDiscreteViewport(), 299 mxVisualizedPage(), 300 mfViewTime(), 301 mbReducedDisplayQuality(false), 302 mxViewInformation(rViewParameters), 303 mxExtendedInformation() 304 { 305 impInterpretPropertyValues(rViewParameters); 306 } 307 308 ImpViewInformation2D() 309 : mnRefCount(0), 310 maObjectTransformation(), 311 maViewTransformation(), 312 maObjectToViewTransformation(), 313 maInverseObjectToViewTransformation(), 314 maViewport(), 315 maDiscreteViewport(), 316 mxVisualizedPage(), 317 mfViewTime(), 318 mbReducedDisplayQuality(false), 319 mxViewInformation(), 320 mxExtendedInformation() 321 { 322 } 323 324 const basegfx::B2DHomMatrix& getObjectTransformation() const 325 { 326 return maObjectTransformation; 327 } 328 329 const basegfx::B2DHomMatrix& getViewTransformation() const 330 { 331 return maViewTransformation; 332 } 333 334 const basegfx::B2DRange& getViewport() const 335 { 336 return maViewport; 337 } 338 339 const basegfx::B2DRange& getDiscreteViewport() const 340 { 341 ::osl::Mutex m_mutex; 342 343 if(maDiscreteViewport.isEmpty() && !maViewport.isEmpty()) 344 { 345 basegfx::B2DRange aDiscreteViewport(maViewport); 346 aDiscreteViewport.transform(getViewTransformation()); 347 const_cast< ImpViewInformation2D* >(this)->maDiscreteViewport = aDiscreteViewport; 348 } 349 350 return maDiscreteViewport; 351 } 352 353 const basegfx::B2DHomMatrix& getObjectToViewTransformation() const 354 { 355 ::osl::Mutex m_mutex; 356 357 if(maObjectToViewTransformation.isIdentity() && 358 (!maObjectTransformation.isIdentity() || !maViewTransformation.isIdentity())) 359 { 360 basegfx::B2DHomMatrix aObjectToView(maViewTransformation * maObjectTransformation); 361 const_cast< ImpViewInformation2D* >(this)->maObjectToViewTransformation = aObjectToView; 362 } 363 364 return maObjectToViewTransformation; 365 } 366 367 const basegfx::B2DHomMatrix& getInverseObjectToViewTransformation() const 368 { 369 ::osl::Mutex m_mutex; 370 371 if(maInverseObjectToViewTransformation.isIdentity() && 372 (!maObjectTransformation.isIdentity() || !maViewTransformation.isIdentity())) 373 { 374 basegfx::B2DHomMatrix aInverseObjectToView(maViewTransformation * maObjectTransformation); 375 aInverseObjectToView.invert(); 376 const_cast< ImpViewInformation2D* >(this)->maInverseObjectToViewTransformation = aInverseObjectToView; 377 } 378 379 return maInverseObjectToViewTransformation; 380 } 381 382 double getViewTime() const 383 { 384 return mfViewTime; 385 } 386 387 const uno::Reference< drawing::XDrawPage >& getVisualizedPage() const 388 { 389 return mxVisualizedPage; 390 } 391 392 bool getReducedDisplayQuality() const 393 { 394 return mbReducedDisplayQuality; 395 } 396 397 const uno::Sequence< beans::PropertyValue >& getViewInformationSequence() const 398 { 399 if(!mxViewInformation.hasElements()) 400 { 401 const_cast< ImpViewInformation2D* >(this)->impFillViewInformationFromContent(); 402 } 403 404 return mxViewInformation; 405 } 406 407 const uno::Sequence< beans::PropertyValue >& getExtendedInformationSequence() const 408 { 409 return mxExtendedInformation; 410 } 411 412 bool operator==(const ImpViewInformation2D& rCandidate) const 413 { 414 return (maObjectTransformation == rCandidate.maObjectTransformation 415 && maViewTransformation == rCandidate.maViewTransformation 416 && maViewport == rCandidate.maViewport 417 && mxVisualizedPage == rCandidate.mxVisualizedPage 418 && mfViewTime == rCandidate.mfViewTime 419 && mxExtendedInformation == rCandidate.mxExtendedInformation); 420 } 421 422 static ImpViewInformation2D* get_global_default() 423 { 424 static ImpViewInformation2D* pDefault = 0; 425 426 if(!pDefault) 427 { 428 pDefault = new ImpViewInformation2D(); 429 430 // never delete; start with RefCount 1, not 0 431 pDefault->mnRefCount++; 432 } 433 434 return pDefault; 435 } 436 }; 437 } // end of anonymous namespace 438 } // end of namespace drawinglayer 439 440 ////////////////////////////////////////////////////////////////////////////// 441 442 namespace drawinglayer 443 { 444 namespace geometry 445 { 446 ViewInformation2D::ViewInformation2D( 447 const basegfx::B2DHomMatrix& rObjectTransformation, 448 const basegfx::B2DHomMatrix& rViewTransformation, 449 const basegfx::B2DRange& rViewport, 450 const uno::Reference< drawing::XDrawPage >& rxDrawPage, 451 double fViewTime, 452 const uno::Sequence< beans::PropertyValue >& rExtendedParameters) 453 : mpViewInformation2D(new ImpViewInformation2D( 454 rObjectTransformation, 455 rViewTransformation, 456 rViewport, 457 rxDrawPage, 458 fViewTime, 459 rExtendedParameters)) 460 { 461 } 462 463 ViewInformation2D::ViewInformation2D(const uno::Sequence< beans::PropertyValue >& rViewParameters) 464 : mpViewInformation2D(new ImpViewInformation2D(rViewParameters)) 465 { 466 } 467 468 ViewInformation2D::ViewInformation2D() 469 : mpViewInformation2D(ImpViewInformation2D::get_global_default()) 470 { 471 mpViewInformation2D->mnRefCount++; 472 } 473 474 ViewInformation2D::ViewInformation2D(const ViewInformation2D& rCandidate) 475 : mpViewInformation2D(rCandidate.mpViewInformation2D) 476 { 477 ::osl::Mutex m_mutex; 478 mpViewInformation2D->mnRefCount++; 479 } 480 481 ViewInformation2D::~ViewInformation2D() 482 { 483 ::osl::Mutex m_mutex; 484 485 if(mpViewInformation2D->mnRefCount) 486 { 487 mpViewInformation2D->mnRefCount--; 488 } 489 else 490 { 491 delete mpViewInformation2D; 492 } 493 } 494 495 bool ViewInformation2D::isDefault() const 496 { 497 return mpViewInformation2D == ImpViewInformation2D::get_global_default(); 498 } 499 500 ViewInformation2D& ViewInformation2D::operator=(const ViewInformation2D& rCandidate) 501 { 502 ::osl::Mutex m_mutex; 503 504 if(mpViewInformation2D->mnRefCount) 505 { 506 mpViewInformation2D->mnRefCount--; 507 } 508 else 509 { 510 delete mpViewInformation2D; 511 } 512 513 mpViewInformation2D = rCandidate.mpViewInformation2D; 514 mpViewInformation2D->mnRefCount++; 515 516 return *this; 517 } 518 519 bool ViewInformation2D::operator==(const ViewInformation2D& rCandidate) const 520 { 521 if(rCandidate.mpViewInformation2D == mpViewInformation2D) 522 { 523 return true; 524 } 525 526 if(rCandidate.isDefault() != isDefault()) 527 { 528 return false; 529 } 530 531 return (*rCandidate.mpViewInformation2D == *mpViewInformation2D); 532 } 533 534 const basegfx::B2DHomMatrix& ViewInformation2D::getObjectTransformation() const 535 { 536 return mpViewInformation2D->getObjectTransformation(); 537 } 538 539 const basegfx::B2DHomMatrix& ViewInformation2D::getViewTransformation() const 540 { 541 return mpViewInformation2D->getViewTransformation(); 542 } 543 544 const basegfx::B2DRange& ViewInformation2D::getViewport() const 545 { 546 return mpViewInformation2D->getViewport(); 547 } 548 549 double ViewInformation2D::getViewTime() const 550 { 551 return mpViewInformation2D->getViewTime(); 552 } 553 554 const uno::Reference< drawing::XDrawPage >& ViewInformation2D::getVisualizedPage() const 555 { 556 return mpViewInformation2D->getVisualizedPage(); 557 } 558 559 const basegfx::B2DHomMatrix& ViewInformation2D::getObjectToViewTransformation() const 560 { 561 return mpViewInformation2D->getObjectToViewTransformation(); 562 } 563 564 const basegfx::B2DHomMatrix& ViewInformation2D::getInverseObjectToViewTransformation() const 565 { 566 return mpViewInformation2D->getInverseObjectToViewTransformation(); 567 } 568 569 const basegfx::B2DRange& ViewInformation2D::getDiscreteViewport() const 570 { 571 return mpViewInformation2D->getDiscreteViewport(); 572 } 573 574 bool ViewInformation2D::getReducedDisplayQuality() const 575 { 576 return mpViewInformation2D->getReducedDisplayQuality(); 577 } 578 579 const uno::Sequence< beans::PropertyValue >& ViewInformation2D::getViewInformationSequence() const 580 { 581 return mpViewInformation2D->getViewInformationSequence(); 582 } 583 584 const uno::Sequence< beans::PropertyValue >& ViewInformation2D::getExtendedInformationSequence() const 585 { 586 return mpViewInformation2D->getExtendedInformationSequence(); 587 } 588 } // end of namespace geometry 589 } // end of namespace drawinglayer 590 591 ////////////////////////////////////////////////////////////////////////////// 592 // eof 593