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