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 #ifndef INCLUDED_DRAWINGLAYER_PRIMITIVE3D_BASEPRIMITIVE3D_HXX
21 #define INCLUDED_DRAWINGLAYER_PRIMITIVE3D_BASEPRIMITIVE3D_HXX
22 
23 #include <drawinglayer/drawinglayerdllapi.h>
24 
25 #include <cppuhelper/compbase.hxx>
26 #include <cppuhelper/basemutex.hxx>
27 #include <com/sun/star/graphic/XPrimitive3D.hpp>
28 #include <basegfx/range/b3drange.hxx>
29 #include <deque>
30 
31 
32 /** defines for DeclPrimitive3DIDBlock and ImplPrimitive3DIDBlock
33     Added to be able to simply change identification stuff later, e.g. add
34     an identification string and/or ID to the interface and to the implementation
35     ATM used to delclare implement getPrimitive3DID()
36  */
37 
38 #define DeclPrimitive3DIDBlock() \
39     virtual sal_uInt32 getPrimitive3DID() const override;
40 
41 #define ImplPrimitive3DIDBlock(TheClass, TheID) \
42     sal_uInt32 TheClass::getPrimitive3DID() const { return TheID; }
43 
44 
45 // predefines
46 
47 namespace drawinglayer { namespace geometry {
48     class ViewInformation3D;
49 }}
50 
51 namespace drawinglayer { namespace primitive3d {
52     /// typedefs for basePrimitive3DImplBase, Primitive3DContainer and Primitive3DReference
53     typedef cppu::WeakComponentImplHelper< css::graphic::XPrimitive3D > BasePrimitive3DImplBase;
54     typedef css::uno::Reference< css::graphic::XPrimitive3D > Primitive3DReference;
55     typedef css::uno::Sequence< Primitive3DReference > Primitive3DSequence;
56 
57     class SAL_WARN_UNUSED DRAWINGLAYER_DLLPUBLIC Primitive3DContainer : public std::deque< Primitive3DReference >
58     {
59     public:
Primitive3DContainer()60         explicit Primitive3DContainer() {}
Primitive3DContainer(size_type count)61         explicit Primitive3DContainer( size_type count ) : deque(count) {}
Primitive3DContainer(const Primitive3DContainer & other)62         Primitive3DContainer( const Primitive3DContainer& other ) : deque(other) {}
Primitive3DContainer(Primitive3DContainer && other)63         Primitive3DContainer( Primitive3DContainer&& other ) noexcept : deque(std::move(other)) {}
Primitive3DContainer(std::initializer_list<Primitive3DReference> init)64         Primitive3DContainer( std::initializer_list<Primitive3DReference> init ) : deque(init) {}
65         template <class Iter>
Primitive3DContainer(Iter first,Iter last)66         Primitive3DContainer(Iter first, Iter last) : deque(first, last) {}
67 
68         void append(const Primitive3DContainer& rSource);
operator =(const Primitive3DContainer & r)69         Primitive3DContainer& operator=(const Primitive3DContainer& r) { deque::operator=(r); return *this; }
operator =(Primitive3DContainer && r)70         Primitive3DContainer& operator=(Primitive3DContainer&& r) noexcept { deque::operator=(std::move(r)); return *this; }
71         bool operator==(const Primitive3DContainer& rB) const;
operator !=(const Primitive3DContainer & rB) const72         bool operator!=(const Primitive3DContainer& rB) const { return !operator==(rB); }
73         basegfx::B3DRange getB3DRange(const geometry::ViewInformation3D& aViewInformation) const;
74     };
75 }}
76 
77 
78 // basePrimitive3D class
79 
80 namespace drawinglayer
81 {
82     namespace primitive3d
83     {
84         /** BasePrimitive3D class
85 
86             Baseclass for all C++ implementations of css::graphic::XPrimitive2D
87 
88             The description/functionality is identical with the 2D case in baseprimitive2d.hxx,
89             please see there for detailed information.
90 
91             Current Basic 3D Primitives are:
92 
93             - PolygonHairlinePrimitive3D (for 3D hairlines)
94             - PolyPolygonMaterialPrimitive3D (for 3D filled plane polygons)
95 
96             That's all for 3D!
97          */
98         class DRAWINGLAYER_DLLPUBLIC BasePrimitive3D
99         :   protected cppu::BaseMutex,
100             public BasePrimitive3DImplBase
101         {
102             BasePrimitive3D(const BasePrimitive3D&) = delete;
103             BasePrimitive3D& operator=( const BasePrimitive3D& ) = delete;
104         public:
105             // constructor/destructor
106             BasePrimitive3D();
107             virtual ~BasePrimitive3D() override;
108 
109             /** the ==operator is mainly needed to allow testing newly-created high level primitives against their last
110                 incarnation which buffers/holds the decompositions. The default implementation
111                 uses getPrimitive3DID()-calls to test if it's the same ID at last.
112                 Overridden implementation are then based on this implementation.
113              */
114             virtual bool operator==( const BasePrimitive3D& rPrimitive ) const;
operator !=(const BasePrimitive3D & rPrimitive) const115             bool operator!=( const BasePrimitive3D& rPrimitive ) const { return !operator==(rPrimitive); }
116 
117             /** This method is for places where using the C++ implementation directly is possible. The subprocessing
118                 and range merging is more efficient when working directly on basegfx::B3DRange. The default implementation
119                 will use getDecomposition results to create the range
120              */
121             virtual basegfx::B3DRange getB3DRange(const geometry::ViewInformation3D& rViewInformation) const;
122 
123             /** provide unique ID for fast identifying of known primitive implementations in renderers. These use
124                 the defines from primitivetypes3d.hxx to define unique IDs.
125              */
126             virtual sal_uInt32 getPrimitive3DID() const = 0;
127 
128             /// The default implementation returns an empty sequence
129             virtual Primitive3DContainer get3DDecomposition(const geometry::ViewInformation3D& rViewInformation) const;
130 
131 
132             // Methods from XPrimitive3D
133 
134 
135             /** The getDecomposition implementation for UNO API will use getDecomposition from this implementation. It
136                 will get the ViewInformation from the ViewParameters for that purpose
137              */
138             virtual css::uno::Sequence< ::css::uno::Reference< ::css::graphic::XPrimitive3D > > SAL_CALL getDecomposition( const css::uno::Sequence< css::beans::PropertyValue >& rViewParameters ) override;
139 
140             /** the getRange default implementation will use getDecomposition to create the range information from merging
141                 getRange results from the single local decomposition primitives.
142              */
143             virtual css::geometry::RealRectangle3D SAL_CALL getRange( const css::uno::Sequence< css::beans::PropertyValue >& rViewParameters ) override;
144         };
145     } // end of namespace primitive3d
146 } // end of namespace drawinglayer
147 
148 
149 // BufferedDecompositionPrimitive3D class
150 
151 namespace drawinglayer
152 {
153     namespace primitive3d
154     {
155         /** BufferedDecompositionPrimitive3D class
156 
157             Baseclass for all C++ implementations of css::graphic::XPrimitive2D
158 
159             The description/functionality is identical with the 2D case in baseprimitive2d.hxx,
160             please see there for detailed information
161          */
162         class DRAWINGLAYER_DLLPUBLIC BufferedDecompositionPrimitive3D
163         :   public BasePrimitive3D
164         {
165         private:
166             /// a sequence used for buffering the last create3DDecomposition() result
167             Primitive3DContainer                             maBuffered3DDecomposition;
168 
169         protected:
170             /** access methods to maBuffered3DDecomposition. The usage of this methods may allow
171                 later thread-safe stuff to be added if needed. Only to be used by getDecomposition()
172                 implementations for buffering the last decomposition.
173              */
getBuffered3DDecomposition() const174             const Primitive3DContainer& getBuffered3DDecomposition() const { return maBuffered3DDecomposition; }
setBuffered3DDecomposition(const Primitive3DContainer & rNew)175             void setBuffered3DDecomposition(const Primitive3DContainer& rNew) { maBuffered3DDecomposition = rNew; }
176 
177             /** method which is to be used to implement the local decomposition of a 2D primitive. The default
178                 implementation will just return an empty decomposition
179              */
180             virtual Primitive3DContainer create3DDecomposition(const geometry::ViewInformation3D& rViewInformation) const;
181 
182         public:
183             // constructor
184             BufferedDecompositionPrimitive3D();
185 
186             /** The getDecomposition default implementation will on demand use create3DDecomposition() if
187                 maBuffered3DDecomposition is empty. It will set maBuffered3DDecomposition to this obtained decomposition
188                 to buffer it. If the decomposition is also ViewInformation-dependent, this method needs to be
189                 overridden and the ViewInformation for the last decomposition needs to be remembered, too, and
190                 be used in the next call to decide if the buffered decomposition may be reused or not.
191              */
192             virtual Primitive3DContainer get3DDecomposition(const geometry::ViewInformation3D& rViewInformation) const override;
193         };
194     } // end of namespace primitive3d
195 } // end of namespace drawinglayer
196 
197 
198 // tooling
199 
200 namespace drawinglayer
201 {
202     namespace primitive3d
203     {
204         /// get B3DRange from a given Primitive3DReference
205         basegfx::B3DRange DRAWINGLAYER_DLLPUBLIC getB3DRangeFromPrimitive3DReference(const Primitive3DReference& rCandidate, const geometry::ViewInformation3D& aViewInformation);
206 
207         /** compare two Primitive2DReferences for equality, including trying to get implementations (BasePrimitive2D)
208             and using compare operator
209          */
210         bool DRAWINGLAYER_DLLPUBLIC arePrimitive3DReferencesEqual(const Primitive3DReference& rA, const Primitive3DReference& rB);
211 
212     } // end of namespace primitive3d
213 } // end of namespace drawinglayer
214 
215 
216 #endif //INCLUDED_DRAWINGLAYER_PRIMITIVE3D_BASEPRIMITIVE3D_HXX
217 
218 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
219