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