Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "XMLImageMapExport.hxx"
30 : : #include <rtl/ustring.hxx>
31 : : #include <rtl/ustrbuf.hxx>
32 : : #include <tools/debug.hxx>
33 : : #include <com/sun/star/uno/Reference.h>
34 : : #include <com/sun/star/uno/Sequence.h>
35 : : #include <com/sun/star/beans/XPropertySet.hpp>
36 : : #include <com/sun/star/lang/XServiceInfo.hpp>
37 : : #include <com/sun/star/container/XIndexContainer.hpp>
38 : :
39 : : #include <com/sun/star/document/XEventsSupplier.hpp>
40 : : #include <com/sun/star/awt/Rectangle.hpp>
41 : : #include <com/sun/star/awt/Point.hpp>
42 : : #include <com/sun/star/awt/Size.hpp>
43 : : #include <com/sun/star/drawing/PointSequence.hpp>
44 : : #include <xmloff/xmlexp.hxx>
45 : : #include "xmloff/xmlnmspe.hxx"
46 : : #include <xmloff/xmltoken.hxx>
47 : : #include <xmloff/XMLEventExport.hxx>
48 : : #include <xmloff/xmluconv.hxx>
49 : : #include "xexptran.hxx"
50 : :
51 : :
52 : :
53 : : using namespace ::com::sun::star;
54 : : using namespace ::xmloff::token;
55 : :
56 : : using ::rtl::OUString;
57 : : using ::rtl::OUStringBuffer;
58 : : using ::com::sun::star::uno::Any;
59 : : using ::com::sun::star::uno::UNO_QUERY;
60 : : using ::com::sun::star::uno::Sequence;
61 : : using ::com::sun::star::uno::Reference;
62 : : using ::com::sun::star::beans::XPropertySet;
63 : : using ::com::sun::star::container::XIndexContainer;
64 : : using ::com::sun::star::document::XEventsSupplier;
65 : : using ::com::sun::star::lang::XServiceInfo;
66 : : using ::com::sun::star::drawing::PointSequence;
67 : :
68 : :
69 : : const sal_Char sAPI_ImageMapRectangleObject[] = "com.sun.star.image.ImageMapRectangleObject";
70 : : const sal_Char sAPI_ImageMapCircleObject[] = "com.sun.star.image.ImageMapCircleObject";
71 : : const sal_Char sAPI_ImageMapPolygonObject[] = "com.sun.star.image.ImageMapPolygonObject";
72 : :
73 : 0 : XMLImageMapExport::XMLImageMapExport(SvXMLExport& rExp) :
74 : : msBoundary(RTL_CONSTASCII_USTRINGPARAM("Boundary")),
75 : : msCenter(RTL_CONSTASCII_USTRINGPARAM("Center")),
76 : : msDescription(RTL_CONSTASCII_USTRINGPARAM("Description")),
77 : : msImageMap(RTL_CONSTASCII_USTRINGPARAM("ImageMap")),
78 : : msIsActive(RTL_CONSTASCII_USTRINGPARAM("IsActive")),
79 : : msName(RTL_CONSTASCII_USTRINGPARAM("Name")),
80 : : msPolygon(RTL_CONSTASCII_USTRINGPARAM("Polygon")),
81 : : msRadius(RTL_CONSTASCII_USTRINGPARAM("Radius")),
82 : : msTarget(RTL_CONSTASCII_USTRINGPARAM("Target")),
83 : : msURL(RTL_CONSTASCII_USTRINGPARAM("URL")),
84 : : msTitle(RTL_CONSTASCII_USTRINGPARAM("Title")),
85 : : mrExport(rExp),
86 [ # # ][ # # ]: 0 : mbWhiteSpace(sal_True)
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
87 : : {
88 : 0 : }
89 : :
90 : 0 : XMLImageMapExport::~XMLImageMapExport()
91 : : {
92 : :
93 : 0 : }
94 : :
95 : 0 : void XMLImageMapExport::Export(
96 : : const Reference<XPropertySet> & rPropertySet)
97 : : {
98 [ # # ][ # # ]: 0 : if (rPropertySet->getPropertySetInfo()->hasPropertyByName(msImageMap))
[ # # ]
99 : : {
100 [ # # ][ # # ]: 0 : Any aAny = rPropertySet->getPropertyValue(msImageMap);
101 : 0 : Reference<XIndexContainer> aContainer;
102 [ # # ]: 0 : aAny >>= aContainer;
103 : :
104 [ # # ]: 0 : Export(aContainer);
105 : : }
106 : : // else: no ImageMap property -> nothing to do
107 : 0 : }
108 : :
109 : 0 : void XMLImageMapExport::Export(
110 : : const Reference<XIndexContainer> & rContainer)
111 : : {
112 [ # # ]: 0 : if (rContainer.is())
113 : : {
114 [ # # ]: 0 : if (rContainer->hasElements())
115 : : {
116 : : // image map container element
117 : : SvXMLElementExport aImageMapElement(
118 : : mrExport, XML_NAMESPACE_DRAW, XML_IMAGE_MAP,
119 [ # # ]: 0 : mbWhiteSpace, mbWhiteSpace);
120 : :
121 : : // iterate over image map elements and call ExportMapEntry(...)
122 : : // for each
123 [ # # ][ # # ]: 0 : sal_Int32 nLength = rContainer->getCount();
124 [ # # ]: 0 : for(sal_Int32 i = 0; i < nLength; i++)
125 : : {
126 [ # # ][ # # ]: 0 : Any aAny = rContainer->getByIndex(i);
127 : 0 : Reference<XPropertySet> rElement;
128 [ # # ]: 0 : aAny >>= rElement;
129 : :
130 : : DBG_ASSERT(rElement.is(), "Image map element is empty!");
131 [ # # ]: 0 : if (rElement.is())
132 : : {
133 [ # # ]: 0 : ExportMapEntry(rElement);
134 : : }
135 [ # # ]: 0 : }
136 : : }
137 : : // else: container is empty -> nothing to do
138 : : }
139 : : // else: no container -> nothign to do
140 : 0 : }
141 : :
142 : :
143 : 0 : void XMLImageMapExport::ExportMapEntry(
144 : : const Reference<XPropertySet> & rPropertySet)
145 : : {
146 [ # # ]: 0 : Reference<XServiceInfo> xServiceInfo(rPropertySet, UNO_QUERY);
147 [ # # ]: 0 : if (xServiceInfo.is())
148 : : {
149 : 0 : enum XMLTokenEnum eType = XML_TOKEN_INVALID;
150 : :
151 : : // distinguish map entries by their service name
152 : : Sequence<OUString> sServiceNames =
153 [ # # ][ # # ]: 0 : xServiceInfo->getSupportedServiceNames();
154 : 0 : sal_Int32 nLength = sServiceNames.getLength();
155 [ # # ]: 0 : for( sal_Int32 i=0; i<nLength; i++ )
156 : : {
157 [ # # ]: 0 : OUString& rName = sServiceNames[i];
158 : :
159 [ # # ]: 0 : if ( rName.equalsAsciiL(sAPI_ImageMapRectangleObject,
160 : 0 : sizeof(sAPI_ImageMapRectangleObject)-1) )
161 : : {
162 : 0 : eType = XML_AREA_RECTANGLE;
163 : 0 : break;
164 : : }
165 [ # # ]: 0 : else if ( rName.equalsAsciiL(sAPI_ImageMapCircleObject,
166 : 0 : sizeof(sAPI_ImageMapCircleObject)-1) )
167 : : {
168 : 0 : eType = XML_AREA_CIRCLE;
169 : 0 : break;
170 : : }
171 [ # # ]: 0 : else if ( rName.equalsAsciiL(sAPI_ImageMapPolygonObject,
172 : 0 : sizeof(sAPI_ImageMapPolygonObject)-1))
173 : : {
174 : 0 : eType = XML_AREA_POLYGON;
175 : 0 : break;
176 : : }
177 : : }
178 : :
179 : : // return from method if no proper service is found!
180 : : DBG_ASSERT(XML_TOKEN_INVALID != eType,
181 : : "Image map element doesn't support appropriate service!");
182 [ # # ]: 0 : if (XML_TOKEN_INVALID == eType)
183 : 0 : return;
184 : :
185 : : // now: handle ImageMapObject properties (those for all types)
186 : :
187 : : // XLINK (URL property)
188 [ # # ][ # # ]: 0 : Any aAny = rPropertySet->getPropertyValue(msURL);
189 : 0 : OUString sHref;
190 : 0 : aAny >>= sHref;
191 [ # # ]: 0 : if (!sHref.isEmpty())
192 : : {
193 [ # # ][ # # ]: 0 : mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, mrExport.GetRelativeReference(sHref));
194 : : }
195 [ # # ]: 0 : mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
196 : :
197 : : // Target property (and xlink:show)
198 [ # # ][ # # ]: 0 : aAny = rPropertySet->getPropertyValue(msTarget);
199 : 0 : OUString sTargt;
200 : 0 : aAny >>= sTargt;
201 [ # # ]: 0 : if (!sTargt.isEmpty())
202 : : {
203 : : mrExport.AddAttribute(
204 [ # # ]: 0 : XML_NAMESPACE_OFFICE, XML_TARGET_FRAME_NAME, sTargt);
205 : :
206 : : mrExport.AddAttribute(
207 : : XML_NAMESPACE_XLINK, XML_SHOW,
208 : 0 : sTargt.equalsAsciiL( "_blank", sizeof("_blank")-1 )
209 [ # # ][ # # ]: 0 : ? XML_NEW : XML_REPLACE );
210 : : }
211 : :
212 : : // name
213 [ # # ][ # # ]: 0 : aAny = rPropertySet->getPropertyValue(msName);
214 : 0 : OUString sItemName;
215 : 0 : aAny >>= sItemName;
216 [ # # ]: 0 : if (!sItemName.isEmpty())
217 : : {
218 [ # # ]: 0 : mrExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_NAME, sItemName);
219 : : }
220 : :
221 : : // is-active
222 [ # # ][ # # ]: 0 : aAny = rPropertySet->getPropertyValue(msIsActive);
223 [ # # ]: 0 : if (! *(sal_Bool*)aAny.getValue())
224 : : {
225 [ # # ]: 0 : mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_NOHREF, XML_NOHREF);
226 : : }
227 : :
228 : : // call specific rectangle/circle/... method
229 : : // also prepare element name
230 [ # # # # ]: 0 : switch (eType)
231 : : {
232 : : case XML_AREA_RECTANGLE:
233 [ # # ]: 0 : ExportRectangle(rPropertySet);
234 : 0 : break;
235 : : case XML_AREA_CIRCLE:
236 [ # # ]: 0 : ExportCircle(rPropertySet);
237 : 0 : break;
238 : : case XML_AREA_POLYGON:
239 [ # # ]: 0 : ExportPolygon(rPropertySet);
240 : 0 : break;
241 : : default:
242 : 0 : break;
243 : : }
244 : :
245 : : // write element
246 : : DBG_ASSERT(XML_TOKEN_INVALID != eType,
247 : : "No name?! How did this happen?");
248 : : SvXMLElementExport aAreaElement(mrExport, XML_NAMESPACE_DRAW, eType,
249 [ # # ]: 0 : mbWhiteSpace, mbWhiteSpace);
250 : :
251 : : // title property (as <svg:title> element)
252 : 0 : OUString sTitle;
253 [ # # ][ # # ]: 0 : rPropertySet->getPropertyValue(msTitle) >>= sTitle;
254 [ # # ]: 0 : if(!sTitle.isEmpty())
255 : : {
256 [ # # ]: 0 : SvXMLElementExport aEventElemt(mrExport, XML_NAMESPACE_SVG, XML_TITLE, mbWhiteSpace, sal_False);
257 [ # # ][ # # ]: 0 : mrExport.Characters(sTitle);
258 : : }
259 : :
260 : : // description property (as <svg:desc> element)
261 : 0 : OUString sDescription;
262 [ # # ][ # # ]: 0 : rPropertySet->getPropertyValue(msDescription) >>= sDescription;
263 [ # # ]: 0 : if (!sDescription.isEmpty())
264 : : {
265 [ # # ]: 0 : SvXMLElementExport aDesc(mrExport, XML_NAMESPACE_SVG, XML_DESC, mbWhiteSpace, sal_False);
266 [ # # ][ # # ]: 0 : mrExport.Characters(sDescription);
267 : : }
268 : :
269 : : // export events attached to this
270 [ # # ]: 0 : Reference<XEventsSupplier> xSupplier(rPropertySet, UNO_QUERY);
271 [ # # ][ # # ]: 0 : mrExport.GetEventExport().Export(xSupplier, mbWhiteSpace);
[ # # ][ # # ]
[ # # ]
272 [ # # ]: 0 : }
273 : : // else: no service info -> can't determine type -> ignore entry
274 : : }
275 : :
276 : 0 : void XMLImageMapExport::ExportRectangle(
277 : : const Reference<XPropertySet> & rPropertySet)
278 : : {
279 : : // get boundary rectangle
280 [ # # ][ # # ]: 0 : Any aAny = rPropertySet->getPropertyValue(msBoundary);
281 : 0 : awt::Rectangle aRectangle;
282 [ # # ]: 0 : aAny >>= aRectangle;
283 : :
284 : : // parameters svg:x, svg:y, svg:width, svg:height
285 : 0 : OUStringBuffer aBuffer;
286 [ # # ]: 0 : mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer, aRectangle.X);
287 : : mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_X,
288 [ # # ][ # # ]: 0 : aBuffer.makeStringAndClear() );
289 [ # # ]: 0 : mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer, aRectangle.Y);
290 : : mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_Y,
291 [ # # ][ # # ]: 0 : aBuffer.makeStringAndClear() );
292 : 0 : mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer,
293 [ # # ]: 0 : aRectangle.Width);
294 : : mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_WIDTH,
295 [ # # ][ # # ]: 0 : aBuffer.makeStringAndClear() );
296 : 0 : mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer,
297 [ # # ]: 0 : aRectangle.Height);
298 : : mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_HEIGHT,
299 [ # # ][ # # ]: 0 : aBuffer.makeStringAndClear() );
300 : 0 : }
301 : :
302 : 0 : void XMLImageMapExport::ExportCircle(
303 : : const Reference<XPropertySet> & rPropertySet)
304 : : {
305 : : // get boundary rectangle
306 [ # # ][ # # ]: 0 : Any aAny = rPropertySet->getPropertyValue(msCenter);
307 : 0 : awt::Point aCenter;
308 [ # # ]: 0 : aAny >>= aCenter;
309 : :
310 : : // parameters svg:cx, svg:cy
311 : 0 : OUStringBuffer aBuffer;
312 [ # # ]: 0 : mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer, aCenter.X);
313 : : mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_CX,
314 [ # # ][ # # ]: 0 : aBuffer.makeStringAndClear() );
315 [ # # ]: 0 : mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer, aCenter.Y);
316 : : mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_CY,
317 [ # # ][ # # ]: 0 : aBuffer.makeStringAndClear() );
318 : :
319 : : // radius
320 [ # # ][ # # ]: 0 : aAny = rPropertySet->getPropertyValue(msRadius);
321 : 0 : sal_Int32 nRadius = 0;
322 : 0 : aAny >>= nRadius;
323 [ # # ]: 0 : mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer, nRadius);
324 : : mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_R,
325 [ # # ][ # # ]: 0 : aBuffer.makeStringAndClear() );
326 : 0 : }
327 : :
328 : 0 : void XMLImageMapExport::ExportPolygon(
329 : : const Reference<XPropertySet> & rPropertySet)
330 : : {
331 : : // polygons get exported as bounding box, viewbox, and coordinate
332 : : // pair sequence. The bounding box is always the entire image.
333 : :
334 : : // get polygon point sequence
335 [ # # ][ # # ]: 0 : Any aAny = rPropertySet->getPropertyValue(msPolygon);
336 [ # # ]: 0 : PointSequence aPoly;
337 [ # # ]: 0 : aAny >>= aPoly;
338 : :
339 : : // get bounding box (assume top-left to be 0,0)
340 : 0 : sal_Int32 nWidth = 0;
341 : 0 : sal_Int32 nHeight = 0;
342 : 0 : sal_Int32 nLength = aPoly.getLength();
343 : 0 : const struct awt::Point* pPointPtr = aPoly.getConstArray();
344 [ # # ]: 0 : for ( sal_Int32 i = 0; i < nLength; i++ )
345 : : {
346 : 0 : sal_Int32 nPolyX = pPointPtr->X;
347 : 0 : sal_Int32 nPolyY = pPointPtr->Y;
348 : :
349 [ # # ]: 0 : if ( nPolyX > nWidth )
350 : 0 : nWidth = nPolyX;
351 [ # # ]: 0 : if ( nPolyY > nHeight )
352 : 0 : nHeight = nPolyY;
353 : :
354 : 0 : pPointPtr++;
355 : : }
356 : : DBG_ASSERT(nWidth > 0, "impossible Polygon found");
357 : : DBG_ASSERT(nHeight > 0, "impossible Polygon found");
358 : :
359 : : // parameters svg:x, svg:y, svg:width, svg:height
360 : 0 : OUStringBuffer aBuffer;
361 [ # # ]: 0 : mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer, 0);
362 : : mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_X,
363 [ # # ][ # # ]: 0 : aBuffer.makeStringAndClear() );
364 [ # # ]: 0 : mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer, 0);
365 : : mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_Y,
366 [ # # ][ # # ]: 0 : aBuffer.makeStringAndClear() );
367 [ # # ]: 0 : mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer, nWidth);
368 : : mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_WIDTH,
369 [ # # ][ # # ]: 0 : aBuffer.makeStringAndClear() );
370 [ # # ]: 0 : mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer, nHeight);
371 : : mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_HEIGHT,
372 [ # # ][ # # ]: 0 : aBuffer.makeStringAndClear() );
373 : :
374 : : // svg:viewbox
375 [ # # ]: 0 : SdXMLImExViewBox aViewBox(0, 0, nWidth, nHeight);
376 : : mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_VIEWBOX,
377 [ # # ][ # # ]: 0 : aViewBox.GetExportString());
378 : :
379 : : // export point sequence
380 : 0 : awt::Point aPoint(0, 0);
381 : 0 : awt::Size aSize(nWidth, nHeight);
382 [ # # ]: 0 : SdXMLImExPointsElement aPoints( &aPoly, aViewBox, aPoint, aSize );
383 : : mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_POINTS,
384 [ # # ][ # # ]: 0 : aPoints.GetExportString());
[ # # ]
385 : 0 : }
386 : :
387 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|