1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 #ifndef INCLUDED_SVGIO_SVGREADER_SVGSTYLEATTRIBUTES_HXX
23 #define INCLUDED_SVGIO_SVGREADER_SVGSTYLEATTRIBUTES_HXX
24 
25 #include <svgio/svgiodllapi.h>
26 #include <svgio/svgreader/svgpaint.hxx>
27 #include <svgio/svgreader/svgnode.hxx>
28 #include <vcl/vclenum.hxx>
29 #include <basegfx/polygon/b2dpolypolygontools.hxx>
30 
31 //////////////////////////////////////////////////////////////////////////////
32 // predefines
33 
34 namespace svgio { namespace svgreader {
35     class SvgGradientNode;
36     class SvgPatternNode;
37     class SvgMarkerNode;
38 }}
39 
40 //////////////////////////////////////////////////////////////////////////////
41 
42 namespace svgio
43 {
44     namespace svgreader
45     {
46         enum StrokeLinecap
47         {
48             StrokeLinecap_notset,
49             StrokeLinecap_butt,
50             StrokeLinecap_round,
51             StrokeLinecap_square
52         };
53 
54         enum StrokeLinejoin
55         {
56             StrokeLinejoin_notset,
57             StrokeLinejoin_miter,
58             StrokeLinejoin_round,
59             StrokeLinejoin_bevel
60         };
61 
62         enum FontStretch
63         {
64             FontStretch_notset,
65             FontStretch_normal,
66             FontStretch_wider,
67             FontStretch_narrower,
68             FontStretch_ultra_condensed,
69             FontStretch_extra_condensed,
70             FontStretch_condensed,
71             FontStretch_semi_condensed,
72             FontStretch_semi_expanded,
73             FontStretch_expanded,
74             FontStretch_extra_expanded,
75             FontStretch_ultra_expanded
76         };
77 
78         FontStretch getWider(FontStretch aSource);
79         FontStretch getNarrower(FontStretch aSource);
80 
81         enum FontStyle
82         {
83             FontStyle_notset,
84             FontStyle_normal,
85             FontStyle_italic,
86             FontStyle_oblique
87         };
88 
89         enum FontVariant
90         {
91             FontVariant_notset,
92             FontVariant_normal,
93             FontVariant_small_caps
94         };
95 
96         enum FontWeight
97         {
98             FontWeight_notset,
99             FontWeight_100,
100             FontWeight_200,
101             FontWeight_300,
102             FontWeight_400, // same as FontWeight_normal
103             FontWeight_500,
104             FontWeight_600,
105             FontWeight_700, // same as FontWeight_bold
106             FontWeight_800,
107             FontWeight_900,
108             FontWeight_bolder,
109             FontWeight_lighter,
110         };
111 
112         FontWeight getBolder(FontWeight aSource);
113         FontWeight getLighter(FontWeight aSource);
114         ::FontWeight getVclFontWeight(FontWeight aSource);
115 
116         enum TextAlign
117         {
118             TextAlign_notset,
119             TextAlign_left,
120             TextAlign_right,
121             TextAlign_center,
122             TextAlign_justify
123         };
124 
125         enum TextDecoration
126         {
127             TextDecoration_notset,
128             TextDecoration_none,
129             TextDecoration_underline,
130             TextDecoration_overline,
131             TextDecoration_line_through,
132             TextDecoration_blink
133         };
134 
135         enum TextAnchor
136         {
137             TextAnchor_notset,
138             TextAnchor_start,
139             TextAnchor_middle,
140             TextAnchor_end
141         };
142 
143         enum FillRule
144         {
145             FillRule_notset,
146             FillRule_nonzero,
147             FillRule_evenodd
148         };
149 
150         enum BaselineShift
151         {
152             BaselineShift_Baseline,
153             BaselineShift_Sub,
154             BaselineShift_Super,
155             BaselineShift_Percentage,
156             BaselineShift_Length
157         };
158 
159         class SvgStyleAttributes
160         {
161         private:
162             SvgNode&                    mrOwner;
163             const SvgStyleAttributes*   mpCssStyleParent;
164             SvgPaint                    maFill;
165             SvgPaint                    maStroke;
166             SvgPaint                    maStopColor;
167             SvgNumber                   maStrokeWidth;
168             SvgNumber                   maStopOpacity;
169             const SvgGradientNode*      mpSvgGradientNodeFill;
170             const SvgGradientNode*      mpSvgGradientNodeStroke;
171             const SvgPatternNode*       mpSvgPatternNodeFill;
172             const SvgPatternNode*       mpSvgPatternNodeStroke;
173             SvgNumber                   maFillOpacity;
174             SvgNumberVector             maStrokeDasharray;
175             SvgNumber                   maStrokeDashOffset;
176             StrokeLinecap               maStrokeLinecap;
177             StrokeLinejoin              maStrokeLinejoin;
178             SvgNumber                   maStrokeMiterLimit;
179             SvgNumber                   maStrokeOpacity;
180             SvgStringVector             maFontFamily;
181             SvgNumber                   maFontSize;
182             FontStretch                 maFontStretch;
183             FontStyle                   maFontStyle;
184             FontVariant                 maFontVariant;
185             FontWeight                  maFontWeight;
186             TextAlign                   maTextAlign;
187             TextDecoration              maTextDecoration;
188             TextAnchor                  maTextAnchor;
189             SvgPaint                    maColor;
190             SvgNumber                   maOpacity;
191             rtl::OUString               maTitle;
192             rtl::OUString               maDesc;
193 
194             /// link to content. If set, the node can be fetched on demand
195             rtl::OUString               maClipPathXLink;
196             rtl::OUString               maMaskXLink;
197 
198             /// link to markers. If set, the node can be fetched on demand
199             rtl::OUString               maMarkerStartXLink;
200             const SvgMarkerNode*        mpMarkerStartXLink;
201             rtl::OUString               maMarkerMidXLink;
202             const SvgMarkerNode*        mpMarkerMidXLink;
203             rtl::OUString               maMarkerEndXLink;
204             const SvgMarkerNode*        mpMarkerEndXLink;
205 
206             /// fill rule
207             FillRule                    maFillRule;
208 
209             // ClipRule setting (only valid wne mbIsClipPathContent == true, default is FillRule_nonzero)
210             FillRule                    maClipRule;
211 
212             // BaselineShift: Type and number (in case of BaselineShift_Percentage or BaselineShift_Length)
213             BaselineShift               maBaselineShift;
214             SvgNumber                   maBaselineShiftNumber;
215 
216             /// bitfield
217 
218             // defines if this attributes are part of a ClipPath. If yes,
219             // rough geometry will be created on decomposition by patching
220             // vaules for fill, stroke, strokeWidth and others
221             bool                        mbIsClipPathContent : 1;
222 
223             // #121221# Defines if evtl. an empty array *is* set
224             bool                        mbStrokeDasharraySet : 1;
225 
226             /// internal helpers
227             void add_fillGradient(
228                 const basegfx::B2DPolyPolygon& rPath,
229                 drawinglayer::primitive2d::Primitive2DSequence& rTarget,
230                 const SvgGradientNode& rFillGradient,
231                 const basegfx::B2DRange& rGeoRange) const;
232             void add_fillPatternTransform(
233                 const basegfx::B2DPolyPolygon& rPath,
234                 drawinglayer::primitive2d::Primitive2DSequence& rTarget,
235                 const SvgPatternNode& rFillGradient,
236                 const basegfx::B2DRange& rGeoRange) const;
237             void add_fillPattern(
238                 const basegfx::B2DPolyPolygon& rPath,
239                 drawinglayer::primitive2d::Primitive2DSequence& rTarget,
240                 const SvgPatternNode& rFillGradient,
241                 const basegfx::B2DRange& rGeoRange) const;
242             void add_fill(
243                 const basegfx::B2DPolyPolygon& rPath,
244                 drawinglayer::primitive2d::Primitive2DSequence& rTarget,
245                 const basegfx::B2DRange& rGeoRange) const;
246             void add_stroke(
247                 const basegfx::B2DPolyPolygon& rPath,
248                 drawinglayer::primitive2d::Primitive2DSequence& rTarget,
249                 const basegfx::B2DRange& rGeoRange) const;
250             bool prepare_singleMarker(
251                 drawinglayer::primitive2d::Primitive2DSequence& rMarkerPrimitives,
252                 basegfx::B2DHomMatrix& rMarkerTransform,
253                 basegfx::B2DRange& rClipRange,
254                 const SvgMarkerNode& rMarker) const;
255             void add_markers(
256                 const basegfx::B2DPolyPolygon& rPath,
257                 drawinglayer::primitive2d::Primitive2DSequence& rTarget,
258                 const basegfx::tools::PointIndexSet* pHelpPointIndices) const;
259 
260         public:
261             /// local attribute scanner
262             void parseStyleAttribute(
263                 const rtl::OUString& rTokenName,
264                 SVGToken aSVGToken,
265                 const rtl::OUString& aContent,
266                 bool bCaseIndependent);
267 
268             /// helper which does the necessary with a given path
269             void add_text(
270                 drawinglayer::primitive2d::Primitive2DSequence& rTarget,
271                 drawinglayer::primitive2d::Primitive2DSequence& rSource) const;
272             void add_path(
273                 const basegfx::B2DPolyPolygon& rPath,
274                 drawinglayer::primitive2d::Primitive2DSequence& rTarget,
275                 const basegfx::tools::PointIndexSet* pHelpPointIndices) const;
276             void add_postProcess(
277                 drawinglayer::primitive2d::Primitive2DSequence& rTarget,
278                 const drawinglayer::primitive2d::Primitive2DSequence& rSource,
279                 const basegfx::B2DHomMatrix* pTransform) const;
280 
281             /// helper to set mpCssStyleParent temporarily for CSS style hierarchies
setCssStyleParent(const SvgStyleAttributes * pNew)282             void setCssStyleParent(const SvgStyleAttributes* pNew) { mpCssStyleParent = pNew; }
getCssStyleParent() const283             const SvgStyleAttributes* getCssStyleParent() const { return mpCssStyleParent; }
284 
285             /// scan helpers
286             void readCssStyle(const rtl::OUString& rCandidate);
287             const SvgStyleAttributes* getParentStyle() const;
288 
289             SvgStyleAttributes(SvgNode& rOwner);
290             ~SvgStyleAttributes();
291 
292             /// fill content
293             bool isFillSet() const; // #125258# ask if fill is a direct hard attribute (no hierarchy)
294             const basegfx::BColor* getFill() const;
setFill(const SvgPaint & rFill)295             void setFill(const SvgPaint& rFill) { maFill = rFill; }
296 
297             /// stroke content
298             const basegfx::BColor* getStroke() const;
setStroke(const SvgPaint & rStroke)299             void setStroke(const SvgPaint& rStroke) { maStroke = rStroke; }
300 
301             /// stop color content
302             const basegfx::BColor& getStopColor() const;
setStopColor(const SvgPaint & rStopColor)303             void setStopColor(const SvgPaint& rStopColor) { maStopColor = rStopColor; }
304 
305             /// stroke-width content
306             SvgNumber getStrokeWidth() const;
setStrokeWidth(const SvgNumber & rStrokeWidth=SvgNumber ())307             void setStrokeWidth(const SvgNumber& rStrokeWidth = SvgNumber()) { maStrokeWidth = rStrokeWidth; }
308 
309             /// stop opacity content
310             SvgNumber getStopOpacity() const;
setStopOpacity(const SvgNumber & rStopOpacity=SvgNumber ())311             void setStopOpacity(const SvgNumber& rStopOpacity = SvgNumber()) { maStopOpacity = rStopOpacity; }
312 
313             /// access to evtl. set fill gradient
314             const SvgGradientNode* getSvgGradientNodeFill() const;
setSvgGradientNodeFill(const SvgGradientNode * pNew)315             void setSvgGradientNodeFill(const SvgGradientNode* pNew) { mpSvgGradientNodeFill = pNew; }
316 
317             /// access to evtl. set fill pattern
318             const SvgPatternNode* getSvgPatternNodeFill() const;
setSvgPatternNodeFill(const SvgPatternNode * pNew)319             void setSvgPatternNodeFill(const SvgPatternNode* pNew) { mpSvgPatternNodeFill = pNew; }
320 
321             /// access to evtl. set stroke gradient
322             const SvgGradientNode* getSvgGradientNodeStroke() const;
setSvgGradientNodeStroke(const SvgGradientNode * pNew)323             void setSvgGradientNodeStroke(const SvgGradientNode* pNew) { mpSvgGradientNodeStroke = pNew; }
324 
325             /// access to evtl. set stroke pattern
326             const SvgPatternNode* getSvgPatternNodeStroke() const;
setSvgPatternNodeStroke(const SvgPatternNode * pNew)327             void setSvgPatternNodeStroke(const SvgPatternNode* pNew) { mpSvgPatternNodeStroke = pNew; }
328 
329             /// fill opacity content
330             SvgNumber getFillOpacity() const;
setFillOpacity(const SvgNumber & rFillOpacity=SvgNumber ())331             void setFillOpacity(const SvgNumber& rFillOpacity = SvgNumber()) { maFillOpacity = rFillOpacity; }
332 
333             /// fill rule content
334             FillRule getFillRule() const;
setFillRule(const FillRule aFillRule=FillRule_notset)335             void setFillRule(const FillRule aFillRule = FillRule_notset) { maFillRule = aFillRule; }
336 
337             /// fill StrokeDasharray content
338             const SvgNumberVector& getStrokeDasharray() const;
setStrokeDasharray(const SvgNumberVector & rStrokeDasharray=SvgNumberVector ())339             void setStrokeDasharray(const SvgNumberVector& rStrokeDasharray = SvgNumberVector()) { maStrokeDasharray = rStrokeDasharray; }
340 
341             /// #121221# StrokeDasharray needs a set state, it *may* be set to empty by purpose
getStrokeDasharraySet() const342             bool getStrokeDasharraySet() const { return mbStrokeDasharraySet; }
setStrokeDasharraySet(bool bNew)343             void setStrokeDasharraySet(bool bNew) { mbStrokeDasharraySet = bNew; }
344 
345             /// StrokeDashOffset content
346             SvgNumber getStrokeDashOffset() const;
setStrokeDashOffset(const SvgNumber & rStrokeDashOffset=SvgNumber ())347             void setStrokeDashOffset(const SvgNumber& rStrokeDashOffset = SvgNumber()) { maStrokeDashOffset = rStrokeDashOffset; }
348 
349             /// StrokeLinecap content
350             StrokeLinecap getStrokeLinecap() const;
setStrokeLinecap(const StrokeLinecap aStrokeLinecap=StrokeLinecap_notset)351             void setStrokeLinecap(const StrokeLinecap aStrokeLinecap = StrokeLinecap_notset) { maStrokeLinecap = aStrokeLinecap; }
352 
353             /// StrokeLinejoin content
354             StrokeLinejoin getStrokeLinejoin() const;
setStrokeLinejoin(const StrokeLinejoin aStrokeLinejoin=StrokeLinejoin_notset)355             void setStrokeLinejoin(const StrokeLinejoin aStrokeLinejoin = StrokeLinejoin_notset) { maStrokeLinejoin = aStrokeLinejoin; }
356 
357             /// StrokeMiterLimit content
358             SvgNumber getStrokeMiterLimit() const;
setStrokeMiterLimit(const SvgNumber & rStrokeMiterLimit=SvgNumber ())359             void setStrokeMiterLimit(const SvgNumber& rStrokeMiterLimit = SvgNumber()) { maStrokeMiterLimit = rStrokeMiterLimit; }
360 
361             /// StrokeOpacity content
362             SvgNumber getStrokeOpacity() const;
setStrokeOpacity(const SvgNumber & rStrokeOpacity=SvgNumber ())363             void setStrokeOpacity(const SvgNumber& rStrokeOpacity = SvgNumber()) { maStrokeOpacity = rStrokeOpacity; }
364 
365             /// Font content
366             const SvgStringVector& getFontFamily() const;
setFontFamily(const SvgStringVector & rSvgStringVector=SvgStringVector ())367             void setFontFamily(const SvgStringVector& rSvgStringVector = SvgStringVector()) { maFontFamily = rSvgStringVector; }
368 
369             /// FontSize content
370             SvgNumber getFontSize() const;
setFontSize(const SvgNumber & rFontSize=SvgNumber ())371             void setFontSize(const SvgNumber& rFontSize = SvgNumber()) { maFontSize = rFontSize; }
372 
373             /// FontStretch content
374             FontStretch getFontStretch() const;
setFontStretch(const FontStretch aFontStretch=FontStretch_notset)375             void setFontStretch(const FontStretch aFontStretch = FontStretch_notset) { maFontStretch = aFontStretch; }
376 
377             /// FontStyle content
378             FontStyle getFontStyle() const;
setFontStyle(const FontStyle aFontStyle=FontStyle_notset)379             void setFontStyle(const FontStyle aFontStyle = FontStyle_notset) { maFontStyle = aFontStyle; }
380 
381             /// FontVariant content
382             FontVariant getFontVariant() const;
setFontVariant(const FontVariant aFontVariant=FontVariant_notset)383             void setFontVariant(const FontVariant aFontVariant = FontVariant_notset) { maFontVariant = aFontVariant; }
384 
385             /// FontWeight content
386             FontWeight getFontWeight() const;
setFontWeight(const FontWeight aFontWeight=FontWeight_notset)387             void setFontWeight(const FontWeight aFontWeight = FontWeight_notset) { maFontWeight = aFontWeight; }
388 
389             /// TextAlign content
390             TextAlign getTextAlign() const;
setTextAlign(const TextAlign aTextAlign=TextAlign_notset)391             void setTextAlign(const TextAlign aTextAlign = TextAlign_notset) { maTextAlign = aTextAlign; }
392 
393             /// TextDecoration content
394             const SvgStyleAttributes* getTextDecorationDefiningSvgStyleAttributes() const;
395             TextDecoration getTextDecoration() const;
setTextDecoration(const TextDecoration aTextDecoration=TextDecoration_notset)396             void setTextDecoration(const TextDecoration aTextDecoration = TextDecoration_notset) { maTextDecoration = aTextDecoration; }
397 
398             /// TextAnchor content
399             TextAnchor getTextAnchor() const;
setTextAnchor(const TextAnchor aTextAnchor=TextAnchor_notset)400             void setTextAnchor(const TextAnchor aTextAnchor = TextAnchor_notset) { maTextAnchor = aTextAnchor; }
401 
402             /// Color content
403             const basegfx::BColor* getColor() const;
setColor(const SvgPaint & rColor)404             void setColor(const SvgPaint& rColor) { maColor = rColor; }
405 
406             /// Opacity content
getOpacity() const407             SvgNumber getOpacity() const { return maOpacity; }
setOpacity(const SvgNumber & rOpacity=SvgNumber ())408             void setOpacity(const SvgNumber& rOpacity = SvgNumber()) { maOpacity = rOpacity; }
409 
410             // Title content
getTitle() const411             const rtl::OUString& getTitle() const { return maTitle; }
setTitle(const rtl::OUString & rNew)412             void setTitle(const rtl::OUString& rNew) { maTitle = rNew; }
413 
414             // Desc content
getDesc() const415             const rtl::OUString& getDesc() const { return maDesc; }
setDesc(const rtl::OUString & rNew)416             void setDesc(const rtl::OUString& rNew) { maDesc = rNew; }
417 
418             // ClipPathXLink content
getClipPathXLink() const419             const rtl::OUString& getClipPathXLink() const { return maClipPathXLink; }
setClipPathXLink(const rtl::OUString & rNew)420             void setClipPathXLink(const rtl::OUString& rNew) { maClipPathXLink = rNew; }
421 
422             // MaskXLink content
getMaskXLink() const423             const rtl::OUString& getMaskXLink() const { return maMaskXLink; }
setMaskXLink(const rtl::OUString & rNew)424             void setMaskXLink(const rtl::OUString& rNew) { maMaskXLink = rNew; }
425 
426             // MarkerStartXLink content
427             rtl::OUString getMarkerStartXLink() const;
428             const SvgMarkerNode* accessMarkerStartXLink() const;
setMarkerStartXLink(const rtl::OUString & rNew)429             void setMarkerStartXLink(const rtl::OUString& rNew) { maMarkerStartXLink = rNew; }
430 
431             // MarkerMidXLink content
432             rtl::OUString getMarkerMidXLink() const;
433             const SvgMarkerNode* accessMarkerMidXLink() const;
setMarkerMidXLink(const rtl::OUString & rNew)434             void setMarkerMidXLink(const rtl::OUString& rNew) { maMarkerMidXLink = rNew; }
435 
436             // MarkerEndXLink content
437             rtl::OUString getMarkerEndXLink() const;
438             const SvgMarkerNode* accessMarkerEndXLink() const;
setMarkerEndXLink(const rtl::OUString & rNew)439             void setMarkerEndXLink(const rtl::OUString& rNew) { maMarkerEndXLink = rNew; }
440 
441             // BaselineShift
setBaselineShift(const BaselineShift aBaselineShift=BaselineShift_Baseline)442             void setBaselineShift(const BaselineShift aBaselineShift = BaselineShift_Baseline) { maBaselineShift = aBaselineShift; }
getBaselineShift() const443             BaselineShift getBaselineShift() const { return maBaselineShift; }
setBaselineShiftNumber(const SvgNumber & rBaselineShift=SvgNumber ())444             void setBaselineShiftNumber(const SvgNumber& rBaselineShift = SvgNumber()) { maBaselineShiftNumber = rBaselineShift; }
445             SvgNumber getBaselineShiftNumber() const;
446         };
447     } // end of namespace svgreader
448 } // end of namespace svgio
449 
450 //////////////////////////////////////////////////////////////////////////////
451 
452 #endif //INCLUDED_SVGIO_SVGREADER_SVGSTYLEATTRIBUTES_HXX
453 
454 // eof
455