Home | History | Annotate | Download | only in svg
      1 /*
      2  * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann (at) kde.org>
      3  * Copyright (C) 2004, 2005, 2006, 2007, 2010 Rob Buis <buis (at) kde.org>
      4  *
      5  * This library is free software; you can redistribute it and/or
      6  * modify it under the terms of the GNU Library General Public
      7  * License as published by the Free Software Foundation; either
      8  * version 2 of the License, or (at your option) any later version.
      9  *
     10  * This library is distributed in the hope that it will be useful,
     11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13  * Library General Public License for more details.
     14  *
     15  * You should have received a copy of the GNU Library General Public License
     16  * along with this library; see the file COPYING.LIB.  If not, write to
     17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     18  * Boston, MA 02110-1301, USA.
     19  */
     20 
     21 #include "config.h"
     22 
     23 #include "core/svg/SVGFitToViewBox.h"
     24 
     25 #include "core/dom/Attribute.h"
     26 #include "core/dom/Document.h"
     27 #include "core/svg/SVGDocumentExtensions.h"
     28 #include "core/svg/SVGParserUtilities.h"
     29 #include "platform/geometry/FloatRect.h"
     30 #include "platform/transforms/AffineTransform.h"
     31 #include "wtf/text/StringImpl.h"
     32 
     33 namespace WebCore {
     34 
     35 template<typename CharType>
     36 static bool parseViewBoxInternal(Document* document, const CharType*& ptr, const CharType* end, FloatRect& viewBox, bool validate)
     37 {
     38     const CharType* start = ptr;
     39 
     40     skipOptionalSVGSpaces(ptr, end);
     41 
     42     float x = 0.0f;
     43     float y = 0.0f;
     44     float width = 0.0f;
     45     float height = 0.0f;
     46     bool valid = parseNumber(ptr, end, x) && parseNumber(ptr, end, y) && parseNumber(ptr, end, width) && parseNumber(ptr, end, height, false);
     47     if (!validate) {
     48         viewBox = FloatRect(x, y, width, height);
     49         return true;
     50     }
     51     if (!valid) {
     52         document->accessSVGExtensions()->reportWarning("Problem parsing viewBox=\"" + String(start, end - start) + "\"");
     53         return false;
     54     }
     55 
     56     if (width < 0.0) { // check that width is positive
     57         document->accessSVGExtensions()->reportError("A negative value for ViewBox width is not allowed");
     58         return false;
     59     }
     60     if (height < 0.0) { // check that height is positive
     61         document->accessSVGExtensions()->reportError("A negative value for ViewBox height is not allowed");
     62         return false;
     63     }
     64     skipOptionalSVGSpaces(ptr, end);
     65     if (ptr < end) { // nothing should come after the last, fourth number
     66         document->accessSVGExtensions()->reportWarning("Problem parsing viewBox=\"" + String(start, end - start) + "\"");
     67         return false;
     68     }
     69 
     70     viewBox = FloatRect(x, y, width, height);
     71     return true;
     72 }
     73 
     74 bool SVGFitToViewBox::parseViewBox(Document* document, const LChar*& ptr, const LChar* end, FloatRect& viewBox, bool validate)
     75 {
     76     return parseViewBoxInternal(document, ptr, end, viewBox, validate);
     77 }
     78 
     79 bool SVGFitToViewBox::parseViewBox(Document* document, const UChar*& ptr, const UChar* end, FloatRect& viewBox, bool validate)
     80 {
     81     return parseViewBoxInternal(document, ptr, end, viewBox, validate);
     82 }
     83 
     84 bool SVGFitToViewBox::parseViewBox(Document* document, const String& string, FloatRect& viewBox)
     85 {
     86     if (string.isEmpty()) {
     87         const LChar* ptr = 0;
     88         return parseViewBoxInternal<LChar>(document, ptr, ptr, viewBox, true);
     89     }
     90     if (string.is8Bit()) {
     91         const LChar* ptr = string.characters8();
     92         const LChar* end = ptr + string.length();
     93         return parseViewBox(document, ptr, end, viewBox, true);
     94     }
     95     const UChar* ptr = string.characters16();
     96     const UChar* end = ptr + string.length();
     97     return parseViewBox(document, ptr, end, viewBox, true);
     98 }
     99 
    100 AffineTransform SVGFitToViewBox::viewBoxToViewTransform(const FloatRect& viewBoxRect, const SVGPreserveAspectRatio& preserveAspectRatio, float viewWidth, float viewHeight)
    101 {
    102     if (!viewBoxRect.width() || !viewBoxRect.height())
    103         return AffineTransform();
    104 
    105     return preserveAspectRatio.getCTM(viewBoxRect.x(), viewBoxRect.y(), viewBoxRect.width(), viewBoxRect.height(), viewWidth, viewHeight);
    106 }
    107 
    108 bool SVGFitToViewBox::isKnownAttribute(const QualifiedName& attrName)
    109 {
    110     return attrName == SVGNames::viewBoxAttr || attrName == SVGNames::preserveAspectRatioAttr;
    111 }
    112 
    113 void SVGFitToViewBox::addSupportedAttributes(HashSet<QualifiedName>& supportedAttributes)
    114 {
    115     supportedAttributes.add(SVGNames::viewBoxAttr);
    116     supportedAttributes.add(SVGNames::preserveAspectRatioAttr);
    117 }
    118 
    119 }
    120