LibreOffice Module xmloff (master) 1
XMLImageMapExport.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <XMLImageMapExport.hxx>
21#include <o3tl/any.hxx>
22#include <rtl/ustring.hxx>
23#include <rtl/ustrbuf.hxx>
24#include <tools/debug.hxx>
25#include <com/sun/star/uno/Reference.h>
26#include <com/sun/star/uno/Sequence.h>
27#include <com/sun/star/beans/XPropertySet.hpp>
28#include <com/sun/star/lang/XServiceInfo.hpp>
29#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/drawing/PointSequence.hpp>
34#include <xmloff/xmlexp.hxx>
36#include <xmloff/xmltoken.hxx>
38#include <xmloff/xmluconv.hxx>
39#include <xexptran.hxx>
42
43using namespace ::com::sun::star;
44using namespace ::xmloff::token;
45
46using ::com::sun::star::uno::Any;
47using ::com::sun::star::uno::UNO_QUERY;
48using ::com::sun::star::uno::Sequence;
49using ::com::sun::star::uno::Reference;
50using ::com::sun::star::beans::XPropertySet;
51using ::com::sun::star::container::XIndexContainer;
52using ::com::sun::star::document::XEventsSupplier;
53using ::com::sun::star::lang::XServiceInfo;
54using ::com::sun::star::drawing::PointSequence;
55
56constexpr OUStringLiteral gsBoundary(u"Boundary");
57constexpr OUStringLiteral gsCenter(u"Center");
58constexpr OUStringLiteral gsDescription(u"Description");
59constexpr OUStringLiteral gsImageMap(u"ImageMap");
60constexpr OUStringLiteral gsIsActive(u"IsActive");
61constexpr OUStringLiteral gsName(u"Name");
62constexpr OUStringLiteral gsPolygon(u"Polygon");
63constexpr OUStringLiteral gsRadius(u"Radius");
64constexpr OUStringLiteral gsTarget(u"Target");
65constexpr OUStringLiteral gsURL(u"URL");
66constexpr OUStringLiteral gsTitle(u"Title");
67
69 mrExport(rExp)
70{
71}
72
74 const Reference<XPropertySet> & rPropertySet)
75{
76 if (rPropertySet->getPropertySetInfo()->hasPropertyByName(gsImageMap))
77 {
78 Any aAny = rPropertySet->getPropertyValue(gsImageMap);
79 Reference<XIndexContainer> aContainer;
80 aAny >>= aContainer;
81
82 Export(aContainer);
83 }
84 // else: no ImageMap property -> nothing to do
85}
86
88 const Reference<XIndexContainer> & rContainer)
89{
90 if (!rContainer.is())
91 return;
92
93 if (!rContainer->hasElements())
94 return;
95
96 // image map container element
97 SvXMLElementExport aImageMapElement(
99 true/*bWhiteSpace*/, true/*bWhiteSpace*/);
100
101 // iterate over image map elements and call ExportMapEntry(...)
102 // for each
103 sal_Int32 nLength = rContainer->getCount();
104 for(sal_Int32 i = 0; i < nLength; i++)
105 {
106 Any aAny = rContainer->getByIndex(i);
107 Reference<XPropertySet> rElement;
108 aAny >>= rElement;
109
110 DBG_ASSERT(rElement.is(), "Image map element is empty!");
111 if (rElement.is())
112 {
113 ExportMapEntry(rElement);
114 }
115 }
116 // else: container is empty -> nothing to do
117 // else: no container -> nothing to do
118}
119
120
122 const Reference<XPropertySet> & rPropertySet)
123{
124 Reference<XServiceInfo> xServiceInfo(rPropertySet, UNO_QUERY);
125 if (!xServiceInfo.is())
126 return;
127
129
130 // distinguish map entries by their service name
131 const Sequence<OUString> sServiceNames =
132 xServiceInfo->getSupportedServiceNames();
133 for( const OUString& rName : sServiceNames )
134 {
135 if ( rName == "com.sun.star.image.ImageMapRectangleObject" )
136 {
138 break;
139 }
140 else if ( rName == "com.sun.star.image.ImageMapCircleObject" )
141 {
143 break;
144 }
145 else if ( rName == "com.sun.star.image.ImageMapPolygonObject" )
146 {
148 break;
149 }
150 }
151
152 // return from method if no proper service is found!
154 "Image map element doesn't support appropriate service!");
156 return;
157
158 // now: handle ImageMapObject properties (those for all types)
159
160 // XLINK (URL property)
161 Any aAny = rPropertySet->getPropertyValue(gsURL);
162 OUString sHref;
163 aAny >>= sHref;
164 if (!sHref.isEmpty())
165 {
167 }
169
170 // Target property (and xlink:show)
171 aAny = rPropertySet->getPropertyValue(gsTarget);
172 OUString sTargt;
173 aAny >>= sTargt;
174 if (!sTargt.isEmpty())
175 {
178
181 sTargt == "_blank" ? XML_NEW : XML_REPLACE );
182 }
183
184 // name
185 aAny = rPropertySet->getPropertyValue(gsName);
186 OUString sItemName;
187 aAny >>= sItemName;
188 if (!sItemName.isEmpty())
189 {
191 }
192
193 // is-active
194 aAny = rPropertySet->getPropertyValue(gsIsActive);
195 if (! *o3tl::doAccess<bool>(aAny))
196 {
198 }
199
200 // call specific rectangle/circle/... method
201 // also prepare element name
202 switch (eType)
203 {
205 ExportRectangle(rPropertySet);
206 break;
207 case XML_AREA_CIRCLE:
208 ExportCircle(rPropertySet);
209 break;
210 case XML_AREA_POLYGON:
211 ExportPolygon(rPropertySet);
212 break;
213 default:
214 break;
215 }
216
217 // write element
219 "No name?! How did this happen?");
221 true/*bWhiteSpace*/, true/*bWhiteSpace*/);
222
223 // title property (as <svg:title> element)
224 OUString sTitle;
225 rPropertySet->getPropertyValue(gsTitle) >>= sTitle;
226 if(!sTitle.isEmpty())
227 {
228 SvXMLElementExport aEventElemt(mrExport, XML_NAMESPACE_SVG, XML_TITLE, true/*bWhiteSpace*/, false);
229 mrExport.Characters(sTitle);
230 }
231
232 // description property (as <svg:desc> element)
233 OUString sDescription;
234 rPropertySet->getPropertyValue(gsDescription) >>= sDescription;
235 if (!sDescription.isEmpty())
236 {
237 SvXMLElementExport aDesc(mrExport, XML_NAMESPACE_SVG, XML_DESC, true/*bWhiteSpace*/, false);
238 mrExport.Characters(sDescription);
239 }
240
241 // export events attached to this
242 Reference<XEventsSupplier> xSupplier(rPropertySet, UNO_QUERY);
243 mrExport.GetEventExport().Export(xSupplier);
244
245 // else: no service info -> can't determine type -> ignore entry
246}
247
249 const Reference<XPropertySet> & rPropertySet)
250{
251 // get boundary rectangle
252 Any aAny = rPropertySet->getPropertyValue(gsBoundary);
253 awt::Rectangle aRectangle;
254 aAny >>= aRectangle;
255
256 // parameters svg:x, svg:y, svg:width, svg:height
257 OUStringBuffer aBuffer;
260 aBuffer.makeStringAndClear() );
263 aBuffer.makeStringAndClear() );
265 aRectangle.Width);
267 aBuffer.makeStringAndClear() );
269 aRectangle.Height);
271 aBuffer.makeStringAndClear() );
272}
273
275 const Reference<XPropertySet> & rPropertySet)
276{
277 // get boundary rectangle
278 Any aAny = rPropertySet->getPropertyValue(gsCenter);
279 awt::Point aCenter;
280 aAny >>= aCenter;
281
282 // parameters svg:cx, svg:cy
283 OUStringBuffer aBuffer;
286 aBuffer.makeStringAndClear() );
289 aBuffer.makeStringAndClear() );
290
291 // radius
292 aAny = rPropertySet->getPropertyValue(gsRadius);
293 sal_Int32 nRadius = 0;
294 aAny >>= nRadius;
297 aBuffer.makeStringAndClear() );
298}
299
300void XMLImageMapExport::ExportPolygon(const Reference<XPropertySet> & rPropertySet)
301{
302 // polygons get exported as bounding box, viewbox, and coordinate
303 // pair sequence. The bounding box is always the entire image.
304
305 // get polygon point sequence
306 Any aAny = rPropertySet->getPropertyValue(gsPolygon);
307 PointSequence aPoly;
308 aAny >>= aPoly;
309
310 const basegfx::B2DPolygon aPolygon(
312 aPoly));
313 const basegfx::B2DRange aPolygonRange(aPolygon.getB2DRange());
314
315 // parameters svg:x, svg:y, svg:width, svg:height
316 OUStringBuffer aBuffer;
317
319 mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_X, aBuffer.makeStringAndClear() );
321 mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_Y, aBuffer.makeStringAndClear() );
323 mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_WIDTH, aBuffer.makeStringAndClear() );
325 mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_HEIGHT, aBuffer.makeStringAndClear() );
326
327 // svg:viewbox
328 SdXMLImExViewBox aViewBox(0.0, 0.0, aPolygonRange.getWidth(), aPolygonRange.getHeight());
330
331 // export point sequence
332 const OUString aPointString(
334 aPolygon));
335
337}
338
339/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
constexpr OUStringLiteral gsIsActive(u"IsActive")
constexpr OUStringLiteral gsURL(u"URL")
constexpr OUStringLiteral gsName(u"Name")
constexpr OUStringLiteral gsPolygon(u"Polygon")
constexpr OUStringLiteral gsBoundary(u"Boundary")
constexpr OUStringLiteral gsDescription(u"Description")
constexpr OUStringLiteral gsRadius(u"Radius")
constexpr OUStringLiteral gsTarget(u"Target")
constexpr OUStringLiteral gsTitle(u"Title")
constexpr OUStringLiteral gsCenter(u"Center")
constexpr OUStringLiteral gsImageMap(u"ImageMap")
const OUString & GetExportString()
Definition: xexptran.cxx:1036
OUString GetRelativeReference(const OUString &rValue)
Definition: xmlexp.cxx:2064
XMLEventExport & GetEventExport()
get Event export, with handlers for script types "None" and "StarBasic" already registered; other han...
Definition: xmlexp.cxx:1993
void AddAttribute(sal_uInt16 nPrefix, const OUString &rName, const OUString &rValue)
Definition: xmlexp.cxx:911
void Characters(const OUString &rChars)
Definition: xmlexp.cxx:2133
const SvXMLUnitConverter & GetMM100UnitConverter() const
Definition: xmlexp.hxx:396
void convertMeasureToXML(OUStringBuffer &rBuffer, sal_Int32 nMeasure) const
convert measure to string: from meCoreMeasureUnit to meXMLMeasureUnit
Definition: xmluconv.cxx:207
void Export(css::uno::Reference< css::document::XEventsSupplier > const &xAccess, bool bUseWhitespace=true)
export the events (calls EventExport::Export(Reference<XNameAccess>) )
void ExportCircle(const css::uno::Reference< css::beans::XPropertySet > &rPropertySet)
Export the specifics of a circular image map entry.
void ExportMapEntry(const css::uno::Reference< css::beans::XPropertySet > &rPropertySet)
Export a single, named map entry.
void ExportPolygon(const css::uno::Reference< css::beans::XPropertySet > &rPropertySet)
Export the specifics of a polygonal image map entry; To be called by ExportMapEntry.
void ExportRectangle(const css::uno::Reference< css::beans::XPropertySet > &rPropertySet)
Export the specifics of a rectangular image map entry.
void Export(const css::uno::Reference< css::beans::XPropertySet > &rPropertySet)
Get the ImageMap object from the "ImageMap" property and subsequently export the map (if present).
SvXMLExport & mrExport
XMLImageMapExport(SvXMLExport &rExport)
B2DRange const & getB2DRange() const
TYPE getWidth() const
TYPE getHeight() const
#define DBG_ASSERT(sCon, aError)
DocumentType eType
B2DPolygon UnoPointSequenceToB2DPolygon(const css::drawing::PointSequence &rPointSequenceSource)
OUString exportToSvgPoints(const B2DPolygon &rPoly)
B2IRange fround(const B2DRange &rRange)
int i
Handling of tokens in XML:
XMLTokenEnum
The enumeration of all XML tokens.
Definition: xmltoken.hxx:50
std::unique_ptr< char[]> aBuffer
constexpr sal_uInt16 XML_NAMESPACE_DRAW
constexpr sal_uInt16 XML_NAMESPACE_XLINK
constexpr sal_uInt16 XML_NAMESPACE_SVG
constexpr sal_uInt16 XML_NAMESPACE_OFFICE
sal_Int32 nLength
Definition: xmltoken.cxx:38