Home | History | Annotate | Download | only in svg
      1 /*
      2  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
      3  *
      4  * This library is free software; you can redistribute it and/or
      5  * modify it under the terms of the GNU Library General Public
      6  * License as published by the Free Software Foundation; either
      7  * version 2 of the License, or (at your option) any later version.
      8  *
      9  * This library is distributed in the hope that it will be useful,
     10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     12  * Library General Public License for more details.
     13  *
     14  * You should have received a copy of the GNU Library General Public License
     15  * along with this library; see the file COPYING.LIB.  If not, write to
     16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     17  * Boston, MA 02110-1301, USA.
     18  */
     19 
     20 #include "config.h"
     21 
     22 #if ENABLE(SVG)
     23 #include "SVGPathParserFactory.h"
     24 
     25 #include "PathTraversalState.h"
     26 #include "SVGPathBlender.h"
     27 #include "SVGPathBuilder.h"
     28 #include "SVGPathByteStreamBuilder.h"
     29 #include "SVGPathByteStreamSource.h"
     30 #include "SVGPathElement.h"
     31 #include "SVGPathParser.h"
     32 #include "SVGPathSegListBuilder.h"
     33 #include "SVGPathSegListSource.h"
     34 #include "SVGPathStringBuilder.h"
     35 #include "SVGPathStringSource.h"
     36 #include "SVGPathTraversalStateBuilder.h"
     37 
     38 namespace WebCore {
     39 
     40 static SVGPathBuilder* globalSVGPathBuilder(Path& result)
     41 {
     42     static SVGPathBuilder* s_builder = 0;
     43     if (!s_builder)
     44         s_builder = new SVGPathBuilder;
     45 
     46     s_builder->setCurrentPath(&result);
     47     return s_builder;
     48 }
     49 
     50 static SVGPathSegListBuilder* globalSVGPathSegListBuilder(SVGPathElement* element, SVGPathSegRole role, SVGPathSegList& result)
     51 {
     52     static SVGPathSegListBuilder* s_builder = 0;
     53     if (!s_builder)
     54         s_builder = new SVGPathSegListBuilder;
     55 
     56     s_builder->setCurrentSVGPathElement(element);
     57     s_builder->setCurrentSVGPathSegList(result);
     58     s_builder->setCurrentSVGPathSegRole(role);
     59     return s_builder;
     60 }
     61 
     62 static SVGPathByteStreamBuilder* globalSVGPathByteStreamBuilder(SVGPathByteStream* result)
     63 {
     64     static SVGPathByteStreamBuilder* s_builder = 0;
     65     if (!s_builder)
     66         s_builder = new SVGPathByteStreamBuilder;
     67 
     68     s_builder->setCurrentByteStream(result);
     69     return s_builder;
     70 }
     71 
     72 static SVGPathStringBuilder* globalSVGPathStringBuilder()
     73 {
     74     static SVGPathStringBuilder* s_builder = 0;
     75     if (!s_builder)
     76         s_builder = new SVGPathStringBuilder;
     77 
     78     return s_builder;
     79 }
     80 
     81 static SVGPathTraversalStateBuilder* globalSVGPathTraversalStateBuilder(PathTraversalState& traversalState, float length)
     82 {
     83     static SVGPathTraversalStateBuilder* s_builder = 0;
     84     if (!s_builder)
     85         s_builder = new SVGPathTraversalStateBuilder;
     86 
     87     s_builder->setCurrentTraversalState(&traversalState);
     88     s_builder->setDesiredLength(length);
     89     return s_builder;
     90 }
     91 
     92 static SVGPathParser* globalSVGPathParser(SVGPathSource* source, SVGPathConsumer* consumer)
     93 {
     94     static SVGPathParser* s_parser = 0;
     95     if (!s_parser)
     96         s_parser = new SVGPathParser;
     97 
     98     s_parser->setCurrentSource(source);
     99     s_parser->setCurrentConsumer(consumer);
    100     return s_parser;
    101 }
    102 
    103 static SVGPathBlender* globalSVGPathBlender()
    104 {
    105     static SVGPathBlender* s_blender = 0;
    106     if (!s_blender)
    107         s_blender = new SVGPathBlender;
    108 
    109     return s_blender;
    110 }
    111 
    112 SVGPathParserFactory* SVGPathParserFactory::self()
    113 {
    114     static SVGPathParserFactory* s_instance = 0;
    115     if (!s_instance)
    116         s_instance = new SVGPathParserFactory;
    117 
    118     return s_instance;
    119 }
    120 
    121 SVGPathParserFactory::SVGPathParserFactory()
    122 {
    123 }
    124 
    125 SVGPathParserFactory::~SVGPathParserFactory()
    126 {
    127 }
    128 
    129 bool SVGPathParserFactory::buildPathFromString(const String& d, Path& result)
    130 {
    131     if (d.isEmpty())
    132         return false;
    133 
    134     SVGPathBuilder* builder = globalSVGPathBuilder(result);
    135 
    136     OwnPtr<SVGPathStringSource> source = SVGPathStringSource::create(d);
    137     SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
    138     bool ok = parser->parsePathDataFromSource(NormalizedParsing);
    139     parser->cleanup();
    140     return ok;
    141 }
    142 
    143 bool SVGPathParserFactory::buildSVGPathByteStreamFromSVGPathSegList(const SVGPathSegList& list, OwnPtr<SVGPathByteStream>& result, PathParsingMode parsingMode)
    144 {
    145     result = SVGPathByteStream::create();
    146     if (list.isEmpty())
    147         return false;
    148 
    149     SVGPathByteStreamBuilder* builder = globalSVGPathByteStreamBuilder(result.get());
    150 
    151     OwnPtr<SVGPathSegListSource> source = SVGPathSegListSource::create(list);
    152     SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
    153     bool ok = parser->parsePathDataFromSource(parsingMode);
    154     parser->cleanup();
    155     return ok;
    156 }
    157 
    158 bool SVGPathParserFactory::buildPathFromByteStream(SVGPathByteStream* stream, Path& result)
    159 {
    160     ASSERT(stream);
    161     if (stream->isEmpty())
    162         return false;
    163 
    164     SVGPathBuilder* builder = globalSVGPathBuilder(result);
    165 
    166     OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream);
    167     SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
    168     bool ok = parser->parsePathDataFromSource(NormalizedParsing);
    169     parser->cleanup();
    170     return ok;
    171 }
    172 
    173 bool SVGPathParserFactory::buildSVGPathSegListFromByteStream(SVGPathByteStream* stream, SVGPathElement* element, SVGPathSegList& result, PathParsingMode parsingMode)
    174 {
    175     ASSERT(stream);
    176     if (stream->isEmpty())
    177         return false;
    178 
    179     SVGPathSegListBuilder* builder = globalSVGPathSegListBuilder(element, parsingMode == NormalizedParsing ? PathSegNormalizedRole : PathSegUnalteredRole, result);
    180 
    181     OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream);
    182     SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
    183     bool ok = parser->parsePathDataFromSource(parsingMode);
    184     parser->cleanup();
    185     return ok;
    186 }
    187 
    188 bool SVGPathParserFactory::buildStringFromByteStream(SVGPathByteStream* stream, String& result, PathParsingMode parsingMode)
    189 {
    190     ASSERT(stream);
    191     if (stream->isEmpty())
    192         return false;
    193 
    194     SVGPathStringBuilder* builder = globalSVGPathStringBuilder();
    195 
    196     OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream);
    197     SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
    198     bool ok = parser->parsePathDataFromSource(parsingMode);
    199     result = builder->result();
    200     parser->cleanup();
    201     return ok;
    202 }
    203 
    204 bool SVGPathParserFactory::buildStringFromSVGPathSegList(const SVGPathSegList& list, String& result, PathParsingMode parsingMode)
    205 {
    206     result = String();
    207     if (list.isEmpty())
    208         return false;
    209 
    210     SVGPathStringBuilder* builder = globalSVGPathStringBuilder();
    211 
    212     OwnPtr<SVGPathSegListSource> source = SVGPathSegListSource::create(list);
    213     SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
    214     bool ok = parser->parsePathDataFromSource(parsingMode);
    215     result = builder->result();
    216     parser->cleanup();
    217     return ok;
    218 }
    219 
    220 bool SVGPathParserFactory::buildSVGPathByteStreamFromString(const String& d, OwnPtr<SVGPathByteStream>& result, PathParsingMode parsingMode)
    221 {
    222     result = SVGPathByteStream::create();
    223     if (d.isEmpty())
    224         return false;
    225 
    226     SVGPathByteStreamBuilder* builder = globalSVGPathByteStreamBuilder(result.get());
    227 
    228     OwnPtr<SVGPathStringSource> source = SVGPathStringSource::create(d);
    229     SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
    230     bool ok = parser->parsePathDataFromSource(parsingMode);
    231     parser->cleanup();
    232     return ok;
    233 }
    234 
    235 bool SVGPathParserFactory::buildAnimatedSVGPathByteStream(SVGPathByteStream* fromStream, SVGPathByteStream* toStream, OwnPtr<SVGPathByteStream>& result, float progress)
    236 {
    237     ASSERT(fromStream);
    238     ASSERT(toStream);
    239     result = SVGPathByteStream::create();
    240     if (fromStream->isEmpty() || toStream->isEmpty())
    241         return false;
    242 
    243     SVGPathByteStreamBuilder* builder = globalSVGPathByteStreamBuilder(result.get());
    244 
    245     OwnPtr<SVGPathByteStreamSource> fromSource = SVGPathByteStreamSource::create(fromStream);
    246     OwnPtr<SVGPathByteStreamSource> toSource = SVGPathByteStreamSource::create(toStream);
    247     SVGPathBlender* blender = globalSVGPathBlender();
    248     bool ok = blender->blendAnimatedPath(progress, fromSource.get(), toSource.get(), builder);
    249     blender->cleanup();
    250     return ok;
    251 }
    252 
    253 bool SVGPathParserFactory::getSVGPathSegAtLengthFromSVGPathByteStream(SVGPathByteStream* stream, float length, unsigned long& pathSeg)
    254 {
    255     ASSERT(stream);
    256     if (stream->isEmpty())
    257         return false;
    258 
    259     PathTraversalState traversalState(PathTraversalState::TraversalSegmentAtLength);
    260     SVGPathTraversalStateBuilder* builder = globalSVGPathTraversalStateBuilder(traversalState, length);
    261 
    262     OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream);
    263     SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
    264     bool ok = parser->parsePathDataFromSource(NormalizedParsing);
    265     pathSeg = builder->pathSegmentIndex();
    266     parser->cleanup();
    267     return ok;
    268 }
    269 
    270 }
    271 
    272 #endif
    273