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 // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_xmloff.hxx"
24 
25 #include "xmloff/MarkerStyle.hxx"
26 #include "xexptran.hxx"
27 #include <xmloff/attrlist.hxx>
28 #include <xmloff/nmspmap.hxx>
29 #include <xmloff/xmluconv.hxx>
30 #include "xmloff/xmlnmspe.hxx"
31 #include <xmloff/xmltoken.hxx>
32 #include <xmloff/xmlexp.hxx>
33 #include <xmloff/xmlimp.hxx>
34 #include <rtl/ustrbuf.hxx>
35 #include <rtl/ustring.hxx>
36 #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
37 #include <basegfx/polygon/b2dpolypolygon.hxx>
38 #include <basegfx/polygon/b2dpolypolygontools.hxx>
39 #include <basegfx/matrix/b2dhommatrixtools.hxx>
40 
41 using namespace ::com::sun::star;
42 using ::rtl::OUString;
43 using ::rtl::OUStringBuffer;
44 
45 using namespace ::xmloff::token;
46 
47 
48 //-------------------------------------------------------------
49 // Import
50 //-------------------------------------------------------------
51 
XMLMarkerStyleImport(SvXMLImport & rImp)52 XMLMarkerStyleImport::XMLMarkerStyleImport( SvXMLImport& rImp )
53     : rImport( rImp )
54 {
55 }
56 
~XMLMarkerStyleImport()57 XMLMarkerStyleImport::~XMLMarkerStyleImport()
58 {
59 }
60 
importXML(const uno::Reference<xml::sax::XAttributeList> & xAttrList,uno::Any & rValue,OUString & rStrName)61 sal_Bool XMLMarkerStyleImport::importXML(
62     const uno::Reference< xml::sax::XAttributeList >& xAttrList,
63     uno::Any& rValue,
64     OUString& rStrName )
65 {
66 	sal_Bool bHasViewBox    = sal_False;
67 	sal_Bool bHasPathData   = sal_False;
68 	OUString aDisplayName;
69 
70 	SdXMLImExViewBox* pViewBox = NULL;
71 
72     SvXMLNamespaceMap& rNamespaceMap = rImport.GetNamespaceMap();
73     SvXMLUnitConverter& rUnitConverter = rImport.GetMM100UnitConverter();
74 
75 	OUString strPathData;
76 
77 	sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
78 	for( sal_Int16 i = 0; i < nAttrCount; i++ )
79 	{
80 		OUString aStrFullAttrName = xAttrList->getNameByIndex( i );
81 		OUString aStrAttrName;
82 		rNamespaceMap.GetKeyByAttrName( aStrFullAttrName, &aStrAttrName );
83 		OUString aStrValue = xAttrList->getValueByIndex( i );
84 
85 		if( IsXMLToken( aStrAttrName, XML_NAME ) )
86 		{
87 			rStrName = aStrValue;
88 		}
89 		else if( IsXMLToken( aStrAttrName, XML_DISPLAY_NAME ) )
90 		{
91 			aDisplayName = aStrValue;
92 		}
93 		else if( IsXMLToken( aStrAttrName, XML_VIEWBOX ) )
94 		{
95 			pViewBox = new SdXMLImExViewBox( aStrValue, rUnitConverter );
96 			bHasViewBox = sal_True;
97 
98 		}
99 		else if( IsXMLToken( aStrAttrName, XML_D ) )
100 		{
101 			strPathData = aStrValue;
102 			bHasPathData = sal_True;
103 		}
104 	}
105 
106     if( bHasViewBox && bHasPathData )
107     {
108         basegfx::B2DPolyPolygon aPolyPolygon;
109 
110         if(basegfx::tools::importFromSvgD(aPolyPolygon, strPathData, true, 0))
111         {
112             if(aPolyPolygon.count())
113             {
114                 // ViewBox probably not used, but stay with former processing inside of
115                 // SdXMLImExSvgDElement
116                 const basegfx::B2DRange aSourceRange(
117                     pViewBox->GetX(), pViewBox->GetY(),
118                     pViewBox->GetX() + pViewBox->GetWidth(), pViewBox->GetY() + pViewBox->GetHeight());
119                 const basegfx::B2DRange aTargetRange(
120                     0.0, 0.0,
121                     pViewBox->GetWidth(), pViewBox->GetHeight());
122 
123                 if(!aSourceRange.equal(aTargetRange))
124                 {
125                     aPolyPolygon.transform(
126                         basegfx::tools::createSourceRangeTargetRangeTransform(
127                             aSourceRange,
128                             aTargetRange));
129                 }
130 
131                 // always use PolyPolygonBezierCoords here
132                 drawing::PolyPolygonBezierCoords aSourcePolyPolygon;
133 
134                 basegfx::tools::B2DPolyPolygonToUnoPolyPolygonBezierCoords(
135                     aPolyPolygon,
136                     aSourcePolyPolygon);
137                 rValue <<= aSourcePolyPolygon;
138             }
139         }
140 
141         if( aDisplayName.getLength() )
142         {
143             rImport.AddStyleDisplayName( XML_STYLE_FAMILY_SD_MARKER_ID, rStrName,
144                                         aDisplayName );
145             rStrName = aDisplayName;
146         }
147     }
148 
149 	if( pViewBox )
150 		delete pViewBox;
151 
152 	return bHasViewBox && bHasPathData;
153 }
154 
155 
156 //-------------------------------------------------------------
157 // Export
158 //-------------------------------------------------------------
159 
160 #ifndef SVX_LIGHT
161 
XMLMarkerStyleExport(SvXMLExport & rExp)162 XMLMarkerStyleExport::XMLMarkerStyleExport( SvXMLExport& rExp )
163     : rExport( rExp )
164 {
165 }
166 
~XMLMarkerStyleExport()167 XMLMarkerStyleExport::~XMLMarkerStyleExport()
168 {
169 }
170 
exportXML(const OUString & rStrName,const uno::Any & rValue)171 sal_Bool XMLMarkerStyleExport::exportXML(
172     const OUString& rStrName,
173     const uno::Any& rValue )
174 {
175     sal_Bool bRet(sal_False);
176 
177     if(rStrName.getLength())
178     {
179         drawing::PolyPolygonBezierCoords aBezier;
180 
181         if(rValue >>= aBezier)
182         {
183             /////////////////
184             // Name
185             sal_Bool bEncoded(sal_False);
186             OUString aStrName( rStrName );
187 
188             rExport.AddAttribute(XML_NAMESPACE_DRAW, XML_NAME, rExport.EncodeStyleName( aStrName, &bEncoded ) );
189 
190             if( bEncoded )
191             {
192                 rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_DISPLAY_NAME, aStrName );
193             }
194 
195             const basegfx::B2DPolyPolygon aPolyPolygon(
196                 basegfx::tools::UnoPolyPolygonBezierCoordsToB2DPolyPolygon(
197                     aBezier));
198             const basegfx::B2DRange aPolyPolygonRange(aPolyPolygon.getB2DRange());
199 
200             /////////////////
201             // Viewbox (viewBox="0 0 1500 1000")
202 
203             SdXMLImExViewBox aViewBox(
204                 aPolyPolygonRange.getMinX(),
205                 aPolyPolygonRange.getMinY(),
206                 aPolyPolygonRange.getWidth(),
207                 aPolyPolygonRange.getHeight());
208             rExport.AddAttribute( XML_NAMESPACE_SVG, XML_VIEWBOX, aViewBox.GetExportString() );
209 
210             /////////////////
211             // Pathdata
212             const ::rtl::OUString aPolygonString(
213                 basegfx::tools::exportToSvgD(
214                     aPolyPolygon,
215                     true,           // bUseRelativeCoordinates
216                     false,          // bDetectQuadraticBeziers: not used in old, but maybe activated now
217                     true));         // bHandleRelativeNextPointCompatible
218 
219             // write point array
220             rExport.AddAttribute(XML_NAMESPACE_SVG, XML_D, aPolygonString);
221 
222             /////////////////
223             // Do Write
224             SvXMLElementExport rElem( rExport, XML_NAMESPACE_DRAW, XML_MARKER, sal_True, sal_False );
225         }
226     }
227 
228     return bRet;
229 }
230 
231 #endif // #ifndef SVX_LIGHT
232