163bba73cSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
363bba73cSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
463bba73cSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
563bba73cSAndrew Rist  * distributed with this work for additional information
663bba73cSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
763bba73cSAndrew Rist  * to you under the Apache License, Version 2.0 (the
863bba73cSAndrew Rist  * "License"); you may not use this file except in compliance
963bba73cSAndrew Rist  * with the License.  You may obtain a copy of the License at
1063bba73cSAndrew Rist  *
1163bba73cSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
1263bba73cSAndrew Rist  *
1363bba73cSAndrew Rist  * Unless required by applicable law or agreed to in writing,
1463bba73cSAndrew Rist  * software distributed under the License is distributed on an
1563bba73cSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1663bba73cSAndrew Rist  * KIND, either express or implied.  See the License for the
1763bba73cSAndrew Rist  * specific language governing permissions and limitations
1863bba73cSAndrew Rist  * under the License.
1963bba73cSAndrew Rist  *
2063bba73cSAndrew Rist  *************************************************************/
2163bba73cSAndrew Rist 
22cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
23cdf0e10cSrcweir #include "precompiled_xmloff.hxx"
24*1f882ec4SArmin Le Grand 
25cdf0e10cSrcweir #include "xmloff/MarkerStyle.hxx"
26cdf0e10cSrcweir #include "xexptran.hxx"
27cdf0e10cSrcweir #include <xmloff/attrlist.hxx>
28cdf0e10cSrcweir #include <xmloff/nmspmap.hxx>
29cdf0e10cSrcweir #include <xmloff/xmluconv.hxx>
30cdf0e10cSrcweir #include "xmloff/xmlnmspe.hxx"
31cdf0e10cSrcweir #include <xmloff/xmltoken.hxx>
32cdf0e10cSrcweir #include <xmloff/xmlexp.hxx>
33cdf0e10cSrcweir #include <xmloff/xmlimp.hxx>
34cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
35cdf0e10cSrcweir #include <rtl/ustring.hxx>
36cdf0e10cSrcweir #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
37*1f882ec4SArmin Le Grand #include <basegfx/polygon/b2dpolypolygon.hxx>
38*1f882ec4SArmin Le Grand #include <basegfx/polygon/b2dpolypolygontools.hxx>
39*1f882ec4SArmin Le Grand #include <basegfx/matrix/b2dhommatrixtools.hxx>
40cdf0e10cSrcweir 
41cdf0e10cSrcweir using namespace ::com::sun::star;
42cdf0e10cSrcweir using ::rtl::OUString;
43cdf0e10cSrcweir using ::rtl::OUStringBuffer;
44cdf0e10cSrcweir 
45cdf0e10cSrcweir using namespace ::xmloff::token;
46cdf0e10cSrcweir 
47cdf0e10cSrcweir 
48cdf0e10cSrcweir //-------------------------------------------------------------
49cdf0e10cSrcweir // Import
50cdf0e10cSrcweir //-------------------------------------------------------------
51cdf0e10cSrcweir 
XMLMarkerStyleImport(SvXMLImport & rImp)52cdf0e10cSrcweir XMLMarkerStyleImport::XMLMarkerStyleImport( SvXMLImport& rImp )
53cdf0e10cSrcweir     : rImport( rImp )
54cdf0e10cSrcweir {
55cdf0e10cSrcweir }
56cdf0e10cSrcweir 
~XMLMarkerStyleImport()57cdf0e10cSrcweir XMLMarkerStyleImport::~XMLMarkerStyleImport()
58cdf0e10cSrcweir {
59cdf0e10cSrcweir }
60cdf0e10cSrcweir 
importXML(const uno::Reference<xml::sax::XAttributeList> & xAttrList,uno::Any & rValue,OUString & rStrName)61cdf0e10cSrcweir sal_Bool XMLMarkerStyleImport::importXML(
62cdf0e10cSrcweir     const uno::Reference< xml::sax::XAttributeList >& xAttrList,
63cdf0e10cSrcweir     uno::Any& rValue,
64cdf0e10cSrcweir     OUString& rStrName )
65cdf0e10cSrcweir {
66cdf0e10cSrcweir 	sal_Bool bHasViewBox    = sal_False;
67cdf0e10cSrcweir 	sal_Bool bHasPathData   = sal_False;
68cdf0e10cSrcweir 	OUString aDisplayName;
69cdf0e10cSrcweir 
70cdf0e10cSrcweir 	SdXMLImExViewBox* pViewBox = NULL;
71cdf0e10cSrcweir 
72cdf0e10cSrcweir     SvXMLNamespaceMap& rNamespaceMap = rImport.GetNamespaceMap();
73cdf0e10cSrcweir     SvXMLUnitConverter& rUnitConverter = rImport.GetMM100UnitConverter();
74cdf0e10cSrcweir 
75cdf0e10cSrcweir 	OUString strPathData;
76cdf0e10cSrcweir 
77cdf0e10cSrcweir 	sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
78cdf0e10cSrcweir 	for( sal_Int16 i = 0; i < nAttrCount; i++ )
79cdf0e10cSrcweir 	{
80cdf0e10cSrcweir 		OUString aStrFullAttrName = xAttrList->getNameByIndex( i );
81cdf0e10cSrcweir 		OUString aStrAttrName;
82cdf0e10cSrcweir 		rNamespaceMap.GetKeyByAttrName( aStrFullAttrName, &aStrAttrName );
83cdf0e10cSrcweir 		OUString aStrValue = xAttrList->getValueByIndex( i );
84cdf0e10cSrcweir 
85cdf0e10cSrcweir 		if( IsXMLToken( aStrAttrName, XML_NAME ) )
86cdf0e10cSrcweir 		{
87cdf0e10cSrcweir 			rStrName = aStrValue;
88cdf0e10cSrcweir 		}
89cdf0e10cSrcweir 		else if( IsXMLToken( aStrAttrName, XML_DISPLAY_NAME ) )
90cdf0e10cSrcweir 		{
91cdf0e10cSrcweir 			aDisplayName = aStrValue;
92cdf0e10cSrcweir 		}
93cdf0e10cSrcweir 		else if( IsXMLToken( aStrAttrName, XML_VIEWBOX ) )
94cdf0e10cSrcweir 		{
95cdf0e10cSrcweir 			pViewBox = new SdXMLImExViewBox( aStrValue, rUnitConverter );
96cdf0e10cSrcweir 			bHasViewBox = sal_True;
97cdf0e10cSrcweir 
98cdf0e10cSrcweir 		}
99cdf0e10cSrcweir 		else if( IsXMLToken( aStrAttrName, XML_D ) )
100cdf0e10cSrcweir 		{
101cdf0e10cSrcweir 			strPathData = aStrValue;
102cdf0e10cSrcweir 			bHasPathData = sal_True;
103cdf0e10cSrcweir 		}
104cdf0e10cSrcweir 	}
105cdf0e10cSrcweir 
106*1f882ec4SArmin Le Grand     if( bHasViewBox && bHasPathData )
107*1f882ec4SArmin Le Grand     {
108*1f882ec4SArmin Le Grand         basegfx::B2DPolyPolygon aPolyPolygon;
109*1f882ec4SArmin Le Grand 
110*1f882ec4SArmin Le Grand         if(basegfx::tools::importFromSvgD(aPolyPolygon, strPathData, true, 0))
111*1f882ec4SArmin Le Grand         {
112*1f882ec4SArmin Le Grand             if(aPolyPolygon.count())
113*1f882ec4SArmin Le Grand             {
114*1f882ec4SArmin Le Grand                 // ViewBox probably not used, but stay with former processing inside of
115*1f882ec4SArmin Le Grand                 // SdXMLImExSvgDElement
116*1f882ec4SArmin Le Grand                 const basegfx::B2DRange aSourceRange(
117*1f882ec4SArmin Le Grand                     pViewBox->GetX(), pViewBox->GetY(),
118*1f882ec4SArmin Le Grand                     pViewBox->GetX() + pViewBox->GetWidth(), pViewBox->GetY() + pViewBox->GetHeight());
119*1f882ec4SArmin Le Grand                 const basegfx::B2DRange aTargetRange(
120*1f882ec4SArmin Le Grand                     0.0, 0.0,
121*1f882ec4SArmin Le Grand                     pViewBox->GetWidth(), pViewBox->GetHeight());
122*1f882ec4SArmin Le Grand 
123*1f882ec4SArmin Le Grand                 if(!aSourceRange.equal(aTargetRange))
124*1f882ec4SArmin Le Grand                 {
125*1f882ec4SArmin Le Grand                     aPolyPolygon.transform(
126*1f882ec4SArmin Le Grand                         basegfx::tools::createSourceRangeTargetRangeTransform(
127*1f882ec4SArmin Le Grand                             aSourceRange,
128*1f882ec4SArmin Le Grand                             aTargetRange));
129*1f882ec4SArmin Le Grand                 }
130*1f882ec4SArmin Le Grand 
131*1f882ec4SArmin Le Grand                 // always use PolyPolygonBezierCoords here
132*1f882ec4SArmin Le Grand                 drawing::PolyPolygonBezierCoords aSourcePolyPolygon;
133*1f882ec4SArmin Le Grand 
134*1f882ec4SArmin Le Grand                 basegfx::tools::B2DPolyPolygonToUnoPolyPolygonBezierCoords(
135*1f882ec4SArmin Le Grand                     aPolyPolygon,
136*1f882ec4SArmin Le Grand                     aSourcePolyPolygon);
137*1f882ec4SArmin Le Grand                 rValue <<= aSourcePolyPolygon;
138*1f882ec4SArmin Le Grand             }
139*1f882ec4SArmin Le Grand         }
140*1f882ec4SArmin Le Grand 
141*1f882ec4SArmin Le Grand         if( aDisplayName.getLength() )
142*1f882ec4SArmin Le Grand         {
143*1f882ec4SArmin Le Grand             rImport.AddStyleDisplayName( XML_STYLE_FAMILY_SD_MARKER_ID, rStrName,
144*1f882ec4SArmin Le Grand                                         aDisplayName );
145*1f882ec4SArmin Le Grand             rStrName = aDisplayName;
146*1f882ec4SArmin Le Grand         }
147*1f882ec4SArmin Le Grand     }
148cdf0e10cSrcweir 
149cdf0e10cSrcweir 	if( pViewBox )
150cdf0e10cSrcweir 		delete pViewBox;
151cdf0e10cSrcweir 
152cdf0e10cSrcweir 	return bHasViewBox && bHasPathData;
153cdf0e10cSrcweir }
154cdf0e10cSrcweir 
155cdf0e10cSrcweir 
156cdf0e10cSrcweir //-------------------------------------------------------------
157cdf0e10cSrcweir // Export
158cdf0e10cSrcweir //-------------------------------------------------------------
159cdf0e10cSrcweir 
160cdf0e10cSrcweir #ifndef SVX_LIGHT
161cdf0e10cSrcweir 
XMLMarkerStyleExport(SvXMLExport & rExp)162cdf0e10cSrcweir XMLMarkerStyleExport::XMLMarkerStyleExport( SvXMLExport& rExp )
163cdf0e10cSrcweir     : rExport( rExp )
164cdf0e10cSrcweir {
165cdf0e10cSrcweir }
166cdf0e10cSrcweir 
~XMLMarkerStyleExport()167cdf0e10cSrcweir XMLMarkerStyleExport::~XMLMarkerStyleExport()
168cdf0e10cSrcweir {
169cdf0e10cSrcweir }
170cdf0e10cSrcweir 
exportXML(const OUString & rStrName,const uno::Any & rValue)171cdf0e10cSrcweir sal_Bool XMLMarkerStyleExport::exportXML(
172cdf0e10cSrcweir     const OUString& rStrName,
173cdf0e10cSrcweir     const uno::Any& rValue )
174cdf0e10cSrcweir {
175*1f882ec4SArmin Le Grand     sal_Bool bRet(sal_False);
176*1f882ec4SArmin Le Grand 
177*1f882ec4SArmin Le Grand     if(rStrName.getLength())
178*1f882ec4SArmin Le Grand     {
179*1f882ec4SArmin Le Grand         drawing::PolyPolygonBezierCoords aBezier;
180*1f882ec4SArmin Le Grand 
181*1f882ec4SArmin Le Grand         if(rValue >>= aBezier)
182*1f882ec4SArmin Le Grand         {
183*1f882ec4SArmin Le Grand             /////////////////
184*1f882ec4SArmin Le Grand             // Name
185*1f882ec4SArmin Le Grand             sal_Bool bEncoded(sal_False);
186*1f882ec4SArmin Le Grand             OUString aStrName( rStrName );
187*1f882ec4SArmin Le Grand 
188*1f882ec4SArmin Le Grand             rExport.AddAttribute(XML_NAMESPACE_DRAW, XML_NAME, rExport.EncodeStyleName( aStrName, &bEncoded ) );
189*1f882ec4SArmin Le Grand 
190*1f882ec4SArmin Le Grand             if( bEncoded )
191*1f882ec4SArmin Le Grand             {
192*1f882ec4SArmin Le Grand                 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_DISPLAY_NAME, aStrName );
193*1f882ec4SArmin Le Grand             }
194*1f882ec4SArmin Le Grand 
195*1f882ec4SArmin Le Grand             const basegfx::B2DPolyPolygon aPolyPolygon(
196*1f882ec4SArmin Le Grand                 basegfx::tools::UnoPolyPolygonBezierCoordsToB2DPolyPolygon(
197*1f882ec4SArmin Le Grand                     aBezier));
198*1f882ec4SArmin Le Grand             const basegfx::B2DRange aPolyPolygonRange(aPolyPolygon.getB2DRange());
199*1f882ec4SArmin Le Grand 
200*1f882ec4SArmin Le Grand             /////////////////
201*1f882ec4SArmin Le Grand             // Viewbox (viewBox="0 0 1500 1000")
202*1f882ec4SArmin Le Grand 
203*1f882ec4SArmin Le Grand             SdXMLImExViewBox aViewBox(
204*1f882ec4SArmin Le Grand                 aPolyPolygonRange.getMinX(),
205*1f882ec4SArmin Le Grand                 aPolyPolygonRange.getMinY(),
206*1f882ec4SArmin Le Grand                 aPolyPolygonRange.getWidth(),
207*1f882ec4SArmin Le Grand                 aPolyPolygonRange.getHeight());
208*1f882ec4SArmin Le Grand             rExport.AddAttribute( XML_NAMESPACE_SVG, XML_VIEWBOX, aViewBox.GetExportString() );
209*1f882ec4SArmin Le Grand 
210*1f882ec4SArmin Le Grand             /////////////////
211*1f882ec4SArmin Le Grand             // Pathdata
212*1f882ec4SArmin Le Grand             const ::rtl::OUString aPolygonString(
213*1f882ec4SArmin Le Grand                 basegfx::tools::exportToSvgD(
214*1f882ec4SArmin Le Grand                     aPolyPolygon,
215*1f882ec4SArmin Le Grand                     true,           // bUseRelativeCoordinates
216*1f882ec4SArmin Le Grand                     false,          // bDetectQuadraticBeziers: not used in old, but maybe activated now
217*1f882ec4SArmin Le Grand                     true));         // bHandleRelativeNextPointCompatible
218*1f882ec4SArmin Le Grand 
219*1f882ec4SArmin Le Grand             // write point array
220*1f882ec4SArmin Le Grand             rExport.AddAttribute(XML_NAMESPACE_SVG, XML_D, aPolygonString);
221*1f882ec4SArmin Le Grand 
222*1f882ec4SArmin Le Grand             /////////////////
223*1f882ec4SArmin Le Grand             // Do Write
224*1f882ec4SArmin Le Grand             SvXMLElementExport rElem( rExport, XML_NAMESPACE_DRAW, XML_MARKER, sal_True, sal_False );
225*1f882ec4SArmin Le Grand         }
226*1f882ec4SArmin Le Grand     }
227*1f882ec4SArmin Le Grand 
228*1f882ec4SArmin Le Grand     return bRet;
229cdf0e10cSrcweir }
230cdf0e10cSrcweir 
231cdf0e10cSrcweir #endif // #ifndef SVX_LIGHT
232