LCOV - code coverage report
Current view: top level - oox/source/vml - vmlshape.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 531 614 86.5 %
Date: 2015-06-13 12:38:46 Functions: 54 56 96.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <algorithm>
      21             : #include <boost/optional.hpp>
      22             : 
      23             : #include "oox/vml/vmlshape.hxx"
      24             : #include <vcl/wmf.hxx>
      25             : 
      26             : #include <com/sun/star/beans/PropertyValues.hpp>
      27             : #include <com/sun/star/beans/XPropertySet.hpp>
      28             : #include <com/sun/star/awt/XControlModel.hpp>
      29             : #include <com/sun/star/drawing/PointSequenceSequence.hpp>
      30             : #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
      31             : #include <com/sun/star/drawing/TextVerticalAdjust.hpp>
      32             : #include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp>
      33             : #include <com/sun/star/drawing/XShapes.hpp>
      34             : #include <com/sun/star/drawing/XControlShape.hpp>
      35             : #include <com/sun/star/graphic/XGraphic.hpp>
      36             : #include <com/sun/star/table/BorderLine2.hpp>
      37             : #include <com/sun/star/text/HoriOrientation.hpp>
      38             : #include <com/sun/star/text/RelOrientation.hpp>
      39             : #include <com/sun/star/text/SizeType.hpp>
      40             : #include <com/sun/star/text/VertOrientation.hpp>
      41             : #include <com/sun/star/text/WrapTextMode.hpp>
      42             : #include <com/sun/star/text/XTextContent.hpp>
      43             : #include <com/sun/star/text/XTextDocument.hpp>
      44             : #include <com/sun/star/text/XTextFrame.hpp>
      45             :  #include <com/sun/star/lang/XServiceInfo.hpp>
      46             : #include <com/sun/star/text/TextContentAnchorType.hpp>
      47             : #include <rtl/math.hxx>
      48             : #include <rtl/ustrbuf.hxx>
      49             : #include <svx/svdtrans.hxx>
      50             : #include "oox/drawingml/shapepropertymap.hxx"
      51             : #include "oox/helper/graphichelper.hxx"
      52             : #include "oox/helper/propertyset.hxx"
      53             : #include "oox/ole/axcontrol.hxx"
      54             : #include "oox/ole/axcontrolfragment.hxx"
      55             : #include "oox/ole/oleobjecthelper.hxx"
      56             : #include "oox/vml/vmldrawing.hxx"
      57             : #include "oox/vml/vmlshapecontainer.hxx"
      58             : #include "oox/vml/vmltextbox.hxx"
      59             : #include "oox/core/xmlfilterbase.hxx"
      60             : #include "oox/helper/containerhelper.hxx"
      61             : #include "svx/EnhancedCustomShapeTypeNames.hxx"
      62             : #include <svx/unoapi.hxx>
      63             : #include <svx/svdoashp.hxx>
      64             : 
      65             : using ::com::sun::star::beans::XPropertySet;
      66             : using ::com::sun::star::uno::Any;
      67             : 
      68             : using namespace ::com::sun::star;
      69             : using namespace ::com::sun::star::text;
      70             : 
      71             : namespace oox {
      72             : namespace vml {
      73             : 
      74             : using namespace ::com::sun::star;
      75             : using namespace ::com::sun::star::drawing;
      76             : using namespace ::com::sun::star::graphic;
      77             : using namespace ::com::sun::star::uno;
      78             : using namespace ::com::sun::star::io;
      79             : 
      80             : using ::oox::core::XmlFilterBase;
      81             : 
      82             : namespace {
      83             : 
      84             : const sal_Int32 VML_SHAPETYPE_PICTUREFRAME  = 75;
      85             : const sal_Int32 VML_SHAPETYPE_HOSTCONTROL   = 201;
      86             : 
      87       15674 : awt::Point lclGetAbsPoint( const awt::Point& rRelPoint, const awt::Rectangle& rShapeRect, const awt::Rectangle& rCoordSys )
      88             : {
      89       15674 :     double fWidthRatio = static_cast< double >( rShapeRect.Width ) / rCoordSys.Width;
      90       15674 :     double fHeightRatio = static_cast< double >( rShapeRect.Height ) / rCoordSys.Height;
      91       15674 :     awt::Point aAbsPoint;
      92       15674 :     aAbsPoint.X = static_cast< sal_Int32 >( rShapeRect.X + fWidthRatio * (rRelPoint.X - rCoordSys.X) + 0.5 );
      93       15674 :     aAbsPoint.Y = static_cast< sal_Int32 >( rShapeRect.Y + fHeightRatio * (rRelPoint.Y - rCoordSys.Y) + 0.5 );
      94       15674 :     return aAbsPoint;
      95             : }
      96             : 
      97         600 : awt::Rectangle lclGetAbsRect( const awt::Rectangle& rRelRect, const awt::Rectangle& rShapeRect, const awt::Rectangle& rCoordSys )
      98             : {
      99         600 :     double fWidthRatio = static_cast< double >( rShapeRect.Width ) / rCoordSys.Width;
     100         600 :     double fHeightRatio = static_cast< double >( rShapeRect.Height ) / rCoordSys.Height;
     101         600 :     awt::Rectangle aAbsRect;
     102         600 :     aAbsRect.X = static_cast< sal_Int32 >( rShapeRect.X + fWidthRatio * (rRelRect.X - rCoordSys.X) + 0.5 );
     103         600 :     aAbsRect.Y = static_cast< sal_Int32 >( rShapeRect.Y + fHeightRatio * (rRelRect.Y - rCoordSys.Y) + 0.5 );
     104         600 :     aAbsRect.Width = static_cast< sal_Int32 >( fWidthRatio * rRelRect.Width + 0.5 );
     105         600 :     aAbsRect.Height = static_cast< sal_Int32 >( fHeightRatio * rRelRect.Height + 0.5 );
     106         600 :     return aAbsRect;
     107             : }
     108             : 
     109             : } // namespace
     110             : 
     111        1168 : ShapeTypeModel::ShapeTypeModel():
     112             :     mbAutoHeight( false ),
     113        1168 :     mbVisible( true )
     114             : {
     115        1168 : }
     116             : 
     117         307 : void ShapeTypeModel::assignUsed( const ShapeTypeModel& rSource )
     118             : {
     119         307 :     moShapeType.assignIfUsed( rSource.moShapeType );
     120         307 :     moCoordPos.assignIfUsed( rSource.moCoordPos );
     121         307 :     moCoordSize.assignIfUsed( rSource.moCoordSize );
     122             :     /*  The style properties position, left, top, width, height, margin-left,
     123             :         margin-top are not derived from shape template to shape. */
     124         307 :     maStrokeModel.assignUsed( rSource.maStrokeModel );
     125         307 :     maFillModel.assignUsed( rSource.maFillModel );
     126         307 :     moGraphicPath.assignIfUsed( rSource.moGraphicPath );
     127         307 :     moGraphicTitle.assignIfUsed( rSource.moGraphicTitle );
     128         307 : }
     129             : 
     130        1168 : ShapeType::ShapeType( Drawing& rDrawing ) :
     131        1168 :     mrDrawing( rDrawing )
     132             : {
     133        1168 : }
     134             : 
     135        1369 : ShapeType::~ShapeType()
     136             : {
     137        1369 : }
     138             : 
     139        1857 : sal_Int32 ShapeType::getShapeType() const
     140             : {
     141        1857 :     return maTypeModel.moShapeType.get( 0 );
     142             : }
     143             : 
     144         583 : OUString ShapeType::getGraphicPath() const
     145             : {
     146         583 :     return maTypeModel.moGraphicPath.get( OUString() );
     147             : }
     148             : 
     149         377 : awt::Rectangle ShapeType::getCoordSystem() const
     150             : {
     151         377 :     Int32Pair aCoordPos = maTypeModel.moCoordPos.get( Int32Pair( 0, 0 ) );
     152         377 :     Int32Pair aCoordSize = maTypeModel.moCoordSize.get( Int32Pair( 1000, 1000 ) );
     153         377 :     if( aCoordSize.first == 0 )
     154           0 :         aCoordSize.first = 1;
     155         377 :     if( aCoordSize.second == 0 )
     156           0 :         aCoordSize.second = 1;
     157         377 :     return awt::Rectangle( aCoordPos.first, aCoordPos.second, aCoordSize.first, aCoordSize.second );
     158             : }
     159             : 
     160         964 : awt::Rectangle ShapeType::getRectangle( const ShapeParentAnchor* pParentAnchor ) const
     161             : {
     162             :     return pParentAnchor ?
     163        2164 :         lclGetAbsRect( getRelRectangle(), pParentAnchor->maShapeRect, pParentAnchor->maCoordSys ) :
     164        2892 :         getAbsRectangle();
     165             : }
     166             : 
     167         362 : awt::Rectangle ShapeType::getAbsRectangle() const
     168             : {
     169         362 :     const GraphicHelper& rGraphicHelper = mrDrawing.getFilter().getGraphicHelper();
     170             : 
     171         362 :     sal_Int32 nWidth = ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maWidth, 0, true, true );
     172         362 :     if ( nWidth == 0 )
     173          12 :         nWidth = 1;
     174             : 
     175         362 :     sal_Int32 nHeight = ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maHeight, 0, false, true );
     176         362 :     if ( nHeight == 0 )
     177           3 :         nHeight = 1;
     178             : 
     179         362 :     sal_Int32 nLeft = ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maLeft, 0, true, true )
     180         362 :         + ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maMarginLeft, 0, true, true );
     181         362 :     if (nLeft == 0 && maTypeModel.maPosition == "absolute")
     182          57 :         nLeft = 1;
     183             : 
     184             :     return awt::Rectangle(
     185             :         nLeft,
     186         362 :         ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maTop, 0, false, true ) + ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maTypeModel.maMarginTop, 0, false, true ),
     187         362 :         nWidth, nHeight );
     188             : }
     189             : 
     190         597 : awt::Rectangle ShapeType::getRelRectangle() const
     191             : {
     192         597 :     sal_Int32 nWidth = maTypeModel.maWidth.toInt32();
     193         597 :     if ( nWidth == 0 )
     194           0 :         nWidth = 1;
     195             : 
     196         597 :     sal_Int32 nHeight = maTypeModel.maHeight.toInt32();
     197         597 :     if ( nHeight == 0 )
     198           0 :         nHeight = 1;
     199             : 
     200             :     return awt::Rectangle(
     201         597 :         maTypeModel.maLeft.toInt32(),
     202         597 :         maTypeModel.maTop.toInt32(),
     203        1194 :         nWidth, nHeight );
     204             : }
     205             : 
     206           3 : ClientData::ClientData() :
     207             :     mnObjType( XML_TOKEN_INVALID ),
     208             :     mnTextHAlign( XML_Left ),
     209             :     mnTextVAlign( XML_Top ),
     210             :     mnCol( -1 ),
     211             :     mnRow( -1 ),
     212             :     mnChecked( VML_CLIENTDATA_UNCHECKED ),
     213             :     mnDropStyle( XML_Combo ),
     214             :     mnDropLines( 1 ),
     215             :     mnVal( 0 ),
     216             :     mnMin( 0 ),
     217             :     mnMax( 0 ),
     218             :     mnInc( 0 ),
     219             :     mnPage( 0 ),
     220             :     mnSelType( XML_Single ),
     221             :     mnVTEdit( VML_CLIENTDATA_TEXT ),
     222             :     mbPrintObject( true ),
     223             :     mbVisible( false ),
     224             :     mbDde( false ),
     225             :     mbNo3D( false ),
     226             :     mbNo3D2( false ),
     227             :     mbMultiLine( false ),
     228             :     mbVScroll( false ),
     229           3 :     mbSecretEdit( false )
     230             : {
     231           3 : }
     232             : 
     233         967 : ShapeModel::ShapeModel()
     234             : {
     235         967 : }
     236             : 
     237         967 : ShapeModel::~ShapeModel()
     238             : {
     239         967 : }
     240             : 
     241         262 : TextBox& ShapeModel::createTextBox(ShapeTypeModel& rModel)
     242             : {
     243         262 :     mxTextBox.reset( new TextBox(rModel) );
     244         262 :     return *mxTextBox;
     245             : }
     246             : 
     247           3 : ClientData& ShapeModel::createClientData()
     248             : {
     249           3 :     mxClientData.reset( new ClientData );
     250           3 :     return *mxClientData;
     251             : }
     252             : 
     253         967 : ShapeBase::ShapeBase( Drawing& rDrawing ) :
     254         967 :     ShapeType( rDrawing )
     255             : {
     256         967 : }
     257             : 
     258         967 : void ShapeBase::finalizeFragmentImport()
     259             : {
     260         967 :     if( maShapeModel.maType.getLength() > 1 )
     261             :     {
     262         328 :         OUString aType = maShapeModel.maType;
     263         328 :         if (aType[ 0 ] == '#')
     264         317 :             aType = aType.copy(1);
     265         328 :         if( const ShapeType* pShapeType = mrDrawing.getShapes().getShapeTypeById( aType, true ) )
     266         307 :             maTypeModel.assignUsed( pShapeType->getTypeModel() );
     267             :     }
     268         967 : }
     269             : 
     270         888 : OUString ShapeBase::getShapeName() const
     271             : {
     272         888 :     if( !maTypeModel.maShapeName.isEmpty() )
     273         345 :         return maTypeModel.maShapeName;
     274             : 
     275         543 :     OUString aBaseName = mrDrawing.getShapeBaseName( *this );
     276         543 :     if( !aBaseName.isEmpty() )
     277             :     {
     278           1 :         sal_Int32 nShapeIdx = mrDrawing.getLocalShapeIndex( getShapeId() );
     279           1 :         if( nShapeIdx > 0 )
     280           1 :             return OUStringBuffer( aBaseName ).append( ' ' ).append( nShapeIdx ).makeStringAndClear();
     281             :     }
     282             : 
     283         542 :     return OUString();
     284             : }
     285             : 
     286          28 : const ShapeType* ShapeBase::getChildTypeById( const OUString& ) const
     287             : {
     288          28 :     return 0;
     289             : }
     290             : 
     291           0 : const ShapeBase* ShapeBase::getChildById( const OUString& ) const
     292             : {
     293           0 :     return 0;
     294             : }
     295             : 
     296         967 : Reference< XShape > ShapeBase::convertAndInsert( const Reference< XShapes >& rxShapes, const ShapeParentAnchor* pParentAnchor ) const
     297             : {
     298         967 :     Reference< XShape > xShape;
     299         967 :     if( mrDrawing.isShapeSupported( *this ) )
     300             :     {
     301             :         /*  Calculate shape rectangle. Applications may do something special
     302             :             according to some imported shape client data (e.g. Excel cell anchor). */
     303         965 :         awt::Rectangle aShapeRect = calcShapeRectangle( pParentAnchor );
     304             : 
     305         965 :         if( ((aShapeRect.Width > 0) || (aShapeRect.Height > 0)) && rxShapes.is() )
     306             :         {
     307         965 :             xShape = implConvertAndInsert( rxShapes, aShapeRect );
     308         965 :             if( xShape.is() )
     309             :             {
     310             :                 // set imported or generated shape name (not supported by form controls)
     311         963 :                 PropertySet aShapeProp( xShape );
     312         963 :                 if( aShapeProp.hasProperty( PROP_Name ) )
     313         887 :                     aShapeProp.setProperty( PROP_Name, getShapeName() );
     314        1926 :                 uno::Reference< lang::XServiceInfo > xSInfo( xShape, uno::UNO_QUERY_THROW );
     315         963 :                 if (xSInfo->supportsService("com.sun.star.text.TextFrame"))
     316             :                 {
     317          75 :                     uno::Sequence<beans::PropertyValue> aGrabBag;
     318         150 :                     uno::Reference<beans::XPropertySet> propertySet (xShape, uno::UNO_QUERY);
     319          75 :                     propertySet->getPropertyValue("FrameInteropGrabBag") >>= aGrabBag;
     320          75 :                     sal_Int32 length = aGrabBag.getLength();
     321             : 
     322          75 :                     aGrabBag.realloc( length+1 );
     323          75 :                     aGrabBag[length].Name = "VML-Z-ORDER";
     324          75 :                     aGrabBag[length].Value = uno::makeAny( maTypeModel.maZIndex.toInt32() );
     325          75 :                     if(!(maTypeModel.maRotation).isEmpty())
     326             :                     {
     327           3 :                         aGrabBag.realloc( length+2 );
     328           3 :                         aGrabBag[length+1].Name = "mso-rotation-angle";
     329           3 :                         aGrabBag[length+1].Value = uno::makeAny(sal_Int32(NormAngle360((maTypeModel.maRotation.toInt32()) * -100)));
     330             :                     }
     331          75 :                     propertySet->setPropertyValue( "FrameInteropGrabBag", uno::makeAny(aGrabBag) );
     332          75 :                     sal_Int32 backColorTransparency = 0;
     333          75 :                     propertySet->getPropertyValue("BackColorTransparency")
     334          75 :                         >>= backColorTransparency;
     335         113 :                     if (propertySet->getPropertyValue("FillStyle") == FillStyle_NONE &&
     336          38 :                         backColorTransparency == 100)
     337             :                     {
     338             :                         // If there is no fill, the Word default is 100% transparency.
     339          38 :                         propertySet->setPropertyValue("FillTransparence", makeAny(sal_Int16(100)));
     340          75 :                     }
     341             :                 }
     342             :                 else
     343             :                 {
     344         888 :                     if( maTypeModel.maZIndex.toInt32() )
     345             :                     {
     346          77 :                         uno::Sequence<beans::PropertyValue> aGrabBag;
     347         154 :                         uno::Reference<beans::XPropertySet> propertySet (xShape, uno::UNO_QUERY);
     348          77 :                         propertySet->getPropertyValue("InteropGrabBag") >>= aGrabBag;
     349          77 :                         sal_Int32 length = aGrabBag.getLength();
     350          77 :                         aGrabBag.realloc( length+1 );
     351          77 :                         aGrabBag[length].Name = "VML-Z-ORDER";
     352          77 :                         aGrabBag[length].Value = uno::makeAny( maTypeModel.maZIndex.toInt32() );
     353         154 :                         propertySet->setPropertyValue( "InteropGrabBag", uno::makeAny(aGrabBag) );
     354             :                     }
     355             :                 }
     356        1926 :                 Reference< XControlShape > xControlShape( xShape, uno::UNO_QUERY );
     357         963 :                 if ( xControlShape.is() && !getTypeModel().mbVisible )
     358             :                 {
     359           0 :                     PropertySet aControlShapeProp( xControlShape->getControl() );
     360           0 :                     aControlShapeProp.setProperty( PROP_EnableVisible, uno::makeAny( sal_False ) );
     361             :                 }
     362             :                 /*  Notify the drawing that a new shape has been inserted. For
     363             :                     convenience, pass the rectangle that contains position and
     364             :                     size of the shape. */
     365         963 :                 bool bGroupChild = pParentAnchor != 0;
     366        1926 :                 mrDrawing.notifyXShapeInserted( xShape, aShapeRect, *this, bGroupChild );
     367             :             }
     368             :         }
     369             :         else
     370             :             SAL_WARN("oox", "not converting shape, as calculated rectangle is empty");
     371             :     }
     372         967 :     return xShape;
     373             : }
     374             : 
     375           2 : void ShapeBase::convertFormatting( const Reference< XShape >& rxShape, const ShapeParentAnchor* pParentAnchor ) const
     376             : {
     377           2 :     if( rxShape.is() )
     378             :     {
     379             :         /*  Calculate shape rectangle. Applications may do something special
     380             :             according to some imported shape client data (e.g. Excel cell anchor). */
     381           2 :         awt::Rectangle aShapeRect = calcShapeRectangle( pParentAnchor );
     382             : 
     383             :         // convert the shape, if the calculated rectangle is not empty
     384           2 :         if( (aShapeRect.Width > 0) || (aShapeRect.Height > 0) )
     385             :         {
     386           2 :             rxShape->setPosition( awt::Point( aShapeRect.X, aShapeRect.Y ) );
     387           2 :             rxShape->setSize( awt::Size( aShapeRect.Width, aShapeRect.Height ) );
     388           2 :             convertShapeProperties( rxShape );
     389             :         }
     390             :     }
     391           2 : }
     392             : 
     393             : // protected ------------------------------------------------------------------
     394             : 
     395         967 : awt::Rectangle ShapeBase::calcShapeRectangle( const ShapeParentAnchor* pParentAnchor ) const
     396             : {
     397             :     /*  Calculate shape rectangle. Applications may do something special
     398             :         according to some imported shape client data (e.g. Excel cell anchor). */
     399         967 :     awt::Rectangle aShapeRect;
     400         967 :     const ClientData* pClientData = getClientData();
     401         967 :     if( !pClientData || !mrDrawing.convertClientAnchor( aShapeRect, pClientData->maAnchor ) )
     402         964 :         aShapeRect = getRectangle( pParentAnchor );
     403         967 :     return aShapeRect;
     404             : }
     405             : 
     406         897 : void ShapeBase::convertShapeProperties( const Reference< XShape >& rxShape ) const
     407             : {
     408         897 :     ::oox::drawingml::ShapePropertyMap aPropMap( mrDrawing.getFilter().getModelObjectHelper() );
     409         897 :     const GraphicHelper& rGraphicHelper = mrDrawing.getFilter().getGraphicHelper();
     410         897 :     maTypeModel.maStrokeModel.pushToPropMap( aPropMap, rGraphicHelper );
     411         897 :     maTypeModel.maFillModel.pushToPropMap( aPropMap, rGraphicHelper );
     412             : 
     413        1794 :     uno::Reference<lang::XServiceInfo> xSInfo(rxShape, uno::UNO_QUERY_THROW);
     414         897 :     if (xSInfo->supportsService("com.sun.star.text.TextFrame"))
     415             :     {
     416             :         // Any other service supporting the ShadowFormat property?
     417          75 :         maTypeModel.maShadowModel.pushToPropMap(aPropMap, rGraphicHelper);
     418             :         // TextFrames have BackColor, not FillColor
     419          75 :         if (aPropMap.hasProperty(PROP_FillColor))
     420             :         {
     421          31 :             aPropMap.setAnyProperty(PROP_BackColor, aPropMap.getProperty(PROP_FillColor));
     422          31 :             aPropMap.erase(PROP_FillColor);
     423             :         }
     424             :         // TextFrames have BackColorTransparency, not FillTransparence
     425          75 :         if (aPropMap.hasProperty(PROP_FillTransparence))
     426             :         {
     427           0 :             aPropMap.setAnyProperty(PROP_BackColorTransparency, aPropMap.getProperty(PROP_FillTransparence));
     428           0 :             aPropMap.erase(PROP_FillTransparence);
     429             :         }
     430             :         // And no LineColor property; individual borders can have colors and widths
     431          75 :         boost::optional<sal_Int32> oLineWidth;
     432          75 :         if (maTypeModel.maStrokeModel.moWeight.has())
     433          16 :             oLineWidth.reset(ConversionHelper::decodeMeasureToHmm(rGraphicHelper, maTypeModel.maStrokeModel.moWeight.get(), 0, false, false));
     434          75 :         if (aPropMap.hasProperty(PROP_LineColor))
     435             :         {
     436          27 :             uno::Reference<beans::XPropertySet> xPropertySet(rxShape, uno::UNO_QUERY);
     437             :             static const sal_Int32 aBorders[] = {
     438             :                 PROP_TopBorder, PROP_LeftBorder, PROP_BottomBorder, PROP_RightBorder
     439             :             };
     440         135 :             for (unsigned int i = 0; i < SAL_N_ELEMENTS(aBorders); ++i)
     441             :             {
     442         108 :                 table::BorderLine2 aBorderLine = xPropertySet->getPropertyValue(PropertyMap::getPropertyName(aBorders[i])).get<table::BorderLine2>();
     443         108 :                 aBorderLine.Color = aPropMap.getProperty(PROP_LineColor).get<sal_Int32>();
     444         108 :                 if (oLineWidth)
     445          44 :                     aBorderLine.LineWidth = *oLineWidth;
     446         108 :                 aPropMap.setProperty(aBorders[i], uno::makeAny(aBorderLine));
     447             :             }
     448          27 :             aPropMap.erase(PROP_LineColor);
     449          75 :         }
     450             :     }
     451         822 :     else if (xSInfo->supportsService("com.sun.star.drawing.CustomShape"))
     452         250 :         maTypeModel.maTextpathModel.pushToPropMap(aPropMap, rxShape);
     453             : 
     454        1794 :     PropertySet( rxShape ).setProperties( aPropMap );
     455         897 : }
     456             : 
     457         933 : SimpleShape::SimpleShape( Drawing& rDrawing, const OUString& rService ) :
     458             :     ShapeBase( rDrawing ),
     459         933 :     maService( rService )
     460             : {
     461         933 : }
     462             : 
     463         962 : void lcl_setSurround(PropertySet& rPropSet, const ShapeTypeModel& rTypeModel)
     464             : {
     465         962 :     sal_Int32 nSurround = com::sun::star::text::WrapTextMode_THROUGHT;
     466        1918 :     if ( rTypeModel.moWrapType.get() == "square" || rTypeModel.moWrapType .get()== "tight" ||
     467         956 :          rTypeModel.moWrapType.get() == "through" )
     468             :     {
     469           6 :         nSurround = com::sun::star::text::WrapTextMode_PARALLEL;
     470           6 :         if ( rTypeModel.moWrapSide.get() == "left" )
     471           0 :             nSurround = com::sun::star::text::WrapTextMode_LEFT;
     472           6 :         else if ( rTypeModel.moWrapSide.get() == "right" )
     473           0 :             nSurround = com::sun::star::text::WrapTextMode_RIGHT;
     474             :     }
     475         956 :     else if ( rTypeModel.moWrapType.get() == "topAndBottom" )
     476           0 :         nSurround = com::sun::star::text::WrapTextMode_NONE;
     477             : 
     478         962 :     rPropSet.setProperty(PROP_Surround, nSurround);
     479         962 : }
     480             : 
     481         962 : void lcl_SetAnchorType(PropertySet& rPropSet, const ShapeTypeModel& rTypeModel)
     482             : {
     483         962 :     if ( rTypeModel.maPositionHorizontal == "center" )
     484          47 :         rPropSet.setAnyProperty(PROP_HoriOrient, makeAny(text::HoriOrientation::CENTER));
     485         915 :     else if ( rTypeModel.maPositionHorizontal == "left" )
     486           2 :         rPropSet.setAnyProperty(PROP_HoriOrient, makeAny(text::HoriOrientation::LEFT));
     487         913 :     else if ( rTypeModel.maPositionHorizontal == "right" )
     488           4 :         rPropSet.setAnyProperty(PROP_HoriOrient, makeAny(text::HoriOrientation::RIGHT));
     489         909 :     else if ( rTypeModel.maPositionHorizontal == "inside" )
     490             :     {
     491           0 :         rPropSet.setAnyProperty(PROP_HoriOrient, makeAny(text::HoriOrientation::LEFT));
     492           0 :         rPropSet.setAnyProperty(PROP_PageToggle, makeAny(sal_True));
     493             :     }
     494         909 :     else if ( rTypeModel.maPositionHorizontal == "outside" )
     495             :     {
     496           0 :         rPropSet.setAnyProperty(PROP_HoriOrient, makeAny(text::HoriOrientation::RIGHT));
     497           0 :         rPropSet.setAnyProperty(PROP_PageToggle, makeAny(sal_True));
     498             :     }
     499             : 
     500         962 :     if ( rTypeModel.maPositionHorizontalRelative == "page" )
     501          44 :         rPropSet.setAnyProperty(PROP_HoriOrientRelation, makeAny(text::RelOrientation::PAGE_FRAME));
     502         918 :     else if ( rTypeModel.maPositionVerticalRelative == "margin" )
     503          41 :         rPropSet.setProperty(PROP_VertOrientRelation, text::RelOrientation::PAGE_PRINT_AREA);
     504         877 :     else if ( rTypeModel.maPositionVerticalRelative == "text" )
     505          17 :         rPropSet.setProperty(PROP_VertOrientRelation, text::RelOrientation::FRAME);
     506             : 
     507         962 :     if ( rTypeModel.maPositionVertical == "center" )
     508          39 :         rPropSet.setAnyProperty(PROP_VertOrient, makeAny(text::VertOrientation::CENTER));
     509         923 :     else if ( rTypeModel.maPositionVertical == "top" )
     510           9 :         rPropSet.setAnyProperty(PROP_VertOrient, makeAny(text::VertOrientation::TOP));
     511         914 :     else if ( rTypeModel.maPositionVertical == "bottom" )
     512           0 :         rPropSet.setAnyProperty(PROP_VertOrient, makeAny(text::VertOrientation::BOTTOM));
     513         914 :     else if ( rTypeModel.maPositionVertical == "inside" )
     514           0 :         rPropSet.setAnyProperty(PROP_VertOrient, makeAny(text::VertOrientation::LINE_TOP));
     515         914 :     else if ( rTypeModel.maPositionVertical == "outside" )
     516           0 :         rPropSet.setAnyProperty(PROP_VertOrient, makeAny(text::VertOrientation::LINE_BOTTOM));
     517             : 
     518         962 :     if ( rTypeModel.maPosition == "absolute" )
     519             :     {
     520             :         // Word supports as-character (inline) and at-character only, absolute can't be inline.
     521         772 :         rPropSet.setProperty(PROP_AnchorType, text::TextContentAnchorType_AT_CHARACTER);
     522             : 
     523         772 :         if ( rTypeModel.maPositionVerticalRelative == "page" )
     524             :         {
     525          39 :             rPropSet.setProperty(PROP_VertOrientRelation, text::RelOrientation::PAGE_FRAME);
     526             :         }
     527         733 :         else if ( rTypeModel.maPositionVerticalRelative == "margin" )
     528             :         {
     529          42 :             rPropSet.setProperty(PROP_VertOrientRelation, text::RelOrientation::PAGE_PRINT_AREA);
     530             :         }
     531             :         else
     532             :         {
     533         691 :             rPropSet.setProperty(PROP_VertOrientRelation, text::RelOrientation::FRAME);
     534             :         }
     535             :     }
     536         190 :     else if( rTypeModel.maPosition == "relative" )
     537             :     {   // I'm not very sure this is correct either.
     538           0 :         rPropSet.setProperty(PROP_AnchorType, text::TextContentAnchorType_AT_PARAGRAPH);
     539             :     }
     540             :     else // static (is the default) means anchored inline
     541             :     {
     542         190 :         rPropSet.setProperty(PROP_AnchorType, text::TextContentAnchorType_AS_CHARACTER);
     543             :     }
     544         962 :     lcl_setSurround( rPropSet, rTypeModel );
     545         962 : }
     546             : 
     547          43 : void lcl_SetRotation(PropertySet& rPropSet, const sal_Int32 nRotation)
     548             : {
     549             :     // See DffPropertyReader::Fix16ToAngle(): in VML, positive rotation angles are clockwise, we have them as counter-clockwise.
     550             :     // Additionally, VML type is 0..360, our is 0..36000.
     551          43 :     rPropSet.setAnyProperty(PROP_RotateAngle, makeAny(sal_Int32(NormAngle360(nRotation * -100))));
     552          43 : }
     553             : 
     554         770 : Reference< XShape > SimpleShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect ) const
     555             : {
     556         770 :     awt::Rectangle aShapeRect(rShapeRect);
     557         770 :     boost::optional<sal_Int32> oRotation;
     558         770 :     bool bFlipX = false, bFlipY = false;
     559         770 :     if (!maTypeModel.maRotation.isEmpty())
     560          42 :         oRotation.reset(maTypeModel.maRotation.toInt32());
     561         770 :     if (!maTypeModel.maFlip.isEmpty())
     562             :     {
     563          17 :         if (maTypeModel.maFlip == "x")
     564             :         {
     565           7 :             bFlipX = true;
     566             :         }
     567          10 :         else if (maTypeModel.maFlip == "y")
     568             :         {
     569           7 :             bFlipY = true;
     570             :         }
     571             :     }
     572             : 
     573         770 :     Reference< XShape > xShape = mrDrawing.createAndInsertXShape( maService, rxShapes, aShapeRect );
     574         770 :     SdrObject* pShape = GetSdrObjectFromXShape( xShape );
     575         770 :     if( pShape && getShapeType() >= 0 )
     576             :     {
     577         693 :         OUString aShapeType;
     578         693 :         aShapeType = EnhancedCustomShapeTypeNames::Get( static_cast< MSO_SPT >(getShapeType()) );
     579             :         //The resize autoshape to fit text attr of FontWork/Word-Art should always be false
     580             :         //for the fallback geometry.
     581         693 :         if(aShapeType.startsWith("fontwork"))
     582             :         {
     583          34 :             pShape->SetMergedItem(makeSdrTextAutoGrowHeightItem(false));
     584          34 :             pShape->SetMergedItem(makeSdrTextAutoGrowWidthItem(false));
     585         693 :         }
     586             :     }
     587         770 :     convertShapeProperties( xShape );
     588             : 
     589             :     // Handle left/right/top/bottom wrap distance.
     590             :     // Default value of mso-wrap-distance-left/right is supposed to be 0 (see
     591             :     // 19.1.2.19 of the VML spec), but Word implements a non-zero value.
     592             :     // [MS-ODRAW] says the below default value in 2.3.4.9.
     593         770 :     const GraphicHelper& rGraphicHelper = mrDrawing.getFilter().getGraphicHelper();
     594        1540 :     OUString aWrapDistanceLeft = OUString::number(0x0001BE7C);
     595         770 :     if (!maTypeModel.maWrapDistanceLeft.isEmpty())
     596           4 :         aWrapDistanceLeft = maTypeModel.maWrapDistanceLeft;
     597         770 :     sal_Int32 nWrapDistanceLeft = ConversionHelper::decodeMeasureToHmm(rGraphicHelper, aWrapDistanceLeft, 0, true, false);
     598         770 :     PropertySet(xShape).setAnyProperty(PROP_LeftMargin, uno::makeAny(nWrapDistanceLeft));
     599        1540 :     OUString aWrapDistanceRight = OUString::number(0x0001BE7C);
     600         770 :     if (!maTypeModel.maWrapDistanceRight.isEmpty())
     601           4 :         aWrapDistanceRight = maTypeModel.maWrapDistanceRight;
     602         770 :     sal_Int32 nWrapDistanceRight = ConversionHelper::decodeMeasureToHmm(rGraphicHelper, aWrapDistanceRight, 0, true, false);
     603         770 :     PropertySet(xShape).setAnyProperty(PROP_RightMargin, uno::makeAny(nWrapDistanceRight));
     604         770 :     sal_Int32 nWrapDistanceTop = 0;
     605         770 :     if (!maTypeModel.maWrapDistanceTop.isEmpty())
     606           6 :         nWrapDistanceTop = ConversionHelper::decodeMeasureToHmm(rGraphicHelper, maTypeModel.maWrapDistanceTop, 0, false, true);
     607         770 :     PropertySet(xShape).setAnyProperty(PROP_TopMargin, uno::makeAny(nWrapDistanceTop));
     608         770 :     sal_Int32 nWrapDistanceBottom = 0;
     609         770 :     if (!maTypeModel.maWrapDistanceBottom.isEmpty())
     610           6 :         nWrapDistanceBottom = ConversionHelper::decodeMeasureToHmm(rGraphicHelper, maTypeModel.maWrapDistanceBottom, 0, false, true);
     611         770 :     PropertySet(xShape).setAnyProperty(PROP_BottomMargin, uno::makeAny(nWrapDistanceBottom));
     612             : 
     613         770 :     if ( maService == "com.sun.star.text.TextFrame" )
     614             :     {
     615          75 :         PropertySet( xShape ).setAnyProperty( PROP_FrameIsAutomaticHeight, makeAny( maTypeModel.mbAutoHeight ) );
     616          75 :         PropertySet( xShape ).setAnyProperty( PROP_SizeType, makeAny( maTypeModel.mbAutoHeight ? SizeType::MIN : SizeType::FIX ) );
     617          75 :         if( getTextBox()->borderDistanceSet )
     618             :         {
     619          75 :             PropertySet( xShape ).setAnyProperty( PROP_LeftBorderDistance, makeAny( sal_Int32( getTextBox()->borderDistanceLeft )));
     620          75 :             PropertySet( xShape ).setAnyProperty( PROP_TopBorderDistance, makeAny( sal_Int32( getTextBox()->borderDistanceTop )));
     621          75 :             PropertySet( xShape ).setAnyProperty( PROP_RightBorderDistance, makeAny( sal_Int32( getTextBox()->borderDistanceRight )));
     622          75 :             PropertySet( xShape ).setAnyProperty( PROP_BottomBorderDistance, makeAny( sal_Int32( getTextBox()->borderDistanceBottom )));
     623             :         }
     624          75 :         if (!maTypeModel.maLayoutFlowAlt.isEmpty())
     625             :         {
     626             :             // Can't handle this property here, as the frame is not attached yet: pass it to writerfilter.
     627           3 :             uno::Reference<beans::XPropertySet> xPropertySet(xShape, uno::UNO_QUERY);
     628           6 :             uno::Sequence<beans::PropertyValue> aGrabBag;
     629           3 :             xPropertySet->getPropertyValue("FrameInteropGrabBag") >>= aGrabBag;
     630           6 :             beans::PropertyValue aPair;
     631           3 :             aPair.Name = "mso-layout-flow-alt";
     632           3 :             aPair.Value = uno::makeAny(maTypeModel.maLayoutFlowAlt);
     633           3 :             if (aGrabBag.hasElements())
     634             :             {
     635           0 :                 sal_Int32 nLength = aGrabBag.getLength();
     636           0 :                 aGrabBag.realloc(nLength + 1);
     637           0 :                 aGrabBag[nLength] = aPair;
     638             :             }
     639             :             else
     640             :             {
     641           3 :                 aGrabBag.realloc(1);
     642           3 :                 aGrabBag[0] = aPair;
     643             :             }
     644           6 :             xPropertySet->setPropertyValue("FrameInteropGrabBag", uno::makeAny(aGrabBag));
     645             :         }
     646             :     }
     647             :     else
     648             :     {
     649             :         // FIXME Setting the relative width/heigh only for everything but text frames as
     650             :         // TextFrames already have relative width/height feature... but currently not working
     651             :         // in the way we need.
     652             : 
     653             :         // Set the relative width / height if any
     654         695 :         if ( !maTypeModel.maWidthPercent.isEmpty( ) )
     655             :         {
     656             :             // Only page-relative width is supported ATM
     657           4 :             if ( maTypeModel.maWidthRelative.isEmpty() || maTypeModel.maWidthRelative == "page" )
     658             :             {
     659           2 :                 sal_Int16 nWidth = maTypeModel.maWidthPercent.toInt32() / 10;
     660             :                 // Only apply if nWidth != 0
     661           2 :                 if ( nWidth )
     662           2 :                     PropertySet( xShape ).setAnyProperty(PROP_RelativeWidth, makeAny( nWidth ) );
     663             :             }
     664             :         }
     665         695 :         if ( !maTypeModel.maHeightPercent.isEmpty( ) )
     666             :         {
     667             :             // Only page-relative height is supported ATM
     668           4 :             if ( maTypeModel.maHeightRelative.isEmpty() || maTypeModel.maHeightRelative == "page" )
     669             :             {
     670           4 :                 sal_Int16 nHeight = maTypeModel.maHeightPercent.toInt32() / 10;
     671             :                 // Only apply if nHeight != 0
     672           4 :                 if ( nHeight )
     673           4 :                     PropertySet( xShape ).setAnyProperty(PROP_RelativeHeight, makeAny( nHeight ) );
     674             :             }
     675             :         }
     676             : 
     677             :         // drawinglayer default is center, MSO default is top.
     678         695 :         drawing::TextVerticalAdjust eTextVerticalAdjust = drawing::TextVerticalAdjust_TOP;
     679         695 :         if (maTypeModel.maVTextAnchor == "middle")
     680           1 :             eTextVerticalAdjust = drawing::TextVerticalAdjust_CENTER;
     681         694 :         else if (maTypeModel.maVTextAnchor == "bottom")
     682           1 :             eTextVerticalAdjust = drawing::TextVerticalAdjust_BOTTOM;
     683         695 :         PropertySet(xShape).setAnyProperty(PROP_TextVerticalAdjust, makeAny(eTextVerticalAdjust));
     684             : 
     685         695 :         if (getTextBox())
     686             :         {
     687         182 :             getTextBox()->convert(xShape);
     688         182 :             if (getTextBox()->borderDistanceSet)
     689             :             {
     690         182 :                 awt::Size aSize = xShape->getSize();
     691         182 :                 PropertySet(xShape).setAnyProperty(PROP_TextLeftDistance, makeAny(sal_Int32(getTextBox()->borderDistanceLeft)));
     692         182 :                 PropertySet(xShape).setAnyProperty(PROP_TextUpperDistance, makeAny(sal_Int32(getTextBox()->borderDistanceTop)));
     693         182 :                 PropertySet(xShape).setAnyProperty(PROP_TextRightDistance, makeAny(sal_Int32(getTextBox()->borderDistanceRight)));
     694         182 :                 PropertySet(xShape).setAnyProperty(PROP_TextLowerDistance, makeAny(sal_Int32(getTextBox()->borderDistanceBottom)));
     695         182 :                 xShape->setSize(aSize);
     696             :             }
     697             :         }
     698             :     }
     699             : 
     700             :     // Import Legacy Fragments (if any)
     701         770 :     if( xShape.is() && !maShapeModel.maLegacyDiagramPath.isEmpty() )
     702             :     {
     703           0 :         Reference< XInputStream > xInStrm( mrDrawing.getFilter().openInputStream( maShapeModel.maLegacyDiagramPath ), UNO_SET_THROW );
     704           0 :         if( xInStrm.is() )
     705           0 :             PropertySet( xShape ).setProperty( PROP_LegacyFragment, xInStrm );
     706             :     }
     707             : 
     708        1540 :     PropertySet aPropertySet(xShape);
     709         770 :     if (xShape.is())
     710             :     {
     711         770 :         if (oRotation)
     712             :         {
     713          42 :             lcl_SetRotation(aPropertySet, *oRotation);
     714          42 :             uno::Reference<lang::XServiceInfo> xServiceInfo(rxShapes, uno::UNO_QUERY);
     715          42 :             if (!xServiceInfo->supportsService("com.sun.star.drawing.GroupShape"))
     716             :             {
     717             :                 // If rotation is used, simple setPosition() is not enough.
     718          33 :                 aPropertySet.setAnyProperty(PROP_HoriOrientPosition, makeAny(aShapeRect.X));
     719          33 :                 aPropertySet.setAnyProperty(PROP_VertOrientPosition, makeAny(aShapeRect.Y));
     720          42 :             }
     721             :         }
     722             : 
     723             :         // When flip has 'x' or 'y', the associated ShapeRect will be changed but direction change doesn't occur.
     724             :         // It might occur internally in SdrObject of "sw" module, not here.
     725             :         // The associated properties "PROP_MirroredX" and "PROP_MirroredY" have to be set here so that direction change will occur internally.
     726         770 :         if (bFlipX || bFlipY)
     727             :         {
     728          14 :             com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > aPropSequence (2);
     729          14 :             int nPropertyIndex = 0;
     730          14 :             if (bFlipX)
     731             :             {
     732           7 :                 aPropSequence [nPropertyIndex].Name = "MirroredX";
     733           7 :                 aPropSequence [nPropertyIndex].Value = makeAny (bFlipX);
     734           7 :                 nPropertyIndex++;
     735             :             }
     736          14 :             if (bFlipY)
     737             :             {
     738           7 :                 aPropSequence [nPropertyIndex].Name = "MirroredY";
     739           7 :                 aPropSequence [nPropertyIndex].Value = makeAny (bFlipY);
     740           7 :                 nPropertyIndex++;
     741             :             }
     742          14 :             aPropertySet.setAnyProperty(PROP_CustomShapeGeometry, makeAny( aPropSequence ) );
     743             :         }
     744             :     }
     745             : 
     746         770 :     lcl_SetAnchorType(aPropertySet, maTypeModel);
     747             : 
     748        1540 :     return xShape;
     749             : }
     750             : 
     751         158 : Reference< XShape > SimpleShape::createPictureObject( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect, OUString& rGraphicPath ) const
     752             : {
     753         158 :     Reference< XShape > xShape = mrDrawing.createAndInsertXShape( "com.sun.star.drawing.GraphicObjectShape", rxShapes, rShapeRect );
     754         158 :     if( xShape.is() )
     755             :     {
     756         158 :         XmlFilterBase& rFilter = mrDrawing.getFilter();
     757         158 :         OUString aGraphicUrl = rFilter.getGraphicHelper().importEmbeddedGraphicObject( rGraphicPath );
     758         316 :         PropertySet aPropSet( xShape );
     759         158 :         if( !aGraphicUrl.isEmpty() )
     760             :         {
     761         158 :             aPropSet.setProperty( PROP_GraphicURL, aGraphicUrl );
     762             :         }
     763         316 :         uno::Reference< lang::XServiceInfo > xServiceInfo(rxShapes, uno::UNO_QUERY);
     764             :         // If the shape has an absolute position, set the properties accordingly, unless we're inside a group shape.
     765         158 :         if ( maTypeModel.maPosition == "absolute" && !xServiceInfo->supportsService("com.sun.star.drawing.GroupShape"))
     766             :         {
     767          31 :             aPropSet.setProperty(PROP_HoriOrientPosition, rShapeRect.X);
     768          31 :             aPropSet.setProperty(PROP_VertOrientPosition, rShapeRect.Y);
     769          31 :             aPropSet.setProperty(PROP_Opaque, sal_False);
     770             :         }
     771             :         // fdo#70457: preserve rotation information
     772         158 :         if ( !maTypeModel.maRotation.isEmpty() )
     773           0 :             lcl_SetRotation( aPropSet, maTypeModel.maRotation.toInt32() );
     774             : 
     775         316 :         lcl_SetAnchorType(aPropSet, maTypeModel);
     776             :     }
     777         158 :     return xShape;
     778             : }
     779             : 
     780         237 : RectangleShape::RectangleShape( Drawing& rDrawing ) :
     781         237 :     SimpleShape( rDrawing, "com.sun.star.drawing.RectangleShape" )
     782             : {
     783         237 : }
     784             : 
     785         237 : Reference<XShape> RectangleShape::implConvertAndInsert(const Reference<XShapes>& rxShapes, const awt::Rectangle& rShapeRect) const
     786             : {
     787         237 :     OUString aGraphicPath = getGraphicPath();
     788             : 
     789             :     // try to create a picture object
     790         237 :     if(!aGraphicPath.isEmpty())
     791           3 :         return SimpleShape::createPictureObject(rxShapes, rShapeRect, aGraphicPath);
     792             : 
     793             :     // default: try to create a rectangle shape
     794         468 :     Reference<XShape> xShape = SimpleShape::implConvertAndInsert(rxShapes, rShapeRect);
     795         468 :     OUString sArcsize = maTypeModel.maArcsize;
     796         234 :     if ( !sArcsize.isEmpty( ) )
     797             :     {
     798           3 :         sal_Unicode cLastChar = sArcsize[sArcsize.getLength() - 1];
     799           3 :         sal_Int32 nValue = sArcsize.copy( 0, sArcsize.getLength() - 1 ).toInt32( );
     800             :         // Get the smallest half-side
     801           3 :         double size = std::min( rShapeRect.Height, rShapeRect.Width ) / 2.0;
     802           3 :         sal_Int32 nRadius = 0;
     803           3 :         if ( cLastChar == 'f' )
     804           3 :             nRadius = size * nValue / 65536;
     805           0 :         else if ( cLastChar == '%' )
     806           0 :             nRadius = size * nValue / 100;
     807           3 :         PropertySet( xShape ).setAnyProperty( PROP_CornerRadius, makeAny( nRadius ) );
     808             :     }
     809         471 :     return xShape;
     810             : }
     811             : 
     812           2 : EllipseShape::EllipseShape( Drawing& rDrawing ) :
     813           2 :     SimpleShape( rDrawing, "com.sun.star.drawing.EllipseShape" )
     814             : {
     815           2 : }
     816             : 
     817           2 : PolyLineShape::PolyLineShape( Drawing& rDrawing ) :
     818           2 :     SimpleShape( rDrawing, "com.sun.star.drawing.PolyLineShape" )
     819             : {
     820           2 : }
     821             : 
     822           2 : Reference< XShape > PolyLineShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect ) const
     823             : {
     824           2 :     Reference< XShape > xShape = SimpleShape::implConvertAndInsert( rxShapes, rShapeRect );
     825             :     // polygon path
     826           2 :     awt::Rectangle aCoordSys = getCoordSystem();
     827           2 :     if( !maShapeModel.maPoints.empty() && (aCoordSys.Width > 0) && (aCoordSys.Height > 0) )
     828             :     {
     829           2 :         ::std::vector< awt::Point > aAbsPoints;
     830           6 :         for( ShapeModel::PointVector::const_iterator aIt = maShapeModel.maPoints.begin(), aEnd = maShapeModel.maPoints.end(); aIt != aEnd; ++aIt )
     831           4 :             aAbsPoints.push_back( lclGetAbsPoint( *aIt, rShapeRect, aCoordSys ) );
     832           4 :         PointSequenceSequence aPointSeq( 1 );
     833           2 :         aPointSeq[ 0 ] = ContainerHelper::vectorToSequence( aAbsPoints );
     834           4 :         PropertySet aPropSet( xShape );
     835           4 :         aPropSet.setProperty( PROP_PolyPolygon, aPointSeq );
     836             :     }
     837           2 :     return xShape;
     838             : }
     839             : 
     840           5 : LineShape::LineShape(Drawing& rDrawing)
     841           5 :     : SimpleShape(rDrawing, "com.sun.star.drawing.LineShape")
     842             : {
     843           5 : }
     844             : 
     845           2 : awt::Rectangle LineShape::getAbsRectangle() const
     846             : {
     847           2 :     const GraphicHelper& rGraphicHelper = mrDrawing.getFilter().getGraphicHelper();
     848           2 :     awt::Rectangle aShapeRect;
     849           2 :     sal_Int32 nIndex = 0;
     850             : 
     851           2 :     aShapeRect.X = ConversionHelper::decodeMeasureToHmm(rGraphicHelper, maShapeModel.maFrom.getToken(0, ',', nIndex), 0, true, true);
     852           2 :     aShapeRect.Y = ConversionHelper::decodeMeasureToHmm(rGraphicHelper, maShapeModel.maFrom.getToken(0, ',', nIndex), 0, false, true);
     853           2 :     nIndex = 0;
     854           2 :     aShapeRect.Width = ConversionHelper::decodeMeasureToHmm(rGraphicHelper, maShapeModel.maTo.getToken(0, ',', nIndex), 0, true, true) - aShapeRect.X;
     855           2 :     aShapeRect.Height = ConversionHelper::decodeMeasureToHmm(rGraphicHelper, maShapeModel.maTo.getToken(0, ',', nIndex), 0, false, true) - aShapeRect.Y;
     856           2 :     return aShapeRect;
     857             : }
     858             : 
     859           3 : awt::Rectangle LineShape::getRelRectangle() const
     860             : {
     861           3 :     awt::Rectangle aShapeRect;
     862           3 :     sal_Int32 nIndex = 0;
     863             : 
     864           3 :     aShapeRect.X = maShapeModel.maFrom.getToken(0, ',', nIndex).toInt32();
     865           3 :     aShapeRect.Y = maShapeModel.maFrom.getToken(0, ',', nIndex).toInt32();
     866           3 :     nIndex = 0;
     867           3 :     aShapeRect.Width = maShapeModel.maTo.getToken(0, ',', nIndex).toInt32() - aShapeRect.X;
     868           3 :     aShapeRect.Height = maShapeModel.maTo.getToken(0, ',', nIndex).toInt32() - aShapeRect.Y;
     869           3 :     return aShapeRect;
     870             : }
     871             : 
     872         341 : BezierShape::BezierShape(Drawing& rDrawing)
     873         341 :     : SimpleShape(rDrawing, "com.sun.star.drawing.OpenBezierShape")
     874             : {
     875         341 : }
     876             : 
     877         341 : Reference< XShape > BezierShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect ) const
     878             : {
     879             :     // If we have an 'x' in the last part of the path it means it is closed...
     880         341 :     sal_Int32 nPos = maShapeModel.maVmlPath.lastIndexOf(',');
     881         341 :     if ( nPos != -1 && maShapeModel.maVmlPath.copy(nPos).indexOf('x') != -1 )
     882             :     {
     883         338 :         const_cast<BezierShape*>( this )->setService( "com.sun.star.drawing.ClosedBezierShape" );
     884             :     }
     885             : 
     886         341 :     awt::Rectangle aCoordSys = getCoordSystem();
     887         341 :     PolyPolygonBezierCoords aBezierCoords;
     888             : 
     889         341 :     if( (aCoordSys.Width > 0) && (aCoordSys.Height > 0) )
     890             :     {
     891         341 :         const GraphicHelper& rGraphicHelper = mrDrawing.getFilter().getGraphicHelper();
     892             : 
     893             :         // Bezier paths may consist of one or more sub-paths
     894             :         typedef ::std::vector< ::std::vector< awt::Point > > SubPathList;
     895             :         typedef ::std::vector< ::std::vector< PolygonFlags > > FlagsList;
     896         341 :         SubPathList aCoordLists;
     897         682 :         FlagsList aFlagLists;
     898         341 :         sal_Int32 nIndex = 0;
     899             : 
     900             :         // Curve defined by to, from, control1 and control2 attributes
     901         341 :         if ( maShapeModel.maVmlPath.isEmpty() )
     902             :         {
     903           0 :             aCoordLists.push_back( ::std::vector< awt::Point >() );
     904           0 :             aFlagLists.push_back( ::std::vector< PolygonFlags >() );
     905             : 
     906             :             // Start point
     907           0 :             aCoordLists[ 0 ].push_back(
     908           0 :                 awt::Point(ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maFrom.getToken( 0, ',', nIndex ), 0, true, true ),
     909           0 :                   ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maFrom.getToken( 0, ',', nIndex ), 0, false, true ) ) );
     910             :             // Control point 1
     911           0 :             aCoordLists[ 0 ].push_back(
     912           0 :                 awt::Point( ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maControl1.getToken( 0, ',', nIndex ), 0, true, true ),
     913           0 :                       ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maControl1.getToken( 0, ',', nIndex ), 0, false, true ) ) );
     914             :             // Control point 2
     915           0 :             aCoordLists[ 0 ].push_back(
     916           0 :                 awt::Point( ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maControl2.getToken( 0, ',', nIndex ), 0, true, true ),
     917           0 :                       ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maControl2.getToken( 0, ',', nIndex ), 0, false, true ) ) );
     918             :             // End point
     919           0 :             aCoordLists[ 0 ].push_back(
     920           0 :                 awt::Point( ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maTo.getToken( 0, ',', nIndex ), 0, true, true ),
     921           0 :                       ConversionHelper::decodeMeasureToHmm( rGraphicHelper, maShapeModel.maTo.getToken( 0, ',', nIndex ), 0, false, true ) ) );
     922             : 
     923             :             // First and last points are normals, points 2 and 4 are controls
     924           0 :             aFlagLists[ 0 ].resize( aCoordLists[ 0 ].size(), PolygonFlags_CONTROL );
     925           0 :             aFlagLists[ 0 ][ 0 ] = PolygonFlags_NORMAL;
     926           0 :             aFlagLists[ 0 ].back() = PolygonFlags_NORMAL;
     927             :         }
     928             :         // Curve defined by path attribute
     929             :         else
     930             :         {
     931             :             // Parse VML path string and convert to absolute coordinates
     932         341 :             ConversionHelper::decodeVmlPath( aCoordLists, aFlagLists, maShapeModel.maVmlPath );
     933             : 
     934         889 :             for ( SubPathList::iterator aListIt = aCoordLists.begin(); aListIt != aCoordLists.end(); ++aListIt )
     935       16218 :                 for ( ::std::vector< awt::Point >::iterator aPointIt = (*aListIt).begin(); aPointIt != (*aListIt).end(); ++aPointIt)
     936             :                 {
     937       15670 :                     (*aPointIt) = lclGetAbsPoint( (*aPointIt), rShapeRect, aCoordSys );
     938             :                 }
     939             :         }
     940             : 
     941         341 :         aBezierCoords.Coordinates.realloc( aCoordLists.size() );
     942         889 :         for ( size_t i = 0; i < aCoordLists.size(); i++ )
     943         548 :             aBezierCoords.Coordinates[i] = ContainerHelper::vectorToSequence( aCoordLists[i] );
     944             : 
     945         341 :         aBezierCoords.Flags.realloc( aFlagLists.size() );
     946         889 :         for ( size_t i = 0; i < aFlagLists.size(); i++ )
     947         548 :             aBezierCoords.Flags[i] = ContainerHelper::vectorToSequence( aFlagLists[i] );
     948             : 
     949        1023 :         if( !aCoordLists.front().empty() && !aCoordLists.back().empty()
     950         341 :             && aCoordLists.front().front().X == aCoordLists.back().back().X
     951         603 :             && aCoordLists.front().front().Y == aCoordLists.back().back().Y )
     952             :         { // HACK: If the shape is in fact closed, which can be found out only when the path is known,
     953             :           // force to closed bezier shape (otherwise e.g. fill won't work).
     954         262 :             const_cast< BezierShape* >( this )->setService( "com.sun.star.drawing.ClosedBezierShape" );
     955         341 :         }
     956             :     }
     957             : 
     958         341 :     Reference< XShape > xShape = SimpleShape::implConvertAndInsert( rxShapes, rShapeRect );
     959             : 
     960         341 :     if( aBezierCoords.Coordinates.hasElements())
     961             :     {
     962         341 :         PropertySet aPropSet( xShape );
     963         341 :         aPropSet.setProperty( PROP_PolyPolygonBezier, aBezierCoords );
     964             :     }
     965             : 
     966             :     // Hacky way of ensuring the shape is correctly sized/positioned
     967         341 :     xShape->setSize( awt::Size( rShapeRect.Width, rShapeRect.Height ) );
     968         341 :     xShape->setPosition( awt::Point( rShapeRect.X, rShapeRect.Y ) );
     969         341 :     return xShape;
     970             : }
     971             : 
     972         346 : CustomShape::CustomShape( Drawing& rDrawing ) :
     973         346 :     SimpleShape( rDrawing, "com.sun.star.drawing.CustomShape" )
     974             : {
     975         346 : }
     976             : 
     977         186 : Reference< XShape > CustomShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect ) const
     978             : {
     979             :     // try to create a custom shape
     980         186 :     Reference< XShape > xShape = SimpleShape::implConvertAndInsert( rxShapes, rShapeRect );
     981         186 :     if( xShape.is() ) try
     982             :     {
     983             :         // create the custom shape geometry
     984         186 :         Reference< XEnhancedCustomShapeDefaulter > xDefaulter( xShape, UNO_QUERY_THROW );
     985         125 :         xDefaulter->createCustomShapeDefaults( OUString::number( getShapeType() ) );
     986             :         // convert common properties
     987         125 :         convertShapeProperties( xShape );
     988             :     }
     989          61 :     catch( Exception& )
     990             :     {
     991             :     }
     992         186 :     return xShape;
     993             : }
     994             : 
     995         346 : ComplexShape::ComplexShape( Drawing& rDrawing ) :
     996         346 :     CustomShape( rDrawing )
     997             : {
     998         346 : }
     999             : 
    1000         344 : Reference< XShape > ComplexShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect ) const
    1001             : {
    1002         344 :     XmlFilterBase& rFilter = mrDrawing.getFilter();
    1003         344 :     sal_Int32 nShapeType = getShapeType();
    1004         344 :     OUString aGraphicPath = getGraphicPath();
    1005             : 
    1006             :     // try to find registered OLE object info
    1007         344 :     if( const OleObjectInfo* pOleObjectInfo = mrDrawing.getOleObjectInfo( maTypeModel.maShapeId ) )
    1008             :     {
    1009             :         SAL_WARN_IF(
    1010             :             nShapeType != VML_SHAPETYPE_PICTUREFRAME, "oox",
    1011             :             "ComplexShape::implConvertAndInsert - unexpected shape type");
    1012             : 
    1013             :         // if OLE object is embedded into a DrawingML shape (PPTX), do not create it here
    1014           2 :         if( pOleObjectInfo->mbDmlShape )
    1015           4 :             return Reference< XShape >();
    1016             : 
    1017           0 :         PropertyMap aOleProps;
    1018           0 :         awt::Size aOleSize( rShapeRect.Width, rShapeRect.Height );
    1019           0 :         if( rFilter.getOleObjectHelper().importOleObject( aOleProps, *pOleObjectInfo, aOleSize ) )
    1020             :         {
    1021           0 :             Reference< XShape > xShape = mrDrawing.createAndInsertXShape( "com.sun.star.drawing.OLE2Shape", rxShapes, rShapeRect );
    1022           0 :             if( xShape.is() )
    1023             :             {
    1024             :                 // set the replacement graphic
    1025           0 :                 if( !aGraphicPath.isEmpty() )
    1026             :                 {
    1027           0 :                     WMF_EXTERNALHEADER aExtHeader;
    1028           0 :                     aExtHeader.mapMode = 8;
    1029           0 :                     aExtHeader.xExt = rShapeRect.Width;
    1030           0 :                     aExtHeader.yExt = rShapeRect.Height;
    1031             : 
    1032           0 :                     Reference< XGraphic > xGraphic = rFilter.getGraphicHelper().importEmbeddedGraphic(aGraphicPath, &aExtHeader);
    1033           0 :                     if (xGraphic.is())
    1034           0 :                         aOleProps.setProperty( PROP_Graphic, xGraphic);
    1035             :                 }
    1036             : 
    1037           0 :                 PropertySet aPropSet( xShape );
    1038           0 :                 aPropSet.setProperties( aOleProps );
    1039             : 
    1040           0 :                 return xShape;
    1041           0 :             }
    1042           0 :         }
    1043             :     }
    1044             : 
    1045             :     // try to find registered form control info
    1046         342 :     const ControlInfo* pControlInfo = mrDrawing.getControlInfo( maTypeModel.maShapeId );
    1047         342 :     if( pControlInfo && !pControlInfo->maFragmentPath.isEmpty() )
    1048             :     {
    1049             :         OSL_ENSURE( nShapeType == VML_SHAPETYPE_HOSTCONTROL, "ComplexShape::implConvertAndInsert - unexpected shape type" );
    1050           0 :         OUString aShapeName = getShapeName();
    1051           0 :         if( !aShapeName.isEmpty() )
    1052             :         {
    1053             :             OSL_ENSURE( aShapeName == pControlInfo->maName, "ComplexShape::implConvertAndInsert - control name mismatch" );
    1054             :             // load the control properties from fragment
    1055           0 :             ::oox::ole::EmbeddedControl aControl( aShapeName );
    1056           0 :             if( rFilter.importFragment( new ::oox::ole::AxControlFragment( rFilter, pControlInfo->maFragmentPath, aControl ) ) )
    1057             :             {
    1058             :                 // create and return the control shape (including control model)
    1059           0 :                 sal_Int32 nCtrlIndex = -1;
    1060           0 :                 Reference< XShape > xShape = mrDrawing.createAndInsertXControlShape( aControl, rxShapes, rShapeRect, nCtrlIndex );
    1061             :                 // on error, proceed and try to create picture from replacement image
    1062           0 :                 if( xShape.is() )
    1063           0 :                     return xShape;
    1064           0 :             }
    1065           0 :         }
    1066             :     }
    1067             : 
    1068             :     // host application wants to create the shape (do not try failed OLE controls again)
    1069         342 :     if( (nShapeType == VML_SHAPETYPE_HOSTCONTROL) && !pControlInfo )
    1070             :     {
    1071             :         OSL_ENSURE( getClientData(), "ComplexShape::implConvertAndInsert - missing client data" );
    1072           1 :         Reference< XShape > xShape = mrDrawing.createAndInsertClientXShape( *this, rxShapes, rShapeRect );
    1073           1 :         if( xShape.is() )
    1074           1 :             return xShape;
    1075             :     }
    1076             : 
    1077             :     // try to create a picture object
    1078         341 :     if( !aGraphicPath.isEmpty() )
    1079             :     {
    1080         155 :         Reference< XShape > xShape = SimpleShape::createPictureObject(rxShapes, rShapeRect, aGraphicPath);
    1081             :         // AS_CHARACTER shape: vertical orientation default is bottom, MSO default is top.
    1082         155 :         if ( maTypeModel.maPosition != "absolute" && maTypeModel.maPosition != "relative" )
    1083         118 :             PropertySet( xShape ).setAnyProperty( PROP_VertOrient, makeAny(text::VertOrientation::TOP));
    1084         155 :         return xShape;
    1085             :     }
    1086             :     // default: try to create a custom shape
    1087         186 :     return CustomShape::implConvertAndInsert( rxShapes, rShapeRect );
    1088             : }
    1089             : 
    1090          34 : GroupShape::GroupShape( Drawing& rDrawing ) :
    1091             :     ShapeBase( rDrawing ),
    1092          34 :     mxChildren( new ShapeContainer( rDrawing ) )
    1093             : {
    1094          34 : }
    1095             : 
    1096          68 : GroupShape::~GroupShape()
    1097             : {
    1098          68 : }
    1099             : 
    1100          34 : void GroupShape::finalizeFragmentImport()
    1101             : {
    1102             :     // basic shape processing
    1103          34 :     ShapeBase::finalizeFragmentImport();
    1104             :     // finalize all child shapes
    1105          34 :     mxChildren->finalizeFragmentImport();
    1106          34 : }
    1107             : 
    1108          62 : const ShapeType* GroupShape::getChildTypeById( const OUString& rShapeId ) const
    1109             : {
    1110          62 :     return mxChildren->getShapeTypeById( rShapeId, true );
    1111             : }
    1112             : 
    1113           0 : const ShapeBase* GroupShape::getChildById( const OUString& rShapeId ) const
    1114             : {
    1115           0 :     return mxChildren->getShapeById( rShapeId, true );
    1116             : }
    1117             : 
    1118          34 : Reference< XShape > GroupShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect ) const
    1119             : {
    1120          34 :     Reference< XShape > xGroupShape;
    1121             :     // check that this shape contains children and a valid coordinate system
    1122          34 :     ShapeParentAnchor aParentAnchor;
    1123          34 :     aParentAnchor.maShapeRect = rShapeRect;
    1124          34 :     aParentAnchor.maCoordSys = getCoordSystem();
    1125          34 :     if( !mxChildren->empty() && (aParentAnchor.maCoordSys.Width > 0) && (aParentAnchor.maCoordSys.Height > 0) ) try
    1126             :     {
    1127          34 :         xGroupShape = mrDrawing.createAndInsertXShape( "com.sun.star.drawing.GroupShape", rxShapes, rShapeRect );
    1128          34 :         Reference< XShapes > xChildShapes( xGroupShape, UNO_QUERY_THROW );
    1129          34 :         mxChildren->convertAndInsert( xChildShapes, &aParentAnchor );
    1130          34 :         if( !xChildShapes->hasElements() )
    1131             :         {
    1132             :             SAL_WARN("oox", "no child shape has been created - deleting the group shape");
    1133           0 :             rxShapes->remove( xGroupShape );
    1134           0 :             xGroupShape.clear();
    1135          34 :         }
    1136             :     }
    1137           0 :     catch( Exception& )
    1138             :     {
    1139             :     }
    1140             : 
    1141          34 :     if (!maTypeModel.maEditAs.isEmpty())
    1142             :     {
    1143          14 :         uno::Reference<beans::XPropertySet> xPropertySet(xGroupShape, uno::UNO_QUERY);
    1144          28 :         uno::Sequence<beans::PropertyValue> aGrabBag;
    1145          14 :         xPropertySet->getPropertyValue("InteropGrabBag") >>= aGrabBag;
    1146          28 :         beans::PropertyValue aPair;
    1147          14 :         aPair.Name = "mso-edit-as";
    1148          14 :         aPair.Value = uno::makeAny(maTypeModel.maEditAs);
    1149          14 :        if (aGrabBag.hasElements())
    1150             :        {
    1151           0 :             sal_Int32 nLength = aGrabBag.getLength();
    1152           0 :             aGrabBag.realloc(nLength + 1);
    1153           0 :             aGrabBag[nLength] = aPair;
    1154             :        }
    1155             :        else
    1156             :        {
    1157          14 :            aGrabBag.realloc(1);
    1158          14 :            aGrabBag[0] = aPair;
    1159             :        }
    1160          28 :        xPropertySet->setPropertyValue("InteropGrabBag", uno::makeAny(aGrabBag));
    1161             :     }
    1162             :     // Make sure group shapes are inline as well, unless there is an explicit different style.
    1163          68 :     PropertySet aPropertySet(xGroupShape);
    1164          34 :     lcl_SetAnchorType(aPropertySet, maTypeModel);
    1165          34 :     if (!maTypeModel.maRotation.isEmpty())
    1166           1 :         lcl_SetRotation(aPropertySet, maTypeModel.maRotation.toInt32());
    1167          68 :     return xGroupShape;
    1168             : }
    1169             : 
    1170             : } // namespace vml
    1171         246 : } // namespace oox
    1172             : 
    1173             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11