Esempio n. 1
0
/*
 Traverse the whole DOM and process each node in three ways
 1. Save XML doc as a nested object tree to be saved out
 2. Parse graphics into ofPaths
 3. Save reference to current processed path node in a lookup flatlist
 
 
 info belongs to ofxSVG
 node is the current object in the tree being parsed, preserving nesting
 cnl is the childlist from original DOM
 state is tinysvg control parse value
 */
svgtiny_code processChildren(svgInfo &info, ofPtr<svgNode> node, Poco::XML::ChildNodesList *cnl,
                             struct svgtiny_parse_state state){

    
        
    svgtiny_code code = svgtiny_OK;
    int i  = 0, l = cnl->length();
    
    while( i < l ){

    Element *child = (Poco::XML::Element *) cnl->item(i);
        ofPtr<svgNode> childnode(new svgNode());
        
    
    // I think this can't happen?
    if (child->nodeType() == Poco::XML::Element::ELEMENT_NODE) {
        const char *name = (const char *) child->localName().c_str();
        
        if (strcmp(name, "svg") == 0){
            
            ofLog()<<"processing a nested svg (not root)"<<endl;
            
            
                        
            //this svg is within root svg
 
            svgDef svgDef;
            svgDef.width = ofToString(child->getAttribute("width").c_str());
            svgDef.height = ofToString(child->getAttribute("height").c_str());
            svgDef.x = ofToString(child->getAttribute("x").c_str());
            svgDef.y = ofToString(child->getAttribute("y").c_str());
            svgDef.viewbox = ofToString(child->getAttribute("viewbox").c_str());
            
            
                
            
            
            
            /*recursive call for any nodes inside svg
            Poco::XML::ChildNodesList *cnl = ( Poco::XML::ChildNodesList *) child->childNodes();
            int ii  = 0, ll = cnl->length();
            while( ii < ll ) {
                 ofLog()<<"recursive svg call"<<ii<<endl;
                Poco::XML::Element * grandchild = (Poco::XML::Element *) cnl->item(ii);
                svgNode childnode;
                svgtiny_code code = processChildren(info,childnode,grandchild,state);
                svgDef.nodes.push_back(childnode);
                if (code != svgtiny_OK)
                    return code;
                 ii++;
                
            }*/
            
            childnode->svg = svgDef;
            childnode->type =SVG_TAG_TYPE_SVG;
            node->children.push_back(childnode);
            
            //recursive call...it seeems svg and groups are treated the same
            code = svgtiny_parse_svg(info,child, state,childnode);
        }else if (strcmp(name, "g") == 0){
           /// ofLog()<<"processing group"<<endl;
            
            svgGroupDef gDef;
            gDef.transform = ofToString(child->getAttribute("transform").c_str());
            
            gDef.fill = ofToString(child->getAttribute("fill").c_str());
            gDef.stroke = ofToString(child->getAttribute("stroke").c_str());
            gDef.stroke_width = ofToString(child->getAttribute("stroke-width").c_str());
            gDef.stroke_miterlimit = ofToString(child->getAttribute("stroke-miterlimit").c_str());
            gDef.fill_opacity = ofToString(child->getAttribute("fill-opacity").c_str());
            gDef.stroke_opacity = ofToString(child->getAttribute("stroke-opacity").c_str());
            
            
            
            
            //recursive call for any nodes inside svg
            /*Poco::XML::ChildNodesList *cnl = ( Poco::XML::ChildNodesList *) child->childNodes();
            int ii  = 0, ll = cnl->length();
            while( ii < ll ) {
                 ofLog()<<"recursive grop call"<<ii<<endl;
                Poco::XML::Element * grandchild = (Poco::XML::Element *) cnl->item(ii);
                svgNode childnode;
                svgtiny_code code = processChildren(info,childnode,grandchild,state);
                gDef.nodes.push_back(childnode);
                if (code != svgtiny_OK)
                    return code;
                ii++;
                
            }
            */
            childnode->group = gDef;  
            childnode->type =SVG_TAG_TYPE_GROUP;
            node->children.push_back(childnode);
            
            
            //recursive call...it seeems svg and groups are treated the same
            code = svgtiny_parse_svg(info,child, state,childnode);
        }else if (strcmp(name, "a") == 0){
            //a node?! who cares

            code = svgtiny_parse_svg(info,child, state,childnode);
        }else if (strcmp(name, "path") == 0){
            //ofLog()<<"--------  "<<child->getAttribute("d").c_str()<<endl;
            //<path fill="#D14E8F" stroke="#0C0404" stroke-miterlimit="10" d="M2802.998,4477.002c-2.002-30-2.002-31.001,7.998-8.003c5,13.999,6.006,28.003,1.006,33.003                C2807.998,4506.001,2802.998,4495,2802.998,4477.002z"/>
            //info.paths.push_back(child->getAttribute("d").c_str());
            //info.paths.push_back("<"+ofToString(child->nodeName().c_str())+"/>");
            //"<path fill='#000000' stroke='#000000' stroke-width='1' stroke-miterlimit='10' d='M590 35 c0 -19 5 -35 11 -35 7 0 9 10 4 28 -4 17 -3 24 3 17 6 -5 12 -19 15 -30 4 -16 5 -16 6 5 1 15 -7 30 -19 38 -19 11 -20 10 -20 -23z' />"

            svgPathDef pDef;
            pDef.d = ofToString(child->getAttribute("d").c_str());
            pDef.fill = ofToString(child->getAttribute("fill").c_str());
            pDef.stroke = ofToString(child->getAttribute("stroke").c_str());
            pDef.stroke_width = ofToString(child->getAttribute("stroke-width").c_str());
            pDef.stroke_miterlimit = ofToString(child->getAttribute("stroke-miterlimit").c_str());
            //info.paths.push_back(pDef);
            pDef.fill_opacity = ofToString(child->getAttribute("fill-opacity").c_str());
            pDef.stroke_opacity = ofToString(child->getAttribute("stroke-opacity").c_str());
            
            childnode->path = pDef;         
            childnode->type = SVG_TAG_TYPE_PATH;
            node->children.push_back(childnode);
            
           // ofLog()<<"defining currNode"<<endl;
            state.currNode = childnode;
            
            /*
             if(info.svgs.size()>0){
             //this path is within a nested svg
             info.svgs[info.svgs.size()-1]->groups[info.svgs[info.svgs.size()-1]->groups.size()-1]->paths.push_back(pDef);
             }else{
             //this path belongs within group in root svg
             info.groups[info.groups.size()-1]->paths.push_back(pDef);                  
             }
             */
            
            
            code = svgtiny_parse_path(child, state);
            
            
        } else if (strcmp(name, "rect") == 0){
            
            
            svgRectDef pDef;
 
            pDef.fill = ofToString(child->getAttribute("fill").c_str());
            pDef.stroke = ofToString(child->getAttribute("stroke").c_str());
            pDef.stroke_width = ofToString(child->getAttribute("stroke-width").c_str());
            pDef.stroke_miterlimit = ofToString(child->getAttribute("stroke-miterlimit").c_str());
            //info.paths.push_back(pDef);
            pDef.fill_opacity = ofToString(child->getAttribute("fill-opacity").c_str());
            pDef.stroke_opacity = ofToString(child->getAttribute("stroke-opacity").c_str());
            
            pDef.x = ofToString(child->getAttribute("x").c_str());
            pDef.y = ofToString(child->getAttribute("y").c_str());
            pDef.width = ofToString(child->getAttribute("width").c_str());
            pDef.height = ofToString(child->getAttribute("height").c_str());
            
            
            childnode->rect = pDef;         
            childnode->type = SVG_TAG_TYPE_RECT;
            node->children.push_back(childnode);
            
           // ofLog()<<"defining currNode"<<endl;
            state.currNode = childnode;

            
            
            
            code = svgtiny_parse_rect(child, state);
        }else if (strcmp(name, "circle") == 0){
            code = svgtiny_parse_circle(child, state);
        }else if (strcmp(name, "ellipse") == 0){
            code = svgtiny_parse_ellipse(child, state);
        }else if (strcmp(name, "line") == 0){
            code = svgtiny_parse_line(child, state);
        } else if (strcmp(name, "polyline") == 0){
            code = svgtiny_parse_poly(child, state, false);
        }else if (strcmp(name, "polygon") == 0){
            code = svgtiny_parse_poly(child, state, true);
        } else if (strcmp(name, "text") == 0){
            code = svgtiny_parse_text(child, state);
        }
        // not sure about this
    } else if (child->nodeType() == Poco::XML::Element::TEXT_NODE) {
        
        const char *name = (const char *) child->localName().c_str();
        
        if (strcmp(name, "text") == 0)
            code = svgtiny_parse_text(child, state);
    }
    
    
    
    
   
    

    
    //pNode = it.nextNode();
   
    
        if (code != svgtiny_OK){
            return code;
        }

        
        i++;
        
	}

    return code;
};
Esempio n. 2
0
		size_t Parser::parseString(const std::string& text, size_t start, size_t len, PTextNode node)
		{
			size_t pos = node->content;
			size_t last = start + len;

			std::string debug1 = text.substr(pos, len);

			while(pos < last)
			{
				size_t view = pos;
				PTextView chunk(new TextView());
				chunk->col = m_color;
				chunk->font = m_font;

				applyFormatting(chunk, node.get());
				chunk->start = view;		

				pos = text.find_first_of("[", pos);
				if(pos != std::string::npos && pos < last)
				{			
					size_t close = text.find_first_of("]", pos);
					if(close == std::string::npos || close > last)
					{
						pos = last;
						chunk->len = pos - view;
						if(chunk->len || node->type == ImgTag)
						{
							chunk->isNewLine = m_paragraph;
							chunk->isList = m_list;
							m_paragraph = false;
							m_formatting.push_back(chunk);
						}
						m_list = false;
						break; // newline symbol inside a tag!
					}

					chunk->len = pos - view;
					if(chunk->len || node->type == ImgTag)
					{
						chunk->isNewLine = m_paragraph;
						chunk->isList = m_list;
						m_paragraph = false;
						m_formatting.push_back(chunk);
					}

					std::string param;
					std::string tag = text.substr(pos + 1, close - (pos + 1));

					bool closed = false;
					TagType type = parseNodeTag(tag, closed, param);

					if(!closed)
					{
						if(type == ListTag)
						{
							m_list = true;
							if(!m_paragraph)
							{
								m_paragraph = true;
								pos = close;
								break;
							}
						}
						// New tag found
						PTextNode childnode(new TextNode());
						childnode->start = pos;
						childnode->content = close + 1;
						childnode->parent = node.get();
						childnode->type = type;
						childnode->param = param;
						node->children.push_back(childnode);

						pos = parseString(text, pos, last - pos, childnode);
					}
					else
					{
						pos = close;
						if(type == node->type)
						{
							break;
						}
					}
				}
				else
				{
					pos = last;
					chunk->len = pos - view;
					if(chunk->len || node->type == ImgTag)
					{
						chunk->isNewLine = m_paragraph;
						chunk->isList = m_list;
						m_paragraph = false;
						m_formatting.push_back(chunk);
					}
					break;
				}
			}	

			pos++;
			node->len = pos - node->start;
			return pos;
		}