summaryrefslogtreecommitdiff
path: root/svgio/source
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2019-02-24 18:08:38 +0100
committerTomaž Vajngerl <quikee@gmail.com>2019-03-06 16:33:06 +0100
commit7894fd2b442eff45ecf14088ebd17ee9f8678752 (patch)
treecf1525a0c7118b6c84a0abd555a36277f8d8e91b /svgio/source
parentde5dc664fc923b9704860f51267c438cad28cbe4 (diff)
svgio visitor, add draw commands and create the from svg
Adds a visitor for svgio for visiting svg nodes and create something useful from them. Basic draw commands - a tree of draw commands (with sub-pixel precision support) just to store a simple definition for drawing. Adds a svg draw visitor and create draw commands from the svg structure and expose the commands through UNO API. Change-Id: I073e891a2cffdd76d4e3b838590e3a19c998e9bf Reviewed-on: https://gerrit.libreoffice.org/68770 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
Diffstat (limited to 'svgio/source')
-rw-r--r--svgio/source/svgreader/svgnode.cxx4
-rw-r--r--svgio/source/svgreader/svgvisitor.cxx105
-rw-r--r--svgio/source/svguno/xsvgparser.cxx116
3 files changed, 189 insertions, 36 deletions
diff --git a/svgio/source/svgreader/svgnode.cxx b/svgio/source/svgreader/svgnode.cxx
index 88b9a72ec196..cb30c3111131 100644
--- a/svgio/source/svgreader/svgnode.cxx
+++ b/svgio/source/svgreader/svgnode.cxx
@@ -673,6 +673,10 @@ namespace svgio
return XmlSpace_default;
}
+ void SvgNode::accept(Visitor & rVisitor)
+ {
+ rVisitor.visit(*this);
+ }
} // end of namespace svgreader
} // end of namespace svgio
diff --git a/svgio/source/svgreader/svgvisitor.cxx b/svgio/source/svgreader/svgvisitor.cxx
new file mode 100644
index 000000000000..841a1cb7022e
--- /dev/null
+++ b/svgio/source/svgreader/svgvisitor.cxx
@@ -0,0 +1,105 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#include <sal/config.h>
+#include <sal/log.hxx>
+
+#include <svgdocumenthandler.hxx>
+#include <svgrectnode.hxx>
+#include <svgsvgnode.hxx>
+#include <svggnode.hxx>
+#include <svgpathnode.hxx>
+
+#include <svgvisitor.hxx>
+
+namespace svgio
+{
+namespace svgreader
+{
+SvgDrawVisitor::SvgDrawVisitor()
+ : mpDrawRoot(std::make_shared<DrawRoot>())
+ , mpCurrent(mpDrawRoot)
+{
+}
+
+void SvgDrawVisitor::visit(svgio::svgreader::SvgNode const& rNode)
+{
+ switch (rNode.getType())
+ {
+ case svgio::svgreader::SVGTokenSvg:
+ {
+ auto const& rSvgNode = static_cast<svgio::svgreader::SvgSvgNode const&>(rNode);
+
+ double x = rSvgNode.getX().getNumber();
+ double y = rSvgNode.getY().getNumber();
+ double w = rSvgNode.getWidth().getNumber();
+ double h = rSvgNode.getHeight().getNumber();
+
+ static_cast<DrawRoot*>(mpCurrent.get())->maRectangle
+ = basegfx::B2DRange(x, y, x + w, y + h);
+ }
+ break;
+ case svgio::svgreader::SVGTokenG:
+ {
+ auto const& rGNode = static_cast<svgio::svgreader::SvgGNode const&>(rNode);
+
+ if (rGNode.getTransform() != nullptr)
+ {
+ basegfx::B2DHomMatrix rMatrix = *rGNode.getTransform();
+
+ printf("G [%f %f %f - %f %f %f - %f %f %f]\n", rMatrix.get(0, 0), rMatrix.get(0, 1),
+ rMatrix.get(0, 2), rMatrix.get(1, 0), rMatrix.get(1, 1), rMatrix.get(1, 2),
+ rMatrix.get(2, 0), rMatrix.get(2, 1), rMatrix.get(2, 2));
+ }
+ }
+ break;
+ case svgio::svgreader::SVGTokenRect:
+ {
+ auto const& rRectNode = static_cast<svgio::svgreader::SvgRectNode const&>(rNode);
+
+ double x = rRectNode.getX().getNumber();
+ double y = rRectNode.getY().getNumber();
+ double w = rRectNode.getWidth().getNumber();
+ double h = rRectNode.getHeight().getNumber();
+
+ auto pRectangle
+ = std::make_shared<DrawRectangle>(basegfx::B2DRange(x, y, x + w, y + h));
+ mpCurrent->maChildren.push_back(pRectangle);
+ }
+ break;
+ case svgio::svgreader::SVGTokenPath:
+ {
+ auto const& rPathNode = static_cast<svgio::svgreader::SvgPathNode const&>(rNode);
+ auto pPath = rPathNode.getPath();
+ if (pPath)
+ {
+ auto pDrawPath = std::make_shared<DrawPath>(*pPath);
+ mpCurrent->maChildren.push_back(pDrawPath);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ goToChildren(rNode);
+}
+
+void SvgDrawVisitor::goToChildren(svgio::svgreader::SvgNode const& rNode)
+{
+ for (auto& rChild : rNode.getChildren())
+ {
+ rChild->accept(*this);
+ }
+}
+}
+} // end of namespace svgio::svgreader
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svgio/source/svguno/xsvgparser.cxx b/svgio/source/svguno/xsvgparser.cxx
index 2f2a51c5c318..3ed675763f72 100644
--- a/svgio/source/svguno/xsvgparser.cxx
+++ b/svgio/source/svguno/xsvgparser.cxx
@@ -32,6 +32,8 @@
#include <drawinglayer/geometry/viewinformation2d.hxx>
#include <svgdocumenthandler.hxx>
+#include <svgvisitor.hxx>
+
#include "xsvgparser.hxx"
using namespace ::com::sun::star;
@@ -43,9 +45,11 @@ namespace svgio
class XSvgParser : public ::cppu::WeakAggImplHelper2< graphic::XSvgParser, lang::XServiceInfo >
{
private:
- uno::Reference< uno::XComponentContext > context_;
+ std::shared_ptr<SvgDrawVisitor> mpVisitor;
- protected:
+ uno::Reference< uno::XComponentContext > context_;
+ bool parseSvgXML(uno::Reference<io::XInputStream> const & xSVGStream,
+ uno::Reference<xml::sax::XDocumentHandler> const & xSvgDocHdl);
public:
explicit XSvgParser(
uno::Reference< uno::XComponentContext > const & context);
@@ -57,6 +61,10 @@ namespace svgio
const uno::Reference< ::io::XInputStream >& xSVGStream,
const OUString& aAbsolutePath) override;
+ virtual uno::Any SAL_CALL getDrawCommands(
+ uno::Reference<io::XInputStream> const & xSvgStream,
+ const OUString& aAbsolutePath) override;
+
// XServiceInfo
virtual OUString SAL_CALL getImplementationName() override;
virtual sal_Bool SAL_CALL supportsService(const OUString&) override;
@@ -97,6 +105,45 @@ namespace svgio
{
}
+ bool XSvgParser::parseSvgXML(uno::Reference<io::XInputStream> const & xSVGStream, uno::Reference<xml::sax::XDocumentHandler> const & xSvgDocHdl)
+ {
+ try
+ {
+ // prepare ParserInputSrouce
+ xml::sax::InputSource myInputSource;
+ myInputSource.aInputStream = xSVGStream;
+
+ // get parser
+ uno::Reference< xml::sax::XParser > xParser(
+ xml::sax::Parser::create(context_));
+ // fdo#60471 need to enable internal entities because
+ // certain ... popular proprietary products write SVG files
+ // that use entities to define XML namespaces.
+ uno::Reference<lang::XInitialization> const xInit(xParser,
+ uno::UNO_QUERY_THROW);
+ uno::Sequence<uno::Any> args(1);
+ args[0] <<= OUString("DoSmeplease");
+ xInit->initialize(args);
+
+ // connect parser and filter
+ xParser->setDocumentHandler(xSvgDocHdl);
+
+ // finally, parse the stream to a hierarchy of
+ // SVGGraphicPrimitive2D which will be embedded to the
+ // primitive sequence. Their decompositions will in the
+ // end create local low-level primitives, thus SVG will
+ // be processable from all our processors
+ xParser->parseStream(myInputSource);
+ }
+ catch(const uno::Exception& e)
+ {
+ SAL_WARN( "svg", "Parse error! : " << e);
+ return false;
+ }
+
+ return true;
+ }
+
uno::Sequence< uno::Reference< ::graphic::XPrimitive2D > > XSvgParser::getDecomposition(
const uno::Reference< ::io::XInputStream >& xSVGStream,
const OUString& aAbsolutePath )
@@ -107,40 +154,8 @@ namespace svgio
{
// local document handler
SvgDocHdl* pSvgDocHdl = new SvgDocHdl(aAbsolutePath);
- uno::Reference< xml::sax::XDocumentHandler > xSvgDocHdl(pSvgDocHdl);
-
- try
- {
- // prepare ParserInputSrouce
- xml::sax::InputSource myInputSource;
- myInputSource.aInputStream = xSVGStream;
-
- // get parser
- uno::Reference< xml::sax::XParser > xParser(
- xml::sax::Parser::create(context_));
- // fdo#60471 need to enable internal entities because
- // certain ... popular proprietary products write SVG files
- // that use entities to define XML namespaces.
- uno::Reference<lang::XInitialization> const xInit(xParser,
- uno::UNO_QUERY_THROW);
- uno::Sequence<uno::Any> args(1);
- args[0] <<= OUString("DoSmeplease");
- xInit->initialize(args);
-
- // connect parser and filter
- xParser->setDocumentHandler(xSvgDocHdl);
-
- // finally, parse the stream to a hierarchy of
- // SVGGraphicPrimitive2D which will be embedded to the
- // primitive sequence. Their decompositions will in the
- // end create local low-level primitives, thus SVG will
- // be processable from all our processors
- xParser->parseStream(myInputSource);
- }
- catch(const uno::Exception& e)
- {
- SAL_WARN( "svg", "Parse error! : " << e);
- }
+ uno::Reference<xml::sax::XDocumentHandler> xSvgDocHdl(pSvgDocHdl);
+ parseSvgXML(xSVGStream, xSvgDocHdl);
// decompose to primitives
for(std::unique_ptr<SvgNode> const & pCandidate : pSvgDocHdl->getSvgDocument().getSvgNodeVector())
@@ -159,6 +174,35 @@ namespace svgio
return comphelper::containerToSequence(aRetval);
}
+ uno::Any SAL_CALL XSvgParser::getDrawCommands(
+ uno::Reference<io::XInputStream> const & xSvgStream,
+ const OUString& aAbsolutePath)
+ {
+ uno::Any aAnyResult;
+
+ if (!xSvgStream.is())
+ return aAnyResult;
+
+ SvgDocHdl* pSvgDocHdl = new SvgDocHdl(aAbsolutePath);
+ uno::Reference<xml::sax::XDocumentHandler> xSvgDocHdl(pSvgDocHdl);
+ parseSvgXML(xSvgStream, xSvgDocHdl);
+
+ // decompose to primitives
+ for (std::unique_ptr<SvgNode> const & pCandidate : pSvgDocHdl->getSvgDocument().getSvgNodeVector())
+ {
+ if (Display_none != pCandidate->getDisplay())
+ {
+ mpVisitor = std::make_shared<SvgDrawVisitor>();
+ pCandidate->accept(*mpVisitor);
+ std::shared_ptr<DrawRoot> pDrawRoot(mpVisitor->getDrawRoot());
+ sal_uInt64 nPointer = reinterpret_cast<sal_uInt64>(pDrawRoot.get());
+ aAnyResult <<= sal_uInt64(nPointer);
+ }
+ }
+
+ return aAnyResult;
+ }
+
OUString SAL_CALL XSvgParser::getImplementationName()
{
return XSvgParser_getImplementationName();