OSDN Git Service

Merge WebKit at r71558: Initial merge by git.
[android-x86/external-webkit.git] / WebCore / svg / SVGPreserveAspectRatio.cpp
index a129fe6..c9c452e 100644 (file)
@@ -25,8 +25,9 @@
 #include "SVGPreserveAspectRatio.h"
 
 #include "AffineTransform.h"
+#include "FloatRect.h"
 #include "SVGParserUtilities.h"
-#include "SVGSVGElement.h"
+#include <wtf/text/StringConcatenate.h>
 
 namespace WebCore {
 
@@ -34,27 +35,26 @@ SVGPreserveAspectRatio::SVGPreserveAspectRatio()
     : m_align(SVG_PRESERVEASPECTRATIO_XMIDYMID)
     , m_meetOrSlice(SVG_MEETORSLICE_MEET)
 {
-    // FIXME: Should the two values default to UNKNOWN instead?
 }
 
-void SVGPreserveAspectRatio::setAlign(unsigned short align)
+void SVGPreserveAspectRatio::setAlign(unsigned short align, ExceptionCode& ec)
 {
-    m_align = align;
-}
+    if (align == SVG_PRESERVEASPECTRATIO_UNKNOWN || align > SVG_PRESERVEASPECTRATIO_XMAXYMAX) {
+        ec = NOT_SUPPORTED_ERR;
+        return;
+    }
 
-unsigned short SVGPreserveAspectRatio::align() const
-{
-    return m_align;
+    m_align = static_cast<SVGPreserveAspectRatioType>(align);
 }
 
-void SVGPreserveAspectRatio::setMeetOrSlice(unsigned short meetOrSlice)
+void SVGPreserveAspectRatio::setMeetOrSlice(unsigned short meetOrSlice, ExceptionCode& ec)
 {
-    m_meetOrSlice = meetOrSlice;
-}
+    if (meetOrSlice == SVG_MEETORSLICE_UNKNOWN || meetOrSlice > SVG_MEETORSLICE_SLICE) {
+        ec = NOT_SUPPORTED_ERR;
+        return;
+    }
 
-unsigned short SVGPreserveAspectRatio::meetOrSlice() const
-{
-    return m_meetOrSlice;
+    m_meetOrSlice = static_cast<SVGMeetOrSliceType>(meetOrSlice);
 }
 
 SVGPreserveAspectRatio SVGPreserveAspectRatio::parsePreserveAspectRatio(const UChar*& currParam, const UChar* end, bool validate, bool& result)
@@ -64,6 +64,7 @@ SVGPreserveAspectRatio SVGPreserveAspectRatio::parsePreserveAspectRatio(const UC
     aspectRatio.m_meetOrSlice = SVG_MEETORSLICE_MEET;
     result = false;
 
+    // FIXME: Rewrite this parser, without gotos!
     if (!skipOptionalSpaces(currParam, end))
         goto bail_out;
 
@@ -160,167 +161,184 @@ void SVGPreserveAspectRatio::transformRect(FloatRect& destRect, FloatRect& srcRe
     FloatSize imageSize = srcRect.size();
     float origDestWidth = destRect.width();
     float origDestHeight = destRect.height();
-    if (meetOrSlice() == SVGPreserveAspectRatio::SVG_MEETORSLICE_MEET) {
+    switch (m_meetOrSlice) {
+    case SVGPreserveAspectRatio::SVG_MEETORSLICE_UNKNOWN:
+        break;
+    case SVGPreserveAspectRatio::SVG_MEETORSLICE_MEET:
+    {
         float widthToHeightMultiplier = srcRect.height() / srcRect.width();
-        if (origDestHeight > (origDestWidth * widthToHeightMultiplier)) {
+        if (origDestHeight > origDestWidth * widthToHeightMultiplier) {
             destRect.setHeight(origDestWidth * widthToHeightMultiplier);
-            switch (align()) {
+            switch (m_align) {
             case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMID:
             case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID:
             case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID:
-                destRect.setY(destRect.y() + origDestHeight / 2.0f - destRect.height() / 2.0f);
+                destRect.setY(destRect.y() + origDestHeight / 2 - destRect.height() / 2);
                 break;
             case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMAX:
             case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX:
             case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX:
                 destRect.setY(destRect.y() + origDestHeight - destRect.height());
                 break;
+            default:
+                break;
             }
         }
-        if (origDestWidth > (origDestHeight / widthToHeightMultiplier)) {
+        if (origDestWidth > origDestHeight / widthToHeightMultiplier) {
             destRect.setWidth(origDestHeight / widthToHeightMultiplier);
-            switch (align()) {
+            switch (m_align) {
             case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMIN:
             case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID:
             case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX:
-                destRect.setX(destRect.x() + origDestWidth / 2.0f - destRect.width() / 2.0f);
+                destRect.setX(destRect.x() + origDestWidth / 2 - destRect.width() / 2);
                 break;
             case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMIN:
             case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID:
             case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX:
                 destRect.setX(destRect.x() + origDestWidth - destRect.width());
                 break;
+            default:
+                break;
             }
         }
-    } else if (meetOrSlice() == SVGPreserveAspectRatio::SVG_MEETORSLICE_SLICE) {
+        break;
+    }
+    case SVGPreserveAspectRatio::SVG_MEETORSLICE_SLICE:
+    {
         float widthToHeightMultiplier = srcRect.height() / srcRect.width();
         // if the destination height is less than the height of the image we'll be drawing
-        if (origDestHeight < (origDestWidth * widthToHeightMultiplier)) {
+        if (origDestHeight < origDestWidth * widthToHeightMultiplier) {
             float destToSrcMultiplier = srcRect.width() / destRect.width();
             srcRect.setHeight(destRect.height() * destToSrcMultiplier);
-            switch (align()) {
+            switch (m_align) {
             case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMID:
             case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID:
             case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID:
-                srcRect.setY(destRect.y() + imageSize.height() / 2.0f - srcRect.height() / 2.0f);
+                srcRect.setY(destRect.y() + imageSize.height() / 2 - srcRect.height() / 2);
                 break;
             case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMAX:
             case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX:
             case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX:
                 srcRect.setY(destRect.y() + imageSize.height() - srcRect.height());
                 break;
+            default:
+                break;
             }
         }
         // if the destination width is less than the width of the image we'll be drawing
-        if (origDestWidth < (origDestHeight / widthToHeightMultiplier)) {
+        if (origDestWidth < origDestHeight / widthToHeightMultiplier) {
             float destToSrcMultiplier = srcRect.height() / destRect.height();
             srcRect.setWidth(destRect.width() * destToSrcMultiplier);
-            switch (align()) {
+            switch (m_align) {
             case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMIN:
             case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID:
             case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX:
-                srcRect.setX(destRect.x() + imageSize.width() / 2.0f - srcRect.width() / 2.0f);
+                srcRect.setX(destRect.x() + imageSize.width() / 2 - srcRect.width() / 2);
                 break;
             case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMIN:
             case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID:
             case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX:
                 srcRect.setX(destRect.x() + imageSize.width() - srcRect.width());
                 break;
+            default:
+                break;
             }
         }
+        break;
+    }
     }
 }
 
-AffineTransform SVGPreserveAspectRatio::getCTM(double logicX, double logicY,
-                                               double logicWidth, double logicHeight,
-                                               double /*physX*/, double /*physY*/,
-                                               double physWidth, double physHeight) const
+// FIXME: We should use floats here, like everywhere else!
+AffineTransform SVGPreserveAspectRatio::getCTM(double logicX, double logicY, double logicWidth, double logicHeight, double physWidth, double physHeight) const
 {
-    AffineTransform temp;
+    AffineTransform transform;
+    if (m_align == SVG_PRESERVEASPECTRATIO_UNKNOWN)
+        return transform;
 
-    if (align() == SVG_PRESERVEASPECTRATIO_UNKNOWN)
-        return temp;
+    double logicalRatio = logicWidth / logicHeight;
+    double physRatio = physWidth / physHeight;
 
-    double vpar = logicWidth / logicHeight;
-    double svgar = physWidth / physHeight;
+    if (m_align == SVG_PRESERVEASPECTRATIO_NONE) {
+        transform.scaleNonUniform(physWidth / logicWidth, physHeight / logicHeight);
+        transform.translate(-logicX, -logicY);
+        return transform;
+    }
 
-    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.scaleNonUniform(physHeight / logicHeight, physHeight / logicHeight);
+    if ((logicalRatio < physRatio && (m_meetOrSlice == SVG_MEETORSLICE_MEET)) || (logicalRatio >= physRatio && (m_meetOrSlice == SVG_MEETORSLICE_SLICE))) {
+        transform.scaleNonUniform(physHeight / logicHeight, physHeight / logicHeight);
 
-        if (align() == SVG_PRESERVEASPECTRATIO_XMINYMIN || align() == SVG_PRESERVEASPECTRATIO_XMINYMID || align() == SVG_PRESERVEASPECTRATIO_XMINYMAX)
-            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);
+        if (m_align == SVG_PRESERVEASPECTRATIO_XMINYMIN || m_align == SVG_PRESERVEASPECTRATIO_XMINYMID || m_align == SVG_PRESERVEASPECTRATIO_XMINYMAX)
+            transform.translate(-logicX, -logicY);
+        else if (m_align == SVG_PRESERVEASPECTRATIO_XMIDYMIN || m_align == SVG_PRESERVEASPECTRATIO_XMIDYMID || m_align == SVG_PRESERVEASPECTRATIO_XMIDYMAX)
+            transform.translate(-logicX - (logicWidth - physWidth * logicHeight / physHeight) / 2, -logicY);
         else
-            temp.translate(-logicX - (logicWidth - physWidth * logicHeight / physHeight), -logicY);
-    } else {
-        temp.scaleNonUniform(physWidth / logicWidth, physWidth / logicWidth);
-
-        if (align() == SVG_PRESERVEASPECTRATIO_XMINYMIN || align() == SVG_PRESERVEASPECTRATIO_XMIDYMIN || align() == SVG_PRESERVEASPECTRATIO_XMAXYMIN)
-            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);
-        else
-            temp.translate(-logicX, -logicY - (logicHeight - physHeight * logicWidth / physWidth));
+            transform.translate(-logicX - (logicWidth - physWidth * logicHeight / physHeight), -logicY);
+        
+        return transform;
     }
 
-    return temp;
+    transform.scaleNonUniform(physWidth / logicWidth, physWidth / logicWidth);
+
+    if (m_align == SVG_PRESERVEASPECTRATIO_XMINYMIN || m_align == SVG_PRESERVEASPECTRATIO_XMIDYMIN || m_align == SVG_PRESERVEASPECTRATIO_XMAXYMIN)
+        transform.translate(-logicX, -logicY);
+    else if (m_align == SVG_PRESERVEASPECTRATIO_XMINYMID || m_align == SVG_PRESERVEASPECTRATIO_XMIDYMID || m_align == SVG_PRESERVEASPECTRATIO_XMAXYMID)
+        transform.translate(-logicX, -logicY - (logicHeight - physHeight * logicWidth / physWidth) / 2);
+    else
+        transform.translate(-logicX, -logicY - (logicHeight - physHeight * logicWidth / physWidth));
+
+    return transform;
 }
 
 String SVGPreserveAspectRatio::valueAsString() const
 {
-    String result;
+    String alignType;
 
-    switch ((SVGPreserveAspectRatioType) align()) {
-    default:
+    switch (m_align) {
     case SVG_PRESERVEASPECTRATIO_NONE:
-        result = "none";
+        alignType = "none";
         break;
     case SVG_PRESERVEASPECTRATIO_XMINYMIN:
-        result = "xMinYMin";
+        alignType = "xMinYMin";
         break;
     case SVG_PRESERVEASPECTRATIO_XMIDYMIN:
-        result = "xMidYMin";
+        alignType = "xMidYMin";
         break;
     case SVG_PRESERVEASPECTRATIO_XMAXYMIN:
-        result = "xMaxYMin";
+        alignType = "xMaxYMin";
         break;
     case SVG_PRESERVEASPECTRATIO_XMINYMID:
-        result = "xMinYMid";
+        alignType = "xMinYMid";
         break;
     case SVG_PRESERVEASPECTRATIO_XMIDYMID:
-        result = "xMidYMid";
+        alignType = "xMidYMid";
         break;
     case SVG_PRESERVEASPECTRATIO_XMAXYMID:
-        result = "xMaxYMid";
+        alignType = "xMaxYMid";
         break;
     case SVG_PRESERVEASPECTRATIO_XMINYMAX:
-        result = "xMinYMax";
+        alignType = "xMinYMax";
         break;
     case SVG_PRESERVEASPECTRATIO_XMIDYMAX:
-        result = "xMidYMax";
+        alignType = "xMidYMax";
         break;
     case SVG_PRESERVEASPECTRATIO_XMAXYMAX:
-        result = "xMaxYMax";
+        alignType = "xMaxYMax";
+        break;
+    case SVG_PRESERVEASPECTRATIO_UNKNOWN:
+        alignType = "unknown";
         break;
     };
 
-    switch ((SVGMeetOrSliceType) meetOrSlice()) {
+    switch (m_meetOrSlice) {
     default:
     case SVG_MEETORSLICE_UNKNOWN:
-        break;
+        return alignType;
     case SVG_MEETORSLICE_MEET:
-        result += " meet";
-        break;
+        return makeString(alignType, " meet");
     case SVG_MEETORSLICE_SLICE:
-        result += " slice";
-        break;
+        return makeString(alignType, " slice");
     };
-
-    return result;
 }
 
 }