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