xref: /trunk/main/drawinglayer/source/geometry/viewinformation2d.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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