* ksvg2/svg/SVGPreserveAspectRatio.cpp: Add a couple of comments.
[WebKit-https.git] / WebCore / ksvg2 / svg / SVGPreserveAspectRatio.cpp
index ad89ff9..2968330 100644 (file)
@@ -1,6 +1,6 @@
 /*
     Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org>
-                  2004, 2005 Rob Buis <buis@kde.org>
+                  2004, 2005, 2006 Rob Buis <buis@kde.org>
 
     This file is part of the KDE project
 
 */
 
 #include "config.h"
-#if SVG_SUPPORT
-#include "DeprecatedString.h"
-#include "DeprecatedStringList.h"
-
-#include "StringImpl.h"
+#ifdef SVG_SUPPORT
+#include "SVGPreserveAspectRatio.h"
 
-#include "ksvg.h"
-#include "SVGMatrix.h"
+#include "SVGParserUtilities.h"
 #include "SVGSVGElement.h"
-#include "SVGPreserveAspectRatio.h"
 
-using namespace WebCore;
+namespace WebCore {
+
+static bool checkString(const UChar*& ptr, const UChar*& end, const char* str)
+{
+    int length = strlen(str);
+    if (end - ptr < length)
+        return false;
+    for (int i = 0; i < length; ++i)
+        if (ptr[i] != str[i])
+            return false;
+    ptr += length;
+    return true;
+}
 
-SVGPreserveAspectRatio::SVGPreserveAspectRatio(const SVGStyledElement *context) : Shared<SVGPreserveAspectRatio>()
+SVGPreserveAspectRatio::SVGPreserveAspectRatio(const SVGStyledElement* context)
+    : Shared<SVGPreserveAspectRatio>()
+    , m_align(SVG_PRESERVEASPECTRATIO_XMIDYMID)
+    , m_meetOrSlice(SVG_MEETORSLICE_MEET)
+    , m_context(context)
 {
-    m_context = context;
-    m_meetOrSlice = SVG_MEETORSLICE_MEET;
-    m_align = SVG_PRESERVEASPECTRATIO_XMIDYMID;
+    // FIXME: Should the two values default to UNKNOWN instead?
 }
 
 SVGPreserveAspectRatio::~SVGPreserveAspectRatio()
@@ -48,6 +57,7 @@ SVGPreserveAspectRatio::~SVGPreserveAspectRatio()
 void SVGPreserveAspectRatio::setAlign(unsigned short align)
 {
     m_align = align;
+    // FIXME: Do we need a call to notifyAttributeChange here?
 }
 
 unsigned short SVGPreserveAspectRatio::align() const
@@ -58,6 +68,7 @@ unsigned short SVGPreserveAspectRatio::align() const
 void SVGPreserveAspectRatio::setMeetOrSlice(unsigned short meetOrSlice)
 {
     m_meetOrSlice = meetOrSlice;
+    // FIXME: Do we need a call to notifyAttributeChange here?
 }
 
 unsigned short SVGPreserveAspectRatio::meetOrSlice() const
@@ -65,52 +76,116 @@ unsigned short SVGPreserveAspectRatio::meetOrSlice() const
     return m_meetOrSlice;
 }
 
-void SVGPreserveAspectRatio::parsePreserveAspectRatio(StringImpl *strImpl)
+void SVGPreserveAspectRatio::parsePreserveAspectRatio(const String& string)
 {
-    // Spec: set the defaults
-    setAlign(SVG_PRESERVEASPECTRATIO_NONE);
-    setMeetOrSlice(SVG_MEETORSLICE_MEET);
-    
-    String s(strImpl);
-    DeprecatedString str = s.deprecatedString();
-    DeprecatedStringList params = DeprecatedStringList::split(' ', str.simplifyWhiteSpace());
-
-    if (params[0] == "none")
-        m_align = SVG_PRESERVEASPECTRATIO_NONE;
-    else if (params[0] == "xMinYMin")
-        m_align = SVG_PRESERVEASPECTRATIO_XMINYMIN;
-    else if (params[0] == "xMidYMin")
-        m_align = SVG_PRESERVEASPECTRATIO_XMIDYMIN;
-    else if (params[0] == "xMaxYMin")
-        m_align = SVG_PRESERVEASPECTRATIO_XMAXYMIN;
-    else if (params[0] == "xMinYMid")
-        m_align = SVG_PRESERVEASPECTRATIO_XMINYMID;
-    else if (params[0] == "xMidYMid")
-        m_align = SVG_PRESERVEASPECTRATIO_XMIDYMID;
-    else if (params[0] == "xMaxYMid")
-        m_align = SVG_PRESERVEASPECTRATIO_XMAXYMID;
-    else if (params[0] == "xMinYMax")
-        m_align = SVG_PRESERVEASPECTRATIO_XMINYMAX;
-    else if (params[0] == "xMidYMax")
-        m_align = SVG_PRESERVEASPECTRATIO_XMIDYMAX;
-    else if (params[0] == "xMaxYMax")
-        m_align = SVG_PRESERVEASPECTRATIO_XMAXYMAX;
-
-    if (m_align != SVG_PRESERVEASPECTRATIO_NONE) {
-        if ((params.count() > 1) && (params[1] == "slice"))
-            m_meetOrSlice = SVG_MEETORSLICE_SLICE;
-        else
-            m_meetOrSlice = SVG_MEETORSLICE_MEET;
+    SVGPreserveAspectRatioType align = SVG_PRESERVEASPECTRATIO_NONE;
+    SVGMeetOrSliceType meetOrSlice = SVG_MEETORSLICE_MEET;
+
+    const UChar* currParam = string.characters();
+    const UChar* end = currParam + string.length();
+
+    if (!skipOptionalSpaces(currParam, end))
+        goto bail_out;
+
+    if (*currParam == 'd') {
+        if (!checkString(currParam, end, "defer"))
+            goto bail_out;
+        // FIXME: We just ignore the "defer" here.
+        if (!skipOptionalSpaces(currParam, end))
+            goto bail_out;
+    }
+
+    if (*currParam == 'n') {
+        if (!checkString(currParam, end, "none"))
+            goto bail_out;
+        skipOptionalSpaces(currParam, end);
+    } else if (*currParam == 'x') {
+        if ((end - currParam) < 8)
+            goto bail_out;
+        if (currParam[1] != 'M' || currParam[4] != 'Y' || currParam[5] != 'M')
+            goto bail_out;
+        if (currParam[2] == 'i') {
+            if (currParam[3] == 'n') {
+                if (currParam[6] == 'i') {
+                    if (currParam[7] == 'n')
+                        align = SVG_PRESERVEASPECTRATIO_XMINYMIN;
+                    else if (currParam[7] == 'd')
+                        align = SVG_PRESERVEASPECTRATIO_XMINYMID;
+                    else
+                        goto bail_out;
+                } else if (currParam[6] == 'a' && currParam[7] == 'x')
+                     align = SVG_PRESERVEASPECTRATIO_XMINYMAX;
+                else
+                     goto bail_out;
+             } else if (currParam[3] == 'd') {
+                if (currParam[6] == 'i') {
+                    if (currParam[7] == 'n')
+                        align = SVG_PRESERVEASPECTRATIO_XMIDYMIN;
+                    else if (currParam[7] == 'd')
+                        align = SVG_PRESERVEASPECTRATIO_XMIDYMID;
+                    else
+                        goto bail_out;
+                } else if (currParam[6] == 'a' && currParam[7] == 'x')
+                    align = SVG_PRESERVEASPECTRATIO_XMIDYMAX;
+                else
+                    goto bail_out;
+            } else
+                goto bail_out;
+        } else if (currParam[2] == 'a' && currParam[3] == 'x') {
+            if (currParam[6] == 'i') {
+                if (currParam[7] == 'n')
+                    align = SVG_PRESERVEASPECTRATIO_XMAXYMIN;
+                else if (currParam[7] == 'd')
+                    align = SVG_PRESERVEASPECTRATIO_XMAXYMID;
+                else
+                    goto bail_out;
+            } else if (currParam[6] == 'a' && currParam[7] == 'x')
+                align = SVG_PRESERVEASPECTRATIO_XMAXYMAX;
+            else
+                goto bail_out;
+        } else
+            goto bail_out;
+        currParam += 8;
+        skipOptionalSpaces(currParam, end);
+    } else
+        goto bail_out;
+
+    if (currParam < end) {
+        if (*currParam == 'm') {
+            if (!checkString(currParam, end, "meet"))
+                goto bail_out;
+            skipOptionalSpaces(currParam, end);
+        } else if (*currParam == 's') {
+            if (!checkString(currParam, end, "slice"))
+                goto bail_out;
+            skipOptionalSpaces(currParam, end);
+            if (align != SVG_PRESERVEASPECTRATIO_NONE)
+                meetOrSlice = SVG_MEETORSLICE_SLICE;    
+        }
+    }
+
+    if (end != currParam) {
+bail_out:
+        // FIXME: Should the two values be set to UNKNOWN instead?
+        align = SVG_PRESERVEASPECTRATIO_NONE;
+        meetOrSlice = SVG_MEETORSLICE_MEET;
     }
 
+    if (m_align == align && m_meetOrSlice == meetOrSlice)
+        return;
+
+    m_align = align;
+    m_meetOrSlice = meetOrSlice;
     if (m_context)
         m_context->notifyAttributeChange();
 }
 
-SVGMatrix *SVGPreserveAspectRatio::getCTM(float logicX, float logicY, float logicWidth, float logicHeight,
-                                                  float /*physX*/, float /*physY*/, float physWidth, float physHeight)
+AffineTransform SVGPreserveAspectRatio::getCTM(float logicX, float logicY,
+                                               float logicWidth, float logicHeight,
+                                               float /*physX*/, float /*physY*/,
+                                               float physWidth, float physHeight)
 {
-    SVGMatrix *temp = SVGSVGElement::createSVGMatrix();
+    AffineTransform temp;
 
     if (align() == SVG_PRESERVEASPECTRATIO_UNKNOWN)
         return temp;
@@ -118,37 +193,33 @@ SVGMatrix *SVGPreserveAspectRatio::getCTM(float logicX, float logicY, float logi
     float vpar = logicWidth / logicHeight;
     float svgar = physWidth / physHeight;
 
-    if (align() == SVG_PRESERVEASPECTRATIO_NONE)
-    {
-        temp->scaleNonUniform(physWidth / logicWidth, physHeight / logicHeight);
-        temp->translate(-logicX, -logicY);
-    }
-    else if (vpar < svgar && (meetOrSlice() == SVG_MEETORSLICE_MEET) || vpar >= svgar && (meetOrSlice() == SVG_MEETORSLICE_SLICE))
-    {
-        temp->scale(physHeight / logicHeight);
+    if (align() == SVG_PRESERVEASPECTRATIO_NONE) {
+        temp.scale(physWidth / logicWidth, physHeight / logicHeight);
+        temp.translate(-logicX, -logicY);
+    } else if (vpar < svgar && (meetOrSlice() == SVG_MEETORSLICE_MEET) || vpar >= svgar && (meetOrSlice() == SVG_MEETORSLICE_SLICE)) {
+        temp.scale(physHeight / logicHeight, physHeight / logicHeight);
 
         if (align() == SVG_PRESERVEASPECTRATIO_XMINYMIN || align() == SVG_PRESERVEASPECTRATIO_XMINYMID || align() == SVG_PRESERVEASPECTRATIO_XMINYMAX)
-            temp->translate(-logicX, -logicY);
+            temp.translate(-logicX, -logicY);
         else if (align() == SVG_PRESERVEASPECTRATIO_XMIDYMIN || align() == SVG_PRESERVEASPECTRATIO_XMIDYMID || align() == SVG_PRESERVEASPECTRATIO_XMIDYMAX)
-            temp->translate(-logicX - (logicWidth - physWidth * logicHeight / physHeight) / 2, -logicY);
+            temp.translate(-logicX - (logicWidth - physWidth * logicHeight / physHeight) / 2, -logicY);
         else
-            temp->translate(-logicX - (logicWidth - physWidth * logicHeight / physHeight), -logicY);
-    }
-    else
-    {
-        temp->scale(physWidth / logicWidth);
+            temp.translate(-logicX - (logicWidth - physWidth * logicHeight / physHeight), -logicY);
+    } else {
+        temp.scale(physWidth / logicWidth, physWidth / logicWidth);
 
         if (align() == SVG_PRESERVEASPECTRATIO_XMINYMIN || align() == SVG_PRESERVEASPECTRATIO_XMIDYMIN || align() == SVG_PRESERVEASPECTRATIO_XMAXYMIN)
-            temp->translate(-logicX, -logicY);
+            temp.translate(-logicX, -logicY);
         else if (align() == SVG_PRESERVEASPECTRATIO_XMINYMID || align() == SVG_PRESERVEASPECTRATIO_XMIDYMID || align() == SVG_PRESERVEASPECTRATIO_XMAXYMID)
-            temp->translate(-logicX, -logicY - (logicHeight - physHeight * logicWidth / physWidth) / 2);
+            temp.translate(-logicX, -logicY - (logicHeight - physHeight * logicWidth / physWidth) / 2);
         else
-            temp->translate(-logicX, -logicY - (logicHeight - physHeight * logicWidth / physWidth));
+            temp.translate(-logicX, -logicY - (logicHeight - physHeight * logicWidth / physWidth));
     }
 
     return temp;
 }
 
+}
+
 // vim:ts=4:noet
 #endif // SVG_SUPPORT
-