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

Generated by: LCOV version 1.10