#include "SvgNode.h" #include "CircleNode.h" #include "PathNode.h" #include "SvgElement.h" #include "SvgShapeElements.h" SvgNode::SvgNode(const Transform& transform) : MaterialNode(transform) { } void SvgNode::setContent(std::unique_ptr doc) { mContent = std::move(doc); mContentDirty = true; mChildren.clear(); mGeometryNodes.clear(); } unsigned SvgNode::getContentWidth() const { return mContentWidth; } unsigned SvgNode::getContentHeight() const { return mContentHeight; } void SvgNode::createOrUpdateGeometry(SceneInfo*) { if (!mContent->getRoot()) { return; } //auto viewbox = mContent->getViewBox(); for (const auto& svg_element : mContent->getRoot()->getChildren()) { std::unique_ptr geom_node; if (svg_element->getTagName() == "circle") { onCircle(svg_element.get(), geom_node); } else if (svg_element->getTagName() == "path") { onPath(svg_element.get(), geom_node); } AbstractVisualNode* raw_node{ nullptr }; if (geom_node) { raw_node = geom_node.get(); mGeometryNodes.push_back(std::move(geom_node)); } if (raw_node) { addChild(raw_node); } } } void SvgNode::update(SceneInfo* sceneInfo) { if (mContent && mContentDirty) { createOrUpdateGeometry(sceneInfo); mContentDirty = false; } if (mMaterialIsDirty) { if (mMaterial->hasFillColor()) { for (const auto& geom_node : mGeometryNodes) { geom_node->setFillColor(mMaterial->getFillColor()); } } else { for (const auto& geom_node : mGeometryNodes) { geom_node->setHasFillColor(false); } } if (mMaterial->hasStrokeColor()) { for (const auto& geom_node : mGeometryNodes) { geom_node->setStrokeColor(mMaterial->getStrokeColor()); } } else { for (const auto& geom_node : mGeometryNodes) { geom_node->setHasStrokeColor(false); } } mMaterialIsDirty = false; } } void SvgNode::onCircle(XmlElement* element, std::unique_ptr& node) { auto svg_circle = dynamic_cast(element); auto loc = svg_circle->getLocation(); auto radius = svg_circle->getRadius(); auto minor_radius = radius; if (svg_circle->getType() == SvgCircle::Type::ELLIPSE) { minor_radius = svg_circle->getMinorRadius(); } if (element->hasAttribute("transform")) { const auto transform = svg_circle->getTransform(); loc.moveBy(transform.getLocation().getX(), transform.getLocation().getY()); radius *= transform.getScale().mX; minor_radius *= transform.getScale().mY; } auto circle_node = std::make_unique(Transform(Point<3>::from(loc)), radius); circle_node->setMinorRadius(minor_radius); node = std::move(circle_node); } void SvgNode::onPath(XmlElement* element, std::unique_ptr& node) { auto svg_path = dynamic_cast(element); Point loc; auto path_node = std::make_unique(loc, svg_path->getPath()); node = std::move(path_node); }