Merge branch 'master' into nikitakit_master
[synfig.git] / synfig-core / src / modules / mod_svg / svg_parser.cpp
index 28b2c60..18e66b4 100644 (file)
@@ -32,6 +32,7 @@
 #endif
 
 #include <iostream>
+#include <cstring>
 #include "svg_parser.h"
 
 /* === U S I N G =========================================================== */
@@ -279,18 +280,14 @@ Svg_parser::parser_graphics(const xmlpp::Node* node,xmlpp::Element* root,String
                        typeStroke=2;   //gradient
                }
                
-               xmlpp::Element* child_layer = nodeStartBasicLayer(root->add_child("layer"));
-               xmlpp::Element* child_fill = child_layer;
-               xmlpp::Element* child_stroke = child_layer;
-               if(typeFill==2){
-                       child_fill=nodeStartBasicLayer(child_fill->add_child("layer"));
-               }
-               if(typeStroke==2){
-                       child_stroke=nodeStartBasicLayer(child_stroke->add_child("layer"));
-               }
+               xmlpp::Element* child_layer = root;
+               xmlpp::Element* child_fill;
+               xmlpp::Element* child_stroke;
 
                //make simple fills
                if(nodename.compare("rect")==0 && typeFill!=0){
+                       if (mtx) child_layer = nodeStartBasicLayer(root->add_child("layer"), id);
+                       child_fill=child_layer;
                        parser_rect(nodeElement,child_fill,fill,fill_opacity,opacity);
                        if(typeFill==2){
                                build_fill (child_fill,fill,NULL);
@@ -298,13 +295,17 @@ Svg_parser::parser_graphics(const xmlpp::Node* node,xmlpp::Element* root,String
                        parser_effects(nodeElement,child_layer,parent_style,mtx);
                        return;
                }
-
+               if ((!(SVG_RESOLVE_BLINE) && mtx) || typeFill==2 || typeStroke==2)
+                       child_layer = nodeStartBasicLayer(root->add_child("layer"), id);
+               child_fill=child_layer;
+               child_stroke=child_layer;
 
                //=======================================================================
-               std::list<std::list<Vertice*> > k;
+
+               std::list<BLine*> k;
                //if we are creating a bline
 
-               //First, create the list of vertices
+               //First, create the list of Verteces
                if (SVG_RESOLVE_BLINE) {
                        if(nodename.compare("path")==0){
                                k=parser_path_d (nodeElement->get_attribute_value("d"),mtx);
@@ -319,17 +320,14 @@ Svg_parser::parser_graphics(const xmlpp::Node* node,xmlpp::Element* root,String
                        }
                }
                
-               int n = k.size();
-               String bline_id[n];
-               String offset_id[n];
-               for (int i=0;i<n;i++){
-                       bline_id[i]=new_guid();
-                       offset_id[i]=new_guid();
-               }
+               std::list<BLine *>::iterator aux;               
+               //int n = k.size();
 
-               std::list<std::list<Vertice*> >::iterator aux = k.begin();
                if(typeFill!=0){//region layer
-                       for (int i=0; aux!=k.end(); aux++){
+                       /*if(typeFill==2){
+                               child_fill=nodeStartBasicLayer(child_fill->add_child("layer"));
+                       }*/
+                       for (aux = k.begin(); aux!=k.end(); aux++){
                                xmlpp::Element *child_region=child_fill->add_child("layer");
                                child_region->set_attribute("type","region");
                                child_region->set_attribute("active","true");
@@ -339,7 +337,7 @@ Svg_parser::parser_graphics(const xmlpp::Node* node,xmlpp::Element* root,String
                                build_param (child_region->add_child("param"),"amount","real","1.0000000000");
                                build_param (child_region->add_child("param"),"blend_method","integer","0");
                                build_color (child_region->add_child("param"),getRed(fill),getGreen(fill),getBlue(fill),atof(fill_opacity.data())*atof(opacity.data()));
-                               build_vector (child_region->add_child("param"),"offset",0,0,offset_id[i]);
+                               build_vector (child_region->add_child("param"),"offset",0,0, *(*aux)->offset_id );
                                build_param (child_region->add_child("param"),"invert","bool","false");
                                build_param (child_region->add_child("param"),"antialias","bool","true");
                                build_param (child_region->add_child("param"),"feather","real","0.0000000000");
@@ -347,8 +345,7 @@ Svg_parser::parser_graphics(const xmlpp::Node* node,xmlpp::Element* root,String
                                if(fill_rule.compare("evenodd")==0) build_param (child_region->add_child("param"),"winding_style","integer","1");
                                else build_param (child_region->add_child("param"),"winding_style","integer","0");
 
-                               build_bline (child_region->add_child("param"),*aux,loop,bline_id[i]);
-                               i++;
+                               build_bline (child_region->add_child("param"),*(*aux)->points,(*aux)->loop,*(*aux)->bline_id); 
                        }
                }
                if(typeFill==2){ //gradient in onto mode (fill)
@@ -359,7 +356,9 @@ Svg_parser::parser_graphics(const xmlpp::Node* node,xmlpp::Element* root,String
                }
 
                if(typeStroke!=0){//outline layer
-                       int i=0;
+                       if(typeStroke==2){
+                               child_stroke=nodeStartBasicLayer(child_stroke->add_child("layer"),"stroke");
+                       }
                        for (aux=k.begin(); aux!=k.end(); aux++){
                                xmlpp::Element *child_outline=child_stroke->add_child("layer");
                                child_outline->set_attribute("type","outline");
@@ -370,7 +369,7 @@ Svg_parser::parser_graphics(const xmlpp::Node* node,xmlpp::Element* root,String
                                build_param (child_outline->add_child("param"),"amount","real","1.0000000000");
                                build_param (child_outline->add_child("param"),"blend_method","integer","0");
                                build_color (child_outline->add_child("param"),getRed(stroke),getGreen(stroke),getBlue(stroke),atof(stroke_opacity.data())*atof(opacity.data()));
-                               build_vector (child_outline->add_child("param"),"offset",0,0,offset_id[i]);
+                               build_vector (child_outline->add_child("param"),"offset",0,0,*(*aux)->offset_id);
                                build_param (child_outline->add_child("param"),"invert","bool","false");
                                build_param (child_outline->add_child("param"),"antialias","bool","true");
                                build_param (child_outline->add_child("param"),"feather","real","0.0000000000");
@@ -378,7 +377,7 @@ Svg_parser::parser_graphics(const xmlpp::Node* node,xmlpp::Element* root,String
                                //outline in nonzero
                                build_param (child_outline->add_child("param"),"winding_style","integer","0");
 
-                               build_bline (child_outline->add_child("param"),*aux,loop,bline_id[i]);
+                               build_bline (child_outline->add_child("param"),*(*aux)->points,(*aux)->loop,*(*aux)->bline_id);
 
                                stroke_width=etl::strprintf("%f",getDimension(stroke_width)/kux);
                                build_param (child_outline->add_child("param"),"width","real",stroke_width);
@@ -394,23 +393,20 @@ Svg_parser::parser_graphics(const xmlpp::Node* node,xmlpp::Element* root,String
                                }
                                build_param (child_outline->add_child("param"),"loopyness","real","1.0000000000");
                                build_param (child_outline->add_child("param"),"homogeneous_width","bool","true");
-
-
-                               i++;
                        }
 
                        if(typeStroke==2){ //gradient in onto mode (stroke)
-                       if (SVG_RESOLVE_BLINE)
-                               build_fill(child_stroke,fill,mtx);
-                       else
-                               build_fill(child_stroke,fill,NULL);
-                       }
-                       if (SVG_RESOLVE_BLINE)
-                               parser_effects(nodeElement,child_layer,parent_style,NULL);
-                       else
-                               parser_effects(nodeElement,child_layer,parent_style,mtx);
-               
+                               if (SVG_RESOLVE_BLINE)
+                                       build_fill(child_stroke,stroke,mtx);
+                               else
+                                       build_fill(child_stroke,stroke,NULL);
+                       }       
                }
+
+               if (SVG_RESOLVE_BLINE)
+                       parser_effects(nodeElement,child_layer,parent_style,NULL);
+               else
+                       parser_effects(nodeElement,child_layer,parent_style,mtx);
        }
 }
 
@@ -495,12 +491,12 @@ Svg_parser::parser_rect(const xmlpp::Element* nodeElement,xmlpp::Element* root,S
 
 /* === CONVERT TO PATH PARSERS ============================================= */       
 
-std::list<std::list<Vertice*> >
+std::list<BLine *>
 Svg_parser::parser_path_polygon(Glib::ustring polygon_points, Matrix* mtx){
-       std::list<std::list<Vertice*> > k0;
+       std::list<BLine *> k0;
        if(polygon_points.empty())
                return k0;
-       std::list<Vertice*> k;
+       std::list<Vertex*> points;
        std::vector<String> tokens=get_tokens_path (polygon_points);
        unsigned int i;
        float ax,ay; ax=ay=0;
@@ -513,16 +509,17 @@ Svg_parser::parser_path_polygon(Glib::ustring polygon_points, Matrix* mtx){
                //adjust
                coor2vect(&ax,&ay);
                //save
-               k.push_back(newVertice(ax,ay));
+               points.push_back(newVertex(ax,ay));
        }
-       k0.push_front(k);
+       k0.push_front(newBLine(&points, true));
        return k0;
 }
 
-std::list<std::list<Vertice*> >
+std::list<BLine *>
 Svg_parser::parser_path_d(String path_d,Matrix* mtx){
-       std::list<std::list<Vertice*> > k;
-       std::list<Vertice*> k1;
+       std::list<BLine *> k;
+       std::list<Vertex*> k1;
+
        std::vector<String> tokens=get_tokens_path(path_d);
        String command="M"; //the current command
        float ax,ay,tgx,tgy,tgx2,tgy2;//each method
@@ -530,7 +527,6 @@ Svg_parser::parser_path_d(String path_d,Matrix* mtx){
        float actual_x=0,actual_y=0; //in svg coordinate space
        float old_x=0,old_y=0; //needed in rare cases
        float init_x=0,init_y=0; //for closepath commands
-       loop=false;
 
        for(unsigned int i=0;i<tokens.size();i++){
                //if the token is a command, change the current command
@@ -549,9 +545,10 @@ Svg_parser::parser_path_d(String path_d,Matrix* mtx){
 
                //now parse the commands
                if(command.compare("M")==0 || command.compare("m")==0){ //move to
-                       if(!k1.empty())
-                               k.push_front(k1);
-                       k1.clear();
+                       if(!k1.empty()) {
+                               k.push_front(newBLine(&k1, false));
+                               k1.clear();
+                       }
                        //read
                        actual_x+=atof(tokens.at(i).data());
                        i++; if(tokens.at(i).compare(",")==0) i++;
@@ -564,7 +561,7 @@ Svg_parser::parser_path_d(String path_d,Matrix* mtx){
                        //operate and save
                        if(mtx) transformPoint2D(mtx,&ax,&ay);
                        coor2vect(&ax,&ay);
-                       k1.push_back(newVertice (ax,ay)); //first element
+                       k1.push_back(newVertex (ax,ay)); //first element
                        setSplit(k1.back(),TRUE);
                        //"If a moveto is followed by multiple pairs of coordinates,
                        // the subsequent pairs are treated as implicit lineto commands."
@@ -603,7 +600,7 @@ Svg_parser::parser_path_d(String path_d,Matrix* mtx){
                        if(isFirst(k1.front(),ax,ay)){
                                setTg1(k1.front(),k1.front()->x,k1.front()->y,tgx,tgy);
                        }else{
-                               k1.push_back(newVertice (ax,ay));
+                               k1.push_back(newVertex (ax,ay));
                                setTg1(k1.back(),k1.back()->x,k1.back()->y,tgx,tgy);
                                setSplit(k1.back(),TRUE);
                        }
@@ -630,7 +627,7 @@ Svg_parser::parser_path_d(String path_d,Matrix* mtx){
                        //save
                        setTg1(k1.back(),k1.back()->x,k1.back()->y,tgx,tgy);
                        setSplit(k1.back(),FALSE);
-                       k1.push_back(newVertice (ax,ay));
+                       k1.push_back(newVertex (ax,ay));
                        setTg1(k1.back(),k1.back()->x,k1.back()->y,tgx,tgy);
                }else if(command.compare("L")==0 || command.compare("l")==0){ //line to
                        //point
@@ -649,7 +646,7 @@ Svg_parser::parser_path_d(String path_d,Matrix* mtx){
                        if(isFirst(k1.front(),ax,ay)){
                                setTg1(k1.front(),k1.front()->x,k1.front()->y,k1.front()->x,k1.front()->y);
                        }else{
-                               k1.push_back(newVertice(ax,ay));
+                               k1.push_back(newVertex(ax,ay));
                                setTg1(k1.back(),k1.back()->x,k1.back()->y,k1.back()->x,k1.back()->y);
                        }
                }else if(command.compare("H")==0 || command.compare("h")==0){// horizontal move
@@ -668,7 +665,7 @@ Svg_parser::parser_path_d(String path_d,Matrix* mtx){
                        if(isFirst(k1.front(),ax,ay)){
                                setTg1(k1.front(),k1.front()->x,k1.front()->y,k1.front()->x,k1.front()->y);
                        }else{
-                               k1.push_back(newVertice(ax,ay));
+                               k1.push_back(newVertex(ax,ay));
                                setTg1(k1.back(),k1.back()->x,k1.back()->y,k1.back()->x,k1.back()->y);
                        }
                }else if(command.compare("V")==0 || command.compare("v")==0){//vertical
@@ -686,7 +683,7 @@ Svg_parser::parser_path_d(String path_d,Matrix* mtx){
                        if(isFirst(k1.front(),ax,ay)){
                                setTg1(k1.front(),k1.front()->x,k1.front()->y,k1.front()->x,k1.front()->y);
                        }else{
-                               k1.push_back(newVertice(ax,ay));
+                               k1.push_back(newVertex(ax,ay));
                                setTg1(k1.back(),k1.back()->x,k1.back()->y,k1.back()->x,k1.back()->y);
                        }
                }else if(command.compare("T")==0 || command.compare("t")==0){// I don't know what does it
@@ -740,7 +737,7 @@ Svg_parser::parser_path_d(String path_d,Matrix* mtx){
                                if(isFirst(k1.front(),ax,ay)){
                                        setTg1(k1.front(),k1.front()->x,k1.front()->y,tgx,tgy);
                                }else{
-                                       k1.push_back(newVertice (ax,ay));
+                                       k1.push_back(newVertex (ax,ay));
                                        setTg1(k1.back(),k1.back()->x,k1.back()->y,tgx,tgy);
                                        setSplit(k1.back(),TRUE);
                                }
@@ -768,7 +765,7 @@ Svg_parser::parser_path_d(String path_d,Matrix* mtx){
                                if(isFirst(k1.front(),ax,ay)){
                                        setTg1(k1.front(),k1.front()->x,k1.front()->y,tgx,tgy);
                                }else{
-                                       k1.push_back(newVertice (ax,ay));
+                                       k1.push_back(newVertex (ax,ay));
                                        setTg1(k1.back(),k1.back()->x,k1.back()->y,tgx,tgy);
                                        setSplit(k1.back(),TRUE);
                                }
@@ -815,7 +812,7 @@ Svg_parser::parser_path_d(String path_d,Matrix* mtx){
                                //save the last tg2
                                setTg2(k1.back(),k1.back()->x,k1.back()->y,tgx2,tgy2);
                                //save the intermediate point
-                               k1.push_back(newVertice (in_x,in_y));
+                               k1.push_back(newVertex (in_x,in_y));
                                setTg1(k1.back(),k1.back()->x,k1.back()->y, in_tgx1 , in_tgy1);
                                setTg2(k1.back(),k1.back()->x,k1.back()->y, in_tgx2 , in_tgy2);
                                setSplit(k1.back(),TRUE); //this could be changed
@@ -823,15 +820,13 @@ Svg_parser::parser_path_d(String path_d,Matrix* mtx){
                                if(isFirst(k1.front(),ax,ay)){
                                        setTg1(k1.front(),k1.front()->x,k1.front()->y,tgx,tgy);
                                }else{
-                                       k1.push_back(newVertice (ax,ay));
+                                       k1.push_back(newVertex (ax,ay));
                                        setTg1(k1.back(),k1.back()->x,k1.back()->y,tgx,tgy);
                                        setSplit(k1.back(),TRUE);
                                }
                        }
                }else if(command.compare("z")==0){
-                       loop=true;
-                       if(!k1.empty())
-                               k.push_front(k1);
+                       k.push_front(newBLine(&k1, true));
                        k1.clear();
                        if (i<tokens.size() && tokens.at(i).compare("M")!=0 && tokens.at(i).compare("m")!=0) {
                                //starting a new path, but not with a moveto
@@ -842,7 +837,7 @@ Svg_parser::parser_path_d(String path_d,Matrix* mtx){
                                //operate and save
                                if(mtx) transformPoint2D(mtx,&ax,&ay);
                                coor2vect(&ax,&ay);
-                               k1.push_back(newVertice (ax,ay)); //first element
+                               k1.push_back(newVertex (ax,ay)); //first element
                                setSplit(k1.back(),TRUE);
                        }
                        i--; //decrement i to balance "i++" at command change
@@ -850,15 +845,16 @@ Svg_parser::parser_path_d(String path_d,Matrix* mtx){
                        std::cout<<"unsupported path token: "<<tokens.at(i)<<std::endl;
                }
        }
-       if(!k1.empty())
-               k.push_front(k1); //last element
+       if(!k1.empty()) {
+               k.push_front(newBLine(&k1, false)); //last element
+       }
        return k;
 }
 
 /* === EFFECTS PARSERS ===================================================== */
 
 void
-Svg_parser::parser_effects(const xmlpp::Element* nodeElement,xmlpp::Element* root,String parent_style,Matrix* mtx){
+Svg_parser::parser_effects(const xmlpp::Element* /*nodeElement*/,xmlpp::Element* root,String /*parent_style*/,Matrix* mtx){
        build_transform(root, mtx);
 }
 
@@ -989,7 +985,7 @@ Svg_parser::build_linearGradient(xmlpp::Element* root,LinearGradient* data,Matri
 
                gradient->set_attribute("type","linear_gradient");
                gradient->set_attribute("active","true");
-               gradient->set_attribute("desc","Gradient004");
+               gradient->set_attribute("desc",data->name);
                build_param (gradient->add_child("param"),"z_depth","real","0");
                build_param (gradient->add_child("param"),"amount","real","1");
                //straight onto
@@ -1048,6 +1044,7 @@ Svg_parser::build_linearGradient(xmlpp::Element* root,LinearGradient* data,Matri
                //gradient link
                xmlpp::Element *child_stops=gradient->add_child("param");
                child_stops->set_attribute("name","gradient");
+               child_stops->set_attribute("guid",GUID::hasher(data->name).get_string());
                build_stop_color (child_stops->add_child("gradient"),data->stops);
                build_param (gradient->add_child("param"),"loop","bool","false");
                build_param (gradient->add_child("param"),"zigzag","bool","false");
@@ -1064,7 +1061,7 @@ Svg_parser::build_radialGradient(xmlpp::Element* root,RadialGradient* data,Matri
                        layer->set_attribute("type","PasteCanvas");
                        layer->set_attribute("active","true");
                        layer->set_attribute("version","0.1");
-                       layer->set_attribute("desc","Composite");
+                       layer->set_attribute("desc",data->name);
                        build_param (layer->add_child("param"),"z_depth","real","0");
                        build_param (layer->add_child("param"),"amount","real","1");
                        build_param (layer->add_child("param"),"blend_method","integer","21"); //straight onto
@@ -1074,6 +1071,7 @@ Svg_parser::build_radialGradient(xmlpp::Element* root,RadialGradient* data,Matri
                        xmlpp::Element* child_layer=child->add_child("canvas");
 
                        gradient=child_layer->add_child("layer");
+                       gradient->set_attribute("desc",data->name);
                        build_param (gradient->add_child("param"),"blend_method","integer","0"); //composite
                        Matrix *mtx2=NULL;
                        if (mtx && data->transform){
@@ -1087,6 +1085,7 @@ Svg_parser::build_radialGradient(xmlpp::Element* root,RadialGradient* data,Matri
                        
                }else {
                        gradient=root->add_child("layer");
+                       gradient->set_attribute("desc",data->name);
                        build_param (gradient->add_child("param"),"blend_method","integer","21"); //straight onto
                }               
 
@@ -1097,6 +1096,7 @@ Svg_parser::build_radialGradient(xmlpp::Element* root,RadialGradient* data,Matri
                //gradient link
                xmlpp::Element *child_stops=gradient->add_child("param");
                child_stops->set_attribute("name","gradient");
+               child_stops->set_attribute("guid",GUID::hasher(data->name).get_string());
                build_stop_color (child_stops->add_child("gradient"),data->stops);
 
                //here the center point and radius
@@ -1261,6 +1261,18 @@ Svg_parser::newRadialGradient(String name,float cx,float cy,float r,std::list<Co
        return data;
 }
 
+BLine*
+Svg_parser::newBLine(std::list<Vertex*> *points,bool loop){
+       BLine* data;
+       data=(BLine*)malloc(sizeof(BLine));
+       //sprintf(data->name,"%s",name.data());
+       data->points=new std::list<Vertex*> (*points);
+       data->loop=loop;
+       data->bline_id=new String(new_guid());
+       data->offset_id=new String(new_guid());
+       return data;
+}
+
 void
 Svg_parser::build_gamma(xmlpp::Element* root,float gamma){
        root->set_attribute("type","colorcorrect");
@@ -1286,11 +1298,11 @@ Svg_parser::build_rotate(xmlpp::Element* root,float dx,float dy,float angle){
        build_real   (root->add_child("param"),"amount",angle);
 }
 void
-Svg_parser::build_points(xmlpp::Element* root,std::list<Vertice*> p){
+Svg_parser::build_points(xmlpp::Element* root,std::list<Vertex*> p){
        root->set_attribute("name","vector_list");
        xmlpp::Element *child=root->add_child("dynamic_list");
        child->set_attribute("type","vector");
-       std::list<Vertice*>::iterator aux = p.begin();
+       std::list<Vertex*>::iterator aux = p.begin();
        while(aux!=p.end()){
                xmlpp::Element *child_entry=child->add_child("entry");
                xmlpp::Element *child_vector=child_entry->add_child("vector");
@@ -1300,7 +1312,7 @@ Svg_parser::build_points(xmlpp::Element* root,std::list<Vertice*> p){
        }
 }
 void
-Svg_parser::build_vertice(xmlpp::Element* root , Vertice *p){
+Svg_parser::build_vertex(xmlpp::Element* root , Vertex *p){
        xmlpp::Element *child_comp=root->add_child("composite");
        child_comp->set_attribute("type","bline_point");
        build_vector (child_comp->add_child("param"),"point",p->x,p->y);
@@ -1323,7 +1335,7 @@ Svg_parser::build_vertice(xmlpp::Element* root , Vertice *p){
 
 }
 void
-Svg_parser::build_bline(xmlpp::Element* root,std::list<Vertice*> p,bool loop,String blineguid){
+Svg_parser::build_bline(xmlpp::Element* root,std::list<Vertex*> p,bool loop,String blineguid){
        root->set_attribute("name","bline");
        xmlpp::Element *child=root->add_child("bline");
        child->set_attribute("type","bline_point");
@@ -1332,9 +1344,9 @@ Svg_parser::build_bline(xmlpp::Element* root,std::list<Vertice*> p,bool loop,Str
        else
                child->set_attribute("loop","false");
        if(!blineguid.empty())  child->set_attribute("guid",blineguid);
-       std::list<Vertice*>::iterator aux = p.begin();
+       std::list<Vertex*>::iterator aux = p.begin();
        while(aux!=p.end()){
-               if(*aux) build_vertice (child->add_child("entry"),*aux);
+               if(*aux) build_vertex (child->add_child("entry"),*aux);
                aux++;
        }
 }
@@ -1425,11 +1437,11 @@ Svg_parser::build_vector (xmlpp::Element* root,String name,float x,float y,Strin
 }
 
 xmlpp::Element*
-Svg_parser::nodeStartBasicLayer(xmlpp::Element* root){
+Svg_parser::nodeStartBasicLayer(xmlpp::Element* root, String name){
        root->set_attribute("type","PasteCanvas");
        root->set_attribute("active","true");
        root->set_attribute("version","0.1");
-       root->set_attribute("desc","Composite");
+       root->set_attribute("desc",name);
        build_param (root->add_child("param"),"z_depth","real","0");
        build_param (root->add_child("param"),"amount","real","1");
        build_param (root->add_child("param"),"blend_method","integer","0");
@@ -1454,7 +1466,7 @@ Svg_parser::coor2vect(float *x,float *y){
 }
 
 void
-Svg_parser::setTg1(Vertice *p,float p1x,float p1y,float p2x,float p2y){
+Svg_parser::setTg1(Vertex *p,float p1x,float p1y,float p2x,float p2y){
        float rd=0,ag=0;
        float d1x,d1y,d2x,d2y,dx,dy;
        d1x=p1x*60;
@@ -1492,7 +1504,7 @@ Svg_parser::setTg1(Vertice *p,float p1x,float p1y,float p2x,float p2y){
        p->angle1=ag;
 }
 void
-Svg_parser::setTg2(Vertice* p,float p1x,float p1y,float p2x,float p2y){
+Svg_parser::setTg2(Vertex* p,float p1x,float p1y,float p2x,float p2y){
        float rd=0,ag=0;
        float d1x,d1y,d2x,d2y,dx,dy;
        d1x=p1x*60;
@@ -1537,22 +1549,22 @@ Svg_parser::setTg2(Vertice* p,float p1x,float p1y,float p2x,float p2y){
 }
 
 void
-Svg_parser::setSplit(Vertice* p,bool val){
+Svg_parser::setSplit(Vertex* p,bool val){
        if(p!=NULL){
                p->split=val;
        }
 }
 int
-Svg_parser::isFirst(Vertice* nodo,float a, float b){
+Svg_parser::isFirst(Vertex* nodo,float a, float b){
        if(nodo->x==a && nodo->y==b)
                return 1;
        return 0;
 }
 
-Vertice*
-Svg_parser::newVertice(float x,float y){
-       Vertice* vert;
-       vert=(Vertice*)malloc(sizeof(Vertice));
+Vertex*
+Svg_parser::newVertex(float x,float y){
+       Vertex* vert;
+       vert=(Vertex*)malloc(sizeof(Vertex));
        vert->x=x;
        vert->y=y;
        vert->radius1=vert->radius2=vert->angle1=vert->angle2=0;
@@ -1630,9 +1642,9 @@ Svg_parser::newMatrix(float a,float b,float c,float d,float e,float f){
 Matrix*
 Svg_parser::newMatrix(const String mvector){
        if(!mvector.empty()){
-               Matrix* data=(Matrix*)malloc(sizeof(Matrix));
                std::vector<String> tokens=tokenize(mvector,",");
                if(tokens.size()!=6) return newMatrix(1,0,0,1,0,0);
+               Matrix* data=(Matrix*)malloc(sizeof(Matrix));
                data->a=atof(tokens.at(0).data());
                data->b=atof(tokens.at(1).data());
                data->c=atof(tokens.at(2).data());
@@ -1769,7 +1781,7 @@ Svg_parser::get_tokens_path(String path){ //mini path lexico-parser
                                        else if(a=='V'){ e=15; i++;}
                                        else if(a=='H'){ e=16; i++;}
                                        else if(a=='z' || a=='Z'){ e=17; i++;}
-                                       else if(a=='-' ||a=='.'|| isdigit (a)){ e=18;}
+                                       else if(a=='-' || a=='.' || a=='e' || a=='E' || isdigit (a)){ e=18;}
                                        else if(a==','){ e=19; i++;}
                                        else if(a==' '){i++;}
                                        break;
@@ -1793,7 +1805,7 @@ Svg_parser::get_tokens_path(String path){ //mini path lexico-parser
                        case 16: tokens.push_back("H"); e=0; break;
 
                        case 17: tokens.push_back("z"); e=0; break;//loop
-                       case 18: if(a=='-'||a=='.'|| isdigit (a)){
+                       case 18: if(a=='-' || a=='.' || a=='e' || a=='E' || isdigit (a)){
                                                buffer.append(path.substr(i,1));i++;
                                        }else{
                                                e=20;
@@ -1842,6 +1854,8 @@ Svg_parser::randomLetter(){
 int
 Svg_parser::getRed(String hex){
        if(hex.at(0)=='#'){
+               //allow for 3-digit hex codes (#rgb = #rrggbb)
+               if (hex.length()<7) return (16+1) * hextodec(hex.substr(1,1));
                return hextodec(hex.substr(1,2));
        }else if(hex.compare(0,3,"rgb")==0 || hex.compare(0,3,"RGB")==0){
                int start=hex.find_first_of("(")+1;
@@ -1849,11 +1863,12 @@ Svg_parser::getRed(String hex){
                String aux=tokenize(hex.substr(start,end-start),",").at(0);
                return atoi(aux.data());
        }
-       return 0;
+       return getColor(hex,1);
 }
 int
 Svg_parser::getGreen(String hex){
        if(hex.at(0)=='#'){
+               if (hex.length()<7) return (16+1) * hextodec(hex.substr(2,1));
                return hextodec(hex.substr(3,2));
        }else if(hex.compare(0,3,"rgb")==0 || hex.compare(0,3,"RGB")==0){
                int start=hex.find_first_of("(")+1;
@@ -1861,11 +1876,12 @@ Svg_parser::getGreen(String hex){
                String aux=tokenize(hex.substr(start,end-start),",").at(1);
                return atoi(aux.data());
        }
-       return 0;
+       return getColor(hex,2);
 }
 int
 Svg_parser::getBlue(String hex){
        if(hex.at(0)=='#'){
+               if (hex.length()<7) return (16+1) * hextodec(hex.substr(3,1));
                return hextodec(hex.substr(5,2));
        }else if(hex.compare(0,3,"rgb")==0 || hex.compare(0,3,"RGB")==0){
                int start=hex.find_first_of("(")+1;
@@ -1873,7 +1889,7 @@ Svg_parser::getBlue(String hex){
                String aux=tokenize(hex.substr(start,end-start),",").at(2);
                return atoi(aux.data());
        }
-       return 0;
+       return getColor(hex,3);
 }
 int
 Svg_parser::hextodec(String hex){
@@ -2006,3 +2022,161 @@ Svg_parser::new_guid(){
        return GUID::hasher(uid).get_string();
 }
 
+
+#define COLOR_NAME(color, r, g, b) else if(name.compare(0,strlen(color),color)==0) \
+                   {switch(position) \
+                              {case 1: return r; case 2: return g; case 3: return b;}  }
+
+int
+Svg_parser::getColor(String name, int position){
+       if (position<1 || position>3) return 0;
+       COLOR_NAME("aliceblue",240, 248, 255)
+       COLOR_NAME("antiquewhite",250, 235, 215)
+       COLOR_NAME("aqua", 0, 255, 255)
+       COLOR_NAME("aquamarine",127, 255, 212)
+       COLOR_NAME("azure",240, 255, 255)
+       COLOR_NAME("beige",245, 245, 220)
+       COLOR_NAME("bisque",255, 228, 196)
+       COLOR_NAME("black", 0, 0, 0)
+       COLOR_NAME("blanchedalmond",255, 235, 205)
+       COLOR_NAME("blue", 0, 0, 255)
+       COLOR_NAME("blueviolet",138, 43, 226)
+       COLOR_NAME("brown",165, 42, 42)
+       COLOR_NAME("burlywood",222, 184, 135)
+       COLOR_NAME("cadetblue", 95, 158, 160)
+       COLOR_NAME("chartreuse",127, 255, 0)
+       COLOR_NAME("chocolate",210, 105, 30)
+       COLOR_NAME("coral",255, 127, 80)
+       COLOR_NAME("cornflowerblue",100, 149, 237)
+       COLOR_NAME("cornsilk",255, 248, 220)
+       COLOR_NAME("crimson",220, 20, 60)
+       COLOR_NAME("cyan", 0, 255, 255)
+       COLOR_NAME("darkblue", 0, 0, 139)
+       COLOR_NAME("darkcyan", 0, 139, 139)
+       COLOR_NAME("darkgoldenrod",184, 134, 11)
+       COLOR_NAME("darkgray",169, 169, 169)
+       COLOR_NAME("darkgreen", 0, 100, 0)
+       COLOR_NAME("darkgrey",169, 169, 169)
+       COLOR_NAME("darkkhaki",189, 183, 107)
+       COLOR_NAME("darkmagenta",139, 0, 139)
+       COLOR_NAME("darkolivegreen", 85, 107, 47)
+       COLOR_NAME("darkorange",255, 140, 0)
+       COLOR_NAME("darkorchid",153, 50, 204)
+       COLOR_NAME("darkred",139, 0, 0)
+       COLOR_NAME("darksalmon",233, 150, 122)
+       COLOR_NAME("darkseagreen",143, 188, 143)
+       COLOR_NAME("darkslateblue", 72, 61, 139)
+       COLOR_NAME("darkslategray", 47, 79, 79)
+       COLOR_NAME("darkslategrey", 47, 79, 79)
+       COLOR_NAME("darkturquoise", 0, 206, 209)
+       COLOR_NAME("darkviolet",148, 0, 211)
+       COLOR_NAME("deeppink",255, 20, 147)
+       COLOR_NAME("deepskyblue", 0, 191, 255)
+       COLOR_NAME("dimgray",105, 105, 105)
+       COLOR_NAME("dimgrey",105, 105, 105)
+       COLOR_NAME("dodgerblue", 30, 144, 255)
+       COLOR_NAME("firebrick",178, 34, 34)
+       COLOR_NAME("floralwhite",255, 250, 240)
+       COLOR_NAME("forestgreen", 34, 139, 34)
+       COLOR_NAME("fuchsia",255, 0, 255)
+       COLOR_NAME("gainsboro",220, 220, 220)
+       COLOR_NAME("ghostwhite",248, 248, 255)
+       COLOR_NAME("gold",255, 215, 0)
+       COLOR_NAME("goldenrod",218, 165, 32)
+       COLOR_NAME("gray",128, 128, 128)
+       COLOR_NAME("grey",128, 128, 128)
+       COLOR_NAME("green", 0, 128, 0)
+       COLOR_NAME("greenyellow",173, 255, 47)
+       COLOR_NAME("honeydew",240, 255, 240)
+       COLOR_NAME("hotpink",255, 105, 180)
+       COLOR_NAME("indianred",205, 92, 92)
+       COLOR_NAME("indigo", 75, 0, 130)
+       COLOR_NAME("ivory",255, 255, 240)
+       COLOR_NAME("khaki",240, 230, 140)
+       COLOR_NAME("lavender",230, 230, 250)
+       COLOR_NAME("lavenderblush",255, 240, 245)
+       COLOR_NAME("lawngreen",124, 252, 0)
+       COLOR_NAME("lemonchiffon",255, 250, 205)
+       COLOR_NAME("lightblue",173, 216, 230)
+       COLOR_NAME("lightcoral",240, 128, 128)
+       COLOR_NAME("lightcyan",224, 255, 255)
+       COLOR_NAME("lightgoldenrodyellow",250, 250, 210)
+       COLOR_NAME("lightgray",211, 211, 211)
+       COLOR_NAME("lightgreen",144, 238, 144)
+       COLOR_NAME("lightgrey",211, 211, 211)
+       COLOR_NAME("lightpink",255, 182, 193)
+       COLOR_NAME("lightsalmon",255, 160, 122)
+       COLOR_NAME("lightseagreen", 32, 178, 170)
+       COLOR_NAME("lightskyblue",135, 206, 250)
+       COLOR_NAME("lightslategray",119, 136, 153)
+       COLOR_NAME("lightslategrey",119, 136, 153)
+       COLOR_NAME("lightsteelblue",176, 196, 222)
+       COLOR_NAME("lightyellow",255, 255, 224)
+       COLOR_NAME("lime", 0, 255, 0)
+       COLOR_NAME("limegreen", 50, 205, 50)
+       COLOR_NAME("linen",250, 240, 230)
+       COLOR_NAME("magenta",255, 0, 255)
+       COLOR_NAME("maroon",128, 0, 0)
+       COLOR_NAME("mediumaquamarine",102, 205, 170)
+       COLOR_NAME("mediumblue", 0, 0, 205)
+       COLOR_NAME("mediumorchid",186, 85, 211)
+       COLOR_NAME("mediumpurple",147, 112, 219)
+       COLOR_NAME("mediumseagreen", 60, 179, 113)
+       COLOR_NAME("mediumslateblue",123, 104, 238)
+       COLOR_NAME("mediumspringgreen", 0, 250, 154)
+       COLOR_NAME("mediumturquoise", 72, 209, 204)
+       COLOR_NAME("mediumvioletred",199, 21, 133)
+       COLOR_NAME("midnightblue", 25, 25, 112)
+       COLOR_NAME("mintcream",245, 255, 250)
+       COLOR_NAME("mistyrose",255, 228, 225)
+       COLOR_NAME("moccasin",255, 228, 181)
+       COLOR_NAME("navajowhite",255, 222, 173)
+       COLOR_NAME("navy", 0, 0, 128)
+       COLOR_NAME("oldlace",253, 245, 230)
+       COLOR_NAME("olive",128, 128, 0)
+       COLOR_NAME("olivedrab",107, 142, 35)
+       COLOR_NAME("orange",255, 165, 0)
+       COLOR_NAME("orangered",255, 69, 0)
+       COLOR_NAME("orchid",218, 112, 214)
+       COLOR_NAME("palegoldenrod",238, 232, 170)
+       COLOR_NAME("palegreen",152, 251, 152)
+       COLOR_NAME("paleturquoise",175, 238, 238)
+       COLOR_NAME("palevioletred",219, 112, 147)
+       COLOR_NAME("papayawhip",255, 239, 213)
+       COLOR_NAME("peachpuff",255, 218, 185)
+       COLOR_NAME("peru",205, 133, 63)
+       COLOR_NAME("pink",255, 192, 203)
+       COLOR_NAME("plum",221, 160, 221)
+       COLOR_NAME("powderblue",176, 224, 230)
+       COLOR_NAME("purple",128, 0, 128)
+       COLOR_NAME("red",255, 0, 0)
+       COLOR_NAME("rosybrown",188, 143, 143)
+       COLOR_NAME("royalblue", 65, 105, 225)
+       COLOR_NAME("saddlebrown",139, 69, 19)
+       COLOR_NAME("salmon",250, 128, 114)
+       COLOR_NAME("sandybrown",244, 164, 96)
+       COLOR_NAME("seagreen", 46, 139, 87)
+       COLOR_NAME("seashell",255, 245, 238)
+       COLOR_NAME("sienna",160, 82, 45)
+       COLOR_NAME("silver",192, 192, 192)
+       COLOR_NAME("skyblue",135, 206, 235)
+       COLOR_NAME("slateblue",106, 90, 205)
+       COLOR_NAME("slategray",112, 128, 144)
+       COLOR_NAME("slategrey",112, 128, 144)
+       COLOR_NAME("snow",255, 250, 250)
+       COLOR_NAME("springgreen", 0, 255, 127)
+       COLOR_NAME("steelblue", 70, 130, 180)
+       COLOR_NAME("tan",210, 180, 140)
+       COLOR_NAME("teal", 0, 128, 128)
+       COLOR_NAME("thistle",216, 191, 216)
+       COLOR_NAME("tomato",255, 99, 71)
+       COLOR_NAME("turquoise", 64, 224, 208)
+       COLOR_NAME("violet",238, 130, 238)
+       COLOR_NAME("wheat",245, 222, 179)
+       COLOR_NAME("white",255, 255, 255)
+       COLOR_NAME("whitesmoke",245, 245, 245)
+       COLOR_NAME("yellow",255, 255, 0)
+       COLOR_NAME("yellowgreen",154, 205, 50)
+       return 0;
+}
+#undef COLOR_NAME