/src/libreoffice/include/drawinglayer/primitive2d/baseprimitive2d.hxx
Line | Count | Source |
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 | | #pragma once |
21 | | |
22 | | #include <config_options.h> |
23 | | #include <drawinglayer/drawinglayerdllapi.h> |
24 | | |
25 | | #include <drawinglayer/primitive2d/Primitive2DContainer.hxx> |
26 | | #include <drawinglayer/primitive2d/Primitive2DVisitor.hxx> |
27 | | #include <drawinglayer/geometry/viewinformation2d.hxx> |
28 | | |
29 | | #include <com/sun/star/util/XAccounting.hpp> |
30 | | #include <basegfx/range/b2drange.hxx> |
31 | | #include <com/sun/star/graphic/XPrimitive2D.hpp> |
32 | | #include <comphelper/compbase.hxx> |
33 | | #include <salhelper/simplereferenceobject.hxx> |
34 | | #include <rtl/ref.hxx> |
35 | | #include <deque> |
36 | | #include <utility> |
37 | | |
38 | | namespace drawinglayer::geometry |
39 | | { |
40 | | class ViewInformation2D; |
41 | | } |
42 | | |
43 | | typedef comphelper::WeakComponentImplHelper<css::graphic::XPrimitive2D, css::util::XAccounting> |
44 | | BasePrimitive2DImplBase; |
45 | | |
46 | | namespace drawinglayer::primitive2d |
47 | | { |
48 | | /** BasePrimitive2D class |
49 | | |
50 | | Baseclass for all C++ implementations of css::graphic::XPrimitive2D |
51 | | |
52 | | This class is strongly virtual due to the lack of getPrimitiveID() implementation. |
53 | | This is by purpose, this base class shall not be incarnated and be used directly as |
54 | | a XPrimitive2D. |
55 | | |
56 | | It is noncopyable to make clear that a primitive is a read-only |
57 | | instance and copying or changing values is not intended. The idea is to hold all data |
58 | | needed for visualisation of this primitive in unchangeable form. |
59 | | |
60 | | It is derived from cppu::BaseMutex to have a Mutex at hand; in a base |
61 | | implementation this may not be needed, but e.g. when buffering at last decomposition |
62 | | in a local member, multiple threads may try to decompose at the same time, so locking |
63 | | is needed to avoid race conditions seen from the UNO object implementation. |
64 | | |
65 | | A method to get a simplified representation is provided by get2DDecomposition. The |
66 | | default implementation returns an empty sequence. The idea is that processors |
67 | | using this primitive and do not know it, may get the decomposition and process |
68 | | these instead. An example is e.g. a fat line, who's decomposition may contain |
69 | | the geometric representation of that line using filled polygon primitives. When |
70 | | the renderer knows how to handle fat lines, he may process this primitive directly; |
71 | | if not he can use the decomposition. With this functionality, renderers may operate by |
72 | | knowing only a small set of primitives. |
73 | | |
74 | | When a primitive does not implement get2DDecomposition, it is called a 'Basic Primitive' and |
75 | | belongs to the set of primitives which a processor should be able to handle. Practice |
76 | | will define this minimal sets of primitives. When defined and the concept is proved, |
77 | | unique UNO APIs may be defined/implemented for these set to allow more intense work |
78 | | with primitives using UNO. |
79 | | |
80 | | Current Basic 2D Primitives are: |
81 | | |
82 | | - BitmapPrimitive2D (bitmap data, evtl. with transparence) |
83 | | - PointArrayPrimitive2D (single points) |
84 | | - PolygonHairlinePrimitive2D (hairline curves/polygons) |
85 | | - PolyPolygonColorPrimitive2D (colored polygons) |
86 | | |
87 | | UPDATE: MetafilePrimitive2D (VCL Metafile) is taken off this list since |
88 | | it is implemented with the integration of CWS aw078 into DV300m69. |
89 | | |
90 | | All other implemented primitives have a defined decomposition and can thus be |
91 | | decomposed down to this small set. |
92 | | |
93 | | A renderer implementing support for this minimal set of primitives can completely |
94 | | render primitive-based visualisations. Of course, he also has to take states into account |
95 | | which are represented by GroupPrimitive2D derivations, see groupprimitive2d.hxx |
96 | | |
97 | | To support getting the geometric BoundRect, getB2DRange is used. The default |
98 | | implementation will use the get2DDecomposition result and merge a range from the |
99 | | entries. Thus, an implementation is only necessary for the Basic Primitives, but |
100 | | of course speedups are possible (and are used) by implementing the method at higher-level |
101 | | primitives. |
102 | | |
103 | | For primitive identification, getPrimitiveID is used currently in this implementations |
104 | | to allow a fast switch/case processing. This needs a unique identifier mechanism which |
105 | | currently uses defines (see drawinglayer_primitivetypes2d.hxx). For UNO primitive API |
106 | | it will be needed to add a unique descriptor (Name?) later to the API. |
107 | | |
108 | | This base implementation provides mappings from the methods from XPrimitive2D |
109 | | (getDecomposition/getRange) to the appropriate methods in the C++ implementations |
110 | | (get2DDecomposition/getB2DRange). The PropertyValue ViewParameters is converted to |
111 | | the appropriate C++ implementation class ViewInformation2D. |
112 | | |
113 | | This base class does not implement any buffering; e.g. buffering the decomposition |
114 | | and/or the range. These may be buffered anytime since the definition is that the primitive |
115 | | is read-only and thus unchangeable. This implies that the decomposition and/or getting |
116 | | the range will lead to the same result as last time, under the precondition that |
117 | | the parameter ViewInformation2D is the same as the last one. This is usually the case |
118 | | for view-independent primitives which are defined by not using ViewInformation2D |
119 | | in their get2DDecomposition/getB2DRange implementations. |
120 | | */ |
121 | | class DRAWINGLAYERCORE_DLLPUBLIC BasePrimitive2D : public cppu::OWeakObject |
122 | | { |
123 | | bool mbVisible = true; |
124 | | |
125 | | BasePrimitive2D(const BasePrimitive2D&) = delete; |
126 | | BasePrimitive2D& operator=(const BasePrimitive2D&) = delete; |
127 | | |
128 | | public: |
129 | | // constructor/destructor |
130 | | BasePrimitive2D(); |
131 | | virtual ~BasePrimitive2D() override; |
132 | | |
133 | | /** the ==operator is mainly needed to allow testing newly-created primitives against their last |
134 | | incarnation which buffers/holds the made decompositions. The default implementation |
135 | | uses getPrimitive2DID()-calls to test if it's the same ID at last. |
136 | | Overridden implementations are then based on this implementation |
137 | | */ |
138 | | virtual bool operator==(const BasePrimitive2D& rPrimitive) const; |
139 | 0 | bool operator!=(const BasePrimitive2D& rPrimitive) const { return !operator==(rPrimitive); } |
140 | | |
141 | | /// The default implementation will use getDecomposition results to create the range |
142 | | virtual basegfx::B2DRange |
143 | | getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; |
144 | | |
145 | | /** provide unique ID for fast identifying of known primitive implementations in renderers. These use |
146 | | the defines from drawinglayer_primitivetypes2d.hxx to define unique IDs. |
147 | | */ |
148 | | virtual sal_uInt32 getPrimitive2DID() const = 0; |
149 | | |
150 | | /// The default implementation will return an empty sequence |
151 | | virtual void get2DDecomposition(Primitive2DDecompositionVisitor& rVisitor, |
152 | | const geometry::ViewInformation2D& rViewInformation) const; |
153 | | |
154 | | // Methods from XPrimitive2D |
155 | | |
156 | | /** The getDecomposition implementation for UNO API will use getDecomposition from this implementation. It |
157 | | will construct a ViewInformation2D from the ViewParameters for that purpose |
158 | | */ |
159 | | Primitive2DContainer |
160 | | getDecomposition(const css::uno::Sequence<css::beans::PropertyValue>& rViewParameters); |
161 | | |
162 | | /** The getRange implementation for UNO API will use getRange from this implementation. It |
163 | | will construct a ViewInformation2D from the ViewParameters for that purpose |
164 | | */ |
165 | | css::geometry::RealRectangle2D |
166 | | getRange(const css::uno::Sequence<css::beans::PropertyValue>& rViewParameters); |
167 | | |
168 | | // XAccounting |
169 | | virtual sal_Int64 estimateUsage(); |
170 | | |
171 | 0 | void setVisible(bool bVisible) { mbVisible = bVisible; } |
172 | | |
173 | 329k | bool getVisible() const { return mbVisible; } |
174 | | }; |
175 | | |
176 | | /** |
177 | | Rather than make all the BasePrimitive2D classes bear the cost of being an UNO |
178 | | object, we just wrap the top level BasePrimitive2D in this class when we need |
179 | | to pass them over UNO |
180 | | */ |
181 | | class UNLESS_MERGELIBS(DRAWINGLAYERCORE_DLLPUBLIC) UnoPrimitive2D final |
182 | | : public BasePrimitive2DImplBase |
183 | | { |
184 | | UnoPrimitive2D(const UnoPrimitive2D&) = delete; |
185 | | UnoPrimitive2D& operator=(const UnoPrimitive2D&) = delete; |
186 | | |
187 | | public: |
188 | | // constructor/destructor |
189 | | UnoPrimitive2D(rtl::Reference<BasePrimitive2D> xPrimitive) |
190 | 6.25k | : mxPrimitive(std::move(xPrimitive)) |
191 | 6.25k | { |
192 | 6.25k | } |
193 | | virtual ~UnoPrimitive2D() override; |
194 | | |
195 | | // Methods from XPrimitive2D |
196 | | |
197 | | /** The getDecomposition implementation for UNO API will use getDecomposition from this implementation. It |
198 | | will construct a ViewInformation2D from the ViewParameters for that purpose |
199 | | */ |
200 | | virtual css::uno::Sequence<::css::uno::Reference<::css::graphic::XPrimitive2D>> SAL_CALL |
201 | | getDecomposition(const css::uno::Sequence<css::beans::PropertyValue>& rViewParameters) override; |
202 | | |
203 | | /** The getRange implementation for UNO API will use getRange from this implementation. It |
204 | | will construct a ViewInformation2D from the ViewParameters for that purpose |
205 | | */ |
206 | | virtual css::geometry::RealRectangle2D SAL_CALL |
207 | | getRange(const css::uno::Sequence<css::beans::PropertyValue>& rViewParameters) override; |
208 | | |
209 | | // XAccounting |
210 | | virtual sal_Int64 SAL_CALL estimateUsage() override; |
211 | | |
212 | 5.71k | rtl::Reference<BasePrimitive2D> const& getBasePrimitive2D() const { return mxPrimitive; } |
213 | | |
214 | | private: |
215 | | rtl::Reference<BasePrimitive2D> mxPrimitive; |
216 | | }; |
217 | | |
218 | | } // end of namespace drawinglayer::primitive2d |
219 | | |
220 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |