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 <drawinglayer/geometry/viewinformation2d.hxx> 21 #include <basegfx/matrix/b2dhommatrix.hxx> 22 #include <basegfx/range/b2drange.hxx> 23 #include <basegfx/utils/canvastools.hxx> 24 #include <com/sun/star/beans/PropertyValue.hpp> 25 #include <com/sun/star/drawing/XDrawPage.hpp> 26 #include <com/sun/star/geometry/AffineMatrix2D.hpp> 27 #include <com/sun/star/geometry/RealRectangle2D.hpp> 28 #include <rtl/instance.hxx> 29 #include <com/sun/star/uno/Sequence.hxx> 30 31 32 using namespace com::sun::star; 33 34 35 namespace drawinglayer 36 { 37 namespace geometry 38 { 39 class ImpViewInformation2D 40 { 41 private: 42 // ViewInformation2D implementation can change refcount, so we have only 43 // two memory regions for pairs of ViewInformation2D/ImpViewInformation2D 44 friend class ::drawinglayer::geometry::ViewInformation2D; 45 46 protected: 47 // the object transformation 48 basegfx::B2DHomMatrix maObjectTransformation; 49 50 // the view transformation 51 basegfx::B2DHomMatrix maViewTransformation; 52 53 // the ObjectToView and it's inverse, both on demand from ObjectTransformation 54 // and ViewTransformation 55 basegfx::B2DHomMatrix maObjectToViewTransformation; 56 basegfx::B2DHomMatrix maInverseObjectToViewTransformation; 57 58 // the visible range and the on-demand one in ViewCoordinates 59 basegfx::B2DRange maViewport; 60 basegfx::B2DRange maDiscreteViewport; 61 62 // the DrawPage which is target of visualisation. This is needed e.g. for 63 // the view-dependent decomposition of PageNumber TextFields. 64 // This parameter is buffered here, but mainly resides in mxExtendedInformation, 65 // so it will be interpreted, but held there. It will also not be added 66 // to mxExtendedInformation in impFillViewInformationFromContent (it's there already) 67 uno::Reference< drawing::XDrawPage > mxVisualizedPage; 68 69 // the point in time 70 double mfViewTime; 71 72 bool mbReducedDisplayQuality : 1; 73 74 // the complete PropertyValue representation (if already created) 75 uno::Sequence< beans::PropertyValue > mxViewInformation; 76 77 // the extra PropertyValues; not represented by ViewTransformation, 78 // Viewport, VisualizedPage or ViewTime 79 uno::Sequence< beans::PropertyValue > mxExtendedInformation; 80 81 // the local UNO API strings getNamePropertyObjectTransformation()82 static OUString getNamePropertyObjectTransformation() 83 { 84 return "ObjectTransformation"; 85 } 86 getNamePropertyViewTransformation()87 static OUString getNamePropertyViewTransformation() 88 { 89 return "ViewTransformation"; 90 } 91 getNamePropertyViewport()92 static OUString getNamePropertyViewport() 93 { 94 return "Viewport"; 95 } 96 getNamePropertyTime()97 static OUString getNamePropertyTime() 98 { 99 return "Time"; 100 } 101 getNamePropertyVisualizedPage()102 static OUString getNamePropertyVisualizedPage() 103 { 104 return "VisualizedPage"; 105 } 106 getNamePropertyReducedDisplayQuality()107 static OUString getNamePropertyReducedDisplayQuality() 108 { 109 return "ReducedDisplayQuality"; 110 } 111 impInterpretPropertyValues(const uno::Sequence<beans::PropertyValue> & rViewParameters)112 void impInterpretPropertyValues(const uno::Sequence< beans::PropertyValue >& rViewParameters) 113 { 114 if(rViewParameters.hasElements()) 115 { 116 const sal_Int32 nCount(rViewParameters.getLength()); 117 sal_Int32 nExtendedInsert(0); 118 119 // prepare extended information for filtering. Maximum size is nCount 120 mxExtendedInformation.realloc(nCount); 121 122 for(sal_Int32 a(0); a < nCount; a++) 123 { 124 const beans::PropertyValue& rProp = rViewParameters[a]; 125 126 if(rProp.Name == getNamePropertyReducedDisplayQuality()) 127 { 128 // extra information; add to filtered information 129 mxExtendedInformation[nExtendedInsert++] = rProp; 130 131 // for performance reasons, also cache content locally 132 bool bSalBool(false); 133 rProp.Value >>= bSalBool; 134 mbReducedDisplayQuality = bSalBool; 135 } 136 else if(rProp.Name == getNamePropertyObjectTransformation()) 137 { 138 css::geometry::AffineMatrix2D aAffineMatrix2D; 139 rProp.Value >>= aAffineMatrix2D; 140 basegfx::unotools::homMatrixFromAffineMatrix(maObjectTransformation, aAffineMatrix2D); 141 } 142 else if(rProp.Name == getNamePropertyViewTransformation()) 143 { 144 css::geometry::AffineMatrix2D aAffineMatrix2D; 145 rProp.Value >>= aAffineMatrix2D; 146 basegfx::unotools::homMatrixFromAffineMatrix(maViewTransformation, aAffineMatrix2D); 147 } 148 else if(rProp.Name == getNamePropertyViewport()) 149 { 150 css::geometry::RealRectangle2D aViewport; 151 rProp.Value >>= aViewport; 152 maViewport = basegfx::unotools::b2DRectangleFromRealRectangle2D(aViewport); 153 } 154 else if(rProp.Name == getNamePropertyTime()) 155 { 156 rProp.Value >>= mfViewTime; 157 } 158 else if(rProp.Name == getNamePropertyVisualizedPage()) 159 { 160 rProp.Value >>= mxVisualizedPage; 161 } 162 else 163 { 164 // extra information; add to filtered information 165 mxExtendedInformation[nExtendedInsert++] = rProp; 166 } 167 } 168 169 // extra information size is now known; realloc to final size 170 mxExtendedInformation.realloc(nExtendedInsert); 171 } 172 } 173 impFillViewInformationFromContent()174 void impFillViewInformationFromContent() 175 { 176 const bool bObjectTransformationUsed(!maObjectTransformation.isIdentity()); 177 const bool bViewTransformationUsed(!maViewTransformation.isIdentity()); 178 const bool bViewportUsed(!maViewport.isEmpty()); 179 const bool bTimeUsed(0.0 < mfViewTime); 180 const bool bVisualizedPageUsed(mxVisualizedPage.is()); 181 const bool bReducedDisplayQualityUsed(mbReducedDisplayQuality); 182 const bool bExtraInformation(mxExtendedInformation.hasElements()); 183 sal_uInt32 nIndex(0); 184 const sal_uInt32 nCount( 185 (bObjectTransformationUsed ? 1 : 0) + 186 (bViewTransformationUsed ? 1 : 0) + 187 (bViewportUsed ? 1 : 0) + 188 (bTimeUsed ? 1 : 0) + 189 (bVisualizedPageUsed ? 1 : 0) + 190 (bReducedDisplayQualityUsed ? 1 : 0) + 191 (bExtraInformation ? mxExtendedInformation.getLength() : 0)); 192 193 mxViewInformation.realloc(nCount); 194 195 if(bObjectTransformationUsed) 196 { 197 css::geometry::AffineMatrix2D aAffineMatrix2D; 198 basegfx::unotools::affineMatrixFromHomMatrix(aAffineMatrix2D, maObjectTransformation); 199 mxViewInformation[nIndex].Name = getNamePropertyObjectTransformation(); 200 mxViewInformation[nIndex].Value <<= aAffineMatrix2D; 201 nIndex++; 202 } 203 204 if(bViewTransformationUsed) 205 { 206 css::geometry::AffineMatrix2D aAffineMatrix2D; 207 basegfx::unotools::affineMatrixFromHomMatrix(aAffineMatrix2D, maViewTransformation); 208 mxViewInformation[nIndex].Name = getNamePropertyViewTransformation(); 209 mxViewInformation[nIndex].Value <<= aAffineMatrix2D; 210 nIndex++; 211 } 212 213 if(bViewportUsed) 214 { 215 const css::geometry::RealRectangle2D aViewport(basegfx::unotools::rectangle2DFromB2DRectangle(maViewport)); 216 mxViewInformation[nIndex].Name = getNamePropertyViewport(); 217 mxViewInformation[nIndex].Value <<= aViewport; 218 nIndex++; 219 } 220 221 if(bTimeUsed) 222 { 223 mxViewInformation[nIndex].Name = getNamePropertyTime(); 224 mxViewInformation[nIndex].Value <<= mfViewTime; 225 nIndex++; 226 } 227 228 if(bVisualizedPageUsed) 229 { 230 mxViewInformation[nIndex].Name = getNamePropertyVisualizedPage(); 231 mxViewInformation[nIndex].Value <<= mxVisualizedPage; 232 nIndex++; 233 } 234 235 if(bExtraInformation) 236 { 237 const sal_Int32 nExtra(mxExtendedInformation.getLength()); 238 239 for(sal_Int32 a(0); a < nExtra; a++) 240 { 241 mxViewInformation[nIndex++] = mxExtendedInformation[a]; 242 } 243 } 244 } 245 246 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)247 ImpViewInformation2D( 248 const basegfx::B2DHomMatrix& rObjectTransformation, 249 const basegfx::B2DHomMatrix& rViewTransformation, 250 const basegfx::B2DRange& rViewport, 251 const uno::Reference< drawing::XDrawPage >& rxDrawPage, 252 double fViewTime, 253 const uno::Sequence< beans::PropertyValue >& rExtendedParameters) 254 : maObjectTransformation(rObjectTransformation), 255 maViewTransformation(rViewTransformation), 256 maObjectToViewTransformation(), 257 maInverseObjectToViewTransformation(), 258 maViewport(rViewport), 259 maDiscreteViewport(), 260 mxVisualizedPage(rxDrawPage), 261 mfViewTime(fViewTime), 262 mbReducedDisplayQuality(false), 263 mxViewInformation(), 264 mxExtendedInformation() 265 { 266 impInterpretPropertyValues(rExtendedParameters); 267 } 268 ImpViewInformation2D(const uno::Sequence<beans::PropertyValue> & rViewParameters)269 explicit ImpViewInformation2D(const uno::Sequence< beans::PropertyValue >& rViewParameters) 270 : maObjectTransformation(), 271 maViewTransformation(), 272 maObjectToViewTransformation(), 273 maInverseObjectToViewTransformation(), 274 maViewport(), 275 maDiscreteViewport(), 276 mxVisualizedPage(), 277 mfViewTime(), 278 mbReducedDisplayQuality(false), 279 mxViewInformation(rViewParameters), 280 mxExtendedInformation() 281 { 282 impInterpretPropertyValues(rViewParameters); 283 } 284 ImpViewInformation2D()285 ImpViewInformation2D() 286 : maObjectTransformation(), 287 maViewTransformation(), 288 maObjectToViewTransformation(), 289 maInverseObjectToViewTransformation(), 290 maViewport(), 291 maDiscreteViewport(), 292 mxVisualizedPage(), 293 mfViewTime(), 294 mbReducedDisplayQuality(false), 295 mxViewInformation(), 296 mxExtendedInformation() 297 { 298 } 299 getObjectTransformation() const300 const basegfx::B2DHomMatrix& getObjectTransformation() const 301 { 302 return maObjectTransformation; 303 } 304 getViewTransformation() const305 const basegfx::B2DHomMatrix& getViewTransformation() const 306 { 307 return maViewTransformation; 308 } 309 getViewport() const310 const basegfx::B2DRange& getViewport() const 311 { 312 return maViewport; 313 } 314 getDiscreteViewport() const315 const basegfx::B2DRange& getDiscreteViewport() const 316 { 317 if(maDiscreteViewport.isEmpty() && !maViewport.isEmpty()) 318 { 319 basegfx::B2DRange aDiscreteViewport(maViewport); 320 aDiscreteViewport.transform(getViewTransformation()); 321 const_cast< ImpViewInformation2D* >(this)->maDiscreteViewport = aDiscreteViewport; 322 } 323 324 return maDiscreteViewport; 325 } 326 getObjectToViewTransformation() const327 const basegfx::B2DHomMatrix& getObjectToViewTransformation() const 328 { 329 if(maObjectToViewTransformation.isIdentity() && 330 (!maObjectTransformation.isIdentity() || !maViewTransformation.isIdentity())) 331 { 332 basegfx::B2DHomMatrix aObjectToView(maViewTransformation * maObjectTransformation); 333 const_cast< ImpViewInformation2D* >(this)->maObjectToViewTransformation = aObjectToView; 334 } 335 336 return maObjectToViewTransformation; 337 } 338 getInverseObjectToViewTransformation() const339 const basegfx::B2DHomMatrix& getInverseObjectToViewTransformation() const 340 { 341 if(maInverseObjectToViewTransformation.isIdentity() && 342 (!maObjectTransformation.isIdentity() || !maViewTransformation.isIdentity())) 343 { 344 basegfx::B2DHomMatrix aInverseObjectToView(maViewTransformation * maObjectTransformation); 345 aInverseObjectToView.invert(); 346 const_cast< ImpViewInformation2D* >(this)->maInverseObjectToViewTransformation = aInverseObjectToView; 347 } 348 349 return maInverseObjectToViewTransformation; 350 } 351 getViewTime() const352 double getViewTime() const 353 { 354 return mfViewTime; 355 } 356 getVisualizedPage() const357 const uno::Reference< drawing::XDrawPage >& getVisualizedPage() const 358 { 359 return mxVisualizedPage; 360 } 361 getReducedDisplayQuality() const362 bool getReducedDisplayQuality() const 363 { 364 return mbReducedDisplayQuality; 365 } 366 getViewInformationSequence() const367 const uno::Sequence< beans::PropertyValue >& getViewInformationSequence() const 368 { 369 if(!mxViewInformation.hasElements()) 370 { 371 const_cast< ImpViewInformation2D* >(this)->impFillViewInformationFromContent(); 372 } 373 374 return mxViewInformation; 375 } 376 getExtendedInformationSequence() const377 const uno::Sequence< beans::PropertyValue >& getExtendedInformationSequence() const 378 { 379 return mxExtendedInformation; 380 } 381 operator ==(const ImpViewInformation2D & rCandidate) const382 bool operator==(const ImpViewInformation2D& rCandidate) const 383 { 384 return (maObjectTransformation == rCandidate.maObjectTransformation 385 && maViewTransformation == rCandidate.maViewTransformation 386 && maViewport == rCandidate.maViewport 387 && mxVisualizedPage == rCandidate.mxVisualizedPage 388 && mfViewTime == rCandidate.mfViewTime 389 && mxExtendedInformation == rCandidate.mxExtendedInformation); 390 } 391 }; 392 } // end of anonymous namespace 393 } // end of namespace drawinglayer 394 395 396 namespace drawinglayer 397 { 398 namespace geometry 399 { 400 namespace 401 { 402 struct theGlobalDefault : 403 public rtl::Static< ViewInformation2D::ImplType, theGlobalDefault > {}; 404 } 405 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)406 ViewInformation2D::ViewInformation2D( 407 const basegfx::B2DHomMatrix& rObjectTransformation, 408 const basegfx::B2DHomMatrix& rViewTransformation, 409 const basegfx::B2DRange& rViewport, 410 const uno::Reference< drawing::XDrawPage >& rxDrawPage, 411 double fViewTime, 412 const uno::Sequence< beans::PropertyValue >& rExtendedParameters) 413 : mpViewInformation2D(ImpViewInformation2D( 414 rObjectTransformation, 415 rViewTransformation, 416 rViewport, 417 rxDrawPage, 418 fViewTime, 419 rExtendedParameters)) 420 { 421 } 422 ViewInformation2D(const uno::Sequence<beans::PropertyValue> & rViewParameters)423 ViewInformation2D::ViewInformation2D(const uno::Sequence< beans::PropertyValue >& rViewParameters) 424 : mpViewInformation2D(ImpViewInformation2D(rViewParameters)) 425 { 426 } 427 ViewInformation2D()428 ViewInformation2D::ViewInformation2D() 429 : mpViewInformation2D(theGlobalDefault::get()) 430 { 431 } 432 433 ViewInformation2D::ViewInformation2D(const ViewInformation2D&) = default; 434 435 ViewInformation2D::ViewInformation2D(ViewInformation2D&&) = default; 436 437 ViewInformation2D::~ViewInformation2D() = default; 438 439 ViewInformation2D& ViewInformation2D::operator=(const ViewInformation2D&) = default; 440 441 ViewInformation2D& ViewInformation2D::operator=(ViewInformation2D&&) = default; 442 operator ==(const ViewInformation2D & rCandidate) const443 bool ViewInformation2D::operator==(const ViewInformation2D& rCandidate) const 444 { 445 return rCandidate.mpViewInformation2D == mpViewInformation2D; 446 } 447 getObjectTransformation() const448 const basegfx::B2DHomMatrix& ViewInformation2D::getObjectTransformation() const 449 { 450 return mpViewInformation2D->getObjectTransformation(); 451 } 452 getViewTransformation() const453 const basegfx::B2DHomMatrix& ViewInformation2D::getViewTransformation() const 454 { 455 return mpViewInformation2D->getViewTransformation(); 456 } 457 getViewport() const458 const basegfx::B2DRange& ViewInformation2D::getViewport() const 459 { 460 return mpViewInformation2D->getViewport(); 461 } 462 getViewTime() const463 double ViewInformation2D::getViewTime() const 464 { 465 return mpViewInformation2D->getViewTime(); 466 } 467 getVisualizedPage() const468 const uno::Reference< drawing::XDrawPage >& ViewInformation2D::getVisualizedPage() const 469 { 470 return mpViewInformation2D->getVisualizedPage(); 471 } 472 getObjectToViewTransformation() const473 const basegfx::B2DHomMatrix& ViewInformation2D::getObjectToViewTransformation() const 474 { 475 return mpViewInformation2D->getObjectToViewTransformation(); 476 } 477 getInverseObjectToViewTransformation() const478 const basegfx::B2DHomMatrix& ViewInformation2D::getInverseObjectToViewTransformation() const 479 { 480 return mpViewInformation2D->getInverseObjectToViewTransformation(); 481 } 482 getDiscreteViewport() const483 const basegfx::B2DRange& ViewInformation2D::getDiscreteViewport() const 484 { 485 return mpViewInformation2D->getDiscreteViewport(); 486 } 487 getReducedDisplayQuality() const488 bool ViewInformation2D::getReducedDisplayQuality() const 489 { 490 return mpViewInformation2D->getReducedDisplayQuality(); 491 } 492 getViewInformationSequence() const493 const uno::Sequence< beans::PropertyValue >& ViewInformation2D::getViewInformationSequence() const 494 { 495 return mpViewInformation2D->getViewInformationSequence(); 496 } 497 getExtendedInformationSequence() const498 const uno::Sequence< beans::PropertyValue >& ViewInformation2D::getExtendedInformationSequence() const 499 { 500 return mpViewInformation2D->getExtendedInformationSequence(); 501 } 502 } // end of namespace geometry 503 } // end of namespace drawinglayer 504 505 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 506