summaryrefslogtreecommitdiff
path: root/svgio
diff options
context:
space:
mode:
authorArmin Le Grand <Armin.Le.Grand@cib.de>2018-06-07 09:44:02 +0200
committerArmin Le Grand <Armin.Le.Grand@cib.de>2018-06-13 13:40:04 +0200
commit3087011e2eb810866276e270a6fc61a7e0998fec (patch)
tree961c9b25d00f0258dd0c3eb4850e50b78367f7c8 /svgio
parent4a0ca73c31990568bf20a1c3f0906c3a5770a38e (diff)
Replace SVGFilter using SVGIO
Next step is to put more logic into the decision if Draw or Impress should be loaded - if we have a self-exported Impress, import as Impress, else (including all not-self-created SVG Graphics) import to Draw. To do this it is necessary to be able to import to different document formats at all. To do this, add an internal filter type to the filter mechanism (types/registration/...) and decide in the SVG XExtendedFilterDetection::detect from SVGFilter which one to use. Added tooling for SVG detection and more, see SVGFileInfo. This allows to detect for SVG, but also if the creator was LO and if it was Draw or Impress. The document format/filter is choosen accordingly. Corrected the error with <g visibility="hidden"> Slides inisde <g class="SlideGroup"> for import of self-exported Impress documents. No idea why this was written that way, but needs to be fixed to get a visible content at all. Also adapted the final mapping from pt to 100thmm in SvgSvgNode::decomposeSvgNode. Unfortunately (and also for unknown reasons) the self-exported Impress does not write svg:width/height values, thus the adaption from assumed svg-units (px) to 100thmm has to be skipped. Have identified the place in svgio where I can embed Pages/Slides to a helper-Primitive to later be able to 'break' such GraphicObjects to multiple Pages/Slides. I have added a Primitive called PageHierarchyPrimitive2D for this purpose. Change-Id: I38bfef6e7b16479a025fc754e38b4e21a006ad38 Reviewed-on: https://gerrit.libreoffice.org/55434 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Armin Le Grand <Armin.Le.Grand@cib.de>
Diffstat (limited to 'svgio')
-rw-r--r--svgio/source/svgreader/svgstyleattributes.cxx72
-rw-r--r--svgio/source/svgreader/svgsvgnode.cxx49
2 files changed, 104 insertions, 17 deletions
diff --git a/svgio/source/svgreader/svgstyleattributes.cxx b/svgio/source/svgreader/svgstyleattributes.cxx
index f1bc7c737aae..2d96cfb9d022 100644
--- a/svgio/source/svgreader/svgstyleattributes.cxx
+++ b/svgio/source/svgreader/svgstyleattributes.cxx
@@ -38,6 +38,7 @@
#include <drawinglayer/primitive2d/patternfillprimitive2d.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <drawinglayer/primitive2d/maskprimitive2d.hxx>
+#include <drawinglayer/primitive2d/pagehierarchyprimitive2d.hxx>
namespace svgio
{
@@ -1196,13 +1197,48 @@ namespace svgio
// #i124852# transform may be needed when userSpaceOnUse
pMask->apply(aSource, pTransform);
}
+ }
+
+ // This is part of the SVG import of self-written SVGs from
+ // Draw/Impress containing multiple Slides/Pages. To be able
+ // to later 'break' these to multiple Pages if wanted, embed
+ // each Page-Content in a identifiable Primitive Grouping
+ // Object.
+ // This is the case when the current Node is a GroupNode, has
+ // class="Page" set, has a parent that also is a GroupNode
+ // at which class="Slide" is set.
+ // Multiple Slides/Pages are possible for Draw and Impress.
+ if(SVGTokenG == mrOwner.getType() && mrOwner.getClass())
+ {
+ const OUString aOwnerClass(*mrOwner.getClass());
- if(!aSource.empty()) // test again, applied mask may have lead to empty geometry
+ if("Page" == aOwnerClass)
{
- // append to current target
- rTarget.append(aSource);
+ const SvgNode* pParent(mrOwner.getParent());
+
+ if(nullptr != pParent && SVGTokenG == pParent->getType() && pParent->getClass())
+ {
+ const OUString aParentClass(*pParent->getClass());
+
+ if("Slide" == aParentClass)
+ {
+ // embed to grouping primitive to identify the
+ // Slide/Page information
+ const drawinglayer::primitive2d::Primitive2DReference xRef(
+ new drawinglayer::primitive2d::PageHierarchyPrimitive2D(
+ aSource));
+
+ aSource = drawinglayer::primitive2d::Primitive2DContainer { xRef };
+ }
+ }
}
}
+
+ if(!aSource.empty()) // test again, applied mask may have lead to empty geometry
+ {
+ // append to current target
+ rTarget.append(aSource);
+ }
}
}
@@ -2216,6 +2252,36 @@ namespace svgio
return Visibility_visible;
}
+ // Visibility correction/exception for self-exported SVGs:
+ // When Impress exports single or multi-page SVGs, it puts the
+ // single slides into <g visibility="hidden">. Not sure why
+ // whis happens, but this leads (correctly) to empty imported
+ // Graphics.
+ // Thus, if Visibility_hidden is active and owner is a SVGTokenG
+ // and it's parent is also a SVGTokenG and it has a Class 'SlideGroup'
+ // set, check if we are an Impress export.
+ // We are an Impress export if an SVG-Node titled 'ooo:meta_slides'
+ // exists.
+ // All togehter gives:
+ if(Visibility_hidden == maVisibility
+ && SVGTokenG == mrOwner.getType()
+ && nullptr != mrOwner.getDocument().findSvgNodeById("ooo:meta_slides"))
+ {
+ const SvgNode* pParent(mrOwner.getParent());
+
+ if(nullptr != pParent && SVGTokenG == pParent->getType() && pParent->getClass())
+ {
+ const OUString aClass(*pParent->getClass());
+
+ if("SlideGroup" == aClass)
+ {
+ // if we detect this exception,
+ // ovverride Visibility_hidden -> Visibility_visible
+ return Visibility_visible;
+ }
+ }
+ }
+
return maVisibility;
}
diff --git a/svgio/source/svgreader/svgsvgnode.cxx b/svgio/source/svgreader/svgsvgnode.cxx
index 40dfaca1a402..524e6d360030 100644
--- a/svgio/source/svgreader/svgsvgnode.cxx
+++ b/svgio/source/svgreader/svgsvgnode.cxx
@@ -26,6 +26,7 @@
#include <basegfx/matrix/b2dhommatrixtools.hxx>
#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
#include <drawinglayer/primitive2d/hiddengeometryprimitive2d.hxx>
+#include <svgdocument.hxx>
namespace svgio
{
@@ -670,21 +671,41 @@ namespace svgio
if(!aSequence.empty())
{
- // embed in transform primitive to scale to 1/100th mm
- // where 1 inch == 25.4 mm to get from Svg coordinates (px) to
- // drawinglayer coordinates
- const double fScaleTo100thmm(25.4 * 100.0 / F_SVG_PIXEL_PER_INCH);
- const basegfx::B2DHomMatrix aTransform(
- basegfx::utils::createScaleB2DHomMatrix(
- fScaleTo100thmm,
- fScaleTo100thmm));
-
- const drawinglayer::primitive2d::Primitive2DReference xTransform(
- new drawinglayer::primitive2d::TransformPrimitive2D(
- aTransform,
- aSequence));
+ // Another correction:
+ // If no Width/Height is set (usually done in
+ // <svg ... width="215.9mm" height="279.4mm" >) which
+ // is the case for own-Impress-exports, assume that
+ // the Units are alrteady 100ThMM.
+ // Maybe only for own-Impress-exports, thus may need to be
+ // &&ed with getDocument().findSvgNodeById("ooo:meta_slides"),
+ // but does not need to be.
+ bool bEmbedInFinalTransformPxTo100ThMM(true);
+
+ if(getDocument().findSvgNodeById("ooo:meta_slides")
+ && !getWidth().isSet()
+ && !getHeight().isSet())
+ {
+ bEmbedInFinalTransformPxTo100ThMM = false;
+ }
+
+ if(bEmbedInFinalTransformPxTo100ThMM)
+ {
+ // embed in transform primitive to scale to 1/100th mm
+ // where 1 inch == 25.4 mm to get from Svg coordinates (px) to
+ // drawinglayer coordinates
+ const double fScaleTo100thmm(25.4 * 100.0 / F_SVG_PIXEL_PER_INCH);
+ const basegfx::B2DHomMatrix aTransform(
+ basegfx::utils::createScaleB2DHomMatrix(
+ fScaleTo100thmm,
+ fScaleTo100thmm));
+
+ const drawinglayer::primitive2d::Primitive2DReference xTransform(
+ new drawinglayer::primitive2d::TransformPrimitive2D(
+ aTransform,
+ aSequence));
- aSequence = drawinglayer::primitive2d::Primitive2DContainer { xTransform };
+ aSequence = drawinglayer::primitive2d::Primitive2DContainer { xTransform };
+ }
// append to result
rTarget.append(aSequence);