xref: /AOO41X/main/drawinglayer/source/geometry/viewinformation2d.cxx (revision 464702f4578bd67db020a330afd07883930c5e07)
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 it's 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