• Skip to content
  • Skip to link menu
KDE 4.3 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

KHTML

SVGTransformable.cpp

Go to the documentation of this file.
00001 /*
00002     Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org>
00003                   2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
00004                   2007 Eric Seidel <eric@webkit.org>
00005 
00006     This file is part of the WebKit project
00007 
00008     This library is free software; you can redistribute it and/or
00009     modify it under the terms of the GNU Library General Public
00010     License as published by the Free Software Foundation; either
00011     version 2 of the License, or (at your option) any later version.
00012 
00013     This library is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016     Library General Public License for more details.
00017 
00018     You should have received a copy of the GNU Library General Public License
00019     along with this library; see the file COPYING.LIB.  If not, write to
00020     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00021     Boston, MA 02110-1301, USA.
00022 */
00023 
00024 #include "config.h"
00025 #include "Document.h"
00026 
00027 #if ENABLE(SVG)
00028 #include "SVGTransformable.h"
00029 
00030 #include "AffineTransform.h"
00031 #include "FloatConversion.h"
00032 //#include "RegularExpression.h"
00033 #include "SVGNames.h"
00034 #include "SVGParserUtilities.h"
00035 #include "SVGStyledElement.h"
00036 #include "SVGTransformList.h"
00037 
00038 namespace WebCore {
00039 
00040 SVGTransformable::SVGTransformable() : SVGLocatable()
00041 {
00042 }
00043 
00044 SVGTransformable::~SVGTransformable()
00045 {
00046 }
00047 
00048 AffineTransform SVGTransformable::getCTM(const SVGElement* element) const
00049 {
00050     AffineTransform ctm = SVGLocatable::getCTM(element);
00051     return animatedLocalTransform() * ctm;
00052 }
00053 
00054 AffineTransform SVGTransformable::getScreenCTM(const SVGElement* element) const
00055 {
00056     AffineTransform ctm = SVGLocatable::getScreenCTM(element);
00057     return animatedLocalTransform() * ctm;
00058 }
00059 
00060 int parseTransformParamList(const UChar*& ptr, const UChar* end, float* values, int required, int optional)
00061 {
00062     int optionalParams = 0, requiredParams = 0;
00063     
00064     if (!skipOptionalSpaces(ptr, end) || *ptr != '(')
00065         return -1;
00066     
00067     ptr++;
00068    
00069     skipOptionalSpaces(ptr, end);
00070 
00071     while (requiredParams < required) {
00072         if (ptr >= end || !parseNumber(ptr, end, values[requiredParams], false))
00073             return -1;
00074         requiredParams++;
00075         if (requiredParams < required)
00076             skipOptionalSpacesOrDelimiter(ptr, end);
00077     }
00078     if (!skipOptionalSpaces(ptr, end))
00079         return -1;
00080     
00081     bool delimParsed = skipOptionalSpacesOrDelimiter(ptr, end);
00082 
00083     if (ptr >= end)
00084         return -1;
00085     
00086     if (*ptr == ')') { // skip optionals
00087         ptr++;
00088         if (delimParsed)
00089             return -1;
00090     } else {
00091         while (optionalParams < optional) {
00092             if (ptr >= end || !parseNumber(ptr, end, values[requiredParams + optionalParams], false))
00093                 return -1;
00094             optionalParams++;
00095             if (optionalParams < optional)
00096                 skipOptionalSpacesOrDelimiter(ptr, end);
00097         }
00098         
00099         if (!skipOptionalSpaces(ptr, end))
00100             return -1;
00101         
00102         delimParsed = skipOptionalSpacesOrDelimiter(ptr, end);
00103         
00104         if (ptr >= end || *ptr != ')' || delimParsed)
00105             return -1;
00106         ptr++;
00107     }
00108 
00109     return requiredParams + optionalParams;
00110 }
00111 
00112 // These should be kept in sync with enum SVGTransformType
00113 static const int requiredValuesForType[] =  {0, 6, 1, 1, 1, 1, 1};
00114 static const int optionalValuesForType[] =  {0, 0, 1, 1, 2, 0, 0};
00115 
00116 bool SVGTransformable::parseTransformValue(unsigned type, const UChar*& ptr, const UChar* end, SVGTransform& t)
00117 {
00118     if (type == SVGTransform::SVG_TRANSFORM_UNKNOWN)
00119         return false;
00120 
00121     int valueCount = 0;
00122     float values[] = {0, 0, 0, 0, 0, 0};
00123     if ((valueCount = parseTransformParamList(ptr, end, values, requiredValuesForType[type], optionalValuesForType[type])) < 0)
00124         return false;
00125 
00126     switch (type) {
00127         case SVGTransform::SVG_TRANSFORM_SKEWX:
00128            t.setSkewX(values[0]);
00129             break;
00130         case SVGTransform::SVG_TRANSFORM_SKEWY:
00131                t.setSkewY(values[0]);
00132             break;
00133         case SVGTransform::SVG_TRANSFORM_SCALE:
00134               if (valueCount == 1) // Spec: if only one param given, assume uniform scaling
00135                   t.setScale(values[0], values[0]);
00136               else
00137                   t.setScale(values[0], values[1]);
00138             break;
00139         case SVGTransform::SVG_TRANSFORM_TRANSLATE:
00140               if (valueCount == 1) // Spec: if only one param given, assume 2nd param to be 0
00141                   t.setTranslate(values[0], 0);
00142               else
00143                   t.setTranslate(values[0], values[1]);
00144             break;
00145         case SVGTransform::SVG_TRANSFORM_ROTATE:
00146               if (valueCount == 1)
00147                   t.setRotate(values[0], 0, 0);
00148               else
00149                   t.setRotate(values[0], values[1], values[2]);
00150             break;
00151         case SVGTransform::SVG_TRANSFORM_MATRIX:
00152             t.setMatrix(AffineTransform(values[0], values[1], values[2], values[3], values[4], values[5]));
00153             break;
00154     }
00155 
00156     return true;
00157 }
00158 
00159 static const UChar skewXDesc[] =  {'s','k','e','w', 'X'};
00160 static const UChar skewYDesc[] =  {'s','k','e','w', 'Y'};
00161 static const UChar scaleDesc[] =  {'s','c','a','l', 'e'};
00162 static const UChar translateDesc[] =  {'t','r','a','n', 's', 'l', 'a', 't', 'e'};
00163 static const UChar rotateDesc[] =  {'r','o','t','a', 't', 'e'};
00164 static const UChar matrixDesc[] =  {'m','a','t','r', 'i', 'x'};
00165 
00166 // KHTML
00167 /*static inline bool skipString(const UChar*& currTransform, const UChar* end, const UChar* pattern, int len)
00168 {
00169     int i = len;
00170     const UChar* curr = currTransform;
00171     while (i && curr < end) {
00172         if (*curr++ != *pattern++)
00173             return false;
00174         --i;
00175     }
00176     if (i)
00177         return false;
00178     currTransform += len;
00179     return true;
00180 }*/
00181 
00182 static inline bool parseAndSkipType(const UChar*& currTransform, const UChar* end, unsigned short& type)
00183 {
00184     if (currTransform >= end)
00185         return false;
00186     
00187     if (*currTransform == 's') {
00188         if (skipString(currTransform, end, skewXDesc, sizeof(skewXDesc) / sizeof(UChar)))
00189             type = SVGTransform::SVG_TRANSFORM_SKEWX;
00190         else if (skipString(currTransform, end, skewYDesc, sizeof(skewYDesc) / sizeof(UChar)))
00191             type = SVGTransform::SVG_TRANSFORM_SKEWY;
00192         else if (skipString(currTransform, end, scaleDesc, sizeof(scaleDesc) / sizeof(UChar)))
00193             type = SVGTransform::SVG_TRANSFORM_SCALE;
00194         else
00195             return false;
00196     } else if (skipString(currTransform, end, translateDesc, sizeof(translateDesc) / sizeof(UChar)))
00197         type = SVGTransform::SVG_TRANSFORM_TRANSLATE;
00198     else if (skipString(currTransform, end, rotateDesc, sizeof(rotateDesc) / sizeof(UChar)))
00199         type = SVGTransform::SVG_TRANSFORM_ROTATE;
00200     else if (skipString(currTransform, end, matrixDesc, sizeof(matrixDesc) / sizeof(UChar)))
00201         type = SVGTransform::SVG_TRANSFORM_MATRIX;
00202     else 
00203         return false;
00204     
00205     return true;
00206 }
00207 
00208 bool SVGTransformable::parseTransformAttribute(SVGTransformList* list, const AtomicString& transform)
00209 {
00210     const UChar* start = transform.characters();
00211     const UChar* end = start + transform.length();
00212     return parseTransformAttribute(list, start, end);
00213 }
00214 
00215 bool SVGTransformable::parseTransformAttribute(SVGTransformList* list, const UChar*& currTransform, const UChar* end)
00216 {
00217     bool delimParsed = false;
00218     while (currTransform < end) {
00219         delimParsed = false;
00220         unsigned short type = SVGTransform::SVG_TRANSFORM_UNKNOWN;
00221         skipOptionalSpaces(currTransform, end);
00222         
00223         if (!parseAndSkipType(currTransform, end, type))
00224             return false;
00225 
00226         SVGTransform t;
00227         if (!parseTransformValue(type, currTransform, end, t))
00228             return false;
00229 
00230         ExceptionCode ec = 0;
00231         list->appendItem(t, ec);
00232         skipOptionalSpaces(currTransform, end);
00233         if (currTransform < end && *currTransform == ',') {
00234             delimParsed = true;
00235             currTransform++;
00236         }
00237         skipOptionalSpaces(currTransform, end);
00238     }
00239 
00240     return !delimParsed;
00241 }
00242 
00243 bool SVGTransformable::isKnownAttribute(const QualifiedName& attrName)
00244 {
00245     return attrName.matches(SVGNames::transformAttr);
00246 }
00247 
00248 }
00249 
00250 #endif // ENABLE(SVG)

KHTML

Skip menu "KHTML"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal