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