* ksvg2/svg/SVGPreserveAspectRatio.cpp: Add a couple of comments.
[WebKit-https.git] / WebCore / ksvg2 / svg / SVGPreserveAspectRatio.cpp
index d7020ff..2968330 100644 (file)
 #ifdef SVG_SUPPORT
 #include "SVGPreserveAspectRatio.h"
 
-#include "SVGMatrix.h"
+#include "SVGParserUtilities.h"
 #include "SVGSVGElement.h"
 
 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>()
     , m_align(SVG_PRESERVEASPECTRATIO_XMIDYMID)
     , m_meetOrSlice(SVG_MEETORSLICE_MEET)
     , m_context(context)
 {
+    // FIXME: Should the two values default to UNKNOWN instead?
 }
 
 SVGPreserveAspectRatio::~SVGPreserveAspectRatio()
@@ -44,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
@@ -54,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
@@ -63,50 +78,114 @@ unsigned short SVGPreserveAspectRatio::meetOrSlice() const
 
 void SVGPreserveAspectRatio::parsePreserveAspectRatio(const String& string)
 {
-    // Spec: set the defaults
-    setAlign(SVG_PRESERVEASPECTRATIO_NONE);
-    setMeetOrSlice(SVG_MEETORSLICE_MEET);
-    
-    Vector<String> params = string.simplifyWhiteSpace().split(' ');
-
-    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.size() > 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;
@@ -115,26 +194,26 @@ SVGMatrix* SVGPreserveAspectRatio::getCTM(float logicX, float logicY,
     float svgar = physWidth / physHeight;
 
     if (align() == SVG_PRESERVEASPECTRATIO_NONE) {
-        temp->scaleNonUniform(physWidth / logicWidth, physHeight / logicHeight);
-        temp->translate(-logicX, -logicY);
+        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);
+        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);
+            temp.translate(-logicX - (logicWidth - physWidth * logicHeight / physHeight), -logicY);
     } else {
-        temp->scale(physWidth / logicWidth);
+        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;
@@ -144,4 +223,3 @@ SVGMatrix* SVGPreserveAspectRatio::getCTM(float logicX, float logicY,
 
 // vim:ts=4:noet
 #endif // SVG_SUPPORT
-