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 #ifndef INCLUDED_DRAWINGLAYER_PRIMITIVE2D_BASEPRIMITIVE2D_HXX
21 #define INCLUDED_DRAWINGLAYER_PRIMITIVE2D_BASEPRIMITIVE2D_HXX
23 #include <drawinglayer/drawinglayerdllapi.h>
25 #include <cppuhelper/compbase1.hxx>
26 #include <boost/utility.hpp>
27 #include <com/sun/star/graphic/XPrimitive2D.hpp>
28 #include <comphelper/broadcasthelper.hxx>
29 #include <basegfx/range/b2drange.hxx>
32 /** defines for DeclPrimitive2DIDBlock and ImplPrimitive2DIDBlock
33 Added to be able to simply change identification stuff later, e.g. add
34 a identification string and/or ID to the interface and to the implementation
35 ATM used to delclare implement getPrimitive2DID()
38 #define DeclPrimitive2DIDBlock() \
39 virtual sal_uInt32 getPrimitive2DID() const SAL_OVERRIDE;
41 #define ImplPrimitive2DIDBlock(TheClass, TheID) \
42 sal_uInt32 TheClass::getPrimitive2DID() const { return TheID; }
47 namespace drawinglayer
{ namespace geometry
{
48 class ViewInformation2D
;
51 namespace drawinglayer
{ namespace primitive2d
{
52 /// typedefs for basePrimitive2DImplBase, Primitive2DSequence and Primitive2DReference
53 typedef cppu::WeakComponentImplHelper1
< ::com::sun::star::graphic::XPrimitive2D
> BasePrimitive2DImplBase
;
54 typedef ::com::sun::star::uno::Reference
< ::com::sun::star::graphic::XPrimitive2D
> Primitive2DReference
;
55 typedef ::com::sun::star::uno::Sequence
< Primitive2DReference
> Primitive2DSequence
;
59 // basePrimitive2D class
61 namespace drawinglayer
65 /** BasePrimitive2D class
67 Baseclass for all C++ implementations of com::sun::star::graphic::XPrimitive2D
69 This class is strongly virtual due to the lack of getPrimitiveID() implementation.
70 This is by purpose, this base class shall not be incarnated and be used directly as
73 It is derived from boost::noncopyable to make clear that a primitive is a read-only
74 instance and copying or changing values is not intended. The idea is to hold all data
75 needed for visualisation of this primitive in unchangeable form.
77 It is derived from comphelper::OBaseMutex to have a Mutex at hand; in a base
78 implementation this may not be needed, but e.g. when buffering at last decomposition
79 in a local member, multiple threads may try to decompose at the same time, so locking
80 is needed to avoid race conditions seen from the UNO object implementation.
82 A method to get a simplified representation is provided by get2DDecomposition. The
83 default implementation returns an empty sequence. The idea is that processors
84 using this primitive and do not know it, may get the decomposition and process
85 these instead. An example is e.g. a fat line, who's decomposition may contain
86 the geometric representation of that line using filled polygon prmimitives. When
87 the renderer knows how to handle fat lines, he may process this primitive directly;
88 if not he can use the decomposition. With this functionality, renderers may operate by
89 knowing only a small set of primitives.
91 When a primitive does not implement get2DDecomposition, it is called a 'Basic Primitive' and
92 belongs to the set of primitives which a processor should be able to handle. Practice
93 will define this minimal sets of primitives. When defined and the concept is proved,
94 unique UNO APIs may be defined/implemented for these set to allow more intense work
95 with primitives using UNO.
97 Current Basic 2D Primitives are:
99 - BitmapPrimitive2D (bitmap data, evtl. with transparence)
100 - PointArrayPrimitive2D (single points)
101 - PolygonHairlinePrimitive2D (hairline curves/polygons)
102 - PolyPolygonColorPrimitive2D (colored polygons)
104 UPDATE: MetafilePrimitive2D (VCL Metafile) is taken off this list since
105 it is implemented with the integration of CWS aw078 into DV300m69.
107 All other implemented primitives have a defined decomposition and can thus be
108 decomposed down to this small set.
110 A renderer implementing support for this minimal set of primitives can completely
111 render primitive-based visualisations. Of course, he also has to take states into account
112 which are representated by GroupPrimitive2D derivations, see groupprimitive2d.hxx
114 To support getting the geometric BoundRect, getB2DRange is used. The default
115 implementation will use the get2DDecomposition result and merge a range from the
116 entries. Thus, an implementation is only necessary for the Basic Primitives, but
117 of course speedups are possible (and are used) by implementing the method at higher-level
120 For primitive identification, getPrimitiveID is used currently in this implementations
121 to allow a fast switch/case processing. This needs a unique identifier mechanism which
122 currently uses defines (see drawinglayer_primitivetypes2d.hxx). For UNO prmitive API
123 it will be needed to add a unique descriptor (Name?) later to the API.
125 This base implementation provides mappings from the methods from XPrimitive2D
126 (getDecomposition/getRange) to the appropriate methods in the C++ implementations
127 (get2DDecomposition/getB2DRange). The PropertyValue ViewParameters is converted to
128 the appropriate C++ implementation class ViewInformation2D.
130 This base class does not implement any buffering; e.g. buffering the decompositon
131 and/or the range. These may be buffered anytime since the definition is that the primitive
132 is read-only and thus unchangeable. This implies that the decomposition and/or getting
133 the range will lead to the same result as last time, under the precondition that
134 the parameter ViewInformation2D is the same as the last one. This is usually the case
135 for view-independent primitives which are defined by not using ViewInformation2D
136 in their get2DDecomposition/getB2DRange implementations.
138 class DRAWINGLAYER_DLLPUBLIC BasePrimitive2D
139 : private boost::noncopyable
,
140 protected comphelper::OBaseMutex
,
141 public BasePrimitive2DImplBase
146 // constructor/destructor
148 virtual ~BasePrimitive2D();
150 /** the ==operator is mainly needed to allow testing newly-created primitives against their last
151 incarnation which buffers/holds the made decompositions. The default implementation
152 uses getPrimitive2DID()-calls to test if it's the same ID at last.
153 Overridden implementations are then based on this implementation
155 virtual bool operator==( const BasePrimitive2D
& rPrimitive
) const;
156 bool operator!=( const BasePrimitive2D
& rPrimitive
) const { return !operator==(rPrimitive
); }
158 /// The default implementation will use getDecomposition results to create the range
159 virtual basegfx::B2DRange
getB2DRange(const geometry::ViewInformation2D
& rViewInformation
) const;
161 /** provide unique ID for fast identifying of known primitive implementations in renderers. These use
162 the defines from drawinglayer_primitivetypes2d.hxx to define unique IDs.
163 This method is normally defined using DeclPrimitive2DIDBlock()
165 virtual sal_uInt32
getPrimitive2DID() const = 0;
167 /// The default implementation will return an empty sequence
168 virtual Primitive2DSequence
get2DDecomposition(const geometry::ViewInformation2D
& rViewInformation
) const;
171 // Methods from XPrimitive2D
174 /** The getDecomposition implementation for UNO API will use getDecomposition from this implementation. It
175 will construct a ViewInformation2D from the ViewParameters for that purpose
177 virtual Primitive2DSequence SAL_CALL
getDecomposition( const ::com::sun::star::uno::Sequence
< ::com::sun::star::beans::PropertyValue
>& rViewParameters
) throw ( ::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
179 /** The getRange implementation for UNO API will use getRange from this implementation. It
180 will construct a ViewInformation2D from the ViewParameters for that purpose
182 virtual ::com::sun::star::geometry::RealRectangle2D SAL_CALL
getRange( const ::com::sun::star::uno::Sequence
< ::com::sun::star::beans::PropertyValue
>& rViewParameters
) throw ( ::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
184 } // end of namespace primitive2d
185 } // end of namespace drawinglayer
188 // BufferedDecompositionPrimitive2D class
190 namespace drawinglayer
192 namespace primitive2d
194 /** BufferedDecompositionPrimitive2D class
196 Baseclass for all C++ implementations of com::sun::star::graphic::XPrimitive2D
197 which want to buffer the decomoposition result
199 Buffering the decomposition is the most-used buffering and is thus used my most
200 primitive implementations which support a decomposition as base class.
202 The buffering is done by holding the last decomposition in the local parameter
203 maBuffered2DDecomposition. The default implementation of get2DDecomposition checks
204 if maBuffered2DDecomposition is empty. If yes, it uses create2DDecomposition
205 to create the content. In all cases, maBuffered2DDecomposition is returned.
207 For view-dependent primitives derived from Primitive2DBufferDecomposition more needs
208 to be done when the decomposition depends on parts of the parameter ViewInformation2D.
209 This defines a standard method for processing these:
211 Implement a view-dependent get2DDecomposition doing te following steps:
212 (a) Locally extract needed parameters from ViewInformation2D to new, local parameters
213 (this may be a complete local copy of ViewInformation2D)
214 (b) If a buffered decomposition exists, ckeck if one of the new local parameters
215 differs from the corresponding locally remembered (as member) ones. If yes,
216 clear maBuffered2DDecomposition
217 (d) call baseclass::get2DDecomposition which will use create2DDecomposition
218 to fill maBuffered2DDecomposition if it's empty
219 (e) copy the new local parameters to the corresponding locally remembered ones
220 to identify if a new decomposition is needed at the next call
221 (f) return maBuffered2DDecomposition
223 class DRAWINGLAYER_DLLPUBLIC BufferedDecompositionPrimitive2D
224 : public BasePrimitive2D
227 /// a sequence used for buffering the last create2DDecomposition() result
228 Primitive2DSequence maBuffered2DDecomposition
;
231 /** access methods to maBuffered2DDecomposition. The usage of this methods may allow
232 later thread-safe stuff to be added if needed. Only to be used by getDecomposition()
233 implementations for buffering the last decomposition.
235 const Primitive2DSequence
& getBuffered2DDecomposition() const { return maBuffered2DDecomposition
; }
236 void setBuffered2DDecomposition(const Primitive2DSequence
& rNew
) { maBuffered2DDecomposition
= rNew
; }
238 /** method which is to be used to implement the local decomposition of a 2D primitive. The default
239 implementation will just return an empty decomposition
241 virtual Primitive2DSequence
create2DDecomposition(const geometry::ViewInformation2D
& rViewInformation
) const;
244 // constructor/destructor
245 BufferedDecompositionPrimitive2D();
247 /** The getDecomposition default implementation will on demand use create2DDecomposition() if
248 maBuffered2DDecomposition is empty. It will set maBuffered2DDecomposition to this obtained decomposition
249 to buffer it. If the decomposition is also ViewInformation2D-dependent, this method needs to be
250 overridden and the ViewInformation2D for the last decomposition need to be remembered, too, and
251 be used in the next call to decide if the buffered decomposition may be reused or not.
253 virtual Primitive2DSequence
get2DDecomposition(const geometry::ViewInformation2D
& rViewInformation
) const SAL_OVERRIDE
;
255 } // end of namespace primitive2d
256 } // end of namespace drawinglayer
261 namespace drawinglayer
263 namespace primitive2d
265 /// support to handle a sequence of primitives as stl vector and convert it during creation
266 typedef ::std::vector
< BasePrimitive2D
* > Primitive2DVector
;
267 Primitive2DSequence DRAWINGLAYER_DLLPUBLIC
Primitive2DVectorToPrimitive2DSequence(const Primitive2DVector
& rSource
, bool bInvert
= false);
269 /// get B2DRange from a given Primitive2DReference
270 basegfx::B2DRange DRAWINGLAYER_DLLPUBLIC
getB2DRangeFromPrimitive2DReference(const Primitive2DReference
& rCandidate
, const geometry::ViewInformation2D
& aViewInformation
);
272 /// get B2DRange from a given Primitive2DSequence
273 basegfx::B2DRange DRAWINGLAYER_DLLPUBLIC
getB2DRangeFromPrimitive2DSequence(const Primitive2DSequence
& rCandidate
, const geometry::ViewInformation2D
& aViewInformation
);
275 /** compare two Primitive2DReferences for equality, including trying to get implementations (BasePrimitive2D)
276 and using compare operator
278 bool DRAWINGLAYER_DLLPUBLIC
arePrimitive2DReferencesEqual(const Primitive2DReference
& rA
, const Primitive2DReference
& rB
);
280 /// compare two Primitive2DReferences for equality, uses arePrimitive2DReferencesEqual internally
281 bool DRAWINGLAYER_DLLPUBLIC
arePrimitive2DSequencesEqual(const Primitive2DSequence
& rA
, const Primitive2DSequence
& rB
);
283 /// concatenate sequence
284 void DRAWINGLAYER_DLLPUBLIC
appendPrimitive2DSequenceToPrimitive2DSequence(Primitive2DSequence
& rDest
, const Primitive2DSequence
& rSource
);
286 /// concatenate single Primitive2D
287 void DRAWINGLAYER_DLLPUBLIC
appendPrimitive2DReferenceToPrimitive2DSequence(Primitive2DSequence
& rDest
, const Primitive2DReference
& rSource
);
289 OUString DRAWINGLAYER_DLLPUBLIC
idToString(sal_uInt32 nId
);
291 } // end of namespace primitive2d
292 } // end of namespace drawinglayer
296 #endif //INCLUDED_DRAWINGLAYER_PRIMITIVE2D_BASEPRIMITIVE2D_HXX
298 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */