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_SVGTOOLS_HXX
21 #define INCLUDED_SVGIO_INC_SVGTOOLS_HXX
22 
23 #include <drawinglayer/primitive2d/baseprimitive2d.hxx>
24 #include <basegfx/color/bcolor.hxx>
25 #include <basegfx/polygon/b2dpolypolygon.hxx>
26 #include "svgpaint.hxx"
27 #include <vector>
28 
29 namespace svgio
30 {
31     namespace svgreader
32     {
33 
34 // recommended value for this device dependent unit, see CSS2 section 4.3.2 Lengths
35 #define F_SVG_PIXEL_PER_INCH  96.0
36 
37         // common non-token strings
38         struct commonStrings
39         {
40             static const OUString aStrUserSpaceOnUse;
41             static const OUString aStrObjectBoundingBox;
42             static const OUString aStrNonzero;
43             static const OUString aStrEvenOdd;
44         };
45 
46         enum SvgUnits
47         {
48             userSpaceOnUse,
49             objectBoundingBox
50         };
51 
52         enum NumberType
53         {
54             xcoordinate,
55             ycoordinate,
56             length
57         };
58 
59         class InfoProvider
60         {
61         public:
~InfoProvider()62             virtual ~InfoProvider() {}
63             virtual basegfx::B2DRange getCurrentViewPort() const = 0;
64             /// return font size of node inherited from parents
65             virtual double getCurrentFontSizeInherited() const = 0;
66             /// return xheight of node inherited from parents
67             virtual double getCurrentXHeightInherited() const = 0;
68         };
69 
70         enum SvgUnit
71         {
72             Unit_em = 0,    // relative to current font size
73             Unit_ex,        // relative to current x-height
74 
75             Unit_px,        // 'user unit'
76             Unit_pt,        // points, 1.25 px
77             Unit_pc,        // 15.0 px
78             Unit_cm,        // 35.43307 px
79             Unit_mm,        // 3.543307 px
80             Unit_in,        // 90 px
81 
82             Unit_percent,   // relative to range
83             Unit_none       // for stroke-miterlimit, which has no unit
84         };
85 
86         class SvgNumber
87         {
88         private:
89             double      mfNumber;
90             SvgUnit     meUnit;
91 
92             bool        mbSet : 1;
93 
94         public:
SvgNumber()95             SvgNumber()
96             :   mfNumber(0.0),
97                 meUnit(Unit_px),
98                 mbSet(false)
99             {
100             }
101 
SvgNumber(double fNum,SvgUnit aSvgUnit=Unit_px,bool bSet=true)102             SvgNumber(double fNum, SvgUnit aSvgUnit = Unit_px, bool bSet = true)
103             :   mfNumber(fNum),
104                 meUnit(aSvgUnit),
105                 mbSet(bSet)
106             {
107             }
108 
getNumber() const109             double getNumber() const
110             {
111                 return mfNumber;
112             }
113 
getUnit() const114             SvgUnit getUnit() const
115             {
116                 return meUnit;
117             }
118 
isSet() const119             bool isSet() const
120             {
121                 return mbSet;
122             }
123 
124             bool isPositive() const;
125 
126             // Only usable in cases, when the unit is not Unit_percent, otherwise use method solve
127             double solveNonPercentage(const InfoProvider& rInfoProvider) const;
128 
129             double solve(const InfoProvider& rInfoProvider, NumberType aNumberType = length) const;
130 
131 
132         };
133 
134         typedef ::std::vector< SvgNumber > SvgNumberVector;
135 
136         enum SvgAlign
137         {
138             Align_none,
139             Align_xMinYMin,
140             Align_xMidYMin,
141             Align_xMaxYMin,
142             Align_xMinYMid,
143             Align_xMidYMid, // default
144             Align_xMaxYMid,
145             Align_xMinYMax,
146             Align_xMidYMax,
147             Align_xMaxYMax
148         };
149 
150         class SvgAspectRatio
151         {
152         private:
153             SvgAlign    maSvgAlign;
154 
155             bool        mbMeetOrSlice : 1; // true = meet (default), false = slice
156             bool        mbSet : 1;
157 
158         public:
SvgAspectRatio()159             SvgAspectRatio()
160             :   maSvgAlign(Align_xMidYMid),
161                 mbMeetOrSlice(true),
162                 mbSet(false)
163             {
164             }
165 
SvgAspectRatio(SvgAlign aSvgAlign,bool bMeetOrSlice)166             SvgAspectRatio(SvgAlign aSvgAlign, bool bMeetOrSlice)
167             :   maSvgAlign(aSvgAlign),
168                 mbMeetOrSlice(bMeetOrSlice),
169                 mbSet(true)
170             {
171             }
172 
173             /// data read access
getSvgAlign() const174             SvgAlign getSvgAlign() const { return maSvgAlign; }
isMeetOrSlice() const175             bool isMeetOrSlice() const { return mbMeetOrSlice; }
isSet() const176             bool isSet() const { return mbSet; }
177 
178             /// tooling
179             static basegfx::B2DHomMatrix createLinearMapping(const basegfx::B2DRange& rTarget, const basegfx::B2DRange& rSource);
180             basegfx::B2DHomMatrix createMapping(const basegfx::B2DRange& rTarget, const basegfx::B2DRange& rSource) const;
181         };
182 
183         void skip_char(const OUString& rCandidate, sal_Unicode aChar, sal_Int32& nPos, const sal_Int32 nLen);
184         void skip_char(const OUString& rCandidate, sal_Unicode aCharA, sal_Unicode nCharB, sal_Int32& nPos, const sal_Int32 nLen);
185         void copySign(const OUString& rCandidate, sal_Int32& nPos, OUStringBuffer& rTarget, const sal_Int32 nLen);
186         void copyNumber(const OUString& rCandidate, sal_Int32& nPos, OUStringBuffer& rTarget, const sal_Int32 nLen);
187         void copyHex(const OUString& rCandidate, sal_Int32& nPos, OUStringBuffer& rTarget, const sal_Int32 nLen);
188         void copyString(const OUString& rCandidate, sal_Int32& nPos, OUStringBuffer& rTarget, const sal_Int32 nLen);
189         void copyToLimiter(const OUString& rCandidate, sal_Unicode aLimiter, sal_Int32& nPos, OUStringBuffer& rTarget, const sal_Int32 nLen);
190         bool readNumber(const OUString& rCandidate, sal_Int32& nPos, double& fNum, const sal_Int32 nLen);
191         SvgUnit readUnit(const OUString& rCandidate, sal_Int32& nPos, const sal_Int32 nLen);
192         bool readNumberAndUnit(const OUString& rCandidate, sal_Int32& nPos, SvgNumber& aNum, const sal_Int32 nLen);
193         bool readAngle(const OUString& rCandidate, sal_Int32& nPos, double& fAngle, const sal_Int32 nLen);
194         sal_Int32 read_hex(sal_Unicode aChar);
195         bool match_colorKeyword(basegfx::BColor& rColor, const OUString& rName, bool bCaseIndependent);
196         bool read_color(const OUString& rCandidate, basegfx::BColor& rColor, bool bCaseIndependent, SvgNumber& rOpacity);
197         basegfx::B2DRange readViewBox(const OUString& rCandidate, InfoProvider const & rInfoProvider);
198         basegfx::B2DHomMatrix readTransform(const OUString& rCandidate, InfoProvider const & rInfoProvider);
199         bool readSingleNumber(const OUString& rCandidate, SvgNumber& aNum);
200         bool readLocalUrl(const OUString& rCandidate, OUString& rURL);
201         bool readSvgPaint(const OUString& rCandidate, SvgPaint& rSvgPaint, OUString& rURL, bool bCaseIndependent, SvgNumber& rOpacity);
202 
203         bool readSvgNumberVector(const OUString& rCandidate, SvgNumberVector& rSvgNumberVector);
204         ::std::vector< double > solveSvgNumberVector(const SvgNumberVector& rInput, const InfoProvider& rInfoProvider);
205 
206         SvgAspectRatio readSvgAspectRatio(const OUString& rCandidate);
207 
208         typedef ::std::vector< OUString > SvgStringVector;
209         bool readSvgStringVector(const OUString& rCandidate, SvgStringVector& rSvgStringVector);
210 
211         void readImageLink(const OUString& rCandidate, OUString& rXLink, OUString& rUrl, OUString& rMimeType, OUString& rData);
212 
213         OUString convert(const OUString& rCandidate, sal_Unicode nPattern, sal_Unicode nNew, bool bRemove);
214         OUString consolidateContiguousSpace(const OUString& rCandidate);
215         OUString whiteSpaceHandlingDefault(const OUString& rCandidate);
216         OUString whiteSpaceHandlingPreserve(const OUString& rCandidate);
217 
218         // #125325# removes block comment of the general form '/* ... */', returns
219         // an adapted string or the original if no comments included
220         OUString removeBlockComments(const OUString& rCandidate);
221 
222     } // end of namespace svgreader
223 } // end of namespace svgio
224 
225 #endif // INCLUDED_SVGIO_INC_SVGTOOLS_HXX
226 
227 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
228