Bump for 4.0-11
[LibreOffice.git] / xmloff / source / draw / XMLImageMapExport.cxx
blobb01a3950b41ed9d5fbb5bca0372c722f383fbfa6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "XMLImageMapExport.hxx"
21 #include <rtl/ustring.hxx>
22 #include <rtl/ustrbuf.hxx>
23 #include <tools/debug.hxx>
24 #include <com/sun/star/uno/Reference.h>
25 #include <com/sun/star/uno/Sequence.h>
26 #include <com/sun/star/beans/XPropertySet.hpp>
27 #include <com/sun/star/lang/XServiceInfo.hpp>
28 #include <com/sun/star/container/XIndexContainer.hpp>
30 #include <com/sun/star/document/XEventsSupplier.hpp>
31 #include <com/sun/star/awt/Rectangle.hpp>
32 #include <com/sun/star/awt/Point.hpp>
33 #include <com/sun/star/awt/Size.hpp>
34 #include <com/sun/star/drawing/PointSequence.hpp>
35 #include <xmloff/xmlexp.hxx>
36 #include "xmloff/xmlnmspe.hxx"
37 #include <xmloff/xmltoken.hxx>
38 #include <xmloff/XMLEventExport.hxx>
39 #include <xmloff/xmluconv.hxx>
40 #include "xexptran.hxx"
44 using namespace ::com::sun::star;
45 using namespace ::xmloff::token;
47 using ::rtl::OUString;
48 using ::rtl::OUStringBuffer;
49 using ::com::sun::star::uno::Any;
50 using ::com::sun::star::uno::UNO_QUERY;
51 using ::com::sun::star::uno::Sequence;
52 using ::com::sun::star::uno::Reference;
53 using ::com::sun::star::beans::XPropertySet;
54 using ::com::sun::star::container::XIndexContainer;
55 using ::com::sun::star::document::XEventsSupplier;
56 using ::com::sun::star::lang::XServiceInfo;
57 using ::com::sun::star::drawing::PointSequence;
60 const sal_Char sAPI_ImageMapRectangleObject[] = "com.sun.star.image.ImageMapRectangleObject";
61 const sal_Char sAPI_ImageMapCircleObject[] = "com.sun.star.image.ImageMapCircleObject";
62 const sal_Char sAPI_ImageMapPolygonObject[] = "com.sun.star.image.ImageMapPolygonObject";
64 XMLImageMapExport::XMLImageMapExport(SvXMLExport& rExp) :
65 msBoundary(RTL_CONSTASCII_USTRINGPARAM("Boundary")),
66 msCenter(RTL_CONSTASCII_USTRINGPARAM("Center")),
67 msDescription(RTL_CONSTASCII_USTRINGPARAM("Description")),
68 msImageMap(RTL_CONSTASCII_USTRINGPARAM("ImageMap")),
69 msIsActive(RTL_CONSTASCII_USTRINGPARAM("IsActive")),
70 msName(RTL_CONSTASCII_USTRINGPARAM("Name")),
71 msPolygon(RTL_CONSTASCII_USTRINGPARAM("Polygon")),
72 msRadius(RTL_CONSTASCII_USTRINGPARAM("Radius")),
73 msTarget(RTL_CONSTASCII_USTRINGPARAM("Target")),
74 msURL(RTL_CONSTASCII_USTRINGPARAM("URL")),
75 msTitle(RTL_CONSTASCII_USTRINGPARAM("Title")),
76 mrExport(rExp),
77 mbWhiteSpace(sal_True)
81 XMLImageMapExport::~XMLImageMapExport()
86 void XMLImageMapExport::Export(
87 const Reference<XPropertySet> & rPropertySet)
89 if (rPropertySet->getPropertySetInfo()->hasPropertyByName(msImageMap))
91 Any aAny = rPropertySet->getPropertyValue(msImageMap);
92 Reference<XIndexContainer> aContainer;
93 aAny >>= aContainer;
95 Export(aContainer);
97 // else: no ImageMap property -> nothing to do
100 void XMLImageMapExport::Export(
101 const Reference<XIndexContainer> & rContainer)
103 if (rContainer.is())
105 if (rContainer->hasElements())
107 // image map container element
108 SvXMLElementExport aImageMapElement(
109 mrExport, XML_NAMESPACE_DRAW, XML_IMAGE_MAP,
110 mbWhiteSpace, mbWhiteSpace);
112 // iterate over image map elements and call ExportMapEntry(...)
113 // for each
114 sal_Int32 nLength = rContainer->getCount();
115 for(sal_Int32 i = 0; i < nLength; i++)
117 Any aAny = rContainer->getByIndex(i);
118 Reference<XPropertySet> rElement;
119 aAny >>= rElement;
121 DBG_ASSERT(rElement.is(), "Image map element is empty!");
122 if (rElement.is())
124 ExportMapEntry(rElement);
128 // else: container is empty -> nothing to do
130 // else: no container -> nothign to do
134 void XMLImageMapExport::ExportMapEntry(
135 const Reference<XPropertySet> & rPropertySet)
137 Reference<XServiceInfo> xServiceInfo(rPropertySet, UNO_QUERY);
138 if (xServiceInfo.is())
140 enum XMLTokenEnum eType = XML_TOKEN_INVALID;
142 // distinguish map entries by their service name
143 Sequence<OUString> sServiceNames =
144 xServiceInfo->getSupportedServiceNames();
145 sal_Int32 nLength = sServiceNames.getLength();
146 for( sal_Int32 i=0; i<nLength; i++ )
148 OUString& rName = sServiceNames[i];
150 if ( rName.equalsAsciiL(sAPI_ImageMapRectangleObject,
151 sizeof(sAPI_ImageMapRectangleObject)-1) )
153 eType = XML_AREA_RECTANGLE;
154 break;
156 else if ( rName.equalsAsciiL(sAPI_ImageMapCircleObject,
157 sizeof(sAPI_ImageMapCircleObject)-1) )
159 eType = XML_AREA_CIRCLE;
160 break;
162 else if ( rName.equalsAsciiL(sAPI_ImageMapPolygonObject,
163 sizeof(sAPI_ImageMapPolygonObject)-1))
165 eType = XML_AREA_POLYGON;
166 break;
170 // return from method if no proper service is found!
171 DBG_ASSERT(XML_TOKEN_INVALID != eType,
172 "Image map element doesn't support appropriate service!");
173 if (XML_TOKEN_INVALID == eType)
174 return;
176 // now: handle ImageMapObject properties (those for all types)
178 // XLINK (URL property)
179 Any aAny = rPropertySet->getPropertyValue(msURL);
180 OUString sHref;
181 aAny >>= sHref;
182 if (!sHref.isEmpty())
184 mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, mrExport.GetRelativeReference(sHref));
186 mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
188 // Target property (and xlink:show)
189 aAny = rPropertySet->getPropertyValue(msTarget);
190 OUString sTargt;
191 aAny >>= sTargt;
192 if (!sTargt.isEmpty())
194 mrExport.AddAttribute(
195 XML_NAMESPACE_OFFICE, XML_TARGET_FRAME_NAME, sTargt);
197 mrExport.AddAttribute(
198 XML_NAMESPACE_XLINK, XML_SHOW,
199 sTargt.equalsAsciiL( "_blank", sizeof("_blank")-1 )
200 ? XML_NEW : XML_REPLACE );
203 // name
204 aAny = rPropertySet->getPropertyValue(msName);
205 OUString sItemName;
206 aAny >>= sItemName;
207 if (!sItemName.isEmpty())
209 mrExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_NAME, sItemName);
212 // is-active
213 aAny = rPropertySet->getPropertyValue(msIsActive);
214 if (! *(sal_Bool*)aAny.getValue())
216 mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_NOHREF, XML_NOHREF);
219 // call specific rectangle/circle/... method
220 // also prepare element name
221 switch (eType)
223 case XML_AREA_RECTANGLE:
224 ExportRectangle(rPropertySet);
225 break;
226 case XML_AREA_CIRCLE:
227 ExportCircle(rPropertySet);
228 break;
229 case XML_AREA_POLYGON:
230 ExportPolygon(rPropertySet);
231 break;
232 default:
233 break;
236 // write element
237 DBG_ASSERT(XML_TOKEN_INVALID != eType,
238 "No name?! How did this happen?");
239 SvXMLElementExport aAreaElement(mrExport, XML_NAMESPACE_DRAW, eType,
240 mbWhiteSpace, mbWhiteSpace);
242 // title property (as <svg:title> element)
243 OUString sTitle;
244 rPropertySet->getPropertyValue(msTitle) >>= sTitle;
245 if(!sTitle.isEmpty())
247 SvXMLElementExport aEventElemt(mrExport, XML_NAMESPACE_SVG, XML_TITLE, mbWhiteSpace, sal_False);
248 mrExport.Characters(sTitle);
251 // description property (as <svg:desc> element)
252 OUString sDescription;
253 rPropertySet->getPropertyValue(msDescription) >>= sDescription;
254 if (!sDescription.isEmpty())
256 SvXMLElementExport aDesc(mrExport, XML_NAMESPACE_SVG, XML_DESC, mbWhiteSpace, sal_False);
257 mrExport.Characters(sDescription);
260 // export events attached to this
261 Reference<XEventsSupplier> xSupplier(rPropertySet, UNO_QUERY);
262 mrExport.GetEventExport().Export(xSupplier, mbWhiteSpace);
264 // else: no service info -> can't determine type -> ignore entry
267 void XMLImageMapExport::ExportRectangle(
268 const Reference<XPropertySet> & rPropertySet)
270 // get boundary rectangle
271 Any aAny = rPropertySet->getPropertyValue(msBoundary);
272 awt::Rectangle aRectangle;
273 aAny >>= aRectangle;
275 // parameters svg:x, svg:y, svg:width, svg:height
276 OUStringBuffer aBuffer;
277 mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer, aRectangle.X);
278 mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_X,
279 aBuffer.makeStringAndClear() );
280 mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer, aRectangle.Y);
281 mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_Y,
282 aBuffer.makeStringAndClear() );
283 mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer,
284 aRectangle.Width);
285 mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_WIDTH,
286 aBuffer.makeStringAndClear() );
287 mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer,
288 aRectangle.Height);
289 mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_HEIGHT,
290 aBuffer.makeStringAndClear() );
293 void XMLImageMapExport::ExportCircle(
294 const Reference<XPropertySet> & rPropertySet)
296 // get boundary rectangle
297 Any aAny = rPropertySet->getPropertyValue(msCenter);
298 awt::Point aCenter;
299 aAny >>= aCenter;
301 // parameters svg:cx, svg:cy
302 OUStringBuffer aBuffer;
303 mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer, aCenter.X);
304 mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_CX,
305 aBuffer.makeStringAndClear() );
306 mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer, aCenter.Y);
307 mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_CY,
308 aBuffer.makeStringAndClear() );
310 // radius
311 aAny = rPropertySet->getPropertyValue(msRadius);
312 sal_Int32 nRadius = 0;
313 aAny >>= nRadius;
314 mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer, nRadius);
315 mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_R,
316 aBuffer.makeStringAndClear() );
319 void XMLImageMapExport::ExportPolygon(
320 const Reference<XPropertySet> & rPropertySet)
322 // polygons get exported as bounding box, viewbox, and coordinate
323 // pair sequence. The bounding box is always the entire image.
325 // get polygon point sequence
326 Any aAny = rPropertySet->getPropertyValue(msPolygon);
327 PointSequence aPoly;
328 aAny >>= aPoly;
330 // get bounding box (assume top-left to be 0,0)
331 sal_Int32 nWidth = 0;
332 sal_Int32 nHeight = 0;
333 sal_Int32 nLength = aPoly.getLength();
334 const struct awt::Point* pPointPtr = aPoly.getConstArray();
335 for ( sal_Int32 i = 0; i < nLength; i++ )
337 sal_Int32 nPolyX = pPointPtr->X;
338 sal_Int32 nPolyY = pPointPtr->Y;
340 if ( nPolyX > nWidth )
341 nWidth = nPolyX;
342 if ( nPolyY > nHeight )
343 nHeight = nPolyY;
345 pPointPtr++;
347 DBG_ASSERT(nWidth > 0, "impossible Polygon found");
348 DBG_ASSERT(nHeight > 0, "impossible Polygon found");
350 // parameters svg:x, svg:y, svg:width, svg:height
351 OUStringBuffer aBuffer;
352 mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer, 0);
353 mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_X,
354 aBuffer.makeStringAndClear() );
355 mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer, 0);
356 mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_Y,
357 aBuffer.makeStringAndClear() );
358 mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer, nWidth);
359 mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_WIDTH,
360 aBuffer.makeStringAndClear() );
361 mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer, nHeight);
362 mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_HEIGHT,
363 aBuffer.makeStringAndClear() );
365 // svg:viewbox
366 SdXMLImExViewBox aViewBox(0, 0, nWidth, nHeight);
367 mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_VIEWBOX,
368 aViewBox.GetExportString());
370 // export point sequence
371 awt::Point aPoint(0, 0);
372 awt::Size aSize(nWidth, nHeight);
373 SdXMLImExPointsElement aPoints( &aPoly, aViewBox, aPoint, aSize );
374 mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_POINTS,
375 aPoints.GetExportString());
378 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */