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