Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/xmloff/source/draw/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 11 kB image not shown  

Quelle  XMLImageMapExport.cxx   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   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 .
 */


#include <XMLImageMapExport.hxx>
#include <o3tl/any.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/drawing/PointSequence.hpp>
#include <xmloff/xmlexp.hxx>
#include <xmloff/xmlnamespace.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 ::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;

constexpr OUStringLiteral gsBoundary(u"Boundary");
constexpr OUStringLiteral gsCenter(u"Center");
constexpr OUStringLiteral gsDescription(u"Description");
constexpr OUString gsImageMap(u"ImageMap"_ustr);
constexpr OUStringLiteral gsIsActive(u"IsActive");
constexpr OUStringLiteral gsName(u"Name");
constexpr OUStringLiteral gsPolygon(u"Polygon");
constexpr OUStringLiteral gsRadius(u"Radius");
constexpr OUStringLiteral gsTarget(u"Target");
constexpr OUStringLiteral gsURL(u"URL");
constexpr OUStringLiteral gsTitle(u"Title");

XMLImageMapExport::XMLImageMapExport(SvXMLExport& rExp) :
    mrExport(rExp)
{
}

void XMLImageMapExport::Export(
    const Reference<XPropertySet> & rPropertySet)
{
    if (rPropertySet->getPropertySetInfo()->hasPropertyByName(gsImageMap))
    {
        Any aAny = rPropertySet->getPropertyValue(gsImageMap);
        Reference<XIndexContainer> aContainer;
        aAny >>= aContainer;

        Export(aContainer);
    }
    // else: no ImageMap property -> nothing to do
}

void XMLImageMapExport::Export(
    const Reference<XIndexContainer> & rContainer)
{
    if (!rContainer.is())
        return;

    if (!rContainer->hasElements())
        return;

    // image map container element
    SvXMLElementExport aImageMapElement(
        mrExport, XML_NAMESPACE_DRAW, XML_IMAGE_MAP,
        true/*bWhiteSpace*/, true/*bWhiteSpace*/);

    // 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 -> nothing to do
}


void XMLImageMapExport::ExportMapEntry(
    const Reference<XPropertySet> & rPropertySet)
{
    Reference<XServiceInfo> xServiceInfo(rPropertySet, UNO_QUERY);
    if (!xServiceInfo.is())
        return;

    enum XMLTokenEnum eType = XML_TOKEN_INVALID;

    // distinguish map entries by their service name
    const Sequence<OUString> sServiceNames =
        xServiceInfo->getSupportedServiceNames();
    forconst OUString& rName : sServiceNames )
    {
        if ( rName == "com.sun.star.image.ImageMapRectangleObject" )
        {
            eType = XML_AREA_RECTANGLE;
            break;
        }
        else if ( rName == "com.sun.star.image.ImageMapCircleObject" )
        {
            eType = XML_AREA_CIRCLE;
            break;
        }
        else if ( rName == "com.sun.star.image.ImageMapPolygonObject" )
        {
            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(gsURL);
    OUString sHref;
    aAny >>= sHref;
    if (!sHref.isEmpty())
    {
        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(gsTarget);
    OUString sTargt;
    aAny >>= sTargt;
    if (!sTargt.isEmpty())
    {
        mrExport.AddAttribute(
            XML_NAMESPACE_OFFICE, XML_TARGET_FRAME_NAME, sTargt);

        mrExport.AddAttribute(
            XML_NAMESPACE_XLINK, XML_SHOW,
            sTargt == "_blank" ? XML_NEW : XML_REPLACE );
    }

    // name
    aAny = rPropertySet->getPropertyValue(gsName);
    OUString sItemName;
    aAny >>= sItemName;
    if (!sItemName.isEmpty())
    {
        mrExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_NAME, sItemName);
    }

    // is-active
    aAny = rPropertySet->getPropertyValue(gsIsActive);
    if (! *o3tl::doAccess<bool>(aAny))
    {
        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,
                                    true/*bWhiteSpace*/, true/*bWhiteSpace*/);

    // title property (as <svg:title> element)
    OUString sTitle;
    rPropertySet->getPropertyValue(gsTitle) >>= sTitle;
    if(!sTitle.isEmpty())
    {
        SvXMLElementExport aEventElemt(mrExport, XML_NAMESPACE_SVG, XML_TITLE, true/*bWhiteSpace*/, false);
        mrExport.Characters(sTitle);
    }

    // description property (as <svg:desc> element)
    OUString sDescription;
    rPropertySet->getPropertyValue(gsDescription) >>= sDescription;
    if (!sDescription.isEmpty())
    {
        SvXMLElementExport aDesc(mrExport, XML_NAMESPACE_SVG, XML_DESC, true/*bWhiteSpace*/, false);
        mrExport.Characters(sDescription);
    }

    // export events attached to this
    Reference<XEventsSupplier> xSupplier(rPropertySet, UNO_QUERY);
    mrExport.GetEventExport().Export(xSupplier);

    // else: no service info -> can't determine type -> ignore entry
}

void XMLImageMapExport::ExportRectangle(
    const Reference<XPropertySet> & rPropertySet)
{
    // get boundary rectangle
    Any aAny = rPropertySet->getPropertyValue(gsBoundary);
    awt::Rectangle aRectangle;
    aAny >>= aRectangle;

    // parameters svg:x, svg:y, svg:width, svg:height
    OUStringBuffer aBuffer;
    mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer, aRectangle.X);
    mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_X,
                          aBuffer.makeStringAndClear() );
    mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer, aRectangle.Y);
    mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_Y,
                          aBuffer.makeStringAndClear() );
    mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer,
            aRectangle.Width);
    mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_WIDTH,
                          aBuffer.makeStringAndClear() );
    mrExport.GetMM100UnitConverter().convertMeasureToXML(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(gsCenter);
    awt::Point aCenter;
    aAny >>= aCenter;

    // parameters svg:cx, svg:cy
    OUStringBuffer aBuffer;
    mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer, aCenter.X);
    mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_CX,
                          aBuffer.makeStringAndClear() );
    mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer, aCenter.Y);
    mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_CY,
                          aBuffer.makeStringAndClear() );

    // radius
    aAny = rPropertySet->getPropertyValue(gsRadius);
    sal_Int32 nRadius = 0;
    aAny >>= nRadius;
    mrExport.GetMM100UnitConverter().convertMeasureToXML(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(gsPolygon);
    PointSequence aPoly;
    aAny >>= aPoly;

    const basegfx::B2DPolygon aPolygon(
        basegfx::utils::UnoPointSequenceToB2DPolygon(
            aPoly));
    const basegfx::B2DRange aPolygonRange(aPolygon.getB2DRange());

    // parameters svg:x, svg:y, svg:width, svg:height
    OUStringBuffer aBuffer;

    mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer, 0);
    mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_X, aBuffer.makeStringAndClear() );
    mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer, 0);
    mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_Y, aBuffer.makeStringAndClear() );
    mrExport.GetMM100UnitConverter().convertMeasureToXML(aBuffer, basegfx::fround(aPolygonRange.getWidth()));
    mrExport.AddAttribute( XML_NAMESPACE_SVG, XML_WIDTH, aBuffer.makeStringAndClear() );
    mrExport.GetMM100UnitConverter().convertMeasureToXML(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 OUString aPointString(
        basegfx::utils::exportToSvgPoints(
            aPolygon));

    mrExport.AddAttribute(XML_NAMESPACE_DRAW, XML_POINTS, aPointString);
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=82 H=97 G=89

¤ Dauer der Verarbeitung: 0.15 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.