| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_xmloff.hxx" |
| #include "XMLImageMapExport.hxx" |
| #include <rtl/ustring.hxx> |
| #include <rtl/ustrbuf.hxx> |
| #include <tools/debug.hxx> |
| #include <com/sun/star/uno/Reference.h> |
| #include <com/sun/star/uno/Sequence.h> |
| #include <com/sun/star/beans/XPropertySet.hpp> |
| #include <com/sun/star/lang/XServiceInfo.hpp> |
| #include <com/sun/star/container/XIndexContainer.hpp> |
| #include <com/sun/star/document/XEventsSupplier.hpp> |
| #include <com/sun/star/awt/Rectangle.hpp> |
| #include <com/sun/star/awt/Point.hpp> |
| #include <com/sun/star/awt/Size.hpp> |
| #include <com/sun/star/drawing/PointSequence.hpp> |
| #include <xmloff/xmlexp.hxx> |
| #include "xmloff/xmlnmspe.hxx" |
| #include <xmloff/xmltoken.hxx> |
| #include <xmloff/XMLEventExport.hxx> |
| #include <xmloff/xmluconv.hxx> |
| #include "xexptran.hxx" |
| #include <basegfx/polygon/b2dpolygon.hxx> |
| #include <basegfx/polygon/b2dpolygontools.hxx> |
| |
| using namespace ::com::sun::star; |
| using namespace ::xmloff::token; |
| |
| using ::rtl::OUString; |
| using ::rtl::OUStringBuffer; |
| using ::com::sun::star::uno::Any; |
| using ::com::sun::star::uno::UNO_QUERY; |
| using ::com::sun::star::uno::Sequence; |
| using ::com::sun::star::uno::Reference; |
| using ::com::sun::star::beans::XPropertySet; |
| using ::com::sun::star::container::XIndexContainer; |
| using ::com::sun::star::document::XEventsSupplier; |
| using ::com::sun::star::lang::XServiceInfo; |
| using ::com::sun::star::drawing::PointSequence; |
| |
| |
| const sal_Char sAPI_ImageMapRectangleObject[] = "com.sun.star.image.ImageMapRectangleObject"; |
| const sal_Char sAPI_ImageMapCircleObject[] = "com.sun.star.image.ImageMapCircleObject"; |
| const sal_Char sAPI_ImageMapPolygonObject[] = "com.sun.star.image.ImageMapPolygonObject"; |
| |
| XMLImageMapExport::XMLImageMapExport(SvXMLExport& rExp) : |
| msBoundary(RTL_CONSTASCII_USTRINGPARAM("Boundary")), |
| msCenter(RTL_CONSTASCII_USTRINGPARAM("Center")), |
| msDescription(RTL_CONSTASCII_USTRINGPARAM("Description")), |
| msImageMap(RTL_CONSTASCII_USTRINGPARAM("ImageMap")), |
| msIsActive(RTL_CONSTASCII_USTRINGPARAM("IsActive")), |
| msName(RTL_CONSTASCII_USTRINGPARAM("Name")), |
| msPolygon(RTL_CONSTASCII_USTRINGPARAM("Polygon")), |
| msRadius(RTL_CONSTASCII_USTRINGPARAM("Radius")), |
| msTarget(RTL_CONSTASCII_USTRINGPARAM("Target")), |
| msURL(RTL_CONSTASCII_USTRINGPARAM("URL")), |
| msTitle(RTL_CONSTASCII_USTRINGPARAM("Title")), |
| mrExport(rExp), |
| mbWhiteSpace(sal_True) |
| { |
| } |
| |
| XMLImageMapExport::~XMLImageMapExport() |
| { |
| |
| } |
| |
| void XMLImageMapExport::Export( |
| const Reference<XPropertySet> & rPropertySet) |
| { |
| if (rPropertySet->getPropertySetInfo()->hasPropertyByName(msImageMap)) |
| { |
| Any aAny = rPropertySet->getPropertyValue(msImageMap); |
| Reference<XIndexContainer> aContainer; |
| aAny >>= aContainer; |
| |
| Export(aContainer); |
| } |
| // else: no ImageMap property -> nothing to do |
| } |
| |
| void XMLImageMapExport::Export( |
| const Reference<XIndexContainer> & rContainer) |
| { |
| if (rContainer.is()) |
| { |
| if (rContainer->hasElements()) |
| { |
| // image map container element |
| SvXMLElementExport aImageMapElement( |
| mrExport, XML_NAMESPACE_DRAW, XML_IMAGE_MAP, |
| mbWhiteSpace, mbWhiteSpace); |
| |
| // iterate over image map elements and call ExportMapEntry(...) |
| // for each |
| sal_Int32 nLength = rContainer->getCount(); |
| for(sal_Int32 i = 0; i < nLength; i++) |
| { |
| Any aAny = rContainer->getByIndex(i); |
| Reference<XPropertySet> rElement; |
| aAny >>= rElement; |
| |
| DBG_ASSERT(rElement.is(), "Image map element is empty!"); |
| if (rElement.is()) |
| { |
| ExportMapEntry(rElement); |
| } |
| } |
| } |
| // else: container is empty -> nothing to do |
| } |
| // else: no container -> nothign to do |
| } |
| |
| |
| void XMLImageMapExport::ExportMapEntry( |
| const Reference<XPropertySet> & rPropertySet) |
| { |
| Reference<XServiceInfo> xServiceInfo(rPropertySet, UNO_QUERY); |
| if (xServiceInfo.is()) |
| { |
| enum XMLTokenEnum eType = XML_TOKEN_INVALID; |
| |
| // distinguish map entries by their service name |
| Sequence<OUString> sServiceNames = |
| xServiceInfo->getSupportedServiceNames(); |
| sal_Int32 nLength = sServiceNames.getLength(); |
| for( sal_Int32 i=0; i<nLength; i++ ) |
| { |
| OUString& rName = sServiceNames[i]; |
| |
| if ( rName.equalsAsciiL(sAPI_ImageMapRectangleObject, |
| sizeof(sAPI_ImageMapRectangleObject)-1) ) |
| { |
| eType = XML_AREA_RECTANGLE; |
| break; |
| } |
| else if ( rName.equalsAsciiL(sAPI_ImageMapCircleObject, |
| sizeof(sAPI_ImageMapCircleObject)-1) ) |
| { |
| eType = XML_AREA_CIRCLE; |
| break; |
| } |
| else if ( rName.equalsAsciiL(sAPI_ImageMapPolygonObject, |
| sizeof(sAPI_ImageMapPolygonObject)-1)) |
| { |
| eType = XML_AREA_POLYGON; |
| break; |
| } |
| } |
| |
| // return from method if no proper service is found! |
| DBG_ASSERT(XML_TOKEN_INVALID != eType, |
| "Image map element doesn't support appropriate service!"); |
| if (XML_TOKEN_INVALID == eType) |
| return; |
| |
| // now: handle ImageMapObject properties (those for all types) |
| |
| // XLINK (URL property) |
| Any aAny = rPropertySet->getPropertyValue(msURL); |
| OUString sHref; |
| aAny >>= sHref; |
| if (sHref.getLength() > 0) |
| { |
| mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, mrExport.GetRelativeReference(sHref)); |
| } |
| mrExport.AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE ); |
| |
| // Target property (and xlink:show) |
| aAny = rPropertySet->getPropertyValue(msTarget); |
| OUString sTargt; |
| aAny >>= sTargt; |
| if (sTargt.getLength() > 0) |
| { |
| mrExport.AddAttribute( |
| XML_NAMESPACE_OFFICE, XML_TARGET_FRAME_NAME, sTargt); |
| |
| mrExport.AddAttribute( |
| XML_NAMESPACE_XLINK, XML_SHOW, |
| sTargt.equalsAsciiL( "_blank", sizeof("_blank")-1 ) |
| ? XML_NEW : XML_REPLACE ); |
| } |
| |
| // name |
| aAny = rPropertySet->getPropertyValue(msName); |
| OUString sItemName; |
| aAny >>= sItemName; |
| if (sItemName.getLength() > 0) |
| { |
| mrExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_NAME, sItemName); |
| } |
| |
| // is-active |
| aAny = rPropertySet->getPropertyValue(msIsActive); |
| if (! *(sal_Bool*)aAny.getValue()) |
| { |
| mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_NOHREF, XML_NOHREF); |
| } |
| |
| // call specific rectangle/circle/... method |
| // also prepare element name |
| switch (eType) |
| { |
| case XML_AREA_RECTANGLE: |
| ExportRectangle(rPropertySet); |
| break; |
| case XML_AREA_CIRCLE: |
| ExportCircle(rPropertySet); |
| break; |
| case XML_AREA_POLYGON: |
| ExportPolygon(rPropertySet); |
| break; |
| default: |
| break; |
| } |
| |
| // write element |
| DBG_ASSERT(XML_TOKEN_INVALID != eType, |
| "No name?! How did this happen?"); |
| SvXMLElementExport aAreaElement(mrExport, XML_NAMESPACE_DRAW, eType, |
| mbWhiteSpace, mbWhiteSpace); |
| |
| // title property (as <svg:title> element) |
| OUString sTitle; |
| rPropertySet->getPropertyValue(msTitle) >>= sTitle; |
| if(sTitle.getLength()) |
| { |
| SvXMLElementExport aEventElemt(mrExport, XML_NAMESPACE_SVG, XML_TITLE, mbWhiteSpace, sal_False); |
| mrExport.Characters(sTitle); |
| } |
| |
| // description property (as <svg:desc> element) |
| OUString sDescription; |
| rPropertySet->getPropertyValue(msDescription) >>= sDescription; |
| if (sDescription.getLength() > 0) |
| { |
| SvXMLElementExport aDesc(mrExport, XML_NAMESPACE_SVG, XML_DESC, mbWhiteSpace, sal_False); |
| mrExport.Characters(sDescription); |
| } |
| |
| // export events attached to this |
| Reference<XEventsSupplier> xSupplier(rPropertySet, UNO_QUERY); |
| mrExport.GetEventExport().Export(xSupplier, mbWhiteSpace); |
| } |
| // else: no service info -> can't determine type -> ignore entry |
| } |
| |
| void XMLImageMapExport::ExportRectangle( |
| const Reference<XPropertySet> & rPropertySet) |
| { |
| // get boundary rectangle |
| Any aAny = rPropertySet->getPropertyValue(msBoundary); |
| awt::Rectangle aRectangle; |
| aAny >>= aRectangle; |
| |
| // parameters svg:x, svg:y, svg:width, svg:height |
| OUStringBuffer aBuffer; |
| mrExport.GetMM100UnitConverter().convertMeasure(aBuffer, aRectangle.X); |
| mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_X, |
| aBuffer.makeStringAndClear() ); |
| mrExport.GetMM100UnitConverter().convertMeasure(aBuffer, aRectangle.Y); |
| mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_Y, |
| aBuffer.makeStringAndClear() ); |
| mrExport.GetMM100UnitConverter().convertMeasure(aBuffer, aRectangle.Width); |
| mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_WIDTH, |
| aBuffer.makeStringAndClear() ); |
| mrExport.GetMM100UnitConverter().convertMeasure(aBuffer, aRectangle.Height); |
| mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_HEIGHT, |
| aBuffer.makeStringAndClear() ); |
| } |
| |
| void XMLImageMapExport::ExportCircle( |
| const Reference<XPropertySet> & rPropertySet) |
| { |
| // get boundary rectangle |
| Any aAny = rPropertySet->getPropertyValue(msCenter); |
| awt::Point aCenter; |
| aAny >>= aCenter; |
| |
| // parameters svg:cx, svg:cy |
| OUStringBuffer aBuffer; |
| mrExport.GetMM100UnitConverter().convertMeasure(aBuffer, aCenter.X); |
| mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_CX, |
| aBuffer.makeStringAndClear() ); |
| mrExport.GetMM100UnitConverter().convertMeasure(aBuffer, aCenter.Y); |
| mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_CY, |
| aBuffer.makeStringAndClear() ); |
| |
| // radius |
| aAny = rPropertySet->getPropertyValue(msRadius); |
| sal_Int32 nRadius = 0; |
| aAny >>= nRadius; |
| mrExport.GetMM100UnitConverter().convertMeasure(aBuffer, nRadius); |
| mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_R, |
| aBuffer.makeStringAndClear() ); |
| } |
| |
| void XMLImageMapExport::ExportPolygon(const Reference<XPropertySet> & rPropertySet) |
| { |
| // polygons get exported as bounding box, viewbox, and coordinate |
| // pair sequence. The bounding box is always the entire image. |
| |
| // get polygon point sequence |
| Any aAny = rPropertySet->getPropertyValue(msPolygon); |
| PointSequence aPoly; |
| aAny >>= aPoly; |
| |
| const basegfx::B2DPolygon aPolygon( |
| basegfx::tools::UnoPointSequenceToB2DPolygon( |
| aPoly)); |
| const basegfx::B2DRange aPolygonRange(aPolygon.getB2DRange()); |
| |
| // parameters svg:x, svg:y, svg:width, svg:height |
| OUStringBuffer aBuffer; |
| |
| mrExport.GetMM100UnitConverter().convertMeasure(aBuffer, 0); |
| mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_X, aBuffer.makeStringAndClear() ); |
| mrExport.GetMM100UnitConverter().convertMeasure(aBuffer, 0); |
| mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_Y, aBuffer.makeStringAndClear() ); |
| mrExport.GetMM100UnitConverter().convertMeasure(aBuffer, basegfx::fround(aPolygonRange.getWidth())); |
| mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_WIDTH, aBuffer.makeStringAndClear() ); |
| mrExport.GetMM100UnitConverter().convertMeasure(aBuffer, basegfx::fround(aPolygonRange.getHeight())); |
| mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_HEIGHT, aBuffer.makeStringAndClear() ); |
| |
| // svg:viewbox |
| SdXMLImExViewBox aViewBox(0.0, 0.0, aPolygonRange.getWidth(), aPolygonRange.getHeight()); |
| mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_VIEWBOX, aViewBox.GetExportString()); |
| |
| // export point sequence |
| const ::rtl::OUString aPointString( |
| basegfx::tools::exportToSvgPoints( |
| aPolygon)); |
| |
| mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_POINTS, aPointString); |
| } |
| |
| // eof |