示例#1
0
svgtiny_code svgtiny_parse_svg(svgInfo &info,Poco::XML::Element *svg,
		struct svgtiny_parse_state state, ofPtr<svgNode> currnode){
	float x, y, width, height;
	Poco::XML::Attr *view_box;
	Poco::XML::Element *child;

	svgtiny_parse_position_attributes(svg, state, &x, &y, &width, &height);
	svgtiny_parse_paint_attributes(svg, &state);
	svgtiny_parse_font_attributes(svg, &state);
    
    view_box = svg->getAttributeNode("viewBox");
    
	if (view_box) {
		//const char *s = (const char *) view_box->children->content;
        const char *s = (const char *) view_box->getValue().c_str();
		float min_x, min_y, vwidth, vheight;
		if (sscanf(s, "%f,%f,%f,%f",
				&min_x, &min_y, &vwidth, &vheight) == 4 ||
				sscanf(s, "%f %f %f %f",
				&min_x, &min_y, &vwidth, &vheight) == 4) {
			state.ctm.a = (float) state.viewport_width / vwidth;
			state.ctm.d = (float) state.viewport_height / vheight;
			state.ctm.e += -min_x * state.ctm.a;
			state.ctm.f += -min_y * state.ctm.d;
		}
	}

	svgtiny_parse_transform_attributes(svg, &state);


    // this is how this should work, but it doesn't
    //Poco::XML::NodeIterator it(svg, Poco::XML::NodeFilter::SHOW_ELEMENT | Poco::XML::NodeFilter::SHOW_TEXT);
    //Poco::XML::Node* pNode = it.nextNode();
    //while (pNode)
    
    

    
    
    // Note: this should be using the NodeIterator, but it doesn't seem to work as advertised when using
    // a Node as the root for the iterator constructor. Really weird.
    Poco::XML::ChildNodesList *cnl = ( Poco::XML::ChildNodesList *) svg->childNodes();
    

    svgtiny_code code = processChildren(info,currnode,cnl,state);
    
    if (code != svgtiny_OK){
        return code;
    }
      
	return svgtiny_OK;
}
示例#2
0
svgtiny_code svgtiny_parse_text(xmlNode *text,
		struct svgtiny_parse_state state)
{
	float x, y, width, height;
	float px, py;
	xmlNode *child;

	svgtiny_parse_position_attributes(text, state,
			&x, &y, &width, &height);
	svgtiny_parse_font_attributes(text, &state);
	svgtiny_parse_transform_attributes(text, &state);

	px = state.ctm.a * x + state.ctm.c * y + state.ctm.e;
	py = state.ctm.b * x + state.ctm.d * y + state.ctm.f;
/* 	state.ctm.e = px - state.origin_x; */
/* 	state.ctm.f = py - state.origin_y; */

	/*struct css_style style = state.style;
	style.font_size.value.length.value *= state.ctm.a;*/

	for (child = text->children; child; child = child->next) {
		svgtiny_code code = svgtiny_OK;

		if (child->type == XML_TEXT_NODE) {
			struct svgtiny_shape *shape = svgtiny_add_shape(&state);
			if (!shape)
				return svgtiny_OUT_OF_MEMORY;
			shape->text = strdup((const char *) child->content);
			shape->text_x = px;
			shape->text_y = py;
			state.diagram->shape_count++;

		} else if (child->type == XML_ELEMENT_NODE &&
				strcmp((const char *) child->name,
					"tspan") == 0) {
			code = svgtiny_parse_text(child, state);
		}

		if (!code != svgtiny_OK)
			return code;
	}

	return svgtiny_OK;
}
示例#3
0
svgtiny_code svgtiny_parse_svg(dom_element *svg,
		struct svgtiny_parse_state state)
{
	float x, y, width, height;
	dom_string *view_box;
	dom_element *child;
	dom_exception exc;

	svgtiny_setup_state_local(&state);

	svgtiny_parse_position_attributes(svg, state, &x, &y, &width, &height);
	svgtiny_parse_paint_attributes(svg, &state);
	svgtiny_parse_font_attributes(svg, &state);

	exc = dom_element_get_attribute(svg, state.interned_viewBox,
					&view_box);
	if (exc != DOM_NO_ERR) {
		svgtiny_cleanup_state_local(&state);
		return svgtiny_LIBDOM_ERROR;
	}

	if (view_box) {
		char *s = strndup(dom_string_data(view_box),
				  dom_string_byte_length(view_box));
		float min_x, min_y, vwidth, vheight;
		if (sscanf(s, "%f,%f,%f,%f",
				&min_x, &min_y, &vwidth, &vheight) == 4 ||
				sscanf(s, "%f %f %f %f",
				&min_x, &min_y, &vwidth, &vheight) == 4) {
			state.ctm.a = (float) state.viewport_width / vwidth;
			state.ctm.d = (float) state.viewport_height / vheight;
			state.ctm.e += -min_x * state.ctm.a;
			state.ctm.f += -min_y * state.ctm.d;
		}
		free(s);
		dom_string_unref(view_box);
	}

	svgtiny_parse_transform_attributes(svg, &state);

	exc = dom_node_get_first_child(svg, (dom_node **) (void *) &child);
	if (exc != DOM_NO_ERR) {
		svgtiny_cleanup_state_local(&state);
		return svgtiny_LIBDOM_ERROR;
	}
	while (child != NULL) {
		dom_element *next;
		dom_node_type nodetype;
		svgtiny_code code = svgtiny_OK;

		exc = dom_node_get_node_type(child, &nodetype);
		if (exc != DOM_NO_ERR) {
			dom_node_unref(child);
			return svgtiny_LIBDOM_ERROR;
		}
		if (nodetype == DOM_ELEMENT_NODE) {
			dom_string *nodename;
			exc = dom_node_get_node_name(child, &nodename);
			if (exc != DOM_NO_ERR) {
				dom_node_unref(child);
				svgtiny_cleanup_state_local(&state);
				return svgtiny_LIBDOM_ERROR;
			}
			if (dom_string_caseless_isequal(state.interned_svg,
							nodename))
				code = svgtiny_parse_svg(child, state);
			else if (dom_string_caseless_isequal(state.interned_g,
							     nodename))
				code = svgtiny_parse_svg(child, state);
			else if (dom_string_caseless_isequal(state.interned_a,
							     nodename))
				code = svgtiny_parse_svg(child, state);
			else if (dom_string_caseless_isequal(state.interned_path,
							     nodename))
				code = svgtiny_parse_path(child, state);
			else if (dom_string_caseless_isequal(state.interned_rect,
							     nodename))
				code = svgtiny_parse_rect(child, state);
			else if (dom_string_caseless_isequal(state.interned_circle,
							     nodename))
				code = svgtiny_parse_circle(child, state);
			else if (dom_string_caseless_isequal(state.interned_ellipse,
							     nodename))
				code = svgtiny_parse_ellipse(child, state);
			else if (dom_string_caseless_isequal(state.interned_line,
							     nodename))
				code = svgtiny_parse_line(child, state);
			else if (dom_string_caseless_isequal(state.interned_polyline,
							     nodename))
				code = svgtiny_parse_poly(child, state, false);
			else if (dom_string_caseless_isequal(state.interned_polygon,
							     nodename))
				code = svgtiny_parse_poly(child, state, true);
			else if (dom_string_caseless_isequal(state.interned_text,
							     nodename))
				code = svgtiny_parse_text(child, state);
			dom_string_unref(nodename);
		}
		if (code != svgtiny_OK) {
			dom_node_unref(child);
			svgtiny_cleanup_state_local(&state);
			return code;
		}
		exc = dom_node_get_next_sibling(child,
						(dom_node **) (void *) &next);
		dom_node_unref(child);
		if (exc != DOM_NO_ERR) {
			svgtiny_cleanup_state_local(&state);
			return svgtiny_LIBDOM_ERROR;
		}
		child = next;
	}

	svgtiny_cleanup_state_local(&state);
	return svgtiny_OK;
}
示例#4
0
svgtiny_code svgtiny_parse_text(dom_element *text,
		struct svgtiny_parse_state state)
{
	float x, y, width, height;
	float px, py;
	dom_node *child;
	dom_exception exc;

	svgtiny_setup_state_local(&state);

	svgtiny_parse_position_attributes(text, state,
			&x, &y, &width, &height);
	svgtiny_parse_font_attributes(text, &state);
	svgtiny_parse_transform_attributes(text, &state);

	px = state.ctm.a * x + state.ctm.c * y + state.ctm.e;
	py = state.ctm.b * x + state.ctm.d * y + state.ctm.f;
/* 	state.ctm.e = px - state.origin_x; */
/* 	state.ctm.f = py - state.origin_y; */

	/*struct css_style style = state.style;
	style.font_size.value.length.value *= state.ctm.a;*/
	
        exc = dom_node_get_first_child(text, &child);
	if (exc != DOM_NO_ERR) {
		return svgtiny_LIBDOM_ERROR;
		svgtiny_cleanup_state_local(&state);
	}
	while (child != NULL) {
		dom_node *next;
		dom_node_type nodetype;
		svgtiny_code code = svgtiny_OK;

		exc = dom_node_get_node_type(child, &nodetype);
		if (exc != DOM_NO_ERR) {
			dom_node_unref(child);
			svgtiny_cleanup_state_local(&state);
			return svgtiny_LIBDOM_ERROR;
		}
		if (nodetype == DOM_ELEMENT_NODE) {
			dom_string *nodename;
			exc = dom_node_get_node_name(child, &nodename);
			if (exc != DOM_NO_ERR) {
				dom_node_unref(child);
				svgtiny_cleanup_state_local(&state);
				return svgtiny_LIBDOM_ERROR;
			}
			if (dom_string_caseless_isequal(nodename,
							state.interned_tspan))
				code = svgtiny_parse_text((dom_element *)child,
							  state);
			dom_string_unref(nodename);
		} else if (nodetype == DOM_TEXT_NODE) {
			struct svgtiny_shape *shape = svgtiny_add_shape(&state);
			dom_string *content;
			if (shape == NULL) {
				dom_node_unref(child);
				svgtiny_cleanup_state_local(&state);
				return svgtiny_OUT_OF_MEMORY;
			}
			exc = dom_text_get_whole_text(child, &content);
			if (exc != DOM_NO_ERR) {
				dom_node_unref(child);
				svgtiny_cleanup_state_local(&state);
				return svgtiny_LIBDOM_ERROR;
			}
			if (content != NULL) {
				shape->text = strndup(dom_string_data(content),
						      dom_string_byte_length(content));
				dom_string_unref(content);
			} else {
				shape->text = strdup("");
			}
			shape->text_x = px;
			shape->text_y = py;
			state.diagram->shape_count++;
		}

		if (code != svgtiny_OK) {
			dom_node_unref(child);
			svgtiny_cleanup_state_local(&state);
			return code;
		}
		exc = dom_node_get_next_sibling(child, &next);
		dom_node_unref(child);
		if (exc != DOM_NO_ERR) {
			svgtiny_cleanup_state_local(&state);
			return svgtiny_LIBDOM_ERROR;
		}
		child = next;
	}

	svgtiny_cleanup_state_local(&state);

	return svgtiny_OK;
}
示例#5
0
svgtiny_code svgtiny_parse_svg(xmlNode *svg,
		struct svgtiny_parse_state state)
{
	float x, y, width, height;
	xmlAttr *view_box;
	xmlNode *child;

	svgtiny_parse_position_attributes(svg, state, &x, &y, &width, &height);
	svgtiny_parse_paint_attributes(svg, &state);
	svgtiny_parse_font_attributes(svg, &state);

	/* parse viewBox */
	view_box = xmlHasProp(svg, (const xmlChar *) "viewBox");
	if (view_box) {
		const char *s = (const char *) view_box->children->content;
		float min_x, min_y, vwidth, vheight;
		if (sscanf(s, "%f,%f,%f,%f",
				&min_x, &min_y, &vwidth, &vheight) == 4 ||
				sscanf(s, "%f %f %f %f",
				&min_x, &min_y, &vwidth, &vheight) == 4) {
			state.ctm.a = (float) state.viewport_width / vwidth;
			state.ctm.d = (float) state.viewport_height / vheight;
			state.ctm.e += -min_x * state.ctm.a;
			state.ctm.f += -min_y * state.ctm.d;
		}
	}

	svgtiny_parse_transform_attributes(svg, &state);

	for (child = svg->children; child; child = child->next) {
		svgtiny_code code = svgtiny_OK;

		if (child->type == XML_ELEMENT_NODE) {
			const char *name = (const char *) child->name;
			if (strcmp(name, "svg") == 0)
				code = svgtiny_parse_svg(child, state);
			else if (strcmp(name, "g") == 0)
				code = svgtiny_parse_svg(child, state);
			else if (strcmp(name, "a") == 0)
				code = svgtiny_parse_svg(child, state);
			else if (strcmp(name, "path") == 0)
				code = svgtiny_parse_path(child, state);
			else if (strcmp(name, "rect") == 0)
				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);
		}

		if (code != svgtiny_OK)
			return code;
	}

	return svgtiny_OK;
}
示例#6
0
svgtiny_code svgtiny_parse_text(Poco::XML::Element *text,
		struct svgtiny_parse_state state)
{
	float x, y, width, height;
	float px, py;
	Poco::XML::Element *child;

	svgtiny_parse_position_attributes(text, state,
			&x, &y, &width, &height);
	svgtiny_parse_font_attributes(text, &state);
	svgtiny_parse_transform_attributes(text, &state);

	px = state.ctm.a * x + state.ctm.c * y + state.ctm.e;
	py = state.ctm.b * x + state.ctm.d * y + state.ctm.f;
    
/* 	state.ctm.e = px - state.origin_x; */
/* 	state.ctm.f = py - state.origin_y; */

	/*struct css_style style = state.style;
	style.font_size.value.length.value *= state.ctm.a;*/

	//for (child = text->children; child; child = child->next) {
    //for( child = (Poco::XML::Element*) text->FirstChild( false ); child; child = (Poco::XML::Element*) child->NextSibling( false ) ) {
    
    
    Poco::XML::NodeIterator it(text, Poco::XML::NodeFilter::SHOW_ELEMENT | Poco::XML::NodeFilter::SHOW_TEXT);
    Poco::XML::Node* pNode = it.nextNode();
    while (pNode) {
    
		svgtiny_code code = svgtiny_OK;

		if (pNode->getNodeValue().compare("text") == 0) 
        {
			struct svgtiny_shape *shape = svgtiny_add_shape(&state);
			
            if (!shape)
				return svgtiny_OUT_OF_MEMORY;
            
			//shape->text = strdup((const char *) child->content);
            
            shape->text = strdup((const char *) pNode->getNodeValue().c_str());
            
			shape->text_x = px;
			shape->text_y = py;
			state.diagram->shape_count++;

		} 
        //else if (strcmp((const char *) child->Value(), "tspan") == 0) 
        else if (pNode->getNodeValue().compare("tspan") == 0) 
        {
			code = svgtiny_parse_text(child, state);
		}
    
        pNode = it.nextNode();

		if (!code != svgtiny_OK)
			return code;
	}

	return svgtiny_OK;
}