Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / drawinglayer / source / geometry / viewinformation2d.cxx
blob03089e41e36f32ed93331880df7ad4f2f8bae092
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
32 #include <atomic>
33 #include <utility>
35 using namespace com::sun::star;
37 namespace drawinglayer::geometry
39 namespace
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";
51 namespace
53 bool bForwardsAreInitialized(false);
54 bool bForwardPixelSnapHairline(true);
57 class ImpViewInformation2D
59 private:
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;
64 protected:
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;
87 // the point in time
88 double mfViewTime;
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;
99 public:
100 ImpViewInformation2D()
101 : maObjectTransformation()
102 , maViewTransformation()
103 , maObjectToViewTransformation()
104 , maInverseObjectToViewTransformation()
105 , maViewport()
106 , maDiscreteViewport()
107 , mxVisualizedPage()
108 , mfViewTime(0.0)
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)
135 maViewport = 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)
181 if (fNew >= 0.0)
183 mfViewTime = 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);
215 namespace
217 ViewInformation2D::ImplType& theGlobalDefault()
219 static ViewInformation2D::ImplType SINGLETON;
220 return 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)
372 && !bTemporary)
374 auto batch = comphelper::ConfigurationChanges::create();
375 officecfg::Office::Common::Drawinglayer::AntiAliasing::set(bAntiAliasing, batch);
376 batch->commit();
379 bool ViewInformation2D::getGlobalAntiAliasing() { return globalAntiAliasing(); }
381 void ViewInformation2D::forwardPixelSnapHairline(bool bPixelSnapHairline)
383 bForwardPixelSnapHairline = bPixelSnapHairline;
386 ViewInformation2D
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)
398 bool bNew(false);
399 rPropertyValue.Value >>= bNew;
400 aRetval.setReducedDisplayQuality(bNew);
402 else if (rPropertyValue.Name == g_PropertyName_PixelSnapHairline)
404 bool bNew(
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);
453 return aRetval;
456 } // end of namespace drawinglayer::geometry
458 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */