diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:51:28 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:51:28 +0000 |
commit | 940b4d1848e8c70ab7642901a68594e8016caffc (patch) | |
tree | eb72f344ee6c3d9b80a7ecc079ea79e9fba8676d /drawinglayer/source/geometry | |
parent | Initial commit. (diff) | |
download | libreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.tar.xz libreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.zip |
Adding upstream version 1:7.0.4.upstream/1%7.0.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | drawinglayer/source/geometry/viewinformation2d.cxx | 447 | ||||
-rw-r--r-- | drawinglayer/source/geometry/viewinformation3d.cxx | 511 |
2 files changed, 958 insertions, 0 deletions
diff --git a/drawinglayer/source/geometry/viewinformation2d.cxx b/drawinglayer/source/geometry/viewinformation2d.cxx new file mode 100644 index 000000000..08a88b23d --- /dev/null +++ b/drawinglayer/source/geometry/viewinformation2d.cxx @@ -0,0 +1,447 @@ +/* -*- 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 <rtl/instance.hxx> +#include <com/sun/star/uno/Sequence.hxx> + +using namespace com::sun::star; + +namespace drawinglayer::geometry +{ +namespace +{ +constexpr OUStringLiteral g_PropertyName_ObjectTransformation = "ObjectTransformation"; +constexpr OUStringLiteral g_PropertyName_ViewTransformation = "ViewTransformation"; +constexpr OUStringLiteral g_PropertyName_Viewport = "Viewport"; +constexpr OUStringLiteral g_PropertyName_Time = "Time"; +constexpr OUStringLiteral g_PropertyName_VisualizedPage = "VisualizedPage"; +constexpr OUStringLiteral g_PropertyName_ReducedDisplayQuality = "ReducedDisplayQuality"; +} + +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; + + bool mbReducedDisplayQuality : 1; + + // the complete PropertyValue representation (if already created) + uno::Sequence<beans::PropertyValue> mxViewInformation; + + // the extra PropertyValues; not represented by ViewTransformation, + // Viewport, VisualizedPage or ViewTime + uno::Sequence<beans::PropertyValue> mxExtendedInformation; + + 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); + + for (sal_Int32 a(0); a < nCount; a++) + { + const beans::PropertyValue& rProp = rViewParameters[a]; + + if (rProp.Name == g_PropertyName_ReducedDisplayQuality) + { + // extra information; add to filtered information + mxExtendedInformation[nExtendedInsert++] = rProp; + + // for performance reasons, also cache content locally + bool bSalBool(false); + rProp.Value >>= bSalBool; + mbReducedDisplayQuality = bSalBool; + } + else if (rProp.Name == g_PropertyName_ObjectTransformation) + { + css::geometry::AffineMatrix2D aAffineMatrix2D; + rProp.Value >>= aAffineMatrix2D; + basegfx::unotools::homMatrixFromAffineMatrix(maObjectTransformation, + aAffineMatrix2D); + } + else if (rProp.Name == g_PropertyName_ViewTransformation) + { + css::geometry::AffineMatrix2D aAffineMatrix2D; + rProp.Value >>= aAffineMatrix2D; + basegfx::unotools::homMatrixFromAffineMatrix(maViewTransformation, aAffineMatrix2D); + } + else if (rProp.Name == g_PropertyName_Viewport) + { + css::geometry::RealRectangle2D aViewport; + rProp.Value >>= aViewport; + maViewport = basegfx::unotools::b2DRectangleFromRealRectangle2D(aViewport); + } + else if (rProp.Name == g_PropertyName_Time) + { + rProp.Value >>= mfViewTime; + } + else if (rProp.Name == g_PropertyName_VisualizedPage) + { + rProp.Value >>= mxVisualizedPage; + } + else + { + // extra information; add to filtered information + mxExtendedInformation[nExtendedInsert++] = rProp; + } + } + + // extra information size is now known; realloc to final size + mxExtendedInformation.realloc(nExtendedInsert); + } + + void impFillViewInformationFromContent() + { + const bool bObjectTransformationUsed(!maObjectTransformation.isIdentity()); + const bool bViewTransformationUsed(!maViewTransformation.isIdentity()); + const bool bViewportUsed(!maViewport.isEmpty()); + const bool bTimeUsed(0.0 < mfViewTime); + const bool bVisualizedPageUsed(mxVisualizedPage.is()); + const bool bReducedDisplayQualityUsed(mbReducedDisplayQuality); + const bool bExtraInformation(mxExtendedInformation.hasElements()); + sal_uInt32 nIndex(0); + const sal_uInt32 nCount((bObjectTransformationUsed ? 1 : 0) + + (bViewTransformationUsed ? 1 : 0) + (bViewportUsed ? 1 : 0) + + (bTimeUsed ? 1 : 0) + (bVisualizedPageUsed ? 1 : 0) + + (bReducedDisplayQualityUsed ? 1 : 0) + + (bExtraInformation ? mxExtendedInformation.getLength() : 0)); + + mxViewInformation.realloc(nCount); + + if (bObjectTransformationUsed) + { + css::geometry::AffineMatrix2D aAffineMatrix2D; + basegfx::unotools::affineMatrixFromHomMatrix(aAffineMatrix2D, maObjectTransformation); + mxViewInformation[nIndex].Name = g_PropertyName_ObjectTransformation; + mxViewInformation[nIndex].Value <<= aAffineMatrix2D; + nIndex++; + } + + if (bViewTransformationUsed) + { + css::geometry::AffineMatrix2D aAffineMatrix2D; + basegfx::unotools::affineMatrixFromHomMatrix(aAffineMatrix2D, maViewTransformation); + mxViewInformation[nIndex].Name = g_PropertyName_ViewTransformation; + mxViewInformation[nIndex].Value <<= aAffineMatrix2D; + nIndex++; + } + + if (bViewportUsed) + { + const css::geometry::RealRectangle2D aViewport( + basegfx::unotools::rectangle2DFromB2DRectangle(maViewport)); + mxViewInformation[nIndex].Name = g_PropertyName_Viewport; + mxViewInformation[nIndex].Value <<= aViewport; + nIndex++; + } + + if (bTimeUsed) + { + mxViewInformation[nIndex].Name = g_PropertyName_Time; + mxViewInformation[nIndex].Value <<= mfViewTime; + nIndex++; + } + + if (bVisualizedPageUsed) + { + mxViewInformation[nIndex].Name = g_PropertyName_VisualizedPage; + mxViewInformation[nIndex].Value <<= mxVisualizedPage; + nIndex++; + } + + if (bExtraInformation) + { + const sal_Int32 nExtra(mxExtendedInformation.getLength()); + + for (sal_Int32 a(0); a < nExtra; a++) + { + mxViewInformation[nIndex++] = mxExtendedInformation[a]; + } + } + } + +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) + : maObjectTransformation(rObjectTransformation) + , maViewTransformation(rViewTransformation) + , maObjectToViewTransformation() + , maInverseObjectToViewTransformation() + , maViewport(rViewport) + , maDiscreteViewport() + , mxVisualizedPage(rxDrawPage) + , mfViewTime(fViewTime) + , mbReducedDisplayQuality(false) + , mxViewInformation() + , mxExtendedInformation() + { + impInterpretPropertyValues(rExtendedParameters); + } + + explicit ImpViewInformation2D(const uno::Sequence<beans::PropertyValue>& rViewParameters) + : maObjectTransformation() + , maViewTransformation() + , maObjectToViewTransformation() + , maInverseObjectToViewTransformation() + , maViewport() + , maDiscreteViewport() + , mxVisualizedPage() + , mfViewTime() + , mbReducedDisplayQuality(false) + , mxViewInformation(rViewParameters) + , mxExtendedInformation() + { + impInterpretPropertyValues(rViewParameters); + } + + ImpViewInformation2D() + : maObjectTransformation() + , maViewTransformation() + , maObjectToViewTransformation() + , maInverseObjectToViewTransformation() + , maViewport() + , maDiscreteViewport() + , mxVisualizedPage() + , mfViewTime() + , mbReducedDisplayQuality(false) + , mxViewInformation() + , mxExtendedInformation() + { + } + + const basegfx::B2DHomMatrix& getObjectTransformation() const { return maObjectTransformation; } + + const basegfx::B2DHomMatrix& getViewTransformation() const { return maViewTransformation; } + + const basegfx::B2DRange& getViewport() const { return maViewport; } + + 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; } + + const uno::Reference<drawing::XDrawPage>& getVisualizedPage() const { return mxVisualizedPage; } + + bool getReducedDisplayQuality() const { return mbReducedDisplayQuality; } + + const uno::Sequence<beans::PropertyValue>& getViewInformationSequence() const + { + if (!mxViewInformation.hasElements()) + { + const_cast<ImpViewInformation2D*>(this)->impFillViewInformationFromContent(); + } + + return mxViewInformation; + } + + const uno::Sequence<beans::PropertyValue>& getExtendedInformationSequence() const + { + return mxExtendedInformation; + } + + bool operator==(const ImpViewInformation2D& rCandidate) const + { + return (maObjectTransformation == rCandidate.maObjectTransformation + && maViewTransformation == rCandidate.maViewTransformation + && maViewport == rCandidate.maViewport + && mxVisualizedPage == rCandidate.mxVisualizedPage + && mfViewTime == rCandidate.mfViewTime + && mxExtendedInformation == rCandidate.mxExtendedInformation); + } +}; + +namespace +{ +struct theGlobalDefault : public rtl::Static<ViewInformation2D::ImplType, theGlobalDefault> +{ +}; +} + +ViewInformation2D::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) + : mpViewInformation2D(ImpViewInformation2D(rObjectTransformation, rViewTransformation, + rViewport, rxDrawPage, fViewTime, + rExtendedParameters)) +{ +} + +ViewInformation2D::ViewInformation2D(const uno::Sequence<beans::PropertyValue>& rViewParameters) + : mpViewInformation2D(ImpViewInformation2D(rViewParameters)) +{ +} + +ViewInformation2D::ViewInformation2D() + : mpViewInformation2D(theGlobalDefault::get()) +{ +} + +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(); +} + +const basegfx::B2DHomMatrix& ViewInformation2D::getViewTransformation() const +{ + return mpViewInformation2D->getViewTransformation(); +} + +const basegfx::B2DRange& ViewInformation2D::getViewport() const +{ + return mpViewInformation2D->getViewport(); +} + +double ViewInformation2D::getViewTime() const { return mpViewInformation2D->getViewTime(); } + +const uno::Reference<drawing::XDrawPage>& ViewInformation2D::getVisualizedPage() const +{ + return mpViewInformation2D->getVisualizedPage(); +} + +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(); +} + +const uno::Sequence<beans::PropertyValue>& ViewInformation2D::getViewInformationSequence() const +{ + return mpViewInformation2D->getViewInformationSequence(); +} + +const uno::Sequence<beans::PropertyValue>& ViewInformation2D::getExtendedInformationSequence() const +{ + return mpViewInformation2D->getExtendedInformationSequence(); +} + +} // 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 000000000..b3e75bffa --- /dev/null +++ b/drawinglayer/source/geometry/viewinformation3d.cxx @@ -0,0 +1,511 @@ +/* -*- 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 <rtl/instance.hxx> +#include <com/sun/star/uno/Sequence.hxx> + + +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 complete PropertyValue representation (if already created) + uno::Sequence< beans::PropertyValue > mxViewInformation; + + // 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); + + 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 + mxExtendedInformation[nExtendedInsert++] = rProp; + } + } + + // extra information size is now known; realloc to final size + mxExtendedInformation.realloc(nExtendedInsert); + } + + // central method to create a Sequence of PropertyValues containing he complete + // data set + void impFillViewInformationFromContent() + { + const bool bObjectTransformationUsed(!maObjectTransformation.isIdentity()); + const bool bOrientationUsed(!maOrientation.isIdentity()); + const bool bProjectionUsed(!maProjection.isIdentity()); + const bool bDeviceToViewUsed(!maDeviceToView.isIdentity()); + const bool bTimeUsed(0.0 < mfViewTime); + const bool bExtraInformation(mxExtendedInformation.hasElements()); + + // 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 bool bProjectionUsed_30(bProjectionUsed && !basegfx::fTools::equalZero(maProjection.get(3, 0))); + const bool bProjectionUsed_31(bProjectionUsed && !basegfx::fTools::equalZero(maProjection.get(3, 1))); + const bool bProjectionUsed_32(bProjectionUsed && !basegfx::fTools::equalZero(maProjection.get(3, 2))); + const bool bProjectionUsed_33(bProjectionUsed && !basegfx::fTools::equal(maProjection.get(3, 3), 1.0)); + + sal_uInt32 nIndex(0); + const sal_uInt32 nCount( + (bObjectTransformationUsed ? 1 : 0) + + (bOrientationUsed ? 1 : 0) + + (bProjectionUsed ? 1 : 0) + + (bProjectionUsed_30 ? 1 : 0) + + (bProjectionUsed_31 ? 1 : 0) + + (bProjectionUsed_32 ? 1 : 0) + + (bProjectionUsed_33 ? 1 : 0) + + (bDeviceToViewUsed ? 1 : 0) + + (bTimeUsed ? 1 : 0) + + (bExtraInformation ? mxExtendedInformation.getLength() : 0)); + + mxViewInformation.realloc(nCount); + + if(bObjectTransformationUsed) + { + css::geometry::AffineMatrix3D aAffineMatrix3D; + basegfx::unotools::affineMatrixFromHomMatrix3D(aAffineMatrix3D, maObjectTransformation); + mxViewInformation[nIndex].Name = getNamePropertyObjectTransformation(); + mxViewInformation[nIndex].Value <<= aAffineMatrix3D; + nIndex++; + } + + if(bOrientationUsed) + { + css::geometry::AffineMatrix3D aAffineMatrix3D; + basegfx::unotools::affineMatrixFromHomMatrix3D(aAffineMatrix3D, maOrientation); + mxViewInformation[nIndex].Name = getNamePropertyOrientation(); + mxViewInformation[nIndex].Value <<= aAffineMatrix3D; + nIndex++; + } + + if(bProjectionUsed) + { + css::geometry::AffineMatrix3D aAffineMatrix3D; + basegfx::unotools::affineMatrixFromHomMatrix3D(aAffineMatrix3D, maProjection); + mxViewInformation[nIndex].Name = getNamePropertyProjection(); + mxViewInformation[nIndex].Value <<= aAffineMatrix3D; + nIndex++; + } + + if(bProjectionUsed_30) + { + mxViewInformation[nIndex].Name = getNamePropertyProjection_30(); + mxViewInformation[nIndex].Value <<= maProjection.get(3, 0); + nIndex++; + } + + if(bProjectionUsed_31) + { + mxViewInformation[nIndex].Name = getNamePropertyProjection_31(); + mxViewInformation[nIndex].Value <<= maProjection.get(3, 1); + nIndex++; + } + + if(bProjectionUsed_32) + { + mxViewInformation[nIndex].Name = getNamePropertyProjection_32(); + mxViewInformation[nIndex].Value <<= maProjection.get(3, 2); + nIndex++; + } + + if(bProjectionUsed_33) + { + mxViewInformation[nIndex].Name = getNamePropertyProjection_33(); + mxViewInformation[nIndex].Value <<= maProjection.get(3, 3); + nIndex++; + } + + if(bDeviceToViewUsed) + { + css::geometry::AffineMatrix3D aAffineMatrix3D; + basegfx::unotools::affineMatrixFromHomMatrix3D(aAffineMatrix3D, maDeviceToView); + mxViewInformation[nIndex].Name = getNamePropertyDeviceToView(); + mxViewInformation[nIndex].Value <<= aAffineMatrix3D; + nIndex++; + } + + if(bTimeUsed) + { + mxViewInformation[nIndex].Name = getNamePropertyTime(); + mxViewInformation[nIndex].Value <<= mfViewTime; + nIndex++; + } + + if(bExtraInformation) + { + const sal_Int32 nExtra(mxExtendedInformation.getLength()); + + for(sal_Int32 a(0); a < nExtra; a++) + { + mxViewInformation[nIndex++] = mxExtendedInformation[a]; + } + } + } + + public: + ImpViewInformation3D( + const basegfx::B3DHomMatrix& rObjectTransformation, + const basegfx::B3DHomMatrix& rOrientation, + const basegfx::B3DHomMatrix& rProjection, + const basegfx::B3DHomMatrix& rDeviceToView, + double fViewTime, + const uno::Sequence< beans::PropertyValue >& rExtendedParameters) + : maObjectTransformation(rObjectTransformation), + maOrientation(rOrientation), + maProjection(rProjection), + maDeviceToView(rDeviceToView), + mfViewTime(fViewTime), + mxViewInformation(), + mxExtendedInformation() + { + impInterpretPropertyValues(rExtendedParameters); + } + + explicit ImpViewInformation3D(const uno::Sequence< beans::PropertyValue >& rViewParameters) + : maObjectTransformation(), + maOrientation(), + maProjection(), + maDeviceToView(), + mfViewTime(), + mxViewInformation(rViewParameters), + mxExtendedInformation() + { + impInterpretPropertyValues(rViewParameters); + } + + ImpViewInformation3D() + : maObjectTransformation(), + maOrientation(), + maProjection(), + maDeviceToView(), + mfViewTime(), + mxViewInformation(), + mxExtendedInformation() + { + } + + 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 >& getViewInformationSequence() const + { + if(!mxViewInformation.hasElements()) + { + const_cast< ImpViewInformation3D* >(this)->impFillViewInformationFromContent(); + } + + return mxViewInformation; + } + + 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 + { + struct theGlobalDefault : + public rtl::Static< ViewInformation3D::ImplType, theGlobalDefault > {}; + } + + 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::get()) + { + } + + ViewInformation3D::ViewInformation3D(const ViewInformation3D&) = default; + + ViewInformation3D::ViewInformation3D(ViewInformation3D&&) = default; + + ViewInformation3D::~ViewInformation3D() = default; + + bool ViewInformation3D::isDefault() const + { + return mpViewInformation3D.same_object(theGlobalDefault::get()); + } + + 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::getViewInformationSequence() const + { + return mpViewInformation3D->getViewInformationSequence(); + } + + const uno::Sequence< beans::PropertyValue >& ViewInformation3D::getExtendedInformationSequence() const + { + return mpViewInformation3D->getExtendedInformationSequence(); + } + +} // end of namespace + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |