1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_xmloff.hxx"
30*cdf0e10cSrcweir #include "xmloff/MarkerStyle.hxx"
31*cdf0e10cSrcweir #include "xexptran.hxx"
32*cdf0e10cSrcweir #include <xmloff/attrlist.hxx>
33*cdf0e10cSrcweir #include <xmloff/nmspmap.hxx>
34*cdf0e10cSrcweir #include <xmloff/xmluconv.hxx>
35*cdf0e10cSrcweir #include "xmloff/xmlnmspe.hxx"
36*cdf0e10cSrcweir #include <xmloff/xmltoken.hxx>
37*cdf0e10cSrcweir #include <xmloff/xmlexp.hxx>
38*cdf0e10cSrcweir #include <xmloff/xmlimp.hxx>
39*cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
40*cdf0e10cSrcweir #include <rtl/ustring.hxx>
41*cdf0e10cSrcweir #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
42*cdf0e10cSrcweir 
43*cdf0e10cSrcweir using namespace ::com::sun::star;
44*cdf0e10cSrcweir using ::rtl::OUString;
45*cdf0e10cSrcweir using ::rtl::OUStringBuffer;
46*cdf0e10cSrcweir 
47*cdf0e10cSrcweir using namespace ::xmloff::token;
48*cdf0e10cSrcweir 
49*cdf0e10cSrcweir 
50*cdf0e10cSrcweir //-------------------------------------------------------------
51*cdf0e10cSrcweir // Import
52*cdf0e10cSrcweir //-------------------------------------------------------------
53*cdf0e10cSrcweir 
54*cdf0e10cSrcweir XMLMarkerStyleImport::XMLMarkerStyleImport( SvXMLImport& rImp )
55*cdf0e10cSrcweir     : rImport( rImp )
56*cdf0e10cSrcweir {
57*cdf0e10cSrcweir }
58*cdf0e10cSrcweir 
59*cdf0e10cSrcweir XMLMarkerStyleImport::~XMLMarkerStyleImport()
60*cdf0e10cSrcweir {
61*cdf0e10cSrcweir }
62*cdf0e10cSrcweir 
63*cdf0e10cSrcweir sal_Bool XMLMarkerStyleImport::importXML(
64*cdf0e10cSrcweir     const uno::Reference< xml::sax::XAttributeList >& xAttrList,
65*cdf0e10cSrcweir     uno::Any& rValue,
66*cdf0e10cSrcweir     OUString& rStrName )
67*cdf0e10cSrcweir {
68*cdf0e10cSrcweir 	sal_Bool bHasViewBox    = sal_False;
69*cdf0e10cSrcweir 	sal_Bool bHasPathData   = sal_False;
70*cdf0e10cSrcweir 	OUString aDisplayName;
71*cdf0e10cSrcweir 
72*cdf0e10cSrcweir 	SdXMLImExViewBox* pViewBox = NULL;
73*cdf0e10cSrcweir 
74*cdf0e10cSrcweir     SvXMLNamespaceMap& rNamespaceMap = rImport.GetNamespaceMap();
75*cdf0e10cSrcweir     SvXMLUnitConverter& rUnitConverter = rImport.GetMM100UnitConverter();
76*cdf0e10cSrcweir 
77*cdf0e10cSrcweir 	OUString strPathData;
78*cdf0e10cSrcweir 
79*cdf0e10cSrcweir 	sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
80*cdf0e10cSrcweir 	for( sal_Int16 i = 0; i < nAttrCount; i++ )
81*cdf0e10cSrcweir 	{
82*cdf0e10cSrcweir 		OUString aStrFullAttrName = xAttrList->getNameByIndex( i );
83*cdf0e10cSrcweir 		OUString aStrAttrName;
84*cdf0e10cSrcweir 		rNamespaceMap.GetKeyByAttrName( aStrFullAttrName, &aStrAttrName );
85*cdf0e10cSrcweir 		OUString aStrValue = xAttrList->getValueByIndex( i );
86*cdf0e10cSrcweir 
87*cdf0e10cSrcweir 		if( IsXMLToken( aStrAttrName, XML_NAME ) )
88*cdf0e10cSrcweir 		{
89*cdf0e10cSrcweir 			rStrName = aStrValue;
90*cdf0e10cSrcweir 		}
91*cdf0e10cSrcweir 		else if( IsXMLToken( aStrAttrName, XML_DISPLAY_NAME ) )
92*cdf0e10cSrcweir 		{
93*cdf0e10cSrcweir 			aDisplayName = aStrValue;
94*cdf0e10cSrcweir 		}
95*cdf0e10cSrcweir 		else if( IsXMLToken( aStrAttrName, XML_VIEWBOX ) )
96*cdf0e10cSrcweir 		{
97*cdf0e10cSrcweir 			pViewBox = new SdXMLImExViewBox( aStrValue, rUnitConverter );
98*cdf0e10cSrcweir 			bHasViewBox = sal_True;
99*cdf0e10cSrcweir 
100*cdf0e10cSrcweir 		}
101*cdf0e10cSrcweir 		else if( IsXMLToken( aStrAttrName, XML_D ) )
102*cdf0e10cSrcweir 		{
103*cdf0e10cSrcweir 			strPathData = aStrValue;
104*cdf0e10cSrcweir 			bHasPathData = sal_True;
105*cdf0e10cSrcweir 		}
106*cdf0e10cSrcweir 	}
107*cdf0e10cSrcweir 
108*cdf0e10cSrcweir 	if( bHasViewBox && bHasPathData )
109*cdf0e10cSrcweir 	{
110*cdf0e10cSrcweir 		SdXMLImExSvgDElement aPoints(strPathData, *pViewBox, awt::Point( 0, 0 ),
111*cdf0e10cSrcweir 			awt::Size( pViewBox->GetWidth(), pViewBox->GetHeight() ),
112*cdf0e10cSrcweir 			rUnitConverter );
113*cdf0e10cSrcweir 
114*cdf0e10cSrcweir 		if(aPoints.IsCurve())
115*cdf0e10cSrcweir 		{
116*cdf0e10cSrcweir 			drawing::PolyPolygonBezierCoords aSourcePolyPolygon(
117*cdf0e10cSrcweir 				aPoints.GetPointSequenceSequence(),
118*cdf0e10cSrcweir 				aPoints.GetFlagSequenceSequence());
119*cdf0e10cSrcweir 			rValue <<= aSourcePolyPolygon;
120*cdf0e10cSrcweir 		}
121*cdf0e10cSrcweir 		else
122*cdf0e10cSrcweir 		{
123*cdf0e10cSrcweir 			drawing::PolyPolygonBezierCoords aSourcePolyPolygon;
124*cdf0e10cSrcweir 			aSourcePolyPolygon.Coordinates = aPoints.GetPointSequenceSequence();
125*cdf0e10cSrcweir 			aSourcePolyPolygon.Flags.realloc(aSourcePolyPolygon.Coordinates.getLength());
126*cdf0e10cSrcweir 
127*cdf0e10cSrcweir 			// Zeiger auf innere sequences holen
128*cdf0e10cSrcweir 			const drawing::PointSequence* pInnerSequence = aSourcePolyPolygon.Coordinates.getConstArray();
129*cdf0e10cSrcweir 			drawing::FlagSequence* pInnerSequenceFlags = aSourcePolyPolygon.Flags.getArray();
130*cdf0e10cSrcweir 
131*cdf0e10cSrcweir 			for(sal_Int32 a(0); a < aSourcePolyPolygon.Coordinates.getLength(); a++)
132*cdf0e10cSrcweir 			{
133*cdf0e10cSrcweir 				pInnerSequenceFlags->realloc(pInnerSequence->getLength());
134*cdf0e10cSrcweir 				drawing::PolygonFlags* pPolyFlags = pInnerSequenceFlags->getArray();
135*cdf0e10cSrcweir 
136*cdf0e10cSrcweir 				for(sal_Int32 b(0); b < pInnerSequence->getLength(); b++)
137*cdf0e10cSrcweir 					*pPolyFlags++ = drawing::PolygonFlags_NORMAL;
138*cdf0e10cSrcweir 
139*cdf0e10cSrcweir 				// next run
140*cdf0e10cSrcweir 				pInnerSequence++;
141*cdf0e10cSrcweir 				pInnerSequenceFlags++;
142*cdf0e10cSrcweir 			}
143*cdf0e10cSrcweir 
144*cdf0e10cSrcweir 			rValue <<= aSourcePolyPolygon;
145*cdf0e10cSrcweir 		}
146*cdf0e10cSrcweir 
147*cdf0e10cSrcweir 		if( aDisplayName.getLength() )
148*cdf0e10cSrcweir 		{
149*cdf0e10cSrcweir 			rImport.AddStyleDisplayName( XML_STYLE_FAMILY_SD_MARKER_ID, rStrName,
150*cdf0e10cSrcweir 										aDisplayName );
151*cdf0e10cSrcweir 			rStrName = aDisplayName;
152*cdf0e10cSrcweir 		}
153*cdf0e10cSrcweir 
154*cdf0e10cSrcweir 	}
155*cdf0e10cSrcweir 
156*cdf0e10cSrcweir 	if( pViewBox )
157*cdf0e10cSrcweir 		delete pViewBox;
158*cdf0e10cSrcweir 
159*cdf0e10cSrcweir 	return bHasViewBox && bHasPathData;
160*cdf0e10cSrcweir }
161*cdf0e10cSrcweir 
162*cdf0e10cSrcweir 
163*cdf0e10cSrcweir //-------------------------------------------------------------
164*cdf0e10cSrcweir // Export
165*cdf0e10cSrcweir //-------------------------------------------------------------
166*cdf0e10cSrcweir 
167*cdf0e10cSrcweir #ifndef SVX_LIGHT
168*cdf0e10cSrcweir 
169*cdf0e10cSrcweir XMLMarkerStyleExport::XMLMarkerStyleExport( SvXMLExport& rExp )
170*cdf0e10cSrcweir     : rExport( rExp )
171*cdf0e10cSrcweir {
172*cdf0e10cSrcweir }
173*cdf0e10cSrcweir 
174*cdf0e10cSrcweir XMLMarkerStyleExport::~XMLMarkerStyleExport()
175*cdf0e10cSrcweir {
176*cdf0e10cSrcweir }
177*cdf0e10cSrcweir 
178*cdf0e10cSrcweir sal_Bool XMLMarkerStyleExport::exportXML(
179*cdf0e10cSrcweir     const OUString& rStrName,
180*cdf0e10cSrcweir     const uno::Any& rValue )
181*cdf0e10cSrcweir {
182*cdf0e10cSrcweir 	sal_Bool bRet(sal_False);
183*cdf0e10cSrcweir 
184*cdf0e10cSrcweir 	if(rStrName.getLength())
185*cdf0e10cSrcweir 	{
186*cdf0e10cSrcweir 		drawing::PolyPolygonBezierCoords aBezier;
187*cdf0e10cSrcweir 
188*cdf0e10cSrcweir 		if(rValue >>= aBezier)
189*cdf0e10cSrcweir 		{
190*cdf0e10cSrcweir 			OUString aStrValue;
191*cdf0e10cSrcweir 			OUStringBuffer aOut;
192*cdf0e10cSrcweir 
193*cdf0e10cSrcweir 			/////////////////
194*cdf0e10cSrcweir 			// Name
195*cdf0e10cSrcweir 			sal_Bool bEncoded = sal_False;
196*cdf0e10cSrcweir 			OUString aStrName( rStrName );
197*cdf0e10cSrcweir 			rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME,
198*cdf0e10cSrcweir 								  rExport.EncodeStyleName( aStrName,
199*cdf0e10cSrcweir 														   &bEncoded ) );
200*cdf0e10cSrcweir 			if( bEncoded )
201*cdf0e10cSrcweir 				rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_DISPLAY_NAME,
202*cdf0e10cSrcweir 									  aStrName );
203*cdf0e10cSrcweir 
204*cdf0e10cSrcweir 			/////////////////
205*cdf0e10cSrcweir 			// Viewbox (viewBox="0 0 1500 1000")
206*cdf0e10cSrcweir 			sal_Int32 nMinX(0x7fffffff);
207*cdf0e10cSrcweir 			sal_Int32 nMaxX(0x80000000);
208*cdf0e10cSrcweir 			sal_Int32 nMinY(0x7fffffff);
209*cdf0e10cSrcweir 			sal_Int32 nMaxY(0x80000000);
210*cdf0e10cSrcweir 			sal_Int32 nOuterCnt(aBezier.Coordinates.getLength());
211*cdf0e10cSrcweir 			drawing::PointSequence* pOuterSequence = aBezier.Coordinates.getArray();
212*cdf0e10cSrcweir 			sal_Int32 a, b;
213*cdf0e10cSrcweir 			sal_Bool bClosed(sal_False);
214*cdf0e10cSrcweir 
215*cdf0e10cSrcweir             for (a = 0; a < nOuterCnt; a++)
216*cdf0e10cSrcweir 			{
217*cdf0e10cSrcweir 				drawing::PointSequence* pSequence = pOuterSequence++;
218*cdf0e10cSrcweir 				const awt::Point *pPoints = pSequence->getConstArray();
219*cdf0e10cSrcweir 				sal_Int32 nPointCount(pSequence->getLength());
220*cdf0e10cSrcweir 
221*cdf0e10cSrcweir 				if(nPointCount)
222*cdf0e10cSrcweir 				{
223*cdf0e10cSrcweir 					const awt::Point aStart = pPoints[0];
224*cdf0e10cSrcweir 					const awt::Point aEnd = pPoints[nPointCount - 1];
225*cdf0e10cSrcweir 
226*cdf0e10cSrcweir 					if(aStart.X == aEnd.X && aStart.Y == aEnd.Y)
227*cdf0e10cSrcweir 					{
228*cdf0e10cSrcweir 						bClosed = sal_True;
229*cdf0e10cSrcweir 					}
230*cdf0e10cSrcweir 				}
231*cdf0e10cSrcweir 
232*cdf0e10cSrcweir                 for (b = 0; b < nPointCount; b++)
233*cdf0e10cSrcweir 				{
234*cdf0e10cSrcweir 					const awt::Point aPoint = pPoints[b];
235*cdf0e10cSrcweir 
236*cdf0e10cSrcweir 					if( aPoint.X < nMinX )
237*cdf0e10cSrcweir 						nMinX = aPoint.X;
238*cdf0e10cSrcweir 
239*cdf0e10cSrcweir 					if( aPoint.X > nMaxX )
240*cdf0e10cSrcweir 						nMaxX = aPoint.X;
241*cdf0e10cSrcweir 
242*cdf0e10cSrcweir 					if( aPoint.Y < nMinY )
243*cdf0e10cSrcweir 						nMinY = aPoint.Y;
244*cdf0e10cSrcweir 
245*cdf0e10cSrcweir 					if( aPoint.Y > nMaxY )
246*cdf0e10cSrcweir 						nMaxY = aPoint.Y;
247*cdf0e10cSrcweir 				}
248*cdf0e10cSrcweir 			}
249*cdf0e10cSrcweir 
250*cdf0e10cSrcweir 			sal_Int32 nDifX(nMaxX - nMinX);
251*cdf0e10cSrcweir 			sal_Int32 nDifY(nMaxY - nMinY);
252*cdf0e10cSrcweir 
253*cdf0e10cSrcweir 			SdXMLImExViewBox aViewBox( 0, 0, nDifX, nDifY );
254*cdf0e10cSrcweir 			rExport.AddAttribute( XML_NAMESPACE_SVG, XML_VIEWBOX, aViewBox.GetExportString() );
255*cdf0e10cSrcweir 
256*cdf0e10cSrcweir 			/////////////////
257*cdf0e10cSrcweir 			// Pathdata
258*cdf0e10cSrcweir 			pOuterSequence = aBezier.Coordinates.getArray();
259*cdf0e10cSrcweir 			drawing::FlagSequence*  pOuterFlags = aBezier.Flags.getArray();
260*cdf0e10cSrcweir 			SdXMLImExSvgDElement aSvgDElement(aViewBox);
261*cdf0e10cSrcweir 
262*cdf0e10cSrcweir             for (a = 0; a < nOuterCnt; a++)
263*cdf0e10cSrcweir 			{
264*cdf0e10cSrcweir 				drawing::PointSequence* pSequence = pOuterSequence++;
265*cdf0e10cSrcweir 				drawing::FlagSequence* pFlags = pOuterFlags++;
266*cdf0e10cSrcweir 
267*cdf0e10cSrcweir 				aSvgDElement.AddPolygon(pSequence, pFlags,
268*cdf0e10cSrcweir 					awt::Point( 0, 0 ),
269*cdf0e10cSrcweir 					awt::Size( aViewBox.GetWidth(), aViewBox.GetHeight() ),
270*cdf0e10cSrcweir 					bClosed);
271*cdf0e10cSrcweir 			}
272*cdf0e10cSrcweir 
273*cdf0e10cSrcweir 			// write point array
274*cdf0e10cSrcweir 			rExport.AddAttribute(XML_NAMESPACE_SVG, XML_D, aSvgDElement.GetExportString());
275*cdf0e10cSrcweir 
276*cdf0e10cSrcweir 			/////////////////
277*cdf0e10cSrcweir 			// Do Write
278*cdf0e10cSrcweir             SvXMLElementExport rElem( rExport, XML_NAMESPACE_DRAW, XML_MARKER,
279*cdf0e10cSrcweir                                       sal_True, sal_False );
280*cdf0e10cSrcweir 		}
281*cdf0e10cSrcweir 	}
282*cdf0e10cSrcweir 
283*cdf0e10cSrcweir 	return bRet;
284*cdf0e10cSrcweir }
285*cdf0e10cSrcweir 
286*cdf0e10cSrcweir #endif // #ifndef SVX_LIGHT
287