1ddde725dSArmin Le Grand /**************************************************************
2ddde725dSArmin Le Grand  *
3ddde725dSArmin Le Grand  * Licensed to the Apache Software Foundation (ASF) under one
4ddde725dSArmin Le Grand  * or more contributor license agreements.  See the NOTICE file
5ddde725dSArmin Le Grand  * distributed with this work for additional information
6ddde725dSArmin Le Grand  * regarding copyright ownership.  The ASF licenses this file
7ddde725dSArmin Le Grand  * to you under the Apache License, Version 2.0 (the
8ddde725dSArmin Le Grand  * "License"); you may not use this file except in compliance
9ddde725dSArmin Le Grand  * with the License.  You may obtain a copy of the License at
10ddde725dSArmin Le Grand  *
11ddde725dSArmin Le Grand  *   http://www.apache.org/licenses/LICENSE-2.0
12ddde725dSArmin Le Grand  *
13ddde725dSArmin Le Grand  * Unless required by applicable law or agreed to in writing,
14ddde725dSArmin Le Grand  * software distributed under the License is distributed on an
15ddde725dSArmin Le Grand  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16ddde725dSArmin Le Grand  * KIND, either express or implied.  See the License for the
17ddde725dSArmin Le Grand  * specific language governing permissions and limitations
18ddde725dSArmin Le Grand  * under the License.
19ddde725dSArmin Le Grand  *
20ddde725dSArmin Le Grand  *************************************************************/
21ddde725dSArmin Le Grand 
22ddde725dSArmin Le Grand // MARKER(update_precomp.py): autogen include statement, do not remove
23ddde725dSArmin Le Grand #include "precompiled_svgio.hxx"
24ddde725dSArmin Le Grand 
25ddde725dSArmin Le Grand #include <svgio/svgreader/svgtools.hxx>
26ddde725dSArmin Le Grand #include <osl/thread.h>
27ddde725dSArmin Le Grand #include <tools/color.hxx>
28ddde725dSArmin Le Grand #include <basegfx/matrix/b2dhommatrix.hxx>
29ddde725dSArmin Le Grand #include <basegfx/matrix/b2dhommatrixtools.hxx>
30ddde725dSArmin Le Grand #include <svgio/svgreader/svgtoken.hxx>
31ddde725dSArmin Le Grand #include <hash_map>
32ddde725dSArmin Le Grand 
33ddde725dSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
34ddde725dSArmin Le Grand 
35ddde725dSArmin Le Grand namespace svgio
36ddde725dSArmin Le Grand {
37ddde725dSArmin Le Grand     namespace svgreader
38ddde725dSArmin Le Grand     {
39ddde725dSArmin Le Grand #ifdef DBG_UTIL
myAssert(const rtl::OUString & rMessage)40ddde725dSArmin Le Grand         void myAssert(const rtl::OUString& rMessage)
41ddde725dSArmin Le Grand         {
42ddde725dSArmin Le Grand             rtl::OString aMessage2;
43ddde725dSArmin Le Grand 
44ddde725dSArmin Le Grand             rMessage.convertToString(&aMessage2, osl_getThreadTextEncoding(), RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR|RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR);
45ddde725dSArmin Le Grand             OSL_ENSURE(false, aMessage2.getStr());
46ddde725dSArmin Le Grand         }
47ddde725dSArmin Le Grand #endif
48ddde725dSArmin Le Grand 
49ddde725dSArmin Le Grand         // common non-token strings
50ddde725dSArmin Le Grand         const rtl::OUString commonStrings::aStrUserSpaceOnUse(rtl::OUString::createFromAscii("userSpaceOnUse"));
51ddde725dSArmin Le Grand         const rtl::OUString commonStrings::aStrObjectBoundingBox(rtl::OUString::createFromAscii("objectBoundingBox"));
52ddde725dSArmin Le Grand         const rtl::OUString commonStrings::aStrNonzero(rtl::OUString::createFromAscii("nonzero"));
53ddde725dSArmin Le Grand         const rtl::OUString commonStrings::aStrEvenOdd(rtl::OUString::createFromAscii("evenodd"));
54ddde725dSArmin Le Grand 
createLinearMapping(const basegfx::B2DRange & rTarget,const basegfx::B2DRange & rSource)55ddde725dSArmin Le Grand         basegfx::B2DHomMatrix SvgAspectRatio::createLinearMapping(const basegfx::B2DRange& rTarget, const basegfx::B2DRange& rSource)
56ddde725dSArmin Le Grand         {
57ddde725dSArmin Le Grand             basegfx::B2DHomMatrix aRetval;
58ddde725dSArmin Le Grand             const double fSWidth(rSource.getWidth());
59ddde725dSArmin Le Grand             const double fSHeight(rSource.getHeight());
60ddde725dSArmin Le Grand             const bool bNoSWidth(basegfx::fTools::equalZero(fSWidth));
61ddde725dSArmin Le Grand             const bool bNoSHeight(basegfx::fTools::equalZero(fSHeight));
62ddde725dSArmin Le Grand 
63ddde725dSArmin Le Grand             // transform from source state to unit range
64ddde725dSArmin Le Grand             aRetval.translate(-rSource.getMinX(), -rSource.getMinY());
65ddde725dSArmin Le Grand             aRetval.scale(
66ddde725dSArmin Le Grand                 (bNoSWidth ? 1.0 : 1.0 / fSWidth) * rTarget.getWidth(),
67ddde725dSArmin Le Grand                 (bNoSHeight ? 1.0 : 1.0 / fSHeight) * rTarget.getHeight());
68ddde725dSArmin Le Grand 
69ddde725dSArmin Le Grand             // transform from unit rage to target range
70ddde725dSArmin Le Grand             aRetval.translate(rTarget.getMinX(), rTarget.getMinY());
71ddde725dSArmin Le Grand 
72ddde725dSArmin Le Grand             return aRetval;
73ddde725dSArmin Le Grand         }
74ddde725dSArmin Le Grand 
createMapping(const basegfx::B2DRange & rTarget,const basegfx::B2DRange & rSource) const75ddde725dSArmin Le Grand         basegfx::B2DHomMatrix SvgAspectRatio::createMapping(const basegfx::B2DRange& rTarget, const basegfx::B2DRange& rSource) const
76ddde725dSArmin Le Grand         {
77ddde725dSArmin Le Grand             if(!isSet() || Align_none == getSvgAlign())
78ddde725dSArmin Le Grand             {
79ddde725dSArmin Le Grand                 // create linear mapping (default)
80ddde725dSArmin Le Grand                 return createLinearMapping(rTarget, rSource);
81ddde725dSArmin Le Grand             }
82ddde725dSArmin Le Grand 
83ddde725dSArmin Le Grand             basegfx::B2DHomMatrix aRetval;
84ddde725dSArmin Le Grand 
85ddde725dSArmin Le Grand             const double fSWidth(rSource.getWidth());
86ddde725dSArmin Le Grand             const double fSHeight(rSource.getHeight());
87ddde725dSArmin Le Grand             const bool bNoSWidth(basegfx::fTools::equalZero(fSWidth));
88ddde725dSArmin Le Grand             const bool bNoSHeight(basegfx::fTools::equalZero(fSHeight));
89ddde725dSArmin Le Grand             const double fScaleX((bNoSWidth ? 1.0 : 1.0 / fSWidth) * rTarget.getWidth());
90ddde725dSArmin Le Grand             const double fScaleY((bNoSHeight ? 1.0 : 1.0 / fSHeight) * rTarget.getHeight());
91ddde725dSArmin Le Grand             const double fScale(isMeetOrSlice() ? std::min(fScaleX, fScaleY) : std::max(fScaleX, fScaleY));
92ddde725dSArmin Le Grand 
93ddde725dSArmin Le Grand             // remove source translation, apply scale
94ddde725dSArmin Le Grand             aRetval.translate(-rSource.getMinX(), -rSource.getMinY());
95ddde725dSArmin Le Grand             aRetval.scale(fScale, fScale);
96ddde725dSArmin Le Grand 
97ddde725dSArmin Le Grand             // evaluate horizontal alignment
98ddde725dSArmin Le Grand             const double fNewWidth(fSWidth * fScale);
99ddde725dSArmin Le Grand             double fTransX(0.0);
100ddde725dSArmin Le Grand 
101ddde725dSArmin Le Grand             switch(getSvgAlign())
102ddde725dSArmin Le Grand             {
103ddde725dSArmin Le Grand                 case Align_xMidYMin:
104ddde725dSArmin Le Grand                 case Align_xMidYMid:
105ddde725dSArmin Le Grand                 case Align_xMidYMax:
106ddde725dSArmin Le Grand                 {
107ddde725dSArmin Le Grand                     // centerX
108ddde725dSArmin Le Grand                     const double fFreeSpace(rTarget.getWidth() - fNewWidth);
109ddde725dSArmin Le Grand                     fTransX = fFreeSpace * 0.5;
110ddde725dSArmin Le Grand                     break;
111ddde725dSArmin Le Grand                 }
112ddde725dSArmin Le Grand                 case Align_xMaxYMin:
113ddde725dSArmin Le Grand                 case Align_xMaxYMid:
114ddde725dSArmin Le Grand                 case Align_xMaxYMax:
115ddde725dSArmin Le Grand                 {
116ddde725dSArmin Le Grand                     // Right align
117ddde725dSArmin Le Grand                     const double fFreeSpace(rTarget.getWidth() - fNewWidth);
118ddde725dSArmin Le Grand                     fTransX = fFreeSpace;
119ddde725dSArmin Le Grand                     break;
120ddde725dSArmin Le Grand                 }
121e2bf1e9dSArmin Le Grand                 default: break;
122ddde725dSArmin Le Grand             }
123ddde725dSArmin Le Grand 
124ddde725dSArmin Le Grand             // evaluate vertical alignment
125ddde725dSArmin Le Grand             const double fNewHeight(fSHeight * fScale);
126ddde725dSArmin Le Grand             double fTransY(0.0);
127ddde725dSArmin Le Grand 
128ddde725dSArmin Le Grand             switch(getSvgAlign())
129ddde725dSArmin Le Grand             {
130ddde725dSArmin Le Grand                 case Align_xMinYMid:
131ddde725dSArmin Le Grand                 case Align_xMidYMid:
132ddde725dSArmin Le Grand                 case Align_xMaxYMid:
133ddde725dSArmin Le Grand                 {
134ddde725dSArmin Le Grand                     // centerY
135ddde725dSArmin Le Grand                     const double fFreeSpace(rTarget.getHeight() - fNewHeight);
136ddde725dSArmin Le Grand                     fTransY = fFreeSpace * 0.5;
137ddde725dSArmin Le Grand                     break;
138ddde725dSArmin Le Grand                 }
139ddde725dSArmin Le Grand                 case Align_xMinYMax:
140ddde725dSArmin Le Grand                 case Align_xMidYMax:
141ddde725dSArmin Le Grand                 case Align_xMaxYMax:
142ddde725dSArmin Le Grand                 {
143ddde725dSArmin Le Grand                     // Bottom align
144ddde725dSArmin Le Grand                     const double fFreeSpace(rTarget.getHeight() - fNewHeight);
145ddde725dSArmin Le Grand                     fTransY = fFreeSpace;
146ddde725dSArmin Le Grand                     break;
147ddde725dSArmin Le Grand                 }
148e2bf1e9dSArmin Le Grand                 default: break;
149ddde725dSArmin Le Grand             }
150ddde725dSArmin Le Grand 
151ddde725dSArmin Le Grand             // add target translation
152ddde725dSArmin Le Grand             aRetval.translate(
153ddde725dSArmin Le Grand                 rTarget.getMinX() + fTransX,
154ddde725dSArmin Le Grand                 rTarget.getMinY() + fTransY);
155ddde725dSArmin Le Grand 
156ddde725dSArmin Le Grand             return aRetval;
157ddde725dSArmin Le Grand         }
158ddde725dSArmin Le Grand 
solveNonPercentage(const InfoProvider & rInfoProvider) const1592169cc62SArmin Le Grand         double SvgNumber::solveNonPercentage(const InfoProvider& rInfoProvider) const
160ddde725dSArmin Le Grand         {
161ddde725dSArmin Le Grand             if(isSet())
162ddde725dSArmin Le Grand             {
163ddde725dSArmin Le Grand                 switch(meUnit)
164ddde725dSArmin Le Grand                 {
165ddde725dSArmin Le Grand                     case Unit_em:
166ddde725dSArmin Le Grand                     {
167ddde725dSArmin Le Grand                         return mfNumber * rInfoProvider.getCurrentFontSize();
168ddde725dSArmin Le Grand                         break;
169ddde725dSArmin Le Grand                     }
170ddde725dSArmin Le Grand                     case Unit_ex:
171ddde725dSArmin Le Grand                     {
172ddde725dSArmin Le Grand                         return mfNumber * rInfoProvider.getCurrentXHeight() * 0.5;
173ddde725dSArmin Le Grand                         break;
174ddde725dSArmin Le Grand                     }
175ddde725dSArmin Le Grand                     case Unit_px:
176ddde725dSArmin Le Grand                     {
177ddde725dSArmin Le Grand                         return mfNumber;
178ddde725dSArmin Le Grand                         break;
179ddde725dSArmin Le Grand                     }
180ddde725dSArmin Le Grand                     case Unit_pt:
181ddde725dSArmin Le Grand                     case Unit_pc:
182ddde725dSArmin Le Grand                     case Unit_cm:
183ddde725dSArmin Le Grand                     case Unit_mm:
184ddde725dSArmin Le Grand                     case Unit_in:
185ddde725dSArmin Le Grand                     {
186ddde725dSArmin Le Grand                         double fRetval(mfNumber);
1872169cc62SArmin Le Grand 
188ddde725dSArmin Le Grand                         switch(meUnit)
189ddde725dSArmin Le Grand                         {
1902169cc62SArmin Le Grand                             case Unit_pt: fRetval *= F_SVG_PIXEL_PER_INCH / 72.0; break;
1912169cc62SArmin Le Grand                             case Unit_pc: fRetval *= F_SVG_PIXEL_PER_INCH / 6.0; break;
1922169cc62SArmin Le Grand                             case Unit_cm: fRetval *= F_SVG_PIXEL_PER_INCH / 2.54; break;
1932169cc62SArmin Le Grand                             case Unit_mm: fRetval *= 0.1 * F_SVG_PIXEL_PER_INCH / 2.54; break;
1942169cc62SArmin Le Grand                             case Unit_in: fRetval *= F_SVG_PIXEL_PER_INCH; break;
195e2bf1e9dSArmin Le Grand                             default: break;
196ddde725dSArmin Le Grand                         }
1972169cc62SArmin Le Grand 
198ddde725dSArmin Le Grand                         return fRetval;
199ddde725dSArmin Le Grand                         break;
200ddde725dSArmin Le Grand                     }
2012169cc62SArmin Le Grand                     default:
2022169cc62SArmin Le Grand                     {
2032169cc62SArmin Le Grand                         OSL_ENSURE(false, "Do not use with percentage! ");
2042169cc62SArmin Le Grand                         return 0.0;
2052169cc62SArmin Le Grand                         break;
2062169cc62SArmin Le Grand                     }
2072169cc62SArmin Le Grand                 }
2082169cc62SArmin Le Grand             }
2092169cc62SArmin Le Grand 
2102169cc62SArmin Le Grand             /// not set
2112169cc62SArmin Le Grand             OSL_ENSURE(false, "SvgNumber not set (!)");
2122169cc62SArmin Le Grand             return 0.0;
2132169cc62SArmin Le Grand         }
2142169cc62SArmin Le Grand 
solve(const InfoProvider & rInfoProvider,NumberType aNumberType) const2152169cc62SArmin Le Grand         double SvgNumber::solve(const InfoProvider& rInfoProvider, NumberType aNumberType) const
2162169cc62SArmin Le Grand         {
2172169cc62SArmin Le Grand             if(isSet())
2182169cc62SArmin Le Grand             {
2192169cc62SArmin Le Grand                 switch(meUnit)
2202169cc62SArmin Le Grand                 {
2212169cc62SArmin Le Grand                     case Unit_px:
2222169cc62SArmin Le Grand                     {
2232169cc62SArmin Le Grand                         return mfNumber;
2242169cc62SArmin Le Grand                         break;
2252169cc62SArmin Le Grand                     }
2262169cc62SArmin Le Grand                     case Unit_pt:
2272169cc62SArmin Le Grand                     case Unit_pc:
2282169cc62SArmin Le Grand                     case Unit_cm:
2292169cc62SArmin Le Grand                     case Unit_mm:
2302169cc62SArmin Le Grand                     case Unit_in:
2312169cc62SArmin Le Grand                     case Unit_em:
2322169cc62SArmin Le Grand                     case Unit_ex:
2332169cc62SArmin Le Grand                     {
2342169cc62SArmin Le Grand                         return solveNonPercentage( rInfoProvider);
2352169cc62SArmin Le Grand                         break;
2362169cc62SArmin Le Grand                     }
237ddde725dSArmin Le Grand                     case Unit_percent:
238ddde725dSArmin Le Grand                     {
239ddde725dSArmin Le Grand                         double fRetval(mfNumber * 0.01);
240*e92bb418SOliver-Rainer Wittmann                         basegfx::B2DRange aViewPort = rInfoProvider.getCurrentViewPort();
241ddde725dSArmin Le Grand 
242*e92bb418SOliver-Rainer Wittmann                         if ( aViewPort.isEmpty() )
243ddde725dSArmin Le Grand                         {
2442169cc62SArmin Le Grand #ifdef DBG_UTIL
2452169cc62SArmin Le Grand                             myAssert(rtl::OUString::createFromAscii("Design error, this case should have been handled in the caller"));
2462169cc62SArmin Le Grand #endif
247ddde725dSArmin Le Grand                             // no viewPort, assume a normal page size (A4)
248*e92bb418SOliver-Rainer Wittmann                             aViewPort = basegfx::B2DRange(
249ddde725dSArmin Le Grand                                 0.0,
250ddde725dSArmin Le Grand                                 0.0,
2512169cc62SArmin Le Grand                                 210.0 * F_SVG_PIXEL_PER_INCH / 2.54,
2522169cc62SArmin Le Grand                                 297.0 * F_SVG_PIXEL_PER_INCH / 2.54);
253ddde725dSArmin Le Grand 
254ddde725dSArmin Le Grand                         }
255ddde725dSArmin Le Grand 
256*e92bb418SOliver-Rainer Wittmann                         if ( !aViewPort.isEmpty() )
257ddde725dSArmin Le Grand                         {
258ddde725dSArmin Le Grand                             if(xcoordinate == aNumberType)
259ddde725dSArmin Le Grand                             {
260ddde725dSArmin Le Grand                                 // it's a x-coordinate, relative to current width (w)
261*e92bb418SOliver-Rainer Wittmann                                 fRetval *= aViewPort.getWidth();
262ddde725dSArmin Le Grand                             }
263ddde725dSArmin Le Grand                             else if(ycoordinate == aNumberType)
264ddde725dSArmin Le Grand                             {
265ddde725dSArmin Le Grand                                 // it's a y-coordinate, relative to current height (h)
266*e92bb418SOliver-Rainer Wittmann                                 fRetval *= aViewPort.getHeight();
267ddde725dSArmin Le Grand                             }
268ddde725dSArmin Le Grand                             else // length
269ddde725dSArmin Le Grand                             {
270ddde725dSArmin Le Grand                                 // it's a length, relative to sqrt(w*w + h*h)/sqrt(2)
271*e92bb418SOliver-Rainer Wittmann                                 const double fCurrentWidth(aViewPort.getWidth());
272*e92bb418SOliver-Rainer Wittmann                                 const double fCurrentHeight(aViewPort.getHeight());
273ddde725dSArmin Le Grand                                 const double fCurrentLength(
274ddde725dSArmin Le Grand                                     sqrt(fCurrentWidth * fCurrentWidth + fCurrentHeight * fCurrentHeight)/sqrt(2.0));
275ddde725dSArmin Le Grand 
276ddde725dSArmin Le Grand                                 fRetval *= fCurrentLength;
277ddde725dSArmin Le Grand                             }
278ddde725dSArmin Le Grand                         }
279ddde725dSArmin Le Grand 
280ddde725dSArmin Le Grand                         return fRetval;
281ddde725dSArmin Le Grand                         break;
282ddde725dSArmin Le Grand                     }
283e2bf1e9dSArmin Le Grand                     default:
284e2bf1e9dSArmin Le Grand                     {
285e2bf1e9dSArmin Le Grand                         break;
286e2bf1e9dSArmin Le Grand                     }
287ddde725dSArmin Le Grand                 }
288ddde725dSArmin Le Grand             }
289ddde725dSArmin Le Grand 
290ddde725dSArmin Le Grand             /// not set
291ddde725dSArmin Le Grand             OSL_ENSURE(false, "SvgNumber not set (!)");
292ddde725dSArmin Le Grand             return 0.0;
293ddde725dSArmin Le Grand         }
294ddde725dSArmin Le Grand 
isPositive() const295ddde725dSArmin Le Grand         bool SvgNumber::isPositive() const
296ddde725dSArmin Le Grand         {
297ddde725dSArmin Le Grand             return basegfx::fTools::moreOrEqual(mfNumber, 0.0);
298ddde725dSArmin Le Grand         }
299ddde725dSArmin Le Grand 
skip_char(const rtl::OUString & rCandidate,const sal_Unicode & rChar,sal_Int32 & nPos,const sal_Int32 nLen)300ddde725dSArmin Le Grand         void skip_char(const rtl::OUString& rCandidate, const sal_Unicode& rChar, sal_Int32& nPos, const sal_Int32 nLen)
301ddde725dSArmin Le Grand         {
302ddde725dSArmin Le Grand             while(nPos < nLen && rChar == rCandidate[nPos])
303ddde725dSArmin Le Grand             {
304ddde725dSArmin Le Grand                 nPos++;
305ddde725dSArmin Le Grand             }
306ddde725dSArmin Le Grand         }
307ddde725dSArmin Le Grand 
skip_char(const rtl::OUString & rCandidate,const sal_Unicode & rCharA,const sal_Unicode & rCharB,sal_Int32 & nPos,const sal_Int32 nLen)308ddde725dSArmin Le Grand         void skip_char(const rtl::OUString& rCandidate, const sal_Unicode& rCharA, const sal_Unicode& rCharB, sal_Int32& nPos, const sal_Int32 nLen)
309ddde725dSArmin Le Grand         {
310ddde725dSArmin Le Grand             while(nPos < nLen && (rCharA == rCandidate[nPos] || rCharB == rCandidate[nPos]))
311ddde725dSArmin Le Grand             {
312ddde725dSArmin Le Grand                 nPos++;
313ddde725dSArmin Le Grand             }
314ddde725dSArmin Le Grand         }
315ddde725dSArmin Le Grand 
copySign(const rtl::OUString & rCandidate,sal_Int32 & nPos,rtl::OUStringBuffer & rTarget,const sal_Int32 nLen)316ddde725dSArmin Le Grand         void copySign(const rtl::OUString& rCandidate, sal_Int32& nPos, rtl::OUStringBuffer& rTarget, const sal_Int32 nLen)
317ddde725dSArmin Le Grand         {
318ddde725dSArmin Le Grand             if(nPos < nLen)
319ddde725dSArmin Le Grand             {
320ddde725dSArmin Le Grand                 const sal_Unicode aChar(rCandidate[nPos]);
321ddde725dSArmin Le Grand 
322ddde725dSArmin Le Grand                 if(sal_Unicode('+') == aChar || sal_Unicode('-') == aChar)
323ddde725dSArmin Le Grand                 {
324ddde725dSArmin Le Grand                     rTarget.append(aChar);
325ddde725dSArmin Le Grand                     nPos++;
326ddde725dSArmin Le Grand                 }
327ddde725dSArmin Le Grand             }
328ddde725dSArmin Le Grand         }
329ddde725dSArmin Le Grand 
copyNumber(const rtl::OUString & rCandidate,sal_Int32 & nPos,rtl::OUStringBuffer & rTarget,const sal_Int32 nLen)330ddde725dSArmin Le Grand         void copyNumber(const rtl::OUString& rCandidate, sal_Int32& nPos, rtl::OUStringBuffer& rTarget, const sal_Int32 nLen)
331ddde725dSArmin Le Grand         {
332ddde725dSArmin Le Grand             bool bOnNumber(true);
333ddde725dSArmin Le Grand 
334ddde725dSArmin Le Grand             while(bOnNumber && nPos < nLen)
335ddde725dSArmin Le Grand             {
336ddde725dSArmin Le Grand                 const sal_Unicode aChar(rCandidate[nPos]);
337ddde725dSArmin Le Grand 
338ddde725dSArmin Le Grand                 bOnNumber = (sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar) || sal_Unicode('.') == aChar;
339ddde725dSArmin Le Grand 
340ddde725dSArmin Le Grand                 if(bOnNumber)
341ddde725dSArmin Le Grand                 {
342ddde725dSArmin Le Grand                     rTarget.append(aChar);
343ddde725dSArmin Le Grand                     nPos++;
344ddde725dSArmin Le Grand                 }
345ddde725dSArmin Le Grand             }
346ddde725dSArmin Le Grand         }
347ddde725dSArmin Le Grand 
copyHex(const rtl::OUString & rCandidate,sal_Int32 & nPos,rtl::OUStringBuffer & rTarget,const sal_Int32 nLen)348ddde725dSArmin Le Grand         void copyHex(const rtl::OUString& rCandidate, sal_Int32& nPos, rtl::OUStringBuffer& rTarget, const sal_Int32 nLen)
349ddde725dSArmin Le Grand         {
350ddde725dSArmin Le Grand             bool bOnHex(true);
351ddde725dSArmin Le Grand 
352ddde725dSArmin Le Grand             while(bOnHex && nPos < nLen)
353ddde725dSArmin Le Grand             {
354ddde725dSArmin Le Grand                 const sal_Unicode aChar(rCandidate[nPos]);
355ddde725dSArmin Le Grand 
356ddde725dSArmin Le Grand                 bOnHex = (sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar)
357ddde725dSArmin Le Grand                     || (sal_Unicode('A') <= aChar && sal_Unicode('F') >= aChar)
358ddde725dSArmin Le Grand                     || (sal_Unicode('a') <= aChar && sal_Unicode('f') >= aChar);
359ddde725dSArmin Le Grand 
360ddde725dSArmin Le Grand                 if(bOnHex)
361ddde725dSArmin Le Grand                 {
362ddde725dSArmin Le Grand                     rTarget.append(aChar);
363ddde725dSArmin Le Grand                     nPos++;
364ddde725dSArmin Le Grand                 }
365ddde725dSArmin Le Grand             }
366ddde725dSArmin Le Grand         }
367ddde725dSArmin Le Grand 
copyString(const rtl::OUString & rCandidate,sal_Int32 & nPos,rtl::OUStringBuffer & rTarget,const sal_Int32 nLen)368ddde725dSArmin Le Grand         void copyString(const rtl::OUString& rCandidate, sal_Int32& nPos, rtl::OUStringBuffer& rTarget, const sal_Int32 nLen)
369ddde725dSArmin Le Grand         {
370ddde725dSArmin Le Grand             bool bOnChar(true);
371ddde725dSArmin Le Grand 
372ddde725dSArmin Le Grand             while(bOnChar && nPos < nLen)
373ddde725dSArmin Le Grand             {
374ddde725dSArmin Le Grand                 const sal_Unicode aChar(rCandidate[nPos]);
375ddde725dSArmin Le Grand 
376ddde725dSArmin Le Grand                 bOnChar = (sal_Unicode('a') <= aChar && sal_Unicode('z') >= aChar)
377ddde725dSArmin Le Grand                     || (sal_Unicode('A') <= aChar && sal_Unicode('Z') >= aChar)
378ddde725dSArmin Le Grand                     || sal_Unicode('-') == aChar;
379ddde725dSArmin Le Grand 
380ddde725dSArmin Le Grand                 if(bOnChar)
381ddde725dSArmin Le Grand                 {
382ddde725dSArmin Le Grand                     rTarget.append(aChar);
383ddde725dSArmin Le Grand                     nPos++;
384ddde725dSArmin Le Grand                 }
385ddde725dSArmin Le Grand             }
386ddde725dSArmin Le Grand         }
387ddde725dSArmin Le Grand 
copyToLimiter(const rtl::OUString & rCandidate,const sal_Unicode & rLimiter,sal_Int32 & nPos,rtl::OUStringBuffer & rTarget,const sal_Int32 nLen)388ddde725dSArmin Le Grand         void copyToLimiter(const rtl::OUString& rCandidate, const sal_Unicode& rLimiter, sal_Int32& nPos, rtl::OUStringBuffer& rTarget, const sal_Int32 nLen)
389ddde725dSArmin Le Grand         {
390ddde725dSArmin Le Grand             while(nPos < nLen && rLimiter != rCandidate[nPos])
391ddde725dSArmin Le Grand             {
392ddde725dSArmin Le Grand                 rTarget.append(rCandidate[nPos]);
393ddde725dSArmin Le Grand                 nPos++;
394ddde725dSArmin Le Grand             }
395ddde725dSArmin Le Grand         }
396ddde725dSArmin Le Grand 
readNumber(const rtl::OUString & rCandidate,sal_Int32 & nPos,double & fNum,const sal_Int32 nLen)397ddde725dSArmin Le Grand         bool readNumber(const rtl::OUString& rCandidate, sal_Int32& nPos, double& fNum, const sal_Int32 nLen)
398ddde725dSArmin Le Grand         {
399ddde725dSArmin Le Grand             if(nPos < nLen)
400ddde725dSArmin Le Grand             {
401ddde725dSArmin Le Grand                 rtl::OUStringBuffer aNum;
402ddde725dSArmin Le Grand 
403ddde725dSArmin Le Grand                 copySign(rCandidate, nPos, aNum, nLen);
404ddde725dSArmin Le Grand                 copyNumber(rCandidate, nPos, aNum, nLen);
405ddde725dSArmin Le Grand 
406ddde725dSArmin Le Grand                 if(nPos < nLen)
407ddde725dSArmin Le Grand                 {
408ddde725dSArmin Le Grand                     const sal_Unicode aChar(rCandidate[nPos]);
409ddde725dSArmin Le Grand 
410ddde725dSArmin Le Grand                     if(sal_Unicode('e') == aChar || sal_Unicode('E') == aChar)
411ddde725dSArmin Le Grand                     {
412ddde725dSArmin Le Grand                         // try to read exponential number, but be careful. I had
413ddde725dSArmin Le Grand                         // a case where dx="2em" was used, thus the 'e' was consumed
414ddde725dSArmin Le Grand                         // by error. First try if there are numbers after the 'e',
415ddde725dSArmin Le Grand                         // safe current state
416ddde725dSArmin Le Grand                         nPos++;
417ddde725dSArmin Le Grand                         const rtl::OUStringBuffer aNum2(aNum);
418ddde725dSArmin Le Grand                         const sal_Int32 nPosAfterE(nPos);
419ddde725dSArmin Le Grand 
420ddde725dSArmin Le Grand                         aNum.append(aChar);
421ddde725dSArmin Le Grand                         copySign(rCandidate, nPos, aNum, nLen);
422ddde725dSArmin Le Grand                         copyNumber(rCandidate, nPos, aNum, nLen);
423ddde725dSArmin Le Grand 
424ddde725dSArmin Le Grand                         if(nPosAfterE == nPos)
425ddde725dSArmin Le Grand                         {
426ddde725dSArmin Le Grand                             // no number after 'e', go back. Do not
427ddde725dSArmin Le Grand                             // return false, it's still a valid integer number
428ddde725dSArmin Le Grand                             aNum = aNum2;
429ddde725dSArmin Le Grand                             nPos--;
430ddde725dSArmin Le Grand                         }
431ddde725dSArmin Le Grand                     }
432ddde725dSArmin Le Grand                 }
433ddde725dSArmin Le Grand 
434ddde725dSArmin Le Grand                 if(aNum.getLength())
435ddde725dSArmin Le Grand                 {
436ddde725dSArmin Le Grand                     rtl_math_ConversionStatus eStatus;
437ddde725dSArmin Le Grand 
438ddde725dSArmin Le Grand                     fNum = rtl::math::stringToDouble(
439ddde725dSArmin Le Grand                         aNum.makeStringAndClear(), (sal_Unicode)('.'), (sal_Unicode)(','),
440ddde725dSArmin Le Grand                         &eStatus, 0);
441ddde725dSArmin Le Grand 
442ddde725dSArmin Le Grand                     return eStatus == rtl_math_ConversionStatus_Ok;
443ddde725dSArmin Le Grand                 }
444ddde725dSArmin Le Grand             }
445ddde725dSArmin Le Grand 
446ddde725dSArmin Le Grand             return false;
447ddde725dSArmin Le Grand         }
448ddde725dSArmin Le Grand 
readUnit(const rtl::OUString & rCandidate,sal_Int32 & nPos,const sal_Int32 nLen)449ddde725dSArmin Le Grand         SvgUnit readUnit(const rtl::OUString& rCandidate, sal_Int32& nPos, const sal_Int32 nLen)
450ddde725dSArmin Le Grand         {
451ddde725dSArmin Le Grand             SvgUnit aRetval(Unit_px);
452ddde725dSArmin Le Grand 
453ddde725dSArmin Le Grand             if(nPos < nLen)
454ddde725dSArmin Le Grand             {
455ddde725dSArmin Le Grand                 const sal_Unicode aCharA(rCandidate[nPos]);
456ddde725dSArmin Le Grand 
457ddde725dSArmin Le Grand                 if(nPos + 1 < nLen)
458ddde725dSArmin Le Grand                 {
459ddde725dSArmin Le Grand                     const sal_Unicode aCharB(rCandidate[nPos + 1]);
460ddde725dSArmin Le Grand                     bool bTwoCharValid(false);
461ddde725dSArmin Le Grand 
462ddde725dSArmin Le Grand                     switch(aCharA)
463ddde725dSArmin Le Grand                     {
464ddde725dSArmin Le Grand                         case sal_Unicode('e') :
465ddde725dSArmin Le Grand                         {
466ddde725dSArmin Le Grand                             if(sal_Unicode('m') == aCharB)
467ddde725dSArmin Le Grand                             {
468ddde725dSArmin Le Grand                                 // 'em' Relative to current font size
469ddde725dSArmin Le Grand                                 aRetval = Unit_em;
470ddde725dSArmin Le Grand                                 bTwoCharValid = true;
471ddde725dSArmin Le Grand                             }
472ddde725dSArmin Le Grand                             else if(sal_Unicode('x') == aCharB)
473ddde725dSArmin Le Grand                             {
474ddde725dSArmin Le Grand                                 // 'ex' Relative to current font x-height
475ddde725dSArmin Le Grand                                 aRetval = Unit_ex;
476ddde725dSArmin Le Grand                                 bTwoCharValid = true;
477ddde725dSArmin Le Grand                             }
478ddde725dSArmin Le Grand                             break;
479ddde725dSArmin Le Grand                         }
480ddde725dSArmin Le Grand                         case sal_Unicode('p') :
481ddde725dSArmin Le Grand                         {
482ddde725dSArmin Le Grand                             if(sal_Unicode('x') == aCharB)
483ddde725dSArmin Le Grand                             {
484ddde725dSArmin Le Grand                                 // 'px' UserUnit (default)
485ddde725dSArmin Le Grand                                 bTwoCharValid = true;
486ddde725dSArmin Le Grand                             }
487ddde725dSArmin Le Grand                             else if(sal_Unicode('t') == aCharB)
488ddde725dSArmin Le Grand                             {
489ddde725dSArmin Le Grand                                 // 'pt' == 1.25 px
490ddde725dSArmin Le Grand                                 aRetval = Unit_pt;
491ddde725dSArmin Le Grand                                 bTwoCharValid = true;
492ddde725dSArmin Le Grand                             }
493ddde725dSArmin Le Grand                             else if(sal_Unicode('c') == aCharB)
494ddde725dSArmin Le Grand                             {
495ddde725dSArmin Le Grand                                 // 'pc' == 15 px
496ddde725dSArmin Le Grand                                 aRetval = Unit_pc;
497ddde725dSArmin Le Grand                                 bTwoCharValid = true;
498ddde725dSArmin Le Grand                             }
499ddde725dSArmin Le Grand                             break;
500ddde725dSArmin Le Grand                         }
501ddde725dSArmin Le Grand                         case sal_Unicode('i') :
502ddde725dSArmin Le Grand                         {
503ddde725dSArmin Le Grand                             if(sal_Unicode('n') == aCharB)
504ddde725dSArmin Le Grand                             {
505ddde725dSArmin Le Grand                                 // 'in' == 90 px
506ddde725dSArmin Le Grand                                 aRetval = Unit_in;
507ddde725dSArmin Le Grand                                 bTwoCharValid = true;
508ddde725dSArmin Le Grand                             }
509ddde725dSArmin Le Grand                             break;
510ddde725dSArmin Le Grand                         }
511ddde725dSArmin Le Grand                         case sal_Unicode('c') :
512ddde725dSArmin Le Grand                         {
513ddde725dSArmin Le Grand                             if(sal_Unicode('m') == aCharB)
514ddde725dSArmin Le Grand                             {
515ddde725dSArmin Le Grand                                 // 'cm' == 35.43307 px
516ddde725dSArmin Le Grand                                 aRetval = Unit_cm;
517ddde725dSArmin Le Grand                                 bTwoCharValid = true;
518ddde725dSArmin Le Grand                             }
519ddde725dSArmin Le Grand                             break;
520ddde725dSArmin Le Grand                         }
521ddde725dSArmin Le Grand                         case sal_Unicode('m') :
522ddde725dSArmin Le Grand                         {
523ddde725dSArmin Le Grand                             if(sal_Unicode('m') == aCharB)
524ddde725dSArmin Le Grand                             {
525ddde725dSArmin Le Grand                                 // 'mm' == 3.543307 px
526ddde725dSArmin Le Grand                                 aRetval = Unit_mm;
527ddde725dSArmin Le Grand                                 bTwoCharValid = true;
528ddde725dSArmin Le Grand                             }
529ddde725dSArmin Le Grand                             break;
530ddde725dSArmin Le Grand                         }
531ddde725dSArmin Le Grand                     }
532ddde725dSArmin Le Grand 
533ddde725dSArmin Le Grand                     if(bTwoCharValid)
534ddde725dSArmin Le Grand                     {
535ddde725dSArmin Le Grand                         nPos += 2;
536ddde725dSArmin Le Grand                     }
537ddde725dSArmin Le Grand                 }
538ddde725dSArmin Le Grand                 else
539ddde725dSArmin Le Grand                 {
540ddde725dSArmin Le Grand                     if(sal_Unicode('%') == aCharA)
541ddde725dSArmin Le Grand                     {
542ddde725dSArmin Le Grand                         // percent used, relative to current
543ddde725dSArmin Le Grand                         nPos++;
544ddde725dSArmin Le Grand                         aRetval = Unit_percent;
545ddde725dSArmin Le Grand                     }
546ddde725dSArmin Le Grand                 }
547ddde725dSArmin Le Grand             }
548ddde725dSArmin Le Grand 
549ddde725dSArmin Le Grand             return aRetval;
550ddde725dSArmin Le Grand         }
551ddde725dSArmin Le Grand 
readNumberAndUnit(const rtl::OUString & rCandidate,sal_Int32 & nPos,SvgNumber & aNum,const sal_Int32 nLen)552ddde725dSArmin Le Grand         bool readNumberAndUnit(const rtl::OUString& rCandidate, sal_Int32& nPos, SvgNumber& aNum, const sal_Int32 nLen)
553ddde725dSArmin Le Grand         {
554ddde725dSArmin Le Grand             double fNum(0.0);
555ddde725dSArmin Le Grand 
556ddde725dSArmin Le Grand             if(readNumber(rCandidate, nPos, fNum, nLen))
557ddde725dSArmin Le Grand             {
558ddde725dSArmin Le Grand                 skip_char(rCandidate, sal_Unicode(' '), nPos, nLen);
559ddde725dSArmin Le Grand                 aNum = SvgNumber(fNum, readUnit(rCandidate, nPos, nLen));
560ddde725dSArmin Le Grand 
561ddde725dSArmin Le Grand                 return true;
562ddde725dSArmin Le Grand             }
563ddde725dSArmin Le Grand 
564ddde725dSArmin Le Grand             return false;
565ddde725dSArmin Le Grand         }
566ddde725dSArmin Le Grand 
readAngle(const rtl::OUString & rCandidate,sal_Int32 & nPos,double & fAngle,const sal_Int32 nLen)567ddde725dSArmin Le Grand         bool readAngle(const rtl::OUString& rCandidate, sal_Int32& nPos, double& fAngle, const sal_Int32 nLen)
568ddde725dSArmin Le Grand         {
569ddde725dSArmin Le Grand             if(readNumber(rCandidate, nPos, fAngle, nLen))
570ddde725dSArmin Le Grand             {
571ddde725dSArmin Le Grand                 skip_char(rCandidate, sal_Unicode(' '), nPos, nLen);
572ddde725dSArmin Le Grand 
573ddde725dSArmin Le Grand                 enum DegreeType
574ddde725dSArmin Le Grand                 {
575ddde725dSArmin Le Grand                     deg,
576ddde725dSArmin Le Grand                     grad,
577ddde725dSArmin Le Grand                     rad
578ddde725dSArmin Le Grand                 } aType(deg); // degrees is default
579ddde725dSArmin Le Grand 
580ddde725dSArmin Le Grand                 if(nPos < nLen)
581ddde725dSArmin Le Grand                 {
582ddde725dSArmin Le Grand                     const sal_Unicode aChar(rCandidate[nPos]);
583ddde725dSArmin Le Grand                     static rtl::OUString aStrGrad(rtl::OUString::createFromAscii("grad"));
584ddde725dSArmin Le Grand                     static rtl::OUString aStrRad(rtl::OUString::createFromAscii("rad"));
585ddde725dSArmin Le Grand 
586ddde725dSArmin Le Grand                     switch(aChar)
587ddde725dSArmin Le Grand                     {
588ddde725dSArmin Le Grand                         case sal_Unicode('g') :
589ddde725dSArmin Le Grand                         case sal_Unicode('G') :
590ddde725dSArmin Le Grand                         {
591ddde725dSArmin Le Grand                             if(rCandidate.matchIgnoreAsciiCase(aStrGrad, nPos))
592ddde725dSArmin Le Grand                             {
593ddde725dSArmin Le Grand                                 // angle in grad
594ddde725dSArmin Le Grand                                 nPos += aStrGrad.getLength();
595ddde725dSArmin Le Grand                             }
596ddde725dSArmin Le Grand                             break;
597ddde725dSArmin Le Grand                         }
598ddde725dSArmin Le Grand                         case sal_Unicode('r') :
599ddde725dSArmin Le Grand                         case sal_Unicode('R') :
600ddde725dSArmin Le Grand                         {
601ddde725dSArmin Le Grand                             if(rCandidate.matchIgnoreAsciiCase(aStrRad, nPos))
602ddde725dSArmin Le Grand                             {
603ddde725dSArmin Le Grand                                 // angle in radians
604ddde725dSArmin Le Grand                                 nPos += aStrRad.getLength();
605ddde725dSArmin Le Grand                             }
606ddde725dSArmin Le Grand                             break;
607ddde725dSArmin Le Grand                         }
608ddde725dSArmin Le Grand                     }
609ddde725dSArmin Le Grand                 }
610ddde725dSArmin Le Grand 
611ddde725dSArmin Le Grand                 // convert to radians
612ddde725dSArmin Le Grand                 if(deg == aType)
613ddde725dSArmin Le Grand                 {
614ddde725dSArmin Le Grand                     fAngle *= F_PI / 180.0;
615ddde725dSArmin Le Grand                 }
616ddde725dSArmin Le Grand                 else if(grad == aType)
617ddde725dSArmin Le Grand                 {
618ddde725dSArmin Le Grand                     // looks like 100 grad is 90 degrees
619ddde725dSArmin Le Grand                     fAngle *= F_PI / 200.0;
620ddde725dSArmin Le Grand                 }
621ddde725dSArmin Le Grand 
622ddde725dSArmin Le Grand                 return true;
623ddde725dSArmin Le Grand             }
624ddde725dSArmin Le Grand 
625ddde725dSArmin Le Grand             return false;
626ddde725dSArmin Le Grand         }
627ddde725dSArmin Le Grand 
read_hex(const sal_Unicode & rChar)628ddde725dSArmin Le Grand         sal_Int32 read_hex(const sal_Unicode& rChar)
629ddde725dSArmin Le Grand         {
630ddde725dSArmin Le Grand             if(rChar >= sal_Unicode('0') && rChar <=sal_Unicode('9'))
631ddde725dSArmin Le Grand             {
632ddde725dSArmin Le Grand                 return sal_Int32(rChar - sal_Unicode('0'));
633ddde725dSArmin Le Grand             }
634ddde725dSArmin Le Grand             else if(rChar >= sal_Unicode('A') && rChar <=sal_Unicode('F'))
635ddde725dSArmin Le Grand             {
636ddde725dSArmin Le Grand                 return 10 + sal_Int32(rChar - sal_Unicode('A'));
637ddde725dSArmin Le Grand             }
638ddde725dSArmin Le Grand             else if(rChar >= sal_Unicode('a') && rChar <=sal_Unicode('f'))
639ddde725dSArmin Le Grand             {
640ddde725dSArmin Le Grand                 return 10 + sal_Int32(rChar - sal_Unicode('a'));
641ddde725dSArmin Le Grand             }
642ddde725dSArmin Le Grand             else
643ddde725dSArmin Le Grand             {
644ddde725dSArmin Le Grand                 // error
645ddde725dSArmin Le Grand                 return 0;
646ddde725dSArmin Le Grand             }
647ddde725dSArmin Le Grand         }
648ddde725dSArmin Le Grand 
match_colorKeyword(basegfx::BColor & rColor,const rtl::OUString & rName)649ddde725dSArmin Le Grand         bool match_colorKeyword(basegfx::BColor& rColor, const rtl::OUString& rName)
650ddde725dSArmin Le Grand         {
651ddde725dSArmin Le Grand             typedef std::hash_map< rtl::OUString, Color, rtl::OUStringHash > ColorTokenMapper;
652ddde725dSArmin Le Grand             typedef std::pair< rtl::OUString, Color > ColorTokenValueType;
653ddde725dSArmin Le Grand             ColorTokenMapper aColorTokenMapperList;
654ddde725dSArmin Le Grand 
655ddde725dSArmin Le Grand             if(aColorTokenMapperList.empty())
656ddde725dSArmin Le Grand             {
657ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("aliceblue"), Color(240, 248, 255)));
658ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("antiquewhite"), Color(250, 235, 215)));
659ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("aqua"), Color( 0, 255, 255)));
660ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("aquamarine"), Color(127, 255, 212)));
661ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("azure"), Color(240, 255, 255)));
662ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("beige"), Color(245, 245, 220)));
663ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("bisque"), Color(255, 228, 196)));
664ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("black"), Color( 0, 0, 0)));
665ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("blanchedalmond"), Color(255, 235, 205)));
666ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("blue"), Color( 0, 0, 255)));
667ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("blueviolet"), Color(138, 43, 226)));
668ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("brown"), Color(165, 42, 42)));
669ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("burlywood"), Color(222, 184, 135)));
670ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("cadetblue"), Color( 95, 158, 160)));
671ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("chartreuse"), Color(127, 255, 0)));
672ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("chocolate"), Color(210, 105, 30)));
673ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("coral"), Color(255, 127, 80)));
674ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("cornflowerblue"), Color(100, 149, 237)));
675ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("cornsilk"), Color(255, 248, 220)));
676ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("crimson"), Color(220, 20, 60)));
677ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("cyan"), Color( 0, 255, 255)));
678ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("darkblue"), Color( 0, 0, 139)));
679ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("darkcyan"), Color( 0, 139, 139)));
680ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("darkgoldenrod"), Color(184, 134, 11)));
681ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("darkgray"), Color(169, 169, 169)));
682ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("darkgreen"), Color( 0, 100, 0)));
683ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("darkgrey"), Color(169, 169, 169)));
684ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("darkkhaki"), Color(189, 183, 107)));
685ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("darkmagenta"), Color(139, 0, 139)));
686ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("darkolivegreen"), Color( 85, 107, 47)));
687ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("darkorange"), Color(255, 140, 0)));
688ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("darkorchid"), Color(153, 50, 204)));
689ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("darkred"), Color(139, 0, 0)));
690ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("darksalmon"), Color(233, 150, 122)));
691ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("darkseagreen"), Color(143, 188, 143)));
692ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("darkslateblue"), Color( 72, 61, 139)));
693ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("darkslategray"), Color( 47, 79, 79)));
694ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("darkslategrey"), Color( 47, 79, 79)));
695ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("darkturquoise"), Color( 0, 206, 209)));
696ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("darkviolet"), Color(148, 0, 211)));
697ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("deeppink"), Color(255, 20, 147)));
698ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("deepskyblue"), Color( 0, 191, 255)));
699ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("dimgray"), Color(105, 105, 105)));
700ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("dimgrey"), Color(105, 105, 105)));
701ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("dodgerblue"), Color( 30, 144, 255)));
702ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("firebrick"), Color(178, 34, 34)));
703ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("floralwhite"), Color(255, 250, 240)));
704ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("forestgreen"), Color( 34, 139, 34)));
705ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("fuchsia"), Color(255, 0, 255)));
706ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("gainsboro"), Color(220, 220, 220)));
707ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("ghostwhite"), Color(248, 248, 255)));
708ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("gold"), Color(255, 215, 0)));
709ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("goldenrod"), Color(218, 165, 32)));
710ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("gray"), Color(128, 128, 128)));
711ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("grey"), Color(128, 128, 128)));
712ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("green"), Color(0, 128, 0)));
713ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("greenyellow"), Color(173, 255, 47)));
714ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("honeydew"), Color(240, 255, 240)));
715ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("hotpink"), Color(255, 105, 180)));
716ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("indianred"), Color(205, 92, 92)));
717ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("indigo"), Color( 75, 0, 130)));
718ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("ivory"), Color(255, 255, 240)));
719ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("khaki"), Color(240, 230, 140)));
720ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lavender"), Color(230, 230, 250)));
721ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lavenderblush"), Color(255, 240, 245)));
722ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lawngreen"), Color(124, 252, 0)));
723ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lemonchiffon"), Color(255, 250, 205)));
724ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lightblue"), Color(173, 216, 230)));
725ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lightcoral"), Color(240, 128, 128)));
726ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lightcyan"), Color(224, 255, 255)));
727ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lightgoldenrodyellow"), Color(250, 250, 210)));
728ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lightgray"), Color(211, 211, 211)));
729ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lightgreen"), Color(144, 238, 144)));
730ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lightgrey"), Color(211, 211, 211)));
731ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lightpink"), Color(255, 182, 193)));
732ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lightsalmon"), Color(255, 160, 122)));
733ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lightseagreen"), Color( 32, 178, 170)));
734ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lightskyblue"), Color(135, 206, 250)));
735ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lightslategray"), Color(119, 136, 153)));
736ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lightslategrey"), Color(119, 136, 153)));
737ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lightsteelblue"), Color(176, 196, 222)));
738ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lightyellow"), Color(255, 255, 224)));
739ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("lime"), Color( 0, 255, 0)));
740ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("limegreen"), Color( 50, 205, 50)));
741ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("linen"), Color(250, 240, 230)));
742ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("magenta"), Color(255, 0, 255)));
743ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("maroon"), Color(128, 0, 0)));
744ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("mediumaquamarine"), Color(102, 205, 170)));
745ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("mediumblue"), Color( 0, 0, 205)));
746ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("mediumorchid"), Color(186, 85, 211)));
747ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("mediumpurple"), Color(147, 112, 219)));
748ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("mediumseagreen"), Color( 60, 179, 113)));
749ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("mediumslateblue"), Color(123, 104, 238)));
750ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("mediumspringgreen"), Color( 0, 250, 154)));
751ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("mediumturquoise"), Color( 72, 209, 204)));
752ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("mediumvioletred"), Color(199, 21, 133)));
753ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("midnightblue"), Color( 25, 25, 112)));
754ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("mintcream"), Color(245, 255, 250)));
755ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("mistyrose"), Color(255, 228, 225)));
756ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("moccasin"), Color(255, 228, 181)));
757ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("navajowhite"), Color(255, 222, 173)));
758ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("navy"), Color( 0, 0, 128)));
759ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("oldlace"), Color(253, 245, 230)));
760ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("olive"), Color(128, 128, 0)));
761ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("olivedrab"), Color(107, 142, 35)));
762ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("orange"), Color(255, 165, 0)));
763ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("orangered"), Color(255, 69, 0)));
764ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("orchid"), Color(218, 112, 214)));
765ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("palegoldenrod"), Color(238, 232, 170)));
766ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("palegreen"), Color(152, 251, 152)));
767ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("paleturquoise"), Color(175, 238, 238)));
768ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("palevioletred"), Color(219, 112, 147)));
769ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("papayawhip"), Color(255, 239, 213)));
770ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("peachpuff"), Color(255, 218, 185)));
771ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("peru"), Color(205, 133, 63)));
772ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("pink"), Color(255, 192, 203)));
773ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("plum"), Color(221, 160, 221)));
774ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("powderblue"), Color(176, 224, 230)));
775ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("purple"), Color(128, 0, 128)));
776ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("red"), Color(255, 0, 0)));
777ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("rosybrown"), Color(188, 143, 143)));
778ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("royalblue"), Color( 65, 105, 225)));
779ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("saddlebrown"), Color(139, 69, 19)));
780ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("salmon"), Color(250, 128, 114)));
781ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("sandybrown"), Color(244, 164, 96)));
782ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("seagreen"), Color( 46, 139, 87)));
783ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("seashell"), Color(255, 245, 238)));
784ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("sienna"), Color(160, 82, 45)));
785ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("silver"), Color(192, 192, 192)));
786ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("skyblue"), Color(135, 206, 235)));
787ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("slateblue"), Color(106, 90, 205)));
788ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("slategray"), Color(112, 128, 144)));
789ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("slategrey"), Color(112, 128, 144)));
790ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("snow"), Color(255, 250, 250)));
791ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("springgreen"), Color( 0, 255, 127)));
792ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("steelblue"), Color( 70, 130, 180)));
793ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("tan"), Color(210, 180, 140)));
794ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("teal"), Color( 0, 128, 128)));
795ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("thistle"), Color(216, 191, 216)));
796ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("tomato"), Color(255, 99, 71)));
797ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("turquoise"), Color( 64, 224, 208)));
798ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("violet"), Color(238, 130, 238)));
799ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("wheat"), Color(245, 222, 179)));
800ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("white"), Color(255, 255, 255)));
801ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("whitesmoke"), Color(245, 245, 245)));
802ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("yellow"), Color(255, 255, 0)));
803ddde725dSArmin Le Grand                 aColorTokenMapperList.insert(ColorTokenValueType(rtl::OUString::createFromAscii("yellowgreen"), Color(154, 205, 50)));
804ddde725dSArmin Le Grand             }
805ddde725dSArmin Le Grand 
806ddde725dSArmin Le Grand             const ColorTokenMapper::const_iterator aResult(aColorTokenMapperList.find(rName));
807ddde725dSArmin Le Grand 
808ddde725dSArmin Le Grand             if(aResult == aColorTokenMapperList.end())
809ddde725dSArmin Le Grand             {
810ddde725dSArmin Le Grand                 return false;
811ddde725dSArmin Le Grand             }
812ddde725dSArmin Le Grand             else
813ddde725dSArmin Le Grand             {
814ddde725dSArmin Le Grand                 rColor = aResult->second.getBColor();
815ddde725dSArmin Le Grand                 return true;
816ddde725dSArmin Le Grand             }
817ddde725dSArmin Le Grand         }
818ddde725dSArmin Le Grand 
read_color(const rtl::OUString & rCandidate,basegfx::BColor & rColor)819ddde725dSArmin Le Grand         bool read_color(const rtl::OUString& rCandidate, basegfx::BColor& rColor)
820ddde725dSArmin Le Grand         {
821ddde725dSArmin Le Grand             const sal_Int32 nLen(rCandidate.getLength());
822ddde725dSArmin Le Grand 
823ddde725dSArmin Le Grand             if(nLen)
824ddde725dSArmin Le Grand             {
825ddde725dSArmin Le Grand                 const sal_Unicode aChar(rCandidate[0]);
826ddde725dSArmin Le Grand                 const double fFactor(1.0 / 255.0);
827ddde725dSArmin Le Grand 
828ddde725dSArmin Le Grand                 if(aChar == sal_Unicode('#'))
829ddde725dSArmin Le Grand                 {
830ddde725dSArmin Le Grand                     // hex definition
831ddde725dSArmin Le Grand                     rtl::OUStringBuffer aNum;
832ddde725dSArmin Le Grand                     sal_Int32 nPos(1);
833ddde725dSArmin Le Grand 
834ddde725dSArmin Le Grand                     copyHex(rCandidate, nPos, aNum, nLen);
835ddde725dSArmin Le Grand                     const sal_Int32 nLength(aNum.getLength());
836ddde725dSArmin Le Grand 
837ddde725dSArmin Le Grand                     if(3 == nLength)
838ddde725dSArmin Le Grand                     {
839ddde725dSArmin Le Grand                         const sal_Int32 nR(read_hex(aNum.charAt(0)));
840ddde725dSArmin Le Grand                         const sal_Int32 nG(read_hex(aNum.charAt(1)));
841ddde725dSArmin Le Grand                         const sal_Int32 nB(read_hex(aNum.charAt(2)));
842ddde725dSArmin Le Grand 
843ddde725dSArmin Le Grand                         rColor.setRed((nR | (nR << 4)) * fFactor);
844ddde725dSArmin Le Grand                         rColor.setGreen((nG | (nG << 4)) * fFactor);
845ddde725dSArmin Le Grand                         rColor.setBlue((nB | (nB << 4)) * fFactor);
846ddde725dSArmin Le Grand 
847ddde725dSArmin Le Grand                         return true;
848ddde725dSArmin Le Grand                     }
849ddde725dSArmin Le Grand                     else if(6 == nLength)
850ddde725dSArmin Le Grand                     {
851ddde725dSArmin Le Grand                         const sal_Int32 nR1(read_hex(aNum.charAt(0)));
852ddde725dSArmin Le Grand                         const sal_Int32 nR2(read_hex(aNum.charAt(1)));
853ddde725dSArmin Le Grand                         const sal_Int32 nG1(read_hex(aNum.charAt(2)));
854ddde725dSArmin Le Grand                         const sal_Int32 nG2(read_hex(aNum.charAt(3)));
855ddde725dSArmin Le Grand                         const sal_Int32 nB1(read_hex(aNum.charAt(4)));
856ddde725dSArmin Le Grand                         const sal_Int32 nB2(read_hex(aNum.charAt(5)));
857ddde725dSArmin Le Grand 
858ddde725dSArmin Le Grand                         rColor.setRed((nR2 | (nR1 << 4)) * fFactor);
859ddde725dSArmin Le Grand                         rColor.setGreen((nG2 | (nG1 << 4)) * fFactor);
860ddde725dSArmin Le Grand                         rColor.setBlue((nB2 | (nB1 << 4)) * fFactor);
861ddde725dSArmin Le Grand 
862ddde725dSArmin Le Grand                         return true;
863ddde725dSArmin Le Grand                     }
864ddde725dSArmin Le Grand                 }
865ddde725dSArmin Le Grand                 else
866ddde725dSArmin Le Grand                 {
867ddde725dSArmin Le Grand                     static rtl::OUString aStrRgb(rtl::OUString::createFromAscii("rgb"));
868ddde725dSArmin Le Grand 
869ddde725dSArmin Le Grand                     if(rCandidate.matchIgnoreAsciiCase(aStrRgb, 0))
870ddde725dSArmin Le Grand                     {
871ddde725dSArmin Le Grand                         // rgb definition
872ddde725dSArmin Le Grand                         sal_Int32 nPos(aStrRgb.getLength());
873ddde725dSArmin Le Grand                         skip_char(rCandidate, sal_Unicode(' '), sal_Unicode('('), nPos, nLen);
874ddde725dSArmin Le Grand                         double fR(0.0);
875ddde725dSArmin Le Grand 
876ddde725dSArmin Le Grand                         if(readNumber(rCandidate, nPos, fR, nLen))
877ddde725dSArmin Le Grand                         {
878ddde725dSArmin Le Grand                             skip_char(rCandidate, sal_Unicode(' '), nPos, nLen);
879ddde725dSArmin Le Grand 
880ddde725dSArmin Le Grand                             if(nPos < nLen)
881ddde725dSArmin Le Grand                             {
882e2bf1e9dSArmin Le Grand                                 const sal_Unicode aPercentChar(rCandidate[nPos]);
883e2bf1e9dSArmin Le Grand                                 const bool bIsPercent(sal_Unicode('%') == aPercentChar);
884ddde725dSArmin Le Grand                                 double fG(0.0);
885ddde725dSArmin Le Grand 
886ddde725dSArmin Le Grand                                 if(bIsPercent)
887ddde725dSArmin Le Grand                                 {
888ddde725dSArmin Le Grand                                     skip_char(rCandidate, sal_Unicode('%'), nPos, nLen);
889ddde725dSArmin Le Grand                                 }
890ddde725dSArmin Le Grand 
891ddde725dSArmin Le Grand                                 skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
892ddde725dSArmin Le Grand 
893ddde725dSArmin Le Grand                                 if(readNumber(rCandidate, nPos, fG, nLen))
894ddde725dSArmin Le Grand                                 {
895ddde725dSArmin Le Grand                                     double fB(0.0);
896ddde725dSArmin Le Grand 
897ddde725dSArmin Le Grand                                     if(bIsPercent)
898ddde725dSArmin Le Grand                                     {
899ddde725dSArmin Le Grand                                         skip_char(rCandidate, sal_Unicode('%'), nPos, nLen);
900ddde725dSArmin Le Grand                                     }
901ddde725dSArmin Le Grand 
902ddde725dSArmin Le Grand                                     skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
903ddde725dSArmin Le Grand 
904ddde725dSArmin Le Grand                                     if(readNumber(rCandidate, nPos, fB, nLen))
905ddde725dSArmin Le Grand                                     {
906ddde725dSArmin Le Grand                                         const double fFac(bIsPercent ? 0.01 : fFactor);
907ddde725dSArmin Le Grand 
908ddde725dSArmin Le Grand                                         rColor.setRed(fR * fFac);
909ddde725dSArmin Le Grand                                         rColor.setGreen(fG * fFac);
910ddde725dSArmin Le Grand                                         rColor.setBlue(fB * fFac);
911ddde725dSArmin Le Grand 
912ddde725dSArmin Le Grand                                         if(bIsPercent)
913ddde725dSArmin Le Grand                                         {
914ddde725dSArmin Le Grand                                             skip_char(rCandidate, sal_Unicode('%'), nPos, nLen);
915ddde725dSArmin Le Grand                                         }
916ddde725dSArmin Le Grand 
917ddde725dSArmin Le Grand                                         skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(')'), nPos, nLen);
918ddde725dSArmin Le Grand                                         return true;
919ddde725dSArmin Le Grand                                     }
920ddde725dSArmin Le Grand                                 }
921ddde725dSArmin Le Grand                             }
922ddde725dSArmin Le Grand                         }
923ddde725dSArmin Le Grand                     }
924ddde725dSArmin Le Grand                     else
925ddde725dSArmin Le Grand                     {
926ddde725dSArmin Le Grand                         // color keyword
927ddde725dSArmin Le Grand                         if(match_colorKeyword(rColor, rCandidate))
928ddde725dSArmin Le Grand                         {
929ddde725dSArmin Le Grand                             return true;
930ddde725dSArmin Le Grand                         }
931ddde725dSArmin Le Grand                     }
932ddde725dSArmin Le Grand                 }
933ddde725dSArmin Le Grand             }
934ddde725dSArmin Le Grand 
935ddde725dSArmin Le Grand             return false;
936ddde725dSArmin Le Grand         }
937ddde725dSArmin Le Grand 
readViewBox(const rtl::OUString & rCandidate,InfoProvider & rInfoProvider)938ddde725dSArmin Le Grand         basegfx::B2DRange readViewBox(const rtl::OUString& rCandidate, InfoProvider& rInfoProvider)
939ddde725dSArmin Le Grand         {
940ddde725dSArmin Le Grand             const sal_Int32 nLen(rCandidate.getLength());
941ddde725dSArmin Le Grand 
942ddde725dSArmin Le Grand             if(nLen)
943ddde725dSArmin Le Grand             {
944ddde725dSArmin Le Grand                 sal_Int32 nPos(0);
945ddde725dSArmin Le Grand                 SvgNumber aMinX;
946ddde725dSArmin Le Grand                 skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
947ddde725dSArmin Le Grand 
948ddde725dSArmin Le Grand                 if(readNumberAndUnit(rCandidate, nPos, aMinX, nLen))
949ddde725dSArmin Le Grand                 {
950ddde725dSArmin Le Grand                     SvgNumber aMinY;
951ddde725dSArmin Le Grand                     skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
952ddde725dSArmin Le Grand 
953ddde725dSArmin Le Grand                     if(readNumberAndUnit(rCandidate, nPos, aMinY, nLen))
954ddde725dSArmin Le Grand                     {
955ddde725dSArmin Le Grand                         SvgNumber aWidth;
956ddde725dSArmin Le Grand                         skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
957ddde725dSArmin Le Grand 
958ddde725dSArmin Le Grand                         if(readNumberAndUnit(rCandidate, nPos, aWidth, nLen))
959ddde725dSArmin Le Grand                         {
960ddde725dSArmin Le Grand                             SvgNumber aHeight;
961ddde725dSArmin Le Grand                             skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
962ddde725dSArmin Le Grand 
963ddde725dSArmin Le Grand                             if(readNumberAndUnit(rCandidate, nPos, aHeight, nLen))
964ddde725dSArmin Le Grand                             {
9652169cc62SArmin Le Grand                                 double fX(aMinX.solve(rInfoProvider, xcoordinate));
9662169cc62SArmin Le Grand                                 double fY(aMinY.solve(rInfoProvider, ycoordinate));
9672169cc62SArmin Le Grand                                 double fW(aWidth.solve(rInfoProvider,xcoordinate));
9682169cc62SArmin Le Grand                                 double fH(aHeight.solve(rInfoProvider,ycoordinate));
9692169cc62SArmin Le Grand                                 return basegfx::B2DRange(fX,fY,fX+fW,fY+fH);
970ddde725dSArmin Le Grand                             }
971ddde725dSArmin Le Grand                         }
972ddde725dSArmin Le Grand                     }
973ddde725dSArmin Le Grand                 }
974ddde725dSArmin Le Grand             }
975ddde725dSArmin Le Grand 
976ddde725dSArmin Le Grand             return basegfx::B2DRange();
977ddde725dSArmin Le Grand         }
978ddde725dSArmin Le Grand 
readTransform(const rtl::OUString & rCandidate,InfoProvider & rInfoProvider)979ddde725dSArmin Le Grand         basegfx::B2DHomMatrix readTransform(const rtl::OUString& rCandidate, InfoProvider& rInfoProvider)
980ddde725dSArmin Le Grand         {
981ddde725dSArmin Le Grand             basegfx::B2DHomMatrix aMatrix;
982ddde725dSArmin Le Grand             const sal_Int32 nLen(rCandidate.getLength());
983ddde725dSArmin Le Grand 
984ddde725dSArmin Le Grand             if(nLen)
985ddde725dSArmin Le Grand             {
986ddde725dSArmin Le Grand                 sal_Int32 nPos(0);
987ddde725dSArmin Le Grand                 skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
988ddde725dSArmin Le Grand 
989ddde725dSArmin Le Grand                 while(nPos < nLen)
990ddde725dSArmin Le Grand                 {
991ddde725dSArmin Le Grand                     const sal_Unicode aChar(rCandidate[nPos]);
992ddde725dSArmin Le Grand                     const sal_Int32 nInitPos(nPos);
993ddde725dSArmin Le Grand                     static rtl::OUString aStrMatrix(rtl::OUString::createFromAscii("matrix"));
994ddde725dSArmin Le Grand                     static rtl::OUString aStrTranslate(rtl::OUString::createFromAscii("translate"));
995ddde725dSArmin Le Grand                     static rtl::OUString aStrScale(rtl::OUString::createFromAscii("scale"));
996ddde725dSArmin Le Grand                     static rtl::OUString aStrRotate(rtl::OUString::createFromAscii("rotate"));
997ddde725dSArmin Le Grand                     static rtl::OUString aStrSkewX(rtl::OUString::createFromAscii("skewX"));
998ddde725dSArmin Le Grand                     static rtl::OUString aStrSkewY(rtl::OUString::createFromAscii("skewY"));
999ddde725dSArmin Le Grand 
1000ddde725dSArmin Le Grand                     switch(aChar)
1001ddde725dSArmin Le Grand                     {
1002ddde725dSArmin Le Grand                         case sal_Unicode('m') :
1003ddde725dSArmin Le Grand                         {
1004ddde725dSArmin Le Grand                             if(rCandidate.match(aStrMatrix, nPos))
1005ddde725dSArmin Le Grand                             {
1006ddde725dSArmin Le Grand                                 // matrix element
1007ddde725dSArmin Le Grand                                 nPos += aStrMatrix.getLength();
1008ddde725dSArmin Le Grand                                 skip_char(rCandidate, sal_Unicode(' '), sal_Unicode('('), nPos, nLen);
1009ddde725dSArmin Le Grand                                 SvgNumber aVal;
1010ddde725dSArmin Le Grand                                 basegfx::B2DHomMatrix aNew;
1011ddde725dSArmin Le Grand 
1012ddde725dSArmin Le Grand                                 if(readNumberAndUnit(rCandidate, nPos, aVal, nLen))
1013ddde725dSArmin Le Grand                                 {
1014ddde725dSArmin Le Grand                                     aNew.set(0, 0, aVal.solve(rInfoProvider)); // Element A
1015ddde725dSArmin Le Grand                                     skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
1016ddde725dSArmin Le Grand 
1017ddde725dSArmin Le Grand                                     if(readNumberAndUnit(rCandidate, nPos, aVal, nLen))
1018ddde725dSArmin Le Grand                                     {
1019ddde725dSArmin Le Grand                                         aNew.set(1, 0, aVal.solve(rInfoProvider)); // Element B
1020ddde725dSArmin Le Grand                                         skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
1021ddde725dSArmin Le Grand 
1022ddde725dSArmin Le Grand                                         if(readNumberAndUnit(rCandidate, nPos, aVal, nLen))
1023ddde725dSArmin Le Grand                                         {
1024ddde725dSArmin Le Grand                                             aNew.set(0, 1, aVal.solve(rInfoProvider)); // Element C
1025ddde725dSArmin Le Grand                                             skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
1026ddde725dSArmin Le Grand 
1027ddde725dSArmin Le Grand                                             if(readNumberAndUnit(rCandidate, nPos, aVal, nLen))
1028ddde725dSArmin Le Grand                                             {
1029ddde725dSArmin Le Grand                                                 aNew.set(1, 1, aVal.solve(rInfoProvider)); // Element D
1030ddde725dSArmin Le Grand                                                 skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
1031ddde725dSArmin Le Grand 
1032ddde725dSArmin Le Grand                                                 if(readNumberAndUnit(rCandidate, nPos, aVal, nLen))
1033ddde725dSArmin Le Grand                                                 {
1034ddde725dSArmin Le Grand                                                     aNew.set(0, 2, aVal.solve(rInfoProvider, xcoordinate)); // Element E
1035ddde725dSArmin Le Grand                                                     skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
1036ddde725dSArmin Le Grand 
1037ddde725dSArmin Le Grand                                                     if(readNumberAndUnit(rCandidate, nPos, aVal, nLen))
1038ddde725dSArmin Le Grand                                                     {
1039ddde725dSArmin Le Grand                                                         aNew.set(1, 2, aVal.solve(rInfoProvider, ycoordinate)); // Element F
1040ddde725dSArmin Le Grand                                                         skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(')'), nPos, nLen);
1041ddde725dSArmin Le Grand                                                         skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
1042ddde725dSArmin Le Grand 
1043ddde725dSArmin Le Grand                                                         // caution: String is evaluated from left to right, but matrix multiplication
1044ddde725dSArmin Le Grand                                                         // in SVG is right to left, so put the new transformation before the current
1045ddde725dSArmin Le Grand                                                         // one by multiplicating from the right side
1046ddde725dSArmin Le Grand                                                         aMatrix = aMatrix * aNew;
1047ddde725dSArmin Le Grand                                                     }
1048ddde725dSArmin Le Grand                                                 }
1049ddde725dSArmin Le Grand                                             }
1050ddde725dSArmin Le Grand                                         }
1051ddde725dSArmin Le Grand                                     }
1052ddde725dSArmin Le Grand                                 }
1053ddde725dSArmin Le Grand                             }
1054ddde725dSArmin Le Grand                             break;
1055ddde725dSArmin Le Grand                         }
1056ddde725dSArmin Le Grand                         case sal_Unicode('t') :
1057ddde725dSArmin Le Grand                         {
1058ddde725dSArmin Le Grand                             if(rCandidate.match(aStrTranslate, nPos))
1059ddde725dSArmin Le Grand                             {
1060ddde725dSArmin Le Grand                                 // translate element
1061ddde725dSArmin Le Grand                                 nPos += aStrTranslate.getLength();
1062ddde725dSArmin Le Grand                                 skip_char(rCandidate, sal_Unicode(' '), sal_Unicode('('), nPos, nLen);
1063ddde725dSArmin Le Grand                                 SvgNumber aTransX;
1064ddde725dSArmin Le Grand 
1065ddde725dSArmin Le Grand                                 if(readNumberAndUnit(rCandidate, nPos, aTransX, nLen))
1066ddde725dSArmin Le Grand                                 {
1067ddde725dSArmin Le Grand                                     skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
1068ddde725dSArmin Le Grand                                     SvgNumber aTransY;
1069ddde725dSArmin Le Grand                                     readNumberAndUnit(rCandidate, nPos, aTransY, nLen);
1070ddde725dSArmin Le Grand                                     skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(')'), nPos, nLen);
1071ddde725dSArmin Le Grand                                     skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
1072ddde725dSArmin Le Grand 
1073ddde725dSArmin Le Grand                                     aMatrix = aMatrix * basegfx::tools::createTranslateB2DHomMatrix(
1074ddde725dSArmin Le Grand                                         aTransX.solve(rInfoProvider, xcoordinate),
1075ddde725dSArmin Le Grand                                         aTransY.solve(rInfoProvider, ycoordinate));
1076ddde725dSArmin Le Grand                                 }
1077ddde725dSArmin Le Grand                             }
1078ddde725dSArmin Le Grand                             break;
1079ddde725dSArmin Le Grand                         }
1080ddde725dSArmin Le Grand                         case sal_Unicode('s') :
1081ddde725dSArmin Le Grand                         {
1082ddde725dSArmin Le Grand                             if(rCandidate.match(aStrScale, nPos))
1083ddde725dSArmin Le Grand                             {
1084ddde725dSArmin Le Grand                                 // scale element
1085ddde725dSArmin Le Grand                                 nPos += aStrScale.getLength();
1086ddde725dSArmin Le Grand                                 skip_char(rCandidate, sal_Unicode(' '), sal_Unicode('('), nPos, nLen);
1087ddde725dSArmin Le Grand                                 SvgNumber aScaleX;
1088ddde725dSArmin Le Grand 
1089ddde725dSArmin Le Grand                                 if(readNumberAndUnit(rCandidate, nPos, aScaleX, nLen))
1090ddde725dSArmin Le Grand                                 {
1091ddde725dSArmin Le Grand                                     skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
1092ddde725dSArmin Le Grand                                     SvgNumber aScaleY(aScaleX);
1093ddde725dSArmin Le Grand                                     readNumberAndUnit(rCandidate, nPos, aScaleY, nLen);
1094ddde725dSArmin Le Grand                                     skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(')'), nPos, nLen);
1095ddde725dSArmin Le Grand                                     skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
1096ddde725dSArmin Le Grand 
1097ddde725dSArmin Le Grand                                     aMatrix = aMatrix * basegfx::tools::createScaleB2DHomMatrix(
1098ddde725dSArmin Le Grand                                         aScaleX.solve(rInfoProvider),
1099ddde725dSArmin Le Grand                                         aScaleY.solve(rInfoProvider));
1100ddde725dSArmin Le Grand                                 }
1101ddde725dSArmin Le Grand                             }
1102ddde725dSArmin Le Grand                             else if(rCandidate.match(aStrSkewX, nPos))
1103ddde725dSArmin Le Grand                             {
1104ddde725dSArmin Le Grand                                 // skewx element
1105ddde725dSArmin Le Grand                                 nPos += aStrSkewX.getLength();
1106ddde725dSArmin Le Grand                                 skip_char(rCandidate, sal_Unicode(' '), sal_Unicode('('), nPos, nLen);
1107ddde725dSArmin Le Grand                                 double fSkewX(0.0);
1108ddde725dSArmin Le Grand 
1109ddde725dSArmin Le Grand                                 if(readAngle(rCandidate, nPos, fSkewX, nLen))
1110ddde725dSArmin Le Grand                                 {
1111ddde725dSArmin Le Grand                                     skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(')'), nPos, nLen);
1112ddde725dSArmin Le Grand                                     skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
1113ddde725dSArmin Le Grand 
1114ddde725dSArmin Le Grand                                     aMatrix = aMatrix * basegfx::tools::createShearXB2DHomMatrix(tan(fSkewX));
1115ddde725dSArmin Le Grand                                 }
1116ddde725dSArmin Le Grand                             }
1117ddde725dSArmin Le Grand                             else if(rCandidate.match(aStrSkewY, nPos))
1118ddde725dSArmin Le Grand                             {
1119ddde725dSArmin Le Grand                                 // skewy element
1120ddde725dSArmin Le Grand                                 nPos += aStrSkewY.getLength();
1121ddde725dSArmin Le Grand                                 skip_char(rCandidate, sal_Unicode(' '), sal_Unicode('('), nPos, nLen);
1122ddde725dSArmin Le Grand                                 double fSkewY(0.0);
1123ddde725dSArmin Le Grand 
1124ddde725dSArmin Le Grand                                 if(readAngle(rCandidate, nPos, fSkewY, nLen))
1125ddde725dSArmin Le Grand                                 {
1126ddde725dSArmin Le Grand                                     skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(')'), nPos, nLen);
1127ddde725dSArmin Le Grand                                     skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
1128ddde725dSArmin Le Grand 
1129ddde725dSArmin Le Grand                                     aMatrix = aMatrix * basegfx::tools::createShearYB2DHomMatrix(tan(fSkewY));
1130ddde725dSArmin Le Grand                                 }
1131ddde725dSArmin Le Grand                             }
1132ddde725dSArmin Le Grand                             break;
1133ddde725dSArmin Le Grand                         }
1134ddde725dSArmin Le Grand                         case sal_Unicode('r') :
1135ddde725dSArmin Le Grand                         {
1136ddde725dSArmin Le Grand                             if(rCandidate.match(aStrRotate, nPos))
1137ddde725dSArmin Le Grand                             {
1138ddde725dSArmin Le Grand                                 // rotate element
1139ddde725dSArmin Le Grand                                 nPos += aStrRotate.getLength();
1140ddde725dSArmin Le Grand                                 skip_char(rCandidate, sal_Unicode(' '), sal_Unicode('('), nPos, nLen);
1141ddde725dSArmin Le Grand                                 double fAngle(0.0);
1142ddde725dSArmin Le Grand 
1143ddde725dSArmin Le Grand                                 if(readAngle(rCandidate, nPos, fAngle, nLen))
1144ddde725dSArmin Le Grand                                 {
1145ddde725dSArmin Le Grand                                     skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
1146ddde725dSArmin Le Grand                                     SvgNumber aX;
1147ddde725dSArmin Le Grand                                     readNumberAndUnit(rCandidate, nPos, aX, nLen);
1148ddde725dSArmin Le Grand                                     skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
1149ddde725dSArmin Le Grand                                     SvgNumber aY;
1150ddde725dSArmin Le Grand                                     readNumberAndUnit(rCandidate, nPos, aY, nLen);
1151ddde725dSArmin Le Grand                                     skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(')'), nPos, nLen);
1152ddde725dSArmin Le Grand                                     skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
1153ddde725dSArmin Le Grand 
1154ddde725dSArmin Le Grand                                     const double fX(aX.isSet() ? aX.solve(rInfoProvider, xcoordinate) : 0.0);
1155ddde725dSArmin Le Grand                                     const double fY(aY.isSet() ? aY.solve(rInfoProvider, ycoordinate) : 0.0);
1156ddde725dSArmin Le Grand 
1157ddde725dSArmin Le Grand                                     if(!basegfx::fTools::equalZero(fX) || !basegfx::fTools::equalZero(fY))
1158ddde725dSArmin Le Grand                                     {
1159ddde725dSArmin Le Grand                                         // rotate around point
1160ddde725dSArmin Le Grand                                         aMatrix = aMatrix * basegfx::tools::createRotateAroundPoint(fX, fY, fAngle);
1161ddde725dSArmin Le Grand                                     }
1162ddde725dSArmin Le Grand                                     else
1163ddde725dSArmin Le Grand                                     {
1164ddde725dSArmin Le Grand                                         // rotate
1165ddde725dSArmin Le Grand                                         aMatrix = aMatrix * basegfx::tools::createRotateB2DHomMatrix(fAngle);
1166ddde725dSArmin Le Grand                                     }
1167ddde725dSArmin Le Grand                                 }
1168ddde725dSArmin Le Grand                             }
1169ddde725dSArmin Le Grand                             break;
1170ddde725dSArmin Le Grand                         }
1171ddde725dSArmin Le Grand                     }
1172ddde725dSArmin Le Grand 
1173ddde725dSArmin Le Grand                     if(nInitPos == nPos)
1174ddde725dSArmin Le Grand                     {
1175ddde725dSArmin Le Grand                         OSL_ENSURE(false, "Could not interpret on current position (!)");
1176ddde725dSArmin Le Grand                         nPos++;
1177ddde725dSArmin Le Grand                     }
1178ddde725dSArmin Le Grand                 }
1179ddde725dSArmin Le Grand             }
1180ddde725dSArmin Le Grand 
1181ddde725dSArmin Le Grand             return aMatrix;
1182ddde725dSArmin Le Grand         }
1183ddde725dSArmin Le Grand 
readSingleNumber(const rtl::OUString & rCandidate,SvgNumber & aNum)1184ddde725dSArmin Le Grand         bool readSingleNumber(const rtl::OUString& rCandidate, SvgNumber& aNum)
1185ddde725dSArmin Le Grand         {
1186ddde725dSArmin Le Grand             const sal_Int32 nLen(rCandidate.getLength());
1187ddde725dSArmin Le Grand             sal_Int32 nPos(0);
1188ddde725dSArmin Le Grand 
1189ddde725dSArmin Le Grand             return readNumberAndUnit(rCandidate, nPos, aNum, nLen);
1190ddde725dSArmin Le Grand         }
1191ddde725dSArmin Le Grand 
readLocalUrl(const rtl::OUString & rCandidate,rtl::OUString & rURL)1192ddde725dSArmin Le Grand         bool readLocalUrl(const rtl::OUString& rCandidate, rtl::OUString& rURL)
1193ddde725dSArmin Le Grand         {
1194ddde725dSArmin Le Grand             static rtl::OUString aStrUrl(rtl::OUString::createFromAscii("url"));
1195ddde725dSArmin Le Grand 
1196ddde725dSArmin Le Grand             if(rCandidate.match(aStrUrl, 0))
1197ddde725dSArmin Le Grand             {
1198ddde725dSArmin Le Grand                 const sal_Int32 nLen(rCandidate.getLength());
1199ddde725dSArmin Le Grand                 sal_Int32 nPos(aStrUrl.getLength());
1200ddde725dSArmin Le Grand 
1201ddde725dSArmin Le Grand                 skip_char(rCandidate, sal_Unicode('('), sal_Unicode('#'), nPos, nLen);
1202ddde725dSArmin Le Grand                 rtl::OUStringBuffer aTokenValue;
1203ddde725dSArmin Le Grand                 copyToLimiter(rCandidate, sal_Unicode(')'), nPos, aTokenValue, nLen);
1204ddde725dSArmin Le Grand                 rURL = aTokenValue.makeStringAndClear();
1205ddde725dSArmin Le Grand 
1206ddde725dSArmin Le Grand                 return true;
1207ddde725dSArmin Le Grand             }
1208ddde725dSArmin Le Grand 
1209ddde725dSArmin Le Grand             return false;
1210ddde725dSArmin Le Grand         }
1211ddde725dSArmin Le Grand 
readSvgPaint(const rtl::OUString & rCandidate,SvgPaint & rSvgPaint,rtl::OUString & rURL)1212ddde725dSArmin Le Grand         bool readSvgPaint(const rtl::OUString& rCandidate, SvgPaint& rSvgPaint, rtl::OUString& rURL)
1213ddde725dSArmin Le Grand         {
1214ddde725dSArmin Le Grand             const sal_Int32 nLen(rCandidate.getLength());
1215ddde725dSArmin Le Grand 
1216ddde725dSArmin Le Grand             if(nLen)
1217ddde725dSArmin Le Grand             {
1218ddde725dSArmin Le Grand                 basegfx::BColor aColor;
1219ddde725dSArmin Le Grand 
1220ddde725dSArmin Le Grand                 if(read_color(rCandidate, aColor))
1221ddde725dSArmin Le Grand                 {
1222ddde725dSArmin Le Grand                     rSvgPaint = SvgPaint(aColor, true, true);
1223ddde725dSArmin Le Grand                     return true;
1224ddde725dSArmin Le Grand                 }
1225ddde725dSArmin Le Grand                 else
1226ddde725dSArmin Le Grand                 {
1227ddde725dSArmin Le Grand                     static rtl::OUString aStrNone(rtl::OUString::createFromAscii("none"));
1228ddde725dSArmin Le Grand                     static rtl::OUString aStrCurrentColor(rtl::OUString::createFromAscii("currentColor"));
1229ddde725dSArmin Le Grand 
1230ddde725dSArmin Le Grand                     if(rCandidate.match(aStrNone, 0))
1231ddde725dSArmin Le Grand                     {
1232ddde725dSArmin Le Grand                         rSvgPaint = SvgPaint(aColor, true, false, false);
1233ddde725dSArmin Le Grand                         return true;
1234ddde725dSArmin Le Grand                     }
1235ddde725dSArmin Le Grand                     else if(readLocalUrl(rCandidate, rURL))
1236ddde725dSArmin Le Grand                     {
1237ddde725dSArmin Le Grand                         /// Url is copied to rURL, but needs to be solved outside this helper
1238ddde725dSArmin Le Grand                         return false;
1239ddde725dSArmin Le Grand                     }
1240ddde725dSArmin Le Grand                     else if(rCandidate.match(aStrCurrentColor, 0))
1241ddde725dSArmin Le Grand                     {
1242ddde725dSArmin Le Grand                         rSvgPaint = SvgPaint(aColor, true, true, true);
1243ddde725dSArmin Le Grand                         return true;
1244ddde725dSArmin Le Grand                     }
1245ddde725dSArmin Le Grand                 }
1246ddde725dSArmin Le Grand             }
1247ddde725dSArmin Le Grand 
1248ddde725dSArmin Le Grand             return false;
1249ddde725dSArmin Le Grand         }
1250ddde725dSArmin Le Grand 
readSvgNumberVector(const rtl::OUString & rCandidate,SvgNumberVector & rSvgNumberVector)1251ddde725dSArmin Le Grand         bool readSvgNumberVector(const rtl::OUString& rCandidate, SvgNumberVector& rSvgNumberVector)
1252ddde725dSArmin Le Grand         {
1253ddde725dSArmin Le Grand             const sal_Int32 nLen(rCandidate.getLength());
1254ddde725dSArmin Le Grand             rSvgNumberVector.clear();
1255ddde725dSArmin Le Grand 
1256ddde725dSArmin Le Grand             if(nLen)
1257ddde725dSArmin Le Grand             {
1258ddde725dSArmin Le Grand                 sal_Int32 nPos(0);
1259ddde725dSArmin Le Grand                 SvgNumber aNum;
1260ddde725dSArmin Le Grand                 skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
1261ddde725dSArmin Le Grand 
1262ddde725dSArmin Le Grand                 while(readNumberAndUnit(rCandidate, nPos, aNum, nLen))
1263ddde725dSArmin Le Grand                 {
1264ddde725dSArmin Le Grand                     rSvgNumberVector.push_back(aNum);
1265ddde725dSArmin Le Grand                     skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
1266ddde725dSArmin Le Grand                 }
1267ddde725dSArmin Le Grand 
1268ddde725dSArmin Le Grand                 return !rSvgNumberVector.empty();
1269ddde725dSArmin Le Grand             }
1270ddde725dSArmin Le Grand 
1271ddde725dSArmin Le Grand             return false;
1272ddde725dSArmin Le Grand         }
1273ddde725dSArmin Le Grand 
readSvgAspectRatio(const rtl::OUString & rCandidate)1274ddde725dSArmin Le Grand         SvgAspectRatio readSvgAspectRatio(const rtl::OUString& rCandidate)
1275ddde725dSArmin Le Grand         {
1276ddde725dSArmin Le Grand             const sal_Int32 nLen(rCandidate.getLength());
1277ddde725dSArmin Le Grand 
1278ddde725dSArmin Le Grand             if(nLen)
1279ddde725dSArmin Le Grand             {
1280ddde725dSArmin Le Grand                 sal_Int32 nPos(0);
1281ddde725dSArmin Le Grand                 SvgAlign aSvgAlign(Align_xMidYMid);
1282ddde725dSArmin Le Grand                 bool bDefer(false);
1283ddde725dSArmin Le Grand                 bool bMeetOrSlice(true);
1284ddde725dSArmin Le Grand                 bool bChanged(false);
1285ddde725dSArmin Le Grand 
1286ddde725dSArmin Le Grand                 while(nPos < nLen)
1287ddde725dSArmin Le Grand                 {
1288ddde725dSArmin Le Grand                     const sal_Int32 nInitPos(nPos);
1289ddde725dSArmin Le Grand                     skip_char(rCandidate, sal_Unicode(' '), nPos, nLen);
1290ddde725dSArmin Le Grand                     rtl::OUStringBuffer aTokenName;
1291ddde725dSArmin Le Grand                     copyString(rCandidate, nPos, aTokenName, nLen);
1292ddde725dSArmin Le Grand 
1293ddde725dSArmin Le Grand                     if(aTokenName.getLength())
1294ddde725dSArmin Le Grand                     {
1295ddde725dSArmin Le Grand                         switch(StrToSVGToken(aTokenName.makeStringAndClear()))
1296ddde725dSArmin Le Grand                         {
1297ddde725dSArmin Le Grand                             case SVGTokenDefer:
1298ddde725dSArmin Le Grand                             {
1299ddde725dSArmin Le Grand                                 bDefer = true;
1300ddde725dSArmin Le Grand                                 bChanged = true;
1301ddde725dSArmin Le Grand                                 break;
1302ddde725dSArmin Le Grand                             }
1303ddde725dSArmin Le Grand                             case SVGTokenNone:
1304ddde725dSArmin Le Grand                             {
1305ddde725dSArmin Le Grand                                 aSvgAlign = Align_none;
1306ddde725dSArmin Le Grand                                 bChanged = true;
1307ddde725dSArmin Le Grand                                 break;
1308ddde725dSArmin Le Grand                             }
1309ddde725dSArmin Le Grand                             case SVGTokenXMinYMin:
1310ddde725dSArmin Le Grand                             {
1311ddde725dSArmin Le Grand                                 aSvgAlign = Align_xMinYMin;
1312ddde725dSArmin Le Grand                                 bChanged = true;
1313ddde725dSArmin Le Grand                                 break;
1314ddde725dSArmin Le Grand                             }
1315ddde725dSArmin Le Grand                             case SVGTokenXMidYMin:
1316ddde725dSArmin Le Grand                             {
1317ddde725dSArmin Le Grand                                 aSvgAlign = Align_xMidYMin;
1318ddde725dSArmin Le Grand                                 bChanged = true;
1319ddde725dSArmin Le Grand                                 break;
1320ddde725dSArmin Le Grand                             }
1321ddde725dSArmin Le Grand                             case SVGTokenXMaxYMin:
1322ddde725dSArmin Le Grand                             {
1323ddde725dSArmin Le Grand                                 aSvgAlign = Align_xMaxYMin;
1324ddde725dSArmin Le Grand                                 bChanged = true;
1325ddde725dSArmin Le Grand                                 break;
1326ddde725dSArmin Le Grand                             }
1327ddde725dSArmin Le Grand                             case SVGTokenXMinYMid:
1328ddde725dSArmin Le Grand                             {
1329ddde725dSArmin Le Grand                                 aSvgAlign = Align_xMinYMid;
1330ddde725dSArmin Le Grand                                 bChanged = true;
1331ddde725dSArmin Le Grand                                 break;
1332ddde725dSArmin Le Grand                             }
1333ddde725dSArmin Le Grand                             case SVGTokenXMidYMid:
1334ddde725dSArmin Le Grand                             {
1335ddde725dSArmin Le Grand                                 aSvgAlign = Align_xMidYMid;
1336ddde725dSArmin Le Grand                                 bChanged = true;
1337ddde725dSArmin Le Grand                                 break;
1338ddde725dSArmin Le Grand                             }
1339ddde725dSArmin Le Grand                             case SVGTokenXMaxYMid:
1340ddde725dSArmin Le Grand                             {
1341ddde725dSArmin Le Grand                                 aSvgAlign = Align_xMaxYMid;
1342ddde725dSArmin Le Grand                                 bChanged = true;
1343ddde725dSArmin Le Grand                                 break;
1344ddde725dSArmin Le Grand                             }
1345ddde725dSArmin Le Grand                             case SVGTokenXMinYMax:
1346ddde725dSArmin Le Grand                             {
1347ddde725dSArmin Le Grand                                 aSvgAlign = Align_xMinYMax;
1348ddde725dSArmin Le Grand                                 bChanged = true;
1349ddde725dSArmin Le Grand                                 break;
1350ddde725dSArmin Le Grand                             }
1351ddde725dSArmin Le Grand                             case SVGTokenXMidYMax:
1352ddde725dSArmin Le Grand                             {
1353ddde725dSArmin Le Grand                                 aSvgAlign = Align_xMidYMax;
1354ddde725dSArmin Le Grand                                 bChanged = true;
1355ddde725dSArmin Le Grand                                 break;
1356ddde725dSArmin Le Grand                             }
1357ddde725dSArmin Le Grand                             case SVGTokenXMaxYMax:
1358ddde725dSArmin Le Grand                             {
1359ddde725dSArmin Le Grand                                 aSvgAlign = Align_xMaxYMax;
1360ddde725dSArmin Le Grand                                 bChanged = true;
1361ddde725dSArmin Le Grand                                 break;
1362ddde725dSArmin Le Grand                             }
1363ddde725dSArmin Le Grand                             case SVGTokenMeet:
1364ddde725dSArmin Le Grand                             {
1365ddde725dSArmin Le Grand                                 bMeetOrSlice = true;
1366ddde725dSArmin Le Grand                                 bChanged = true;
1367ddde725dSArmin Le Grand                                 break;
1368ddde725dSArmin Le Grand                             }
1369ddde725dSArmin Le Grand                             case SVGTokenSlice:
1370ddde725dSArmin Le Grand                             {
1371ddde725dSArmin Le Grand                                 bMeetOrSlice = false;
1372ddde725dSArmin Le Grand                                 bChanged = true;
1373ddde725dSArmin Le Grand                                 break;
1374ddde725dSArmin Le Grand                             }
1375e2bf1e9dSArmin Le Grand                             default:
1376e2bf1e9dSArmin Le Grand                             {
1377e2bf1e9dSArmin Le Grand                                 break;
1378e2bf1e9dSArmin Le Grand                             }
1379ddde725dSArmin Le Grand                         }
1380ddde725dSArmin Le Grand                     }
1381ddde725dSArmin Le Grand 
1382ddde725dSArmin Le Grand                     if(nInitPos == nPos)
1383ddde725dSArmin Le Grand                     {
1384ddde725dSArmin Le Grand                         OSL_ENSURE(false, "Could not interpret on current position (!)");
1385ddde725dSArmin Le Grand                         nPos++;
1386ddde725dSArmin Le Grand                     }
1387ddde725dSArmin Le Grand                 }
1388ddde725dSArmin Le Grand 
1389ddde725dSArmin Le Grand                 if(bChanged)
1390ddde725dSArmin Le Grand                 {
1391ddde725dSArmin Le Grand                     return SvgAspectRatio(aSvgAlign, bDefer, bMeetOrSlice);
1392ddde725dSArmin Le Grand                 }
1393ddde725dSArmin Le Grand             }
1394ddde725dSArmin Le Grand 
1395ddde725dSArmin Le Grand             return SvgAspectRatio();
1396ddde725dSArmin Le Grand         }
1397ddde725dSArmin Le Grand 
readSvgStringVector(const rtl::OUString & rCandidate,SvgStringVector & rSvgStringVector)1398ddde725dSArmin Le Grand         bool readSvgStringVector(const rtl::OUString& rCandidate, SvgStringVector& rSvgStringVector)
1399ddde725dSArmin Le Grand         {
1400ddde725dSArmin Le Grand             rSvgStringVector.clear();
1401ddde725dSArmin Le Grand             const sal_Int32 nLen(rCandidate.getLength());
1402ddde725dSArmin Le Grand 
1403ddde725dSArmin Le Grand             if(nLen)
1404ddde725dSArmin Le Grand             {
1405ddde725dSArmin Le Grand                 sal_Int32 nPos(0);
1406ddde725dSArmin Le Grand                 rtl::OUStringBuffer aTokenValue;
1407ddde725dSArmin Le Grand                 skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
1408ddde725dSArmin Le Grand 
1409ddde725dSArmin Le Grand                 while(nPos < nLen)
1410ddde725dSArmin Le Grand                 {
1411ddde725dSArmin Le Grand                     copyToLimiter(rCandidate, sal_Unicode(','), nPos, aTokenValue, nLen);
1412ddde725dSArmin Le Grand                     skip_char(rCandidate, sal_Unicode(','), sal_Unicode(' '), nPos, nLen);
1413ddde725dSArmin Le Grand                     const rtl::OUString aString = aTokenValue.makeStringAndClear();
1414ddde725dSArmin Le Grand 
1415ddde725dSArmin Le Grand                     if(aString.getLength())
1416ddde725dSArmin Le Grand                     {
1417ddde725dSArmin Le Grand                         rSvgStringVector.push_back(aString);
1418ddde725dSArmin Le Grand                     }
1419ddde725dSArmin Le Grand                 }
1420ddde725dSArmin Le Grand             }
1421ddde725dSArmin Le Grand 
1422ddde725dSArmin Le Grand             return !rSvgStringVector.empty();
1423ddde725dSArmin Le Grand         }
1424ddde725dSArmin Le Grand 
readImageLink(const rtl::OUString & rCandidate,rtl::OUString & rXLink,rtl::OUString & rUrl,rtl::OUString & rMimeType,rtl::OUString & rData)1425ddde725dSArmin Le Grand         void readImageLink(const rtl::OUString& rCandidate, rtl::OUString& rXLink, rtl::OUString& rUrl, rtl::OUString& rMimeType, rtl::OUString& rData)
1426ddde725dSArmin Le Grand         {
1427ddde725dSArmin Le Grand             rXLink = rUrl = rMimeType = rData = rtl::OUString();
1428ddde725dSArmin Le Grand 
1429ddde725dSArmin Le Grand             if(sal_Unicode('#') == rCandidate[0])
1430ddde725dSArmin Le Grand             {
1431ddde725dSArmin Le Grand                 // local link
1432ddde725dSArmin Le Grand                 rXLink = rCandidate.copy(1);
1433ddde725dSArmin Le Grand             }
1434ddde725dSArmin Le Grand             else
1435ddde725dSArmin Le Grand             {
1436ddde725dSArmin Le Grand                 static rtl::OUString aStrData(rtl::OUString::createFromAscii("data:"));
1437ddde725dSArmin Le Grand 
1438ddde725dSArmin Le Grand                 if(rCandidate.match(aStrData, 0))
1439ddde725dSArmin Le Grand                 {
1440ddde725dSArmin Le Grand                     // embedded data
1441ddde725dSArmin Le Grand                     sal_Int32 nPos(aStrData.getLength());
1442ddde725dSArmin Le Grand                     sal_Int32 nLen(rCandidate.getLength());
1443ddde725dSArmin Le Grand                     rtl::OUStringBuffer aBuffer;
1444ddde725dSArmin Le Grand 
1445ddde725dSArmin Le Grand                     // read mime type
1446ddde725dSArmin Le Grand                     skip_char(rCandidate, sal_Unicode(' '), nPos, nLen);
1447ddde725dSArmin Le Grand                     copyToLimiter(rCandidate, sal_Unicode(';'), nPos, aBuffer, nLen);
1448ddde725dSArmin Le Grand                     skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(';'), nPos, nLen);
1449ddde725dSArmin Le Grand                     rMimeType = aBuffer.makeStringAndClear();
1450ddde725dSArmin Le Grand 
1451ddde725dSArmin Le Grand                     if(rMimeType.getLength() && nPos < nLen)
1452ddde725dSArmin Le Grand                     {
1453ddde725dSArmin Le Grand                         static rtl::OUString aStrImage(rtl::OUString::createFromAscii("image"));
1454ddde725dSArmin Le Grand 
1455ddde725dSArmin Le Grand                         if(rMimeType.match(aStrImage, 0))
1456ddde725dSArmin Le Grand                         {
1457ddde725dSArmin Le Grand                             // image data
1458ddde725dSArmin Le Grand                             rtl::OUString aData(rCandidate.copy(nPos));
1459ddde725dSArmin Le Grand                             static rtl::OUString aStrBase64(rtl::OUString::createFromAscii("base64"));
1460ddde725dSArmin Le Grand 
1461ddde725dSArmin Le Grand                             if(aData.match(aStrBase64, 0))
1462ddde725dSArmin Le Grand                             {
1463ddde725dSArmin Le Grand                                 // base64 encoded
1464ddde725dSArmin Le Grand                                 nPos = aStrBase64.getLength();
1465ddde725dSArmin Le Grand                                 nLen = aData.getLength();
1466ddde725dSArmin Le Grand 
1467ddde725dSArmin Le Grand                                 skip_char(aData, sal_Unicode(' '), sal_Unicode(','), nPos, nLen);
1468ddde725dSArmin Le Grand 
1469ddde725dSArmin Le Grand                                 if(nPos < nLen)
1470ddde725dSArmin Le Grand                                 {
1471ddde725dSArmin Le Grand                                     rData = aData.copy(nPos);
1472ddde725dSArmin Le Grand                                 }
1473ddde725dSArmin Le Grand                             }
1474ddde725dSArmin Le Grand                         }
1475ddde725dSArmin Le Grand                     }
1476ddde725dSArmin Le Grand                 }
1477ddde725dSArmin Le Grand                 else
1478ddde725dSArmin Le Grand                 {
1479ddde725dSArmin Le Grand                     // Url (path and filename)
1480ddde725dSArmin Le Grand                     rUrl = rCandidate;
1481ddde725dSArmin Le Grand                 }
1482ddde725dSArmin Le Grand             }
1483ddde725dSArmin Le Grand         }
1484ddde725dSArmin Le Grand 
convert(const rtl::OUString & rCandidate,const sal_Unicode & rPattern,const sal_Unicode & rNew,bool bRemove)1485ddde725dSArmin Le Grand         rtl::OUString convert(const rtl::OUString& rCandidate, const sal_Unicode& rPattern, const sal_Unicode& rNew, bool bRemove)
1486ddde725dSArmin Le Grand         {
1487ddde725dSArmin Le Grand             const sal_Int32 nLen(rCandidate.getLength());
1488ddde725dSArmin Le Grand 
1489ddde725dSArmin Le Grand             if(nLen)
1490ddde725dSArmin Le Grand             {
1491ddde725dSArmin Le Grand                 sal_Int32 nPos(0);
1492ddde725dSArmin Le Grand                 rtl::OUStringBuffer aBuffer;
1493ddde725dSArmin Le Grand                 bool bChanged(false);
1494ddde725dSArmin Le Grand 
1495ddde725dSArmin Le Grand                 while(nPos < nLen)
1496ddde725dSArmin Le Grand                 {
1497ddde725dSArmin Le Grand                     const sal_Unicode aChar(rCandidate[nPos]);
1498ddde725dSArmin Le Grand 
1499ddde725dSArmin Le Grand                     if(rPattern == aChar)
1500ddde725dSArmin Le Grand                     {
1501ddde725dSArmin Le Grand                         bChanged = true;
1502ddde725dSArmin Le Grand 
1503ddde725dSArmin Le Grand                         if(!bRemove)
1504ddde725dSArmin Le Grand                         {
1505ddde725dSArmin Le Grand                             aBuffer.append(rNew);
1506ddde725dSArmin Le Grand                         }
1507ddde725dSArmin Le Grand                     }
1508ddde725dSArmin Le Grand                     else
1509ddde725dSArmin Le Grand                     {
1510ddde725dSArmin Le Grand                         aBuffer.append(aChar);
1511ddde725dSArmin Le Grand                     }
1512ddde725dSArmin Le Grand 
1513ddde725dSArmin Le Grand                     nPos++;
1514ddde725dSArmin Le Grand                 }
1515ddde725dSArmin Le Grand 
1516ddde725dSArmin Le Grand                 if(bChanged)
1517ddde725dSArmin Le Grand                 {
1518ddde725dSArmin Le Grand                     return aBuffer.makeStringAndClear();
1519ddde725dSArmin Le Grand                 }
1520ddde725dSArmin Le Grand             }
1521ddde725dSArmin Le Grand 
1522ddde725dSArmin Le Grand             return rCandidate;
1523ddde725dSArmin Le Grand         }
1524ddde725dSArmin Le Grand 
consolidateContiguosSpace(const rtl::OUString & rCandidate)1525ddde725dSArmin Le Grand         rtl::OUString consolidateContiguosSpace(const rtl::OUString& rCandidate)
1526ddde725dSArmin Le Grand         {
1527ddde725dSArmin Le Grand             const sal_Int32 nLen(rCandidate.getLength());
1528ddde725dSArmin Le Grand 
1529ddde725dSArmin Le Grand             if(nLen)
1530ddde725dSArmin Le Grand             {
1531ddde725dSArmin Le Grand                 sal_Int32 nPos(0);
1532ddde725dSArmin Le Grand                 rtl::OUStringBuffer aBuffer;
1533ddde725dSArmin Le Grand                 bool bInsideSpace(false);
1534ddde725dSArmin Le Grand                 const sal_Unicode aSpace(' ');
1535ddde725dSArmin Le Grand 
1536ddde725dSArmin Le Grand                 while(nPos < nLen)
1537ddde725dSArmin Le Grand                 {
1538ddde725dSArmin Le Grand                     const sal_Unicode aChar(rCandidate[nPos]);
1539ddde725dSArmin Le Grand 
1540ddde725dSArmin Le Grand                     if(aSpace == aChar)
1541ddde725dSArmin Le Grand                     {
1542ddde725dSArmin Le Grand                         bInsideSpace = true;
1543ddde725dSArmin Le Grand                     }
1544ddde725dSArmin Le Grand                     else
1545ddde725dSArmin Le Grand                     {
1546ddde725dSArmin Le Grand                         if(bInsideSpace)
1547ddde725dSArmin Le Grand                         {
1548ddde725dSArmin Le Grand                             bInsideSpace = false;
1549ddde725dSArmin Le Grand                             aBuffer.append(aSpace);
1550ddde725dSArmin Le Grand                         }
1551ddde725dSArmin Le Grand 
1552ddde725dSArmin Le Grand                         aBuffer.append(aChar);
1553ddde725dSArmin Le Grand                     }
1554ddde725dSArmin Le Grand 
1555ddde725dSArmin Le Grand                     nPos++;
1556ddde725dSArmin Le Grand                 }
1557ddde725dSArmin Le Grand 
1558ddde725dSArmin Le Grand                 if(bInsideSpace)
1559ddde725dSArmin Le Grand                 {
1560ddde725dSArmin Le Grand                     aBuffer.append(aSpace);
1561ddde725dSArmin Le Grand                 }
1562ddde725dSArmin Le Grand 
1563ddde725dSArmin Le Grand                 if(aBuffer.getLength() != nLen)
1564ddde725dSArmin Le Grand                 {
1565ddde725dSArmin Le Grand                     return aBuffer.makeStringAndClear();
1566ddde725dSArmin Le Grand                 }
1567ddde725dSArmin Le Grand             }
1568ddde725dSArmin Le Grand 
1569ddde725dSArmin Le Grand             return rCandidate;
1570ddde725dSArmin Le Grand         }
1571ddde725dSArmin Le Grand 
whiteSpaceHandlingDefault(const rtl::OUString & rCandidate)1572ddde725dSArmin Le Grand         rtl::OUString whiteSpaceHandlingDefault(const rtl::OUString& rCandidate)
1573ddde725dSArmin Le Grand         {
1574ddde725dSArmin Le Grand             const sal_Unicode aNewline('\n');
1575ddde725dSArmin Le Grand             const sal_Unicode aTab('\t');
1576ddde725dSArmin Le Grand             const sal_Unicode aSpace(' ');
1577ddde725dSArmin Le Grand 
1578ddde725dSArmin Le Grand             // remove all newline characters
1579ddde725dSArmin Le Grand             rtl::OUString aRetval(convert(rCandidate, aNewline, aNewline, true));
1580ddde725dSArmin Le Grand 
1581ddde725dSArmin Le Grand             // convert tab to space
1582ddde725dSArmin Le Grand             aRetval = convert(aRetval, aTab, aSpace, false);
1583ddde725dSArmin Le Grand 
1584ddde725dSArmin Le Grand             // strip of all leading and trailing spaces
1585ddde725dSArmin Le Grand             aRetval = aRetval.trim();
1586ddde725dSArmin Le Grand 
1587ddde725dSArmin Le Grand             // consolidate contiguos space
1588ddde725dSArmin Le Grand             aRetval = consolidateContiguosSpace(aRetval);
1589ddde725dSArmin Le Grand 
1590ddde725dSArmin Le Grand             return aRetval;
1591ddde725dSArmin Le Grand         }
1592ddde725dSArmin Le Grand 
whiteSpaceHandlingPreserve(const rtl::OUString & rCandidate)1593ddde725dSArmin Le Grand         rtl::OUString whiteSpaceHandlingPreserve(const rtl::OUString& rCandidate)
1594ddde725dSArmin Le Grand         {
1595ddde725dSArmin Le Grand             const sal_Unicode aNewline('\n');
1596ddde725dSArmin Le Grand             const sal_Unicode aTab('\t');
1597ddde725dSArmin Le Grand             const sal_Unicode aSpace(' ');
1598ddde725dSArmin Le Grand 
1599ddde725dSArmin Le Grand             // convert newline to space
1600ddde725dSArmin Le Grand             rtl::OUString aRetval(convert(rCandidate, aNewline, aSpace, false));
1601ddde725dSArmin Le Grand 
1602ddde725dSArmin Le Grand             // convert tab to space
1603ddde725dSArmin Le Grand             aRetval = convert(rCandidate, aTab, aSpace, false);
1604ddde725dSArmin Le Grand 
1605ddde725dSArmin Le Grand             return rCandidate;
1606ddde725dSArmin Le Grand         }
1607ddde725dSArmin Le Grand 
solveSvgNumberVector(const SvgNumberVector & rInput,const InfoProvider & rInfoProvider,NumberType aNumberType)1608ddde725dSArmin Le Grand         ::std::vector< double > solveSvgNumberVector(const SvgNumberVector& rInput, const InfoProvider& rInfoProvider, NumberType aNumberType)
1609ddde725dSArmin Le Grand         {
1610ddde725dSArmin Le Grand             ::std::vector< double > aRetval;
1611ddde725dSArmin Le Grand 
1612ddde725dSArmin Le Grand             if(!rInput.empty())
1613ddde725dSArmin Le Grand             {
1614ddde725dSArmin Le Grand                 const double nCount(rInput.size());
1615ddde725dSArmin Le Grand                 aRetval.reserve(nCount);
1616ddde725dSArmin Le Grand 
1617ddde725dSArmin Le Grand                 for(sal_uInt32 a(0); a < nCount; a++)
1618ddde725dSArmin Le Grand                 {
1619ddde725dSArmin Le Grand                     aRetval.push_back(rInput[a].solve(rInfoProvider, aNumberType));
1620ddde725dSArmin Le Grand                 }
1621ddde725dSArmin Le Grand             }
1622ddde725dSArmin Le Grand 
1623ddde725dSArmin Le Grand             return aRetval;
1624ddde725dSArmin Le Grand         }
1625ddde725dSArmin Le Grand 
1626ddde725dSArmin Le Grand     } // end of namespace svgreader
1627ddde725dSArmin Le Grand } // end of namespace svgio
1628ddde725dSArmin Le Grand 
1629ddde725dSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
1630ddde725dSArmin Le Grand // eof
1631