Coverage Report

Created: 2026-02-14 09:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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: */