1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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 <o3tl/temporary.hxx>
29 #include <officecfg/Office/Common.hxx>
30 #include <unotools/configmgr.hxx>
35 using namespace com::sun::star
;
37 namespace drawinglayer::geometry
41 constexpr OUStringLiteral g_PropertyName_ObjectTransformation
= u
"ObjectTransformation";
42 constexpr OUStringLiteral g_PropertyName_ViewTransformation
= u
"ViewTransformation";
43 constexpr OUStringLiteral g_PropertyName_Viewport
= u
"Viewport";
44 constexpr OUStringLiteral g_PropertyName_Time
= u
"Time";
45 constexpr OUStringLiteral g_PropertyName_VisualizedPage
= u
"VisualizedPage";
46 constexpr OUStringLiteral g_PropertyName_ReducedDisplayQuality
= u
"ReducedDisplayQuality";
47 constexpr OUStringLiteral g_PropertyName_UseAntiAliasing
= u
"UseAntiAliasing";
48 constexpr OUStringLiteral g_PropertyName_PixelSnapHairline
= u
"PixelSnapHairline";
53 bool bForwardsAreInitialized(false);
54 bool bForwardPixelSnapHairline(true);
57 class ImpViewInformation2D
60 // ViewInformation2D implementation can change refcount, so we have only
61 // two memory regions for pairs of ViewInformation2D/ImpViewInformation2D
62 friend class ::drawinglayer::geometry::ViewInformation2D
;
65 // the object transformation
66 basegfx::B2DHomMatrix maObjectTransformation
;
68 // the view transformation
69 basegfx::B2DHomMatrix maViewTransformation
;
71 // the ObjectToView and it's inverse, both on demand from ObjectTransformation
72 // and ViewTransformation
73 basegfx::B2DHomMatrix maObjectToViewTransformation
;
74 basegfx::B2DHomMatrix maInverseObjectToViewTransformation
;
76 // the visible range and the on-demand one in ViewCoordinates
77 basegfx::B2DRange maViewport
;
78 basegfx::B2DRange maDiscreteViewport
;
80 // the DrawPage which is target of visualisation. This is needed e.g. for
81 // the view-dependent decomposition of PageNumber TextFields.
82 // This parameter is buffered here, but mainly resides in mxExtendedInformation,
83 // so it will be interpreted, but held there. It will also not be added
84 // to mxExtendedInformation in impFillViewInformationFromContent (it's there already)
85 uno::Reference
<drawing::XDrawPage
> mxVisualizedPage
;
90 // allow to reduce DisplayQuality (e.g. sw 3d fallback renderer for interactions)
91 bool mbReducedDisplayQuality
: 1;
93 // determine if to use AntiAliasing on target pixel device
94 bool mbUseAntiAliasing
: 1;
96 // determine if to use PixelSnapHairline on target pixel device
97 bool mbPixelSnapHairline
: 1;
100 ImpViewInformation2D()
101 : maObjectTransformation()
102 , maViewTransformation()
103 , maObjectToViewTransformation()
104 , maInverseObjectToViewTransformation()
106 , maDiscreteViewport()
109 , mbReducedDisplayQuality(false)
110 , mbUseAntiAliasing(ViewInformation2D::getGlobalAntiAliasing())
111 , mbPixelSnapHairline(mbUseAntiAliasing
&& bForwardPixelSnapHairline
)
115 const basegfx::B2DHomMatrix
& getObjectTransformation() const { return maObjectTransformation
; }
116 void setObjectTransformation(const basegfx::B2DHomMatrix
& rNew
)
118 maObjectTransformation
= rNew
;
119 maObjectToViewTransformation
.identity();
120 maInverseObjectToViewTransformation
.identity();
123 const basegfx::B2DHomMatrix
& getViewTransformation() const { return maViewTransformation
; }
124 void setViewTransformation(const basegfx::B2DHomMatrix
& rNew
)
126 maViewTransformation
= rNew
;
127 maDiscreteViewport
.reset();
128 maObjectToViewTransformation
.identity();
129 maInverseObjectToViewTransformation
.identity();
132 const basegfx::B2DRange
& getViewport() const { return maViewport
; }
133 void setViewport(const basegfx::B2DRange
& rNew
)
136 maDiscreteViewport
.reset();
139 const basegfx::B2DRange
& getDiscreteViewport() const
141 if (maDiscreteViewport
.isEmpty() && !maViewport
.isEmpty())
143 basegfx::B2DRange
aDiscreteViewport(maViewport
);
144 aDiscreteViewport
.transform(getViewTransformation());
145 const_cast<ImpViewInformation2D
*>(this)->maDiscreteViewport
= aDiscreteViewport
;
148 return maDiscreteViewport
;
151 const basegfx::B2DHomMatrix
& getObjectToViewTransformation() const
153 if (maObjectToViewTransformation
.isIdentity()
154 && (!maObjectTransformation
.isIdentity() || !maViewTransformation
.isIdentity()))
156 basegfx::B2DHomMatrix
aObjectToView(maViewTransformation
* maObjectTransformation
);
157 const_cast<ImpViewInformation2D
*>(this)->maObjectToViewTransformation
= aObjectToView
;
160 return maObjectToViewTransformation
;
163 const basegfx::B2DHomMatrix
& getInverseObjectToViewTransformation() const
165 if (maInverseObjectToViewTransformation
.isIdentity()
166 && (!maObjectTransformation
.isIdentity() || !maViewTransformation
.isIdentity()))
168 basegfx::B2DHomMatrix
aInverseObjectToView(maViewTransformation
169 * maObjectTransformation
);
170 aInverseObjectToView
.invert();
171 const_cast<ImpViewInformation2D
*>(this)->maInverseObjectToViewTransformation
172 = aInverseObjectToView
;
175 return maInverseObjectToViewTransformation
;
178 double getViewTime() const { return mfViewTime
; }
179 void setViewTime(double fNew
)
187 const uno::Reference
<drawing::XDrawPage
>& getVisualizedPage() const { return mxVisualizedPage
; }
188 void setVisualizedPage(const uno::Reference
<drawing::XDrawPage
>& rNew
)
190 mxVisualizedPage
= rNew
;
193 bool getReducedDisplayQuality() const { return mbReducedDisplayQuality
; }
194 void setReducedDisplayQuality(bool bNew
) { mbReducedDisplayQuality
= bNew
; }
196 bool getUseAntiAliasing() const { return mbUseAntiAliasing
; }
197 void setUseAntiAliasing(bool bNew
) { mbUseAntiAliasing
= bNew
; }
199 bool getPixelSnapHairline() const { return mbPixelSnapHairline
; }
200 void setPixelSnapHairline(bool bNew
) { mbPixelSnapHairline
= bNew
; }
202 bool operator==(const ImpViewInformation2D
& rCandidate
) const
204 return (maObjectTransformation
== rCandidate
.maObjectTransformation
205 && maViewTransformation
== rCandidate
.maViewTransformation
206 && maViewport
== rCandidate
.maViewport
207 && mxVisualizedPage
== rCandidate
.mxVisualizedPage
208 && mfViewTime
== rCandidate
.mfViewTime
209 && mbReducedDisplayQuality
== rCandidate
.mbReducedDisplayQuality
210 && mbUseAntiAliasing
== rCandidate
.mbUseAntiAliasing
211 && mbPixelSnapHairline
== rCandidate
.mbPixelSnapHairline
);
217 ViewInformation2D::ImplType
& theGlobalDefault()
219 static ViewInformation2D::ImplType SINGLETON
;
224 ViewInformation2D::ViewInformation2D()
225 : mpViewInformation2D(theGlobalDefault())
227 if (!bForwardsAreInitialized
)
229 bForwardsAreInitialized
= true;
230 if (!utl::ConfigManager::IsFuzzing())
232 bForwardPixelSnapHairline
233 = officecfg::Office::Common::Drawinglayer::SnapHorVerLinesToDiscrete::get();
237 setUseAntiAliasing(ViewInformation2D::getGlobalAntiAliasing());
238 setPixelSnapHairline(bForwardPixelSnapHairline
);
241 ViewInformation2D::ViewInformation2D(const ViewInformation2D
&) = default;
243 ViewInformation2D::ViewInformation2D(ViewInformation2D
&&) = default;
245 ViewInformation2D::~ViewInformation2D() = default;
247 ViewInformation2D
& ViewInformation2D::operator=(const ViewInformation2D
&) = default;
249 ViewInformation2D
& ViewInformation2D::operator=(ViewInformation2D
&&) = default;
251 bool ViewInformation2D::operator==(const ViewInformation2D
& rCandidate
) const
253 return rCandidate
.mpViewInformation2D
== mpViewInformation2D
;
256 const basegfx::B2DHomMatrix
& ViewInformation2D::getObjectTransformation() const
258 return mpViewInformation2D
->getObjectTransformation();
261 void ViewInformation2D::setObjectTransformation(const basegfx::B2DHomMatrix
& rNew
)
263 if (std::as_const(mpViewInformation2D
)->getObjectTransformation() != rNew
)
264 mpViewInformation2D
->setObjectTransformation(rNew
);
267 const basegfx::B2DHomMatrix
& ViewInformation2D::getViewTransformation() const
269 return mpViewInformation2D
->getViewTransformation();
272 void ViewInformation2D::setViewTransformation(const basegfx::B2DHomMatrix
& rNew
)
274 if (std::as_const(mpViewInformation2D
)->getViewTransformation() != rNew
)
275 mpViewInformation2D
->setViewTransformation(rNew
);
278 const basegfx::B2DRange
& ViewInformation2D::getViewport() const
280 return mpViewInformation2D
->getViewport();
283 void ViewInformation2D::setViewport(const basegfx::B2DRange
& rNew
)
285 if (rNew
!= std::as_const(mpViewInformation2D
)->getViewport())
286 mpViewInformation2D
->setViewport(rNew
);
289 double ViewInformation2D::getViewTime() const { return mpViewInformation2D
->getViewTime(); }
291 void ViewInformation2D::setViewTime(double fNew
)
293 if (fNew
!= std::as_const(mpViewInformation2D
)->getViewTime())
294 mpViewInformation2D
->setViewTime(fNew
);
297 const uno::Reference
<drawing::XDrawPage
>& ViewInformation2D::getVisualizedPage() const
299 return mpViewInformation2D
->getVisualizedPage();
302 void ViewInformation2D::setVisualizedPage(const uno::Reference
<drawing::XDrawPage
>& rNew
)
304 if (rNew
!= std::as_const(mpViewInformation2D
)->getVisualizedPage())
305 mpViewInformation2D
->setVisualizedPage(rNew
);
308 const basegfx::B2DHomMatrix
& ViewInformation2D::getObjectToViewTransformation() const
310 return mpViewInformation2D
->getObjectToViewTransformation();
313 const basegfx::B2DHomMatrix
& ViewInformation2D::getInverseObjectToViewTransformation() const
315 return mpViewInformation2D
->getInverseObjectToViewTransformation();
318 const basegfx::B2DRange
& ViewInformation2D::getDiscreteViewport() const
320 return mpViewInformation2D
->getDiscreteViewport();
323 bool ViewInformation2D::getReducedDisplayQuality() const
325 return mpViewInformation2D
->getReducedDisplayQuality();
328 void ViewInformation2D::setReducedDisplayQuality(bool bNew
)
330 if (bNew
!= std::as_const(mpViewInformation2D
)->getReducedDisplayQuality())
331 mpViewInformation2D
->setReducedDisplayQuality(bNew
);
334 bool ViewInformation2D::getUseAntiAliasing() const
336 return mpViewInformation2D
->getUseAntiAliasing();
339 void ViewInformation2D::setUseAntiAliasing(bool bNew
)
341 if (bNew
!= std::as_const(mpViewInformation2D
)->getUseAntiAliasing())
342 mpViewInformation2D
->setUseAntiAliasing(bNew
);
345 bool ViewInformation2D::getPixelSnapHairline() const
347 return mpViewInformation2D
->getPixelSnapHairline();
350 void ViewInformation2D::setPixelSnapHairline(bool bNew
)
352 if (bNew
!= std::as_const(mpViewInformation2D
)->getPixelSnapHairline())
353 mpViewInformation2D
->setPixelSnapHairline(bNew
);
356 static std::atomic
<bool>& globalAntiAliasing()
358 static std::atomic
<bool> g_GlobalAntiAliasing
359 = utl::ConfigManager::IsFuzzing()
360 || officecfg::Office::Common::Drawinglayer::AntiAliasing::get();
361 return g_GlobalAntiAliasing
;
365 * Some code like to turn this stuff on and off during a drawing operation
366 * so it can "tunnel" information down through several layers,
367 * so we don't want to actually do a config write all the time.
369 void ViewInformation2D::setGlobalAntiAliasing(bool bAntiAliasing
, bool bTemporary
)
371 if (globalAntiAliasing().compare_exchange_strong(o3tl::temporary(!bAntiAliasing
), bAntiAliasing
)
374 auto batch
= comphelper::ConfigurationChanges::create();
375 officecfg::Office::Common::Drawinglayer::AntiAliasing::set(bAntiAliasing
, batch
);
379 bool ViewInformation2D::getGlobalAntiAliasing() { return globalAntiAliasing(); }
381 void ViewInformation2D::forwardPixelSnapHairline(bool bPixelSnapHairline
)
383 bForwardPixelSnapHairline
= bPixelSnapHairline
;
387 createViewInformation2D(const css::uno::Sequence
<css::beans::PropertyValue
>& rViewParameters
)
389 if (!rViewParameters
.hasElements())
390 return ViewInformation2D();
392 ViewInformation2D aRetval
;
394 for (auto const& rPropertyValue
: rViewParameters
)
396 if (rPropertyValue
.Name
== g_PropertyName_ReducedDisplayQuality
)
399 rPropertyValue
.Value
>>= bNew
;
400 aRetval
.setReducedDisplayQuality(bNew
);
402 else if (rPropertyValue
.Name
== g_PropertyName_PixelSnapHairline
)
405 true); //SvtOptionsDrawinglayer::IsAntiAliasing() && SvtOptionsDrawinglayer::IsSnapHorVerLinesToDiscrete());
406 rPropertyValue
.Value
>>= bNew
;
407 aRetval
.setPixelSnapHairline(bNew
);
409 else if (rPropertyValue
.Name
== g_PropertyName_UseAntiAliasing
)
411 bool bNew(true); //SvtOptionsDrawinglayer::IsAntiAliasing());
412 rPropertyValue
.Value
>>= bNew
;
413 aRetval
.setUseAntiAliasing(bNew
);
415 else if (rPropertyValue
.Name
== g_PropertyName_ObjectTransformation
)
417 css::geometry::AffineMatrix2D aAffineMatrix2D
;
418 rPropertyValue
.Value
>>= aAffineMatrix2D
;
419 basegfx::B2DHomMatrix aTransformation
;
420 basegfx::unotools::homMatrixFromAffineMatrix(aTransformation
, aAffineMatrix2D
);
421 aRetval
.setObjectTransformation(aTransformation
);
423 else if (rPropertyValue
.Name
== g_PropertyName_ViewTransformation
)
425 css::geometry::AffineMatrix2D aAffineMatrix2D
;
426 rPropertyValue
.Value
>>= aAffineMatrix2D
;
427 basegfx::B2DHomMatrix aTransformation
;
428 basegfx::unotools::homMatrixFromAffineMatrix(aTransformation
, aAffineMatrix2D
);
429 aRetval
.setViewTransformation(aTransformation
);
431 else if (rPropertyValue
.Name
== g_PropertyName_Viewport
)
433 css::geometry::RealRectangle2D aUnoViewport
;
434 rPropertyValue
.Value
>>= aUnoViewport
;
435 const basegfx::B2DRange
aViewport(
436 basegfx::unotools::b2DRectangleFromRealRectangle2D(aUnoViewport
));
437 aRetval
.setViewport(aViewport
);
439 else if (rPropertyValue
.Name
== g_PropertyName_Time
)
441 double fViewTime(0.0);
442 rPropertyValue
.Value
>>= fViewTime
;
443 aRetval
.setViewTime(fViewTime
);
445 else if (rPropertyValue
.Name
== g_PropertyName_VisualizedPage
)
447 css::uno::Reference
<css::drawing::XDrawPage
> xVisualizedPage
;
448 rPropertyValue
.Value
>>= xVisualizedPage
;
449 aRetval
.setVisualizedPage(xVisualizedPage
);
456 } // end of namespace drawinglayer::geometry
458 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */