Coverage Report

Created: 2026-05-16 09:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/svgio/inc/svgstyleattributes.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 "svgpaint.hxx"
23
#include "svgnode.hxx"
24
#include "svgtools.hxx"
25
#include <tools/fontenum.hxx>
26
#include <vcl/font/Variation.hxx>
27
#include <basegfx/polygon/b2dpolypolygontools.hxx>
28
#include <drawinglayer/primitive2d/Primitive2DContainer.hxx>
29
30
31
// predefines
32
33
namespace svgio::svgreader {
34
    class SvgGradientNode;
35
    class SvgPatternNode;
36
    class SvgMarkerNode;
37
    class SvgClipPathNode;
38
    class SvgFilterNode;
39
    class SvgMaskNode;
40
}
41
42
43
namespace svgio::svgreader
44
    {
45
        enum class StrokeLinecap
46
        {
47
            notset,
48
            butt,
49
            round,
50
            square
51
        };
52
53
        enum class StrokeLinejoin
54
        {
55
            notset,
56
            miter,
57
            round,
58
            bevel
59
        };
60
61
        enum class FontSize
62
        {
63
            notset,
64
            xx_small,
65
            x_small,
66
            small,
67
            smaller,
68
            medium,
69
            large,
70
            larger,
71
            x_large,
72
            xx_large,
73
            initial
74
        };
75
76
        enum class FontStretch
77
        {
78
            notset,
79
            normal,
80
            wider,
81
            narrower,
82
            ultra_condensed,
83
            extra_condensed,
84
            condensed,
85
            semi_condensed,
86
            semi_expanded,
87
            expanded,
88
            extra_expanded,
89
            ultra_expanded
90
        };
91
92
        FontStretch getWider(FontStretch aSource);
93
        FontStretch getNarrower(FontStretch aSource);
94
95
        enum class FontStyle
96
        {
97
            notset,
98
            normal,
99
            italic,
100
            oblique
101
        };
102
103
        enum class FontWeight
104
        {
105
            notset,
106
            N100,
107
            N200,
108
            N300,
109
            N400, // same as normal
110
            N500,
111
            N600,
112
            N700, // same as bold
113
            N800,
114
            N900,
115
            bolder,
116
            lighter,
117
        };
118
119
        enum class FontDirection
120
        {
121
            notset,
122
            LTR,
123
            RTL,
124
        };
125
126
        enum class UnicodeBidi
127
        {
128
            notset,
129
            normal,
130
            bidi_override,
131
        };
132
133
        FontWeight getBolder(FontWeight aSource);
134
        FontWeight getLighter(FontWeight aSource);
135
        ::FontWeight getVclFontWeight(FontWeight aSource);
136
137
        enum class TextAlign
138
        {
139
            notset,
140
            left,
141
            right,
142
            center,
143
            justify
144
        };
145
146
        enum class TextDecoration
147
        {
148
            notset,
149
            none,
150
            underline,
151
            overline,
152
            line_through,
153
            blink
154
        };
155
156
        enum class TextAnchor
157
        {
158
            notset,
159
            start,
160
            middle,
161
            end
162
        };
163
164
        enum class FillRule
165
        {
166
            notset,
167
            nonzero,
168
            evenodd
169
        };
170
171
        enum class BaselineShift
172
        {
173
            Baseline,
174
            Sub,
175
            Super,
176
            Percentage,
177
            Length
178
        };
179
180
        enum class DominantBaseline
181
        {
182
            Auto,
183
            Middle,
184
            Hanging,
185
            Central
186
        };
187
188
        enum class Overflow
189
        {
190
            notset,
191
            hidden,
192
            visible
193
        };
194
195
        enum class Visibility
196
        {
197
            notset,
198
            visible,
199
            hidden,
200
            collapse,
201
            inherit
202
        };
203
204
        class SvgStyleAttributes
205
        {
206
        private:
207
            SvgNode&                    mrOwner;
208
            const SvgStyleAttributes*   mpCssStyle;
209
            SvgPaint                    maFill;
210
            SvgPaint                    maStroke;
211
            SvgPaint                    maStopColor;
212
            SvgNumber                   maStrokeWidth;
213
            SvgNumber                   maStopOpacity;
214
            SvgNumber                   maFillOpacity;
215
            SvgNumberVector             maStrokeDasharray;
216
            SvgNumber                   maStrokeDashOffset;
217
            StrokeLinecap               maStrokeLinecap;
218
            StrokeLinejoin              maStrokeLinejoin;
219
            SvgNumber                   maStrokeMiterLimit;
220
            SvgNumber                   maStrokeOpacity;
221
            SvgStringVector             maFontFamily;
222
            FontSize                    maFontSize;
223
            SvgNumber                   maFontSizeNumber;
224
            FontStretch                 maFontStretch;
225
            FontStyle                   maFontStyle;
226
            FontWeight                  maFontWeight;
227
            std::vector<vcl::font::Variation> maFontVariations;
228
            FontDirection               maFontDirection;
229
            UnicodeBidi                 maUnicodeBidi;
230
            TextAlign                   maTextAlign;
231
            TextDecoration              maTextDecoration;
232
            TextAnchor                  maTextAnchor;
233
            SvgPaint                    maColor;
234
            SvgNumber                   maOpacity;
235
            Overflow                    maOverflow;
236
            Visibility                  maVisibility;
237
            OUString               maTitle;
238
            OUString               maDesc;
239
240
            /// link to content. If set, the node can be fetched on demand
241
            OUString               maClipPathXLink;
242
            OUString               maFilterXLink;
243
            OUString               maMaskXLink;
244
245
            /// link to markers. If set, the node can be fetched on demand
246
            OUString               maMarkerStartXLink;
247
            OUString               maMarkerMidXLink;
248
            OUString               maMarkerEndXLink;
249
250
            /// fill rule
251
            FillRule                    maFillRule;
252
253
            // ClipRule setting (only valid when mbIsClipPathContent == true, default is FillRule_nonzero)
254
            FillRule                    maClipRule;
255
256
            // BaselineShift: Type and number (in case of BaselineShift_Percentage or BaselineShift_Length)
257
            BaselineShift               maBaselineShift;
258
            SvgNumber                   maBaselineShiftNumber;
259
260
            DominantBaseline            maDominantBaseline;
261
262
            mutable std::vector<sal_uInt16> maResolvingParent;
263
264
265
            // #121221# Defines if evtl. an empty array *is* set
266
            bool                        mbStrokeDasharraySet : 1;
267
268
            // tdf#155651 Defines if 'context-fill' is used in fill
269
            bool                        mbUseFillFromContextFill : 1;
270
271
            // tdf#155651 Defines if 'context-stroke' is used in fill
272
            bool                        mbUseFillFromContextStroke : 1;
273
274
            // tdf#155651 Defines if 'context-fill' is used in stroke
275
            bool                        mbUseStrokeFromContextFill : 1;
276
277
            // tdf#155651 Defines if 'context-stroke' is used in stroke
278
            bool                        mbUseStrokeFromContextStroke : 1;
279
280
            // tdf#94765 Check id references in gradient/pattern getters
281
            OUString                    maNodeFillURL;
282
            OUString                    maNodeStrokeURL;
283
284
            /// internal helpers
285
            void add_fillGradient(
286
                const basegfx::B2DPolyPolygon& rPath,
287
                drawinglayer::primitive2d::Primitive2DContainer& rTarget,
288
                const SvgGradientNode& rFillGradient,
289
                const basegfx::B2DRange& rGeoRange) const;
290
            void add_fillPatternTransform(
291
                const basegfx::B2DPolyPolygon& rPath,
292
                drawinglayer::primitive2d::Primitive2DContainer& rTarget,
293
                const SvgPatternNode& rFillGradient,
294
                const basegfx::B2DRange& rGeoRange) const;
295
            void add_fillPattern(
296
                const basegfx::B2DPolyPolygon& rPath,
297
                drawinglayer::primitive2d::Primitive2DContainer& rTarget,
298
                const SvgPatternNode& rFillGradient,
299
                const basegfx::B2DRange& rGeoRange) const;
300
            void add_fill(
301
                const basegfx::B2DPolyPolygon& rPath,
302
                drawinglayer::primitive2d::Primitive2DContainer& rTarget,
303
                const basegfx::B2DRange& rGeoRange) const;
304
            void add_stroke(
305
                const basegfx::B2DPolyPolygon& rPath,
306
                drawinglayer::primitive2d::Primitive2DContainer& rTarget,
307
                const basegfx::B2DRange& rGeoRange) const;
308
            bool prepare_singleMarker(
309
                drawinglayer::primitive2d::Primitive2DContainer& rMarkerPrimitives,
310
                basegfx::B2DHomMatrix& rMarkerTransform,
311
                basegfx::B2DRange& rClipRange,
312
                const SvgMarkerNode& rMarker) const;
313
            void add_markers(
314
                const basegfx::B2DPolyPolygon& rPath,
315
                drawinglayer::primitive2d::Primitive2DContainer& rTarget,
316
                const basegfx::utils::PointIndexSet* pHelpPointIndices) const;
317
318
319
        public:
320
            /// local attribute scanner
321
            void parseStyleAttribute(SVGToken aSVGToken, const OUString& rContent);
322
323
            /// helper which does the necessary with a given path
324
            void add_text(
325
                drawinglayer::primitive2d::Primitive2DContainer& rTarget,
326
                drawinglayer::primitive2d::Primitive2DContainer&& rSource) const;
327
            void add_path(
328
                const basegfx::B2DPolyPolygon& rPath,
329
                drawinglayer::primitive2d::Primitive2DContainer& rTarget,
330
                const basegfx::utils::PointIndexSet* pHelpPointIndices) const;
331
            void add_postProcess(
332
                drawinglayer::primitive2d::Primitive2DContainer& rTarget,
333
                drawinglayer::primitive2d::Primitive2DContainer&& rSource,
334
                const std::optional<basegfx::B2DHomMatrix>& pTransform) const;
335
336
            /// helper to set mpCssStyle temporarily for CSS style hierarchies
337
0
            void setCssStyle(const SvgStyleAttributes* pNew) { mpCssStyle = pNew; }
338
128
            const SvgStyleAttributes* getCssStyle() const { return mpCssStyle; }
339
340
            /// scan helpers
341
            void readCssStyle(std::u16string_view rCandidate);
342
            const SvgStyleAttributes* getCssStyleOrParentStyle() const;
343
344
            const SvgMarkerNode* getMarkerParentNode() const;
345
346
            SvgStyleAttributes(SvgNode& rOwner);
347
            ~SvgStyleAttributes();
348
349
            // Check if this attribute is part of a ClipPath.
350
            // If so, rough geometry will be created on decomposition by patching
351
            // values for fill, stroke, strokeWidth and others
352
            bool isClipPathContent() const;
353
354
            /// fill content
355
            bool isFillSet() const; // #i125258# ask if fill is a direct hard attribute (no hierarchy)
356
            const basegfx::BColor* getFill() const;
357
64
            void setFill(const SvgPaint& rFill) { maFill = rFill; }
358
359
            /// stroke content
360
            const basegfx::BColor* getStroke() const;
361
362
            /// stop color content
363
            const basegfx::BColor& getStopColor() const;
364
365
            /// stroke-width content
366
            SvgNumber getStrokeWidth() const;
367
368
            /// stop opacity content
369
            SvgNumber getStopOpacity() const;
370
371
            /// access to evtl. set fill gradient
372
            const SvgGradientNode* getSvgGradientNodeFill() const;
373
374
            /// access to evtl. set fill pattern
375
            const SvgPatternNode* getSvgPatternNodeFill() const;
376
377
            /// access to evtl. set stroke gradient
378
            const SvgGradientNode* getSvgGradientNodeStroke() const;
379
380
            /// access to evtl. set stroke pattern
381
            const SvgPatternNode* getSvgPatternNodeStroke() const;
382
383
            /// fill opacity content
384
            SvgNumber getFillOpacity() const;
385
386
            /// fill rule content
387
            FillRule getFillRule() const;
388
389
            /// clip rule content
390
            FillRule getClipRule() const;
391
392
            /// fill StrokeDasharray content
393
            const SvgNumberVector& getStrokeDasharray() const;
394
395
            /// StrokeDashOffset content
396
            SvgNumber getStrokeDashOffset() const;
397
398
            /// StrokeLinecap content
399
            StrokeLinecap getStrokeLinecap() const;
400
0
            void setStrokeLinecap(const StrokeLinecap aStrokeLinecap) { maStrokeLinecap = aStrokeLinecap; }
401
402
            /// StrokeLinejoin content
403
            StrokeLinejoin getStrokeLinejoin() const;
404
0
            void setStrokeLinejoin(const StrokeLinejoin aStrokeLinejoin) { maStrokeLinejoin = aStrokeLinejoin; }
405
406
            /// StrokeMiterLimit content
407
            SvgNumber getStrokeMiterLimit() const;
408
409
            /// StrokeOpacity content
410
            SvgNumber getStrokeOpacity() const;
411
412
            /// Font content
413
            const SvgStringVector& getFontFamily() const;
414
415
            /// FontSize content
416
6
            void setFontSize(const FontSize aFontSize) { maFontSize = aFontSize; }
417
            SvgNumber getFontSizeNumber() const;
418
419
            /// FontStretch content
420
            FontStretch getFontStretch() const;
421
0
            void setFontStretch(const FontStretch aFontStretch) { maFontStretch = aFontStretch; }
422
423
            /// FontStyle content
424
            FontStyle getFontStyle() const;
425
11
            void setFontStyle(const FontStyle aFontStyle) { maFontStyle = aFontStyle; }
426
427
            /// FontWeight content
428
            FontWeight getFontWeight() const;
429
9
            void setFontWeight(const FontWeight aFontWeight) { maFontWeight = aFontWeight; }
430
431
            /// FontVariations content
432
0
            const std::vector<vcl::font::Variation>& getFontVariations() const { return maFontVariations; }
433
0
            void setFontVariations(std::vector<vcl::font::Variation>&& rFontVariations) { maFontVariations = std::move(rFontVariations); }
434
435
            /// FontDirection content
436
            FontDirection getFontDirection() const;
437
0
            void setFontDirection(const FontDirection aFontDirection) { maFontDirection = aFontDirection; }
438
439
            /// UnicodeBidi content
440
            UnicodeBidi getUnicodeBidi() const;
441
0
            void setUnicodeBidi(const UnicodeBidi aUnicodeBidi) { maUnicodeBidi = aUnicodeBidi; }
442
443
            /// TextAlign content
444
            TextAlign getTextAlign() const;
445
0
            void setTextAlign(const TextAlign aTextAlign) { maTextAlign = aTextAlign; }
446
447
            /// TextDecoration content
448
            const SvgStyleAttributes* getTextDecorationDefiningSvgStyleAttributes() const;
449
            TextDecoration getTextDecoration() const;
450
42
            void setTextDecoration(const TextDecoration aTextDecoration) { maTextDecoration = aTextDecoration; }
451
452
            /// TextAnchor content
453
            TextAnchor getTextAnchor() const;
454
0
            void setTextAnchor(const TextAnchor aTextAnchor) { maTextAnchor = aTextAnchor; }
455
456
            /// Color content
457
            const basegfx::BColor* getColor() const;
458
459
            /// Resolve current color (defaults to black if no color is specified)
460
            const basegfx::BColor* getCurrentColor() const;
461
462
            /// Opacity content
463
            SvgNumber getOpacity() const;
464
0
            void setOpacity(const SvgNumber& rOpacity) { maOpacity = rOpacity; }
465
466
            /// Overflow
467
            Overflow getOverflow() const;
468
0
            void setOverflow(const Overflow aOverflow) { maOverflow = aOverflow; }
469
470
            /// Visibility
471
            Visibility getVisibility() const;
472
0
            void setVisibility(const Visibility aVisibility) { maVisibility = aVisibility; }
473
474
            // Title content
475
0
            const OUString& getTitle() const { return maTitle; }
476
477
            // Desc content
478
0
            const OUString& getDesc() const { return maDesc; }
479
480
            // ClipPathXLink content
481
            OUString getClipPathXLink() const;
482
            const SvgClipPathNode* accessClipPathXLink() const;
483
484
            // FilterXLink content
485
            OUString getFilterXLink() const;
486
            const SvgFilterNode* accessFilterXLink() const;
487
488
            // MaskXLink content
489
            OUString getMaskXLink() const;
490
            const SvgMaskNode* accessMaskXLink() const;
491
492
            // MarkerStartXLink content
493
            OUString getMarkerStartXLink() const;
494
            const SvgMarkerNode* accessMarkerStartXLink() const;
495
496
            // MarkerMidXLink content
497
            OUString getMarkerMidXLink() const;
498
            const SvgMarkerNode* accessMarkerMidXLink() const;
499
500
            // MarkerEndXLink content
501
            OUString getMarkerEndXLink() const;
502
            const SvgMarkerNode* accessMarkerEndXLink() const;
503
504
            // BaselineShift
505
0
            void setBaselineShift(const BaselineShift aBaselineShift) { maBaselineShift = aBaselineShift; }
506
            BaselineShift getBaselineShift() const;
507
            SvgNumber getBaselineShiftNumber() const;
508
509
            // DominantBaseline
510
0
            void setDominantBaseline(const DominantBaseline aDominantBaseline) { maDominantBaseline = aDominantBaseline; }
511
            DominantBaseline getDominantBaseline() const;
512
        };
513
514
} // end of namespace svgio::svgreader
515
516
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */