summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drawinglayer/Library_drawinglayer.mk1
-rw-r--r--drawinglayer/source/primitive2d/baseprimitive2d.cxx1
-rwxr-xr-xdrawinglayer/source/primitive2d/pagehierarchyprimitive2d.cxx40
-rw-r--r--filter/Configuration_filter.mk3
-rwxr-xr-xfilter/source/config/fragments/filters/SVG___Scalable_Vector_Graphics_Draw.xcu30
-rw-r--r--filter/source/config/fragments/types/svg_Scalable_Vector_Graphics.xcu2
-rwxr-xr-xfilter/source/config/fragments/types/svg_Scalable_Vector_Graphics_Draw.xcu29
-rw-r--r--filter/source/svg/svgfilter.cxx260
-rw-r--r--filter/source/svg/svgfilter.hxx3
-rw-r--r--include/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx1
-rwxr-xr-xinclude/drawinglayer/primitive2d/pagehierarchyprimitive2d.hxx52
-rw-r--r--solenv/clang-format/blacklist2
-rw-r--r--svgio/source/svgreader/svgstyleattributes.cxx72
-rw-r--r--svgio/source/svgreader/svgsvgnode.cxx49
14 files changed, 463 insertions, 82 deletions
diff --git a/drawinglayer/Library_drawinglayer.mk b/drawinglayer/Library_drawinglayer.mk
index 91c137d56c29..26b6a9c37ba4 100644
--- a/drawinglayer/Library_drawinglayer.mk
+++ b/drawinglayer/Library_drawinglayer.mk
@@ -95,6 +95,7 @@ $(eval $(call gb_Library_add_exception_objects,drawinglayer,\
drawinglayer/source/primitive2d/metafileprimitive2d \
drawinglayer/source/primitive2d/modifiedcolorprimitive2d \
drawinglayer/source/primitive2d/objectinfoprimitive2d \
+ drawinglayer/source/primitive2d/pagehierarchyprimitive2d \
drawinglayer/source/primitive2d/pagepreviewprimitive2d \
drawinglayer/source/primitive2d/patternfillprimitive2d \
drawinglayer/source/primitive2d/pointarrayprimitive2d \
diff --git a/drawinglayer/source/primitive2d/baseprimitive2d.cxx b/drawinglayer/source/primitive2d/baseprimitive2d.cxx
index cd45da11bae5..d9fac66c63dd 100644
--- a/drawinglayer/source/primitive2d/baseprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/baseprimitive2d.cxx
@@ -367,6 +367,7 @@ namespace drawinglayer
case PRIMITIVE2D_ID_PATTERNFILLPRIMITIVE2D: return OUString("PATTERNFILL");
case PRIMITIVE2D_ID_OBJECTINFOPRIMITIVE2D: return OUString("OBJECTINFO");
case PRIMITIVE2D_ID_POLYPOLYGONSELECTIONPRIMITIVE2D: return OUString("POLYPOLYGONSELECTION");
+ case PRIMITIVE2D_ID_PAGEHIERARCHYPRIMITIVE2D: return OUString("PAGEHIERARCHY");
default: return OUString::number((nId >> 16) & 0xFF) + "|" + OUString::number(nId & 0xFF);
}
}
diff --git a/drawinglayer/source/primitive2d/pagehierarchyprimitive2d.cxx b/drawinglayer/source/primitive2d/pagehierarchyprimitive2d.cxx
new file mode 100755
index 000000000000..19225b01e9a6
--- /dev/null
+++ b/drawinglayer/source/primitive2d/pagehierarchyprimitive2d.cxx
@@ -0,0 +1,40 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <drawinglayer/primitive2d/pagehierarchyprimitive2d.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+
+using namespace com::sun::star;
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ PageHierarchyPrimitive2D::PageHierarchyPrimitive2D(const Primitive2DContainer& rChildren)
+ : GroupPrimitive2D(rChildren)
+ {
+ }
+
+ // provide unique ID
+ ImplPrimitive2DIDBlock(PageHierarchyPrimitive2D, PRIMITIVE2D_ID_PAGEHIERARCHYPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/filter/Configuration_filter.mk b/filter/Configuration_filter.mk
index 35d7620f6f70..d7a6322e5564 100644
--- a/filter/Configuration_filter.mk
+++ b/filter/Configuration_filter.mk
@@ -695,6 +695,7 @@ $(eval $(call filter_Configuration_add_types,fcfg_langpack,fcfg_drawgraphics_typ
ppm_Portable_Pixelmap \
psd_Adobe_Photoshop \
ras_Sun_Rasterfile \
+ svg_Scalable_Vector_Graphics_Draw \
svg_Scalable_Vector_Graphics \
svm_StarView_Metafile \
tga_Truevision_TARGA \
@@ -721,6 +722,7 @@ $(eval $(call filter_Configuration_add_filters,fcfg_langpack,fcfg_drawgraphics_f
PPM___Portable_Pixelmap \
PSD___Adobe_Photoshop \
RAS___Sun_Rasterfile \
+ SVG___Scalable_Vector_Graphics_Draw \
SVG___Scalable_Vector_Graphics \
SVM___StarView_Metafile \
TGA___Truevision_TARGA \
@@ -761,6 +763,7 @@ $(eval $(call filter_Configuration_add_types,fcfg_langpack,fcfg_impressgraphics_
png_Portable_Network_Graphic \
ppm_Portable_Pixelmap \
ras_Sun_Rasterfile \
+ svg_Scalable_Vector_Graphics_Draw \
svg_Scalable_Vector_Graphics \
svm_StarView_Metafile \
tif_Tag_Image_File \
diff --git a/filter/source/config/fragments/filters/SVG___Scalable_Vector_Graphics_Draw.xcu b/filter/source/config/fragments/filters/SVG___Scalable_Vector_Graphics_Draw.xcu
new file mode 100755
index 000000000000..eb98d7f940e8
--- /dev/null
+++ b/filter/source/config/fragments/filters/SVG___Scalable_Vector_Graphics_Draw.xcu
@@ -0,0 +1,30 @@
+<!--
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+-->
+ <node oor:name="SVG - Scalable Vector Graphics Draw" oor:op="replace">
+ <prop oor:name="Flags"><value>IMPORT ALIEN 3RDPARTYFILTER PREFERRED</value></prop>
+ <prop oor:name="UIComponent"/>
+ <prop oor:name="FilterService"><value>com.sun.star.comp.Draw.SVGFilter</value></prop>
+ <prop oor:name="UserData"><value></value></prop>
+ <prop oor:name="UIName">
+ <value xml:lang="en-US">SVG - Scalable Vector Graphics Draw</value>
+ </prop>
+ <prop oor:name="FileFormatVersion"><value>0</value></prop>
+ <prop oor:name="Type"><value>svg_Scalable_Vector_Graphics_Draw</value></prop>
+ <prop oor:name="TemplateName"/>
+ <prop oor:name="DocumentService"><value>com.sun.star.drawing.DrawingDocument</value></prop>
+ </node>
diff --git a/filter/source/config/fragments/types/svg_Scalable_Vector_Graphics.xcu b/filter/source/config/fragments/types/svg_Scalable_Vector_Graphics.xcu
index f811f9bb9c9e..a2015a536873 100644
--- a/filter/source/config/fragments/types/svg_Scalable_Vector_Graphics.xcu
+++ b/filter/source/config/fragments/types/svg_Scalable_Vector_Graphics.xcu
@@ -20,7 +20,7 @@
<prop oor:name="URLPattern"/>
<prop oor:name="Extensions"><value>svg svgz</value></prop>
<prop oor:name="MediaType"><value>image/svg+xml</value></prop>
- <prop oor:name="Preferred"><value>true</value></prop>
+ <prop oor:name="Preferred"><value>false</value></prop>
<prop oor:name="PreferredFilter"><value>SVG - Scalable Vector Graphics</value></prop>
<prop oor:name="UIName">
<value>SVG - Scalable Vector Graphics</value>
diff --git a/filter/source/config/fragments/types/svg_Scalable_Vector_Graphics_Draw.xcu b/filter/source/config/fragments/types/svg_Scalable_Vector_Graphics_Draw.xcu
new file mode 100755
index 000000000000..4b3b9cab58b1
--- /dev/null
+++ b/filter/source/config/fragments/types/svg_Scalable_Vector_Graphics_Draw.xcu
@@ -0,0 +1,29 @@
+<!--
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+-->
+ <node oor:name="svg_Scalable_Vector_Graphics_Draw" oor:op="replace" >
+ <prop oor:name="DetectService"><value>com.sun.star.comp.Draw.SVGFilter</value></prop>
+ <prop oor:name="URLPattern"/>
+ <prop oor:name="Extensions"><value>svg svgz</value></prop>
+ <prop oor:name="MediaType"><value>image/svg+xml</value></prop>
+ <prop oor:name="Preferred"><value>true</value></prop>
+ <prop oor:name="PreferredFilter"><value>SVG - Scalable Vector Graphics Draw</value></prop>
+ <prop oor:name="UIName">
+ <value>SVG - Scalable Vector Graphics Draw</value>
+ </prop>
+ <prop oor:name="ClipboardFormat"/>
+ </node>
diff --git a/filter/source/svg/svgfilter.cxx b/filter/source/svg/svgfilter.cxx
index 1ec09f65ab05..ddc81b4f89e5 100644
--- a/filter/source/svg/svgfilter.cxx
+++ b/filter/source/svg/svgfilter.cxx
@@ -64,6 +64,7 @@ using namespace ::com::sun::star;
namespace
{
+ static const char constFilterNameDraw[] = "svg_Scalable_Vector_Graphics_Draw";
static const char constFilterName[] = "svg_Scalable_Vector_Graphics";
}
@@ -254,19 +255,22 @@ sal_Bool SAL_CALL SVGFilter::filter( const Sequence< PropertyValue >& rDescripto
// pTargetSdrPage->SetBorder(...) and
// pTargetSdrPage->SetSize(...),
// but ::adaptSizeAndBorderForAllPages
+ // Do use original Size and borders to get as close to original
+ // as possible for better turn-arounds.
pTargetSdrPage->getSdrModelFromSdrPage().adaptSizeAndBorderForAllPages(
Size(
- aGraphicSize.Width() + nAllBorder + nAllBorder,
- aGraphicSize.Height() + nAllBorder + nAllBorder),
+ aGraphicSize.Width(),
+ aGraphicSize.Height()),
nAllBorder,
nAllBorder,
nAllBorder,
nAllBorder);
- // set pos/size at SdrGraphicObj - add offset to PageBorder
+ // set pos/size at SdrGraphicObj - use zero position for
+ // better turn-around results
aNewSdrGrafObj->SetSnapRect(
tools::Rectangle(
- Point(nAllBorder, nAllBorder),
+ Point(0, 0),
aGraphicSize));
// insert to page (owner change of SdrGrafObj)
@@ -472,86 +476,220 @@ void SAL_CALL SVGFilter::setTargetDocument( const Reference< XComponent >& xDoc
mxDstDoc = xDoc;
}
-bool SVGFilter::isStreamGZip(const uno::Reference<io::XInputStream>& xInput)
+// There is already another SVG-Type_Detector, see
+// vcl/source/filter/graphicfilter.cxx ("DOCTYPE svg"),
+// but since these start from different preconditions it is not
+// easy to unify these. For now, use this local helper.
+class SVGFileInfo
{
- uno::Reference<io::XSeekable> xSeek(xInput, uno::UNO_QUERY);
- if(xSeek.is())
- xSeek->seek(0);
-
- uno::Sequence<sal_Int8> aBuffer(2);
- const sal_uInt64 nBytes = xInput->readBytes(aBuffer, 2);
- if (nBytes == 2)
+private:
+ const uno::Reference<io::XInputStream>& mxInput;
+ uno::Sequence< sal_Int8 > mnFirstBytes;
+ sal_Int32 mnFirstBytesSize;
+ sal_uInt64 mnFirstRead;
+ bool mbProcessed;
+ bool mbIsSVG;
+
+ bool impCheckForMagic(
+ const sal_Int8* pMagic,
+ const sal_Int32 nMagicSize)
{
- const sal_Int8* pBuffer = aBuffer.getConstArray();
- if (pBuffer[0] == 0x1F && static_cast<sal_uInt8>(pBuffer[1]) == 0x8B)
- return true;
+ const sal_Int8* pBuffer(mnFirstBytes.getConstArray());
+ return std::search(
+ pBuffer,
+ pBuffer + mnFirstRead,
+ pMagic,
+ pMagic + nMagicSize) != pBuffer + mnFirstRead;
}
- return false;
-}
-bool SVGFilter::isStreamSvg(const uno::Reference<io::XInputStream>& xInput)
-{
- uno::Reference<io::XSeekable> xSeek(xInput, uno::UNO_QUERY);
- if(xSeek.is())
- xSeek->seek(0);
+ void impEnsureProcessed()
+ {
+ if(mbProcessed)
+ {
+ return;
+ }
- const sal_Int32 nLookAhead = 1024;
- uno::Sequence<sal_Int8> aBuffer(nLookAhead);
- const sal_uInt64 nBytes = xInput->readBytes(aBuffer, nLookAhead);
- const sal_Int8* pBuffer = aBuffer.getConstArray();
+ mbProcessed = true;
- sal_Int8 aMagic1[] = {'<', 's', 'v', 'g'};
- sal_Int32 const aMagic1Size = SAL_N_ELEMENTS(aMagic1);
+ if(!mxInput.is())
+ {
+ return;
+ }
- if (std::search(pBuffer, pBuffer + nBytes, aMagic1, aMagic1 + aMagic1Size) != pBuffer + nBytes )
- return true;
+ if(0 == mnFirstBytesSize)
+ {
+ return;
+ }
- sal_Int8 aMagic2[] = {'D', 'O', 'C', 'T', 'Y', 'P', 'E', ' ', 's', 'v', 'g'};
- sal_Int32 const aMagic2Size = SAL_N_ELEMENTS(aMagic2);
+ mnFirstBytes.realloc(mnFirstBytesSize);
- return std::search(pBuffer, pBuffer + nBytes, aMagic2, aMagic2 + aMagic2Size) != pBuffer + nBytes;
-}
+ if(mnFirstBytesSize != mnFirstBytes.getLength())
+ {
+ return;
+ }
-OUString SAL_CALL SVGFilter::detect(Sequence<PropertyValue>& rDescriptor)
-{
- utl::MediaDescriptor aMediaDescriptor(rDescriptor);
- uno::Reference<io::XInputStream> xInput(aMediaDescriptor[utl::MediaDescriptor::PROP_INPUTSTREAM()], UNO_QUERY);
+ std::unique_ptr< SvStream > aStream(utl::UcbStreamHelper::CreateStream(mxInput, true));
- if (!xInput.is())
- return OUString();
+ if(!aStream.get())
+ {
+ return;
+ }
+
+ const sal_uLong nStreamPos(aStream->Tell());
+ aStream->Seek(STREAM_SEEK_TO_END);
+ const sal_uLong nStreamLen(aStream->Tell() - nStreamPos);
+ aStream->Seek(nStreamPos);
- try {
- if (isStreamGZip(xInput))
+ if(aStream->GetError())
{
- std::unique_ptr<SvStream> aStream(utl::UcbStreamHelper::CreateStream(xInput, true ));
- if(!aStream.get())
- return OUString();
+ return;
+ }
+
+ mnFirstRead = aStream->ReadBytes(
+ &mnFirstBytes[0],
+ std::min(nStreamLen, sal_uLong(mnFirstBytesSize)));
- SvStream* pMemoryStream = new SvMemoryStream;
- uno::Reference<io::XSeekable> xSeek(xInput, uno::UNO_QUERY);
- if (!xSeek.is())
- return OUString();
- xSeek->seek(0);
+ if(aStream->GetError())
+ {
+ return;
+ }
+ // check if it is gzipped -> svgz
+ if(mnFirstBytes[0] == 0x1F && static_cast<sal_uInt8>(mnFirstBytes[1]) == 0x8B)
+ {
ZCodec aCodec;
- aCodec.BeginCompression(ZCODEC_DEFAULT_COMPRESSION, false, true);
- aCodec.Decompress(*aStream.get(), *pMemoryStream);
+
+ aCodec.BeginCompression(
+ ZCODEC_DEFAULT_COMPRESSION,
+ false,
+ true);
+ mnFirstRead = aCodec.Read(
+ *aStream,
+ reinterpret_cast< sal_uInt8* >(mnFirstBytes.getArray()),
+ mnFirstBytesSize);
aCodec.EndCompression();
- pMemoryStream->Seek(STREAM_SEEK_TO_BEGIN);
- uno::Reference<io::XInputStream> xDecompressedInput(new utl::OSeekableInputStreamWrapper(pMemoryStream, true));
+ }
+
+ if(!mbIsSVG)
+ {
+ const sal_Int8 aMagic[] = {'<', 's', 'v', 'g'};
+ const sal_Int32 nMagicSize(SAL_N_ELEMENTS(aMagic));
- if (xDecompressedInput.is() && isStreamSvg(xDecompressedInput))
- return OUString(constFilterName);
+ mbIsSVG = impCheckForMagic(aMagic, nMagicSize);
}
- else
+
+ if(!mbIsSVG)
{
- if (isStreamSvg(xInput))
- return OUString(constFilterName);
+ const sal_Int8 aMagic[] = {'D', 'O', 'C', 'T', 'Y', 'P', 'E', ' ', 's', 'v', 'g'};
+ const sal_Int32 nMagicSize(SAL_N_ELEMENTS(aMagic));
+
+ mbIsSVG = impCheckForMagic(aMagic, nMagicSize);
}
- } catch (css::io::IOException & e) {
+
+ return;
+ }
+
+public:
+ SVGFileInfo(
+ const uno::Reference<io::XInputStream>& xInput,
+ sal_Int32 nFirstBytesSize = 4096)
+ : mxInput(xInput),
+ mnFirstBytes(),
+ mnFirstBytesSize(nFirstBytesSize),
+ mnFirstRead(0),
+ mbProcessed(false),
+ mbIsSVG(false)
+ {
+ // For the default buffer size: Use not too big
+ // (not more than 16K), but also not too small
+ // (not less than 1/2K), see comments at
+ // ImpPeekGraphicFormat, SVG section.
+ // I remember these cases and it *can* happen
+ // that SVGs have quite massive comments in their
+ // headings (!)
+ // Limit to plausible sizes, also for security reasons
+ mnFirstBytesSize = std::min(sal_Int32(512), mnFirstBytesSize);
+ mnFirstBytesSize = std::max(sal_Int32(16384), mnFirstBytesSize);
+ }
+
+ bool isSVG()
+ {
+ impEnsureProcessed();
+
+ return mbIsSVG;
+ }
+
+ bool isOwnFormat()
+ {
+ impEnsureProcessed();
+
+ if(mbIsSVG)
+ {
+ // xmlns:ooo
+ const sal_Int8 aMagic[] = {'x', 'm', 'l', 'n', 's', ':', 'o', 'o', 'o'};
+ const sal_Int32 nMagicSize(SAL_N_ELEMENTS(aMagic));
+
+ return impCheckForMagic(aMagic, nMagicSize);
+ }
+
+ return false;
+ }
+
+ bool isImpress()
+ {
+ impEnsureProcessed();
+
+ if(mbIsSVG)
+ {
+ // ooo:meta_slides
+ const sal_Int8 aMagic[] = {'o', 'o', 'o', ':', 'm', 'e', 't', 'a', '_', 's', 'l', 'i', 'd', 'e', 's'};
+ const sal_Int32 nMagicSize(SAL_N_ELEMENTS(aMagic));
+
+ return impCheckForMagic(aMagic, nMagicSize);
+ }
+
+ return false;
+ }
+};
+
+OUString SAL_CALL SVGFilter::detect(Sequence<PropertyValue>& rDescriptor)
+{
+ utl::MediaDescriptor aMediaDescriptor(rDescriptor);
+ uno::Reference<io::XInputStream> xInput(aMediaDescriptor[utl::MediaDescriptor::PROP_INPUTSTREAM()], UNO_QUERY);
+ OUString aRetval;
+
+ if (!xInput.is())
+ {
+ return aRetval;
+ }
+
+ try
+ {
+ SVGFileInfo aSVGFileInfo(xInput, 2048);
+
+ if(aSVGFileInfo.isSVG())
+ {
+ // We have SVG - set default document format to Draw
+ aRetval = OUString(constFilterNameDraw);
+
+ if(aSVGFileInfo.isOwnFormat())
+ {
+ // it's a file that was written/exported by LO
+ if(aSVGFileInfo.isImpress())
+ {
+ // it was written by Impress export. Set document
+ // format for import to Impress
+ aRetval = OUString(constFilterName);
+ }
+ }
+ }
+ }
+ catch (css::io::IOException & e)
+ {
SAL_WARN("filter.svg", "caught " << e);
}
- return OUString();
+
+ return aRetval;
}
#define SVG_FILTER_IMPL_NAME "com.sun.star.comp.Draw.SVGFilter"
diff --git a/filter/source/svg/svgfilter.hxx b/filter/source/svg/svgfilter.hxx
index 5f117c3310ee..1b5254e25469 100644
--- a/filter/source/svg/svgfilter.hxx
+++ b/filter/source/svg/svgfilter.hxx
@@ -266,9 +266,6 @@ private:
const Reference< XPropertySetInfo > & rxPropSetInfo );
DECL_LINK( CalcFieldHdl, EditFieldInfo*, void );
- static bool isStreamGZip(const css::uno::Reference<css::io::XInputStream>& xInput);
- static bool isStreamSvg(const css::uno::Reference<css::io::XInputStream>& xInput);
-
protected:
// XFilter
diff --git a/include/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx b/include/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx
index 7dcc2455effb..98d009deda6b 100644
--- a/include/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx
+++ b/include/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx
@@ -102,6 +102,7 @@
#define PRIMITIVE2D_ID_PATTERNFILLPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 67)
#define PRIMITIVE2D_ID_OBJECTINFOPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 68)
#define PRIMITIVE2D_ID_POLYPOLYGONSELECTIONPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 69)
+#define PRIMITIVE2D_ID_PAGEHIERARCHYPRIMITIVE2D (PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 70)
// When you add a new primitive, please update the drawinglayer::primitive2d::idToString() function
// in drawinglayer/source/primitive2d/baseprimitive2d.cxx.
diff --git a/include/drawinglayer/primitive2d/pagehierarchyprimitive2d.hxx b/include/drawinglayer/primitive2d/pagehierarchyprimitive2d.hxx
new file mode 100755
index 000000000000..e2c9b1d603ab
--- /dev/null
+++ b/include/drawinglayer/primitive2d/pagehierarchyprimitive2d.hxx
@@ -0,0 +1,52 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_DRAWINGLAYER_PRIMITIVE2D_PAGEHIERARCHYPRIMITIVE2D_HXX
+#define INCLUDED_DRAWINGLAYER_PRIMITIVE2D_PAGEHIERARCHYPRIMITIVE2D_HXX
+
+#include <drawinglayer/drawinglayerdllapi.h>
+
+#include <drawinglayer/primitive2d/groupprimitive2d.hxx>
+#include <rtl/ustring.hxx>
+
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ /** PageHierarchyPrimitive2D class
+
+ This primitive encapsulates text lines.
+ */
+ class DRAWINGLAYER_DLLPUBLIC PageHierarchyPrimitive2D : public GroupPrimitive2D
+ {
+ private:
+ public:
+ /// constructor
+ explicit PageHierarchyPrimitive2D(const Primitive2DContainer& rChildren);
+
+ /// provide unique ID
+ DeclPrimitive2DIDBlock()
+ };
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+#endif //INCLUDED_DRAWINGLAYER_PRIMITIVE2D_PAGEHIERARCHYPRIMITIVE2D_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/solenv/clang-format/blacklist b/solenv/clang-format/blacklist
index 79c639c82cb9..a0e79ad167dc 100644
--- a/solenv/clang-format/blacklist
+++ b/solenv/clang-format/blacklist
@@ -3941,6 +3941,7 @@ drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx
drawinglayer/source/primitive2d/texteffectprimitive2d.cxx
drawinglayer/source/primitive2d/textenumsprimitive2d.cxx
drawinglayer/source/primitive2d/texthierarchyprimitive2d.cxx
+drawinglayer/source/primitive2d/pagehierarchyprimitive2d.cxx
drawinglayer/source/primitive2d/textlayoutdevice.cxx
drawinglayer/source/primitive2d/textlineprimitive2d.cxx
drawinglayer/source/primitive2d/textprimitive2d.cxx
@@ -6281,6 +6282,7 @@ include/drawinglayer/primitive2d/textdecoratedprimitive2d.hxx
include/drawinglayer/primitive2d/texteffectprimitive2d.hxx
include/drawinglayer/primitive2d/textenumsprimitive2d.hxx
include/drawinglayer/primitive2d/texthierarchyprimitive2d.hxx
+include/drawinglayer/primitive2d/pagehierarchyprimitive2d.hxx
include/drawinglayer/primitive2d/textlayoutdevice.hxx
include/drawinglayer/primitive2d/textlineprimitive2d.hxx
include/drawinglayer/primitive2d/textprimitive2d.hxx
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);