summaryrefslogtreecommitdiffstats
path: root/drawinglayer/source/geometry
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
commit267c6f2ac71f92999e969232431ba04678e7437e (patch)
tree358c9467650e1d0a1d7227a21dac2e3d08b622b2 /drawinglayer/source/geometry
parentInitial commit. (diff)
downloadlibreoffice-267c6f2ac71f92999e969232431ba04678e7437e.tar.xz
libreoffice-267c6f2ac71f92999e969232431ba04678e7437e.zip
Adding upstream version 4:24.2.0.upstream/4%24.2.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'drawinglayer/source/geometry')
-rw-r--r--drawinglayer/source/geometry/viewinformation2d.cxx458
-rw-r--r--drawinglayer/source/geometry/viewinformation3d.cxx367
2 files changed, 825 insertions, 0 deletions
diff --git a/drawinglayer/source/geometry/viewinformation2d.cxx b/drawinglayer/source/geometry/viewinformation2d.cxx
new file mode 100644
index 0000000000..03089e41e3
--- /dev/null
+++ b/drawinglayer/source/geometry/viewinformation2d.cxx
@@ -0,0 +1,458 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <drawinglayer/geometry/viewinformation2d.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/range/b2drange.hxx>
+#include <basegfx/utils/canvastools.hxx>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/drawing/XDrawPage.hpp>
+#include <com/sun/star/geometry/AffineMatrix2D.hpp>
+#include <com/sun/star/geometry/RealRectangle2D.hpp>
+#include <o3tl/temporary.hxx>
+#include <officecfg/Office/Common.hxx>
+#include <unotools/configmgr.hxx>
+
+#include <atomic>
+#include <utility>
+
+using namespace com::sun::star;
+
+namespace drawinglayer::geometry
+{
+namespace
+{
+constexpr OUStringLiteral g_PropertyName_ObjectTransformation = u"ObjectTransformation";
+constexpr OUStringLiteral g_PropertyName_ViewTransformation = u"ViewTransformation";
+constexpr OUStringLiteral g_PropertyName_Viewport = u"Viewport";
+constexpr OUStringLiteral g_PropertyName_Time = u"Time";
+constexpr OUStringLiteral g_PropertyName_VisualizedPage = u"VisualizedPage";
+constexpr OUStringLiteral g_PropertyName_ReducedDisplayQuality = u"ReducedDisplayQuality";
+constexpr OUStringLiteral g_PropertyName_UseAntiAliasing = u"UseAntiAliasing";
+constexpr OUStringLiteral g_PropertyName_PixelSnapHairline = u"PixelSnapHairline";
+}
+
+namespace
+{
+bool bForwardsAreInitialized(false);
+bool bForwardPixelSnapHairline(true);
+}
+
+class ImpViewInformation2D
+{
+private:
+ // ViewInformation2D implementation can change refcount, so we have only
+ // two memory regions for pairs of ViewInformation2D/ImpViewInformation2D
+ friend class ::drawinglayer::geometry::ViewInformation2D;
+
+protected:
+ // the object transformation
+ basegfx::B2DHomMatrix maObjectTransformation;
+
+ // the view transformation
+ basegfx::B2DHomMatrix maViewTransformation;
+
+ // the ObjectToView and it's inverse, both on demand from ObjectTransformation
+ // and ViewTransformation
+ basegfx::B2DHomMatrix maObjectToViewTransformation;
+ basegfx::B2DHomMatrix maInverseObjectToViewTransformation;
+
+ // the visible range and the on-demand one in ViewCoordinates
+ basegfx::B2DRange maViewport;
+ basegfx::B2DRange maDiscreteViewport;
+
+ // the DrawPage which is target of visualisation. This is needed e.g. for
+ // the view-dependent decomposition of PageNumber TextFields.
+ // This parameter is buffered here, but mainly resides in mxExtendedInformation,
+ // so it will be interpreted, but held there. It will also not be added
+ // to mxExtendedInformation in impFillViewInformationFromContent (it's there already)
+ uno::Reference<drawing::XDrawPage> mxVisualizedPage;
+
+ // the point in time
+ double mfViewTime;
+
+ // allow to reduce DisplayQuality (e.g. sw 3d fallback renderer for interactions)
+ bool mbReducedDisplayQuality : 1;
+
+ // determine if to use AntiAliasing on target pixel device
+ bool mbUseAntiAliasing : 1;
+
+ // determine if to use PixelSnapHairline on target pixel device
+ bool mbPixelSnapHairline : 1;
+
+public:
+ ImpViewInformation2D()
+ : maObjectTransformation()
+ , maViewTransformation()
+ , maObjectToViewTransformation()
+ , maInverseObjectToViewTransformation()
+ , maViewport()
+ , maDiscreteViewport()
+ , mxVisualizedPage()
+ , mfViewTime(0.0)
+ , mbReducedDisplayQuality(false)
+ , mbUseAntiAliasing(ViewInformation2D::getGlobalAntiAliasing())
+ , mbPixelSnapHairline(mbUseAntiAliasing && bForwardPixelSnapHairline)
+ {
+ }
+
+ const basegfx::B2DHomMatrix& getObjectTransformation() const { return maObjectTransformation; }
+ void setObjectTransformation(const basegfx::B2DHomMatrix& rNew)
+ {
+ maObjectTransformation = rNew;
+ maObjectToViewTransformation.identity();
+ maInverseObjectToViewTransformation.identity();
+ }
+
+ const basegfx::B2DHomMatrix& getViewTransformation() const { return maViewTransformation; }
+ void setViewTransformation(const basegfx::B2DHomMatrix& rNew)
+ {
+ maViewTransformation = rNew;
+ maDiscreteViewport.reset();
+ maObjectToViewTransformation.identity();
+ maInverseObjectToViewTransformation.identity();
+ }
+
+ const basegfx::B2DRange& getViewport() const { return maViewport; }
+ void setViewport(const basegfx::B2DRange& rNew)
+ {
+ maViewport = rNew;
+ maDiscreteViewport.reset();
+ }
+
+ const basegfx::B2DRange& getDiscreteViewport() const
+ {
+ if (maDiscreteViewport.isEmpty() && !maViewport.isEmpty())
+ {
+ basegfx::B2DRange aDiscreteViewport(maViewport);
+ aDiscreteViewport.transform(getViewTransformation());
+ const_cast<ImpViewInformation2D*>(this)->maDiscreteViewport = aDiscreteViewport;
+ }
+
+ return maDiscreteViewport;
+ }
+
+ const basegfx::B2DHomMatrix& getObjectToViewTransformation() const
+ {
+ if (maObjectToViewTransformation.isIdentity()
+ && (!maObjectTransformation.isIdentity() || !maViewTransformation.isIdentity()))
+ {
+ basegfx::B2DHomMatrix aObjectToView(maViewTransformation * maObjectTransformation);
+ const_cast<ImpViewInformation2D*>(this)->maObjectToViewTransformation = aObjectToView;
+ }
+
+ return maObjectToViewTransformation;
+ }
+
+ const basegfx::B2DHomMatrix& getInverseObjectToViewTransformation() const
+ {
+ if (maInverseObjectToViewTransformation.isIdentity()
+ && (!maObjectTransformation.isIdentity() || !maViewTransformation.isIdentity()))
+ {
+ basegfx::B2DHomMatrix aInverseObjectToView(maViewTransformation
+ * maObjectTransformation);
+ aInverseObjectToView.invert();
+ const_cast<ImpViewInformation2D*>(this)->maInverseObjectToViewTransformation
+ = aInverseObjectToView;
+ }
+
+ return maInverseObjectToViewTransformation;
+ }
+
+ double getViewTime() const { return mfViewTime; }
+ void setViewTime(double fNew)
+ {
+ if (fNew >= 0.0)
+ {
+ mfViewTime = fNew;
+ }
+ }
+
+ const uno::Reference<drawing::XDrawPage>& getVisualizedPage() const { return mxVisualizedPage; }
+ void setVisualizedPage(const uno::Reference<drawing::XDrawPage>& rNew)
+ {
+ mxVisualizedPage = rNew;
+ }
+
+ bool getReducedDisplayQuality() const { return mbReducedDisplayQuality; }
+ void setReducedDisplayQuality(bool bNew) { mbReducedDisplayQuality = bNew; }
+
+ bool getUseAntiAliasing() const { return mbUseAntiAliasing; }
+ void setUseAntiAliasing(bool bNew) { mbUseAntiAliasing = bNew; }
+
+ bool getPixelSnapHairline() const { return mbPixelSnapHairline; }
+ void setPixelSnapHairline(bool bNew) { mbPixelSnapHairline = bNew; }
+
+ bool operator==(const ImpViewInformation2D& rCandidate) const
+ {
+ return (maObjectTransformation == rCandidate.maObjectTransformation
+ && maViewTransformation == rCandidate.maViewTransformation
+ && maViewport == rCandidate.maViewport
+ && mxVisualizedPage == rCandidate.mxVisualizedPage
+ && mfViewTime == rCandidate.mfViewTime
+ && mbReducedDisplayQuality == rCandidate.mbReducedDisplayQuality
+ && mbUseAntiAliasing == rCandidate.mbUseAntiAliasing
+ && mbPixelSnapHairline == rCandidate.mbPixelSnapHairline);
+ }
+};
+
+namespace
+{
+ViewInformation2D::ImplType& theGlobalDefault()
+{
+ static ViewInformation2D::ImplType SINGLETON;
+ return SINGLETON;
+}
+}
+
+ViewInformation2D::ViewInformation2D()
+ : mpViewInformation2D(theGlobalDefault())
+{
+ if (!bForwardsAreInitialized)
+ {
+ bForwardsAreInitialized = true;
+ if (!utl::ConfigManager::IsFuzzing())
+ {
+ bForwardPixelSnapHairline
+ = officecfg::Office::Common::Drawinglayer::SnapHorVerLinesToDiscrete::get();
+ }
+ }
+
+ setUseAntiAliasing(ViewInformation2D::getGlobalAntiAliasing());
+ setPixelSnapHairline(bForwardPixelSnapHairline);
+}
+
+ViewInformation2D::ViewInformation2D(const ViewInformation2D&) = default;
+
+ViewInformation2D::ViewInformation2D(ViewInformation2D&&) = default;
+
+ViewInformation2D::~ViewInformation2D() = default;
+
+ViewInformation2D& ViewInformation2D::operator=(const ViewInformation2D&) = default;
+
+ViewInformation2D& ViewInformation2D::operator=(ViewInformation2D&&) = default;
+
+bool ViewInformation2D::operator==(const ViewInformation2D& rCandidate) const
+{
+ return rCandidate.mpViewInformation2D == mpViewInformation2D;
+}
+
+const basegfx::B2DHomMatrix& ViewInformation2D::getObjectTransformation() const
+{
+ return mpViewInformation2D->getObjectTransformation();
+}
+
+void ViewInformation2D::setObjectTransformation(const basegfx::B2DHomMatrix& rNew)
+{
+ if (std::as_const(mpViewInformation2D)->getObjectTransformation() != rNew)
+ mpViewInformation2D->setObjectTransformation(rNew);
+}
+
+const basegfx::B2DHomMatrix& ViewInformation2D::getViewTransformation() const
+{
+ return mpViewInformation2D->getViewTransformation();
+}
+
+void ViewInformation2D::setViewTransformation(const basegfx::B2DHomMatrix& rNew)
+{
+ if (std::as_const(mpViewInformation2D)->getViewTransformation() != rNew)
+ mpViewInformation2D->setViewTransformation(rNew);
+}
+
+const basegfx::B2DRange& ViewInformation2D::getViewport() const
+{
+ return mpViewInformation2D->getViewport();
+}
+
+void ViewInformation2D::setViewport(const basegfx::B2DRange& rNew)
+{
+ if (rNew != std::as_const(mpViewInformation2D)->getViewport())
+ mpViewInformation2D->setViewport(rNew);
+}
+
+double ViewInformation2D::getViewTime() const { return mpViewInformation2D->getViewTime(); }
+
+void ViewInformation2D::setViewTime(double fNew)
+{
+ if (fNew != std::as_const(mpViewInformation2D)->getViewTime())
+ mpViewInformation2D->setViewTime(fNew);
+}
+
+const uno::Reference<drawing::XDrawPage>& ViewInformation2D::getVisualizedPage() const
+{
+ return mpViewInformation2D->getVisualizedPage();
+}
+
+void ViewInformation2D::setVisualizedPage(const uno::Reference<drawing::XDrawPage>& rNew)
+{
+ if (rNew != std::as_const(mpViewInformation2D)->getVisualizedPage())
+ mpViewInformation2D->setVisualizedPage(rNew);
+}
+
+const basegfx::B2DHomMatrix& ViewInformation2D::getObjectToViewTransformation() const
+{
+ return mpViewInformation2D->getObjectToViewTransformation();
+}
+
+const basegfx::B2DHomMatrix& ViewInformation2D::getInverseObjectToViewTransformation() const
+{
+ return mpViewInformation2D->getInverseObjectToViewTransformation();
+}
+
+const basegfx::B2DRange& ViewInformation2D::getDiscreteViewport() const
+{
+ return mpViewInformation2D->getDiscreteViewport();
+}
+
+bool ViewInformation2D::getReducedDisplayQuality() const
+{
+ return mpViewInformation2D->getReducedDisplayQuality();
+}
+
+void ViewInformation2D::setReducedDisplayQuality(bool bNew)
+{
+ if (bNew != std::as_const(mpViewInformation2D)->getReducedDisplayQuality())
+ mpViewInformation2D->setReducedDisplayQuality(bNew);
+}
+
+bool ViewInformation2D::getUseAntiAliasing() const
+{
+ return mpViewInformation2D->getUseAntiAliasing();
+}
+
+void ViewInformation2D::setUseAntiAliasing(bool bNew)
+{
+ if (bNew != std::as_const(mpViewInformation2D)->getUseAntiAliasing())
+ mpViewInformation2D->setUseAntiAliasing(bNew);
+}
+
+bool ViewInformation2D::getPixelSnapHairline() const
+{
+ return mpViewInformation2D->getPixelSnapHairline();
+}
+
+void ViewInformation2D::setPixelSnapHairline(bool bNew)
+{
+ if (bNew != std::as_const(mpViewInformation2D)->getPixelSnapHairline())
+ mpViewInformation2D->setPixelSnapHairline(bNew);
+}
+
+static std::atomic<bool>& globalAntiAliasing()
+{
+ static std::atomic<bool> g_GlobalAntiAliasing
+ = utl::ConfigManager::IsFuzzing()
+ || officecfg::Office::Common::Drawinglayer::AntiAliasing::get();
+ return g_GlobalAntiAliasing;
+}
+
+/**
+ * Some code like to turn this stuff on and off during a drawing operation
+ * so it can "tunnel" information down through several layers,
+ * so we don't want to actually do a config write all the time.
+ */
+void ViewInformation2D::setGlobalAntiAliasing(bool bAntiAliasing, bool bTemporary)
+{
+ if (globalAntiAliasing().compare_exchange_strong(o3tl::temporary(!bAntiAliasing), bAntiAliasing)
+ && !bTemporary)
+ {
+ auto batch = comphelper::ConfigurationChanges::create();
+ officecfg::Office::Common::Drawinglayer::AntiAliasing::set(bAntiAliasing, batch);
+ batch->commit();
+ }
+}
+bool ViewInformation2D::getGlobalAntiAliasing() { return globalAntiAliasing(); }
+
+void ViewInformation2D::forwardPixelSnapHairline(bool bPixelSnapHairline)
+{
+ bForwardPixelSnapHairline = bPixelSnapHairline;
+}
+
+ViewInformation2D
+createViewInformation2D(const css::uno::Sequence<css::beans::PropertyValue>& rViewParameters)
+{
+ if (!rViewParameters.hasElements())
+ return ViewInformation2D();
+
+ ViewInformation2D aRetval;
+
+ for (auto const& rPropertyValue : rViewParameters)
+ {
+ if (rPropertyValue.Name == g_PropertyName_ReducedDisplayQuality)
+ {
+ bool bNew(false);
+ rPropertyValue.Value >>= bNew;
+ aRetval.setReducedDisplayQuality(bNew);
+ }
+ else if (rPropertyValue.Name == g_PropertyName_PixelSnapHairline)
+ {
+ bool bNew(
+ true); //SvtOptionsDrawinglayer::IsAntiAliasing() && SvtOptionsDrawinglayer::IsSnapHorVerLinesToDiscrete());
+ rPropertyValue.Value >>= bNew;
+ aRetval.setPixelSnapHairline(bNew);
+ }
+ else if (rPropertyValue.Name == g_PropertyName_UseAntiAliasing)
+ {
+ bool bNew(true); //SvtOptionsDrawinglayer::IsAntiAliasing());
+ rPropertyValue.Value >>= bNew;
+ aRetval.setUseAntiAliasing(bNew);
+ }
+ else if (rPropertyValue.Name == g_PropertyName_ObjectTransformation)
+ {
+ css::geometry::AffineMatrix2D aAffineMatrix2D;
+ rPropertyValue.Value >>= aAffineMatrix2D;
+ basegfx::B2DHomMatrix aTransformation;
+ basegfx::unotools::homMatrixFromAffineMatrix(aTransformation, aAffineMatrix2D);
+ aRetval.setObjectTransformation(aTransformation);
+ }
+ else if (rPropertyValue.Name == g_PropertyName_ViewTransformation)
+ {
+ css::geometry::AffineMatrix2D aAffineMatrix2D;
+ rPropertyValue.Value >>= aAffineMatrix2D;
+ basegfx::B2DHomMatrix aTransformation;
+ basegfx::unotools::homMatrixFromAffineMatrix(aTransformation, aAffineMatrix2D);
+ aRetval.setViewTransformation(aTransformation);
+ }
+ else if (rPropertyValue.Name == g_PropertyName_Viewport)
+ {
+ css::geometry::RealRectangle2D aUnoViewport;
+ rPropertyValue.Value >>= aUnoViewport;
+ const basegfx::B2DRange aViewport(
+ basegfx::unotools::b2DRectangleFromRealRectangle2D(aUnoViewport));
+ aRetval.setViewport(aViewport);
+ }
+ else if (rPropertyValue.Name == g_PropertyName_Time)
+ {
+ double fViewTime(0.0);
+ rPropertyValue.Value >>= fViewTime;
+ aRetval.setViewTime(fViewTime);
+ }
+ else if (rPropertyValue.Name == g_PropertyName_VisualizedPage)
+ {
+ css::uno::Reference<css::drawing::XDrawPage> xVisualizedPage;
+ rPropertyValue.Value >>= xVisualizedPage;
+ aRetval.setVisualizedPage(xVisualizedPage);
+ }
+ }
+
+ return aRetval;
+}
+
+} // end of namespace drawinglayer::geometry
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/drawinglayer/source/geometry/viewinformation3d.cxx b/drawinglayer/source/geometry/viewinformation3d.cxx
new file mode 100644
index 0000000000..1fb3344c8b
--- /dev/null
+++ b/drawinglayer/source/geometry/viewinformation3d.cxx
@@ -0,0 +1,367 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <drawinglayer/geometry/viewinformation3d.hxx>
+#include <basegfx/matrix/b3dhommatrix.hxx>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/geometry/AffineMatrix3D.hpp>
+#include <basegfx/utils/canvastools.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <utility>
+
+
+using namespace com::sun::star;
+
+
+namespace drawinglayer::geometry
+{
+ /** Implementation class for ViewInformation3D
+ */
+ class ImpViewInformation3D
+ {
+ private:
+ // ViewInformation3D implementation can change refcount, so we have only
+ // two memory regions for pairs of ViewInformation3D/ImpViewInformation3D
+ friend class ::drawinglayer::geometry::ViewInformation3D;
+
+ // the 3D transformations
+ // Object to World. This may change and being adapted when entering 3D transformation
+ // groups
+ basegfx::B3DHomMatrix maObjectTransformation;
+
+ // World to Camera. This includes VRP, VPN and VUV camera coordinate system
+ basegfx::B3DHomMatrix maOrientation;
+
+ // Camera to Device with X,Y and Z [-1.0 .. 1.0]. This is the
+ // 3D to 2D projection which may be parallel or perspective. When it is perspective,
+ // the last line of the homogen matrix will NOT be unused
+ basegfx::B3DHomMatrix maProjection;
+
+ // Device to View with X,Y and Z [0.0 .. 1.0]. This converts from -1 to 1 coordinates
+ // in camera coordinate system to 0 to 1 in unit 2D coordinates. This way it stays
+ // view-independent. To get discrete coordinates, the 2D transformation of a scene
+ // as 2D object needs to be involved
+ basegfx::B3DHomMatrix maDeviceToView;
+
+ // Object to View is the linear combination of all four transformations. It's
+ // buffered to avoid too much matrix multiplying and created on demand
+ basegfx::B3DHomMatrix maObjectToView;
+
+ // the point in time
+ double mfViewTime;
+
+ // the extra PropertyValues; does not contain the transformations
+ uno::Sequence< beans::PropertyValue > mxExtendedInformation;
+
+ // the local UNO API strings
+ static OUString getNamePropertyObjectTransformation()
+ {
+ return "ObjectTransformation";
+ }
+
+ static OUString getNamePropertyOrientation()
+ {
+ return "Orientation";
+ }
+
+ static OUString getNamePropertyProjection()
+ {
+ return "Projection";
+ }
+
+ static OUString getNamePropertyProjection_30()
+ {
+ return "Projection30";
+ }
+
+ static OUString getNamePropertyProjection_31()
+ {
+ return "Projection31";
+ }
+
+ static OUString getNamePropertyProjection_32()
+ {
+ return "Projection32";
+ }
+
+ static OUString getNamePropertyProjection_33()
+ {
+ return "Projection33";
+ }
+
+ static OUString getNamePropertyDeviceToView()
+ {
+ return "DeviceToView";
+ }
+
+ static OUString getNamePropertyTime()
+ {
+ return "Time";
+ }
+
+ // a central PropertyValue parsing method to allow transportation of
+ // all ViewParameters using UNO API
+ void impInterpretPropertyValues(const uno::Sequence< beans::PropertyValue >& rViewParameters)
+ {
+ if(!rViewParameters.hasElements())
+ return;
+
+ const sal_Int32 nCount(rViewParameters.getLength());
+ sal_Int32 nExtendedInsert(0);
+
+ // prepare extended information for filtering. Maximum size is nCount
+ mxExtendedInformation.realloc(nCount);
+ auto pExtendedInformation = mxExtendedInformation.getArray();
+
+ for(sal_Int32 a(0); a < nCount; a++)
+ {
+ const beans::PropertyValue& rProp = rViewParameters[a];
+
+ if(rProp.Name == getNamePropertyObjectTransformation())
+ {
+ css::geometry::AffineMatrix3D aAffineMatrix3D;
+ rProp.Value >>= aAffineMatrix3D;
+ maObjectTransformation = basegfx::unotools::homMatrixFromAffineMatrix3D(aAffineMatrix3D);
+ }
+ else if(rProp.Name == getNamePropertyOrientation())
+ {
+ css::geometry::AffineMatrix3D aAffineMatrix3D;
+ rProp.Value >>= aAffineMatrix3D;
+ maOrientation = basegfx::unotools::homMatrixFromAffineMatrix3D(aAffineMatrix3D);
+ }
+ else if(rProp.Name == getNamePropertyProjection())
+ {
+ // projection may be defined using a frustum in which case the last line of
+ // the 4x4 matrix is not (0,0,0,1). Since AffineMatrix3D does not support that,
+ // these four values need to be treated extra
+ const double f_30(maProjection.get(3, 0));
+ const double f_31(maProjection.get(3, 1));
+ const double f_32(maProjection.get(3, 2));
+ const double f_33(maProjection.get(3, 3));
+
+ css::geometry::AffineMatrix3D aAffineMatrix3D;
+ rProp.Value >>= aAffineMatrix3D;
+ maProjection = basegfx::unotools::homMatrixFromAffineMatrix3D(aAffineMatrix3D);
+
+ maProjection.set(3, 0, f_30);
+ maProjection.set(3, 1, f_31);
+ maProjection.set(3, 2, f_32);
+ maProjection.set(3, 3, f_33);
+ }
+ else if(rProp.Name == getNamePropertyProjection_30())
+ {
+ double f_30(0.0);
+ rProp.Value >>= f_30;
+ maProjection.set(3, 0, f_30);
+ }
+ else if(rProp.Name == getNamePropertyProjection_31())
+ {
+ double f_31(0.0);
+ rProp.Value >>= f_31;
+ maProjection.set(3, 1, f_31);
+ }
+ else if(rProp.Name == getNamePropertyProjection_32())
+ {
+ double f_32(0.0);
+ rProp.Value >>= f_32;
+ maProjection.set(3, 2, f_32);
+ }
+ else if(rProp.Name == getNamePropertyProjection_33())
+ {
+ double f_33(1.0);
+ rProp.Value >>= f_33;
+ maProjection.set(3, 3, f_33);
+ }
+ else if(rProp.Name == getNamePropertyDeviceToView())
+ {
+ css::geometry::AffineMatrix3D aAffineMatrix3D;
+ rProp.Value >>= aAffineMatrix3D;
+ maDeviceToView = basegfx::unotools::homMatrixFromAffineMatrix3D(aAffineMatrix3D);
+ }
+ else if(rProp.Name == getNamePropertyTime())
+ {
+ rProp.Value >>= mfViewTime;
+ }
+ else
+ {
+ // extra information; add to filtered information
+ pExtendedInformation[nExtendedInsert++] = rProp;
+ }
+ }
+
+ // extra information size is now known; realloc to final size
+ mxExtendedInformation.realloc(nExtendedInsert);
+ }
+
+ public:
+ ImpViewInformation3D(
+ basegfx::B3DHomMatrix aObjectTransformation,
+ basegfx::B3DHomMatrix aOrientation,
+ basegfx::B3DHomMatrix aProjection,
+ basegfx::B3DHomMatrix aDeviceToView,
+ double fViewTime,
+ const uno::Sequence< beans::PropertyValue >& rExtendedParameters)
+ : maObjectTransformation(std::move(aObjectTransformation)),
+ maOrientation(std::move(aOrientation)),
+ maProjection(std::move(aProjection)),
+ maDeviceToView(std::move(aDeviceToView)),
+ mfViewTime(fViewTime)
+ {
+ impInterpretPropertyValues(rExtendedParameters);
+ }
+
+ explicit ImpViewInformation3D(const uno::Sequence< beans::PropertyValue >& rViewParameters)
+ : mfViewTime()
+ {
+ impInterpretPropertyValues(rViewParameters);
+ }
+
+ ImpViewInformation3D()
+ : mfViewTime()
+ {
+ }
+
+ const basegfx::B3DHomMatrix& getObjectTransformation() const { return maObjectTransformation; }
+ const basegfx::B3DHomMatrix& getOrientation() const { return maOrientation; }
+ const basegfx::B3DHomMatrix& getProjection() const { return maProjection; }
+ const basegfx::B3DHomMatrix& getDeviceToView() const { return maDeviceToView; }
+ double getViewTime() const { return mfViewTime; }
+
+ const basegfx::B3DHomMatrix& getObjectToView() const
+ {
+ // on demand WorldToView creation
+
+ if(maObjectToView.isIdentity())
+ {
+ const_cast< ImpViewInformation3D* >(this)->maObjectToView = maDeviceToView * maProjection * maOrientation * maObjectTransformation;
+ }
+
+ return maObjectToView;
+ }
+
+ const uno::Sequence< beans::PropertyValue >& getExtendedInformationSequence() const
+ {
+ return mxExtendedInformation;
+ }
+
+ bool operator==(const ImpViewInformation3D& rCandidate) const
+ {
+ return (maObjectTransformation == rCandidate.maObjectTransformation
+ && maOrientation == rCandidate.maOrientation
+ && maProjection == rCandidate.maProjection
+ && maDeviceToView == rCandidate.maDeviceToView
+ && mfViewTime == rCandidate.mfViewTime
+ && mxExtendedInformation == rCandidate.mxExtendedInformation);
+ }
+ };
+} // end of namespace drawinglayer::geometry
+
+
+namespace drawinglayer::geometry
+{
+ namespace
+ {
+ ViewInformation3D::ImplType& theGlobalDefault()
+ {
+ static ViewInformation3D::ImplType SINGLETON;
+ return SINGLETON;
+ }
+ }
+
+ ViewInformation3D::ViewInformation3D(
+ const basegfx::B3DHomMatrix& rObjectObjectTransformation,
+ const basegfx::B3DHomMatrix& rOrientation,
+ const basegfx::B3DHomMatrix& rProjection,
+ const basegfx::B3DHomMatrix& rDeviceToView,
+ double fViewTime,
+ const uno::Sequence< beans::PropertyValue >& rExtendedParameters)
+ : mpViewInformation3D(ImpViewInformation3D(
+ rObjectObjectTransformation, rOrientation, rProjection,
+ rDeviceToView, fViewTime, rExtendedParameters))
+ {
+ }
+
+ ViewInformation3D::ViewInformation3D(const uno::Sequence< beans::PropertyValue >& rViewParameters)
+ : mpViewInformation3D(ImpViewInformation3D(rViewParameters))
+ {
+ }
+
+ ViewInformation3D::ViewInformation3D()
+ : mpViewInformation3D(theGlobalDefault())
+ {
+ }
+
+ ViewInformation3D::ViewInformation3D(const ViewInformation3D&) = default;
+
+ ViewInformation3D::ViewInformation3D(ViewInformation3D&&) = default;
+
+ ViewInformation3D::~ViewInformation3D() = default;
+
+ bool ViewInformation3D::isDefault() const
+ {
+ return mpViewInformation3D.same_object(theGlobalDefault());
+ }
+
+ ViewInformation3D& ViewInformation3D::operator=(const ViewInformation3D&) = default;
+
+ ViewInformation3D& ViewInformation3D::operator=(ViewInformation3D&&) = default;
+
+ bool ViewInformation3D::operator==(const ViewInformation3D& rCandidate) const
+ {
+ return rCandidate.mpViewInformation3D == mpViewInformation3D;
+ }
+
+ const basegfx::B3DHomMatrix& ViewInformation3D::getObjectTransformation() const
+ {
+ return mpViewInformation3D->getObjectTransformation();
+ }
+
+ const basegfx::B3DHomMatrix& ViewInformation3D::getOrientation() const
+ {
+ return mpViewInformation3D->getOrientation();
+ }
+
+ const basegfx::B3DHomMatrix& ViewInformation3D::getProjection() const
+ {
+ return mpViewInformation3D->getProjection();
+ }
+
+ const basegfx::B3DHomMatrix& ViewInformation3D::getDeviceToView() const
+ {
+ return mpViewInformation3D->getDeviceToView();
+ }
+
+ const basegfx::B3DHomMatrix& ViewInformation3D::getObjectToView() const
+ {
+ return mpViewInformation3D->getObjectToView();
+ }
+
+ double ViewInformation3D::getViewTime() const
+ {
+ return mpViewInformation3D->getViewTime();
+ }
+
+ const uno::Sequence< beans::PropertyValue >& ViewInformation3D::getExtendedInformationSequence() const
+ {
+ return mpViewInformation3D->getExtendedInformationSequence();
+ }
+
+} // end of namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */