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

Quelle  shapeimporter.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 <utility>
#include <vcl/GraphicObject.hxx>
#include <basegfx/point/b2dpoint.hxx>
#include <basegfx/polygon/b2dpolygon.hxx>
#include <cppcanvas/basegfxfactory.hxx>
#include <cppcanvas/polypolygon.hxx>
#include <com/sun/star/awt/Rectangle.hpp>
#include <com/sun/star/drawing/ColorMode.hpp>
#include <com/sun/star/text/GraphicCrop.hpp>
#include <com/sun/star/drawing/PointSequenceSequence.hpp>
#include <com/sun/star/drawing/PointSequence.hpp>
#include <com/sun/star/drawing/XLayerSupplier.hpp>
#include <com/sun/star/drawing/XLayerManager.hpp>
#include <com/sun/star/graphic/XGraphic.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>

#include "drawshape.hxx"
#include "backgroundshape.hxx"
#include "mediashape.hxx"
#include "appletshape.hxx"
#include <shapeimporter.hxx>
#include <slideshowexceptions.hxx>
#include <tools.hxx>
#include <slideshowcontext.hxx>
#include <unoviewcontainer.hxx>

#include <memory>

using namespace com::sun::star;

namespace slideshow::internal {

namespace {

std::unique_ptr<GraphicObject> importShapeGraphic(uno::Reference<beans::XPropertySet> const& xPropSet)
{
    std::unique_ptr<GraphicObject> xRet;

    uno::Reference<graphic::XGraphic> xGraphic;
    if (!getPropertyValue(xGraphic, xPropSet, u"Graphic"_ustr) || !xGraphic.is())
    {
        // no or empty property - cannot import shape graphic
        return xRet;
    }

    Graphic aGraphic(xGraphic);
    xRet.reset(new GraphicObject(std::move(aGraphic)));

    if (GraphicType::Default == xRet->GetType() || GraphicType::NONE == xRet->GetType())
    {
        xRet.reset();
    }
    return xRet;
}

/** This shape implementation just acts as a dummy for the layermanager.
    Its sole role is for hit test detection of group shapes.
*/

class ShapeOfGroup : public Shape
{
public:
    ShapeOfGroup( ShapeSharedPtr const&                      pGroupShape,
                  uno::Reference<drawing::XShape>            xShape,
                  uno::Reference<beans::XPropertySet> const& xPropSet,
                  double                                     nPrio );

    // Shape:
    virtual uno::Reference<drawing::XShape> getXShape() const override;
    virtual void addViewLayer( ViewLayerSharedPtr const& pNewLayer,
                               bool                      bRedrawLayer ) override;
    virtual bool removeViewLayer( ViewLayerSharedPtr const& pNewLayer ) override;
    virtual void clearAllViewLayers() override;
    virtual bool update() const override;
    virtual bool render() const override;
    virtual bool isContentChanged() const override;
    virtual basegfx::B2DRectangle getBounds() const override;
    virtual basegfx::B2DRectangle getDomBounds() const override;
    virtual basegfx::B2DRectangle getUpdateArea() const override;
    virtual bool isVisible() const override;
    virtual double getPriority() const override;
    virtual bool isBackgroundDetached() const override;

private:
    ShapeSharedPtr const                  mpGroupShape;
    uno::Reference<drawing::XShape> const mxShape;
    double const                          mnPrio;
    basegfx::B2DPoint                     maPosOffset;
    double                                mnWidth;
    double                                mnHeight;
};

ShapeOfGroup::ShapeOfGroup( ShapeSharedPtr const&                      pGroupShape,
                            uno::Reference<drawing::XShape>            xShape,
                            uno::Reference<beans::XPropertySet> const& xPropSet,
                            double                                     nPrio ) :
    mpGroupShape(pGroupShape),
    mxShape(std::move(xShape)),
    mnPrio(nPrio)
{
    // read bound rect
    uno::Any const aTmpRect_( xPropSet->getPropertyValue( u"BoundRect"_ustr ));
    awt::Rectangle const aTmpRect( aTmpRect_.get<awt::Rectangle>() );
    basegfx::B2DRectangle const groupPosSize( pGroupShape->getBounds() );
    maPosOffset = basegfx::B2DPoint( aTmpRect.X - groupPosSize.getMinX(),
                                     aTmpRect.Y - groupPosSize.getMinY() );
    mnWidth = aTmpRect.Width;
    mnHeight = aTmpRect.Height;
}

uno::Reference<drawing::XShape> ShapeOfGroup::getXShape() const
{
    return mxShape;
}

void ShapeOfGroup::addViewLayer( ViewLayerSharedPtr const/*pNewLayer*/,
                                 bool                      /*bRedrawLayer*/ )
{
}

bool ShapeOfGroup::removeViewLayer( ViewLayerSharedPtr const/*pNewLayer*/ )
{
    return true;
}

void ShapeOfGroup::clearAllViewLayers()
{
}

bool ShapeOfGroup::update() const
{
    return true;
}

bool ShapeOfGroup::render() const
{
    return true;
}

bool ShapeOfGroup::isContentChanged() const
{
    return false;
}

basegfx::B2DRectangle ShapeOfGroup::getBounds() const
{
    basegfx::B2DRectangle const groupPosSize( mpGroupShape->getBounds() );
    double const posX = groupPosSize.getMinX() + maPosOffset.getX();
    double const posY = groupPosSize.getMinY() + maPosOffset.getY();
    return basegfx::B2DRectangle( posX, posY, posX + mnWidth, posY + mnHeight );
}

basegfx::B2DRectangle ShapeOfGroup::getDomBounds() const
{
    return getBounds();
}

basegfx::B2DRectangle ShapeOfGroup::getUpdateArea() const
{
    return getBounds();
}

bool ShapeOfGroup::isVisible() const
{
    return mpGroupShape->isVisible();
}

double ShapeOfGroup::getPriority() const
{
    return mnPrio;
}

bool ShapeOfGroup::isBackgroundDetached() const
{
    return false;
}

// anon namespace

ShapeSharedPtr ShapeImporter::createShape(
    uno::Reference<drawing::XShape> const& xCurrShape,
    uno::Reference<beans::XPropertySet> const& xPropSet,
    std::u16string_view shapeType ) const
{
    css::uno::Reference<css::drawing::XDrawPage> xPage = mxPage;
    if (mbConvertingMasterPage && mbMasterPageObjectsOnly)
    {
        const XShapesEntry& rTop = maShapesStack.top();
        css::uno::Reference<css::drawing::XDrawPage> xMasterPage(rTop.mxShapes, uno::UNO_QUERY_THROW);
        if (xMasterPage.is())
            xPage = std::move(xMasterPage);
    }

    if( shapeType == u"com.sun.star.drawing.MediaShape" || shapeType == u"com.sun.star.presentation.MediaShape" )
    {
        // Media shape (video etc.). This is a special object
        return createMediaShape(xCurrShape,
                                mnAscendingPrio,
                                mrContext);
    }
    else if( shapeType == u"com.sun.star.drawing.AppletShape" )
    {
        // PropertyValues to copy from XShape to applet
        static const char* aPropertyValues[] =
            {
                "AppletCodeBase",
                "AppletName",
                "AppletCode",
                "AppletCommands",
                "AppletIsScript"
            };

        // (Java)Applet shape. This is a special object
        return createAppletShape( xCurrShape,
                                  mnAscendingPrio,
                                  u"com.sun.star.comp.sfx2.AppletObject"_ustr,
                                  aPropertyValues,
                                  SAL_N_ELEMENTS(aPropertyValues),
                                  mrContext );
    }
    else if( shapeType == u"com.sun.star.drawing.OLE2Shape" || shapeType == u"com.sun.star.presentation.OLE2Shape" )
    {
        // #i46224# Mark OLE shapes as foreign content - scan them for
        // unsupported actions, and fallback to bitmap, if necessary
        return DrawShape::create( xCurrShape,
                                  xPage,
                                  mnAscendingPrio,
                                  true,
                                  mrContext );
    }
    else if( shapeType == u"com.sun.star.drawing.GraphicObjectShape" || shapeType == u"com.sun.star.presentation.GraphicObjectShape" )
    {
        // to get hold of GIF animations, inspect Graphic
        // objects more thoroughly (the plain-jane shape
        // metafile of course would only contain the first
        // animation frame)
        std::unique_ptr<GraphicObject> xGraphicObject(importShapeGraphic(xPropSet));
        if (!xGraphicObject)
            return ShapeSharedPtr(); // error loading graphic -
                                     // no placeholders in
                                     // slideshow

        if (!xGraphicObject->IsAnimated())
        {
            // no animation - simply utilize plain draw shape import

            // import shape as bitmap - either it's a bitmap
            // anyway, or it's a metafile, which currently the
            // metafile renderer might not display correctly.
            return DrawShape::create( xCurrShape,
                                      xPage,
                                      mnAscendingPrio,
                                      true,
                                      mrContext );
        }


        // now extract relevant shape attributes via API


        drawing::ColorMode eColorMode( drawing::ColorMode_STANDARD );
        sal_Int16 nLuminance(0);
        sal_Int16 nContrast(0);
        sal_Int16 nRed(0);
        sal_Int16 nGreen(0);
        sal_Int16 nBlue(0);
        double    nGamma(1.0);
        sal_Int16 nTransparency(0);
        sal_Int32 nRotation(0);

        getPropertyValue( eColorMode, xPropSet, u"GraphicColorMode"_ustr );
        getPropertyValue( nLuminance, xPropSet, u"AdjustLuminance"_ustr );
        getPropertyValue( nContrast, xPropSet, u"AdjustContrast"_ustr );
        getPropertyValue( nRed, xPropSet, u"AdjustRed"_ustr );
        getPropertyValue( nGreen, xPropSet, u"AdjustGreen"_ustr );
        getPropertyValue( nBlue, xPropSet, u"AdjustBlue"_ustr );
        getPropertyValue( nGamma, xPropSet, u"Gamma"_ustr );
        getPropertyValue( nTransparency, xPropSet, u"Transparency"_ustr );
        getPropertyValue( nRotation, xPropSet, u"RotateAngle"_ustr );

        GraphicAttr aGraphAttrs;
        aGraphAttrs.SetDrawMode( static_cast<GraphicDrawMode>(eColorMode) );
        aGraphAttrs.SetLuminance( nLuminance );
        aGraphAttrs.SetContrast( nContrast );
        aGraphAttrs.SetChannelR( nRed );
        aGraphAttrs.SetChannelG( nGreen );
        aGraphAttrs.SetChannelB( nBlue );
        aGraphAttrs.SetGamma( nGamma );
        aGraphAttrs.SetAlpha( 255 - static_cast<sal_uInt8>(nTransparency) );
        aGraphAttrs.SetRotation( Degree10(static_cast<sal_Int16>(nRotation*10)) );

        text::GraphicCrop aGraphCrop;
        if( getPropertyValue( aGraphCrop, xPropSet, u"GraphicCrop"_ustr ))
        {
            aGraphAttrs.SetCrop( aGraphCrop.Left,
                                 aGraphCrop.Top,
                                 aGraphCrop.Right,
                                 aGraphCrop.Bottom );
        }

        // fetch readily transformed and color-modified
        // graphic

        std::shared_ptr<Graphic> pGraphic
            = ::std::make_shared<Graphic>(xGraphicObject->GetTransformedGraphic(
                xGraphicObject->GetPrefSize(),
                xGraphicObject->GetPrefMapMode(),
                aGraphAttrs ) );

        return DrawShape::create( xCurrShape,
                                  xPage,
                                  mnAscendingPrio,
                                  std::move(pGraphic),
                                  mrContext );
    }
    else
    {
        return DrawShape::create( xCurrShape,
                                  xPage,
                                  mnAscendingPrio,
                                  false,
                                  mrContext );
    }
}

bool ShapeImporter::isSkip(
    uno::Reference<beans::XPropertySet> const& xPropSet,
    std::u16string_view shapeType,
    uno::Reference< drawing::XLayer> const& xLayer )
{
    // skip empty presentation objects:
    bool bEmpty = false;
    if( getPropertyValue( bEmpty,
                          xPropSet,
                          u"IsEmptyPresentationObject"_ustr) &&
        bEmpty )
    {
        // check object have fill or linestyle, if have, it should be visible
        drawing::FillStyle aFillStyle{ drawing::FillStyle_NONE };
        if (getPropertyValue(aFillStyle,
            xPropSet, u"FillStyle"_ustr) &&
            aFillStyle != drawing::FillStyle_NONE)
        {
            bEmpty = false;
        }

        drawing::LineStyle aLineStyle{ drawing::LineStyle_NONE };
        if (bEmpty && getPropertyValue(aLineStyle,
            xPropSet, u"LineStyle"_ustr) &&
            aLineStyle != drawing::LineStyle_NONE)
        {
            bEmpty = false;
        }

        if (bEmpty)
            return true;
    }

    //skip shapes which corresponds to annotations
    if(xLayer.is())
    {
        OUString layerName;
        const uno::Any a(xLayer->getPropertyValue(u"Name"_ustr) );
        bool const bRet = (a >>= layerName);
        if(bRet)
        {
            if( layerName == "DrawnInSlideshow" )
            {
                //Transform shapes into PolyPolygons
                importPolygons(xPropSet);

                return true;
            }
        }
    }

    // don't export presentation placeholders on masterpage
    // they can be non empty when user edits the default texts
    if(mbConvertingMasterPage)
    {
        if( shapeType == u"com.sun.star.presentation.TitleTextShape" || shapeType == u"com.sun.star.presentation.OutlinerShape" )
        {
            return true;
        }
        if( mbTextFieldsOnly )
        {
            if( !( shapeType == u"com.sun.star.presentation.SlideNumberShape" ||
                   shapeType == u"com.sun.star.presentation.FooterShape" ||
                   shapeType == u"com.sun.star.presentation.DateTimeShape" ) )
            {
                return true;
            }
        }
    }
    return false;
}


void ShapeImporter::importPolygons(uno::Reference<beans::XPropertySet> const& xPropSet) {

    drawing::PointSequenceSequence aRetval;
    sal_Int32           nLineColor=0;
    double              fLineWidth;
    getPropertyValue( aRetval, xPropSet, u"PolyPolygon"_ustr );
    getPropertyValue( nLineColor, xPropSet, u"LineColor"_ustr );
    getPropertyValue( fLineWidth, xPropSet, u"LineWidth"_ustr );

    const drawing::PointSequence* pOuterSequence = aRetval.getArray();

    ::basegfx::B2DPolygon aPoly;
    basegfx::B2DPoint aPoint;
    forconst awt::Point& rPoint : *pOuterSequence )
    {
        aPoint.setX(rPoint.X);
        aPoint.setY(rPoint.Y);
        aPoly.append( aPoint );
    }
    forconst auto& pView : mrContext.mrViewContainer )
    {
        ::cppcanvas::PolyPolygonSharedPtr pPolyPoly(
            ::cppcanvas::BaseGfxFactory::createPolyPolygon( pView->getCanvas(),
                                                            aPoly ) );
        if( pPolyPoly )
        {
                pPolyPoly->setRGBALineColor( unoColor2RGBColor( nLineColor ).getIntegerColor() );
                pPolyPoly->setStrokeWidth(fLineWidth);
                pPolyPoly->draw();
                pPolyPoly->setIsFromPreviousSlideshow(true);
                maPolygons.push_back(pPolyPoly);
        }
    }
}

ShapeSharedPtr ShapeImporter::importBackgroundShape() // throw (ShapeLoadFailedException)
{
    if( maShapesStack.empty() )
        throw ShapeLoadFailedException();

    XShapesEntry& rTop = maShapesStack.top();
    ShapeSharedPtr pBgShape(
        createBackgroundShape(mxPage,
                              uno::Reference<drawing::XDrawPage>(
                                  rTop.mxShapes,
                                  uno::UNO_QUERY_THROW),
                              mrContext) );
    mnAscendingPrio += 1.0;

    return pBgShape;
}

ShapeSharedPtr ShapeImporter::importShape() // throw (ShapeLoadFailedException)
{
    ShapeSharedPtr pRet;
    bool bIsGroupShape = false;

    while( !maShapesStack.empty() && !pRet )
    {
        XShapesEntry& rTop = maShapesStack.top();
        if( rTop.mnPos < rTop.mnCount )
        {
            uno::Reference<drawing::XShape> const xCurrShape(
                rTop.mxShapes->getByIndex( rTop.mnPos ), uno::UNO_QUERY );
            ++rTop.mnPos;
            uno::Reference<beans::XPropertySet> xPropSet(
                xCurrShape, uno::UNO_QUERY );
            if( !xPropSet.is() )
            {
                // we definitely need the properties of
                // the shape here. This will also fail,
                // if getByIndex did not return a valid
                // shape
                throw ShapeLoadFailedException();
            }

            //Retrieve the layer for the current shape
            uno::Reference< drawing::XLayer > xDrawnInSlideshow;

            uno::Reference< drawing::XLayerSupplier > xLayerSupplier(mxPagesSupplier, uno::UNO_QUERY);
            if(xLayerSupplier.is())
            {
                uno::Reference< container::XNameAccess > xNameAccess = xLayerSupplier->getLayerManager();

                uno::Reference< drawing::XLayerManager > xLayerManager(xNameAccess, uno::UNO_QUERY);

                xDrawnInSlideshow = xLayerManager->getLayerForShape(xCurrShape);
            }

            OUString const shapeType( xCurrShape->getShapeType());

            // is this shape presentation-invisible?
            if( !isSkip(xPropSet, shapeType, xDrawnInSlideshow) )
            {
                bIsGroupShape = shapeType == "com.sun.star.drawing.GroupShape";

                if( rTop.mpGroupShape ) // in group particle mode?
                {
                    pRet = std::make_shared<ShapeOfGroup>(
                                    rTop.mpGroupShape /* container shape */,
                                    xCurrShape, xPropSet,
                                    mnAscendingPrio );
                }
                else
                {
                    pRet = createShape( xCurrShape, xPropSet, shapeType );
                }
                mnAscendingPrio += 1.0;
            }
        }
        if( rTop.mnPos >= rTop.mnCount )
        {
            // group or top-level shapes finished:
            maShapesStack.pop();
        }
        if( bIsGroupShape && pRet )
        {
            // push new group on the stack: group traversal
            maShapesStack.push( XShapesEntry( pRet ) );
        }
    }

    return pRet;
}

bool ShapeImporter::isImportDone() const
{
    return maShapesStack.empty();
}

const PolyPolygonVector& ShapeImporter::getPolygons() const
{
    return maPolygons;
}

ShapeImporter::ShapeImporter( uno::Reference<drawing::XDrawPage> const&          xPage,
                              uno::Reference<drawing::XDrawPage>                 xActualPage,
                              uno::Reference<drawing::XDrawPagesSupplier>        xPagesSupplier,
                              const SlideShowContext&                            rContext,
                              sal_Int32                                          nOrdNumStart,
                              bool                                               bConvertingMasterPage ) :
    mxPage(std::move( xActualPage )),
    mxPagesSupplier(std::move( xPagesSupplier )),
    mrContext( rContext ),
    maPolygons(),
    maShapesStack(),
    mnAscendingPrio( nOrdNumStart ),
    mbConvertingMasterPage( bConvertingMasterPage ),
    mbMasterPageObjectsOnly( false ),
    mbTextFieldsOnly( false )
{
    uno::Reference<drawing::XShapes> const xShapes(
        xPage, uno::UNO_QUERY_THROW );
    maShapesStack.push( XShapesEntry(xShapes) );
}

// namespace presentation

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

Messung V0.5
C=93 H=99 G=95

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