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