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_SVGIO_INC_SVGNODE_HXX
21 #define INCLUDED_SVGIO_INC_SVGNODE_HXX
22 
23 #include "svgtools.hxx"
24 #include "svgtoken.hxx"
25 #include "svgpaint.hxx"
26 #include <basegfx/matrix/b2dhommatrix.hxx>
27 #include <com/sun/star/xml/sax/XAttributeList.hpp>
28 #include <memory>
29 #include <vector>
30 #include <boost/optional.hpp>
31 
32 // predefines
33 namespace svgio
34 {
35     namespace svgreader
36     {
37         class SvgNode;
38         class SvgDocument;
39         class SvgStyleAttributes;
40     }
41 }
42 
43 
44 namespace svgio
45 {
46     namespace svgreader
47     {
48         enum XmlSpace
49         {
50             XmlSpace_notset,
51             XmlSpace_default,
52             XmlSpace_preserve
53         };
54 
55         // display property (see SVG 1.1. 11.5), not inheritable
56         enum Display // #i121656#
57         {
58             Display_inline, // the default
59             Display_block,
60             Display_list_item,
61             Display_run_in,
62             Display_compact,
63             Display_marker,
64             Display_table,
65             Display_inline_table,
66             Display_table_row_group,
67             Display_table_header_group,
68             Display_table_footer_group,
69             Display_table_row,
70             Display_table_column_group,
71             Display_table_column,
72             Display_table_cell,
73             Display_table_caption,
74             Display_none,
75             Display_inherit
76         };
77 
78         // helper to convert a string associated with a token of type SVGTokenDisplay
79         // to the enum Display. Empty strings return the default 'Display_inline' with
80         // which members should be initialized
81         Display getDisplayFromContent(const OUString& aContent);
82 
83       class Visitor;
84 
85         class SvgNode : public InfoProvider
86         {
87         private:
88             /// basic data, Type, document we belong to and parent (if not root)
89             SVGToken const              maType;
90             SvgDocument&                mrDocument;
91             const SvgNode*              mpParent;
92             const SvgNode*              mpAlternativeParent;
93 
94             /// sub hierarchy
95             std::vector< std::unique_ptr<SvgNode> >  maChildren;
96 
97             /// Id svan value
98             boost::optional<OUString>   mpId;
99 
100             /// Class svan value
101             boost::optional<OUString>   mpClass;
102 
103             /// XmlSpace value
104             XmlSpace                    maXmlSpace;
105 
106             /// Display value #i121656#
107             Display                     maDisplay;
108 
109             // CSS style vector chain, used in decompose phase and built up once per node.
110             // It contains the StyleHierarchy for the local node. Independent from the
111             // node hierarchy itself which also needs to be used in style entry solving
112             ::std::vector< const SvgStyleAttributes* > maCssStyleVector;
113 
114             /// possible local CssStyle, e.g. style="fill:red; stroke:red;"
115             std::unique_ptr<SvgStyleAttributes>        mpLocalCssStyle;
116 
117             mutable bool                mbDecomposing;
118 
119             // flag if maCssStyleVector is already computed (done only once)
120             bool                        mbCssStyleVectorBuilt : 1;
121 
122         protected:
123             /// helper to evtl. link to css style
124             const SvgStyleAttributes* checkForCssStyle(const OUString& rClassStr, const SvgStyleAttributes& rOriginal) const;
125 
126             /// helper for filling the CssStyle vector once dependent on mbCssStyleVectorBuilt
127             void fillCssStyleVector(const OUString& rClassStr, const SvgStyleAttributes& rOriginal);
128             void fillCssStyleVectorUsingHierarchyAndSelectors(
129                 const OUString& rClassStr,
130                 const SvgNode& rCurrent,
131                 const OUString& aConcatenated);
132 
133         public:
134             SvgNode(
135                 SVGToken aType,
136                 SvgDocument& rDocument,
137                 SvgNode* pParent);
138             virtual ~SvgNode() override;
139             SvgNode(const SvgNode&) = delete;
140             SvgNode& operator=(const SvgNode&) = delete;
141 
142             void accept(Visitor& rVisitor);
143 
144             /// scan helper to read and interpret a local CssStyle to mpLocalCssStyle
145             void readLocalCssStyle(const OUString& aContent);
146 
147             /// style helpers
148             void parseAttributes(const css::uno::Reference< css::xml::sax::XAttributeList >& xAttribs);
149             virtual const SvgStyleAttributes* getSvgStyleAttributes() const;
150             virtual void parseAttribute(const OUString& rTokenName, SVGToken aSVGToken, const OUString& aContent);
151             virtual void decomposeSvgNode(drawinglayer::primitive2d::Primitive2DContainer& rTarget, bool bReferenced) const;
152 
153             /// #i125258# tell if this node is allowed to have a parent style (e.g. defs do not)
154             virtual bool supportsParentStyle() const;
155 
156             /// basic data read access
getType() const157             SVGToken getType() const { return maType; }
getDocument() const158             const SvgDocument& getDocument() const { return mrDocument; }
getParent() const159             const SvgNode* getParent() const { if(mpAlternativeParent) return mpAlternativeParent; return mpParent; }
getChildren() const160             const std::vector< std::unique_ptr<SvgNode> > & getChildren() const { return maChildren; }
161 
162             /// InfoProvider support for %, em and ex values
163             virtual basegfx::B2DRange getCurrentViewPort() const override;
164             virtual double getCurrentFontSizeInherited() const override;
165             virtual double getCurrentXHeightInherited() const override;
166 
167             virtual double getCurrentFontSize() const;
168             double getCurrentXHeight() const;
169 
170             /// Id access
getId() const171             boost::optional<OUString> const & getId() const { return mpId; }
172             void setId(OUString const &);
173 
174             /// Class access
getClass() const175             boost::optional<OUString> const & getClass() const { return mpClass; }
176             void setClass(OUString const &);
177 
178             /// XmlSpace access
179             XmlSpace getXmlSpace() const;
setXmlSpace(XmlSpace eXmlSpace)180             void setXmlSpace(XmlSpace eXmlSpace) { maXmlSpace = eXmlSpace; }
181 
182             /// Display access #i121656#
getDisplay() const183             Display getDisplay() const { return maDisplay; }
setDisplay(Display eDisplay)184             void setDisplay(Display eDisplay) { maDisplay = eDisplay; }
185 
186             /// alternative parent
setAlternativeParent(const SvgNode * pAlternativeParent=nullptr)187             void setAlternativeParent(const SvgNode* pAlternativeParent = nullptr) { mpAlternativeParent = pAlternativeParent; }
188         };
189 
190       class Visitor
191       {
192       public:
193             virtual ~Visitor() = default;
194             virtual void visit(SvgNode const & pNode) = 0;
195       };
196 
197     } // end of namespace svgreader
198 } // end of namespace svgio
199 
200 #endif // INCLUDED_SVGIO_INC_SVGNODE_HXX
201 
202 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
203