summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Repository.mk1
-rw-r--r--compilerplugins/clang/store/constantfunction.cxx4
-rw-r--r--filter/Executable_svg2odf.mk46
-rw-r--r--filter/Library_svgfilter.mk6
-rw-r--r--filter/Module_filter.mk6
-rw-r--r--filter/inc/parserfragments.hxx69
-rw-r--r--filter/inc/svgreader.hxx47
-rw-r--r--filter/source/config/fragments/filters/SVG___Scalable_Vector_Graphics.xcu2
-rw-r--r--filter/source/svg/b2dellipse.cxx27
-rw-r--r--filter/source/svg/b2dellipse.hxx51
-rw-r--r--filter/source/svg/parserfragments.cxx587
-rw-r--r--filter/source/svg/svgfilter.cxx187
-rw-r--r--filter/source/svg/svgfilter.hxx3
-rw-r--r--filter/source/svg/svgimport.cxx119
-rw-r--r--filter/source/svg/svgreader.cxx2304
-rw-r--r--filter/source/svg/test/parsertest.cxx172
-rw-r--r--filter/source/svg/test/svg2odf.cxx134
-rw-r--r--filter/source/svg/tokenmap.cxx74
-rw-r--r--filter/source/svg/tokenmap.hxx27
-rw-r--r--filter/source/svg/units.cxx143
-rw-r--r--filter/source/svg/units.hxx59
-rw-r--r--include/svx/svdmodel.hxx10
-rw-r--r--sd/inc/drawdoc.hxx31
-rw-r--r--sd/source/core/drawdoc.cxx176
-rw-r--r--sd/source/ui/view/viewshe2.cxx167
-rw-r--r--svx/source/svdraw/svdmodel.cxx12
26 files changed, 454 insertions, 4010 deletions
diff --git a/Repository.mk b/Repository.mk
index 4cd3f1036637..7a019e2d311b 100644
--- a/Repository.mk
+++ b/Repository.mk
@@ -53,7 +53,6 @@ $(eval $(call gb_Helper_register_executables,NONE, \
regsvrex \
saxparser \
sp2bv \
- svg2odf \
svidl \
$(if $(ENABLE_ONLINE_UPDATE_MAR),\
test_updater_dialog \
diff --git a/compilerplugins/clang/store/constantfunction.cxx b/compilerplugins/clang/store/constantfunction.cxx
index 19c28df00db5..f3dd4f8a39c5 100644
--- a/compilerplugins/clang/store/constantfunction.cxx
+++ b/compilerplugins/clang/store/constantfunction.cxx
@@ -109,10 +109,6 @@ bool ConstantFunction::VisitFunctionDecl(const FunctionDecl * pFunctionDecl) {
if (aFileName == SRCDIR "/extensions/source/plugin/unx/npnapi.cxx") {
return true;
}
- // template magic
- if (aFileName == SRCDIR "/filter/source/svg/svgreader.cxx") {
- return true;
- }
// vcl/unx/gtk3 re-using vcl/unx/gtk:
if (aFileName.find("/../../gtk/") != std::string::npos) {
return true;
diff --git a/filter/Executable_svg2odf.mk b/filter/Executable_svg2odf.mk
deleted file mode 100644
index d63808600bb1..000000000000
--- a/filter/Executable_svg2odf.mk
+++ /dev/null
@@ -1,46 +0,0 @@
-# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
-#
-# 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/.
-#
-
-$(eval $(call gb_Executable_Executable,svg2odf))
-
-$(eval $(call gb_Executable_set_targettype_gui,svg2odf,YES))
-
-$(eval $(call gb_Executable_use_external,svg2odf,boost_headers))
-
-$(eval $(call gb_Executable_use_sdk_api,svg2odf))
-
-$(eval $(call gb_Executable_set_include,svg2odf,\
- $$(INCLUDE) \
- -I$(SRCDIR)/filter/inc \
-))
-
-$(eval $(call gb_Executable_use_libraries,svg2odf,\
- svgfilter \
- svxcore \
- editeng \
- xo \
- svt \
- vcl \
- svl \
- utl \
- tl \
- sax \
- comphelper \
- basegfx \
- cppuhelper \
- cppu \
- sal \
-))
-
-$(eval $(call gb_Executable_add_exception_objects,svg2odf,\
- filter/source/svg/test/svg2odf \
- filter/source/svg/test/odfserializer \
-))
-
-# vim: set ts=4 sw=4 et:
diff --git a/filter/Library_svgfilter.mk b/filter/Library_svgfilter.mk
index 9708b8ca6ed8..bdd917a50a0c 100644
--- a/filter/Library_svgfilter.mk
+++ b/filter/Library_svgfilter.mk
@@ -68,13 +68,7 @@ $(eval $(call gb_Library_use_externals,svgfilter,\
))
$(eval $(call gb_Library_add_exception_objects,svgfilter,\
- filter/source/svg/b2dellipse \
- filter/source/svg/parserfragments \
filter/source/svg/svgfilter \
- filter/source/svg/svgimport \
- filter/source/svg/svgreader \
- filter/source/svg/tokenmap \
- filter/source/svg/units \
filter/source/svg/svgexport \
filter/source/svg/svgfontexport \
filter/source/svg/svgwriter \
diff --git a/filter/Module_filter.mk b/filter/Module_filter.mk
index 08aa0f2d395b..2d380fbd91ac 100644
--- a/filter/Module_filter.mk
+++ b/filter/Module_filter.mk
@@ -47,12 +47,6 @@ $(eval $(call gb_Module_add_l10n_targets,filter,\
AllLangMoTarget_flt \
))
-ifneq (,$(filter DESKTOP,$(BUILD_TYPE)))
-$(eval $(call gb_Module_add_targets,filter,\
- Executable_svg2odf \
-))
-endif
-
$(eval $(call gb_Module_add_check_targets,filter,\
CppunitTest_filter_xslt \
CppunitTest_filter_priority \
diff --git a/filter/inc/parserfragments.hxx b/filter/inc/parserfragments.hxx
deleted file mode 100644
index f8b456029892..000000000000
--- a/filter/inc/parserfragments.hxx
+++ /dev/null
@@ -1,69 +0,0 @@
-/* -*- 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/.
- */
-#ifndef INCLUDED_FILTER_INC_PARSERFRAGMENTS_HXX
-#define INCLUDED_FILTER_INC_PARSERFRAGMENTS_HXX
-
-#include <sal/config.h>
-#include <vector>
-#include <utility>
-#include <rtl/ustring.hxx>
-
-namespace basegfx
-{
- class B2DHomMatrix;
- class B2DRange;
-}
-namespace svgi
-{
- struct ARGBColor;
-
- /// Parse given string for one of the SVG color grammars
- bool parseColor( const char* sColor, ARGBColor& rColor );
- bool parseOpacity( const char* sOpacity, ARGBColor& rColor );
-
- /// Parse given string for one of the SVG transformation grammars
- bool parseTransform( const char* sTransform, basegfx::B2DHomMatrix& rTransform );
-
- /// Parse given string for the viewBox attribute
- bool parseViewBox( const char* sViewbox, basegfx::B2DRange& rRect );
-
- /// Parse given string for a list of double values, comma-delimited
- bool parseDashArray( const char* sDashArray, std::vector<double>& rOutputVector );
-
- /** Parse paint uri
-
- @param o_rPaintUri
- Start and end ptr for uri substring (within
- [sPaintUri,sPaintUri+strlen(sPaintUri)]
-
- @param io_rColor
- The optional paint color to use. if o_rPaintUri is empty,
- parser sets io_rColor.second to false for color="None", to
- true and keeps current io_rColor.first entry for
- "currentColor", and to true and sets io_rColor.first to parsed
- color otherwise.
-
- @param sPaintUri
- String to parse. Permitted to contain the optional paint
- stuff, like fallback color.
-
- @return true, if a paint uri was successfully parsed.
- */
- bool parsePaintUri( std::pair<const char*,const char*>& o_rPaintUri,
- std::pair<ARGBColor,bool>& io_rColor,
- const char* sPaintUri );
-
- /// Parse given string for the xlink attribute
- bool parseXlinkHref( const char* xlink, OUString& data );
-
-} // namespace svgi
-
-#endif
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/filter/inc/svgreader.hxx b/filter/inc/svgreader.hxx
deleted file mode 100644
index 3149e1770158..000000000000
--- a/filter/inc/svgreader.hxx
+++ /dev/null
@@ -1,47 +0,0 @@
-/* -*- 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/.
- */
-#ifndef INCLUDED_FILTER_INC_SVGREADER_HXX
-#define INCLUDED_FILTER_INC_SVGREADER_HXX
-
-#include <filter/dllapi.h>
-
-#include <com/sun/star/uno/XComponentContext.hpp>
-#include <com/sun/star/lang/XMultiServiceFactory.hpp>
-#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
-#include <com/sun/star/io/XInputStream.hpp>
-#include <xmloff/xmlimp.hxx>
-
-namespace svgi
-{
-
-class SVGReader
-{
-private:
- const css::uno::Reference< css::uno::XComponentContext > m_xContext;
- const css::uno::Reference< css::io::XInputStream > m_xInputStream;
- const css::uno::Reference< css::xml::sax::XDocumentHandler > m_xDocumentHandler;
-
- SVGReader( const css::uno::Reference<css::uno::XComponentContext>& xContext,
- const css::uno::Reference< css::io::XInputStream >& xInputStream,
- const css::uno::Reference< css::xml::sax::XDocumentHandler >& xDocumentHandler,
- SvXMLImport *pFastHandler);
-
-public:
- FILTER_DLLPUBLIC SVGReader( const css::uno::Reference<css::uno::XComponentContext>& xContext,
- const css::uno::Reference< css::io::XInputStream >& xInputStream,
- const css::uno::Reference< css::xml::sax::XDocumentHandler >& xDocumentHandler );
-
- FILTER_DLLPUBLIC bool parseAndConvert();
-};
-
-} // namespace svgi
-
-#endif
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/filter/source/config/fragments/filters/SVG___Scalable_Vector_Graphics.xcu b/filter/source/config/fragments/filters/SVG___Scalable_Vector_Graphics.xcu
index b6d816ea4620..c5cae01dde53 100644
--- a/filter/source/config/fragments/filters/SVG___Scalable_Vector_Graphics.xcu
+++ b/filter/source/config/fragments/filters/SVG___Scalable_Vector_Graphics.xcu
@@ -26,5 +26,5 @@
<prop oor:name="FileFormatVersion"><value>0</value></prop>
<prop oor:name="Type"><value>svg_Scalable_Vector_Graphics</value></prop>
<prop oor:name="TemplateName"/>
- <prop oor:name="DocumentService"><value>com.sun.star.drawing.DrawingDocument</value></prop>
+ <prop oor:name="DocumentService"><value>com.sun.star.presentation.PresentationDocument</value></prop>
</node>
diff --git a/filter/source/svg/b2dellipse.cxx b/filter/source/svg/b2dellipse.cxx
deleted file mode 100644
index b4761090c446..000000000000
--- a/filter/source/svg/b2dellipse.cxx
+++ /dev/null
@@ -1,27 +0,0 @@
-/* -*- 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 "b2dellipse.hxx"
-
-#include <basegfx/point/b2dpoint.hxx>
-#include <basegfx/matrix/b2dhommatrix.hxx>
-
-namespace basegfx
-{
- B2DEllipse::B2DEllipse(const basegfx::B2DPoint& rCenter, const basegfx::B2DTuple& rRadius)
- : maCenter(rCenter), maRadius(rRadius)
- {
- }
-
- B2DEllipse::~B2DEllipse()
- {
- }
-
-} // end of namespace basegfx
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/filter/source/svg/b2dellipse.hxx b/filter/source/svg/b2dellipse.hxx
deleted file mode 100644
index af97794ee420..000000000000
--- a/filter/source/svg/b2dellipse.hxx
+++ /dev/null
@@ -1,51 +0,0 @@
-/* -*- 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/.
- */
-#ifndef INCLUDED_FILTER_SOURCE_SVG_B2DELLIPSE_HXX
-#define INCLUDED_FILTER_SOURCE_SVG_B2DELLIPSE_HXX
-
-#include <sal/types.h>
-
-#include <o3tl/cow_wrapper.hxx>
-
-#include <basegfx/point/b2dpoint.hxx>
-
-#include <basegfx/tuple/b2dtuple.hxx>
-
-#include <basegfx/vector/b2enums.hxx>
-
-namespace basegfx
-{
- class B2DPoint;
-} // end of namespace basegfx
-
-namespace basegfx
-{
- class B2DEllipse
- {
- private:
- const basegfx::B2DPoint maCenter;
- const basegfx::B2DTuple maRadius;
-
- public:
- B2DEllipse(const B2DEllipse& rEllipse);
- B2DEllipse(const basegfx::B2DPoint& rCenter, const basegfx::B2DTuple& rRadius);
- ~B2DEllipse();
-
- // assignment operator
- B2DEllipse& operator=(const B2DEllipse& rEllipse);
-
- // Coordinate interface
- const basegfx::B2DPoint& getB2DEllipseCenter() const { return maCenter; }
- const basegfx::B2DTuple& getB2DEllipseRadius() const { return maRadius; }
- };
-} // end of namespace basegfx
-
-#endif // INCLUDED_FILTER_SOURCE_SVG_B2DELLIPSE_HXX
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/filter/source/svg/parserfragments.cxx b/filter/source/svg/parserfragments.cxx
deleted file mode 100644
index 02c37089cf0d..000000000000
--- a/filter/source/svg/parserfragments.cxx
+++ /dev/null
@@ -1,587 +0,0 @@
-/* -*- 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 <parserfragments.hxx>
-#include "spirit_supplements.hxx"
-#include <gfxtypes.hxx>
-
-#include <basegfx/utils/canvastools.hxx>
-#include <com/sun/star/geometry/AffineMatrix2D.hpp>
-
-#include <limits.h>
-#include <boost/bind.hpp>
-#include <boost/spirit/include/classic.hpp>
-#include <boost/spirit/include/classic_while.hpp>
-#include <numeric>
-#include <algorithm>
-
-#include "units.hxx"
-#include "tokenmap.hxx"
-#include <sal/log.hxx>
-
-using namespace ::com::sun::star;
-
-namespace svgi
-{
-
-inline sal_uInt8 hex2int( char val )
-{
- return val <= '9' ? val-'0' : (val < 'a' ? val+10-'A' : val+10-'a');
-}
-
-void setFourBitColor( double& rChannel, char nChar )
-{
- const sal_uInt8 nVal(hex2int(nChar));
- rChannel = (nVal*16+nVal)/255.0;
-}
-
-void setEightBitColor( double& rChannel, const char* pStart )
-{
- const sal_uInt8 nVal0(hex2int(pStart[0]));
- const sal_uInt8 nVal1(hex2int(pStart[1]));
- rChannel = (nVal0*16+nVal1)/255.0;
-}
-
-void setIntColor( double& rChannel, sal_uInt8 nVal )
-{
- rChannel = nVal/255.0;
-}
-
-void setPercentColor( double& rChannel, double nVal )
-{
- rChannel = nVal/100.0;
-}
-
-void calcRotation(std::vector<geometry::AffineMatrix2D>& rTransforms,
- geometry::AffineMatrix2D& rCurrTransform,
- double fRotationAngle)
-{
- ::basegfx::B2DHomMatrix aCurr;
- aCurr.translate(-rCurrTransform.m02,-rCurrTransform.m12);
- aCurr.rotate(fRotationAngle*M_PI/180);
- aCurr.translate(rCurrTransform.m02,rCurrTransform.m12);
-
- rTransforms.push_back(
- basegfx::unotools::affineMatrixFromHomMatrix(
- rCurrTransform,
- aCurr));
-}
-
-void calcSkewX(std::vector<geometry::AffineMatrix2D>& rTransforms,
- double fSkewAngle)
-{
- geometry::AffineMatrix2D aMat(1.0,tan(fSkewAngle*M_PI/180),0.0,
- 0.0,1.0,0.0);
- rTransforms.push_back(aMat);
-}
-
-void calcSkewY(std::vector<geometry::AffineMatrix2D>& rTransforms,
- double fSkewAngle)
-{
- geometry::AffineMatrix2D aMat(1.0,0.0,0.0,
- tan(fSkewAngle*M_PI/180),1.0,0.0);
- rTransforms.push_back(aMat);
-}
-
-void assign_twice(double& r_oVal1, double& r_oVal2, const double& rInVal )
-{
- r_oVal1 = r_oVal2 = rInVal;
-}
-
-geometry::AffineMatrix2D multiplyMatrix( const geometry::AffineMatrix2D& rLHS,
- const geometry::AffineMatrix2D& rRHS )
-{
- basegfx::B2DHomMatrix aLHS;
- basegfx::B2DHomMatrix aRHS;
-
- basegfx::unotools::homMatrixFromAffineMatrix(aLHS,rLHS);
- basegfx::unotools::homMatrixFromAffineMatrix(aRHS,rRHS);
-
- aRHS*=aLHS;
-
- geometry::AffineMatrix2D aRet;
- return basegfx::unotools::affineMatrixFromHomMatrix(aRet,aRHS);
-}
-
-namespace
-{
- struct ColorGrammar : public ::boost::spirit::classic::grammar< ColorGrammar >
- {
- public:
- ARGBColor& m_rColor;
- explicit ColorGrammar( ARGBColor& rColor ) : m_rColor(rColor) {}
- template< typename ScannerT >
- struct definition
- {
- ::boost::spirit::classic::rule< ScannerT > colorExpression;
- explicit definition( const ColorGrammar& self )
- {
- using namespace ::boost::spirit::classic;
-
- auto lambdaSetEightBitColorR = [&self](const char* pStart, const char* /*nChar*/){ setEightBitColor(self.m_rColor.r, pStart); };
- auto lambdaSetEightBitColorG = [&self](const char* pStart, const char* /*nChar*/){ setEightBitColor(self.m_rColor.g, pStart); };
- auto lambdaSetEightBitColorB = [&self](const char* pStart, const char* /*nChar*/){ setEightBitColor(self.m_rColor.b, pStart); };
- auto lambdaSetFourBitColorR = [&self](char nChar){ setFourBitColor(self.m_rColor.r, nChar); };
- auto lambdaSetFourBitColorG = [&self](char nChar){ setFourBitColor(self.m_rColor.g, nChar); };
- auto lambdaSetFourBitColorB = [&self](char nChar){ setFourBitColor(self.m_rColor.b, nChar); };
- auto lambdaSetIntColorR = [&self](sal_uInt8 nVal){ setIntColor(self.m_rColor.r, nVal); };
- auto lambdaSetIntColorG = [&self](sal_uInt8 nVal){ setIntColor(self.m_rColor.g, nVal); };
- auto lambdaSetIntColorB = [&self](sal_uInt8 nVal){ setIntColor(self.m_rColor.b, nVal); };
- auto lambdaSetPercentColorR = [&self](double nVal){ setPercentColor(self.m_rColor.r, nVal); };
- auto lambdaSetPercentColorG = [&self](double nVal){ setPercentColor(self.m_rColor.g, nVal); };
- auto lambdaSetPercentColorB = [&self](double nVal){ setPercentColor(self.m_rColor.b, nVal); };
- int_parser<sal_uInt8,10,1,3> byte_p;
- colorExpression =
- (
- // the #rrggbb form
- ('#' >> (xdigit_p >> xdigit_p)[ lambdaSetEightBitColorR ]
- >> (xdigit_p >> xdigit_p)[ lambdaSetEightBitColorG ]
- >> (xdigit_p >> xdigit_p)[ lambdaSetEightBitColorB ] )
- |
- // the #rgb form
- ('#' >> xdigit_p[ lambdaSetFourBitColorR ]
- >> xdigit_p[ lambdaSetFourBitColorG ]
- >> xdigit_p[ lambdaSetFourBitColorB ] )
- |
- // rgb() form
- (str_p("rgb")
- >> '(' >>
- (
- // rgb(int,int,int)
- (byte_p[ lambdaSetIntColorR ] >> ',' >>
- byte_p[ lambdaSetIntColorG ] >> ',' >>
- byte_p[ lambdaSetIntColorB ] )
- |
- // rgb(double,double,double)
- (real_p[assign_a(self.m_rColor.r)] >> ',' >>
- real_p[assign_a(self.m_rColor.g)] >> ',' >>
- real_p[assign_a(self.m_rColor.b)])
- |
- // rgb(percent,percent,percent)
- (real_p[ lambdaSetPercentColorR ] >> "%," >>
- real_p[ lambdaSetPercentColorG ] >> "%," >>
- real_p[ lambdaSetPercentColorB ] >> "%")
- )
- >> ')')
- );
- }
- ::boost::spirit::classic::rule<ScannerT> const& start() const { return colorExpression; }
- };
- };
-}
-
-bool parseColor( const char* sColor, ARGBColor& rColor )
-{
- using namespace ::boost::spirit::classic;
-
- if( parse(sColor,
- ColorGrammar(rColor) >> end_p,
- space_p).full )
- {
- // free-form color found & parsed
- return true;
- }
-
- // no free-form color - maybe a color name?
- // trim white space before
- while( *sColor &&
- (*sColor==' ' || *sColor=='\t' || *sColor=='\r' || *sColor=='\n') )
- ++sColor;
- // trim white space after
- int nLen=strlen(sColor)-1;
- while( nLen &&
- (sColor[nLen]==' ' || sColor[nLen]=='\t' || sColor[nLen]=='\r' || sColor[nLen]=='\n') )
- --nLen;
- switch (getTokenId(sColor, nLen+1))
- {
- case XML_ALICEBLUE: rColor = ARGBColor(240,248,255); return true;
- case XML_ANTIQUEWHITE: rColor = ARGBColor(250,235,215); return true;
- case XML_AQUA: rColor = ARGBColor(0,255,255); return true;
- case XML_AQUAMARINE: rColor = ARGBColor(127,255,212); return true;
- case XML_AZURE: rColor = ARGBColor(240,255,255); return true;
- case XML_BEIGE: rColor = ARGBColor(245,245,220); return true;
- case XML_BISQUE: rColor = ARGBColor(255,228,196); return true;
- case XML_BLACK: rColor = ARGBColor(0,0,0); return true;
- case XML_BLANCHEDALMOND: rColor = ARGBColor(255,235,205); return true;
- case XML_BLUE: rColor = ARGBColor(0,0,255); return true;
- case XML_BLUEVIOLET: rColor = ARGBColor(138,43,226); return true;
- case XML_BROWN: rColor = ARGBColor(165,42,42); return true;
- case XML_BURLYWOOD: rColor = ARGBColor(222,184,135); return true;
- case XML_CADETBLUE: rColor = ARGBColor(95,158,160); return true;
- case XML_CHARTREUSE: rColor = ARGBColor(127,255,0); return true;
- case XML_CHOCOLATE: rColor = ARGBColor(210,105,30); return true;
- case XML_CORAL: rColor = ARGBColor(255,127,80); return true;
- case XML_CORNFLOWERBLUE: rColor = ARGBColor(100,149,237); return true;
- case XML_CORNSILK: rColor = ARGBColor(255,248,220); return true;
- case XML_CRIMSON: rColor = ARGBColor(220,20,60); return true;
- case XML_CYAN: rColor = ARGBColor(0,255,255); return true;
- case XML_DARKBLUE: rColor = ARGBColor(0,0,139); return true;
- case XML_DARKCYAN: rColor = ARGBColor(0,139,139); return true;
- case XML_DARKGOLDENROD: rColor = ARGBColor(184,134,11); return true;
- case XML_DARKGRAY: rColor = ARGBColor(169,169,169); return true;
- case XML_DARKGREEN: rColor = ARGBColor(0,100,0); return true;
- case XML_DARKGREY: rColor = ARGBColor(169,169,169); return true;
- case XML_DARKKHAKI: rColor = ARGBColor(189,183,107); return true;
- case XML_DARKMAGENTA: rColor = ARGBColor(139,0,139); return true;
- case XML_DARKOLIVEGREEN: rColor = ARGBColor(85,107,47); return true;
- case XML_DARKORANGE: rColor = ARGBColor(255,140,0); return true;
- case XML_DARKORCHID: rColor = ARGBColor(153,50,204); return true;
- case XML_DARKRED: rColor = ARGBColor(139,0,0); return true;
- case XML_DARKSALMON: rColor = ARGBColor(233,150,122); return true;
- case XML_DARKSEAGREEN: rColor = ARGBColor(143,188,143); return true;
- case XML_DARKSLATEBLUE: rColor = ARGBColor(72,61,139); return true;
- case XML_DARKSLATEGRAY: rColor = ARGBColor(47,79,79); return true;
- case XML_DARKSLATEGREY: rColor = ARGBColor(47,79,79); return true;
- case XML_DARKTURQUOISE: rColor = ARGBColor(0,206,209); return true;
- case XML_DARKVIOLET: rColor = ARGBColor(148,0,211); return true;
- case XML_DEEPPINK: rColor = ARGBColor(255,20,147); return true;
- case XML_DEEPSKYBLUE: rColor = ARGBColor(0,191,255); return true;
- case XML_DIMGRAY: rColor = ARGBColor(105,105,105); return true;
- case XML_DIMGREY: rColor = ARGBColor(105,105,105); return true;
- case XML_DODGERBLUE: rColor = ARGBColor(30,144,255); return true;
- case XML_FIREBRICK: rColor = ARGBColor(178,34,34); return true;
- case XML_FLORALWHITE: rColor = ARGBColor(255,250,240); return true;
- case XML_FORESTGREEN: rColor = ARGBColor(34,139,34); return true;
- case XML_FUCHSIA: rColor = ARGBColor(255,0,255); return true;
- case XML_GAINSBORO: rColor = ARGBColor(220,220,220); return true;
- case XML_GHOSTWHITE: rColor = ARGBColor(248,248,255); return true;
- case XML_GOLD: rColor = ARGBColor(255,215,0); return true;
- case XML_GOLDENROD: rColor = ARGBColor(218,165,32); return true;
- case XML_GRAY: rColor = ARGBColor(128,128,128); return true;
- case XML_GREY: rColor = ARGBColor(128,128,128); return true;
- case XML_GREEN: rColor = ARGBColor(0,128,0); return true;
- case XML_GREENYELLOW: rColor = ARGBColor(173,255,47); return true;
- case XML_HONEYDEW: rColor = ARGBColor(240,255,240); return true;
- case XML_HOTPINK: rColor = ARGBColor(255,105,180); return true;
- case XML_INDIANRED: rColor = ARGBColor(205,92,92); return true;
- case XML_INDIGO: rColor = ARGBColor(75,0,130); return true;
- case XML_IVORY: rColor = ARGBColor(255,255,240); return true;
- case XML_KHAKI: rColor = ARGBColor(240,230,140); return true;
- case XML_LAVENDER: rColor = ARGBColor(230,230,250); return true;
- case XML_LAVENDERBLUSH: rColor = ARGBColor(255,240,245); return true;
- case XML_LAWNGREEN: rColor = ARGBColor(124,252,0); return true;
- case XML_LEMONCHIFFON: rColor = ARGBColor(255,250,205); return true;
- case XML_LIGHTBLUE: rColor = ARGBColor(173,216,230); return true;
- case XML_LIGHTCORAL: rColor = ARGBColor(240,128,128); return true;
- case XML_LIGHTCYAN: rColor = ARGBColor(224,255,255); return true;
- case XML_LIGHTGOLDENRODYELLOW: rColor = ARGBColor(250,250,210); return true;
- case XML_LIGHTGRAY: rColor = ARGBColor(211,211,211); return true;
- case XML_LIGHTGREEN: rColor = ARGBColor(144,238,144); return true;
- case XML_LIGHTGREY: rColor = ARGBColor(211,211,211); return true;
- case XML_LIGHTPINK: rColor = ARGBColor(255,182,193); return true;
- case XML_LIGHTSALMON: rColor = ARGBColor(255,160,122); return true;
- case XML_LIGHTSEAGREEN: rColor = ARGBColor(32,178,170); return true;
- case XML_LIGHTSKYBLUE: rColor = ARGBColor(135,206,250); return true;
- case XML_LIGHTSLATEGRAY: rColor = ARGBColor(119,136,153); return true;
- case XML_LIGHTSLATEGREY: rColor = ARGBColor(119,136,153); return true;
- case XML_LIGHTSTEELBLUE: rColor = ARGBColor(176,196,222); return true;
- case XML_LIGHTYELLOW: rColor = ARGBColor(255,255,224); return true;
- case XML_LIME: rColor = ARGBColor(0,255,0); return true;
- case XML_LIMEGREEN: rColor = ARGBColor(50,205,50); return true;
- case XML_LINEN: rColor = ARGBColor(250,240,230); return true;
- case XML_MAGENTA: rColor = ARGBColor(255,0,255); return true;
- case XML_MAROON: rColor = ARGBColor(128,0,0); return true;
- case XML_MEDIUMAQUAMARINE: rColor = ARGBColor(102,205,170); return true;
- case XML_MEDIUMBLUE: rColor = ARGBColor(0,0,205); return true;
- case XML_MEDIUMORCHID: rColor = ARGBColor(186,85,211); return true;
- case XML_MEDIUMPURPLE: rColor = ARGBColor(147,112,219); return true;
- case XML_MEDIUMSEAGREEN: rColor = ARGBColor(60,179,113); return true;
- case XML_MEDIUMSLATEBLUE: rColor = ARGBColor(123,104,238); return true;
- case XML_MEDIUMSPRINGGREEN: rColor = ARGBColor(0,250,154); return true;
- case XML_MEDIUMTURQUOISE: rColor = ARGBColor(72,209,204); return true;
- case XML_MEDIUMVIOLETRED: rColor = ARGBColor(199,21,133); return true;
- case XML_MIDNIGHTBLUE: rColor = ARGBColor(25,25,112); return true;
- case XML_MINTCREAM: rColor = ARGBColor(245,255,250); return true;
- case XML_MISTYROSE: rColor = ARGBColor(255,228,225); return true;
- case XML_MOCCASIN: rColor = ARGBColor(255,228,181); return true;
- case XML_NAVAJOWHITE: rColor = ARGBColor(255,222,173); return true;
- case XML_NAVY: rColor = ARGBColor(0,0,128); return true;
- case XML_OLDLACE: rColor = ARGBColor(253,245,230); return true;
- case XML_OLIVE: rColor = ARGBColor(128,128,0); return true;
- case XML_OLIVEDRAB: rColor = ARGBColor(107,142,35); return true;
- case XML_ORANGE: rColor = ARGBColor(255,165,0); return true;
- case XML_ORANGERED: rColor = ARGBColor(255,69,0); return true;
- case XML_ORCHID: rColor = ARGBColor(218,112,214); return true;
- case XML_PALEGOLDENROD: rColor = ARGBColor(238,232,170); return true;
- case XML_PALEGREEN: rColor = ARGBColor(152,251,152); return true;
- case XML_PALETURQUOISE: rColor = ARGBColor(175,238,238); return true;
- case XML_PALEVIOLETRED: rColor = ARGBColor(219,112,147); return true;
- case XML_PAPAYAWHIP: rColor = ARGBColor(255,239,213); return true;
- case XML_PEACHPUFF: rColor = ARGBColor(255,218,185); return true;
- case XML_PERU: rColor = ARGBColor(205,133,63); return true;
- case XML_PINK: rColor = ARGBColor(255,192,203); return true;
- case XML_PLUM: rColor = ARGBColor(221,160,221); return true;
- case XML_POWDERBLUE: rColor = ARGBColor(176,224,230); return true;
- case XML_PURPLE: rColor = ARGBColor(128,0,128); return true;
- case XML_RED: rColor = ARGBColor(255,0,0); return true;
- case XML_ROSYBROWN: rColor = ARGBColor(188,143,143); return true;
- case XML_ROYALBLUE: rColor = ARGBColor(65,105,225); return true;
- case XML_SADDLEBROWN: rColor = ARGBColor(139,69,19); return true;
- case XML_SALMON: rColor = ARGBColor(250,128,114); return true;
- case XML_SANDYBROWN: rColor = ARGBColor(244,164,96); return true;
- case XML_SEAGREEN: rColor = ARGBColor(46,139,87); return true;
- case XML_SEASHELL: rColor = ARGBColor(255,245,238); return true;
- case XML_SIENNA: rColor = ARGBColor(160,82,45); return true;
- case XML_SILVER: rColor = ARGBColor(192,192,192); return true;
- case XML_SKYBLUE: rColor = ARGBColor(135,206,235); return true;
- case XML_SLATEBLUE: rColor = ARGBColor(106,90,205); return true;
- case XML_SLATEGRAY: rColor = ARGBColor(112,128,144); return true;
- case XML_SLATEGREY: rColor = ARGBColor(112,128,144); return true;
- case XML_SNOW: rColor = ARGBColor(255,250,250); return true;
- case XML_SPRINGGREEN: rColor = ARGBColor(0,255,127); return true;
- case XML_STEELBLUE: rColor = ARGBColor(70,130,180); return true;
- case XML_TAN: rColor = ARGBColor(210,180,140); return true;
- case XML_TEAL: rColor = ARGBColor(0,128,128); return true;
- case XML_THISTLE: rColor = ARGBColor(216,191,216); return true;
- case XML_TOMATO: rColor = ARGBColor(255,99,71); return true;
- case XML_TURQUOISE: rColor = ARGBColor(64,224,208); return true;
- case XML_VIOLET: rColor = ARGBColor(238,130,238); return true;
- case XML_WHEAT: rColor = ARGBColor(245,222,179); return true;
- case XML_WHITE: rColor = ARGBColor(255,255,255); return true;
- case XML_WHITESMOKE: rColor = ARGBColor(245,245,245); return true;
- case XML_YELLOW: rColor = ARGBColor(255,255,0); return true;
- case XML_YELLOWGREEN: rColor = ARGBColor(154,205,50); return true;
-
- default:
- return false; // no color at all, I'd guess.
- }
-}
-
-bool parseOpacity (const char* sOpacity, ARGBColor& rColor )
-{
- using namespace ::boost::spirit::classic;
-
- if( parse(sOpacity,
- // Begin grammar
- (
- real_p[assign_a(rColor.a)]
- ) >> end_p,
- // End grammar
- space_p).full )
- {
- return true;
- }
- return false;
-}
-
-
-bool parseTransform( const char* sTransform, basegfx::B2DHomMatrix& rTransform )
-{
- using namespace ::boost::spirit::classic;
-
- double fRefOffsetX(0.0);
- double fRefOffsetY(0.0);
- bool bRefTransform(false);
-
- double fRotationAngle=0.0;
- double fSkewAngle=0.0;
- geometry::AffineMatrix2D aIdentityTransform;
- geometry::AffineMatrix2D aCurrTransform;
- std::vector<geometry::AffineMatrix2D> aTransforms;
- aIdentityTransform.m00 = 1.0; aIdentityTransform.m11 = 1.0;
- aCurrTransform = aIdentityTransform;
-
- const bool bRes = parse(sTransform,
- // Begin grammar
- (
- // identity transform
- str_p("none")
- |
- // the ref() form
- (str_p("ref")
- >> '('
- >> str_p("svg")[assign_a(bRefTransform,true)]
- >> !(real_p[assign_a(fRefOffsetX)] >> (',' | eps_p) >>
- real_p[assign_a(fRefOffsetY)])
- >> ')')
- |
- // the transform-list form
- (list_p(
- (
- // matrix(a,b,c,d,e,f)
- (str_p("matrix")
- >> '('
- >> real_p[assign_a(aCurrTransform.m00)] >> (',' | eps_p)
- >> real_p[assign_a(aCurrTransform.m10)] >> (',' | eps_p)
- >> real_p[assign_a(aCurrTransform.m01)] >> (',' | eps_p)
- >> real_p[assign_a(aCurrTransform.m11)] >> (',' | eps_p)
- >> real_p[assign_a(aCurrTransform.m02)] >> (',' | eps_p)
- >> real_p[assign_a(aCurrTransform.m12)]
- >> ')')[push_back_a(aTransforms,aCurrTransform)]
- |
- // translate(x,[y])
- (str_p("translate")
- >> '('
- >> real_p[boost::bind(&assign_twice,
- boost::ref(aCurrTransform.m02),
- boost::ref(aCurrTransform.m12),_1)]
- >> !((',' | eps_p) >> real_p[assign_a(aCurrTransform.m12)])
- >> ')')[push_back_a(aTransforms,aCurrTransform)]
- |
- // scale(x,[y])
- (str_p("scale")
- >> '('
- >> real_p[boost::bind(&assign_twice,
- boost::ref(aCurrTransform.m00),
- boost::ref(aCurrTransform.m11),_1)]
- >> !((',' | eps_p) >> real_p[assign_a(aCurrTransform.m11)])
- >> ')')[push_back_a(aTransforms,aCurrTransform)]
- |
- // rotate(phi,[cx, cy])
- (str_p("rotate")
- >> '('
- >> real_p[assign_a(fRotationAngle)]
- >> !((',' | eps_p) >> real_p[assign_a(aCurrTransform.m02)]
- >> (',' | eps_p) >> real_p[assign_a(aCurrTransform.m12)])
- >> ')')[boost::bind(&calcRotation,
- boost::ref(aTransforms),
- boost::ref(aCurrTransform),
- boost::cref(fRotationAngle))]
- |
- // skewX(phi)
- (str_p("skewX")
- >> '('
- >> real_p[assign_a(fSkewAngle)]
- >> ')')[boost::bind(&calcSkewX,
- boost::ref(aTransforms),
- boost::cref(fSkewAngle))]
- |
- // skewY(phi)
- (str_p("skewY")
- >> '('
- >> real_p[assign_a(fSkewAngle)]
- >> ')')[boost::bind(&calcSkewY,
- boost::ref(aTransforms),
- boost::cref(fSkewAngle))]
- // reset current transform after every push
- )[assign_a(aCurrTransform,aIdentityTransform)],
- // list delimiter is either ',' or space
- ',' | eps_p ))
- ) >> end_p,
- // End grammar
- space_p).full;
-
- if( !bRes )
- return false;
-
- // fold all transformations into one
- const geometry::AffineMatrix2D aTotalTransform(
- std::accumulate(aTransforms.begin(),
- aTransforms.end(),
- aIdentityTransform,
- &multiplyMatrix));
-
- basegfx::unotools::homMatrixFromAffineMatrix(
- rTransform,
- aTotalTransform);
-
- // TODO(F1): handle the ref case
- return bRes;
-}
-
-
-bool parseViewBox( const char* sViewbox, basegfx::B2DRange& rRect )
-{
- using namespace ::boost::spirit::classic;
-
- double x=0.0,y=0.0,w=0.0,h=0.0;
-
- const bool bRes = parse(sViewbox,
- // Begin grammar
- (
- // either comma- or space-delimited list of four doubles
- real_p[assign_a(x)] >> (',' | eps_p) >>
- real_p[assign_a(y)] >> (',' | eps_p) >>
- real_p[assign_a(w)] >> (',' | eps_p) >>
- real_p[assign_a(h)] >> end_p
- ),
- // End grammar
- space_p).full;
-
- if( !bRes )
- return false;
-
- rRect = basegfx::B2DRange(x,y,x+w,y+h);
-
- return true;
-}
-
-
-bool parseDashArray( const char* sDashArray, std::vector<double>& rOutputVector )
-{
- using namespace ::boost::spirit::classic;
-
- rOutputVector.clear();
- return parse(sDashArray,
- // Begin grammar
- (
- // parse comma-delimited list of doubles (have to use the
- // 'direct' variant, as otherwise spirit refactors our
- // parser to push both real num and comma to push_back_a)
- list_p.direct
- (
- real_p[push_back_a(rOutputVector)],
- // list delimiter is either ',' or space
- ',' | eps_p
- )
- ) >> end_p,
- // End grammar
- space_p).full;
-}
-
-
-bool parsePaintUri( std::pair<const char*,const char*>& o_rPaintUri,
- std::pair<ARGBColor,bool>& io_rColor,
- const char* sPaintUri )
-{
- using namespace ::boost::spirit::classic;
-
- const bool bRes = parse(sPaintUri,
- // Begin grammar
- (
- str_p("url(") >> !( str_p("'") ) >> "#" >>
- (+(anychar_p - (str_p("'") | str_p(")"))))[assign_a(o_rPaintUri)] >>
- !( str_p("'") ) >> str_p(")") >>
- *( str_p("none")[assign_a(io_rColor.second,false)] |
- str_p("currentColor")[assign_a(io_rColor.second,true)] |
- ColorGrammar(io_rColor.first)
- // TODO(F1): named color
- )
- ) >> end_p,
- // End grammar
- space_p).full;
-
- return bRes;
-}
-
-
-bool parseXlinkHref( const char* sXlinkHref, OUString& data )
-{
- OUString sLink(OUString::createFromAscii(sXlinkHref));
-
- if (sLink.startsWith("data:"))
- {
- sal_Int32 nIndex=0;
- OUString aCurrToken = sLink.getToken(0,',',nIndex);
-
- // the inplace "data" uri
- if ( !aCurrToken.isEmpty() )
- {
- data = sLink.copy(nIndex);
- SAL_INFO("filter.svg", data);
- return true;
- }
- }
-
- return false;
-}
-
-} // namespace svgi
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/filter/source/svg/svgfilter.cxx b/filter/source/svg/svgfilter.cxx
index 94fe876e3faa..1ec09f65ab05 100644
--- a/filter/source/svg/svgfilter.cxx
+++ b/filter/source/svg/svgfilter.cxx
@@ -52,6 +52,12 @@
#include "svgfilter.hxx"
#include "svgwriter.hxx"
+#include <svx/unopage.hxx>
+#include <vcl/graphicfilter.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdograf.hxx>
+#include <svl/itempool.hxx>
+
#include <memory>
using namespace ::com::sun::star;
@@ -94,14 +100,185 @@ SVGFilter::~SVGFilter()
sal_Bool SAL_CALL SVGFilter::filter( const Sequence< PropertyValue >& rDescriptor )
{
SolarMutexGuard aGuard;
- vcl::Window* pFocusWindow = Application::GetFocusWindow();
- bool bRet;
+ vcl::Window* pFocusWindow(Application::GetFocusWindow());
+ bool bRet(false);
- if( pFocusWindow )
+ if(pFocusWindow)
+ {
pFocusWindow->EnterWait();
+ }
+
+ if(mxDstDoc.is())
+ {
+ // Import. Use an endless loop to have easy exits for error handling
+ while(true)
+ {
+ // use MediaDescriptor to get needed data out of Sequence< PropertyValue >
+ utl::MediaDescriptor aMediaDescriptor(rDescriptor);
+ uno::Reference<io::XInputStream> xInputStream;
+ uno::Reference<task::XStatusIndicator> xStatus;
+
+ xInputStream.set(aMediaDescriptor[utl::MediaDescriptor::PROP_INPUTSTREAM()], UNO_QUERY);
+ xStatus.set(aMediaDescriptor[utl::MediaDescriptor::PROP_STATUSINDICATOR()], UNO_QUERY);
+
+ if(!xInputStream.is() || !xStatus.is())
+ {
+ // we need the InputStream and StatusIndicator
+ break;
+ }
+
+ // get the DrawPagesSupplier
+ uno::Reference< drawing::XDrawPagesSupplier > xDrawPagesSupplier( mxDstDoc, uno::UNO_QUERY );
+
+ if(!xDrawPagesSupplier.is())
+ {
+ // we need the DrawPagesSupplier
+ break;
+ }
+
+ // get the DrawPages
+ uno::Reference< drawing::XDrawPages > xDrawPages( xDrawPagesSupplier->getDrawPages(), uno::UNO_QUERY );
+
+ if(!xDrawPages.is())
+ {
+ // we need the DrawPages
+ break;
+ }
+
+ // check DrawPageCount (there should be one by default)
+ sal_Int32 nDrawPageCount(xDrawPages->getCount());
+
+ if(0 == nDrawPageCount)
+ {
+ // at least one DrawPage should be there - we need that
+ break;
+ }
+
+ // get that DrawPage
+ uno::Reference< drawing::XDrawPage > xDrawPage( xDrawPages->getByIndex(0), uno::UNO_QUERY );
+
+ if(!xDrawPage.is())
+ {
+ // we need that DrawPage
+ break;
+ }
- if( mxDstDoc.is() )
- bRet = implImport( rDescriptor );
+ // get that DrawPage's UNO API implementation
+ SvxDrawPage* pSvxDrawPage(SvxDrawPage::getImplementation(xDrawPage));
+
+ if(nullptr == pSvxDrawPage || nullptr == pSvxDrawPage->GetSdrPage())
+ {
+ // we need a SvxDrawPage
+ break;
+ }
+
+ // get the SvStream to work with
+ std::unique_ptr< SvStream > aStream(utl::UcbStreamHelper::CreateStream(xInputStream, true));
+
+ if(!aStream.get())
+ {
+ // we need the SvStream
+ break;
+ }
+
+ // create a GraphicFilter and load the SVG (format already known, thus *could*
+ // be handed over to ImportGraphic - but detection is fast).
+ // As a bonus, zipped data is already detected and handled there
+ GraphicFilter aGraphicFilter;
+ Graphic aGraphic;
+ const ErrCode nGraphicFilterErrorCode(aGraphicFilter.ImportGraphic(aGraphic, OUString(), *aStream.get()));
+
+ if(ERRCODE_NONE != nGraphicFilterErrorCode)
+ {
+ // SVG import error, cannot continue
+ break;
+ }
+
+ // get the GraphicPrefSize early to check if we have any content
+ // (the SVG may contain nothing and/or just <g visibility="hidden"> stuff...)
+ const Size aGraphicPrefSize(aGraphic.GetPrefSize());
+
+ if(0 == aGraphicPrefSize.Width() || 0 == aGraphicPrefSize.Height())
+ {
+ // SVG has no displayable content, stop import.
+ // Also possible would be to get the sequence< Primitives >
+ // from aGraphic and check if it is empty.
+ // Possibility to set some error message here to tell
+ // the user what/why loading went wrong, but I do not
+ // know how this could be done here
+ break;
+ }
+
+ // create a SdrModel-GraphicObject to insert to page
+ SdrPage* pTargetSdrPage(pSvxDrawPage->GetSdrPage());
+ std::unique_ptr< SdrGrafObj, SdrObjectFreeOp > aNewSdrGrafObj(
+ new SdrGrafObj(
+ pTargetSdrPage->getSdrModelFromSdrPage(),
+ aGraphic));
+
+ if(!aNewSdrGrafObj.get())
+ {
+ // could not create GraphicObject
+ break;
+ }
+
+ // Evtl. adapt the GraphicPrefSize to target-MapMode of target-Model
+ // (should be 100thmm here, but just stay safe by doing the conversion)
+ const MapMode aGraphicPrefMapMode(aGraphic.GetPrefMapMode());
+ const MapUnit eDestUnit(pTargetSdrPage->getSdrModelFromSdrPage().GetItemPool().GetMetric(0));
+ const MapUnit eSrcUnit(aGraphicPrefMapMode.GetMapUnit());
+ Size aGraphicSize(aGraphicPrefSize);
+
+ if (eDestUnit != eSrcUnit)
+ {
+ aGraphicSize = Size(
+ OutputDevice::LogicToLogic(aGraphicSize.Width(), eSrcUnit, eDestUnit),
+ OutputDevice::LogicToLogic(aGraphicSize.Height(), eSrcUnit, eDestUnit));
+ }
+
+ // Based on GraphicSize, set size of Page. Do not forget to adapt PageBorders,
+ // but interpret them relative to PageSize so that they do not 'expolde/shrink'
+ // in comparison. Use a common scaling factor for hor/ver to not get
+ // asynchronous border distances, though. All in all this will adapt borders
+ // nicely and is based on office-defaults for standard-page-border-sizes.
+ const Size aPageSize(pTargetSdrPage->GetSize());
+ const double fBorderRelation((
+ static_cast< double >(pTargetSdrPage->GetLeftBorder()) / aPageSize.Width() +
+ static_cast< double >(pTargetSdrPage->GetRightBorder()) / aPageSize.Width() +
+ static_cast< double >(pTargetSdrPage->GetUpperBorder()) / aPageSize.Height() +
+ static_cast< double >(pTargetSdrPage->GetLowerBorder()) / aPageSize.Height()) / 4.0);
+ const long nAllBorder(basegfx::fround((aGraphicSize.Width() + aGraphicSize.Height()) * fBorderRelation * 0.5));
+
+ // Adapt PageSize and Border stuff. To get all MasterPages and PresObjs
+ // correctly adapted, do not just use
+ // pTargetSdrPage->SetBorder(...) and
+ // pTargetSdrPage->SetSize(...),
+ // but ::adaptSizeAndBorderForAllPages
+ pTargetSdrPage->getSdrModelFromSdrPage().adaptSizeAndBorderForAllPages(
+ Size(
+ aGraphicSize.Width() + nAllBorder + nAllBorder,
+ aGraphicSize.Height() + nAllBorder + nAllBorder),
+ nAllBorder,
+ nAllBorder,
+ nAllBorder,
+ nAllBorder);
+
+ // set pos/size at SdrGraphicObj - add offset to PageBorder
+ aNewSdrGrafObj->SetSnapRect(
+ tools::Rectangle(
+ Point(nAllBorder, nAllBorder),
+ aGraphicSize));
+
+ // insert to page (owner change of SdrGrafObj)
+ pTargetSdrPage->InsertObject(aNewSdrGrafObj.release());
+
+ // done - set positive result now
+ bRet = true;
+
+ // always leave helper endless loop
+ break;
+ };
+ }
else if( mxSrcDoc.is() )
{
// #i124608# detect selection
diff --git a/filter/source/svg/svgfilter.hxx b/filter/source/svg/svgfilter.hxx
index 63616a9e0c53..5f117c3310ee 100644
--- a/filter/source/svg/svgfilter.hxx
+++ b/filter/source/svg/svgfilter.hxx
@@ -223,9 +223,6 @@ private:
Link<EditFieldInfo*,void> maNewFieldHdl;
/// @throws css::uno::RuntimeException
- bool implImport( const Sequence< PropertyValue >& rDescriptor );
-
- /// @throws css::uno::RuntimeException
bool implExport( const Sequence< PropertyValue >& rDescriptor );
static Reference< XWriter > implCreateExportDocumentHandler( const Reference< XOutputStream >& rxOStm );
diff --git a/filter/source/svg/svgimport.cxx b/filter/source/svg/svgimport.cxx
deleted file mode 100644
index 5b39d2aa9c37..000000000000
--- a/filter/source/svg/svgimport.cxx
+++ /dev/null
@@ -1,119 +0,0 @@
-/* -*- 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 "svgfilter.hxx"
-#include <svgreader.hxx>
-
-#include <rtl/ref.hxx>
-
-#include <com/sun/star/lang/XMultiServiceFactory.hpp>
-
-#include <com/sun/star/lang/XComponent.hpp>
-
-#include <com/sun/star/uno/Any.hxx>
-
-#include <com/sun/star/beans/PropertyValue.hpp>
-
-#include <com/sun/star/xml/sax/XParser.hpp>
-#include <com/sun/star/xml/sax/InputSource.hpp>
-#include <com/sun/star/xml/XImportFilter.hpp>
-
-#include <com/sun/star/io/XActiveDataSource.hpp>
-#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
-#include <com/sun/star/task/XStatusIndicator.hpp>
-
-#include <unotools/mediadescriptor.hxx>
-#include <unotools/ucbstreamhelper.hxx>
-#include <tools/zcodec.hxx>
-
-#include <memory>
-
-using namespace ::com::sun::star;
-using namespace ::svgi;
-
-bool SVGFilter::implImport(const Sequence< PropertyValue >& rDescriptor)
-{
- utl::MediaDescriptor aMediaDescriptor(rDescriptor);
- uno::Reference<io::XInputStream> xInputStream;
- uno::Reference<task::XStatusIndicator> xStatus;
-
- xInputStream.set(aMediaDescriptor[utl::MediaDescriptor::PROP_INPUTSTREAM()], UNO_QUERY);
- xStatus.set(aMediaDescriptor[utl::MediaDescriptor::PROP_STATUSINDICATOR()], UNO_QUERY);
-
- if (isStreamGZip(xInputStream))
- {
- uno::Reference<io::XSeekable> xSeek(xInputStream, uno::UNO_QUERY);
- if (!xSeek.is())
- return false;
- xSeek->seek(0);
-
- std::unique_ptr<SvStream> aStream(utl::UcbStreamHelper::CreateStream(xInputStream, true ));
- if(!aStream.get())
- return false;
-
- SvStream* pMemoryStream = new SvMemoryStream;
- ZCodec aCodec;
- aCodec.BeginCompression(ZCODEC_DEFAULT_COMPRESSION, false, true);
- aCodec.Decompress(*aStream.get(), *pMemoryStream);
- aCodec.EndCompression();
- pMemoryStream->Seek(STREAM_SEEK_TO_BEGIN);
- uno::Reference<io::XInputStream> xDecompressedInput(new utl::OSeekableInputStreamWrapper(pMemoryStream, true));
- if (!xDecompressedInput.is())
- return false;
- xInputStream = xDecompressedInput;
- }
- else
- {
- uno::Reference<io::XSeekable> xSeek(xInputStream, uno::UNO_QUERY);
- if (xSeek.is())
- xSeek->seek(0);
- }
-
- OSL_ASSERT(xInputStream.is());
- if(!xInputStream.is())
- return false;
-
- Reference < XDocumentHandler > xInternalHandler(
- mxContext->getServiceManager()->createInstanceWithContext( "com.sun.star.comp.Draw.XMLOasisImporter", mxContext ), UNO_QUERY );
-
- // The XImporter sets up an empty target document for XDocumentHandler to write to..
- uno::Reference < XImporter > xImporter(xInternalHandler, UNO_QUERY);
- xImporter->setTargetDocument(mxDstDoc);
-
- bool bRet = false;
- SVGReader aReader(mxContext, xInputStream, xInternalHandler);
- try
- {
- bRet = aReader.parseAndConvert();
- }
- catch (const RuntimeException&)
- {
- throw;
- }
- catch (const Exception& e)
- {
- throw css::lang::WrappedTargetRuntimeException("SVGFilter::implImport non-RuntimeException",
- static_cast<uno::XWeak*>(this), uno::makeAny(e));
- }
- return bRet;
-}
-
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/filter/source/svg/svgreader.cxx b/filter/source/svg/svgreader.cxx
deleted file mode 100644
index 1bffc82e9190..000000000000
--- a/filter/source/svg/svgreader.cxx
+++ /dev/null
@@ -1,2304 +0,0 @@
-/* -*- 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 <svgreader.hxx>
-#include <xmloff/attrlist.hxx>
-#include <gfxtypes.hxx>
-#include "units.hxx"
-#include <parserfragments.hxx>
-#include "tokenmap.hxx"
-#include "b2dellipse.hxx"
-
-#include <rtl/math.hxx>
-#include <rtl/ref.hxx>
-#include <rtl/ustring.hxx>
-#include <rtl/ustrbuf.hxx>
-#include <basegfx/vector/b2enums.hxx>
-#include <basegfx/range/b2drange.hxx>
-#include <basegfx/matrix/b2dhommatrix.hxx>
-#include <basegfx/polygon/b2dpolypolygon.hxx>
-#include <basegfx/polygon/b2dlinegeometry.hxx>
-#include <basegfx/polygon/b2dpolygontools.hxx>
-#include <basegfx/polygon/b2dpolypolygontools.hxx>
-#include <com/sun/star/io/XSeekable.hpp>
-#include <com/sun/star/xml/sax/XParser.hpp>
-#include <com/sun/star/xml/dom/DocumentBuilder.hpp>
-#include <com/sun/star/xml/dom/NodeType.hpp>
-
-#include <basegfx/polygon/b2dpolygoncutandtouch.hxx>
-#include <basegfx/polygon/b2dpolypolygoncutter.hxx>
-#include <unotools/streamwrap.hxx>
-#include <sax/tools/converter.hxx>
-#include <vcl/graph.hxx>
-#include <vcl/virdev.hxx>
-#include <vcl/gradient.hxx>
-#include <vcl/graphicfilter.hxx>
-#include <tools/zcodec.hxx>
-
-#include <map>
-
-#define OASIS_STR "urn:oasis:names:tc:opendocument:xmlns:"
-
-using namespace ::com::sun::star;
-
-namespace svgi
-{
- enum SvgiVisitorCaller {STYLE_ANNOTATOR, SHAPE_WRITER, STYLE_WRITER};
-namespace
-{
-
-/** visits all children of the specified type with the given functor
- */
-template<typename Func> void visitChildren(const Func& rFunc,
- const uno::Reference<xml::dom::XElement>& rElem,
- xml::dom::NodeType eChildType )
-{
- uno::Reference<xml::dom::XNodeList> xChildren( rElem->getChildNodes() );
- const sal_Int32 nNumNodes( xChildren->getLength() );
- for( sal_Int32 i=0; i<nNumNodes; ++i )
- {
- SAL_INFO("filter.svg", "node type: " << sal::static_int_cast<sal_uInt32>(xChildren->item(i)->getNodeType()) << " tag name " << xChildren->item(i)->getNodeName() << " value |" << xChildren->item(i)->getNodeValue() << "|");
- if( xChildren->item(i)->getNodeType() == eChildType )
- rFunc( *xChildren->item(i).get() );
- }
-}
-
-/** Visit all elements of the given tree (in-order traversal)
-
- Given functor is called for every element, and passed the
- element's attributes, if any
- */
-template<typename Func> void visitElements(Func& rFunc,
- const uno::Reference<xml::dom::XElement>& rElem,
- SvgiVisitorCaller eCaller)
-{
- if( rElem->hasAttributes() )
- rFunc(rElem, rElem->getAttributes());
- else
- rFunc(rElem);
-
- // notify children processing
- rFunc.push();
-
- if (eCaller == SHAPE_WRITER && rElem->getTagName() == "defs")
- return;
-
- // recurse over children
- uno::Reference<xml::dom::XNodeList> xChildren( rElem->getChildNodes() );
- const sal_Int32 nNumNodes( xChildren->getLength() );
- for( sal_Int32 i=0; i<nNumNodes; ++i )
- {
- if( xChildren->item(i)->getNodeType() == xml::dom::NodeType_ELEMENT_NODE ){
- visitElements( rFunc,
- uno::Reference<xml::dom::XElement>(
- xChildren->item(i),
- uno::UNO_QUERY_THROW),
- eCaller );
- }
- }
-
- // children processing done
- rFunc.pop();
-}
-
-template<typename value_type> value_type square(value_type v)
-{
- return v*v;
-}
-
-double colorDiffSquared(const ARGBColor& rCol1, const ARGBColor& rCol2)
-{
- return
- square(rCol1.a-rCol2.a)
- + square(rCol1.r-rCol2.r)
- + square(rCol1.g-rCol2.g)
- + square(rCol1.b-rCol2.b);
-}
-
-/**
- check whether a polypolygon contains both open and closed
- polygons
-**/
-bool PolyPolygonIsMixedOpenAndClosed( const basegfx::B2DPolyPolygon& rPoly )
-{
- bool bRetval(false);
- bool bOpen(false);
- bool bClosed(false);
-
- // PolyPolygon is mixed open and closed if there is more than one
- // polygon and there are both closed and open polygons.
- for( sal_uInt32 a(0); !bRetval && a < rPoly.count(); a++ )
- {
- if ( rPoly.getB2DPolygon(a).isClosed() )
- {
- bClosed = true;
- }
- else
- {
- bOpen = true;
- }
-
- bRetval = (bClosed && bOpen);
- }
-
- return bRetval;
-}
-
-typedef std::map<OUString,std::size_t> ElementRefMapType;
-
-struct AnnotatingVisitor
-{
- AnnotatingVisitor(StatePool& rStatePool,
- StateMap& rStateMap,
- const State& rInitialState,
- const uno::Reference<xml::sax::XDocumentHandler>& xDocumentHandler,
- std::vector< uno::Reference<xml::dom::XElement> >& rUseElementVector,
- bool& rGradientNotFound) :
- mnCurrStateId(0),
- maCurrState(),
- maParentStates(),
- mrStates(rStatePool),
- mrStateMap(rStateMap),
- mxDocumentHandler(xDocumentHandler),
- maGradientVector(),
- maGradientStopVector(),
- maElementVector(),
- mrUseElementVector(rUseElementVector),
- mrGradientNotFound(rGradientNotFound)
- {
- maParentStates.push_back(rInitialState);
- }
-
- void operator()( const uno::Reference<xml::dom::XElement>& xElem)
- {
- const sal_Int32 nTagId(getTokenId(xElem->getTagName()));
- if (nTagId != XML_TEXT && nTagId != XML_TSPAN)
- return;
-
- maCurrState = maParentStates.back();
- maCurrState.maTransform.identity();
- maCurrState.maViewBox.reset();
- // if necessary, serialize to automatic-style section
- writeStyle(xElem,nTagId);
- }
-
- bool IsAncestorId(const uno::Reference<xml::dom::XNode>& xParentNode, const OUString& rValue)
- {
- bool bSelfCycle = false;
- if (xParentNode.is() && xParentNode->getNodeType() == xml::dom::NodeType_ELEMENT_NODE)
- {
- if (xParentNode->hasAttributes())
- {
- const uno::Reference<xml::dom::XNamedNodeMap> xParentAttributes = xParentNode->getAttributes();
- const sal_Int32 nFooNumAttrs(xParentAttributes->getLength());
- for (sal_Int32 i=0; i < nFooNumAttrs; ++i)
- {
- const sal_Int32 nTokenId(getTokenId(xParentAttributes->item(i)->getNodeName()));
- if (XML_ID == nTokenId)
- {
- OUString sParentID = xParentAttributes->item(i)->getNodeValue();
- bSelfCycle = sParentID == rValue;
- break;
- }
- }
- }
-
- if (!bSelfCycle)
- bSelfCycle = IsAncestorId(xParentNode->getParentNode(), rValue);
- }
- return bSelfCycle;
- }
-
- void operator()( const uno::Reference<xml::dom::XElement>& xElem,
- const uno::Reference<xml::dom::XNamedNodeMap>& xAttributes )
- {
- const sal_Int32 nTagId(getTokenId(xElem->getTagName()));
- switch (nTagId)
- {
- case XML_LINEARGRADIENT:
- {
- const sal_Int32 nNumAttrs( xAttributes->getLength() );
- maGradientVector.emplace_back(Gradient::LINEAR);
-
- // do we have a reference to a parent gradient? parse
- // that first, as it sets our defaults here (manually
- // tracking default state on each Gradient variable is
- // much more overhead)
- uno::Reference<xml::dom::XNode> xNode(xAttributes->getNamedItem("href"));
- if(xNode.is())
- {
- const OUString sValue(xNode->getNodeValue());
- ElementRefMapType::iterator aFound=maGradientIdMap.end();
- if ( sValue.startsWith("#") )
- aFound = maGradientIdMap.find(sValue.copy(1));
- else
- aFound = maGradientIdMap.find(sValue);
-
- if( aFound != maGradientIdMap.end() )
- maGradientVector.back() = maGradientVector[aFound->second];
- else
- {
- mrGradientNotFound = true;
- maGradientVector.pop_back();
- return;
- }
- }
-
- // do that after dereferencing, to prevent hyperlinked
- // gradient to clobber our Id again
- maGradientVector.back().mnId = maGradientVector.size()-1;
- maGradientVector.back().meType = Gradient::LINEAR; // has been clobbered as well
-
- for( sal_Int32 i=0; i<nNumAttrs; ++i )
- {
- parseLinearGradientData( maGradientVector.back(),
- maGradientVector.size()-1,
- getTokenId(xAttributes->item(i)->getNodeName()),
- xAttributes->item(i)->getNodeValue() );
- }
- break;
- }
- case XML_RADIALGRADIENT:
- {
- const sal_Int32 nNumAttrs( xAttributes->getLength() );
- maGradientVector.emplace_back(Gradient::RADIAL);
-
- // do we have a reference to a parent gradient? parse
- // that first, as it sets our defaults here (manually
- // tracking default state on each Gradient variable is
- // much more overhead)
- uno::Reference<xml::dom::XNode> xNode(xAttributes->getNamedItem("href"));
- if(xNode.is())
- {
- const OUString sValue(xNode->getNodeValue());
- ElementRefMapType::iterator aFound=maGradientIdMap.end();
- if ( sValue.startsWith("#") )
- aFound = maGradientIdMap.find(sValue.copy(1));
- else
- aFound = maGradientIdMap.find(sValue);
-
- if( aFound != maGradientIdMap.end() )
- maGradientVector.back() = maGradientVector[aFound->second];
- else
- {
- mrGradientNotFound = true;
- maGradientVector.pop_back();
- return;
- }
- }
-
- // do that after dereferencing, to prevent hyperlinked
- // gradient to clobber our Id again
- maGradientVector.back().mnId = maGradientVector.size()-1;
- maGradientVector.back().meType = Gradient::RADIAL; // has been clobbered as well
-
- for( sal_Int32 i=0; i<nNumAttrs; ++i )
- {
- parseRadialGradientData( maGradientVector.back(),
- maGradientVector.size()-1,
- getTokenId(xAttributes->item(i)->getNodeName()),
- xAttributes->item(i)->getNodeValue() );
- }
- break;
- }
- case XML_USE:
- {
- uno::Reference<xml::dom::XNode> xNode(xAttributes->getNamedItem("href"));
- if(xNode.is())
- {
- OUString sValue(xNode->getNodeValue());
- ElementRefMapType::iterator aFound=maElementIdMap.end();
- if ( sValue.startsWith("#") )
- sValue = sValue.copy(1);
- aFound = maElementIdMap.find(sValue);
- bool bFound = aFound != maElementIdMap.end();
- if (bFound)
- {
- const bool bSelfCycle = IsAncestorId(xElem->getParentNode(), sValue);
- if (bSelfCycle)
- {
- SAL_WARN("filter.svg", "\"use\" declaration with target of ancestor node, causing use cycle");
- //drop this invalid self-referencing "use" node
- maElementIdMap.erase(aFound);
- bFound = false;
- }
- }
-
- if (bFound)
- {
- uno::Reference<xml::dom::XElement> xRefElem(
- maElementVector[aFound->second]->cloneNode(true), uno::UNO_QUERY);
-
- xRefElem->removeAttribute("id");
-
- const sal_Int32 nNumAttrs( xAttributes->getLength() );
- OUString sAttributeValue;
- double x=0.0, y=0.0;
- for( sal_Int32 i=0; i<nNumAttrs; ++i )
- {
- sAttributeValue = xAttributes->item(i)->getNodeValue();
- const sal_Int32 nAttribId(
- getTokenId(xAttributes->item(i)->getNodeName()));
-
- switch(nAttribId)
- {
- case XML_ID:
- maElementVector.push_back(xElem);
- maElementIdMap.insert(std::make_pair(sAttributeValue,
- maElementVector.size() - 1));
- break;
- case XML_X:
- x = convLength(sAttributeValue,maCurrState,'h');
- break;
- case XML_Y:
- y = convLength(sAttributeValue,maCurrState,'v');
- break;
- case XML_TRANSFORM:
- break;
- default:
- OUString sAttributeName = xAttributes->item(i)->getNodeName();
- xRefElem->setAttribute(sAttributeName, sAttributeValue);
- break;
- }
- }
- std::stringstream ssAttrValue;
- ssAttrValue << xRefElem->getAttribute("transform");
- ssAttrValue << xElem->getAttribute("transform");
- ssAttrValue << " translate(" << x << "," << y << ")";
-
- OUString attrValue(OUString::createFromAscii (ssAttrValue.str().c_str()));
- xRefElem->setAttribute("transform", attrValue);
-
- mrUseElementVector.push_back(xRefElem);
-
- visitElements((*this), xRefElem, STYLE_ANNOTATOR);
- }
- }
- break;
- }
- case XML_STOP:
- {
- if (!maGradientVector.empty())
- {
- const sal_Int32 nNumAttrs( xAttributes->getLength() );
- maGradientStopVector.emplace_back();
- maGradientVector.back().maStops.push_back(maGradientStopVector.size()-1);
-
- // first parse 'color' as 'stop-color' might depend on it
- // if 'stop-color''s value is "currentColor" and parsed previously
- uno::Reference<xml::dom::XNode> xNodeColor(xAttributes->getNamedItem("color"));
- if(xNodeColor.is())
- parseGradientStop( maGradientStopVector.back(),
- maGradientStopVector.size()-1,
- XML_STOP_COLOR,
- xNodeColor->getNodeValue() );
-
- //now, parse the rest of attributes
- for( sal_Int32 i=0; i<nNumAttrs; ++i )
- {
- const sal_Int32 nTokenId(
- getTokenId(xAttributes->item(i)->getNodeName()));
- if ( nTokenId != XML_COLOR )
- parseGradientStop( maGradientStopVector.back(),
- maGradientStopVector.size()-1,
- nTokenId,
- xAttributes->item(i)->getNodeValue() );
- }
- }
- break;
- }
- default:
- {
- if ( !mrGradientNotFound )
- {
- // init state. inherit defaults from parent.
- maCurrState = maParentStates.back();
- maCurrState.maTransform.identity();
- maCurrState.maViewBox.reset();
-
- // first parse 'color' and 'style' as 'fill' and 'stroke' might depend on them
- // if their values are "currentColor" and parsed previously
- uno::Reference<xml::dom::XNode> xNodeColor(xAttributes->getNamedItem("color"));
- if(xNodeColor.is())
- parseAttribute(XML_COLOR, xNodeColor->getNodeValue());
-
- uno::Reference<xml::dom::XNode> xNodeStyle(xAttributes->getNamedItem("style"));
- if(xNodeStyle.is())
- parseStyle(xNodeStyle->getNodeValue());
-
- const sal_Int32 nNumAttrs( xAttributes->getLength() );
- OUString sAttributeValue;
-
- //now, parse the rest of attributes
- for( sal_Int32 i=0; i<nNumAttrs; ++i )
- {
- sAttributeValue = xAttributes->item(i)->getNodeValue();
- const sal_Int32 nTokenId(
- getTokenId(xAttributes->item(i)->getNodeName()));
- if( XML_ID == nTokenId )
- {
- maElementVector.push_back(xElem);
- maElementIdMap.insert(std::make_pair(sAttributeValue,
- maElementVector.size() - 1));
- }
- else if (nTokenId != XML_COLOR && nTokenId != XML_STYLE)
- parseAttribute(nTokenId,
- sAttributeValue);
- }
-
- // all attributes parsed, can calc total CTM now
- basegfx::B2DHomMatrix aLocalTransform;
- if( !maCurrState.maViewBox.isEmpty() &&
- maCurrState.maViewBox.getWidth() != 0.0 &&
- maCurrState.maViewBox.getHeight() != 0.0 )
- {
- // transform aViewBox into viewport, keep aspect ratio
- aLocalTransform.translate(-maCurrState.maViewBox.getMinX(),
- -maCurrState.maViewBox.getMinY());
- double scaleW = maCurrState.maViewport.getWidth()/maCurrState.maViewBox.getWidth();
- double scaleH = maCurrState.maViewport.getHeight()/maCurrState.maViewBox.getHeight();
- double scale = (scaleW < scaleH) ? scaleW : scaleH;
- aLocalTransform.scale(scale,scale);
- }
- else if( !maParentStates.back().maViewBox.isEmpty() )
- maCurrState.maViewBox = maParentStates.back().maViewBox;
-
- maCurrState.maCTM = maCurrState.maCTM*maCurrState.maTransform*aLocalTransform;
-
- // if necessary, serialize to automatic-style section
- writeStyle(xElem,nTagId);
- }
- }
- }
- }
-
- static OUString getStyleName( const char* sPrefix, sal_Int32 nId )
- {
- return OUString::createFromAscii(sPrefix)+OUString::number(nId);
- }
-
- bool hasGradientOpacity( const Gradient& rGradient )
- {
- return
- (rGradient.maStops.size() > 1) &&
- (maGradientStopVector[
- rGradient.maStops[0]].maStopColor.a != 1.0 ||
- maGradientStopVector[
- rGradient.maStops[1]].maStopColor.a != 1.0);
- }
-
- struct StopSorter
- {
- explicit StopSorter( const std::vector< GradientStop >& rStopVec ) :
- mrStopVec(rStopVec)
- {}
-
- bool operator()( std::size_t rLHS, std::size_t rRHS )
- {
- return mrStopVec[rLHS].mnStopPosition < mrStopVec[rRHS].mnStopPosition;
- }
-
- const std::vector< GradientStop >& mrStopVec;
- };
-
- void optimizeGradientStops( Gradient& rGradient )
- {
- // sort for increasing stop position
- std::sort(rGradient.maStops.begin(),rGradient.maStops.end(),
- StopSorter(maGradientStopVector));
-
- if( rGradient.maStops.size() < 3 )
- return; //easy! :-)
-
- // join similar colors
- std::vector<std::size_t> aNewStops { rGradient.maStops.front() };
- for( std::size_t i=1; i<rGradient.maStops.size(); ++i )
- {
- if( maGradientStopVector[rGradient.maStops[i]].maStopColor !=
- maGradientStopVector[aNewStops.back()].maStopColor )
- aNewStops.push_back(rGradient.maStops[i]);
- }
-
- rGradient.maStops = aNewStops;
- if (rGradient.maStops.size() < 2)
- {
- return; // can't optimize further...
- }
-
- // axial gradient, maybe?
- if( rGradient.meType == Gradient::LINEAR &&
- rGradient.maStops.size() == 3 &&
- maGradientStopVector[rGradient.maStops.front()].maStopColor ==
- maGradientStopVector[rGradient.maStops.back()].maStopColor )
- {
- // yep - keep it at that
- return;
- }
-
- // find out most significant color difference, and limit to
- // those two stops around this border (metric is
- // super-simplistic: take euclidean distance of colors, weigh
- // with stop distance)
- std::size_t nMaxIndex=0;
- double fMaxDistance=0.0;
- for( std::size_t i=1; i<rGradient.maStops.size(); ++i )
- {
- const double fCurrDistance(
- colorDiffSquared(
- maGradientStopVector[rGradient.maStops[i-1]].maStopColor,
- maGradientStopVector[rGradient.maStops[i]].maStopColor) *
- (square(maGradientStopVector[rGradient.maStops[i-1]].mnStopPosition) +
- square(maGradientStopVector[rGradient.maStops[i]].mnStopPosition)) );
-
- if( fCurrDistance > fMaxDistance )
- {
- nMaxIndex = i-1;
- fMaxDistance = fCurrDistance;
- }
- }
- rGradient.maStops[0] = rGradient.maStops[nMaxIndex];
- rGradient.maStops[1] = rGradient.maStops[nMaxIndex+1];
- rGradient.maStops.erase(rGradient.maStops.begin()+2,rGradient.maStops.end());
- }
-
- static sal_Int8 toByteColor( double val )
- {
- // TODO(Q3): duplicated from vcl::unotools
- return sal::static_int_cast<sal_Int8>(
- basegfx::fround(val*255.0));
- }
-
- static OUString getOdfColor( const ARGBColor& rColor )
- {
- // TODO(Q3): duplicated from pdfimport
- OUStringBuffer aBuf( 7 );
- const sal_uInt8 nRed ( toByteColor(rColor.r) );
- const sal_uInt8 nGreen( toByteColor(rColor.g) );
- const sal_uInt8 nBlue ( toByteColor(rColor.b) );
- aBuf.append( '#' );
- if( nRed < 0x10 )
- aBuf.append( '0' );
- aBuf.append( sal_Int32(nRed), 16 );
- if( nGreen < 0x10 )
- aBuf.append( '0' );
- aBuf.append( sal_Int32(nGreen), 16 );
- if( nBlue < 0x10 )
- aBuf.append( '0' );
- aBuf.append( sal_Int32(nBlue), 16 );
-
- // TODO(F3): respect alpha transparency (polygons etc.)
- OSL_ASSERT(rColor.a == 1.0);
-
- return aBuf.makeStringAndClear();
- }
-
- static OUString getOdfAlign( TextAlign eAlign )
- {
- switch(eAlign)
- {
- default:
- case BEFORE:
- return OUString("start");
- case CENTER:
- return OUString("center");
- case AFTER:
- return OUString("end");
- }
- }
-
- bool writeStyle(State& rState, const sal_Int32 nTagId)
- {
- rtl::Reference<SvXMLAttributeList> xAttrs( new SvXMLAttributeList() );
- uno::Reference<xml::sax::XAttributeList> xUnoAttrs( xAttrs.get() );
-
- if (XML_TEXT == nTagId || XML_TSPAN == nTagId) {
- rState.mbIsText = true;
- basegfx::B2DTuple aScale, aTranslate;
- double fRotate, fShearX;
- if (rState.maCTM.decompose(aScale, aTranslate, fRotate, fShearX))
- {
- rState.mnFontSize *= aScale.getX();
- }
- }
-
- std::pair<StatePool::iterator,
- bool> aRes = mrStates.insert(rState);
- SAL_INFO ("filter.svg", "size " << mrStates.size() << " id " << const_cast<State&>(*aRes.first).mnStyleId);
-
- if( !aRes.second )
- return false; // not written
-
- ++mnCurrStateId;
-
- // mnStyleId does not take part in hashing/comparison
- const_cast<State&>(*aRes.first).mnStyleId = mnCurrStateId;
- SAL_INFO ("filter.svg", " --> " << const_cast<State&>(*aRes.first).mnStyleId);
-
- mrStateMap.insert(std::make_pair(
- mnCurrStateId,
- rState));
-
- // find two representative stop colors (as ODF only support
- // start&end color)
- optimizeGradientStops(rState.maFillGradient);
-
- if( !mxDocumentHandler.is() )
- return true; // cannot write style, svm import case
-
- // do we have a gradient fill? then write out gradient as well
- if( rState.meFillType == GRADIENT && rState.maFillGradient.maStops.size() > 0 )
- {
- // if only one stop-color is defined
- if( rState.maFillGradient.maStops.size() == 1 )
- rState.maFillGradient.maStops.push_back(rState.maFillGradient.maStops[0]);
-
- // TODO(F3): ODF12 supposedly also groks svg:linear/radialGradient. But CL says: nope.
- xAttrs->AddAttribute( "draw:name", getStyleName("svggradient", rState.maFillGradient.mnId) );
- if( rState.maFillGradient.meType == Gradient::LINEAR )
- {
- // should the optimizeGradientStops method decide that
- // this is a three-color gradient, it prolly wanted us
- // to take axial instead
- xAttrs->AddAttribute( "draw:style",
- rState.maFillGradient.maStops.size() == 3 ?
- OUString("axial") :
- OUString("linear") );
- }
- else
- {
- xAttrs->AddAttribute( "draw:style", "ellipsoid" );
- xAttrs->AddAttribute( "draw:cx", "50%" );
- xAttrs->AddAttribute( "draw:cy", "50%" );
- }
-
- basegfx::B2DTuple rScale, rTranslate;
- double rRotate, rShearX;
- if( rState.maFillGradient.maTransform.decompose(rScale, rTranslate, rRotate, rShearX) )
- xAttrs->AddAttribute( "draw:angle",
- OUString::number(rRotate*1800.0/M_PI ) );
- xAttrs->AddAttribute( "draw:start-color",
- getOdfColor(
- maGradientStopVector[
- rState.maFillGradient.maStops[0]].maStopColor) );
- xAttrs->AddAttribute( "draw:end-color",
- getOdfColor(
- maGradientStopVector[
- rState.maFillGradient.maStops[1]].maStopColor) );
- xAttrs->AddAttribute( "draw:border", "0%" );
- mxDocumentHandler->startElement( "draw:gradient", xUnoAttrs );
- mxDocumentHandler->endElement( "draw:gradient" );
-
- if( hasGradientOpacity(rState.maFillGradient) )
- {
- // need to write out opacity style as well
- xAttrs->Clear();
- xAttrs->AddAttribute( "draw:name", getStyleName("svgopacity", rState.maFillGradient.mnId) );
- if( rState.maFillGradient.meType == Gradient::LINEAR )
- {
- xAttrs->AddAttribute( "draw:style", "linear" );
- }
- else
- {
- xAttrs->AddAttribute( "draw:style", "ellipsoid" );
- xAttrs->AddAttribute( "draw:cx", "50%" );
- xAttrs->AddAttribute( "draw:cy", "50%" );
- }
-
- // modulate gradient opacity with overall fill opacity
- xAttrs->AddAttribute( "draw:end",
- OUString::number(
- maGradientStopVector[
- rState.maFillGradient.maStops[0]].maStopColor.a*
- maCurrState.mnFillOpacity*maCurrState.mnOpacity*100.0)+"%" );
- xAttrs->AddAttribute( "draw:start",
- OUString::number(
- maGradientStopVector[
- rState.maFillGradient.maStops[1]].maStopColor.a*
- maCurrState.mnFillOpacity*maCurrState.mnOpacity*100.0)+"%" );
- xAttrs->AddAttribute( "draw:border", "0%" );
- mxDocumentHandler->startElement( "draw:opacity", xUnoAttrs );
- mxDocumentHandler->endElement( "draw:opacity" );
- }
- }
-
- // serialize to automatic-style section
- if( nTagId == XML_TEXT || nTagId == XML_TSPAN)
- {
- // write paragraph style attributes
- xAttrs->Clear();
-
- xAttrs->AddAttribute( "style:name", getStyleName("svgparagraphstyle", mnCurrStateId) );
- xAttrs->AddAttribute( "style:family", "paragraph" );
- mxDocumentHandler->startElement( "style:style", xUnoAttrs );
-
- xAttrs->Clear();
- xAttrs->AddAttribute( "fo:text-align", getOdfAlign(rState.meTextAnchor));
-
- mxDocumentHandler->startElement( "style:paragraph-properties", xUnoAttrs );
- mxDocumentHandler->endElement( "style:paragraph-properties" );
- mxDocumentHandler->endElement( "style:style" );
-
- // write text style attributes
- xAttrs->Clear();
-
- xAttrs->AddAttribute( "style:name", getStyleName("svgtextstyle", mnCurrStateId) );
- xAttrs->AddAttribute( "style:family", "text" );
- mxDocumentHandler->startElement( "style:style", xUnoAttrs );
- xAttrs->Clear();
- xAttrs->AddAttribute( "fo:font-family", rState.maFontFamily);
- xAttrs->AddAttribute( "fo:font-size",
- OUString::number(pt2mm(rState.mnFontSize))+"mm");
- xAttrs->AddAttribute( "fo:font-style", rState.maFontStyle);
- xAttrs->AddAttribute( "fo:font-variant", rState.maFontVariant);
- xAttrs->AddAttribute( "fo:font-weight",
- OUString::number(rState.mnFontWeight));
- xAttrs->AddAttribute( "fo:color", getOdfColor(rState.maFillColor));
-
- mxDocumentHandler->startElement( "style:text-properties", xUnoAttrs );
- mxDocumentHandler->endElement( "style:text-properties" );
- mxDocumentHandler->endElement( "style:style" );
- }
-
- xAttrs->Clear();
- xAttrs->AddAttribute( "style:name" , getStyleName("svggraphicstyle", mnCurrStateId) );
- xAttrs->AddAttribute( "style:family", "graphic" );
- mxDocumentHandler->startElement( "style:style", xUnoAttrs );
-
- xAttrs->Clear();
- // text or shape? if the former, no use in processing any
- // graphic attributes except stroke color, ODF can do ~nothing
- // with text shapes
- if( nTagId == XML_TEXT || nTagId == XML_TSPAN )
- {
- //xAttrs->AddAttribute( "draw:auto-grow-height", "true");
- xAttrs->AddAttribute( "draw:auto-grow-width", "true");
- xAttrs->AddAttribute( "draw:textarea-horizontal-align", "left");
- //xAttrs->AddAttribute( "draw:textarea-vertical-align", "top");
- xAttrs->AddAttribute( "fo:min-height", "0cm");
-
- xAttrs->AddAttribute( "fo:padding-top", "0cm");
- xAttrs->AddAttribute( "fo:padding-left", "0cm");
- xAttrs->AddAttribute( "fo:padding-right", "0cm");
- xAttrs->AddAttribute( "fo:padding-bottom", "0cm");
-
- // disable any background shape
- xAttrs->AddAttribute( "draw:stroke", "none");
- xAttrs->AddAttribute( "draw:fill", "none");
- }
- else
- {
- if( rState.meFillType != NONE )
- {
- if( rState.meFillType == GRADIENT )
- {
- // don't fill the gradient if there's no stop element present
- if( rState.maFillGradient.maStops.size() == 0 )
- xAttrs->AddAttribute( "draw:fill", "none" );
- else
- {
- xAttrs->AddAttribute( "draw:fill", "gradient");
- xAttrs->AddAttribute( "draw:fill-gradient-name",
- getStyleName("svggradient", rState.maFillGradient.mnId) );
- if( hasGradientOpacity(rState.maFillGradient) )
- {
- // needs transparency gradient as well
- xAttrs->AddAttribute( "draw:opacity-name",
- getStyleName("svgopacity", rState.maFillGradient.mnId) );
- }
- else if( maCurrState.mnFillOpacity*maCurrState.mnOpacity != 1.0 )
- xAttrs->AddAttribute( "draw:opacity",
- OUString::number(100.0*maCurrState.mnFillOpacity*maCurrState.mnOpacity)+"%" );
- }
- }
- else
- {
- xAttrs->AddAttribute( "draw:fill", "solid");
- xAttrs->AddAttribute( "draw:fill-color", getOdfColor(rState.maFillColor));
- if( maCurrState.mnFillOpacity*maCurrState.mnOpacity != 1.0 )
- xAttrs->AddAttribute( "draw:opacity",
- OUString::number(100.0*maCurrState.mnFillOpacity*maCurrState.mnOpacity)+"%" );
- }
- }
- else
- xAttrs->AddAttribute( "draw:fill", "none");
-
- if( rState.meStrokeType == SOLID )
- {
- xAttrs->AddAttribute( "draw:stroke", "solid");
- xAttrs->AddAttribute( "svg:stroke-color", getOdfColor(rState.maStrokeColor));
- }
- else if( rState.meStrokeType == DASH )
- {
- xAttrs->AddAttribute( "draw:stroke", "dash");
- xAttrs->AddAttribute( "draw:stroke-dash", "dash"+OUString::number(mnCurrStateId));
- xAttrs->AddAttribute( "svg:stroke-color", getOdfColor(rState.maStrokeColor));
- }
- else
- xAttrs->AddAttribute( "draw:stroke", "none");
-
- if( maCurrState.mnStrokeWidth != 0.0 )
- {
- ::basegfx::B2DVector aVec(maCurrState.mnStrokeWidth,0);
- aVec *= maCurrState.maCTM;
- xAttrs->AddAttribute( "svg:stroke-width", OUString::number( pt2mm(aVec.getLength()) )+"mm");
- }
- if( maCurrState.meLineJoin == basegfx::B2DLineJoin::Miter )
- xAttrs->AddAttribute( "draw:stroke-linejoin", "miter");
- else if( maCurrState.meLineJoin == basegfx::B2DLineJoin::Round )
- xAttrs->AddAttribute( "draw:stroke-linejoin", "round");
- else if( maCurrState.meLineJoin == basegfx::B2DLineJoin::Bevel )
- xAttrs->AddAttribute( "draw:stroke-linejoin", "bevel");
- if( maCurrState.mnStrokeOpacity*maCurrState.mnOpacity != 1.0 )
- xAttrs->AddAttribute( "svg:stroke-opacity",
- OUString::number(100.0*maCurrState.mnStrokeOpacity*maCurrState.mnOpacity)+"%");
- }
-
- mxDocumentHandler->startElement( "style:graphic-properties", xUnoAttrs );
- mxDocumentHandler->endElement( "style:graphic-properties" );
- mxDocumentHandler->endElement( "style:style" );
-
- return true; // newly written
- }
-
- void writeStyle(const uno::Reference<xml::dom::XElement>& xElem, const sal_Int32 nTagId)
- {
- SAL_INFO ("filter.svg", "writeStyle xElem " << xElem->getTagName());
-
- sal_Int32 nStyleId=0;
- if( writeStyle(maCurrState, nTagId) )
- nStyleId = mnCurrStateId;
- else
- nStyleId = mrStates.find(maCurrState)->mnStyleId;
-
- xElem->setAttribute("internal-style-ref",
- OUString::number(
- nStyleId)
- +"$0");
- }
-
- void push()
- {
- maParentStates.push_back(maCurrState);
- }
-
- void pop()
- {
- maParentStates.pop_back();
- }
-
- void parseLinearGradientData( Gradient& io_rCurrGradient,
- const sal_Int32 nGradientNumber,
- const sal_Int32 nTokenId,
- const OUString& sValue )
- {
- switch(nTokenId)
- {
- case XML_GRADIENTTRANSFORM:
- {
- OString aValueUtf8( sValue.getStr(),
- sValue.getLength(),
- RTL_TEXTENCODING_UTF8 );
- parseTransform(aValueUtf8.getStr(),io_rCurrGradient.maTransform);
- break;
- }
- case XML_X1:
- io_rCurrGradient.maCoords.linear.mfX1 = convLength(sValue,maCurrState,'h');
- break;
- case XML_X2:
- io_rCurrGradient.maCoords.linear.mfX2 = convLength(sValue,maCurrState,'h');
- break;
- case XML_Y1:
- io_rCurrGradient.maCoords.linear.mfY1 = convLength(sValue,maCurrState,'v');
- break;
- case XML_Y2:
- io_rCurrGradient.maCoords.linear.mfY2 = convLength(sValue,maCurrState,'v');
- break;
- case XML_ID:
- maGradientIdMap.insert(std::make_pair(sValue,nGradientNumber));
- break;
- case XML_GRADIENTUNITS:
- if (getTokenId(sValue) == XML_OBJECTBOUNDINGBOX)
- io_rCurrGradient.mbBoundingBoxUnits = true;
- else
- io_rCurrGradient.mbBoundingBoxUnits = false;
- break;
- default:
- break;
- }
- }
-
- void parseRadialGradientData( Gradient& io_rCurrGradient,
- const sal_Int32 nGradientNumber,
- const sal_Int32 nTokenId,
- const OUString& sValue )
- {
- switch(nTokenId)
- {
- case XML_GRADIENTTRANSFORM:
- {
- OString aValueUtf8( sValue.getStr(),
- sValue.getLength(),
- RTL_TEXTENCODING_UTF8 );
- parseTransform(aValueUtf8.getStr(),io_rCurrGradient.maTransform);
- break;
- }
- case XML_CX:
- io_rCurrGradient.maCoords.radial.mfCX = convLength(sValue,maCurrState,'h');
- break;
- case XML_CY:
- io_rCurrGradient.maCoords.radial.mfCY = convLength(sValue,maCurrState,'v');
- break;
- case XML_FX:
- io_rCurrGradient.maCoords.radial.mfFX = convLength(sValue,maCurrState,'h');
- break;
- case XML_FY:
- io_rCurrGradient.maCoords.radial.mfFY = convLength(sValue,maCurrState,'v');
- break;
- case XML_R:
- io_rCurrGradient.maCoords.radial.mfR = convLength(sValue,maCurrState,'r');
- break;
- case XML_ID:
- maGradientIdMap.insert(std::make_pair(sValue,nGradientNumber));
- break;
- case XML_GRADIENTUNITS:
- if (getTokenId(sValue) == XML_OBJECTBOUNDINGBOX)
- io_rCurrGradient.mbBoundingBoxUnits = true;
- else
- io_rCurrGradient.mbBoundingBoxUnits = false;
- break;
- default:
- break;
- }
- }
-
- void parseGradientStop( GradientStop& io_rGradientStop,
- const sal_Int32 nStopNumber,
- const sal_Int32 nTokenId,
- const OUString& sValue )
- {
- switch(nTokenId)
- {
- case XML_HREF:
- {
- ElementRefMapType::iterator aFound=maStopIdMap.end();
- if ( sValue.startsWith("#") )
- aFound = maStopIdMap.find(sValue.copy(1));
- else
- aFound = maStopIdMap.find(sValue);
-
- if( aFound != maStopIdMap.end() )
- io_rGradientStop = maGradientStopVector[aFound->second];
- break;
- }
- case XML_ID:
- maStopIdMap.insert(std::make_pair(sValue,nStopNumber));
- break;
- case XML_STOP_COLOR:
- if( maGradientVector.empty() ||
- maGradientVector.back().maStops.empty() )
- break;
- parseColor( sValue.toUtf8().getStr(), maGradientStopVector[
- maGradientVector.back().maStops.back()].maStopColor );
- break;
- case XML_STOP_OPACITY:
- if( maGradientVector.empty() ||
- maGradientVector.back().maStops.empty() )
- break;
- parseOpacity( sValue.toUtf8().getStr(),
- maGradientStopVector[
- maGradientVector.back().maStops.back()].maStopColor );
- break;
- case XML_OFFSET:
- io_rGradientStop.mnStopPosition = sValue.toDouble();
- break;
- case XML_STYLE:
- parseStyle( sValue );
- break;
- default:
- break;
- }
- }
-
- void parseAttribute( const sal_Int32 nTokenId,
- const OUString& sValue )
- {
- OString aValueUtf8( sValue.getStr(),
- sValue.getLength(),
- RTL_TEXTENCODING_UTF8 );
- switch(nTokenId)
- {
- case XML_WIDTH:
- {
- const double fViewPortWidth(
- convLength(sValue,maCurrState,'h'));
-
- maCurrState.maViewport.expand(
- basegfx::B2DTuple(fViewPortWidth,0.0));
- break;
- }
- case XML_HEIGHT:
- {
- const double fViewPortHeight(
- convLength(sValue,maCurrState,'v'));
-
- maCurrState.maViewport.expand(
- basegfx::B2DTuple(0.0,fViewPortHeight));
- break;
- }
- case XML_VIEWBOX:
- {
- // TODO(F1): preserveAspectRatio
- parseViewBox(
- aValueUtf8.getStr(),
- maCurrState.maViewBox);
- break;
- }
- case XML_FILL_RULE:
- {
- if( aValueUtf8 == "evenodd" )
- maCurrState.meFillRule = EVEN_ODD;
- else if( aValueUtf8 == "nonzero" )
- maCurrState.meFillRule = NON_ZERO;
- else if( aValueUtf8 == "inherit" )
- maCurrState.meFillRule = maParentStates.back().meFillRule;
- break;
- }
- case XML_OPACITY:
- if( aValueUtf8 == "inherit" )
- maCurrState.mnOpacity = maParentStates.back().mnOpacity;
- else
- maCurrState.mnOpacity = aValueUtf8.toDouble();
- break;
- case XML_FILL_OPACITY:
- if( aValueUtf8 == "inherit" )
- maCurrState.mnFillOpacity = maParentStates.back().mnFillOpacity;
- else {
- maCurrState.mnFillOpacity = aValueUtf8.toDouble();
- if( maCurrState.mnFillOpacity > 1 )
- maCurrState.mnFillOpacity = 1;
- }
- break;
- case XML_STROKE_WIDTH:
- {
- if( aValueUtf8 == "inherit" )
- maCurrState.mnStrokeWidth = maParentStates.back().mnStrokeWidth;
- else
- maCurrState.mnStrokeWidth = convLength(sValue,maCurrState,'r');
- break;
- }
- case XML_STROKE_LINECAP:
- {
- if( aValueUtf8 == "butt" )
- maCurrState.meLineCap = BUTT;
- else if( aValueUtf8 == "round" )
- maCurrState.meLineCap = ROUND;
- else if( aValueUtf8 == "square" )
- maCurrState.meLineCap = RECT;
- else if( aValueUtf8 == "inherit" )
- maCurrState.meLineCap = maParentStates.back().meLineCap;
- break;
- }
- case XML_STROKE_LINEJOIN:
- {
- if( aValueUtf8 == "miter" )
- maCurrState.meLineJoin = basegfx::B2DLineJoin::Miter;
- else if( aValueUtf8 == "round" )
- maCurrState.meLineJoin = basegfx::B2DLineJoin::Round;
- else if( aValueUtf8 == "bevel" )
- maCurrState.meLineJoin = basegfx::B2DLineJoin::Bevel;
- else if( aValueUtf8 == "inherit" )
- maCurrState.meLineJoin = maParentStates.back().meLineJoin;
- break;
- }
- case XML_STROKE_MITERLIMIT:
- {
- if( aValueUtf8 == "inherit" )
- maCurrState.mnMiterLimit = maParentStates.back().mnMiterLimit;
- else
- maCurrState.mnMiterLimit = aValueUtf8.toDouble();
- break;
- }
- case XML_STROKE_DASHOFFSET:
- {
- if( aValueUtf8 == "inherit" )
- maCurrState.mnDashOffset = maParentStates.back().mnDashOffset;
- else
- maCurrState.mnDashOffset = convLength(sValue,maCurrState,'r');
- break;
- }
- case XML_STROKE_DASHARRAY:
- {
- if( aValueUtf8 == "none" )
- {
- maCurrState.maDashArray.clear();
- maCurrState.meStrokeType = SOLID;
- }
- else if( aValueUtf8 == "inherit" )
- maCurrState.maDashArray = maParentStates.back().maDashArray;
- else
- {
- if( parseDashArray(aValueUtf8.getStr(),
- maCurrState.maDashArray) )
- {
- maCurrState.meStrokeType = DASH;
- }
- else
- {
- maCurrState.meStrokeType = SOLID;
- }
- }
- break;
- }
- case XML_STROKE_OPACITY:
- if( aValueUtf8 == "inherit" )
- maCurrState.mnStrokeOpacity = maParentStates.back().mnStrokeOpacity;
- else
- maCurrState.mnStrokeOpacity = aValueUtf8.toDouble();
- break;
- case XML_FILL:
- {
- const State& rParent( maParentStates.back() );
- parsePaint( sValue,
- aValueUtf8.getStr(),
- maCurrState.meFillType,
- maCurrState.maFillColor,
- maCurrState.maFillGradient,
- rParent.meFillType,
- rParent.maFillColor,
- rParent.maFillGradient );
- break;
- }
- case XML_STROKE:
- {
- const State& rParent( maParentStates.back() );
- parsePaint( sValue,
- aValueUtf8.getStr(),
- maCurrState.meStrokeType,
- maCurrState.maStrokeColor,
- maCurrState.maStrokeGradient,
- rParent.meStrokeType,
- rParent.maStrokeColor,
- rParent.maStrokeGradient );
- break;
- }
- case XML_COLOR:
- {
- if( aValueUtf8 == "inherit" )
- maCurrState.maCurrentColor = maParentStates.back().maCurrentColor;
- else
- parseColor(aValueUtf8.getStr(), maCurrState.maCurrentColor);
- break;
- }
- case XML_TRANSFORM:
- {
- basegfx::B2DHomMatrix aTransform;
- parseTransform(aValueUtf8.getStr(),aTransform);
- maCurrState.maTransform = maCurrState.maTransform*aTransform;
- break;
- }
- case XML_FONT_FAMILY:
- maCurrState.maFontFamily=sValue;
- break;
- case XML_FONT_SIZE:
- maCurrState.mnParentFontSize=maParentStates.back().mnFontSize;
- maCurrState.mnFontSize=convLength(sValue,maCurrState,'v');
- break;
- case XML_FONT_STYLE:
- parseFontStyle(maCurrState,sValue,aValueUtf8.getStr());
- break;
- case XML_FONT_WEIGHT:
- maCurrState.mnFontWeight=sValue.toDouble();
- break;
- case XML_FONT_VARIANT:
- parseFontVariant(maCurrState,sValue,aValueUtf8.getStr());
- break;
- case XML_TEXT_ANCHOR:
- parseTextAlign(maCurrState,aValueUtf8.getStr());
- break;
- case XML_STOP_COLOR:
- case XML_STOP_OPACITY:
- parseGradientStop( maGradientStopVector.back(),
- maGradientStopVector.size()-1,
- nTokenId, sValue );
- break;
- case XML_TOKEN_INVALID:
- SAL_INFO("filter.svg", "unhandled token");
- break;
- default:
- SAL_INFO("filter.svg", "unhandled token " << getTokenName(nTokenId));
- break;
- }
- }
-
- void parseStyle( const OUString& sValue )
- {
- // split individual style attributes
- sal_Int32 nIndex=0, nDummyIndex=0;
- OUString aCurrToken;
- do
- {
- aCurrToken=sValue.getToken(0,';',nIndex);
-
- if( !aCurrToken.isEmpty() )
- {
- // split attrib & value
- nDummyIndex=0;
- OUString aCurrAttrib(
- aCurrToken.getToken(0,':',nDummyIndex).trim());
- OSL_ASSERT(nDummyIndex!=-1);
- nDummyIndex=0;
- OUString aCurrValue(
- aCurrToken.getToken(1,':',nDummyIndex).trim());
- OSL_ASSERT(nDummyIndex==-1);
-
- // recurse into normal attribute parsing
- parseAttribute( getTokenId(aCurrAttrib),
- aCurrValue );
- }
- }
- while( nIndex != -1 );
- }
-
- static void parseFontStyle( State& io_rInitialState,
- const OUString& rValue,
- const char* sValue )
- {
- if( strcmp(sValue,"inherit") != 0 )
- io_rInitialState.maFontStyle = rValue;
- }
-
- static void parseFontVariant( State& io_rInitialState,
- const OUString& rValue,
- const char* sValue )
- {
- if( strcmp(sValue,"inherit") != 0 )
- io_rInitialState.maFontVariant = rValue;
- }
-
- static void parseTextAlign( State& io_rInitialState,
- const char* sValue )
- {
- if( strcmp(sValue,"start") == 0 )
- io_rInitialState.meTextAnchor = BEFORE;
- else if( strcmp(sValue,"middle") == 0 )
- io_rInitialState.meTextAnchor = CENTER;
- else if( strcmp(sValue,"end") == 0 )
- io_rInitialState.meTextAnchor = AFTER;
- // keep current val for sValue == "inherit"
- }
-
- void parsePaint( const OUString& rValue,
- const char* sValue,
- PaintType& rType,
- ARGBColor& rColor,
- Gradient& rGradient,
- const PaintType& rInheritType,
- const ARGBColor& rInheritColor,
- const Gradient& rInheritGradient )
- {
- std::pair<const char*,const char*> aPaintUri(nullptr,nullptr);
- std::pair<ARGBColor,bool> aColor(maCurrState.maCurrentColor,
- false);
- if( strcmp(sValue,"none") == 0 )
- rType = NONE;
- else if( strcmp(sValue,"currentColor") == 0 )
- {
- rType = SOLID;
- rColor = maCurrState.maCurrentColor;
- }
- else if( strcmp(sValue,"inherit") == 0)
- {
- rType = rInheritType;
- rColor = rInheritColor;
- rGradient = rInheritGradient;
- }
- else if( parsePaintUri(aPaintUri,aColor,sValue) )
- {
- if( aPaintUri.first != aPaintUri.second )
- {
- // assuming gradient. assumption does not hold generally
- if( strstr(sValue,")") && rValue.getLength() > 5 )
- {
- ElementRefMapType::iterator aRes;
- if( (aRes=maGradientIdMap.find(
- rValue.copy(aPaintUri.first-sValue,
- aPaintUri.second-aPaintUri.first))) != maGradientIdMap.end() )
- {
- rGradient = maGradientVector[aRes->second];
- rType = GRADIENT;
- }
- }
- }
- else if( aColor.second )
- {
- rType = SOLID;
- rColor = aColor.first;
- }
- else
- {
- rType = NONE;
- }
- }
- else
- {
- rType = SOLID;
- parseColor(sValue,rColor);
- }
- }
-
- sal_Int32 mnCurrStateId;
- State maCurrState;
- std::vector<State> maParentStates;
- StatePool& mrStates;
- StateMap& mrStateMap;
- uno::Reference<xml::sax::XDocumentHandler> mxDocumentHandler;
- std::vector< Gradient > maGradientVector;
- std::vector< GradientStop > maGradientStopVector;
- std::vector< uno::Reference<xml::dom::XElement> > maElementVector;
- std::vector< uno::Reference<xml::dom::XElement> >& mrUseElementVector;
- ElementRefMapType maGradientIdMap;
- ElementRefMapType maStopIdMap;
- ElementRefMapType maElementIdMap;
- bool& mrGradientNotFound;
-};
-
-/// Annotate svg styles with unique references to state pool
-void annotateStyles( StatePool& rStatePool,
- StateMap& rStateMap,
- const State& rInitialState,
- uno::Reference<xml::dom::XElement> const & rElem,
- const uno::Reference<xml::sax::XDocumentHandler>& xDocHdl,
- std::vector< uno::Reference<xml::dom::XElement> >& rUseElementVector )
-{
- bool bGradientNotFound = false;
- AnnotatingVisitor aVisitor(rStatePool, rStateMap, rInitialState, xDocHdl, rUseElementVector, bGradientNotFound);
- visitElements(aVisitor, rElem, STYLE_ANNOTATOR);
-
- //Sometimes, xlink:href in gradients refers to another gradient which hasn't been parsed yet.
- // if that happens, we'll need to parse the styles again, so everything gets referred.
- if( bGradientNotFound )
- {
- visitElements(aVisitor, rElem, STYLE_ANNOTATOR);
- }
-}
-
-struct ShapeWritingVisitor
-{
- ShapeWritingVisitor(StateMap& rStateMap,
- const uno::Reference<xml::sax::XDocumentHandler>& xDocumentHandler) :
- mrStateMap(rStateMap),
- mxDocumentHandler(xDocumentHandler),
- mnShapeNum(0)
- {}
-
- void operator()( const uno::Reference<xml::dom::XElement>& )
- {
- }
-
- void operator()( const uno::Reference<xml::dom::XElement>& xElem,
- const uno::Reference<xml::dom::XNamedNodeMap>& xAttributes )
- {
- rtl::Reference<SvXMLAttributeList> xAttrs( new SvXMLAttributeList() );
- uno::Reference<xml::sax::XAttributeList> xUnoAttrs( xAttrs.get() );
-
- sal_Int32 nDummyIndex(0);
- OUString sStyleId(
- xElem->getAttribute("internal-style-ref").getToken(
- 0,'$',nDummyIndex));
- StateMap::iterator pOrigState=mrStateMap.find(
- sStyleId.toInt32());
-
- if( pOrigState == mrStateMap.end() )
- return; // non-exportable element, e.g. linearGradient
-
- maCurrState = pOrigState->second;
-
- const sal_Int32 nTokenId(getTokenId(xElem->getNodeName()));
- switch(nTokenId)
- {
- case XML_LINE:
- {
- // collect attributes
- const sal_Int32 nNumAttrs( xAttributes->getLength() );
- OUString sAttributeValue;
- double x1=0.0,y1=0.0,x2=0.0,y2=0.0;
- for( sal_Int32 i=0; i<nNumAttrs; ++i )
- {
- sAttributeValue = xAttributes->item(i)->getNodeValue();
- const sal_Int32 nAttribId(
- getTokenId(xAttributes->item(i)->getNodeName()));
- switch(nAttribId)
- {
- case XML_X1:
- x1= convLength(sAttributeValue,maCurrState,'h');
- break;
- case XML_X2:
- x2 = convLength(sAttributeValue,maCurrState,'h');
- break;
- case XML_Y1:
- y1 = convLength(sAttributeValue,maCurrState,'v');
- break;
- case XML_Y2:
- y2 = convLength(sAttributeValue,maCurrState,'v');
- break;
- default:
- // skip
- break;
- }
- }
-
- if ( x1 != x2 || y1 != y2 ) {
- OUString sLinePath = "M"+OUString::number(x1)+","
- +OUString::number(y1)+"L"+OUString::number(x2)+","
- +OUString::number(y2);
- basegfx::B2DPolyPolygon aPoly;
- basegfx::utils::importFromSvgD(aPoly, sLinePath, false, nullptr);
-
- writePathShape(xAttrs,
- xUnoAttrs,
- sStyleId,
- aPoly);
- }
-
- break;
- }
- case XML_POLYGON:
- case XML_POLYLINE:
- {
- OUString sPoints = xElem->hasAttribute("points") ? xElem->getAttribute("points") : "";
- basegfx::B2DPolygon aPoly;
- (void)basegfx::utils::importFromSvgPoints(aPoly, sPoints);
- if( nTokenId == XML_POLYGON || maCurrState.meFillType != NONE )
- aPoly.setClosed(true);
-
- writePathShape(xAttrs,
- xUnoAttrs,
- sStyleId,
- basegfx::B2DPolyPolygon(aPoly));
- break;
- }
- case XML_RECT:
- {
- // collect attributes
- const sal_Int32 nNumAttrs( xAttributes->getLength() );
- OUString sAttributeValue;
- bool bRxSeen=false, bRySeen=false;
- double x=0.0,y=0.0,width=0.0,height=0.0,rx=0.0,ry=0.0;
- for( sal_Int32 i=0; i<nNumAttrs; ++i )
- {
- sAttributeValue = xAttributes->item(i)->getNodeValue();
- const sal_Int32 nAttribId(
- getTokenId(xAttributes->item(i)->getNodeName()));
- switch(nAttribId)
- {
- case XML_X:
- x = convLength(sAttributeValue,maCurrState,'h');
- break;
- case XML_Y:
- y = convLength(sAttributeValue,maCurrState,'v');
- break;
- case XML_WIDTH:
- width = convLength(sAttributeValue,maCurrState,'h');
- break;
- case XML_HEIGHT:
- height = convLength(sAttributeValue,maCurrState,'v');
- break;
- case XML_RX:
- rx = convLength(sAttributeValue,maCurrState,'h');
- bRxSeen=true;
- break;
- case XML_RY:
- ry = convLength(sAttributeValue,maCurrState,'v');
- bRySeen=true;
- break;
- default:
- // skip
- break;
- }
- }
-
- if ( (width > 0) && (height > 0) ) {
- if( bRxSeen && !bRySeen )
- ry = rx;
- else if( bRySeen && !bRxSeen )
- rx = ry;
-
- basegfx::B2DPolygon aPoly;
- aPoly = basegfx::utils::createPolygonFromRect(
- basegfx::B2DRange(x,y,x+width,y+height),
- rx/(0.5*width), ry/(0.5*height) );
-
- writePathShape(xAttrs,
- xUnoAttrs,
- sStyleId,
- basegfx::B2DPolyPolygon(aPoly));
- }
- break;
- }
- case XML_PATH:
- {
- OUString sPath = xElem->hasAttribute("d") ? xElem->getAttribute("d") : "";
- basegfx::B2DPolyPolygon aPoly;
- basegfx::utils::importFromSvgD(aPoly, sPath, false, nullptr);
-
- if ((maCurrState.meStrokeType == NONE) &&
- (maCurrState.meFillType != NONE) &&
- !aPoly.isClosed())
- {
- aPoly.setClosed(true);
- }
-
- // tdf#51165: rendering of paths with open and closed polygons is not implemented
- // split mixed polypolygons into single polygons and add them one by one
- if( PolyPolygonIsMixedOpenAndClosed(aPoly) )
- {
- for( sal_uInt32 i(0); i<aPoly.count(); ++i ) {
- writePathShape(xAttrs,
- xUnoAttrs,
- sStyleId,
- basegfx::B2DPolyPolygon(aPoly.getB2DPolygon(i)));
- }
- }
- else
- {
- writePathShape(xAttrs,
- xUnoAttrs,
- sStyleId,
- aPoly);
- }
- break;
- }
- case XML_CIRCLE:
- {
- // collect attributes
- const sal_Int32 nNumAttrs( xAttributes->getLength() );
- OUString sAttributeValue;
- double cx=0.0,cy=0.0,r=0.0;
- for( sal_Int32 i=0; i<nNumAttrs; ++i )
- {
- sAttributeValue = xAttributes->item(i)->getNodeValue();
- const sal_Int32 nAttribId(
- getTokenId(xAttributes->item(i)->getNodeName()));
- switch(nAttribId)
- {
- case XML_CX:
- cx = convLength(sAttributeValue,maCurrState,'h');
- break;
- case XML_CY:
- cy = convLength(sAttributeValue,maCurrState,'v');
- break;
- case XML_R:
- r = convLength(sAttributeValue,maCurrState,'r');
- break;
- default:
- // skip
- break;
- }
- }
-
- if ( r > 0 )
- writeEllipseShape(xAttrs,
- xUnoAttrs,
- sStyleId,
- basegfx::B2DEllipse(basegfx::B2DPoint(cx, cy), basegfx::B2DTuple(r,r)));
- break;
- }
- case XML_ELLIPSE:
- {
- // collect attributes
- const sal_Int32 nNumAttrs( xAttributes->getLength() );
- OUString sAttributeValue;
- double cx=0.0,cy=0.0,rx=0.0, ry=0.0;
- for( sal_Int32 i=0; i<nNumAttrs; ++i )
- {
- sAttributeValue = xAttributes->item(i)->getNodeValue();
- const sal_Int32 nAttribId(
- getTokenId(xAttributes->item(i)->getNodeName()));
- switch(nAttribId)
- {
- case XML_CX:
- cx = convLength(sAttributeValue,maCurrState,'h');
- break;
- case XML_CY:
- cy = convLength(sAttributeValue,maCurrState,'v');
- break;
- case XML_RX:
- rx = convLength(sAttributeValue,maCurrState,'h');
- break;
- case XML_RY:
- ry = convLength(sAttributeValue,maCurrState,'v');
- break;
- default:
- // skip
- break;
- }
- }
-
- if ( rx > 0 && ry > 0 )
- writeEllipseShape(xAttrs,
- xUnoAttrs,
- sStyleId,
- basegfx::B2DEllipse(basegfx::B2DPoint(cx, cy), basegfx::B2DTuple(rx,ry)));
- break;
- }
- case XML_IMAGE:
- {
- // collect attributes
- const sal_Int32 nNumAttrs( xAttributes->getLength() );
- OUString sAttributeValue;
- double x=0.0, y=0.0, width=0.0, height=0.0;
- for( sal_Int32 i=0; i<nNumAttrs; ++i )
- {
- sAttributeValue = xAttributes->item(i)->getNodeValue();
- const sal_Int32 nAttribId(
- getTokenId(xAttributes->item(i)->getNodeName()));
- switch(nAttribId)
- {
- case XML_X:
- x = convLength(sAttributeValue,maCurrState,'h');
- break;
- case XML_Y:
- y = convLength(sAttributeValue,maCurrState,'v');
- break;
- case XML_WIDTH:
- width = convLength(sAttributeValue,maCurrState,'h');
- break;
- case XML_HEIGHT:
- height = convLength(sAttributeValue,maCurrState,'v');
- break;
- default:
- // skip
- break;
- }
- }
- // extract basic transformations out of CTM
- basegfx::B2DTuple aScale, aTranslate;
- double fRotate, fShearX;
- if (maCurrState.maCTM.decompose(aScale, aTranslate, fRotate, fShearX))
- {
- // apply transform
- x *= aScale.getX();
- width *= aScale.getX();
- y *= aScale.getY();
- height *= aScale.getY();
- x += aTranslate.getX();
- y += aTranslate.getY();
- //TODO: Rotate
- }
-
- OUString sValue = xElem->hasAttribute("href") ? xElem->getAttribute("href") : "";
- OString aValueUtf8( sValue.getStr(), sValue.getLength(), RTL_TEXTENCODING_UTF8 );
- OUString sLinkValue;
- parseXlinkHref(aValueUtf8.getStr(), sLinkValue);
-
- if (!sLinkValue.isEmpty())
- writeBinaryData(xAttrs, xUnoAttrs, basegfx::B2DRange(x,y,x+width,y+height), sLinkValue);
- break;
- }
- case XML_TSPAN:
- case XML_TEXT:
- {
- // collect text from all TEXT_NODE children into sText
- OUStringBuffer sText;
- visitChildren(
- [&sText] (xml::dom::XNode & rNode) {
- return sText.append(rNode.getNodeValue());
- },
- xElem,
- xml::dom::NodeType_TEXT_NODE);
-
- // collect attributes
- const sal_Int32 nNumAttrs( xAttributes->getLength() );
- OUString sAttributeValue;
- double x=0.0,y=0.0;
- for( sal_Int32 i=0; i<nNumAttrs; ++i )
- {
- sAttributeValue = xAttributes->item(i)->getNodeValue();
- const sal_Int32 nAttribId(
- getTokenId(xAttributes->item(i)->getNodeName()));
- switch(nAttribId)
- {
- case XML_X:
- x = convLength(sAttributeValue,maCurrState,'h');
- break;
- case XML_Y:
- y = convLength(sAttributeValue,maCurrState,'v');
- break;
- default:
- // skip
- break;
- }
- }
-
- // actually export text
- xAttrs->Clear();
-
-
- // extract basic transformations out of CTM
- basegfx::B2DTuple aScale, aTranslate;
- double fRotate, fShearX;
- if (maCurrState.maCTM.decompose(aScale, aTranslate, fRotate, fShearX))
- {
- // some heuristic attempts to have text output
- // baseline-relative
- y -= 2.0*maCurrState.mnFontSize/aScale.getX()/3.0;
- // apply transform
- x *= aScale.getX();
- y *= aScale.getY();
- x += aTranslate.getX();
- y += aTranslate.getY();
- //TODO: Rotate
- }
- else {
- // some heuristic attempts to have text output
- // baseline-relative
- y -= 2.0*maCurrState.mnFontSize/3.0;
- }
-
- xAttrs->AddAttribute( "svg:x", OUString::number(pt2mm(x))+"mm");
- xAttrs->AddAttribute( "svg:y", OUString::number(pt2mm(y))+"mm");
- xAttrs->AddAttribute( "draw:style-name", "svggraphicstyle"+sStyleId );
-
- mxDocumentHandler->startElement("draw:frame", xUnoAttrs);
-
- xAttrs->Clear();
- mxDocumentHandler->startElement("draw:text-box", xUnoAttrs);
- xAttrs->AddAttribute( "text:style-name", "svgparagraphstyle"+sStyleId);
- mxDocumentHandler->startElement("text:p", xUnoAttrs);
-
- xAttrs->Clear();
- xAttrs->AddAttribute( "text:style-name", "svgtextstyle"+sStyleId);
- mxDocumentHandler->startElement("text:span", xUnoAttrs);
-
- xAttrs->Clear();
- mxDocumentHandler->characters(sText.makeStringAndClear());
- mxDocumentHandler->endElement("text:span");
- mxDocumentHandler->endElement("text:p");
- mxDocumentHandler->endElement("draw:text-box");
- mxDocumentHandler->endElement("draw:frame");
- break;
- }
- }
- }
-
- static void push()
- {}
-
- static void pop()
- {}
-
- void writeBinaryData( rtl::Reference<SvXMLAttributeList> const & xAttrs,
- const uno::Reference<xml::sax::XAttributeList>& xUnoAttrs,
- const basegfx::B2DRange& rShapeBounds,
- const OUString& data)
- {
- xAttrs->Clear();
- xAttrs->AddAttribute( "svg:x", OUString::number(pt2mm(rShapeBounds.getMinX()))+"mm");
- xAttrs->AddAttribute( "svg:y", OUString::number(pt2mm(rShapeBounds.getMinY()))+"mm");
- xAttrs->AddAttribute( "svg:width", OUString::number(pt2mm(rShapeBounds.getWidth()))+"mm");
- xAttrs->AddAttribute( "svg:height", OUString::number(pt2mm(rShapeBounds.getHeight()))+"mm");
-
- mxDocumentHandler->startElement("draw:frame", xUnoAttrs);
-
- xAttrs->Clear();
- mxDocumentHandler->startElement("draw:image", xUnoAttrs);
-
- mxDocumentHandler->startElement("office:binary-data", xUnoAttrs);
-
- mxDocumentHandler->characters(data);
-
- mxDocumentHandler->endElement("office:binary-data");
-
- mxDocumentHandler->endElement("draw:image");
-
- mxDocumentHandler->endElement("draw:frame");
- }
-
-
- void writeEllipseShape( rtl::Reference<SvXMLAttributeList> const & xAttrs,
- const uno::Reference<xml::sax::XAttributeList>& xUnoAttrs,
- const OUString& rStyleId,
- const basegfx::B2DEllipse& rEllipse)
- {
- State aState = maCurrState;
-
- xAttrs->Clear();
-
- basegfx::B2DPolygon aPoly = basegfx::utils::createPolygonFromEllipse(rEllipse.getB2DEllipseCenter(),
- rEllipse.getB2DEllipseRadius().getX(), rEllipse.getB2DEllipseRadius().getY());
- writePathShape(xAttrs, xUnoAttrs, rStyleId, basegfx::B2DPolyPolygon(aPoly));
- }
-
- void writePathShape( rtl::Reference<SvXMLAttributeList> const & xAttrs,
- const uno::Reference<xml::sax::XAttributeList>& xUnoAttrs,
- const OUString& rStyleId,
- const basegfx::B2DPolyPolygon& rPoly )
- {
- // we might need to split up polypolygon into multiple path
- // shapes (e.g. when emulating line stroking)
- std::vector<basegfx::B2DPolyPolygon> aPolys(1,rPoly);
- State aState = maCurrState;
-
- xAttrs->Clear();
-
- // TODO(F2): separate out shear, rotate etc.
- // apply transformation to polygon, to keep draw
- // import in 100th mm
- for (basegfx::B2DPolyPolygon & aPoly : aPolys)
- {
- aPoly.transform(aState.maCTM);
- }
-
- for(basegfx::B2DPolyPolygon & aPoly : aPolys)
- {
- const basegfx::B2DRange aBounds(
- aPoly.areControlPointsUsed() ?
- basegfx::utils::getRange(
- basegfx::utils::adaptiveSubdivideByAngle(aPoly)) :
- basegfx::utils::getRange(aPoly));
- fillShapeProperties(xAttrs,
- aBounds,
- "svggraphicstyle"+rStyleId);
-
- // force path coordinates to 100th millimeter, after
- // putting polygon data at origin (ODF viewbox
- // calculations largely untested codepaths, as OOo always
- // writes "0 0 w h" viewboxes)
- basegfx::B2DHomMatrix aNormalize;
- aNormalize.translate(-aBounds.getMinX(),-aBounds.getMinY());
- aNormalize.scale(2540.0/72.0,2540.0/72.0);
- aPoly.transform(aNormalize);
-
- xAttrs->AddAttribute( "svg:d", basegfx::utils::exportToSvgD(
- aPoly,
- false, // no relative coords. causes rounding errors
- false, // no quad bezier detection. crashes older versions.
- false ));
- mxDocumentHandler->startElement("draw:path", xUnoAttrs);
- mxDocumentHandler->endElement("draw:path");
- }
- }
-
- void fillShapeProperties( rtl::Reference<SvXMLAttributeList> const & xAttrs,
- const basegfx::B2DRange& rShapeBounds,
- const OUString& rStyleName )
- {
- xAttrs->AddAttribute( "draw:z-index", OUString::number( mnShapeNum++ ));
- xAttrs->AddAttribute( "draw:style-name", rStyleName);
- xAttrs->AddAttribute( "svg:width", OUString::number(pt2mm(rShapeBounds.getWidth()))+"mm");
- xAttrs->AddAttribute( "svg:height", OUString::number(pt2mm(rShapeBounds.getHeight()))+"mm");
-
- // OOo expects the viewbox to be in 100th of mm
- xAttrs->AddAttribute( "svg:viewBox",
- "0 0 "
- + OUString::number(
- basegfx::fround(pt100thmm(rShapeBounds.getWidth())) )
- + " "
- + OUString::number(
- basegfx::fround(pt100thmm(rShapeBounds.getHeight())) ));
-
- // TODO(F1): decompose transformation in calling code, and use
- // transform attribute here
- // writeTranslate(maCurrState.maCTM, xAttrs);
- xAttrs->AddAttribute( "svg:x", OUString::number(pt2mm(rShapeBounds.getMinX()))+"mm");
- xAttrs->AddAttribute( "svg:y", OUString::number(pt2mm(rShapeBounds.getMinY()))+"mm");
- }
-
- State maCurrState;
- StateMap& mrStateMap;
- uno::Reference<xml::sax::XDocumentHandler> mxDocumentHandler;
- sal_Int32 mnShapeNum;
-};
-
-/// Write out shapes from DOM tree
-void writeShapes( StateMap& rStateMap,
- const uno::Reference<xml::dom::XElement>& rElem,
- const uno::Reference<xml::sax::XDocumentHandler>& xDocHdl,
- std::vector< uno::Reference<xml::dom::XElement> >& rUseElementVector )
-{
- ShapeWritingVisitor aVisitor(rStateMap,xDocHdl);
- visitElements(aVisitor, rElem, SHAPE_WRITER);
-
- for (auto const& useElement : rUseElementVector)
- {
- visitElements(aVisitor, useElement, SHAPE_WRITER);
- }
-}
-
-} // namespace
-
-struct OfficeStylesWritingVisitor
-{
- OfficeStylesWritingVisitor( StateMap& rStateMap,
- const uno::Reference<xml::sax::XDocumentHandler>& xDocumentHandler) :
- mrStateMap(rStateMap),
- mxDocumentHandler(xDocumentHandler)
- {}
- void operator()( const uno::Reference<xml::dom::XElement>& /*xElem*/ )
- {
- }
- void operator()( const uno::Reference<xml::dom::XElement>& xElem,
- const uno::Reference<xml::dom::XNamedNodeMap>& /*xAttributes*/ )
- {
- rtl::Reference<SvXMLAttributeList> xAttrs( new SvXMLAttributeList() );
- uno::Reference<xml::sax::XAttributeList> xUnoAttrs( xAttrs.get() );
-
- sal_Int32 nDummyIndex(0);
- OUString sStyleId(
- xElem->getAttribute("internal-style-ref").getToken(
- 0,'$',nDummyIndex));
- StateMap::iterator pOrigState=mrStateMap.find(
- sStyleId.toInt32());
-
- if( pOrigState == mrStateMap.end() )
- return; // non-exportable element, e.g. linearGradient
-
- maCurrState = pOrigState->second;
-
- if( maCurrState.meStrokeType == DASH )
- {
- sal_Int32 dots1, dots2;
- double dots1_length, dots2_length, dash_distance;
- SvgDashArray2Odf( &dots1, &dots1_length, &dots2, &dots2_length, &dash_distance );
-
- xAttrs->Clear();
- xAttrs->AddAttribute( "draw:name", "dash"+sStyleId );
- xAttrs->AddAttribute( "draw:display-name", "dash"+sStyleId );
- xAttrs->AddAttribute( "draw:style", "rect" );
- if ( dots1>0 ) {
- xAttrs->AddAttribute( "draw:dots1", OUString::number(dots1) );
- xAttrs->AddAttribute( "draw:dots1-length", OUString::number(pt2mm(convLength( OUString::number(dots1_length), maCurrState, 'h' )))+"mm" );
- }
- xAttrs->AddAttribute( "draw:distance", OUString::number(pt2mm(convLength( OUString::number(dash_distance), maCurrState, 'h' )))+"mm" );
- if ( dots2>0 ) {
- xAttrs->AddAttribute( "draw:dots2", OUString::number(dots2) );
- xAttrs->AddAttribute( "draw:dots2-length", OUString::number(pt2mm(convLength( OUString::number(dots2_length), maCurrState, 'h' )))+"mm" );
- }
-
- mxDocumentHandler->startElement( "draw:stroke-dash", xUnoAttrs);
- mxDocumentHandler->endElement( "draw:stroke-dash" );
- }
- }
-
- void SvgDashArray2Odf( sal_Int32 *dots1, double *dots1_length, sal_Int32 *dots2, double *dots2_length, double *dash_distance )
- {
- *dots1 = 0;
- *dots1_length = 0;
- *dots2 = 0;
- *dots2_length = 0;
- *dash_distance = 0;
-
- if( maCurrState.maDashArray.empty() ) {
- return;
- }
-
- double effective_dasharray_size = maCurrState.maDashArray.size();
- if( maCurrState.maDashArray.size() % 2 == 1 )
- effective_dasharray_size = maCurrState.maDashArray.size()*2;
-
- *dash_distance = maCurrState.maDashArray[1%maCurrState.maDashArray.size()];
- sal_Int32 dist_count = 1;
- for( int i=3; i<effective_dasharray_size; i+=2 ) {
- *dash_distance = ((dist_count * *dash_distance) + maCurrState.maDashArray[i%maCurrState.maDashArray.size()])/(dist_count+1);
- ++dist_count;
- }
-
- *dots1 = 1;
- *dots1_length = maCurrState.maDashArray[0];
- int i=2;
- while( ( i<effective_dasharray_size ) && ( maCurrState.maDashArray[i%maCurrState.maDashArray.size()] == *dots1_length ) ) {
- ++(*dots1);
- i += 2;
- }
- if( i<effective_dasharray_size ) {
- *dots2 = 1;
- *dots2_length = maCurrState.maDashArray[i];
- i+=2;
- while( ( i<effective_dasharray_size ) && ( maCurrState.maDashArray[i%maCurrState.maDashArray.size()] == *dots2_length ) ) {
- ++(*dots2);
- i += 2;
- }
- }
-
- SAL_INFO("filter.svg", "SvgDashArray2Odf " << *dash_distance << " " << *dots1 << " " << *dots1_length << " " << *dots2 << " " << *dots2_length );
- }
-
- static void push() {}
- static void pop() {}
-
- State maCurrState;
- StateMap& mrStateMap;
- uno::Reference<xml::sax::XDocumentHandler> mxDocumentHandler;
-};
-
-static void writeOfficeStyles( StateMap& rStateMap,
- const uno::Reference<xml::dom::XElement>& rElem,
- const uno::Reference<xml::sax::XDocumentHandler>& xDocHdl )
-{
- OfficeStylesWritingVisitor aVisitor( rStateMap, xDocHdl );
- visitElements( aVisitor, rElem, STYLE_WRITER );
-
-}
-
-#ifdef DEBUG_FILTER_SVGREADER
-struct DumpingVisitor
-{
- void operator()( const uno::Reference<xml::dom::XElement>& xElem )
- {
- SAL_WARN("filter", "name: " << xElem->getTagName());
- }
-
- void operator()( const uno::Reference<xml::dom::XElement>& xElem,
- const uno::Reference<xml::dom::XNamedNodeMap>& xAttributes )
- {
- SAL_WARN("filter", "name: " << xElem->getTagName());
- const sal_Int32 nNumAttrs( xAttributes->getLength() );
- for( sal_Int32 i=0; i<nNumAttrs; ++i )
- {
- SAL_WARN("filter", xAttributes->item(i)->getNodeName() << "=" << xAttributes->item(i)->getNodeValue());
- }
- }
-
- void push() {}
- void pop() {}
-};
-
-static void dumpTree( const uno::Reference<xml::dom::XElement> xElem )
-{
- DumpingVisitor aVisitor;
- visitElements(aVisitor, xElem, STYLE_ANNOTATOR);
-}
-#endif
-
-
-SVGReader::SVGReader(const uno::Reference<uno::XComponentContext>& xContext,
- const uno::Reference<io::XInputStream>& xInputStream,
- const uno::Reference<xml::sax::XDocumentHandler>& xDocumentHandler) :
- SVGReader(xContext, xInputStream, xDocumentHandler, dynamic_cast<SvXMLImport *>(xDocumentHandler.get()))
-{
-}
-
-SVGReader::SVGReader(const uno::Reference<uno::XComponentContext>& xContext,
- const uno::Reference<io::XInputStream>& xInputStream,
- const uno::Reference<xml::sax::XDocumentHandler>& xDocumentHandler,
- SvXMLImport *pFastHandler) :
- m_xContext( xContext ),
- m_xInputStream( xInputStream ),
- m_xDocumentHandler( pFastHandler != nullptr ? new SvXMLLegacyToFastDocHandler(pFastHandler) : xDocumentHandler )
-{
-}
-
-bool SVGReader::parseAndConvert()
-{
- uno::Reference<xml::dom::XDocumentBuilder> xDomBuilder = xml::dom::DocumentBuilder::create(m_xContext);
-
- uno::Reference<xml::dom::XDocument> xDom(
- xDomBuilder->parse(m_xInputStream),
- uno::UNO_QUERY_THROW );
-
- uno::Reference<xml::dom::XElement> xDocElem( xDom->getDocumentElement(),
- uno::UNO_QUERY_THROW );
-
- // the root state for svg document
- State aInitialState;
-
-
- // doc boilerplate
-
-
- m_xDocumentHandler->startDocument();
-
- // get the document dimensions
-
- // if the "width" and "height" attributes are missing, inkscape fakes
- // A4 portrait for. Let's do the same.
- if (!xDocElem->hasAttribute("width"))
- xDocElem->setAttribute("width", "210mm");
- if (!xDocElem->hasAttribute("height"))
- xDocElem->setAttribute("height", "297mm");
-
- double fViewPortWidth( pt2mm(convLength(xDocElem->getAttribute("width"),aInitialState,'h')) );
- double fViewPortHeight( pt2mm(convLength(xDocElem->getAttribute("height"),aInitialState,'v')) );
-
- // document prolog
- rtl::Reference<SvXMLAttributeList> xAttrs( new SvXMLAttributeList() );
- uno::Reference<xml::sax::XAttributeList> xUnoAttrs( xAttrs.get() );
-
- xAttrs->AddAttribute( "xmlns:office", OASIS_STR "office:1.0" );
- xAttrs->AddAttribute( "xmlns:style", OASIS_STR "style:1.0" );
- xAttrs->AddAttribute( "xmlns:text", OASIS_STR "text:1.0" );
- xAttrs->AddAttribute( "xmlns:svg", OASIS_STR "svg-compatible:1.0" );
- xAttrs->AddAttribute( "xmlns:table", OASIS_STR "table:1.0" );
- xAttrs->AddAttribute( "xmlns:draw", OASIS_STR "drawing:1.0" );
- xAttrs->AddAttribute( "xmlns:fo", OASIS_STR "xsl-fo-compatible:1.0" );
- xAttrs->AddAttribute( "xmlns:xlink", "http://www.w3.org/1999/xlink");
- xAttrs->AddAttribute( "xmlns:dc", "http://purl.org/dc/elements/1.1/");
- xAttrs->AddAttribute( "xmlns:number", OASIS_STR "datastyle:1.0" );
- xAttrs->AddAttribute( "xmlns:presentation", OASIS_STR "presentation:1.0" );
- xAttrs->AddAttribute( "xmlns:math", "http://www.w3.org/1998/Math/MathML");
- xAttrs->AddAttribute( "xmlns:form", OASIS_STR "form:1.0" );
- xAttrs->AddAttribute( "xmlns:script", OASIS_STR "script:1.0" );
- xAttrs->AddAttribute( "xmlns:config", OASIS_STR "config:1.0" );
- xAttrs->AddAttribute( "xmlns:dom", "http://www.w3.org/2001/xml-events");
- xAttrs->AddAttribute( "xmlns:xforms", "http://www.w3.org/2002/xforms");
- xAttrs->AddAttribute( "xmlns:xsd", "http://www.w3.org/2001/XMLSchema");
- xAttrs->AddAttribute( "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
- xAttrs->AddAttribute( "office:version", "1.0");
- xAttrs->AddAttribute( "office:mimetype", "application/vnd.oasis.opendocument.graphics");
-
- m_xDocumentHandler->startElement( "office:document", xUnoAttrs );
-
- xAttrs->Clear();
-
- m_xDocumentHandler->startElement( "office:settings", xUnoAttrs);
-
- xAttrs->AddAttribute( "config:name", "ooo:view-settings");
- m_xDocumentHandler->startElement( "config:config-item-set", xUnoAttrs);
-
- xAttrs->Clear();
-
- xAttrs->AddAttribute( "config:name", "VisibleAreaTop");
- xAttrs->AddAttribute( "config:type", "int");
- m_xDocumentHandler->startElement( "config:config-item", xUnoAttrs);
-
- m_xDocumentHandler->characters( "0" );
-
- m_xDocumentHandler->endElement( "config:config-item" );
-
- xAttrs->Clear();
-
- xAttrs->AddAttribute( "config:name", "VisibleAreaLeft" );
- xAttrs->AddAttribute( "config:type", "int" );
- m_xDocumentHandler->startElement( "config:config-item" , xUnoAttrs);
-
- m_xDocumentHandler->characters( "0" );
-
- m_xDocumentHandler->endElement( "config:config-item" );
-
- xAttrs->Clear();
-
- xAttrs->AddAttribute( "config:name" , "VisibleAreaWidth" );
- xAttrs->AddAttribute( "config:type" , "int" );
- m_xDocumentHandler->startElement( "config:config-item" , xUnoAttrs);
-
- sal_Int64 iWidth = sal_Int64(fViewPortWidth);
- m_xDocumentHandler->characters( OUString::number(iWidth) );
-
- m_xDocumentHandler->endElement( "config:config-item" );
-
- xAttrs->Clear();
-
- xAttrs->AddAttribute( "config:name", "VisibleAreaHeight" );
- xAttrs->AddAttribute( "config:type", "int" );
- m_xDocumentHandler->startElement( "config:config-item", xUnoAttrs);
-
- sal_Int64 iHeight = sal_Int64(fViewPortHeight);
- m_xDocumentHandler->characters( OUString::number(iHeight) );
-
- m_xDocumentHandler->endElement( "config:config-item" );
-
- m_xDocumentHandler->endElement( "config:config-item-set" );
-
- m_xDocumentHandler->endElement( "office:settings" );
-
- xAttrs->Clear();
-
- m_xDocumentHandler->startElement( "office:automatic-styles",
- xUnoAttrs );
-
- xAttrs->AddAttribute( "style:name", "pagelayout1");
- m_xDocumentHandler->startElement( "style:page-layout", xUnoAttrs );
- // TODO(Q3): this is super-ugly. In-place container come to mind.
- xAttrs->Clear();
-
- // make page viewport-width times viewport-height mm large - add
- // 5% border at every side
- xAttrs->AddAttribute( "fo:margin-top", "0mm");
- xAttrs->AddAttribute( "fo:margin-bottom", "0mm");
- xAttrs->AddAttribute( "fo:margin-left", "0mm");
- xAttrs->AddAttribute( "fo:margin-right", "0mm");
- xAttrs->AddAttribute( "fo:page-width", OUString::number(fViewPortWidth)+"mm");
- xAttrs->AddAttribute( "fo:page-height", OUString::number(fViewPortHeight)+"mm");
- xAttrs->AddAttribute( "style:print-orientation",
- fViewPortWidth > fViewPortHeight ? OUString("landscape") : OUString("portrait") );
- m_xDocumentHandler->startElement( "style:page-layout-properties", xUnoAttrs );
- m_xDocumentHandler->endElement( "style:page-layout-properties" );
- m_xDocumentHandler->endElement( "style:page-layout" );
-
- xAttrs->Clear();
- xAttrs->AddAttribute( "style:name", "pagestyle1" );
- xAttrs->AddAttribute( "style:family", "drawing-page" );
- m_xDocumentHandler->startElement( "style:style", xUnoAttrs );
-
- xAttrs->Clear();
- xAttrs->AddAttribute( "draw:background-size", "border");
- xAttrs->AddAttribute( "draw:fill", "none");
- m_xDocumentHandler->startElement( "style:drawing-page-properties", xUnoAttrs );
- m_xDocumentHandler->endElement( "style:drawing-page-properties" );
- m_xDocumentHandler->endElement( "style:style" );
-
- StatePool aStatePool;
- StateMap aStateMap;
- std::vector< uno::Reference<xml::dom::XElement> > aUseElementVector;
-
- annotateStyles(aStatePool,aStateMap,aInitialState,
- xDocElem,m_xDocumentHandler,aUseElementVector);
-
-#ifdef DEBUG_FILTER_SVGREADER
- dumpTree(xDocElem);
-#endif
-
- m_xDocumentHandler->endElement( "office:automatic-styles" );
-
- xAttrs->Clear();
- m_xDocumentHandler->startElement( "office:styles", xUnoAttrs);
- writeOfficeStyles( aStateMap,
- xDocElem,
- m_xDocumentHandler);
- m_xDocumentHandler->endElement( "office:styles" );
-
-
- m_xDocumentHandler->startElement( "office:master-styles", xUnoAttrs );
- xAttrs->Clear();
- xAttrs->AddAttribute( "style:name", "Default");
- xAttrs->AddAttribute( "style:page-layout-name", "pagelayout1");
- xAttrs->AddAttribute( "draw:style-name", "pagestyle1");
- m_xDocumentHandler->startElement( "style:master-page", xUnoAttrs );
- m_xDocumentHandler->endElement( "style:master-page" );
-
- m_xDocumentHandler->endElement( "office:master-styles" );
-
-
- xAttrs->Clear();
- m_xDocumentHandler->startElement( "office:body", xUnoAttrs );
- m_xDocumentHandler->startElement( "office:drawing", xUnoAttrs );
-
- xAttrs->Clear();
- xAttrs->AddAttribute( "draw:master-page-name", "Default");
- xAttrs->AddAttribute( "draw:style-name", "pagestyle1");
- m_xDocumentHandler->startElement("draw:page", xUnoAttrs);
-
- // write out all shapes
- writeShapes(aStateMap,
- xDocElem,
- m_xDocumentHandler,
- aUseElementVector);
-
- m_xDocumentHandler->endElement( "draw:page" );
- m_xDocumentHandler->endElement( "office:drawing" );
- m_xDocumentHandler->endElement( "office:body" );
- m_xDocumentHandler->endElement( "office:document" );
- m_xDocumentHandler->endDocument();
-
- return true;
-}
-
-} // namespace svgi
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/filter/source/svg/test/parsertest.cxx b/filter/source/svg/test/parsertest.cxx
deleted file mode 100644
index 8cb367ea9a6d..000000000000
--- a/filter/source/svg/test/parsertest.cxx
+++ /dev/null
@@ -1,172 +0,0 @@
-/* -*- 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/types.h>
-#include <cppunit/TestAssert.h>
-#include <cppunit/TestFixture.h>
-#include <cppunit/extensions/HelperMacros.h>
-
-#include "gfxtypes.hxx"
-#include "parserfragments.hxx"
-
-using namespace svgi;
-
-class TestParser : public CppUnit::TestFixture
-{
-public:
- void testParseColor()
- {
- ARGBColor aTmp;
-
- const char* sIn="#102030 ";
- ARGBColor aOut(16, 32, 48);
- CPPUNIT_ASSERT_MESSAGE( "Consuming color #112233",
- parseColor( sIn, aTmp ) );
- CPPUNIT_ASSERT_MESSAGE( "Parsing color #112233",
- aOut==aTmp );
-
- sIn=" #321";
- aOut=ARGBColor(51, 34, 17);
- CPPUNIT_ASSERT_MESSAGE( "Consuming color #321",
- parseColor( sIn, aTmp ) );
- CPPUNIT_ASSERT_MESSAGE( "Parsing color #321",
- aOut==aTmp );
-
- sIn="rgb(100,200,\t 50)";
- aOut=ARGBColor(100, 200, 50);
- CPPUNIT_ASSERT_MESSAGE( "Consuming color rgb(100,200,50)",
- parseColor( sIn, aTmp ) );
- CPPUNIT_ASSERT_MESSAGE( "Parsing color rgb(100,200,50)",
- aOut==aTmp );
-
- sIn="rgb(0.1, \t0.2,0.9)";
- aOut=ARGBColor(0.1, 0.2, 0.9);
- CPPUNIT_ASSERT_MESSAGE( "Consuming color rgb(0.1,0.2,0.9)",
- parseColor( sIn, aTmp ) );
- CPPUNIT_ASSERT_MESSAGE( "Parsing color rgb(0.1,0.2,0.9)",
- aOut==aTmp );
-
- sIn=" burlywood ";
- aOut=ARGBColor(222,184,135);
- CPPUNIT_ASSERT_MESSAGE( "Consuming color burlywood",
- parseColor( sIn, aTmp ) );
- CPPUNIT_ASSERT_MESSAGE( "Parsing color burlywood",
- aOut==aTmp );
- }
-
- void testParseOpacity()
- {
- ARGBColor aTmp;
-
- const char* sIn=" 0.123 ";
- ARGBColor aOut(0.123, 0.0, 0.0, 0.0);
- CPPUNIT_ASSERT_MESSAGE( "Consuming opacity 0.123",
- parseOpacity( sIn, aTmp ) );
- CPPUNIT_ASSERT_MESSAGE( "Parsing opacity 0.123",
- aOut==aTmp );
- }
-
- void testParseTransform()
- {
- basegfx::B2DHomMatrix aOut;
-
- const char* sIn=" none ";
- basegfx::B2DHomMatrix aTmp;
- CPPUNIT_ASSERT_MESSAGE( "Consuming transformation none",
- parseTransform( sIn, aTmp ) );
- CPPUNIT_ASSERT_MESSAGE( "Parsing transformation none",
- aOut==aTmp );
-
- sIn=" scale( 10 ) ";
- aOut.identity();
- aOut.scale(10.0,10.0);
- CPPUNIT_ASSERT_MESSAGE( "Consuming transformation scale(10)",
- parseTransform( sIn, aTmp ) );
- CPPUNIT_ASSERT_MESSAGE( "Parsing transformation scale(10)",
- aOut==aTmp );
-
- sIn=" scale( 10 20.12 ) ";
- aOut.identity();
- aOut.scale(10.0,20.12);
- CPPUNIT_ASSERT_MESSAGE( "Consuming transformation scale(10 20.12)",
- parseTransform( sIn, aTmp ) );
- CPPUNIT_ASSERT_MESSAGE( "Parsing transformation scale(10 20.12)",
- aOut==aTmp );
-
- sIn="matrix( 1,2 3,4,5 6 )";
- aOut.identity();
- aOut.set(0,0,1.0); aOut.set(1,0,2.0); aOut.set(0,1,3.0); aOut.set(1,1,4.0); aOut.set(0,2,5.0); aOut.set(1,2,6.0);
- CPPUNIT_ASSERT_MESSAGE( "Consuming transformation matrix(1,2,3,4,5,6)",
- parseTransform( sIn, aTmp ) );
- CPPUNIT_ASSERT_MESSAGE( "Parsing transformation matrix(1,2,3,4,5,6)",
- aOut==aTmp );
-
- sIn="matrix( 1 0 0 1 -10 -10 ) translate(10) scale(10), rotate(90)";
- aOut.identity();
- aOut.set(0,0,0.0); aOut.set(1,0,10.0); aOut.set(0,1,-10.0); aOut.set(1,1,0.0); aOut.set(0,2,0.0); aOut.set(1,2,0.0);
- CPPUNIT_ASSERT_MESSAGE( "Consuming transformation matrix(1,2,3,4,5,6)",
- parseTransform( sIn, aTmp ) );
- CPPUNIT_ASSERT_MESSAGE( "Parsing transformation matrix(1,2,3,4,5,6)",
- aOut==aTmp );
-
- sIn="skewX(45)";
- aOut.identity();
- aOut.set(0,0,1.0); aOut.set(1,0,1.0); aOut.set(0,1,0.0); aOut.set(1,1,1.0); aOut.set(0,2,0.0); aOut.set(1,2,0.0);
- CPPUNIT_ASSERT_MESSAGE( "Consuming transformation skewX(45)",
- parseTransform( sIn, aTmp ) );
- CPPUNIT_ASSERT_MESSAGE( "Parsing transformation skewX(45)",
- aOut==aTmp );
-
- sIn="skewY(45)";
- aOut.identity();
- aOut.set(0,0,1.0); aOut.set(1,0,0.0); aOut.set(0,1,1.0); aOut.set(1,1,1.0); aOut.set(0,2,0.0); aOut.set(1,2,0.0);
- CPPUNIT_ASSERT_MESSAGE( "Consuming transformation skewY(45)",
- parseTransform( sIn, aTmp ) );
- CPPUNIT_ASSERT_MESSAGE( "Parsing transformation skewY(45)",
- aOut==aTmp );
- }
-
- void testParseViewBox()
- {
- basegfx::B2DRange aTmp;
-
- const char* sIn=" 10 20, 30.5,5 ";
- basegfx::B2DRange aOut(10,20,40.5,25);
- CPPUNIT_ASSERT_MESSAGE( "Consuming 10,20,30.5,5",
- parseViewBox( sIn, aTmp ) );
- CPPUNIT_ASSERT_MESSAGE( "Parsing 10,20,30.5,5",
- aOut==aTmp );
- }
-
- void testParseDashArray()
- {
- std::vector<double> aTmp;
-
- const char* sIn=" 10,20, -10.00 ";
- std::vector<double> aOut; aOut.push_back(10.0); aOut.push_back(20.0); aOut.push_back(-10.0);
- CPPUNIT_ASSERT_MESSAGE( "Consuming 10,20,-10.00",
- parseDashArray( sIn, aTmp ) );
- CPPUNIT_ASSERT_MESSAGE( "Parsing 10,20,-10.00",
- aOut==aTmp );
- }
-
- CPPUNIT_TEST_SUITE(TestParser);
- CPPUNIT_TEST(testParseColor);
- CPPUNIT_TEST(testParseOpacity);
- CPPUNIT_TEST(testParseTransform);
- CPPUNIT_TEST(testParseViewBox);
- CPPUNIT_TEST(testParseDashArray);
- // TODO: CPPUNIT_TEST(testParseXlinkHref);
- CPPUNIT_TEST_SUITE_END();
-};
-
-
-CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(TestParser, "test svg parser fragments");
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/filter/source/svg/test/svg2odf.cxx b/filter/source/svg/test/svg2odf.cxx
deleted file mode 100644
index 524c2e79424e..000000000000
--- a/filter/source/svg/test/svg2odf.cxx
+++ /dev/null
@@ -1,134 +0,0 @@
-/* -*- 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 <svgreader.hxx>
-#include "odfserializer.hxx"
-
-#include <sal/main.h>
-#include <osl/file.hxx>
-#include <osl/process.h>
-#include <rtl/bootstrap.hxx>
-
-#include <cppuhelper/implbase.hxx>
-#include <cppuhelper/bootstrap.hxx>
-#include <comphelper/processfactory.hxx>
-#include <comphelper/oslfile2streamwrap.hxx>
-
-using namespace ::com::sun::star;
-
-namespace
-{
- class OutputWrap : public cppu::WeakImplHelper<
- io::XOutputStream>
- {
- osl::File maFile;
-
- public:
-
- explicit OutputWrap( const OUString& rURL ) : maFile(rURL)
- {
- maFile.open( osl_File_OpenFlag_Create|osl_File_OpenFlag_Write );
- }
-
- virtual void SAL_CALL writeBytes( const css::uno::Sequence< ::sal_Int8 >& aData ) override
-
- {
- sal_uInt64 nBytesWritten(0);
- maFile.write(aData.getConstArray(),aData.getLength(),nBytesWritten);
- }
-
- virtual void SAL_CALL flush() override
- {
- }
-
- virtual void SAL_CALL closeOutput() override
- {
- maFile.close();
- }
- };
-}
-
-SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv)
-{
- if( argc != 4 )
- {
- SAL_WARN("filter.svg", "Invocation: svg2odf <base_url> <dst_url> <ini_file>. Exiting" );
- return 1;
- }
-
- int nRet = 1;
-
- try
- {
- OUString aBaseURL, aTmpURL, aSrcURL, aDstURL, aIniUrl;
-
- osl_getProcessWorkingDir(&aBaseURL.pData);
- osl_getFileURLFromSystemPath( OUString::createFromAscii(argv[1]).pData,
- &aTmpURL.pData );
- osl_getAbsoluteFileURL(aBaseURL.pData,aTmpURL.pData,&aSrcURL.pData);
-
- osl_getFileURLFromSystemPath( OUString::createFromAscii(argv[2]).pData,
- &aTmpURL.pData );
- osl_getAbsoluteFileURL(aBaseURL.pData,aTmpURL.pData,&aDstURL.pData);
-
- osl_getFileURLFromSystemPath( OUString::createFromAscii(argv[3]).pData,
- &aTmpURL.pData );
- osl_getAbsoluteFileURL(aBaseURL.pData,aTmpURL.pData,&aIniUrl.pData);
-
- // bootstrap UNO
- uno::Reference< lang::XMultiServiceFactory > xFactory;
- uno::Reference< uno::XComponentContext > xCtx;
- xCtx = ::cppu::defaultBootstrap_InitialComponentContext(aIniUrl);
- xFactory.set(xCtx->getServiceManager(), uno::UNO_QUERY);
- if (!xFactory.is())
- {
- SAL_WARN("filter.svg", "Could not bootstrap UNO, installation must be in disorder. Exiting." );
- return 1;
- }
-
- ::comphelper::setProcessServiceFactory( xFactory );
-
- osl::File aInputFile(aSrcURL);
- if( osl::FileBase::E_None!=aInputFile.open(osl_File_OpenFlag_Read) )
- {
- SAL_WARN("filter.svg", "Cannot open input file" );
- return 1;
- }
-
- svgi::SVGReader aReader(xCtx,
- uno::Reference<io::XInputStream>(
- new comphelper::OSLInputStreamWrapper(aInputFile)),
- svgi::createSerializer(new OutputWrap(aDstURL)));
- nRet = aReader.parseAndConvert() ? 0 : 1;
-
- }
- catch (const uno::Exception& e)
- {
- SAL_WARN("filter.svg", "Fatal exception: " << e);
- return 1;
- }
- catch (const std::exception &e)
- {
- SAL_WARN("filter.svg", "Fatal exception: " << e.what());
- return 1;
- }
- return nRet;
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/filter/source/svg/tokenmap.cxx b/filter/source/svg/tokenmap.cxx
deleted file mode 100644
index 3362803887cd..000000000000
--- a/filter/source/svg/tokenmap.cxx
+++ /dev/null
@@ -1,74 +0,0 @@
-/* -*- 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 "tokenmap.hxx"
-#include <string.h>
-
-namespace svgi
-{
-
-#if defined __clang__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
-#if __has_warning("-Wdeprecated-register")
-#pragma GCC diagnostic ignored "-Wdeprecated-register"
-#endif
-#endif
-#include <tokens.cxx>
-#if defined __clang__
-#pragma GCC diagnostic pop
-#endif
-
-sal_Int32 getTokenId( const char* sIdent, sal_Int32 nLen )
-{
- const struct xmltoken* t = Perfect_Hash::in_word_set( sIdent, nLen );
- if( t )
- return t->nToken;
- else
- return XML_TOKEN_INVALID;
-}
-
-sal_Int32 getTokenId( const OUString& sIdent )
-{
- OString aUTF8( sIdent.getStr(),
- sIdent.getLength(),
- RTL_TEXTENCODING_UTF8 );
- return getTokenId( aUTF8.getStr(), aUTF8.getLength() );
-}
-
-const char* getTokenName( sal_Int32 nTokenId )
-{
- if( nTokenId >= XML_TOKEN_COUNT )
- return nullptr;
-
- const xmltoken* pCurr=wordlist;
- const xmltoken* pEnd=wordlist+SAL_N_ELEMENTS(wordlist);
- while( pCurr != pEnd )
- {
- if(pCurr->nToken == nTokenId)
- return pCurr->name;
- ++pCurr;
- }
-
- return nullptr;
-}
-
-} // namespace svgi
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/filter/source/svg/tokenmap.hxx b/filter/source/svg/tokenmap.hxx
deleted file mode 100644
index b227d07a01ac..000000000000
--- a/filter/source/svg/tokenmap.hxx
+++ /dev/null
@@ -1,27 +0,0 @@
-/* -*- 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/.
- */
-#ifndef INCLUDED_FILTER_SOURCE_SVG_TOKENMAP_HXX
-#define INCLUDED_FILTER_SOURCE_SVG_TOKENMAP_HXX
-
-#include <tokens.hxx>
-
-#include <rtl/string.hxx>
-#include <rtl/ustring.hxx>
-
-namespace svgi
-{
- sal_Int32 getTokenId( const char* sIdent, sal_Int32 nLen );
- sal_Int32 getTokenId( const OUString& sIdent );
- const char* getTokenName( sal_Int32 nTokenId );
-
-} // namespace svgi
-
-#endif
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/filter/source/svg/units.cxx b/filter/source/svg/units.cxx
deleted file mode 100644
index d3537b3af72e..000000000000
--- a/filter/source/svg/units.cxx
+++ /dev/null
@@ -1,143 +0,0 @@
-/* -*- 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 "units.hxx"
-#include <basegfx/range/b2drange.hxx>
-#include <gfxtypes.hxx>
-#include <rtl/ustring.hxx>
-#include <boost/spirit/include/classic.hpp>
-
-namespace svgi
-{
-
-double convLength( const OUString& value, SvgUnit unit, const State& rState, char dir )
-{
- // convert svg unit to internal coordinates ("pixel"). Since the
- // OOo drawing layer is still largely integer-based, the initial
- // viewport transformation includes a certain scale factor
- double fRet(value.toDouble());
- switch ( unit )
- {
- case SVG_LENGTH_UNIT_CM: fRet *= F_SVG_PIXEL_PER_INCH/2.54; break;
- case SVG_LENGTH_UNIT_IN: fRet *= F_SVG_PIXEL_PER_INCH; break;
- case SVG_LENGTH_UNIT_MM: fRet *= F_SVG_PIXEL_PER_INCH/25.4; break;
- case SVG_LENGTH_UNIT_PC: fRet *= F_SVG_PIXEL_PER_INCH/6.0; break;
- case SVG_LENGTH_UNIT_PT: fRet *= F_SVG_PIXEL_PER_INCH/72.0; break;
- case SVG_LENGTH_UNIT_EM: fRet *= rState.mnFontSize; break;
- case SVG_LENGTH_UNIT_EX: fRet *= rState.mnFontSize / 2.0; break;
- case SVG_LENGTH_UNIT_USER:
- case SVG_LENGTH_UNIT_PX:
- // no unit defaults to PX in svg, assume display to have 90DPI
- break;
- case SVG_LENGTH_FONT_SIZE:
- {
- //In CSS2, the suggested scaling factor between adjacent indexes is 1.2
- if ( value == "xx-small" )
- fRet = rState.mnFontSize / 1.728;
- else if ( value == "x-small" )
- fRet = rState.mnFontSize / 1.44;
- else if ( value == "small" )
- fRet = rState.mnFontSize / 1.2;
- else if ( value == "smaller" )
- fRet = rState.mnParentFontSize / 1.2;
- else if ( value == "initial" || value == "medium" )
- fRet = rState.mnFontSize;
- else if ( value == "larger" )
- fRet = rState.mnParentFontSize * 1.2;
- else if ( value == "large" )
- fRet = rState.mnFontSize * 1.2;
- else if ( value == "x-large" )
- fRet = rState.mnFontSize * 1.44;
- else if ( value == "xx-large" )
- fRet = rState.mnFontSize * 1.728;
-
- break;
- }
- case SVG_LENGTH_UNIT_PERCENTAGE:
- {
- double fBoxLen;
- if (rState.maViewBox.isEmpty())
- {
- basegfx::B2DRange aDefaultBox(0, 0,
- convLength("210", SVG_LENGTH_UNIT_MM, rState, 'h'),
- convLength("297", SVG_LENGTH_UNIT_MM, rState, 'v'));
- fBoxLen = (dir=='h' ? aDefaultBox.getWidth() :
- (dir=='v' ? aDefaultBox.getHeight() :
- aDefaultBox.getRange().getLength()));
- }
- else
- {
- fBoxLen = (dir=='h' ? rState.maViewBox.getWidth() :
- (dir=='v' ? rState.maViewBox.getHeight() :
- rState.maViewBox.getRange().getLength()));
- }
-
- fRet *= fBoxLen/100.0;
- }
- break;
- default: SAL_WARN("filter.svg", "Unknown length type" ); break;
- }
-
- return fRet;
-}
-
-double convLength( const OUString& sValue, const State& rState, char dir )
-{
- //FIXME: convert deprecated spirit::classic to use spirit::qi
- using namespace ::boost::spirit::classic;
-
- OString aUTF8 = OUStringToOString( sValue,
- RTL_TEXTENCODING_UTF8 );
-
- std::string sVal;
- SvgUnit eUnit=SVG_LENGTH_UNIT_PX;
- const bool bRes = parse(aUTF8.getStr(),
- // Begin grammar
- (
- //parse font-size keywords (ie: xx-large, medium )
- ( +alpha_p >> !(str_p("-") >> +alpha_p) )[assign_a(sVal)]
- >> str_p("")[assign_a(eUnit,SVG_LENGTH_FONT_SIZE)] |
- //take the first part and ignore the units
- ( +(anychar_p -
- (str_p("cm") |
- str_p("em") |
- str_p("ex") |
- str_p("in") |
- str_p("mm") |
- str_p("pc") |
- str_p("pt") |
- str_p("px") |
- str_p("%")))
- )[assign_a(sVal)]
- >> ( str_p("cm") [assign_a(eUnit,SVG_LENGTH_UNIT_CM)]
- | str_p("em") [assign_a(eUnit,SVG_LENGTH_UNIT_EM)]
- | str_p("ex") [assign_a(eUnit,SVG_LENGTH_UNIT_EX)]
- | str_p("in") [assign_a(eUnit,SVG_LENGTH_UNIT_IN)]
- | str_p("mm") [assign_a(eUnit,SVG_LENGTH_UNIT_MM)]
- | str_p("pc") [assign_a(eUnit,SVG_LENGTH_UNIT_PC)]
- | str_p("pt") [assign_a(eUnit,SVG_LENGTH_UNIT_PT)]
- | str_p("px") [assign_a(eUnit,SVG_LENGTH_UNIT_PX)]
- | str_p("%") [assign_a(eUnit,SVG_LENGTH_UNIT_PERCENTAGE)]
- | str_p("") [assign_a(eUnit,SVG_LENGTH_UNIT_USER)]
- | end_p)
- ),
- // End grammar
- space_p).full;
-
- if( !bRes )
- return 0.0;
-
- OUString oVal = OUString::createFromAscii(sVal.c_str()).replaceAll(",",".");
-
- return convLength(oVal,eUnit,rState,dir);
-}
-
-} // namespace svgi
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/filter/source/svg/units.hxx b/filter/source/svg/units.hxx
deleted file mode 100644
index 06b7217c1b6c..000000000000
--- a/filter/source/svg/units.hxx
+++ /dev/null
@@ -1,59 +0,0 @@
-/* -*- 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/.
- */
-#ifndef INCLUDED_FILTER_SOURCE_SVG_UNITS_HXX
-#define INCLUDED_FILTER_SOURCE_SVG_UNITS_HXX
-
-#include <sal/config.h>
-#include <rtl/ustring.hxx>
-
-namespace svgi
-{
- // recommended value for this device dependent unit, see CSS2 section 4.3.2 Lengths
- // Same as in svgio
- #define F_SVG_PIXEL_PER_INCH 90.0
-
- struct State;
- enum SvgUnit
- {
- SVG_LENGTH_UNIT_CM,
- SVG_LENGTH_UNIT_EM,
- SVG_LENGTH_UNIT_EX,
- SVG_LENGTH_UNIT_IN,
- SVG_LENGTH_UNIT_MM,
- SVG_LENGTH_UNIT_PC,
- SVG_LENGTH_UNIT_PT,
- SVG_LENGTH_UNIT_PX,
- SVG_LENGTH_UNIT_PERCENTAGE,
- SVG_LENGTH_UNIT_USER,
- SVG_LENGTH_FONT_SIZE
- };
-
- /** return svg_length_t in 100th's of mm
- @param fVal value to convert
- @param unit unit the value is in
- @param rState current state (needed for viewport dimensions etc.)
- @param dir direction - either 'h' or 'v' for horizonal or vertical, resp.
- */
- double convLength( const OUString& sVal, SvgUnit unit, const State& rState, char dir );
-
- /** return svg_length_t in 100th's of mm
- @param sValue value to convert
- @param rState current state (needed for viewport dimensions etc.)
- @param dir direction - either 'h' or 'v' for horizonal or vertical, resp.
- */
- double convLength( const OUString& sValue, const State& rState, char dir );
-
- inline double pt2mm(double fVal) { return fVal*25.4/72.0; }
- inline double pt100thmm(double fVal) { return fVal*2540.0/72.0; }
-
-} // namespace svgi
-
-#endif
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/svx/svdmodel.hxx b/include/svx/svdmodel.hxx
index 0b7b5ab5cc40..cc5ad89b74dc 100644
--- a/include/svx/svdmodel.hxx
+++ b/include/svx/svdmodel.hxx
@@ -214,8 +214,16 @@ public:
sal_uInt16 getHandoutPageCount() const { return mnHandoutPageCount; }
void setHandoutPageCount( sal_uInt16 nHandoutPageCount ) { mnHandoutPageCount = nHandoutPageCount; }
-protected:
+ // Adapt to given Size and Borders scaling all contained data, maybe
+ // including PresObj's in higher derivations
+ virtual void adaptSizeAndBorderForAllPages(
+ const Size& rNewSize,
+ long nLeft = 0,
+ long nRight = 0,
+ long nUpper = 0,
+ long nLower = 0);
+protected:
virtual css::uno::Reference< css::uno::XInterface > createUnoModel();
private:
diff --git a/sd/inc/drawdoc.hxx b/sd/inc/drawdoc.hxx
index ac824cf90653..a302fa6eb726 100644
--- a/sd/inc/drawdoc.hxx
+++ b/sd/inc/drawdoc.hxx
@@ -77,6 +77,7 @@ struct SpellCallbackInfo;
class SdDrawDocument;
class SdCustomShow;
class SdCustomShowList;
+class SdUndoGroup;
namespace sd
{
@@ -202,8 +203,34 @@ protected:
public:
- SAL_DLLPRIVATE SdDrawDocument(DocumentType eType, SfxObjectShell* pDocSh);
- SAL_DLLPRIVATE virtual ~SdDrawDocument() override;
+ SAL_DLLPRIVATE SdDrawDocument(DocumentType eType, SfxObjectShell* pDocSh);
+ SAL_DLLPRIVATE virtual ~SdDrawDocument() override;
+
+ // Adapt to given Size and Borders scaling all contained data, maybe
+ // including PresObj's in higher derivations
+ virtual void adaptSizeAndBorderForAllPages(
+ const Size& rNewSize,
+ long nLeft = 0,
+ long nRight = 0,
+ long nUpper = 0,
+ long nLower = 0) override;
+
+ // Adapt PageSize for all Pages of PageKind ePageKind. Also
+ // set Borders to left/right/upper/lower, ScaleAll, Orientation,
+ // PaperBin and BackgroundFullSize. Create Undo-Actions when
+ // a SdUndoGroup is given (then used from the View probably)
+ void AdaptPageSizeForAllPages(
+ const Size& rNewSize,
+ PageKind ePageKind,
+ SdUndoGroup* pUndoGroup = nullptr,
+ long nLeft = 0,
+ long nRight = 0,
+ long nUpper = 0,
+ long nLower = 0,
+ bool bScaleAll = false,
+ Orientation eOrientation = Orientation::Landscape,
+ sal_uInt16 nPaperBin = 0,
+ bool bBackgroundFullSize = false);
SAL_DLLPRIVATE SdDrawDocument* AllocSdDrawDocument() const;
SAL_DLLPRIVATE virtual SdrModel* AllocModel() const override; //forwards to AllocSdDrawDocument
diff --git a/sd/source/core/drawdoc.cxx b/sd/source/core/drawdoc.cxx
index 36d6a82e251e..0c152e067594 100644
--- a/sd/source/core/drawdoc.cxx
+++ b/sd/source/core/drawdoc.cxx
@@ -96,7 +96,8 @@
#include <optsitem.hxx>
#include <FrameView.hxx>
#include <undo/undomanager.hxx>
-
+#include <sdundogr.hxx>
+#include <undopage.hxx>
#include <tools/tenccvt.hxx>
#include <vcl/settings.hxx>
@@ -392,6 +393,179 @@ SdDrawDocument::~SdDrawDocument()
mpCharClass.reset();
}
+void SdDrawDocument::adaptSizeAndBorderForAllPages(
+ const Size& rNewSize,
+ long nLeft,
+ long nRight,
+ long nUpper,
+ long nLower)
+{
+ const sal_uInt16 nMasterPageCnt(GetMasterSdPageCount(PageKind::Standard));
+ const sal_uInt16 nPageCnt(GetSdPageCount(PageKind::Standard));
+
+ if(0 == nMasterPageCnt && 0 == nPageCnt)
+ {
+ return;
+ }
+
+ SdPage* pPage(0 != nPageCnt ? GetSdPage(0, PageKind::Standard) : GetMasterSdPage(0, PageKind::Standard));
+
+ // call fully implemented local version, including getting
+ // some more information from one of the Pages (1st one)
+ AdaptPageSizeForAllPages(
+ rNewSize,
+ PageKind::Standard,
+ nullptr,
+ nLeft,
+ nRight,
+ nUpper,
+ nLower,
+ true,
+ pPage->GetOrientation(),
+ pPage->GetPaperBin(),
+ pPage->IsBackgroundFullSize());
+
+ // adjust handout page to new format of the standard page
+ if(0 != nPageCnt)
+ {
+ GetSdPage(0, PageKind::Handout)->CreateTitleAndLayout(true);
+ }
+}
+
+void SdDrawDocument::AdaptPageSizeForAllPages(
+ const Size& rNewSize,
+ PageKind ePageKind,
+ SdUndoGroup* pUndoGroup,
+ long nLeft,
+ long nRight,
+ long nUpper,
+ long nLower,
+ bool bScaleAll,
+ Orientation eOrientation,
+ sal_uInt16 nPaperBin,
+ bool bBackgroundFullSize)
+{
+ sal_uInt16 i;
+ const sal_uInt16 nMasterPageCnt(GetMasterSdPageCount(ePageKind));
+ const sal_uInt16 nPageCnt(GetSdPageCount(ePageKind));
+
+ if(0 == nMasterPageCnt && 0 == nPageCnt)
+ {
+ return;
+ }
+
+ for (i = 0; i < nMasterPageCnt; i++)
+ {
+ // first, handle all master pages
+ SdPage* pPage(GetMasterSdPage(i, ePageKind));
+
+ if(pUndoGroup)
+ {
+ SdUndoAction* pUndo(
+ new SdPageFormatUndoAction(
+ this,
+ pPage,
+ pPage->GetSize(),
+ pPage->GetLeftBorder(), pPage->GetRightBorder(),
+ pPage->GetUpperBorder(), pPage->GetLowerBorder(),
+ pPage->GetOrientation(),
+ pPage->GetPaperBin(),
+ pPage->IsBackgroundFullSize(),
+ rNewSize,
+ nLeft, nRight,
+ nUpper, nLower,
+ bScaleAll,
+ eOrientation,
+ nPaperBin,
+ bBackgroundFullSize));
+ pUndoGroup->AddAction(pUndo);
+ }
+
+ if (rNewSize.Width() > 0 || nLeft >= 0 || nRight >= 0 || nUpper >= 0 || nLower >= 0)
+ {
+ ::tools::Rectangle aNewBorderRect(nLeft, nUpper, nRight, nLower);
+ pPage->ScaleObjects(rNewSize, aNewBorderRect, bScaleAll);
+
+ if (rNewSize.Width() > 0)
+ {
+ pPage->SetSize(rNewSize);
+ }
+ }
+
+ if( nLeft >= 0 || nRight >= 0 || nUpper >= 0 || nLower >= 0 )
+ {
+ pPage->SetBorder(nLeft, nUpper, nRight, nLower);
+ }
+
+ pPage->SetOrientation(eOrientation);
+ pPage->SetPaperBin( nPaperBin );
+ pPage->SetBackgroundFullSize( bBackgroundFullSize );
+
+ if ( ePageKind == PageKind::Standard )
+ {
+ GetMasterSdPage(i, PageKind::Notes)->CreateTitleAndLayout();
+ }
+
+ pPage->CreateTitleAndLayout();
+ }
+
+ for (i = 0; i < nPageCnt; i++)
+ {
+ // then, handle all pages
+ SdPage* pPage(GetSdPage(i, ePageKind));
+
+ if(pUndoGroup)
+ {
+ SdUndoAction* pUndo(
+ new SdPageFormatUndoAction(
+ this,
+ pPage,
+ pPage->GetSize(),
+ pPage->GetLeftBorder(), pPage->GetRightBorder(),
+ pPage->GetUpperBorder(), pPage->GetLowerBorder(),
+ pPage->GetOrientation(),
+ pPage->GetPaperBin(),
+ pPage->IsBackgroundFullSize(),
+ rNewSize,
+ nLeft, nRight,
+ nUpper, nLower,
+ bScaleAll,
+ eOrientation,
+ nPaperBin,
+ bBackgroundFullSize));
+ pUndoGroup->AddAction(pUndo);
+ }
+
+ if (rNewSize.Width() > 0 || nLeft >= 0 || nRight >= 0 || nUpper >= 0 || nLower >= 0)
+ {
+ ::tools::Rectangle aNewBorderRect(nLeft, nUpper, nRight, nLower);
+ pPage->ScaleObjects(rNewSize, aNewBorderRect, bScaleAll);
+
+ if (rNewSize.Width() > 0)
+ {
+ pPage->SetSize(rNewSize);
+ }
+ }
+
+ if( nLeft >= 0 || nRight >= 0 || nUpper >= 0 || nLower >= 0 )
+ {
+ pPage->SetBorder(nLeft, nUpper, nRight, nLower);
+ }
+
+ pPage->SetOrientation(eOrientation);
+ pPage->SetPaperBin( nPaperBin );
+ pPage->SetBackgroundFullSize( bBackgroundFullSize );
+
+ if ( ePageKind == PageKind::Standard )
+ {
+ SdPage* pNotesPage = GetSdPage(i, PageKind::Notes);
+ pNotesPage->SetAutoLayout( pNotesPage->GetAutoLayout() );
+ }
+
+ pPage->SetAutoLayout( pPage->GetAutoLayout() );
+ }
+}
+
SdrModel* SdDrawDocument::AllocModel() const
{
return AllocSdDrawDocument();
diff --git a/sd/source/ui/view/viewshe2.cxx b/sd/source/ui/view/viewshe2.cxx
index f20469071b72..6c1ad846131c 100644
--- a/sd/source/ui/view/viewshe2.cxx
+++ b/sd/source/ui/view/viewshe2.cxx
@@ -470,139 +470,65 @@ void ViewShell::SetPageSizeAndBorder(PageKind ePageKind, const Size& rNewSize,
Orientation eOrientation, sal_uInt16 nPaperBin,
bool bBackgroundFullSize)
{
- SdPage* pPage = nullptr;
- SdUndoGroup* pUndoGroup = nullptr;
- pUndoGroup = new SdUndoGroup(GetDoc());
- OUString aString(SdResId(STR_UNDO_CHANGE_PAGEFORMAT));
- pUndoGroup->SetComment(aString);
- SfxViewShell* pViewShell = GetViewShell();
- OSL_ASSERT (pViewShell!=nullptr);
-
- sal_uInt16 i, nPageCnt = GetDoc()->GetMasterSdPageCount(ePageKind);
-
- Broadcast (ViewShellHint(ViewShellHint::HINT_PAGE_RESIZE_START));
+ const sal_uInt16 nMasterPageCnt(GetDoc()->GetMasterSdPageCount(ePageKind));
+ const sal_uInt16 nPageCnt(GetDoc()->GetSdPageCount(ePageKind));
- for (i = 0; i < nPageCnt; i++)
+ if(0 == nPageCnt && 0 == nMasterPageCnt)
{
- // first, handle all master pages
- pPage = GetDoc()->GetMasterSdPage(i, ePageKind);
-
- SdUndoAction* pUndo = new SdPageFormatUndoAction(GetDoc(), pPage,
- pPage->GetSize(),
- pPage->GetLeftBorder(), pPage->GetRightBorder(),
- pPage->GetUpperBorder(), pPage->GetLowerBorder(),
- pPage->GetOrientation(),
- pPage->GetPaperBin(),
- pPage->IsBackgroundFullSize(),
- rNewSize,
- nLeft, nRight,
- nUpper, nLower,
- bScaleAll,
- eOrientation,
- nPaperBin,
- bBackgroundFullSize);
- pUndoGroup->AddAction(pUndo);
-
- if (rNewSize.Width() > 0 ||
- nLeft >= 0 || nRight >= 0 || nUpper >= 0 || nLower >= 0)
- {
- ::tools::Rectangle aNewBorderRect(nLeft, nUpper, nRight, nLower);
- pPage->ScaleObjects(rNewSize, aNewBorderRect, bScaleAll);
-
- if (rNewSize.Width() > 0)
- pPage->SetSize(rNewSize);
- }
-
- if( nLeft >= 0 || nRight >= 0 || nUpper >= 0 || nLower >= 0 )
- {
- pPage->SetBorder(nLeft, nUpper, nRight, nLower);
- }
-
- pPage->SetOrientation(eOrientation);
- pPage->SetPaperBin( nPaperBin );
- pPage->SetBackgroundFullSize( bBackgroundFullSize );
-
- if ( ePageKind == PageKind::Standard )
- GetDoc()->GetMasterSdPage(i, PageKind::Notes)->CreateTitleAndLayout();
-
- pPage->CreateTitleAndLayout();
+ return;
}
- nPageCnt = GetDoc()->GetSdPageCount(ePageKind);
-
- for (i = 0; i < nPageCnt; i++)
- {
- // then, handle all pages
- pPage = GetDoc()->GetSdPage(i, ePageKind);
-
- SdUndoAction* pUndo = new SdPageFormatUndoAction(GetDoc(), pPage,
- pPage->GetSize(),
- pPage->GetLeftBorder(), pPage->GetRightBorder(),
- pPage->GetUpperBorder(), pPage->GetLowerBorder(),
- pPage->GetOrientation(),
- pPage->GetPaperBin(),
- pPage->IsBackgroundFullSize(),
- rNewSize,
- nLeft, nRight,
- nUpper, nLower,
- bScaleAll,
- eOrientation,
- nPaperBin,
- bBackgroundFullSize);
- pUndoGroup->AddAction(pUndo);
-
- if (rNewSize.Width() > 0 ||
- nLeft >= 0 || nRight >= 0 || nUpper >= 0 || nLower >= 0)
- {
- ::tools::Rectangle aNewBorderRect(nLeft, nUpper, nRight, nLower);
- pPage->ScaleObjects(rNewSize, aNewBorderRect, bScaleAll);
-
- if (rNewSize.Width() > 0)
- pPage->SetSize(rNewSize);
- }
-
- if( nLeft >= 0 || nRight >= 0 || nUpper >= 0 || nLower >= 0 )
- {
- pPage->SetBorder(nLeft, nUpper, nRight, nLower);
- }
-
- pPage->SetOrientation(eOrientation);
- pPage->SetPaperBin( nPaperBin );
- pPage->SetBackgroundFullSize( bBackgroundFullSize );
-
- if ( ePageKind == PageKind::Standard )
- {
- SdPage* pNotesPage = GetDoc()->GetSdPage(i, PageKind::Notes);
- pNotesPage->SetAutoLayout( pNotesPage->GetAutoLayout() );
- }
+ SdUndoGroup* pUndoGroup(new SdUndoGroup(GetDoc()));
+ pUndoGroup->SetComment(SdResId(STR_UNDO_CHANGE_PAGEFORMAT));
+ Broadcast (ViewShellHint(ViewShellHint::HINT_PAGE_RESIZE_START));
- pPage->SetAutoLayout( pPage->GetAutoLayout() );
- }
+ // use Model-based method at SdDrawDocument
+ GetDoc()->AdaptPageSizeForAllPages(
+ rNewSize,
+ ePageKind,
+ pUndoGroup,
+ nLeft,
+ nRight,
+ nUpper,
+ nLower,
+ bScaleAll,
+ eOrientation,
+ nPaperBin,
+ bBackgroundFullSize);
// adjust handout page to new format of the standard page
- if( (ePageKind == PageKind::Standard) || (ePageKind == PageKind::Handout) )
+ if(0 != nPageCnt && ((ePageKind == PageKind::Standard) || (ePageKind == PageKind::Handout)))
+ {
GetDoc()->GetSdPage(0, PageKind::Handout)->CreateTitleAndLayout(true);
+ }
// handed over undo group to undo manager
- pViewShell->GetViewFrame()->GetObjectShell()
- ->GetUndoManager()->AddUndoAction(pUndoGroup);
+ SfxViewShell* pViewShell(GetViewShell());
- long nWidth = pPage->GetSize().Width();
- long nHeight = pPage->GetSize().Height();
+ if(nullptr != pViewShell)
+ {
+ pViewShell->GetViewFrame()->GetObjectShell()->GetUndoManager()->AddUndoAction(pUndoGroup);
+ }
- Point aPageOrg(nWidth, nHeight / 2);
- Size aViewSize(nWidth * 3, nHeight * 2);
+ // calculate View-Sizes
+ SdPage* pPage(0 != nPageCnt
+ ? GetDoc()->GetSdPage(0, ePageKind)
+ : GetDoc()->GetMasterSdPage(0, ePageKind));
+ const long nWidth(pPage->GetSize().Width());
+ const long nHeight(pPage->GetSize().Height());
+ const Point aPageOrg(nWidth, nHeight / 2);
+ const Size aViewSize(nWidth * 3, nHeight * 2);
+ Point aVisAreaPos;
+ ::sd::View* pView(GetView());
+ const Point aNewOrigin(pPage->GetLeftBorder(), pPage->GetUpperBorder());
InitWindows(aPageOrg, aViewSize, Point(-1, -1), true);
- Point aVisAreaPos;
-
if ( GetDocSh()->GetCreateMode() == SfxObjectCreateMode::EMBEDDED )
{
aVisAreaPos = GetDocSh()->GetVisArea(ASPECT_CONTENT).TopLeft();
}
- ::sd::View* pView = GetView();
if (pView)
{
pView->SetWorkArea(::tools::Rectangle(Point() - aVisAreaPos - aPageOrg, aViewSize));
@@ -610,20 +536,19 @@ void ViewShell::SetPageSizeAndBorder(PageKind ePageKind, const Size& rNewSize,
UpdateScrollBars();
- Point aNewOrigin(pPage->GetLeftBorder(), pPage->GetUpperBorder());
-
if (pView)
{
pView->GetSdrPageView()->SetPageOrigin(aNewOrigin);
}
- pViewShell->GetViewFrame()->GetBindings().Invalidate(SID_RULER_NULL_OFFSET);
-
- // zoom onto (new) page size
- pViewShell->GetViewFrame()->GetDispatcher()->Execute(SID_SIZE_PAGE,
- SfxCallMode::ASYNCHRON | SfxCallMode::RECORD);
+ if(nullptr != pViewShell)
+ {
+ pViewShell->GetViewFrame()->GetBindings().Invalidate(SID_RULER_NULL_OFFSET);
+ // zoom onto (new) page size
+ pViewShell->GetViewFrame()->GetDispatcher()->Execute(SID_SIZE_PAGE, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD);
+ }
- Broadcast (ViewShellHint(ViewShellHint::HINT_PAGE_RESIZE_END));
+ Broadcast(ViewShellHint(ViewShellHint::HINT_PAGE_RESIZE_END));
}
/**
diff --git a/svx/source/svdraw/svdmodel.cxx b/svx/source/svdraw/svdmodel.cxx
index 5be0dffeac55..1b17da722a86 100644
--- a/svx/source/svdraw/svdmodel.cxx
+++ b/svx/source/svdraw/svdmodel.cxx
@@ -1718,6 +1718,18 @@ void SdrModel::setUnoModel( const css::uno::Reference< css::uno::XInterface >& x
mxUnoModel = xModel;
}
+void SdrModel::adaptSizeAndBorderForAllPages(
+ const Size& /*rNewSize*/,
+ long /*nLeft*/,
+ long /*nRight*/,
+ long /*nUpper*/,
+ long /*nLower*/)
+{
+ // base implementation does currently nothing. It may be added if needed,
+ // but we are on SdrModel level here, thus probably have not enough information
+ // to do this for higher-level (derived) Models (e.g. Draw/Impress)
+}
+
uno::Reference< uno::XInterface > SdrModel::createUnoModel()
{
OSL_FAIL( "SdrModel::createUnoModel() - base implementation should not be called!" );