Coverage Report

Created: 2026-02-14 09:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/include/vcl/graphictools.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
#ifndef INCLUDED_VCL_GRAPHICTOOLS_HXX
21
#define INCLUDED_VCL_GRAPHICTOOLS_HXX
22
23
#include <vcl/dllapi.h>
24
#include <sal/types.h>
25
#include <tools/color.hxx>
26
#include <tools/poly.hxx>
27
#include <vcl/graph.hxx>
28
29
#include <vector>
30
31
class SvStream;
32
33
/** Encapsulates geometry and associated attributes of a graphical 'pen stroke'
34
35
    @attention Widespread use is deprecated. See declarations above
36
    for the way to go. Especially the copied enums from svx/xenum.hxx
37
    are troublesome.
38
39
    Use this class to store geometry and attributes of a graphical
40
    'pen stroke', such as pen width, dashing etc. The geometry is the
41
    so-called 'path' along which the stroke is traced, with the given
42
    pen width. The cap type determines how the open ends of the path
43
    should be drawn. If the geometry consists of more than one
44
    segment, the join type determines in which way the segments are
45
    joined.
46
 */
47
class VCL_DLLPUBLIC SvtGraphicStroke
48
{
49
public:
50
    /// Style for open stroke ends
51
    enum CapType
52
    {
53
        /// No additional cap
54
        capButt=0,
55
        /// Half-round cap at the line end, the center lying at the end point
56
        capRound,
57
        /// Half-square cap at the line end, the center lying at the end point
58
        capSquare
59
    };
60
    /// Style for joins of individual stroke segments
61
    enum JoinType
62
    {
63
        /// Extend segment edges, until they cross
64
        joinMiter=0,
65
        /// Connect segments by a filled round arc
66
        joinRound,
67
        /// Connect segments by a direct straight line
68
        joinBevel,
69
        /// Perform no join, leads to visible gaps between thick line segments
70
        joinNone
71
    };
72
    typedef ::std::vector< double > DashArray;
73
74
    SvtGraphicStroke();
75
    /** All in one constructor
76
77
        See accessor method descriptions for argument description
78
     */
79
    SvtGraphicStroke( tools::Polygon  aPath,
80
                      tools::PolyPolygon  aStartArrow,
81
                      tools::PolyPolygon  aEndArrow,
82
                      double                fTransparency,
83
                      double                fStrokeWidth,
84
                      CapType               aCap,
85
                      JoinType              aJoin,
86
                      double                fMiterLimit,
87
                      DashArray&&           rDashArray  );      // TODO: Dash array offset (position where to start, see PS)
88
89
    // accessors
90
    /// Query path to stroke
91
    void            getPath             ( tools::Polygon& ) const;
92
    /** Get the polygon that is put at the start of the line
93
94
        The polygon is in a special normalized position: the center of
95
        the stroked path will meet the given polygon at (0,0) from
96
        negative y values. Thus, an arrow would have its baseline on
97
        the x axis, going upwards to positive y values. Furthermore,
98
        the polygon is also scaled in a special way: the width of the
99
        joining stroke is defined to be
100
        SvtGraphicStroke::normalizedArrowWidth (0x10000), i.e. ranging
101
        from x=-0x8000 to x=0x8000. So, if the arrow does have this
102
        width, it has to fit every stroke with every stroke width
103
        exactly.
104
     */
105
    void            getStartArrow       ( tools::PolyPolygon& ) const;
106
    /** Get the polygon that is put at the end of the line
107
108
        The polygon is in a special normalized position, and already
109
        scaled to the desired size: the center of the stroked path
110
        will meet the given polygon at (0,0) from negative y
111
        values. Thus, an arrow would have its baseline on the x axis,
112
        going upwards to positive y values. Furthermore, the polygon
113
        is also scaled in a special way: the width of the joining
114
        stroke is defined to be SvtGraphicStroke::normalizedArrowWidth
115
        (0x10000), i.e. ranging from x=-0x8000 to x=0x8000. So, if the
116
        arrow does have this width, it has to fit every stroke with
117
        every stroke width exactly.
118
     */
119
    void            getEndArrow         ( tools::PolyPolygon& ) const;
120
    /** Get stroke transparency
121
122
        @return the transparency, ranging from 0.0 (opaque) to 1.0 (fully translucent)
123
     */
124
4.24k
    double          getTransparency     () const { return mfTransparency;}
125
    /// Get width of the stroke
126
4.24k
    double          getStrokeWidth      () const { return mfStrokeWidth;}
127
    /// Get the style in which open stroke ends are drawn
128
4.24k
    CapType         getCapType          () const { return maCapType;}
129
    /// Get the style in which the stroke segments are joined
130
8.49k
    JoinType        getJoinType         () const { return maJoinType;}
131
    /// Get the maximum length of mitered joins
132
4.24k
    double          getMiterLimit       () const { return mfMiterLimit;}
133
    /// Get an array of "on" and "off" lengths for stroke dashing
134
    void            getDashArray        ( DashArray& ) const;
135
136
    // mutators
137
    /// Set path to stroke
138
    void    setPath             ( const tools::Polygon& );
139
    /** Set the polygon that is put at the start of the line
140
141
        The polygon has to be in a special normalized position, and
142
        already scaled to the desired size: the center of the stroked
143
        path will meet the given polygon at (0,0) from negative y
144
        values. Thus, an arrow would have its baseline on the x axis,
145
        going upwards to positive y values. Furthermore, the polygon
146
        also has to be scaled appropriately: the width of the joining
147
        stroke is defined to be SvtGraphicStroke::normalizedArrowWidth
148
        (0x10000), i.e. ranging from x=-0x8000 to x=0x8000. If your
149
        arrow does have this width, it will fit every stroke with
150
        every stroke width exactly.
151
     */
152
    void    setStartArrow       ( const tools::PolyPolygon& );
153
    /** Set the polygon that is put at the end of the line
154
155
        The polygon has to be in a special normalized position, and
156
        already scaled to the desired size: the center of the stroked
157
        path will meet the given polygon at (0,0) from negative y
158
        values. Thus, an arrow would have its baseline on the x axis,
159
        going upwards to positive y values. Furthermore, the polygon
160
        also has to be scaled appropriately: the width of the joining
161
        stroke is defined to be SvtGraphicStroke::normalizedArrowWidth
162
        (0x10000), i.e. ranging from x=-0x8000 to x=0x8000. If your
163
        arrow does have this width, it will fit every stroke with
164
        every stroke width exactly.
165
     */
166
    void    setEndArrow         ( const tools::PolyPolygon& );
167
    /// Affine scaling in both X and Y dimensions
168
    void    scale               ( double fScaleX, double fScaleY );
169
170
private:
171
    // friends
172
    VCL_DLLPUBLIC friend SvStream& WriteSvtGraphicStroke( SvStream& rOStm, const SvtGraphicStroke& rClass );
173
    VCL_DLLPUBLIC friend SvStream& ReadSvtGraphicStroke( SvStream& rIStm, SvtGraphicStroke& rClass );
174
175
    tools::Polygon  maPath;
176
    tools::PolyPolygon maStartArrow;
177
    tools::PolyPolygon maEndArrow;
178
    double          mfTransparency;
179
    double          mfStrokeWidth;
180
    CapType         maCapType;
181
    JoinType        maJoinType;
182
    double          mfMiterLimit;
183
    DashArray       maDashArray;
184
};
185
186
/** Encapsulates geometry and associated attributes of a filled area
187
188
    @attention Widespread use is deprecated. See declarations above
189
    for the way to go. Especially the copied enums from svx/xenum.hxx
190
    is troublesome.
191
192
    Use this class to store geometry and attributes of a filled area,
193
    such as fill color, transparency, texture or hatch.  The geometry
194
    is the so-called 'path', whose inner area will get filled
195
    according to the attributes set. If the path is intersecting, or
196
    one part of the path is lying fully within another part, then the
197
    fill rule determines which parts are filled and which are not.
198
 */
199
class VCL_DLLPUBLIC SvtGraphicFill
200
{
201
public:
202
    /// Type of fill algorithm used
203
    enum FillRule
204
    {
205
        /** Non-zero winding rule
206
207
            Fill shape scanline-wise. Starting at the left, determine
208
            the winding number as follows: every segment crossed that
209
            runs counter-clockwise adds one to the winding number,
210
            every segment crossed that runs clockwise subtracts
211
            one. The part of the scanline where the winding number is
212
            non-zero gets filled.
213
         */
214
        fillNonZero=0,
215
        /** Even-odd fill rule
216
217
            Fill shape scanline-wise. Starting at the left, count the
218
            number of segments crossed. If this number is odd, the
219
            part of the scanline is filled, otherwise not.
220
         */
221
        fillEvenOdd
222
    };
223
    /// Type of filling used
224
    enum FillType
225
    {
226
        /// Fill with a specified solid color
227
        fillSolid=0,
228
        /// Fill with the specified gradient
229
        fillGradient,
230
        /// Fill with the specified hatch
231
        fillHatch,
232
        /// Fill with the specified texture (a Graphic object)
233
        fillTexture
234
    };
235
    /// Type of hatching used
236
    enum HatchType
237
    {
238
        /// horizontal parallel lines, one unit apart
239
        hatchSingle=0,
240
        /// horizontal and vertical orthogonally crossing lines, one unit apart
241
        hatchDouble,
242
        /// three crossing lines, like HatchType::hatchDouble, but
243
        /// with an additional diagonal line, rising to the upper
244
        /// right corner. The first diagonal line goes through the
245
        /// upper left corner, the other are each spaced a unit apart.
246
        hatchTriple
247
    };
248
    /// Type of gradient used
249
    enum class GradientType {Linear, Radial, Rectangular};
250
    /// Special values for gradient step count
251
    enum { gradientStepsInfinite=0 };
252
    /** Homogeneous 2D transformation matrix
253
254
        This is a 2x3 matrix representing an affine transformation on
255
        the R^2, in the usual C/C++ row major form. It is structured as follows:
256
        <pre>
257
        a b t_x
258
        c d t_y
259
        0 0 1
260
        </pre>
261
        where the lowest line is not stored in the matrix, since it is
262
        constant. Variables t_x and t_y contain translational
263
        components, a to d rotation, scale and shear (for details,
264
        look up your favorite linear algebra/computer graphics book).
265
     */
266
    struct UNLESS_MERGELIBS(VCL_DLLPUBLIC) Transform
267
    {
268
        enum { MatrixSize=6 };
269
        Transform();
270
        double matrix[MatrixSize];
271
    };
272
273
    SvtGraphicFill();
274
    /** All in one constructor
275
276
        See accessor method descriptions for argument description
277
     */
278
    SvtGraphicFill( tools::PolyPolygon   aPath,
279
                    Color               aFillColor,
280
                    double              fTransparency,
281
                    FillRule            aFillRule,
282
                    FillType            aFillType,              // TODO: Multitexturing
283
                    const Transform&    aFillTransform,
284
                    bool                bTiling,
285
                    HatchType           aHatchType,             // TODO: vector of directions and start points
286
                    Color               aHatchColor,
287
                    GradientType        aGradientType,          // TODO: Transparent gradients (orthogonal to normal ones)
288
                    Color               aGradient1stColor,      // TODO: vector of colors and offsets
289
                    Color               aGradient2ndColor,
290
                    sal_Int32           aGradientStepCount,     // numbers of steps to render the gradient. gradientStepsInfinite means infinitely many.
291
                    Graphic       aFillGraphic );
292
293
    // accessors
294
    /// Query path to fill
295
    void            getPath             ( tools::PolyPolygon& ) const;
296
    /// Get color used for solid fills
297
0
    const Color&    getFillColor        () const { return maFillColor;}
298
    /** Get stroke transparency
299
300
        @return the transparency, ranging from 0.0 (opaque) to 1.0 (fully translucent)
301
     */
302
0
    double          getTransparency     () const { return mfTransparency;}
303
    /// Get fill rule used
304
0
    FillRule        getFillRule         () const { return maFillRule;}
305
    /** Get fill type used
306
307
        Currently, only one of the fill types can be used
308
        simultaneously. If you specify e.g. FillRule::fillGradient,
309
        hatching, texture and solid fill color are ignored.
310
     */
311
0
    FillType        getFillType         () const { return maFillType;}
312
    /** Get transformation applied to hatch, gradient or texture during fill
313
314
        A fill operation generally starts at the top left position of
315
        the object's bounding box. At that position (if tiling is on,
316
        also all successive positions), the specified fill graphic is
317
        rendered, after applying the fill transformation to it. For
318
        example, if the fill transformation contains a translation,
319
        the fill graphic is rendered at the object's bounding box's
320
        top left corner plus the translation components.
321
322
     */
323
    void            getTransform        ( Transform& ) const;
324
325
    /** Query state of texture tiling
326
327
        @return true, if texture is tiled, false, if output only once.
328
     */
329
0
    bool            isTiling            () const { return mbTiling;}
330
    /// Get type of gradient used
331
0
    GradientType    getGradientType     () const { return maGradientType;}
332
333
    /** Get the texture graphic used
334
335
        The Graphic object returned is used to fill the geometry, if
336
        the FillType is fillTexture. The Graphic object is always
337
        assumed to be of size 1x1, the transformation is used to scale
338
        it to the appropriate size.
339
     */
340
    void            getGraphic          ( Graphic& ) const;
341
342
    // mutators
343
    /// Set path to fill
344
    void    setPath             ( const tools::PolyPolygon& rPath );
345
346
private:
347
    // friends
348
    VCL_DLLPUBLIC friend SvStream& WriteSvtGraphicFill( SvStream& rOStm, const SvtGraphicFill& rClass );
349
    VCL_DLLPUBLIC friend SvStream& ReadSvtGraphicFill( SvStream& rIStm, SvtGraphicFill& rClass );
350
351
    tools::PolyPolygon     maPath;
352
    Color           maFillColor;
353
    double          mfTransparency;
354
    FillRule        maFillRule;
355
    FillType        maFillType;
356
    Transform       maFillTransform;
357
    bool            mbTiling;
358
    HatchType       maHatchType;
359
    Color           maHatchColor;
360
    GradientType    maGradientType;
361
    Color           maGradient1stColor;
362
    Color           maGradient2ndColor;
363
    sal_Int32       maGradientStepCount;
364
    Graphic         maFillGraphic;
365
};
366
367
#endif // INCLUDED_VCL_GRAPHICTOOLS_HXX
368
369
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */