| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2002, 2003 The Karbon Developers | 2 * Copyright (C) 2002, 2003 The Karbon Developers |
| 3 * Copyright (C) 2006 Alexander Kellett <lypanov@kde.org> | 3 * Copyright (C) 2006 Alexander Kellett <lypanov@kde.org> |
| 4 * Copyright (C) 2006, 2007 Rob Buis <buis@kde.org> | 4 * Copyright (C) 2006, 2007 Rob Buis <buis@kde.org> |
| 5 * Copyright (C) 2007, 2009, 2013 Apple Inc. All rights reserved. | 5 * Copyright (C) 2007, 2009, 2013 Apple Inc. All rights reserved. |
| 6 * | 6 * |
| 7 * This library is free software; you can redistribute it and/or | 7 * This library is free software; you can redistribute it and/or |
| 8 * modify it under the terms of the GNU Library General Public | 8 * modify it under the terms of the GNU Library General Public |
| 9 * License as published by the Free Software Foundation; either | 9 * License as published by the Free Software Foundation; either |
| 10 * version 2 of the License, or (at your option) any later version. | 10 * version 2 of the License, or (at your option) any later version. |
| 11 * | 11 * |
| 12 * This library is distributed in the hope that it will be useful, | 12 * This library is distributed in the hope that it will be useful, |
| 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 15 * Library General Public License for more details. | 15 * Library General Public License for more details. |
| 16 * | 16 * |
| 17 * You should have received a copy of the GNU Library General Public License | 17 * You should have received a copy of the GNU Library General Public License |
| 18 * along with this library; see the file COPYING.LIB. If not, write to | 18 * along with this library; see the file COPYING.LIB. If not, write to |
| 19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| 20 * Boston, MA 02110-1301, USA. | 20 * Boston, MA 02110-1301, USA. |
| 21 */ | 21 */ |
| 22 | 22 |
| 23 #include "config.h" | 23 #include "config.h" |
| 24 #include "core/svg/SVGParserUtilities.h" | 24 #include "core/svg/SVGParserUtilities.h" |
| 25 | 25 |
| 26 #include "core/dom/Document.h" | 26 #include "core/dom/Document.h" |
| 27 #include "core/svg/SVGPointList.h" | 27 #include "core/svg/SVGPointList.h" |
| 28 #include "core/svg/SVGTransformList.h" | |
| 29 #include "platform/geometry/FloatRect.h" | 28 #include "platform/geometry/FloatRect.h" |
| 30 #include "platform/transforms/AffineTransform.h" | 29 #include "platform/transforms/AffineTransform.h" |
| 31 #include "wtf/ASCIICType.h" | 30 #include "wtf/ASCIICType.h" |
| 32 #include <limits> | 31 #include <limits> |
| 33 | 32 |
| 34 namespace WebCore { | 33 namespace WebCore { |
| 35 | 34 |
| 36 template <typename FloatType> | 35 template <typename FloatType> |
| 37 static inline bool isValidRange(const FloatType& x) | 36 static inline bool isValidRange(const FloatType& x) |
| 38 { | 37 { |
| (...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 482 return false; | 481 return false; |
| 483 point1 = FloatPoint(x1, y1); | 482 point1 = FloatPoint(x1, y1); |
| 484 point2 = FloatPoint(x2, y2); | 483 point2 = FloatPoint(x2, y2); |
| 485 point3 = FloatPoint(x3, y3); | 484 point3 = FloatPoint(x3, y3); |
| 486 return true; | 485 return true; |
| 487 } | 486 } |
| 488 | 487 |
| 489 template bool parseFloatPoint3(const LChar*& current, const LChar* end, FloatPoi
nt& point1, FloatPoint& point2, FloatPoint& point3); | 488 template bool parseFloatPoint3(const LChar*& current, const LChar* end, FloatPoi
nt& point1, FloatPoint& point2, FloatPoint& point3); |
| 490 template bool parseFloatPoint3(const UChar*& current, const UChar* end, FloatPoi
nt& point1, FloatPoint& point2, FloatPoint& point3); | 489 template bool parseFloatPoint3(const UChar*& current, const UChar* end, FloatPoi
nt& point1, FloatPoint& point2, FloatPoint& point3); |
| 491 | 490 |
| 492 template<typename CharType> | |
| 493 static int parseTransformParamList(const CharType*& ptr, const CharType* end, fl
oat* values, int required, int optional) | |
| 494 { | |
| 495 int optionalParams = 0, requiredParams = 0; | |
| 496 | |
| 497 if (!skipOptionalSVGSpaces(ptr, end) || *ptr != '(') | |
| 498 return -1; | |
| 499 | |
| 500 ptr++; | |
| 501 | |
| 502 skipOptionalSVGSpaces(ptr, end); | |
| 503 | |
| 504 while (requiredParams < required) { | |
| 505 if (ptr >= end || !parseNumber(ptr, end, values[requiredParams], false)) | |
| 506 return -1; | |
| 507 requiredParams++; | |
| 508 if (requiredParams < required) | |
| 509 skipOptionalSVGSpacesOrDelimiter(ptr, end); | |
| 510 } | |
| 511 if (!skipOptionalSVGSpaces(ptr, end)) | |
| 512 return -1; | |
| 513 | |
| 514 bool delimParsed = skipOptionalSVGSpacesOrDelimiter(ptr, end); | |
| 515 | |
| 516 if (ptr >= end) | |
| 517 return -1; | |
| 518 | |
| 519 if (*ptr == ')') { // skip optionals | |
| 520 ptr++; | |
| 521 if (delimParsed) | |
| 522 return -1; | |
| 523 } else { | |
| 524 while (optionalParams < optional) { | |
| 525 if (ptr >= end || !parseNumber(ptr, end, values[requiredParams + opt
ionalParams], false)) | |
| 526 return -1; | |
| 527 optionalParams++; | |
| 528 if (optionalParams < optional) | |
| 529 skipOptionalSVGSpacesOrDelimiter(ptr, end); | |
| 530 } | |
| 531 | |
| 532 if (!skipOptionalSVGSpaces(ptr, end)) | |
| 533 return -1; | |
| 534 | |
| 535 delimParsed = skipOptionalSVGSpacesOrDelimiter(ptr, end); | |
| 536 | |
| 537 if (ptr >= end || *ptr != ')' || delimParsed) | |
| 538 return -1; | |
| 539 ptr++; | |
| 540 } | |
| 541 | |
| 542 return requiredParams + optionalParams; | |
| 543 } | |
| 544 | |
| 545 // These should be kept in sync with enum SVGTransformType | |
| 546 static const int requiredValuesForType[] = {0, 6, 1, 1, 1, 1, 1}; | |
| 547 static const int optionalValuesForType[] = {0, 0, 1, 1, 2, 0, 0}; | |
| 548 | |
| 549 template<typename CharType> | |
| 550 static bool parseTransformValueInternal(unsigned type, const CharType*& ptr, con
st CharType* end, SVGTransform& transform) | |
| 551 { | |
| 552 if (type == SVGTransform::SVG_TRANSFORM_UNKNOWN) | |
| 553 return false; | |
| 554 | |
| 555 int valueCount = 0; | |
| 556 float values[] = {0, 0, 0, 0, 0, 0}; | |
| 557 if ((valueCount = parseTransformParamList(ptr, end, values, requiredValuesFo
rType[type], optionalValuesForType[type])) < 0) | |
| 558 return false; | |
| 559 | |
| 560 switch (type) { | |
| 561 case SVGTransform::SVG_TRANSFORM_SKEWX: | |
| 562 transform.setSkewX(values[0]); | |
| 563 break; | |
| 564 case SVGTransform::SVG_TRANSFORM_SKEWY: | |
| 565 transform.setSkewY(values[0]); | |
| 566 break; | |
| 567 case SVGTransform::SVG_TRANSFORM_SCALE: | |
| 568 if (valueCount == 1) // Spec: if only one param given, assume uniform sc
aling | |
| 569 transform.setScale(values[0], values[0]); | |
| 570 else | |
| 571 transform.setScale(values[0], values[1]); | |
| 572 break; | |
| 573 case SVGTransform::SVG_TRANSFORM_TRANSLATE: | |
| 574 if (valueCount == 1) // Spec: if only one param given, assume 2nd param
to be 0 | |
| 575 transform.setTranslate(values[0], 0); | |
| 576 else | |
| 577 transform.setTranslate(values[0], values[1]); | |
| 578 break; | |
| 579 case SVGTransform::SVG_TRANSFORM_ROTATE: | |
| 580 if (valueCount == 1) | |
| 581 transform.setRotate(values[0], 0, 0); | |
| 582 else | |
| 583 transform.setRotate(values[0], values[1], values[2]); | |
| 584 break; | |
| 585 case SVGTransform::SVG_TRANSFORM_MATRIX: | |
| 586 transform.setMatrix(AffineTransform(values[0], values[1], values[2], val
ues[3], values[4], values[5])); | |
| 587 break; | |
| 588 } | |
| 589 | |
| 590 return true; | |
| 591 } | |
| 592 | |
| 593 bool parseTransformValue(unsigned type, const LChar*& ptr, const LChar* end, SVG
Transform& transform) | |
| 594 { | |
| 595 return parseTransformValueInternal(type, ptr, end, transform); | |
| 596 } | |
| 597 | |
| 598 bool parseTransformValue(unsigned type, const UChar*& ptr, const UChar* end, SVG
Transform& transform) | |
| 599 { | |
| 600 return parseTransformValueInternal(type, ptr, end, transform); | |
| 601 } | |
| 602 | |
| 603 static const LChar skewXDesc[] = {'s', 'k', 'e', 'w', 'X'}; | 491 static const LChar skewXDesc[] = {'s', 'k', 'e', 'w', 'X'}; |
| 604 static const LChar skewYDesc[] = {'s', 'k', 'e', 'w', 'Y'}; | 492 static const LChar skewYDesc[] = {'s', 'k', 'e', 'w', 'Y'}; |
| 605 static const LChar scaleDesc[] = {'s', 'c', 'a', 'l', 'e'}; | 493 static const LChar scaleDesc[] = {'s', 'c', 'a', 'l', 'e'}; |
| 606 static const LChar translateDesc[] = {'t', 'r', 'a', 'n', 's', 'l', 'a', 't', '
e'}; | 494 static const LChar translateDesc[] = {'t', 'r', 'a', 'n', 's', 'l', 'a', 't', '
e'}; |
| 607 static const LChar rotateDesc[] = {'r', 'o', 't', 'a', 't', 'e'}; | 495 static const LChar rotateDesc[] = {'r', 'o', 't', 'a', 't', 'e'}; |
| 608 static const LChar matrixDesc[] = {'m', 'a', 't', 'r', 'i', 'x'}; | 496 static const LChar matrixDesc[] = {'m', 'a', 't', 'r', 'i', 'x'}; |
| 609 | 497 |
| 610 template<typename CharType> | 498 template<typename CharType> |
| 611 static inline bool parseAndSkipType(const CharType*& ptr, const CharType* end, u
nsigned short& type) | 499 bool parseAndSkipTransformType(const CharType*& ptr, const CharType* end, SVGTra
nsformType& type) |
| 612 { | 500 { |
| 613 if (ptr >= end) | 501 if (ptr >= end) |
| 614 return false; | 502 return false; |
| 615 | 503 |
| 616 if (*ptr == 's') { | 504 if (*ptr == 's') { |
| 617 if (skipString(ptr, end, skewXDesc, WTF_ARRAY_LENGTH(skewXDesc))) | 505 if (skipString(ptr, end, skewXDesc, WTF_ARRAY_LENGTH(skewXDesc))) |
| 618 type = SVGTransform::SVG_TRANSFORM_SKEWX; | 506 type = SVG_TRANSFORM_SKEWX; |
| 619 else if (skipString(ptr, end, skewYDesc, WTF_ARRAY_LENGTH(skewYDesc))) | 507 else if (skipString(ptr, end, skewYDesc, WTF_ARRAY_LENGTH(skewYDesc))) |
| 620 type = SVGTransform::SVG_TRANSFORM_SKEWY; | 508 type = SVG_TRANSFORM_SKEWY; |
| 621 else if (skipString(ptr, end, scaleDesc, WTF_ARRAY_LENGTH(scaleDesc))) | 509 else if (skipString(ptr, end, scaleDesc, WTF_ARRAY_LENGTH(scaleDesc))) |
| 622 type = SVGTransform::SVG_TRANSFORM_SCALE; | 510 type = SVG_TRANSFORM_SCALE; |
| 623 else | 511 else |
| 624 return false; | 512 return false; |
| 625 } else if (skipString(ptr, end, translateDesc, WTF_ARRAY_LENGTH(translateDes
c))) | 513 } else if (skipString(ptr, end, translateDesc, WTF_ARRAY_LENGTH(translateDes
c))) |
| 626 type = SVGTransform::SVG_TRANSFORM_TRANSLATE; | 514 type = SVG_TRANSFORM_TRANSLATE; |
| 627 else if (skipString(ptr, end, rotateDesc, WTF_ARRAY_LENGTH(rotateDesc))) | 515 else if (skipString(ptr, end, rotateDesc, WTF_ARRAY_LENGTH(rotateDesc))) |
| 628 type = SVGTransform::SVG_TRANSFORM_ROTATE; | 516 type = SVG_TRANSFORM_ROTATE; |
| 629 else if (skipString(ptr, end, matrixDesc, WTF_ARRAY_LENGTH(matrixDesc))) | 517 else if (skipString(ptr, end, matrixDesc, WTF_ARRAY_LENGTH(matrixDesc))) |
| 630 type = SVGTransform::SVG_TRANSFORM_MATRIX; | 518 type = SVG_TRANSFORM_MATRIX; |
| 631 else | 519 else |
| 632 return false; | 520 return false; |
| 633 | 521 |
| 634 return true; | 522 return true; |
| 635 } | 523 } |
| 636 | 524 |
| 637 SVGTransform::SVGTransformType parseTransformType(const String& string) | 525 template bool parseAndSkipTransformType(const UChar*& current, const UChar* end,
SVGTransformType&); |
| 526 template bool parseAndSkipTransformType(const LChar*& current, const LChar* end,
SVGTransformType&); |
| 527 |
| 528 SVGTransformType parseTransformType(const String& string) |
| 638 { | 529 { |
| 639 if (string.isEmpty()) | 530 if (string.isEmpty()) |
| 640 return SVGTransform::SVG_TRANSFORM_UNKNOWN; | 531 return SVG_TRANSFORM_UNKNOWN; |
| 641 unsigned short type = SVGTransform::SVG_TRANSFORM_UNKNOWN; | 532 SVGTransformType type = SVG_TRANSFORM_UNKNOWN; |
| 642 if (string.is8Bit()) { | 533 if (string.is8Bit()) { |
| 643 const LChar* ptr = string.characters8(); | 534 const LChar* ptr = string.characters8(); |
| 644 const LChar* end = ptr + string.length(); | 535 const LChar* end = ptr + string.length(); |
| 645 parseAndSkipType(ptr, end, type); | 536 parseAndSkipTransformType(ptr, end, type); |
| 646 } else { | 537 } else { |
| 647 const UChar* ptr = string.characters16(); | 538 const UChar* ptr = string.characters16(); |
| 648 const UChar* end = ptr + string.length(); | 539 const UChar* end = ptr + string.length(); |
| 649 parseAndSkipType(ptr, end, type); | 540 parseAndSkipTransformType(ptr, end, type); |
| 650 } | 541 } |
| 651 return static_cast<SVGTransform::SVGTransformType>(type); | 542 return type; |
| 652 } | |
| 653 | |
| 654 template<typename CharType> | |
| 655 bool parseTransformAttributeInternal(SVGTransformList& list, const CharType*& pt
r, const CharType* end, TransformParsingMode mode) | |
| 656 { | |
| 657 if (mode == ClearList) | |
| 658 list.clear(); | |
| 659 | |
| 660 bool delimParsed = false; | |
| 661 while (ptr < end) { | |
| 662 delimParsed = false; | |
| 663 unsigned short type = SVGTransform::SVG_TRANSFORM_UNKNOWN; | |
| 664 skipOptionalSVGSpaces(ptr, end); | |
| 665 | |
| 666 if (!parseAndSkipType(ptr, end, type)) | |
| 667 return false; | |
| 668 | |
| 669 SVGTransform transform; | |
| 670 if (!parseTransformValue(type, ptr, end, transform)) | |
| 671 return false; | |
| 672 | |
| 673 list.append(transform); | |
| 674 skipOptionalSVGSpaces(ptr, end); | |
| 675 if (ptr < end && *ptr == ',') { | |
| 676 delimParsed = true; | |
| 677 ++ptr; | |
| 678 } | |
| 679 skipOptionalSVGSpaces(ptr, end); | |
| 680 } | |
| 681 | |
| 682 return !delimParsed; | |
| 683 } | |
| 684 | |
| 685 bool parseTransformAttribute(SVGTransformList& list, const LChar*& ptr, const LC
har* end, TransformParsingMode mode) | |
| 686 { | |
| 687 return parseTransformAttributeInternal(list, ptr, end, mode); | |
| 688 } | |
| 689 | |
| 690 bool parseTransformAttribute(SVGTransformList& list, const UChar*& ptr, const UC
har* end, TransformParsingMode mode) | |
| 691 { | |
| 692 return parseTransformAttributeInternal(list, ptr, end, mode); | |
| 693 } | 543 } |
| 694 | 544 |
| 695 } | 545 } |
| OLD | NEW |