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

Quelle  UnoGraphicExporter.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 <vector>
#include <com/sun/star/io/XOutputStream.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/container/XChild.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/drawing/XShape.hpp>
#include <com/sun/star/drawing/XDrawPage.hpp>
#include <com/sun/star/drawing/XGraphicExportFilter.hpp>
#include <com/sun/star/graphic/XGraphic.hpp>
#include <com/sun/star/graphic/XGraphicRenderer.hpp>
#include <com/sun/star/task/XStatusIndicator.hpp>
#include <com/sun/star/task/XInteractionHandler.hpp>
#include <com/sun/star/task/XInteractionContinuation.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>

#include <boost/property_tree/json_parser/error.hpp>
#include <tools/debug.hxx>
#include <comphelper/diagnose_ex.hxx>
#include <tools/urlobj.hxx>
#include <comphelper/interaction.hxx>
#include <framework/interaction.hxx>
#include <com/sun/star/drawing/GraphicFilterRequest.hpp>
#include <com/sun/star/util/URL.hpp>
#include <cppuhelper/implbase.hxx>
#include <cppuhelper/supportsservice.hxx>
#include <vcl/metaact.hxx>
#include <vcl/svapp.hxx>
#include <vcl/virdev.hxx>
#include <svl/outstrm.hxx>
#include <sdr/contact/objectcontactofobjlistpainter.hxx>
#include <svx/sdr/contact/viewobjectcontact.hxx>
#include <svx/sdr/contact/viewcontact.hxx>
#include <svx/sdr/contact/displayinfo.hxx>
#include <editeng/numitem.hxx>
#include <svx/svdograf.hxx>
#include <svx/xoutbmp.hxx>
#include <vcl/graphicfilter.hxx>
#include <svx/svdpage.hxx>
#include <svx/svdmodel.hxx>
#include <svx/fmview.hxx>
#include <svx/fmmodel.hxx>
#include <svx/unopage.hxx>
#include <svx/svdoutl.hxx>
#include <svx/xlineit0.hxx>
#include <editeng/flditem.hxx>
#include <svtools/optionsdrawinglayer.hxx>
#include <comphelper/sequenceashashmap.hxx>
#include <comphelper/propertysequence.hxx>
#include <comphelper/sequence.hxx>
#include <UnoGraphicExporter.hxx>
#include <memory>
// #i102251#
#include <editeng/editstat.hxx>

#define MAX_EXT_PIX         2048

using namespace ::comphelper;
using namespace ::cppu;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::drawing;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::task;

namespace {

    struct ExportSettings
    {
        OUString maFilterName;
        OUString maMediaType;
        URL maURL;
        css::uno::Reference< css::io::XOutputStream >         mxOutputStream;
        css::uno::Reference< css::graphic::XGraphicRenderer > mxGraphicRenderer;
        css::uno::Reference< css::task::XStatusIndicator >    mxStatusIndicator;
        css::uno::Reference< css::task::XInteractionHandler > mxInteractionHandler;

        sal_Int32 mnWidth;
        sal_Int32 mnHeight;
        bool mbExportOnlyBackground;
        bool mbScrollText;
        bool mbUseHighContrast;
        bool mbTranslucent;

        Sequence< PropertyValue >   maFilterData;

        Fraction    maScaleX;
        Fraction    maScaleY;

        TriState meAntiAliasing = TRISTATE_INDET;

        explicit ExportSettings();
    };

    ExportSettings::ExportSettings()
    :   mnWidth( 0 )
        ,mnHeight( 0 )
        ,mbExportOnlyBackground( false )
        ,mbScrollText( false )
        ,mbUseHighContrast( false )
        ,mbTranslucent( false )
        ,maScaleX(1, 1)
        ,maScaleY(1, 1)
    {
    }

    /** implements a component to export shapes or pages to external graphic formats.

        @implements com.sun.star.drawing.GraphicExportFilter
    */

    class GraphicExporter : public ::cppu::WeakImplHelper< XGraphicExportFilter, XServiceInfo >
    {
    public:
        GraphicExporter();

        // XFilter
        virtual sal_Bool SAL_CALL filter( const Sequence< PropertyValue >& aDescriptor ) override;
        virtual void SAL_CALL cancel(  ) override;

        // XExporter
        virtual void SAL_CALL setSourceDocument( const Reference< XComponent >& xDoc ) override;

        // XServiceInfo
        virtual OUString SAL_CALL getImplementationName(  ) override;
        virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
        virtual Sequence< OUString > SAL_CALL getSupportedServiceNames(  ) override;

        // XMimeTypeInfo
        virtual sal_Bool SAL_CALL supportsMimeType( const OUString& MimeTypeName ) override;
        virtual Sequence< OUString > SAL_CALL getSupportedMimeTypeNames(  ) override;

        VclPtr<VirtualDevice> CreatePageVDev( SdrPage* pPage, tools::Long nWidthPixel, tools::Long nHeightPixel ) const;

        DECL_LINK( CalcFieldValueHdl, EditFieldInfo*, void );

        void ParseSettings( const Sequence< PropertyValue >& aDescriptor, ExportSettings& rSettings );
        bool GetGraphic( ExportSettings const & rSettings, Graphic& aGraphic, bool bVectorType );

    private:
        Reference< XShape >     mxShape;
        Reference< XDrawPage >  mxPage;
        Reference< XShapes >    mxShapes;
        Graphic maGraphic;

        SvxDrawPage*        mpUnoPage;

        Link<EditFieldInfo*,void> maOldCalcFieldValueHdl;
        sal_Int32           mnPageNumber;
        SdrPage*            mpCurrentPage;
        SdrModel*           mpDoc;
    };

    Size* CalcSize( sal_Int32 nWidth, sal_Int32 nHeight, const Size& aBoundSize, Size& ;aOutSize )
    {
        if( (nWidth == 0) && (nHeight == 0) )
            return nullptr;

        if( (nWidth == 0) && (nHeight != 0) && (aBoundSize.Height() != 0) )
        {
            nWidth = ( nHeight * aBoundSize.Width() ) / aBoundSize.Height();
        }
        else if( (nWidth != 0) && (nHeight == 0) && (aBoundSize.Width() != 0) )
        {
            nHeight = ( nWidth * aBoundSize.Height() ) / aBoundSize.Width();
        }

        aOutSize.setWidth( nWidth );
        aOutSize.setHeight( nHeight );

        return &aOutSize;
    }

class ImplExportCheckVisisbilityRedirector : public sdr::contact::ViewObjectContactRedirector
{
public:
    explicit ImplExportCheckVisisbilityRedirector( SdrPage* pCurrentPage );

    virtual void createRedirectedPrimitive2DSequence(
        const sdr::contact::ViewObjectContact& rOriginal,
        const sdr::contact::DisplayInfo& rDisplayInfo,
        drawinglayer::primitive2d::Primitive2DDecompositionVisitor& rVisitor) override;

private:
    SdrPage*    mpCurrentPage;
};

ImplExportCheckVisisbilityRedirector::ImplExportCheckVisisbilityRedirector( SdrPage* pCurrentPage )
:   mpCurrentPage( pCurrentPage )
{
}

void ImplExportCheckVisisbilityRedirector::createRedirectedPrimitive2DSequence(
    const sdr::contact::ViewObjectContact& rOriginal,
    const sdr::contact::DisplayInfo& rDisplayInfo,
    drawinglayer::primitive2d::Primitive2DDecompositionVisitor& rVisitor)
{
    SdrObject* pObject = rOriginal.GetViewContact().TryToGetSdrObject();

    if(pObject)
    {
        SdrPage* pPage = mpCurrentPage;

        if(nullptr == pPage)
        {
            pPage = pObject->getSdrPageFromSdrObject();
        }

        if( (pPage == nullptr) || pPage->checkVisibility(rOriginal, rDisplayInfo, false) )
        {
            return sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence(rOriginal, rDisplayInfo, rVisitor);
        }

        return;
    }
    else
    {
        // not an object, maybe a page
        sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence(rOriginal, rDisplayInfo, rVisitor);
    }
}

GraphicExporter::GraphicExporter()
: mpUnoPage( nullptr ), mnPageNumber(-1), mpCurrentPage(nullptr), mpDoc( nullptr )
{
}

IMPL_LINK(GraphicExporter, CalcFieldValueHdl, EditFieldInfo*, pInfo, void)
{
    if( pInfo )
    {
        if( mpCurrentPage )
        {
            pInfo->SetSdrPage( mpCurrentPage );
        }
        else if( mnPageNumber != -1 )
        {
            const SvxFieldData* pField = pInfo->GetField().GetField();
            ifdynamic_cast<const SvxPageField*>( pField) )
            {
                OUString aPageNumValue;
                bool bUpper = false;

                switch(mpDoc->GetPageNumType())
                {
                    case css::style::NumberingType::CHARS_UPPER_LETTER:
                        aPageNumValue += OUStringChar( sal_Unicode((mnPageNumber - 1) % 26 + 'A') );
                        break;
                    case css::style::NumberingType::CHARS_LOWER_LETTER:
                        aPageNumValue += OUStringChar( sal_Unicode((mnPageNumber - 1) % 26 + 'a') );
                        break;
                    case css::style::NumberingType::ROMAN_UPPER:
                        bUpper = true;
                        [[fallthrough]];
                    case css::style::NumberingType::ROMAN_LOWER:
                        aPageNumValue += SvxNumberFormat::CreateRomanString(mnPageNumber, bUpper);
                        break;
                    case css::style::NumberingType::NUMBER_NONE:
                        aPageNumValue = " ";
                        break;
                    default:
                        aPageNumValue += OUString::number( mnPageNumber );
                }

                pInfo->SetRepresentation( aPageNumValue );

                return;
            }
        }
    }

    maOldCalcFieldValueHdl.Call( pInfo );

    if( pInfo && mpCurrentPage )
        pInfo->SetSdrPage( nullptr );
}

/** creates a virtual device for the given page

    @return the returned VirtualDevice is owned by the caller
*/

VclPtr<VirtualDevice> GraphicExporter::CreatePageVDev( SdrPage* pPage, tools::Long nWidthPixel, tools::Long nHeightPixel ) const
{
    VclPtr<VirtualDevice>  pVDev = VclPtr<VirtualDevice>::Create();
    MapMode         aMM( MapUnit::Map100thMM );

    Point aPoint( 0, 0 );
    Size aPageSize(pPage->GetSize());

    // use scaling?
    if( nWidthPixel != 0 )
    {
        const Fraction aFrac( nWidthPixel, pVDev->LogicToPixel( aPageSize, aMM ).Width() );

        aMM.SetScaleX( aFrac );

        if( nHeightPixel == 0 )
            aMM.SetScaleY( aFrac );
    }

    if( nHeightPixel != 0 )
    {
        const Fraction aFrac( nHeightPixel, pVDev->LogicToPixel( aPageSize, aMM ).Height() );

        if( nWidthPixel == 0 )
            aMM.SetScaleX( aFrac );

        aMM.SetScaleY( aFrac );
    }

    pVDev->SetMapMode( aMM );
    bool bSuccess(false);

    // #i122820# If available, use pixel size directly
    if(nWidthPixel && nHeightPixel)
    {
        bSuccess = pVDev->SetOutputSizePixel(Size(nWidthPixel, nHeightPixel));
    }
    else
    {
        bSuccess = pVDev->SetOutputSize(aPageSize);
    }

    if(bSuccess)
    {
        SdrView aView(*mpDoc, pVDev);

        aView.SetPageVisible( false );
        aView.SetBordVisible( false );
        aView.SetGridVisible( false );
        aView.SetHlplVisible( false );
        aView.SetGlueVisible( false );
        aView.ShowSdrPage(pPage);

        vcl::Region aRegion (tools::Rectangle( aPoint, aPageSize ) );

        ImplExportCheckVisisbilityRedirector aRedirector( mpCurrentPage );

        aView.CompleteRedraw(pVDev, aRegion, &aRedirector);
    }
    else
    {
        OSL_ENSURE(false"Could not get a VirtualDevice of requested size (!)");
    }

    return pVDev;
}

void GraphicExporter::ParseSettings(const Sequence<PropertyValue>& rDescriptor,
                                    ExportSettings& rSettings)
{
    Sequence<PropertyValue> aDescriptor = rDescriptor;
    if (aDescriptor.hasElements())
    {
        comphelper::SequenceAsHashMap aMap(aDescriptor);
        Sequence<PropertyValue> aFilterData;
        OUString aFilterOptions;
        auto it = aMap.find(u"FilterData"_ustr);
        if (it != aMap.end())
        {
            it->second >>= aFilterData;
        }
        it = aMap.find(u"FilterOptions"_ustr);
        if (it != aMap.end())
        {
            it->second >>= aFilterOptions;
        }
        if (!aFilterData.hasElements() && !aFilterOptions.isEmpty())
        {
            // Allow setting filter data keys from the cmdline.
            try
            {
                std::vector<PropertyValue> aData
                    = comphelper::JsonToPropertyValues(aFilterOptions.toUtf8());
                aFilterData = comphelper::containerToSequence(aData);
            }
            catch (const boost::property_tree::json_parser::json_parser_error&)
            {
                // This wasn't a valid json; maybe came from import filter (tdf#162528)
            }
            if (aFilterData.hasElements())
            {
                aMap[u"FilterData"_ustr] <<= aFilterData;
                aDescriptor = aMap.getAsConstPropertyValueList();
            }
        }
    }

    forconst PropertyValue& rValue : aDescriptor )
    {
        if ( rValue.Name == "FilterName" )
        {
            rValue.Value >>= rSettings.maFilterName;
        }
        else if ( rValue.Name == "MediaType" )
        {
            rValue.Value >>= rSettings.maMediaType;
        }
        else if ( rValue.Name == "URL" )
        {
            if( !( rValue.Value >>= rSettings.maURL ) )
            {
                rValue.Value >>= rSettings.maURL.Complete;
            }
        }
        else if ( rValue.Name == "OutputStream" )
        {
            rValue.Value >>= rSettings.mxOutputStream;
        }
        else if ( rValue.Name == "GraphicRenderer" )
        {
            rValue.Value >>= rSettings.mxGraphicRenderer;
        }
        else if ( rValue.Name == "StatusIndicator" )
        {
            rValue.Value >>= rSettings.mxStatusIndicator;
        }
        else if ( rValue.Name == "InteractionHandler" )
        {
            rValue.Value >>= rSettings.mxInteractionHandler;
        }
        else if( rValue.Name == "Width" )  // for compatibility reasons, deprecated
        {
            rValue.Value >>= rSettings.mnWidth;
        }
        else if( rValue.Name == "Height" ) // for compatibility reasons, deprecated
        {
            rValue.Value >>= rSettings.mnHeight;
        }
        else if( rValue.Name == "ExportOnlyBackground" )   // for compatibility reasons, deprecated
        {
            rValue.Value >>= rSettings.mbExportOnlyBackground;
        }
        else if ( rValue.Name == "FilterData" )
        {
            rValue.Value >>= rSettings.maFilterData;

            for( PropertyValue& rDataValue : asNonConstRange(rSettings.maFilterData) )
            {
                if ( rDataValue.Name == "Translucent" )
                {
                    if ( !( rDataValue.Value >>= rSettings.mbTranslucent ) )  // SJ: TODO: The GIF Transparency is stored as int32 in
                    {                                               // configuration files, this has to be changed to boolean
                        sal_Int32 nTranslucent = 0;
                        if ( rDataValue.Value >>= nTranslucent )
                            rSettings.mbTranslucent = nTranslucent != 0;
                    }
                }
                else if ( rDataValue.Name == "PixelWidth" )
                {
                    rDataValue.Value >>= rSettings.mnWidth;
                }
                else if ( rDataValue.Name == "PixelHeight" )
                {
                    rDataValue.Value >>= rSettings.mnHeight;
                }
                else if( rDataValue.Name == "Width" )  // for compatibility reasons, deprecated
                {
                    rDataValue.Value >>= rSettings.mnWidth;
                    rDataValue.Name = "PixelWidth";
                }
                else if( rDataValue.Name == "Height" ) // for compatibility reasons, deprecated
                {
                    rDataValue.Value >>= rSettings.mnHeight;
                    rDataValue.Name = "PixelHeight";
                }
                else if ( rDataValue.Name == "ExportOnlyBackground" )
                {
                    rDataValue.Value >>= rSettings.mbExportOnlyBackground;
                }
                else if ( rDataValue.Name == "HighContrast" )
                {
                    rDataValue.Value >>= rSettings.mbUseHighContrast;
                }
                else if ( rDataValue.Name == "PageNumber" )
                {
                    rDataValue.Value >>= mnPageNumber;
                }
                else if ( rDataValue.Name == "ScrollText" )
                {
                    // #110496# Read flag solitary scroll text metafile
                    rDataValue.Value >>= rSettings.mbScrollText;
                }
                else if ( rDataValue.Name == "CurrentPage" )
                {
                    Reference< XDrawPage >  xPage;
                    rDataValue.Value >>= xPage;
                    if( xPage.is() )
                    {
                        SvxDrawPage* pUnoPage = comphelper::getFromUnoTunnel<SvxDrawPage>( xPage );
                        if( pUnoPage && pUnoPage->GetSdrPage() )
                            mpCurrentPage = pUnoPage->GetSdrPage();
                    }
                }
                else if ( rDataValue.Name == "ScaleXNumerator" )
                {
                    sal_Int32 nVal = 1;
                    if( rDataValue.Value >>= nVal )
                        rSettings.maScaleX = Fraction( nVal, rSettings.maScaleX.GetDenominator() );
                }
                else if ( rDataValue.Name == "ScaleXDenominator" )
                {
                    sal_Int32 nVal = 1;
                    if( rDataValue.Value >>= nVal )
                        rSettings.maScaleX = Fraction( rSettings.maScaleX.GetNumerator(), nVal );
                }
                else if ( rDataValue.Name == "ScaleYNumerator" )
                {
                    sal_Int32 nVal = 1;
                    if( rDataValue.Value >>= nVal )
                        rSettings.maScaleY = Fraction( nVal, rSettings.maScaleY.GetDenominator() );
                }
                else if ( rDataValue.Name == "ScaleYDenominator" )
                {
                    sal_Int32 nVal = 1;
                    if( rDataValue.Value >>= nVal )
                        rSettings.maScaleY = Fraction( rSettings.maScaleY.GetNumerator(), nVal );
                }
                else if (rDataValue.Name == "AntiAliasing")
                {
                    bool bAntiAliasing;
                    if (rDataValue.Value >>= bAntiAliasing)
                        rSettings.meAntiAliasing = bAntiAliasing ? TRISTATE_TRUE : TRISTATE_FALSE;
                }
            }
        }
    }

    // putting the StatusIndicator that we got from the MediaDescriptor into our local FilterData copy
    if ( rSettings.mxStatusIndicator.is() )
    {
        int i = rSettings.maFilterData.getLength();
        rSettings.maFilterData.realloc( i + 1 );
        auto pFilterData = rSettings.maFilterData.getArray();
        pFilterData[ i ].Name = "StatusIndicator";
        pFilterData[ i ].Value <<= rSettings.mxStatusIndicator;
    }
}

bool GraphicExporter::GetGraphic( ExportSettings const & rSettings, Graphic& aGraphic, bool bVectorType )
{
    if( !mpDoc || !mpUnoPage )
        return false;

    SdrPage* pPage = mpUnoPage->GetSdrPage();
    if( !pPage )
        return false;

    ScopedVclPtrInstance< VirtualDevice > aVDev;
    const MapMode       aMap( mpDoc->GetScaleUnit(), Point(), rSettings.maScaleX, rSettings.maScaleY );

    SdrOutliner& rOutl=mpDoc->GetDrawOutliner();
    maOldCalcFieldValueHdl = rOutl.GetCalcFieldValueHdl();
    rOutl.SetCalcFieldValueHdl( LINK(this, GraphicExporter, CalcFieldValueHdl) );
    ::Color aOldBackColor(rOutl.GetBackgroundColor());
    rOutl.SetBackgroundColor(pPage->GetPageBackgroundColor());

    // #i102251#
    const EEControlBits nOldCntrl(rOutl.GetControlWord());
    EEControlBits nCntrl = nOldCntrl & ~EEControlBits::ONLINESPELLING;
    rOutl.SetControlWord(nCntrl);

    rtl::Reference<SdrObject> pTempBackgroundShape;
    std::vector< SdrObject* > aShapes;
    bool bRet = true;

    // export complete page?
    if ( !mxShape.is() )
    {
        if( rSettings.mbExportOnlyBackground )
        {
            const SdrPageProperties* pCorrectProperties = pPage->getCorrectSdrPageProperties();

            if(pCorrectProperties)
            {
                pTempBackgroundShape = new SdrRectObj(
                    *mpDoc,
                    tools::Rectangle(Point(0,0), pPage->GetSize()));
                pTempBackgroundShape->SetMergedItemSet(pCorrectProperties->GetItemSet());
                pTempBackgroundShape->SetMergedItem(XLineStyleItem(drawing::LineStyle_NONE));
                pTempBackgroundShape->NbcSetStyleSheet(pCorrectProperties->GetStyleSheet(), true);
                aShapes.push_back(pTempBackgroundShape.get());
            }
        }
        else
        {
            const Size aSize( pPage->GetSize() );

            // generate a bitmap to convert it to a pixel format.
            // For gif pictures there can also be a vector format used (bTranslucent)
            if ( !bVectorType && !rSettings.mbTranslucent )
            {
                tools::Long nWidthPix = 0;
                tools::Long nHeightPix = 0;
                if ( rSettings.mnWidth > 0 && rSettings.mnHeight > 0 )
                {
                    nWidthPix = rSettings.mnWidth;
                    nHeightPix = rSettings.mnHeight;
                }
                else
                {
                    const Size aSizePix( Application::GetDefaultDevice()->LogicToPixel( aSize, aMap ) );
                    if (aSizePix.Width() > MAX_EXT_PIX || aSizePix.Height() > MAX_EXT_PIX)
                    {
                        if (aSizePix.Width() > MAX_EXT_PIX)
                            nWidthPix = MAX_EXT_PIX;
                        else
                            nWidthPix = aSizePix.Width();
                        if (aSizePix.Height() > MAX_EXT_PIX)
                            nHeightPix = MAX_EXT_PIX;
                        else
                            nHeightPix = aSizePix.Height();

                        double fWidthDif = static_cast<double>(aSizePix.Width()) / nWidthPix;
                        double fHeightDif = static_cast<double>(aSizePix.Height()) / nHeightPix;

                        if (fWidthDif > fHeightDif)
                            nHeightPix = static_cast<tools::Long>(aSizePix.Height() / fWidthDif);
                        else
                            nWidthPix = static_cast<tools::Long>(aSizePix.Width() / fHeightDif);
                    }
                    else
                    {
                        nWidthPix = aSizePix.Width();
                        nHeightPix = aSizePix.Height();
                    }
                }

                std::unique_ptr<SdrView> xLocalView;

                if (FmFormModel* pFormModel = dynamic_cast<FmFormModel*>(mpDoc))
                {
                    xLocalView.reset(new FmFormView(*pFormModel, aVDev));
                }
                else
                {
                    xLocalView.reset(new SdrView(*mpDoc, aVDev));
                }

                ScopedVclPtr<VirtualDevice> pVDev(CreatePageVDev( pPage, nWidthPix, nHeightPix ));

                if( pVDev )
                {
                    aGraphic = pVDev->GetBitmapEx( Point(), pVDev->GetOutputSize() );
                    aGraphic.SetPrefMapMode( aMap );
                    aGraphic.SetPrefSize( aSize );
                }
            }
            // create a metafile to export a vector format
            else
            {
                GDIMetaFile aMtf;

                aVDev->SetMapMode( aMap );
                if( rSettings.mbUseHighContrast )
                    aVDev->SetDrawMode( aVDev->GetDrawMode() | DrawModeFlags::SettingsLine | DrawModeFlags::SettingsFill | DrawModeFlags::SettingsText | DrawModeFlags::SettingsGradient );
                aVDev->EnableOutput( false );
                aMtf.Record( aVDev );
                Size aNewSize;

                // create a view
                std::unique_ptr< SdrView > pView;

                if (FmFormModel *pFormModel = dynamic_cast<FmFormModel*>(mpDoc))
                {
                    pView.reset(new FmFormView(*pFormModel, aVDev));
                }
                else
                {
                    pView.reset(new SdrView(*mpDoc, aVDev));
                }

                pView->SetBordVisible( false );
                pView->SetPageVisible( false );
                pView->ShowSdrPage( pPage );

                // tdf#96922 deactivate EditView PageVisualization, including PageBackground
                // (formerly 'wiese'). Do *not* switch off MasterPageVisualizationAllowed, we
                // want MasterPage content if a whole SdrPage is exported
                pView->SetPageDecorationAllowed(false);

                const Point aNewOrg( pPage->GetLeftBorder(), pPage->GetUpperBorder() );
                aNewSize = Size( aSize.Width() - pPage->GetLeftBorder() - pPage->GetRightBorder(),
                                 aSize.Height() - pPage->GetUpperBorder() - pPage->GetLowerBorder() );
                const tools::Rectangle aClipRect( aNewOrg, aNewSize );
                MapMode         aVMap( aMap );

                aVDev->Push();
                aVMap.SetOrigin( Point( -aNewOrg.X(), -aNewOrg.Y() ) );
                aVDev->SetRelativeMapMode( aVMap );
                aVDev->IntersectClipRegion( aClipRect );

                // Use new StandardCheckVisisbilityRedirector
                ImplExportCheckVisisbilityRedirector aRedirector( mpCurrentPage );

                pView->CompleteRedraw(aVDev, vcl::Region(tools::Rectangle(aNewOrg, aNewSize)), &aRedirector);

                aVDev->Pop();

                aMtf.Stop();
                aMtf.WindStart();
                aMtf.SetPrefMapMode( aMap );
                aMtf.SetPrefSize( aNewSize );

                // AW: Here the current version was filtering out the MetaActionType::CLIPREGIONs
                // from the metafile. I asked some other developers why this was done, but no
                // one knew a direct reason. Since it's in for long time, it may be an old
                // piece of code. MetaFiles save and load ClipRegions with polygons with preserving
                // the polygons, so a resolution-independent roundtrip is supported. Removed this
                // code since it destroys some MetaFiles where ClipRegions are used. Anyways,
                // just filtering them out is a hack, at least the encapsulated content would need
                // to be clipped geometrically.
                aGraphic = Graphic(aMtf);

                pView->HideSdrPage();

                if( rSettings.mbTranslucent )
                {
                    Size aOutSize;
                    aGraphic = GetBitmapFromMetaFile( aGraphic.GetGDIMetaFile(), CalcSize( rSettings.mnWidth, rSettings.mnHeight, aNewSize, aOutSize ) );
                }
            }
        }
    }

    // export only single shape or shape collection
    else
    {
        // build list of SdrObject
        if( mxShapes.is() )
        {
            Reference< XShape > xShape;
            const sal_Int32 nCount = mxShapes->getCount();

            for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ )
            {
                mxShapes->getByIndex( nIndex ) >>= xShape;
                SdrObject* pObj = SdrObject::getSdrObjectFromXShape(xShape);
                if( pObj )
                    aShapes.push_back( pObj );
            }
        }
        else
        {
            // only one shape
            SdrObject* pObj = SdrObject::getSdrObjectFromXShape(mxShape);
            if( pObj )
                aShapes.push_back( pObj );
        }

        if( aShapes.empty() )
            bRet = false;
    }

    if( bRet && !aShapes.empty() )
    {
        // special treatment for only one SdrGrafObj that has text
        bool bSingleGraphic = false;

        if( 1 == aShapes.size() )
        {
            if( !bVectorType )
            {
                ifauto pGrafObj = dynamic_cast<const SdrGrafObj*>(aShapes.front()) )
                    if (pGrafObj->HasText() )
                    {
                        aGraphic = pGrafObj->GetTransformedGraphic();
                        if ( aGraphic.GetType() == GraphicType::Bitmap )
                        {
                            Size aSizePixel( aGraphic.GetSizePixel() );
                            if( rSettings.mnWidth && rSettings.mnHeight &&
                                ( ( rSettings.mnWidth != aSizePixel.Width() ) ||
                                  ( rSettings.mnHeight != aSizePixel.Height() ) ) )
                            {
                                BitmapEx aBmpEx( aGraphic.GetBitmapEx() );
                                // export: use highest quality
                                aBmpEx.Scale( Size( rSettings.mnWidth, rSettings.mnHeight ), BmpScaleFlag::Lanczos );
                                aGraphic = aBmpEx;
                            }

                            // #118804# only accept for bitmap graphics, else the
                            // conversion to bitmap will happen anywhere without size control
                            // as evtl. defined in rSettings.mnWidth/mnHeight
                            bSingleGraphic = true;
                        }
                    }
            }
            else if( rSettings.mbScrollText )
            {
                SdrObject* pObj = aShapes.front();
                auto pTextObj = DynCastSdrTextObj( pObj);
                if( pTextObj && pTextObj->HasText() )
                {
                    tools::Rectangle aScrollRectangle;
                    tools::Rectangle aPaintRectangle;

                    const std::unique_ptr< GDIMetaFile > pMtf(
                        pTextObj->GetTextScrollMetaFileAndRectangle(
                           aScrollRectangle, aPaintRectangle ) );

                    // take the larger one of the two rectangles (that
                    // should be the bound rect of the retrieved
                    // metafile)
                    tools::Rectangle aTextRect;

                    if( aScrollRectangle.Contains( aPaintRectangle ) )
                        aTextRect = aScrollRectangle;
                    else
                        aTextRect = aPaintRectangle;

                    // setup pref size and mapmode
                    pMtf->SetPrefSize( aTextRect.GetSize() );

                    // set actual origin (mtf is at actual shape
                    // output position)
                    MapMode aLocalMapMode( aMap );
                    aLocalMapMode.SetOrigin(
                        Point( -aPaintRectangle.Left(),
                               -aPaintRectangle.Top() ) );
                    pMtf->SetPrefMapMode( aLocalMapMode );

                    pMtf->AddAction( new MetaCommentAction(
                                         "XTEXT_SCROLLRECT"_ostr, 0,
                                         reinterpret_cast<sal_uInt8 const*>(&aScrollRectangle),
                                         sizeof( tools::Rectangle ) ) );
                    pMtf->AddAction( new MetaCommentAction(
                                         "XTEXT_PAINTRECT"_ostr, 0,
                                         reinterpret_cast<sal_uInt8 const*>(&aPaintRectangle),
                                         sizeof( tools::Rectangle ) ) );

                    aGraphic = Graphic( *pMtf );

                    bSingleGraphic = true;
                }
            }
        }

        if( !bSingleGraphic )
        {
            // create a metafile for all shapes
            ScopedVclPtrInstance< VirtualDevice > aOut;

            // calculate bound rect for all shapes
            // tdf#126319 I did not convert all rendering to primitives,
            // that would be too much for this fix. But I  did so for the
            // range calculation to get a valid high quality range.
            // Based on that the conversion is reliable. With the BoundRect
            // fetched from the Metafile it was just not possible to get the
            // examples from the task handled in a way to fit all cases -
            // due to bad-quality range data from it.
            basegfx::B2DRange aBound;
            const drawinglayer::geometry::ViewInformation2D aViewInformation2D;

            {
                for( SdrObject* pObj : aShapes )
                {
                    drawinglayer::primitive2d::Primitive2DContainer aSequence;
                    pObj->GetViewContact().getViewIndependentPrimitive2DContainer(aSequence);
                    aBound.expand(aSequence.getB2DRange(aViewInformation2D));
                }
            }

            aOut->EnableOutput( false );
            aOut->SetMapMode( aMap );
            if( rSettings.mbUseHighContrast )
                aOut->SetDrawMode( aOut->GetDrawMode() | DrawModeFlags::SettingsLine | DrawModeFlags::SettingsFill | DrawModeFlags::SettingsText | DrawModeFlags::SettingsGradient );

            GDIMetaFile aMtf;
            aMtf.Clear();
            aMtf.Record( aOut );

            MapMode aOutMap( aMap );
            const Size aOnePixelInMtf(
                Application::GetDefaultDevice()->PixelToLogic(
                    Size(1, 1),
                    aMap));
            const Size aHalfPixelInMtf(
                (aOnePixelInMtf.getWidth() + 1) / 2,
                (aOnePixelInMtf.getHeight() + 1) / 2);

            // tdf#126319 Immediately add needed offset to create metafile,
            // that avoids to do it later by Metafile::Move what would be expensive
            aOutMap.SetOrigin(
                Point(
                    basegfx::fround<tools::Long>(-aBound.getMinX() - aHalfPixelInMtf.getWidth()),
                    basegfx::fround<tools::Long>(-aBound.getMinY() - aHalfPixelInMtf.getHeight()) ) );
            aOut->SetRelativeMapMode( aOutMap );

            sdr::contact::DisplayInfo aDisplayInfo;

            if(mpCurrentPage)
            {
                if(mpCurrentPage->TRG_HasMasterPage() && pPage->IsMasterPage())
                {
                    // MasterPage is processed as another page's SubContent
                    aDisplayInfo.SetProcessLayers(mpCurrentPage->TRG_GetMasterPageVisibleLayers());
                    aDisplayInfo.SetSubContentActive(true);
                }
            }

            if(!aShapes.empty())
            {
                // more effective way to paint a vector of SdrObjects. Hand over the processed page
                // to have it in the
                ImplExportCheckVisisbilityRedirector aCheckVisibilityRedirector(mpCurrentPage);
                sdr::contact::ObjectContactOfObjListPainter aMultiObjectPainter(*aOut, std::move(aShapes), mpCurrentPage);
                aMultiObjectPainter.SetViewObjectContactRedirector(&aCheckVisibilityRedirector);

                aMultiObjectPainter.ProcessDisplay(aDisplayInfo);
            }

            aMtf.Stop();
            aMtf.WindStart();

            // tdf#126319 Immediately add needed size to target's PrefSize
            // tdf#150102 Checked that in aBound is indeed the size - 1 (probably
            // due to old integer stuff using Size()/Rectangle() and getWidth()/GetWidth()
            // with the old one-less paradigm somewhere), so just correct to the
            // correct size. Be aware that checking of tdf#126319 is needed, but
            // looks good in my tests. Still: Changing the central UNO API Metafile
            // export is always a risky thing, so it will have to show if this will
            // not influence something else.
            const Size aBoundSize(
                basegfx::fround<tools::Long>(aBound.getWidth() + 1),
                basegfx::fround<tools::Long>(aBound.getHeight() + 1));
            aMtf.SetPrefMapMode( aMap );
            aMtf.SetPrefSize( aBoundSize );

            if( !bVectorType )
            {
                Size aOutSize;
                aGraphic = GetBitmapFromMetaFile( aMtf, CalcSize( rSettings.mnWidth, rSettings.mnHeight, aBoundSize, aOutSize ) );
            }
            else
            {
                aGraphic = aMtf;
            }
        }
    }

    pTempBackgroundShape.clear();

    rOutl.SetCalcFieldValueHdl( maOldCalcFieldValueHdl );

    // #i102251#
    rOutl.SetControlWord(nOldCntrl);

    rOutl.SetBackgroundColor(aOldBackColor);

    return bRet;

}

// XFilter
sal_Bool SAL_CALL GraphicExporter::filter( const Sequence< PropertyValue >& aDescriptor )
{
    ::SolarMutexGuard aGuard;

    if( maGraphic.IsNone() && nullptr == mpUnoPage )
        return false;

    if( maGraphic.IsNone() && ( nullptr == mpUnoPage->GetSdrPage() || nullptr == mpDoc ) )
        return false;

    GraphicFilter &rFilter = GraphicFilter::GetGraphicFilter();

    // get the arguments from the descriptor
    ExportSettings aSettings;
    ParseSettings(aDescriptor, aSettings);

    const sal_uInt16    nFilter = !aSettings.maMediaType.isEmpty()
                            ? rFilter.GetExportFormatNumberForMediaType( aSettings.maMediaType )
                            : rFilter.GetExportFormatNumberForShortName( aSettings.maFilterName );
    bool            bVectorType = !rFilter.IsExportPixelFormat( nFilter );

    // create the output stuff
    Graphic aGraphic = maGraphic;

    ErrCode nStatus = ERRCODE_NONE;
    if (maGraphic.IsNone())
    {
        bool bAntiAliasing = SvtOptionsDrawinglayer::IsAntiAliasing();
        AllSettings aAllSettings = Application::GetSettings();
        StyleSettings aStyleSettings = aAllSettings.GetStyleSettings();
        bool bUseFontAAFromSystem = aStyleSettings.GetUseFontAAFromSystem();
        bool bUseSubpixelAA = aStyleSettings.GetUseSubpixelAA();
        aStyleSettings.SetUseSubpixelAA(false);
        if (aSettings.meAntiAliasing != TRISTATE_INDET)
        {
            // This is safe to do globally as we own the solar mutex.
            SvtOptionsDrawinglayer::SetAntiAliasing(aSettings.meAntiAliasing == TRISTATE_TRUE, /*bTemporary*/true);
            // Opt in to have AA affect font rendering as well.
            aStyleSettings.SetUseFontAAFromSystem(false);
        }
        aAllSettings.SetStyleSettings(aStyleSettings);
        Application::SetSettings(aAllSettings, /*bTemporary*/true);
        nStatus = GetGraphic( aSettings, aGraphic, bVectorType ) ? ERRCODE_NONE : ERRCODE_GRFILTER_FILTERERROR;
        if (aSettings.meAntiAliasing != TRISTATE_INDET)
        {
            SvtOptionsDrawinglayer::SetAntiAliasing(bAntiAliasing, /*bTemporary*/true);
            aStyleSettings.SetUseFontAAFromSystem(bUseFontAAFromSystem);
        }
        aStyleSettings.SetUseSubpixelAA(bUseSubpixelAA);
        aAllSettings.SetStyleSettings(aStyleSettings);
        Application::SetSettings(aAllSettings, /*bTemporary*/true);
    }

    if( nStatus == ERRCODE_NONE )
    {
        // export graphic only if it has a size
        const Size aGraphSize( aGraphic.GetPrefSize() );
        if ( aGraphSize.IsEmpty() )
        {
            nStatus = ERRCODE_GRFILTER_FILTERERROR;
        }
        else
        {
            // now we have a graphic, so export it
            if( aSettings.mxGraphicRenderer.is() )
            {
                // render graphic directly into given renderer
                aSettings.mxGraphicRenderer->render( aGraphic.GetXGraphic() );
            }
            else if( aSettings.mxOutputStream.is() )
            {
                // TODO: Either utilize optional XSeekable functionality for the
                // SvOutputStream, or adapt the graphic filter to not seek anymore.
                SvMemoryStream aStream( 1024, 1024 );

                nStatus = rFilter.ExportGraphic( aGraphic, u"", aStream, nFilter, &aSettings.maFilterData );

                // copy temp stream to XOutputStream
                SvOutputStream aOutputStream( aSettings.mxOutputStream );
                aStream.Seek(0);
                aOutputStream.WriteStream( aStream );
            }
            else
            {
                INetURLObject aURLObject( aSettings.maURL.Complete );
                DBG_ASSERT( aURLObject.GetProtocol() != INetProtocol::NotValid, "invalid URL" );

                nStatus = XOutBitmap::ExportGraphic( aGraphic, aURLObject, rFilter, nFilter, &aSettings.maFilterData );
            }
        }
    }

    if ( aSettings.mxInteractionHandler.is() && ( nStatus != ERRCODE_NONE ) )
    {
        Any aInteraction;
        Sequence< css::uno::Reference< css::task::XInteractionContinuation > > lContinuations{
            new ::comphelper::OInteractionApprove()
        };

        GraphicFilterRequest aErrorCode;
        aErrorCode.ErrCode = sal_uInt32(nStatus);
        aInteraction <<= aErrorCode;
        aSettings.mxInteractionHandler->handle( framework::InteractionRequest::CreateRequest( aInteraction, lContinuations ) );
    }
    return nStatus == ERRCODE_NONE;
}

void SAL_CALL GraphicExporter::cancel()
{
}

// XExporter

/** the source 'document' could be a XDrawPage, a XShape or a generic XShapes */
void SAL_CALL GraphicExporter::setSourceDocument( const Reference< lang::XComponent >&&nbsp;xComponent )
{
    ::SolarMutexGuard aGuard;

    mxShapes = nullptr;
    mpUnoPage = nullptr;

    try
    {
    // any break inside this one loop while will throw an IllegalArgumentException
    do
    {
        mxPage.set( xComponent, UNO_QUERY );
        mxShapes.set( xComponent, UNO_QUERY );
        mxShape.set( xComponent, UNO_QUERY );

        // Step 1: try a generic XShapes
        if( !mxPage.is() && !mxShape.is() && mxShapes.is() )
        {
            // we do not support empty shape collections
            if( 0 == mxShapes->getCount() )
                break;

            // get first shape to detect corresponding page and model
            mxShapes->getByIndex(0) >>= mxShape;
        }
        else
        {
            mxShapes = nullptr;
        }

        // Step 2: try a shape
        if( mxShape.is() )
        {
            if (nullptr == SdrObject::getSdrObjectFromXShape(mxShape))
            {
                // This is not a Draw shape, let's see if it's a Writer one.
                uno::Reference<beans::XPropertySet> xPropertySet(mxShape, uno::UNO_QUERY);
                if (!xPropertySet.is())
                    break;
                uno::Reference<graphic::XGraphic> xGraphic(
                    xPropertySet->getPropertyValue(u"Graphic"_ustr), uno::UNO_QUERY);
                if (!xGraphic.is())
                    break;

                maGraphic = Graphic(xGraphic);
                if (!maGraphic.IsNone())
                    return;
                else
                    break;
            }

            // get page for this shape
            Reference< XChild > xChild( mxShape, UNO_QUERY );
            if( !xChild.is() )
                break;

            Reference< XInterface > xInt;
            do
            {
                xInt = xChild->getParent();
                mxPage.set( xInt, UNO_QUERY );
                if( !mxPage.is() )
                    xChild.set( xInt, UNO_QUERY );
            }
            while( !mxPage.is() && xChild.is() );

            if( !mxPage.is() )
                break;
        }

        // Step 3: check the page
        if( !mxPage.is() )
            break;

        mpUnoPage = comphelper::getFromUnoTunnel<SvxDrawPage>( mxPage );

        if( nullptr == mpUnoPage || nullptr == mpUnoPage->GetSdrPage() )
            break;

        mpDoc = &mpUnoPage->GetSdrPage()->getSdrModelFromSdrPage();

        // Step 4:  If we got a generic XShapes test all contained shapes
        //          if they belong to the same XDrawPage

        if( mxShapes.is() )
        {
            SdrPage* pPage = mpUnoPage->GetSdrPage();
            SdrObject* pObj;
            Reference< XShape > xShape;

            bool bOk = true;

            const sal_Int32 nCount = mxShapes->getCount();

            // test all but the first shape if they have the same page than
            // the first shape
            for( sal_Int32 nIndex = 1; bOk && ( nIndex < nCount ); nIndex++ )
            {
                mxShapes->getByIndex( nIndex ) >>= xShape;
                pObj = SdrObject::getSdrObjectFromXShape(xShape);
                bOk = pObj && pObj->getSdrPageFromSdrObject() == pPage;
            }

            if( !bOk )
                break;
        }

        // no errors so far
        return;
    }
    whilefalse );
    }
    catch( Exception& )
    {
    }

    throw IllegalArgumentException();
}

// XServiceInfo
OUString SAL_CALL GraphicExporter::getImplementationName(  )
{
    return u"com.sun.star.comp.Draw.GraphicExporter"_ustr;
}

sal_Bool SAL_CALL GraphicExporter::supportsService( const OUString& ServiceName )
{
    return cppu::supportsService(this, ServiceName);
}

Sequence< OUString > SAL_CALL GraphicExporter::getSupportedServiceNames(  )
{
    Sequence< OUString > aSupportedServiceNames { u"com.sun.star.drawing.GraphicExportFilter"_ustr };
    return aSupportedServiceNames;
}

// XMimeTypeInfo
sal_Bool SAL_CALL GraphicExporter::supportsMimeType( const OUString& rMimeTypeName )
{
    GraphicFilter &rFilter = GraphicFilter::GetGraphicFilter();
    sal_uInt16 nCount = rFilter.GetExportFormatCount();
    sal_uInt16 nFilter;
    for( nFilter = 0; nFilter < nCount; nFilter++ )
    {
        if( rMimeTypeName == rFilter.GetExportFormatMediaType( nFilter ) )
        {
            return true;
        }
    }

    return false;
}

Sequence< OUString > SAL_CALL GraphicExporter::getSupportedMimeTypeNames(  )
{
    GraphicFilter &rFilter = GraphicFilter::GetGraphicFilter();
    sal_uInt16 nCount = rFilter.GetExportFormatCount();
    sal_uInt16 nFilter;
    sal_uInt16 nFound = 0;

    Sequence< OUString > aSeq( nCount );
    OUString* pStr = aSeq.getArray();

    for( nFilter = 0; nFilter < nCount; nFilter++ )
    {
        OUString aMimeType( rFilter.GetExportFormatMediaType( nFilter ) );
        if( !aMimeType.isEmpty() )
        {
            *pStr++ = aMimeType;
            nFound++;
        }
    }

    if( nFound < nCount )
        aSeq.realloc( nFound );

    return aSeq;
}

}

/** creates a bitmap that is optionally transparent from a metafile
    */

BitmapEx GetBitmapFromMetaFile(const GDIMetaFile& rMtf, const Size* pSize)
{
    // use new primitive conversion tooling
    basegfx::B2DRange aRange(basegfx::B2DPoint(0.0, 0.0));
    sal_uInt32 nMaximumQuadraticPixels;

    if (pSize)
    {
        // use 100th mm for primitive bitmap converter tool, input is pixel
        // use a real OutDev to get the correct DPI, the static LogicToLogic assumes 72dpi which is wrong (!)
        const Size aSize100th(
            Application::GetDefaultDevice()->PixelToLogic(*pSize, MapMode(MapUnit::Map100thMM)));

        aRange.expand(basegfx::B2DPoint(aSize100th.Width(), aSize100th.Height()));

        // when explicitly pixels are requested from the GraphicExporter, use a *very* high limit
        // of 16gb (4096x4096 pixels)
        nMaximumQuadraticPixels = 4096 * 4096;
    }
    else
    {
        // use 100th mm for primitive bitmap converter tool
        const Size aSize100th(OutputDevice::LogicToLogic(rMtf.GetPrefSize(), rMtf.GetPrefMapMode(),
                                                         MapMode(MapUnit::Map100thMM)));

        aRange.expand(basegfx::B2DPoint(aSize100th.Width(), aSize100th.Height()));

        // limit to 2048x2048 pixels, as in ImpGraphic::getBitmap (vcl/source/gdi/impgraph.cxx):
        nMaximumQuadraticPixels = 2048 * 2048;
    }

    return convertMetafileToBitmapEx(rMtf, aRange, nMaximumQuadraticPixels);
}

Graphic SvxGetGraphicForShape( SdrObject& rShape )
{
    Graphic aGraphic;
    try
    {
        rtl::Reference< GraphicExporter > xExporter( new GraphicExporter() );
        Reference< XComponent > xComp( rShape.getUnoShape(), UNO_QUERY_THROW );
        xExporter->setSourceDocument( xComp );
        ExportSettings aSettings;
        xExporter->GetGraphic( aSettings, aGraphic, true/*bVector*/ );
    }
    catch( Exception& )
    {
        TOOLS_WARN_EXCEPTION("svx""");
    }
    return aGraphic;
}

extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
com_sun_star_comp_Draw_GraphicExporter_get_implementation(
    css::uno::XComponentContext *,
    css::uno::Sequence<css::uno::Any> const &)
{
    return cppu::acquire(new GraphicExporter);
}

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

Messung V0.5
C=92 H=97 G=94

¤ Dauer der Verarbeitung: 0.19 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.