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