File indexing completed on 2024-04-28 15:24:32

0001 /*
0002     Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org>
0003                   2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
0004 
0005     This file is part of the KDE project
0006 
0007     This library is free software; you can redistribute it and/or
0008     modify it under the terms of the GNU Library General Public
0009     License as published by the Free Software Foundation; either
0010     version 2 of the License, or (at your option) any later version.
0011 
0012     This library is distributed in the hope that it will be useful,
0013     but WITHOUT ANY WARRANTY; without even the implied warranty of
0014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0015     Library General Public License for more details.
0016 
0017     You should have received a copy of the GNU Library General Public License
0018     along with this library; see the file COPYING.LIB.  If not, write to
0019     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0020     Boston, MA 02110-1301, USA.
0021 */
0022 
0023 #include "wtf/Platform.h"
0024 
0025 #if ENABLE(SVG)
0026 #include "SVGFitToViewBox.h"
0027 
0028 #include "AffineTransform.h"
0029 #include "FloatRect.h"
0030 #include "SVGDocumentExtensions.h"
0031 #include "SVGNames.h"
0032 #include "SVGParserUtilities.h"
0033 #include "SVGPreserveAspectRatio.h"
0034 //#include "StringImpl.h"
0035 
0036 namespace WebCore
0037 {
0038 
0039 SVGFitToViewBox::SVGFitToViewBox()
0040     : m_viewBox()
0041     , m_preserveAspectRatio(SVGPreserveAspectRatio::create())
0042 {
0043 }
0044 
0045 SVGFitToViewBox::~SVGFitToViewBox()
0046 {
0047 }
0048 
0049 ANIMATED_PROPERTY_DEFINITIONS_WITH_CONTEXT(SVGFitToViewBox, FloatRect, Rect, rect, ViewBox, viewBox, SVGNames::viewBoxAttr, m_viewBox)
0050 ANIMATED_PROPERTY_DEFINITIONS_WITH_CONTEXT(SVGFitToViewBox, SVGPreserveAspectRatio *, PreserveAspectRatio, preserveAspectRatio, PreserveAspectRatio, preserveAspectRatio, SVGNames::preserveAspectRatioAttr, m_preserveAspectRatio.get())
0051 
0052 bool SVGFitToViewBox::parseViewBox(const UChar *&c, const UChar *end, float &x, float &y, float &w, float &h, bool validate)
0053 {
0054     Document *doc = contextElement()->document();
0055     String str(c, end - c);
0056 
0057     skipOptionalSpaces(c, end);
0058 
0059     bool valid = (parseNumber(c, end, x) && parseNumber(c, end, y) &&
0060                   parseNumber(c, end, w) && parseNumber(c, end, h, false));
0061     if (!validate) {
0062         return true;
0063     }
0064     if (!valid) {
0065         //FIXME vtokarev doc->accessSVGExtensions()->reportWarning("Problem parsing viewBox=\"" + str + "\"");
0066         return false;
0067     }
0068 
0069     if (w < 0.0) { // check that width is positive
0070         doc->accessSVGExtensions()->reportError("A negative value for ViewBox width is not allowed");
0071         return false;
0072     } else if (h < 0.0) { // check that height is positive
0073         doc->accessSVGExtensions()->reportError("A negative value for ViewBox height is not allowed");
0074         return false;
0075     } else {
0076         skipOptionalSpaces(c, end);
0077         if (c < end) { // nothing should come after the last, fourth number
0078             //FIXME vtokarev doc->accessSVGExtensions()->reportWarning("Problem parsing viewBox=\"" + str + "\"");
0079             return false;
0080         }
0081     }
0082 
0083     return true;
0084 }
0085 
0086 AffineTransform SVGFitToViewBox::viewBoxToViewTransform(float viewWidth, float viewHeight) const
0087 {
0088     FloatRect viewBoxRect = viewBox();
0089     if (!viewBoxRect.width() || !viewBoxRect.height()) {
0090         return AffineTransform();
0091     }
0092 
0093     return preserveAspectRatio()->getCTM(viewBoxRect.x(),
0094                                          viewBoxRect.y(), viewBoxRect.width(), viewBoxRect.height(),
0095                                          0, 0, viewWidth, viewHeight);
0096 }
0097 
0098 bool SVGFitToViewBox::parseMappedAttribute(MappedAttribute *attr)
0099 {
0100     if (attr->name() == SVGNames::viewBoxAttr) {
0101         float x = 0.0f, y = 0.0f, w = 0.0f, h = 0.0f;
0102         const UChar *c = attr->value().characters();
0103         const UChar *end = c + attr->value().length();
0104         if (parseViewBox(c, end, x, y, w, h)) {
0105             setViewBoxBaseValue(FloatRect(x, y, w, h));
0106         }
0107         return true;
0108     } else if (attr->name() == SVGNames::preserveAspectRatioAttr) {
0109         const UChar *c = attr->value().characters();
0110         const UChar *end = c + attr->value().length();
0111         preserveAspectRatioBaseValue()->parsePreserveAspectRatio(c, end);
0112         return true;
0113     }
0114 
0115     return false;
0116 }
0117 
0118 bool SVGFitToViewBox::isKnownAttribute(const QualifiedName &attrName)
0119 {
0120     return (attrName == SVGNames::viewBoxAttr ||
0121             attrName == SVGNames::preserveAspectRatioAttr);
0122 }
0123 
0124 }
0125 
0126 #endif // ENABLE(SVG)