LCOV - code coverage report
Current view: top level - libreoffice/svgio/source/svgreader - svgtools.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 788 0.0 %
Date: 2012-12-27 Functions: 0 34 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10