Svg_parser::parser_graphics(const xmlpp::Node* node,xmlpp::Element* root,String parent_style,Matrix* mtx_parent){
if(const xmlpp::Element* nodeElement = dynamic_cast<const xmlpp::Element*>(node)){
Glib::ustring nodename = node->get_name();
+ if (nodename.compare("g")==0 || nodename.compare("path")==0 || nodename.compare("polygon")==0 || nodename.compare("rect")==0){} else return;
//load sub-attributes
Glib::ustring id =nodeElement->get_attribute_value("id");
if(nodename.compare("rect")==0 && typeFill!=0){
rect_simple(nodeElement,child_fill,fill,fill_opacity,opacity);
if(typeFill==2){
- build_url (child_fill->add_child("layer"),fill,NULL);
+ build_url (child_fill,fill,NULL);
}
parser_effects(nodeElement,child_layer,parent_style,mtx);
return;
}
if(typeFill==2){ //gradient in onto mode (fill)
if (SVG_RESOLVE_BLINE)
- build_url(child_fill->add_child("layer"),fill,mtx);
+ build_url(child_fill,fill,mtx);
else
- build_url(child_fill->add_child("layer"),fill,NULL);
+ build_url(child_fill,fill,NULL);
}
if(typeStroke!=0){//outline layer
if(typeStroke==2){ //gradient in onto mode (stroke)
if (SVG_RESOLVE_BLINE)
- build_url(child_stroke->add_child("layer"),fill,mtx);
+ build_url(child_stroke,fill,mtx);
else
- build_url(child_stroke->add_child("layer"),fill,NULL);
+ build_url(child_stroke,fill,NULL);
}
if (SVG_RESOLVE_BLINE)
parser_effects(nodeElement,child_layer,parent_style,NULL);
Svg_parser::parser_path_d(String path_d,Matrix* mtx){
std::list<std::list<Vertice*> > k;
std::list<Vertice*> 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
- float actual_x=0,actual_y=0;//for relative methods;
+ ax=ay=0;
+ 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;
- unsigned int i;
- std::vector<String> tokens=get_tokens_path(path_d);
- for(i=0;i<tokens.size();i++){
- if(tokens.at(i).compare("M")==0){//absolute move to
+
+ for(unsigned int i=0;i<tokens.size();i++){
+ //if the token is a command, change the current command
+ if(tokens.at(i).compare("M")==0 || tokens.at(i).compare("m")==0 || tokens.at(i).compare("L")==0 || tokens.at(i).compare("l")==0 || tokens.at(i).compare("H")==0 || tokens.at(i).compare("h")==0 || tokens.at(i).compare("V")==0 || tokens.at(i).compare("v")==0 || tokens.at(i).compare("C")==0 || tokens.at(i).compare("c")==0 || tokens.at(i).compare("S")==0 || tokens.at(i).compare("s")==0 || tokens.at(i).compare("Q")==0 || tokens.at(i).compare("q")==0 || tokens.at(i).compare("T")==0 || tokens.at(i).compare("t")==0 || tokens.at(i).compare("A")==0 || tokens.at(i).compare("a")==0 || tokens.at(i).compare("z")==0) {
+ command=tokens.at(i);
+ i++;
+ }
+
+ old_x=actual_x;
+ old_y=actual_y;
+ //if command is absolute, set actual_x/y to zero
+ if(command.compare("M")==0 || command.compare("L")==0 || command.compare("C")==0 || command.compare("S")==0 || command.compare("Q")==0 || command.compare("T")==0 || command.compare("A")==0 || command.compare("H")==0 || command.compare("V")==0) {
+ actual_x=0;
+ actual_y=0;
+ }
+
+ //now parse the commands
+ if(command.compare("M")==0 || command.compare("m")==0){ //move to
if(!k1.empty())
k.push_front(k1);
k1.clear();
//read
- i++; ax=atof(tokens.at(i).data());
+ actual_x+=atof(tokens.at(i).data());
i++; if(tokens.at(i).compare(",")==0) i++;
- ay=atof(tokens.at(i).data());
- actual_x=ax;
- actual_y=ay;
+ actual_y+=atof(tokens.at(i).data());
+
+ init_x=actual_x;
+ init_y=actual_y;
+ ax=actual_x;
+ ay=actual_y;
//operate and save
if(mtx) transformPoint2D(mtx,&ax,&ay);
coor2vect(&ax,&ay);
k1.push_back(newVertice (ax,ay)); //first element
setSplit(k1.back(),TRUE);
- }else if(tokens.at(i).compare("C")==0){ //absolute curve
+ //"If a moveto is followed by multiple pairs of coordinates,
+ // the subsequent pairs are treated as implicit lineto commands."
+ if (command.compare("M")==0)
+ command="L";
+ else
+ command="l";
+ }else if(command.compare("C")==0 || command.compare("c")==0){ //curve
//tg2
- i++; tgx2=atof(tokens.at(i).data());
+ tgx2=actual_x+atof(tokens.at(i).data());
i++; if(tokens.at(i).compare(",")==0) i++;
- tgy2=atof(tokens.at(i).data());
+ tgy2=actual_y+atof(tokens.at(i).data());
//tg1
- i++; tgx=atof(tokens.at(i).data());
+ i++; tgx=actual_x+atof(tokens.at(i).data());
i++; if(tokens.at(i).compare(",")==0) i++;
- tgy=atof(tokens.at(i).data());
+ tgy=actual_y+atof(tokens.at(i).data());
//point
- i++; ax=atof(tokens.at(i).data());
+ i++; actual_x+=atof(tokens.at(i).data());
i++; if(tokens.at(i).compare(",")==0) i++;
- ay=atof(tokens.at(i).data());
- actual_x=ax;
- actual_y=ay;
+ actual_y+=atof(tokens.at(i).data());
+
+ ax=actual_x;
+ ay=actual_y;
//mtx
if(mtx){
transformPoint2D(mtx,&tgx2,&tgy2);
setTg1(k1.back(),k1.back()->x,k1.back()->y,tgx,tgy);
setSplit(k1.back(),TRUE);
}
- }else if(tokens.at(i).compare("Q")==0){ //absolute quadractic curve
+ }else if(command.compare("Q")==0 || command.compare("q")==0){ //quadractic curve
//tg1 and tg2
- i++; tgx=ax=atof(tokens.at(i).data());
+ tgx=actual_x+atof(tokens.at(i).data());
i++; if(tokens.at(i).compare(",")==0) i++;
- tgy=ay=atof(tokens.at(i).data());
+ tgy=actual_y+atof(tokens.at(i).data());
//point
- i++; ax=atof(tokens.at(i).data());
+ i++; actual_x+=atof(tokens.at(i).data());
i++; if(tokens.at(i).compare(",")==0) i++;
- ay=atof(tokens.at(i).data());
- actual_x=ax;
- actual_y=ay;
+ actual_y+=atof(tokens.at(i).data());
+
+ ax=actual_x;
+ ay=actual_y;
//mtx
if(mtx){
transformPoint2D(mtx,&ax,&ay);
setSplit(k1.back(),FALSE);
k1.push_back(newVertice (ax,ay));
setTg1(k1.back(),k1.back()->x,k1.back()->y,tgx,tgy);
- }else if(tokens.at(i).compare("L")==0){ //absolute line to
+ }else if(command.compare("L")==0 || command.compare("l")==0){ //line to
//point
- i++; ax=atof(tokens.at(i).data());
- i++; if(tokens.at(i).compare(",")==0) i++;
- ay=atof(tokens.at(i).data());
- actual_x=ax;
- actual_y=ay;
- //mtx
- if(mtx) transformPoint2D(mtx,&ax,&ay);
- //adjust
- coor2vect(&ax,&ay);
- //save
- setTg2(k1.back(),k1.back()->x,k1.back()->y,k1.back()->x,k1.back()->y);
- 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));
- setTg1(k1.back(),k1.back()->x,k1.back()->y,k1.back()->x,k1.back()->y);
- }
- }else if(tokens.at(i).compare("l")==0){//relative line to
- //point read
- i++; ax=atof(tokens.at(i).data());
+ actual_x+=atof(tokens.at(i).data());
i++; if(tokens.at(i).compare(",")==0) i++;
- ay=atof(tokens.at(i).data());
- //relative
- ax=actual_x+ax;
- ay=actual_y+ay;
- actual_x=ax;
- actual_y=ay;
- //mtx
- if(mtx) transformPoint2D(mtx,&ax,&ay);
- //adjust
- coor2vect(&ax,&ay);
- //save
- setTg2(k1.back(),k1.back()->x,k1.back()->y,k1.back()->x,k1.back()->y);
- 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));
- setTg1(k1.back(),k1.back()->x,k1.back()->y,k1.back()->x,k1.back()->y);
- }
- }else if(tokens.at(i).compare("H")==0){//absolute horizontal move
- //the same that L but only Horizontal movement
- //point
- i++; ax=atof(tokens.at(i).data());
- ay=actual_y;
- actual_x=ax;
- actual_y=ay;
- //mtx
- if(mtx) transformPoint2D(mtx,&ax,&ay);
- //adjust
- coor2vect(&ax,&ay);
- //save
- setTg2(k1.back(),k1.back()->x,k1.back()->y,k1.back()->x,k1.back()->y);
- 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));
- setTg1(k1.back(),k1.back()->x,k1.back()->y,k1.back()->x,k1.back()->y);
- }
- }else if(tokens.at(i).compare("h")==0){//horizontal relative
- i++; ax=atof(tokens.at(i).data());
- ax=actual_x+ax;
+ actual_y+=atof(tokens.at(i).data());
+
+ ax=actual_x;
ay=actual_y;
- actual_x=ax;
- actual_y=ay;
//mtx
if(mtx) transformPoint2D(mtx,&ax,&ay);
//adjust
k1.push_back(newVertice(ax,ay));
setTg1(k1.back(),k1.back()->x,k1.back()->y,k1.back()->x,k1.back()->y);
}
- }else if(tokens.at(i).compare("V")==0){//vertical absolute
+ }else if(command.compare("H")==0 || command.compare("h")==0){// horizontal move
+ //the same that L but only Horizontal movement
//point
- i++; ay=atof(tokens.at(i).data());
+ actual_x+=atof(tokens.at(i).data());
+
ax=actual_x;
- actual_x=ax;
- actual_y=ay;
+ ay=old_y;
//mtx
if(mtx) transformPoint2D(mtx,&ax,&ay);
//adjust
k1.push_back(newVertice(ax,ay));
setTg1(k1.back(),k1.back()->x,k1.back()->y,k1.back()->x,k1.back()->y);
}
- }else if(tokens.at(i).compare("v")==0){//relative
+ }else if(command.compare("V")==0 || command.compare("v")==0){//vertical
//point
- i++; ay=atof(tokens.at(i).data());
- ax=actual_x;
- ay=actual_y+ay;
- actual_x=ax;
- actual_y=ay;
+ actual_y+=atof(tokens.at(i).data());
+
+ ax=old_x;
+ ay=actual_y;
//mtx
if(mtx) transformPoint2D(mtx,&ax,&ay);
//adjust
k1.push_back(newVertice(ax,ay));
setTg1(k1.back(),k1.back()->x,k1.back()->y,k1.back()->x,k1.back()->y);
}
- }else if(tokens.at(i).compare("T")==0){// I don't know what does it
- }else if(tokens.at(i).compare("A")==0){//elliptic arc
+ }else if(command.compare("T")==0 || command.compare("t")==0){// I don't know what does it
+ actual_x+=atof(tokens.at(i).data());
+ i++; if(tokens.at(i).compare(",")==0) i++;
+ actual_y+=atof(tokens.at(i).data());
+ }else if(command.compare("A")==0 || command.compare("a")==0){//elliptic arc
//isn't complete support, is only for circles
float angle;
bool sweep,large;
//radio
- i++; radio_x=atof(tokens.at(i).data());
+ radio_x=atof(tokens.at(i).data());
i++; if(tokens.at(i).compare(",")==0) i++;
radio_y=atof(tokens.at(i).data());
//angle
i++; large=atoi(tokens.at(i).data());
i++; sweep=atoi(tokens.at(i).data());
//point
- i++; ax=atof(tokens.at(i).data());
+ i++; actual_x+=atof(tokens.at(i).data());
i++; if(tokens.at(i).compare(",")==0) i++;
- ay=atof(tokens.at(i).data());
+ actual_y+=atof(tokens.at(i).data());
//how to draw?
if(!large && !sweep){
//points
- tgx2 = actual_x + radio_x*0.5;
- tgy2 = actual_y ;
- tgx = ax;
- tgy = ay + radio_y*0.5;
- actual_x=ax;
- actual_y=ay;
+ tgx2 = old_x + radio_x*0.5;
+ tgy2 = old_y ;
+ tgx = actual_x;
+ tgy = actual_y + radio_y*0.5;
+
+ ax=actual_x;
+ ay=actual_y;
//transformations
if(mtx){
transformPoint2D(mtx,&tgx2,&tgy2);
}
}else if(!large && sweep){
//points
- tgx2 = actual_x;
- tgy2 = actual_y + radio_y*0.5;
- tgx = ax + radio_x*0.5;
- tgy = ay ;
- actual_x=ax;
- actual_y=ay;
+ tgx2 = old_x;
+ tgy2 = old_y + radio_y*0.5;
+ tgx = actual_x + radio_x*0.5;
+ tgy = actual_y ;
+
+ ax=actual_x;
+ ay=actual_y;
//transformations
if(mtx){
transformPoint2D(mtx,&tgx2,&tgy2);
}else if( large && !sweep){//rare
//this need more than one vertex
}else if( large && sweep){//circles in inkscape are made with this kind of arc
- if(actual_y==ay){//circles
- //intermediate point
- int sense=1;
- if(actual_x>ax) sense =-1;
- float in_x,in_y,in_tgx1,in_tgy1,in_tgx2,in_tgy2;
- in_x = (actual_x+ax)/2;
- in_y = actual_y - sense*radio_y;
- in_tgx1 = in_x - sense*(radio_x*0.5);
- in_tgx2 = in_x + sense*(radio_x*0.5);
- in_tgy1 = in_y;
- in_tgy2 = in_y;
- //start/end points
- tgx2=actual_x;
- tgy2=ay - sense*(radio_y*0.5);
- tgx =ax;
- tgy =ay - sense*(radio_y*0.5);
-
- actual_x=ax;
- actual_y=ay;
- //transformations
- if(mtx){
- transformPoint2D(mtx,&tgx2,&tgy2);
- transformPoint2D(mtx,&tgx ,&tgy );
- transformPoint2D(mtx,&ax,&ay);
-
- transformPoint2D(mtx,&in_tgx2,&in_tgy2);
- transformPoint2D(mtx,&in_tgx1,&in_tgy1);
- transformPoint2D(mtx,&in_x,&in_y);
- }
- //adjust
- coor2vect(&tgx2 , &tgy2);
- coor2vect(&ax , &ay );
- coor2vect(&tgx , &tgy );
-
- coor2vect(&in_tgx2 , &in_tgy2);
- coor2vect(&in_tgx1 , &in_tgy1);
- coor2vect(&in_x , &in_y );
-
- //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));
- 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
- //save the new point
- if(isFirst(k1.front(),ax,ay)){
- setTg1(k1.front(),k1.front()->x,k1.front()->y,tgx,tgy);
- }else{
- k1.push_back(newVertice (ax,ay));
- setTg1(k1.back(),k1.back()->x,k1.back()->y,tgx,tgy);
- setSplit(k1.back(),TRUE);
- }
+ //intermediate point
+ int sense=1;
+ if(old_x>actual_x) sense =-1;
+ float in_x,in_y,in_tgx1,in_tgy1,in_tgx2,in_tgy2;
+ in_x = (old_x+actual_x)/2;
+ in_y = old_y - sense*radio_y;
+ in_tgx1 = in_x - sense*(radio_x*0.5);
+ in_tgx2 = in_x + sense*(radio_x*0.5);
+ in_tgy1 = in_y;
+ in_tgy2 = in_y;
+ //start/end points
+ tgx2=old_x;
+ tgy2=actual_y - sense*(radio_y*0.5);
+ tgx =actual_x;
+ tgy =actual_y - sense*(radio_y*0.5);
+
+ ax=actual_x;
+ ay=actual_y;
+ //transformations
+ if(mtx){
+ transformPoint2D(mtx,&tgx2,&tgy2);
+ transformPoint2D(mtx,&tgx ,&tgy );
+ transformPoint2D(mtx,&ax,&ay);
+
+ transformPoint2D(mtx,&in_tgx2,&in_tgy2);
+ transformPoint2D(mtx,&in_tgx1,&in_tgy1);
+ transformPoint2D(mtx,&in_x,&in_y);
+ }
+ //adjust
+ coor2vect(&tgx2 , &tgy2);
+ coor2vect(&ax , &ay );
+ coor2vect(&tgx , &tgy );
+
+ coor2vect(&in_tgx2 , &in_tgy2);
+ coor2vect(&in_tgx1 , &in_tgy1);
+ coor2vect(&in_x , &in_y );
+
+ //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));
+ 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
+ //save the new point
+ if(isFirst(k1.front(),ax,ay)){
+ setTg1(k1.front(),k1.front()->x,k1.front()->y,tgx,tgy);
+ }else{
+ k1.push_back(newVertice (ax,ay));
+ setTg1(k1.back(),k1.back()->x,k1.back()->y,tgx,tgy);
+ setSplit(k1.back(),TRUE);
}
}
- }else if(tokens.at(i).compare("z")==0){
+ }else if(command.compare("z")==0){
loop=true;
+ if(!k1.empty())
+ k.push_front(k1);
+ 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
+ actual_x=init_x;
+ actual_y=init_y;
+ ax=actual_x;
+ ay=actual_y;
+ //operate and save
+ if(mtx) transformPoint2D(mtx,&ax,&ay);
+ coor2vect(&ax,&ay);
+ k1.push_back(newVertice (ax,ay)); //first element
+ setSplit(k1.back(),TRUE);
+ }
+ i--; //decrement i to balance "i++" at command change
}else{
- std::cout<<"don't supported: "<<tokens.at(i)<<std::endl;
+ std::cout<<"unsupported path token: "<<tokens.at(i)<<std::endl;
}
}
if(!k1.empty())
void
Svg_parser::parser_effects(const xmlpp::Element* nodeElement,xmlpp::Element* root,String parent_style,Matrix* mtx){
+ parser_transform(root, mtx);
+}
+
+void
+Svg_parser::parser_transform(xmlpp::Element* root,Matrix* mtx){
if (mtx) {
xmlpp::Element *child_transform=root->add_child("layer");
child_transform->set_attribute("type","warp");
void
Svg_parser::build_url(xmlpp::Element* root, String name,Matrix *mtx){
if(!name.empty()){
- if(lg.empty()&& rg.empty())
- root->get_parent()->remove_child(root);
-
int start=name.find_first_of("#")+1;
int end=name.find_first_of(")");
String find= name.substr(start,end-start);
aux++;
}
}
- if(!encounter)
- root->get_parent()->remove_child(root);
- }else{
- root->get_parent()->remove_child(root);
}
}
void
void
Svg_parser::build_linearGradient(xmlpp::Element* root,LinearGradient* data,Matrix* mtx){
if(data){
- root->set_attribute("type","linear_gradient");
- root->set_attribute("active","true");
- root->set_attribute("desc","Gradient004");
- build_param (root->add_child("param"),"z_depth","real","0");
- build_param (root->add_child("param"),"amount","real","1");
+ xmlpp::Element* gradient=root->add_child("layer");
+
+ gradient->set_attribute("type","linear_gradient");
+ gradient->set_attribute("active","true");
+ gradient->set_attribute("desc","Gradient004");
+ build_param (gradient->add_child("param"),"z_depth","real","0");
+ build_param (gradient->add_child("param"),"amount","real","1");
//straight onto
- build_param (root->add_child("param"),"blend_method","integer","21");
+ build_param (gradient->add_child("param"),"blend_method","integer","21");
float x1,y1,x2,y2;
x1=data->x1;
y1=data->y1;
x2=data->x2;
y2=data->y2;
- if(mtx){
- transformPoint2D(mtx,&x1,&y1);
- transformPoint2D(mtx,&x2,&y2);
+
+
+ if (mtx || data->transform){
+ Matrix *mtx2=NULL;
+ if (mtx && data->transform){
+ composeMatrix(&mtx2,mtx,data->transform);
+ }else if (mtx){
+ mtx2=mtx;
+ }else if (data->transform){
+ mtx2=data->transform;
+ }
+ //matrix transforms the gradient as a whole
+ //it does not preserve angles, so we cant' simply transform both points
+ float x3, y3, k;
+ //set point (x3,y3) on the same gradient line as (x2,y2)
+ //the gradient line is perpendicular to (x1,y1)(x2,y2)
+ x3=x2+(y2-y1);
+ y3=y2-(x2-x1);
+ //transform everything
+ transformPoint2D(mtx2,&x1,&y1);
+ transformPoint2D(mtx2,&x2,&y2);
+ transformPoint2D(mtx2,&x3,&y3);
+
+ if (x2!=x3 && y2!=y3) {//divide by zero check
+
+ //set k as slope between (x2,y2) and (x3,y3)
+ //k is the slope of gradient lines post-transformation
+ k=(y3-y2)/(x3-x2);
+ //set point (x2,y2) on the gradient line passing through (x3,y3)
+ //so that the line (x1,y1)(x2,y2) is perpendicular to (x2,y2)(x3,y3)
+ x2= (x3*k+x1/k+y1-y3)/(k+(1/k));
+ y2= k*(x2-x3)+y3;
+ } else if (x2==x3 && y2!=y3) {
+ y2=y1;
+ } else if (x2!=x3 && y2==y3) {
+ x2=x1;
+ } else {
+ std::cout<<"SVG Import warning: gradient points equal each other"<<std::endl;
+ }
}
+
coor2vect (&x1,&y1);
coor2vect (&x2,&y2);
- build_vector (root->add_child("param"),"p1",x1,y1);
- build_vector (root->add_child("param"),"p2",x2,y2);
+ build_vector (gradient->add_child("param"),"p1",x1,y1);
+ build_vector (gradient->add_child("param"),"p2",x2,y2);
//gradient link
- xmlpp::Element *child=root->add_child("param");
- child->set_attribute("name","gradient");
- build_stop_color (child->add_child("gradient"),data->stops);
- build_param (root->add_child("param"),"loop","bool","false");
- build_param (root->add_child("param"),"zigzag","bool","false");
+ xmlpp::Element *child_stops=gradient->add_child("param");
+ child_stops->set_attribute("name","gradient");
+ 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");
}
}
void
Svg_parser::build_radialGradient(xmlpp::Element* root,RadialGradient* data,Matrix* mtx){
-//not completed
if(data){
- root->set_attribute("type","radial_gradient");
- root->set_attribute("active","true");
- build_param (root->add_child("param"),"z_depth","real","0");
- build_param (root->add_child("param"),"amount","real","1");
- //straight onto
- build_param (root->add_child("param"),"blend_method","integer","21");
+ xmlpp::Element* gradient;
+
+ if (mtx || data->transform) {
+ xmlpp::Element* layer=root->add_child("layer");
+
+ layer->set_attribute("type","PasteCanvas");
+ layer->set_attribute("active","true");
+ layer->set_attribute("version","0.1");
+ layer->set_attribute("desc","Composite");
+ 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
+ build_vector (layer->add_child("param"),"origin",0,0);
+ xmlpp::Element *child=layer->add_child("param");
+ child->set_attribute("name","canvas");
+ xmlpp::Element* child_layer=child->add_child("canvas");
+
+ gradient=child_layer->add_child("layer");
+ build_param (gradient->add_child("param"),"blend_method","integer","0"); //composite
+ Matrix *mtx2=NULL;
+ if (mtx && data->transform){
+ composeMatrix(&mtx2,mtx,data->transform);
+ }else if (mtx){
+ mtx2=mtx;
+ }else if (data->transform){
+ mtx2=data->transform;
+ }
+ parser_transform(child_layer,mtx2);
+
+ }else {
+ gradient=root->add_child("layer");
+ build_param (gradient->add_child("param"),"blend_method","integer","21"); //straight onto
+ }
+
+ gradient->set_attribute("type","radial_gradient");
+ gradient->set_attribute("active","true");
+ build_param (gradient->add_child("param"),"z_depth","real","0");
+ build_param (gradient->add_child("param"),"amount","real","1");
//gradient link
- xmlpp::Element *child=root->add_child("param");
- child->set_attribute("name","gradient");
- build_stop_color (child->add_child("gradient"),data->stops);
+ xmlpp::Element *child_stops=gradient->add_child("param");
+ child_stops->set_attribute("name","gradient");
+ build_stop_color (child_stops->add_child("gradient"),data->stops);
+
//here the center point and radio
float cx=data->cx;
float cy=data->cy;
float r =data->r;
- //transform
- if(mtx){
- transformPoint2D(mtx,&cx,&cy);
- }
+
//adjust
coor2vect (&cx,&cy);
r=r/kux;
- build_vector (root->add_child("param"),"center",cx,cy);
- build_param (root->add_child("param"),"radius","real",r);
+ build_vector (gradient->add_child("param"),"center",cx,cy);
+ build_param (gradient->add_child("param"),"radius","real",r);
- build_param (root->add_child("param"),"loop","bool","false");
- build_param (root->add_child("param"),"zigzag","bool","false");
+ build_param (gradient->add_child("param"),"loop","bool","false");
+ build_param (gradient->add_child("param"),"zigzag","bool","false");
}
}
float x2 =atof(nodeElement->get_attribute_value("x2").data());
float y2 =atof(nodeElement->get_attribute_value("y2").data());
Glib::ustring link =nodeElement->get_attribute_value("href");
+ Glib::ustring transform =nodeElement->get_attribute_value("gradientTransform");
+
+ //resolve transformations
+ Matrix* mtx=NULL;
+ if(!transform.empty())
+ mtx=build_transform (transform);
std::list<ColorStop*> *stops;
if(!link.empty()){
}
}
if(stops)
- lg.push_back(newLinearGradient(id,x1,y1,x2,y2,stops));
+ lg.push_back(newLinearGradient(id,x1,y1,x2,y2,stops,mtx));
}
}
Glib::ustring id =nodeElement->get_attribute_value("id");
float cx =atof(nodeElement->get_attribute_value("cx").data());
float cy =atof(nodeElement->get_attribute_value("cy").data());
+ float fx =atof(nodeElement->get_attribute_value("fx").data());
+ float fy =atof(nodeElement->get_attribute_value("fy").data());
float r =atof(nodeElement->get_attribute_value("r").data());
Glib::ustring link =nodeElement->get_attribute_value("href");//basic
+ Glib::ustring transform =nodeElement->get_attribute_value("gradientTransform");
+
+ if (cx!=fx || cy!=fy)
+ std::cout<<"SVG Parser: ignoring focus attributes for radial gradient";
+
+ //resolve transformations
+ Matrix* mtx=NULL;
+ if(!transform.empty())
+ mtx=build_transform (transform);
+
std::list<ColorStop*> *stops=NULL;
if(!link.empty()){
//inkscape always use link, i dont need parser stops here, but it's posible
stops=find_colorStop (link);
}
if(stops)
- rg.push_back(newRadialGradient(id,cx,cy,r,stops));
+ rg.push_back(newRadialGradient(id,cx,cy,r,stops,mtx));
}
}
}
LinearGradient*
-Svg_parser::newLinearGradient(String name,float x1,float y1, float x2,float y2,std::list<ColorStop*> *stops){
+Svg_parser::newLinearGradient(String name,float x1,float y1, float x2,float y2,std::list<ColorStop*> *stops, Matrix* transform){
LinearGradient* data;
data=(LinearGradient*)malloc(sizeof(LinearGradient));
sprintf(data->name,"%s",name.data());
data->x2=x2;
data->y2=y2;
data->stops=stops;
+ data->transform=transform;
return data;
}
RadialGradient*
-Svg_parser::newRadialGradient(String name,float cx,float cy,float r,std::list<ColorStop*> *stops){
+Svg_parser::newRadialGradient(String name,float cx,float cy,float r,std::list<ColorStop*> *stops, Matrix* transform){
RadialGradient* data;
data=(RadialGradient*)malloc(sizeof(RadialGradient));
sprintf(data->name,"%s",name.data());
data->cy=cy;
data->r=r;
data->stops=stops;
+ data->transform=transform;
return data;
}