LCOV - code coverage report
Current view: top level - writerfilter/source/rtftok - rtfsdrimport.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 508 545 93.2 %
Date: 2014-11-03 Functions: 19 19 100.0 %
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             : 
      10             : #include <com/sun/star/container/XNamed.hpp>
      11             : #include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp>
      12             : #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
      13             : #include <com/sun/star/drawing/LineStyle.hpp>
      14             : #include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
      15             : #include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
      16             : #include <com/sun/star/lang/XServiceInfo.hpp>
      17             : #include <com/sun/star/table/BorderLine2.hpp>
      18             : #include <com/sun/star/text/HoriOrientation.hpp>
      19             : #include <com/sun/star/text/RelOrientation.hpp>
      20             : #include <com/sun/star/text/SizeType.hpp>
      21             : #include <com/sun/star/text/VertOrientation.hpp>
      22             : #include <com/sun/star/text/WrapTextMode.hpp>
      23             : #include <com/sun/star/text/WritingMode.hpp>
      24             : #include <com/sun/star/text/TextContentAnchorType.hpp>
      25             : #include <ooxml/resourceids.hxx>
      26             : #include <filter/msfilter/util.hxx>
      27             : #include <svx/svdtrans.hxx>
      28             : #include <dmapper/DomainMapper.hxx>
      29             : #include "../dmapper/GraphicHelpers.hxx"
      30             : #include <rtfsdrimport.hxx>
      31             : #include <rtfreferenceproperties.hxx>
      32             : #include <oox/vml/vmlformatting.hxx>
      33             : #include <oox/helper/modelobjecthelper.hxx>
      34             : #include <oox/drawingml/shapepropertymap.hxx>
      35             : #include <oox/helper/propertyset.hxx>
      36             : #include <boost/logic/tribool.hpp>
      37             : 
      38             : using namespace com::sun::star;
      39             : 
      40             : namespace writerfilter
      41             : {
      42             : namespace rtftok
      43             : {
      44             : 
      45         814 : RTFSdrImport::RTFSdrImport(RTFDocumentImpl& rDocument,
      46             :                            uno::Reference<lang::XComponent> const& xDstDoc)
      47             :     : m_rImport(rDocument)
      48             :     , m_bTextFrame(false)
      49         814 :     , m_bFakePict(false)
      50             : {
      51         814 :     uno::Reference<drawing::XDrawPageSupplier> xDrawings(xDstDoc, uno::UNO_QUERY);
      52         814 :     if (xDrawings.is())
      53         762 :         m_aParents.push(xDrawings->getDrawPage());
      54         814 : }
      55             : 
      56        2442 : RTFSdrImport::~RTFSdrImport()
      57             : {
      58         814 :     if (m_aParents.size())
      59         762 :         m_aParents.pop();
      60        1628 : }
      61             : 
      62         192 : void RTFSdrImport::createShape(const OUString& aStr, uno::Reference<drawing::XShape>& xShape, uno::Reference<beans::XPropertySet>& xPropertySet)
      63             : {
      64         192 :     if (m_rImport.getModelFactory().is())
      65         174 :         xShape.set(m_rImport.getModelFactory()->createInstance(aStr), uno::UNO_QUERY);
      66         192 :     xPropertySet.set(xShape, uno::UNO_QUERY);
      67         192 : }
      68             : 
      69          94 : std::vector<beans::PropertyValue> RTFSdrImport::getTextFrameDefaults(bool bNew)
      70             : {
      71          94 :     std::vector<beans::PropertyValue> aRet;
      72         188 :     beans::PropertyValue aPropertyValue;
      73             : 
      74          94 :     aPropertyValue.Name = "HoriOrient";
      75          94 :     aPropertyValue.Value <<= text::HoriOrientation::NONE;
      76          94 :     aRet.push_back(aPropertyValue);
      77          94 :     aPropertyValue.Name = "HoriOrientRelation";
      78          94 :     aPropertyValue.Value <<= text::RelOrientation::FRAME;
      79          94 :     aRet.push_back(aPropertyValue);
      80          94 :     aPropertyValue.Name = "VertOrient";
      81          94 :     aPropertyValue.Value <<= text::VertOrientation::NONE;
      82          94 :     aRet.push_back(aPropertyValue);
      83          94 :     aPropertyValue.Name = "VertOrientRelation";
      84          94 :     aPropertyValue.Value <<= text::RelOrientation::FRAME;
      85          94 :     aRet.push_back(aPropertyValue);
      86          94 :     if (!bNew)
      87             :     {
      88          24 :         aPropertyValue.Name = "BackColorTransparency";
      89          24 :         aPropertyValue.Value <<= sal_Int32(100);
      90          24 :         aRet.push_back(aPropertyValue);
      91             :     }
      92             :     // See the spec, new-style frame default margins are specified in EMUs.
      93          94 :     aPropertyValue.Name = "LeftBorderDistance";
      94          94 :     aPropertyValue.Value <<= sal_Int32(bNew ? (91440 / 360) : 0);
      95          94 :     aRet.push_back(aPropertyValue);
      96          94 :     aPropertyValue.Name = "RightBorderDistance";
      97          94 :     aPropertyValue.Value <<= sal_Int32(bNew ? (91440 / 360) : 0);
      98          94 :     aRet.push_back(aPropertyValue);
      99          94 :     aPropertyValue.Name = "TopBorderDistance";
     100          94 :     aPropertyValue.Value <<= sal_Int32(bNew ? (45720 / 360) : 0);
     101          94 :     aRet.push_back(aPropertyValue);
     102          94 :     aPropertyValue.Name = "BottomBorderDistance";
     103          94 :     aPropertyValue.Value <<= sal_Int32(bNew ? (45720 / 360) : 0);
     104          94 :     aRet.push_back(aPropertyValue);
     105          94 :     aPropertyValue.Name = "SizeType";
     106          94 :     aPropertyValue.Value <<= text::SizeType::FIX;
     107          94 :     aRet.push_back(aPropertyValue);
     108         188 :     return aRet;
     109             : }
     110             : 
     111          10 : void RTFSdrImport::pushParent(uno::Reference<drawing::XShapes> const& xParent)
     112             : {
     113          10 :     m_aParents.push(xParent);
     114          10 : }
     115             : 
     116          10 : void RTFSdrImport::popParent()
     117             : {
     118          10 :     m_aParents.pop();
     119          10 : }
     120             : 
     121         158 : void RTFSdrImport::resolveDhgt(uno::Reference<beans::XPropertySet> const& xPropertySet,
     122             :                                sal_Int32 const nZOrder, bool const bOldStyle)
     123             : {
     124             :     writerfilter::dmapper::DomainMapper& rMapper =
     125         158 :         dynamic_cast<writerfilter::dmapper::DomainMapper&>(m_rImport.Mapper());
     126         158 :     writerfilter::dmapper::GraphicZOrderHelper* pHelper = rMapper.graphicZOrderHelper();
     127         158 :     xPropertySet->setPropertyValue("ZOrder", uno::makeAny(pHelper->findZOrder(nZOrder, bOldStyle)));
     128         158 :     pHelper->addItem(xPropertySet, nZOrder);
     129         158 : }
     130             : 
     131          74 : void RTFSdrImport::resolveFLine(uno::Reference<beans::XPropertySet> const& xPropertySet,
     132             :                                 sal_Int32 const nFLine)
     133             : {
     134          74 :     if (nFLine == 0)
     135          44 :         xPropertySet->setPropertyValue("LineStyle", uno::makeAny(drawing::LineStyle_NONE));
     136          74 : }
     137             : 
     138         110 : void RTFSdrImport::applyProperty(uno::Reference<drawing::XShape> const& xShape, const OUString& aKey, const OUString& aValue)
     139             : {
     140         110 :     uno::Reference<beans::XPropertySet> xPropertySet(xShape, uno::UNO_QUERY);
     141         110 :     sal_Int16 nHoriOrient = 0;
     142         110 :     sal_Int16 nVertOrient = 0;
     143         110 :     boost::logic::tribool obFitShapeToText(boost::logic::indeterminate);
     144         110 :     bool bFilled = true;
     145             : 
     146         110 :     if (aKey == "posh")
     147             :     {
     148          20 :         switch (aValue.toInt32())
     149             :         {
     150             :         case 1:
     151           0 :             nHoriOrient = text::HoriOrientation::LEFT;
     152           0 :             break;
     153             :         case 2:
     154          20 :             nHoriOrient = text::HoriOrientation::CENTER;
     155          20 :             break;
     156             :         case 3:
     157           0 :             nHoriOrient = text::HoriOrientation::RIGHT;
     158           0 :             break;
     159             :         case 4:
     160           0 :             nHoriOrient = text::HoriOrientation::INSIDE;
     161           0 :             break;
     162             :         case 5:
     163           0 :             nHoriOrient = text::HoriOrientation::OUTSIDE;
     164           0 :             break;
     165             :         default:
     166           0 :             break;
     167             :         }
     168             :     }
     169          90 :     else if (aKey == "posv")
     170             :     {
     171           8 :         switch (aValue.toInt32())
     172             :         {
     173             :         case 1:
     174           4 :             nVertOrient = text::VertOrientation::TOP;
     175           4 :             break;
     176             :         case 2:
     177           4 :             nVertOrient = text::VertOrientation::CENTER;
     178           4 :             break;
     179             :         case 3:
     180           0 :             nVertOrient = text::VertOrientation::BOTTOM;
     181           0 :             break;
     182             :         default:
     183           0 :             break;
     184             :         }
     185             :     }
     186          82 :     else if (aKey == "fFitShapeToText")
     187          22 :         obFitShapeToText = aValue.toInt32() == 1;
     188          60 :     else if (aKey == "fFilled")
     189          54 :         bFilled = aValue.toInt32() == 1;
     190           6 :     else if (aKey == "rotation")
     191             :     {
     192             :         // See DffPropertyReader::Fix16ToAngle(): in RTF, positive rotation angles are clockwise, we have them as counter-clockwise.
     193             :         // Additionally, RTF type is 0..360*2^16, our is 0..360*100.
     194           6 :         sal_Int32 nRotation = aValue.toInt32()*100/65536;
     195           6 :         uno::Reference<lang::XServiceInfo> xServiceInfo(xShape, uno::UNO_QUERY);
     196           6 :         if (!xServiceInfo->supportsService("com.sun.star.text.TextFrame"))
     197           4 :             xPropertySet->setPropertyValue("RotateAngle", uno::makeAny(sal_Int32(NormAngle360(nRotation * -1))));
     198             :     }
     199             : 
     200         110 :     if (nHoriOrient != 0 && xPropertySet.is())
     201          18 :         xPropertySet->setPropertyValue("HoriOrient", uno::makeAny(nHoriOrient));
     202         110 :     if (nVertOrient != 0 && xPropertySet.is())
     203           6 :         xPropertySet->setPropertyValue("VertOrient", uno::makeAny(nVertOrient));
     204         110 :     if (!boost::logic::indeterminate(obFitShapeToText) && xPropertySet.is())
     205             :     {
     206          14 :         xPropertySet->setPropertyValue("SizeType", uno::makeAny(obFitShapeToText ? text::SizeType::MIN : text::SizeType::FIX));
     207          14 :         xPropertySet->setPropertyValue("FrameIsAutomaticHeight", uno::makeAny(static_cast<bool>(obFitShapeToText)));
     208             :     }
     209         110 :     if (!bFilled && xPropertySet.is())
     210             :     {
     211          28 :         if (m_bTextFrame)
     212          10 :             xPropertySet->setPropertyValue("BackColorTransparency", uno::makeAny(sal_Int32(100)));
     213             :         else
     214          18 :             xPropertySet->setPropertyValue("FillStyle", uno::makeAny(drawing::FillStyle_NONE));
     215         110 :     }
     216         110 : }
     217             : 
     218         192 : int RTFSdrImport::initShape(uno::Reference<drawing::XShape>& o_xShape,
     219             :                             uno::Reference<beans::XPropertySet>& o_xPropSet,
     220             :                             bool& o_rIsCustomShape,
     221             :                             RTFShape const& rShape, bool const bClose, ShapeOrPict const shapeOrPict)
     222             : {
     223             :     assert(!o_xShape.is());
     224             :     assert(!o_xPropSet.is());
     225         192 :     o_rIsCustomShape = false;
     226         192 :     m_bFakePict = false;
     227             : 
     228             :     // first, find the shape type
     229         192 :     int nType = -1;
     230         438 :     auto iter = std::find_if(rShape.aProperties.begin(), rShape.aProperties.end(), [](std::pair<OUString, OUString> aProperty)
     231             :     {
     232         438 :         return aProperty.first == "shapeType";
     233         630 :     });
     234             : 
     235         192 :     if (iter == rShape.aProperties.end())
     236             :     {
     237          12 :         if (SHAPE == shapeOrPict)
     238             :         {
     239             :             // The spec doesn't state what is the default for shapeType,
     240             :             // Word seems to implement it as a rectangle.
     241           8 :             nType = ESCHER_ShpInst_Rectangle;
     242             :         }
     243             :         else
     244             :         {
     245             :             // pict is picture by default but can be a rectangle too fdo#79319
     246           4 :             nType = ESCHER_ShpInst_PictureFrame;
     247             :         }
     248             :     }
     249             :     else
     250             :     {
     251         180 :         nType = iter->second.toInt32();
     252         180 :         if (PICT == shapeOrPict && ESCHER_ShpInst_PictureFrame != nType)
     253             :         {
     254           4 :             m_bFakePict = true;
     255             :         }
     256             :     }
     257             : 
     258         192 :     switch (nType)
     259             :     {
     260             :     case ESCHER_ShpInst_PictureFrame:
     261          36 :         createShape("com.sun.star.drawing.GraphicObjectShape", o_xShape, o_xPropSet);
     262          36 :         break;
     263             :     case ESCHER_ShpInst_Line:
     264           8 :         createShape("com.sun.star.drawing.LineShape", o_xShape, o_xPropSet);
     265           8 :         break;
     266             :     case ESCHER_ShpInst_Rectangle:
     267             :     case ESCHER_ShpInst_TextBox:
     268             :         // If we're inside a groupshape, can't use text frames.
     269         126 :         if (!bClose && m_aParents.size() == 1)
     270             :         {
     271          70 :             createShape("com.sun.star.text.TextFrame", o_xShape, o_xPropSet);
     272          70 :             m_bTextFrame = true;
     273          70 :             std::vector<beans::PropertyValue> aDefaults = getTextFrameDefaults(true);
     274         700 :             for (size_t j = 0; j < aDefaults.size(); ++j)
     275         630 :                 o_xPropSet->setPropertyValue(aDefaults[j].Name, aDefaults[j].Value);
     276          70 :             break;
     277             :         }
     278             :     // fall-through intended
     279             :     default:
     280          78 :         createShape("com.sun.star.drawing.CustomShape", o_xShape, o_xPropSet);
     281          78 :         o_rIsCustomShape = true;
     282          78 :         break;
     283             :     }
     284             : 
     285             :     // Defaults
     286         192 :     if (o_xPropSet.is() && !m_bTextFrame)
     287             :     {
     288         104 :         o_xPropSet->setPropertyValue("FillColor", uno::makeAny(sal_uInt32(0xffffff))); // White in Word, kind of blue in Writer.
     289             :     }
     290             : 
     291         192 :     return nType;
     292             : }
     293             : 
     294         192 : void RTFSdrImport::resolve(RTFShape& rShape, bool bClose, ShapeOrPict const shapeOrPict)
     295             : {
     296         192 :     bool bPib = false;
     297         192 :     m_bTextFrame = false;
     298             : 
     299         192 :     uno::Reference<drawing::XShape> xShape;
     300         346 :     uno::Reference<beans::XPropertySet> xPropertySet;
     301         346 :     uno::Any aAny;
     302         346 :     beans::PropertyValue aPropertyValue;
     303         192 :     awt::Rectangle aViewBox;
     304         346 :     comphelper::SequenceAsVector<beans::PropertyValue> aPath;
     305             :     // Default line color is black in Word, blue in Writer.
     306         346 :     uno::Any aLineColor = uno::makeAny(COL_BLACK);
     307             :     // Default line width is 0.75 pt (26 mm100) in Word, 0 in Writer.
     308         346 :     uno::Any aLineWidth = uno::makeAny(sal_Int32(26));
     309         192 :     text::WritingMode eWritingMode = text::WritingMode_LR_TB;
     310             :     // Groupshape support
     311         346 :     boost::optional<sal_Int32> oGroupLeft, oGroupTop, oGroupRight, oGroupBottom;
     312         346 :     boost::optional<sal_Int32> oRelLeft, oRelTop, oRelRight, oRelBottom;
     313             : 
     314             :     // Importing these are not trivial, let the VML import do the hard work.
     315         346 :     oox::vml::FillModel aFillModel; // Gradient.
     316         346 :     oox::vml::ShadowModel aShadowModel; // Shadow.
     317             : 
     318         192 :     bool bOpaque = true;
     319             : 
     320         346 :     boost::optional<sal_Int16> oRelativeWidth, oRelativeHeight;
     321         192 :     sal_Int16 nRelativeWidthRelation = text::RelOrientation::PAGE_FRAME;
     322         192 :     sal_Int16 nRelativeHeightRelation = text::RelOrientation::PAGE_FRAME;
     323             : 
     324         192 :     bool bCustom(false);
     325         192 :     int const nType = initShape(xShape, xPropertySet, bCustom, rShape, bClose, shapeOrPict);
     326             : 
     327        5682 :     for (std::vector< std::pair<OUString, OUString> >::iterator i = rShape.aProperties.begin();
     328        3788 :             i != rShape.aProperties.end(); ++i)
     329             :     {
     330        1702 :         if (i->first == "shapeType")
     331             :         {
     332         182 :             continue; // ignore: already handled by initShape
     333             :         }
     334        1520 :         else if (i->first == "wzName")
     335             :         {
     336          14 :             if (m_bTextFrame)
     337             :             {
     338           0 :                 uno::Reference<container::XNamed> xNamed(xShape, uno::UNO_QUERY);
     339           0 :                 xNamed->setName(i->second);
     340             :             }
     341             :             else
     342          14 :                 xPropertySet->setPropertyValue("Name", uno::makeAny(i->second));
     343             :         }
     344        1506 :         else if (i->first == "wzDescription")
     345          26 :             xPropertySet->setPropertyValue("Description", uno::makeAny(i->second));
     346        1480 :         else if (i->first == "pib")
     347             :         {
     348          26 :             m_rImport.setDestinationText(i->second);
     349          26 :             bPib = true;
     350             :         }
     351        1454 :         else if (i->first == "fillColor" && xPropertySet.is())
     352             :         {
     353          50 :             aAny <<= msfilter::util::BGRToRGB(i->second.toUInt32());
     354          50 :             if (m_bTextFrame)
     355          20 :                 xPropertySet->setPropertyValue("BackColor", aAny);
     356             :             else
     357          30 :                 xPropertySet->setPropertyValue("FillColor", aAny);
     358             : 
     359             :             // fillType will decide, possible it'll be the start color of a gradient.
     360          50 :             aFillModel.moColor.set(OUString("#") + OStringToOUString(msfilter::util::ConvertColor(aAny.get<sal_Int32>()), RTL_TEXTENCODING_UTF8));
     361             :         }
     362        1404 :         else if (i->first == "fillBackColor")
     363             :             // fillType will decide, possible it'll be the end color of a gradient.
     364          18 :             aFillModel.moColor2.set(OUString("#") + OStringToOUString(msfilter::util::ConvertColor(msfilter::util::BGRToRGB(i->second.toInt32())), RTL_TEXTENCODING_UTF8));
     365        1386 :         else if (i->first == "lineColor")
     366          48 :             aLineColor <<= msfilter::util::BGRToRGB(i->second.toInt32());
     367        1338 :         else if (i->first == "lineBackColor")
     368             :             ; // Ignore: complementer of lineColor
     369        1334 :         else if (i->first == "txflTextFlow" && xPropertySet.is())
     370             :         {
     371           4 :             if (i->second.toInt32() == 1)
     372           0 :                 eWritingMode = text::WritingMode_TB_RL;
     373             :         }
     374        1330 :         else if (i->first == "fLine" && xPropertySet.is())
     375          24 :             resolveFLine(xPropertySet, i->second.toInt32());
     376        1306 :         else if (i->first == "fillOpacity" && xPropertySet.is())
     377             :         {
     378           0 :             int opacity = 100 - (i->second.toInt32())*100/65536;
     379           0 :             aAny <<= uno::makeAny(sal_uInt32(opacity));
     380           0 :             xPropertySet->setPropertyValue("FillTransparence", aAny);
     381             :         }
     382        1306 :         else if (i->first == "lineWidth")
     383          50 :             aLineWidth <<= i->second.toInt32()/360;
     384        1256 :         else if (i->first == "pVerticies")
     385             :         {
     386          10 :             comphelper::SequenceAsVector<drawing::EnhancedCustomShapeParameterPair> aCoordinates;
     387          10 :             sal_Int32 nSize = 0; // Size of a token (its value is hardwired in the exporter)
     388          10 :             sal_Int32 nCount = 0; // Number of tokens
     389          10 :             sal_Int32 nCharIndex = 0; // Character index
     390         280 :             do
     391             :             {
     392         280 :                 OUString aToken = i->second.getToken(0, ';', nCharIndex);
     393         280 :                 if (!nSize)
     394          10 :                     nSize = aToken.toInt32();
     395         270 :                 else if (!nCount)
     396          10 :                     nCount = aToken.toInt32();
     397         260 :                 else if (aToken.getLength())
     398             :                 {
     399             :                     // The coordinates are in an (x,y) form.
     400         260 :                     aToken = aToken.copy(1, aToken.getLength() - 2);
     401         260 :                     sal_Int32 nI = 0;
     402         260 :                     boost::optional<sal_Int32> oX;
     403         520 :                     boost::optional<sal_Int32> oY;
     404         520 :                     do
     405             :                     {
     406         520 :                         OUString aPoint = aToken.getToken(0, ',', nI);
     407         520 :                         if (!oX)
     408         260 :                             oX.reset(aPoint.toInt32());
     409             :                         else
     410         260 :                             oY.reset(aPoint.toInt32());
     411             :                     }
     412         520 :                     while (nI >= 0);
     413         520 :                     drawing::EnhancedCustomShapeParameterPair aPair;
     414         260 :                     aPair.First.Value <<= *oX;
     415         260 :                     aPair.Second.Value <<= *oY;
     416         520 :                     aCoordinates.push_back(aPair);
     417         280 :                 }
     418             :             }
     419         280 :             while (nCharIndex >= 0);
     420          10 :             aPropertyValue.Name = "Coordinates";
     421          10 :             aPropertyValue.Value <<= aCoordinates.getAsConstList();
     422          10 :             aPath.push_back(aPropertyValue);
     423             :         }
     424        1246 :         else if (i->first == "pSegmentInfo")
     425             :         {
     426          10 :             comphelper::SequenceAsVector<drawing::EnhancedCustomShapeSegment> aSegments;
     427          10 :             sal_Int32 nSize = 0;
     428          10 :             sal_Int32 nCount = 0;
     429          10 :             sal_Int32 nCharIndex = 0;
     430          82 :             do
     431             :             {
     432          82 :                 sal_Int32 nSeg = i->second.getToken(0, ';', nCharIndex).toInt32();
     433          82 :                 if (!nSize)
     434          10 :                     nSize = nSeg;
     435          72 :                 else if (!nCount)
     436          10 :                     nCount = nSeg;
     437             :                 else
     438             :                 {
     439          62 :                     sal_Int32 nPoints = 1;
     440          62 :                     if (nSeg >= 0x2000 && nSeg < 0x20FF)
     441             :                     {
     442          12 :                         nPoints = nSeg & 0x0FFF;
     443          12 :                         nSeg &= 0xFF00;
     444             :                     }
     445             : 
     446          62 :                     drawing::EnhancedCustomShapeSegment aSegment;
     447          62 :                     switch (nSeg)
     448             :                     {
     449             :                     case 0x0001: // lineto
     450           6 :                         aSegment.Command = drawing::EnhancedCustomShapeSegmentCommand::LINETO;
     451           6 :                         aSegment.Count = sal_Int32(1);
     452           6 :                         aSegments.push_back(aSegment);
     453           6 :                         break;
     454             :                     case 0x4000: // moveto
     455          14 :                         aSegment.Command = drawing::EnhancedCustomShapeSegmentCommand::MOVETO;
     456          14 :                         aSegment.Count = sal_Int32(1);
     457          14 :                         aSegments.push_back(aSegment);
     458          14 :                         break;
     459             :                     case 0x2000: // curveto
     460          12 :                         aSegment.Command = drawing::EnhancedCustomShapeSegmentCommand::CURVETO;
     461          12 :                         aSegment.Count = sal_Int32(nPoints);
     462          12 :                         aSegments.push_back(aSegment);
     463          12 :                         break;
     464             :                     case 0xb300: // arcto
     465           0 :                         aSegment.Command = drawing::EnhancedCustomShapeSegmentCommand::ARCTO;
     466           0 :                         aSegment.Count = sal_Int32(0);
     467           0 :                         aSegments.push_back(aSegment);
     468           0 :                         break;
     469             :                     case 0xac00:
     470             :                     case 0xaa00: // nofill
     471             :                     case 0xab00: // nostroke
     472             :                     case 0x6001: // close
     473           6 :                         break;
     474             :                     case 0x8000: // end
     475          14 :                         aSegment.Command = drawing::EnhancedCustomShapeSegmentCommand::ENDSUBPATH;
     476          14 :                         aSegment.Count = sal_Int32(0);
     477          14 :                         aSegments.push_back(aSegment);
     478          14 :                         break;
     479             :                     default: // given number of lineto elements
     480          10 :                         aSegment.Command = drawing::EnhancedCustomShapeSegmentCommand::LINETO;
     481          10 :                         aSegment.Count = nSeg;
     482          10 :                         aSegments.push_back(aSegment);
     483          10 :                         break;
     484             :                     }
     485             :                 }
     486             :             }
     487          82 :             while (nCharIndex >= 0);
     488          10 :             aPropertyValue.Name = "Segments";
     489          10 :             aPropertyValue.Value <<= aSegments.getAsConstList();
     490          10 :             aPath.push_back(aPropertyValue);
     491             :         }
     492        1236 :         else if (i->first == "geoLeft")
     493           4 :             aViewBox.X = i->second.toInt32();
     494        1232 :         else if (i->first == "geoTop")
     495           4 :             aViewBox.Y = i->second.toInt32();
     496        1228 :         else if (i->first == "geoRight")
     497           8 :             aViewBox.Width = i->second.toInt32();
     498        1220 :         else if (i->first == "geoBottom")
     499           8 :             aViewBox.Height = i->second.toInt32();
     500        1212 :         else if (i->first == "dhgt")
     501             :         {
     502             :             // dhgt is Word 2007, \shpz is Word 97-2003, the later has priority.
     503          26 :             if (!rShape.oZ)
     504           0 :                 resolveDhgt(xPropertySet, i->second.toInt32(), /*bOldStyle=*/false);
     505             :         }
     506             :         // These are in EMU, convert to mm100.
     507        1186 :         else if (i->first == "dxTextLeft")
     508             :         {
     509          36 :             if (xPropertySet.is())
     510          28 :                 xPropertySet->setPropertyValue("LeftBorderDistance", uno::makeAny(i->second.toInt32() / 360));
     511             :         }
     512        1150 :         else if (i->first == "dyTextTop")
     513             :         {
     514          36 :             if (xPropertySet.is())
     515          28 :                 xPropertySet->setPropertyValue("TopBorderDistance", uno::makeAny(i->second.toInt32() / 360));
     516             :         }
     517        1114 :         else if (i->first == "dxTextRight")
     518             :         {
     519          36 :             if (xPropertySet.is())
     520          28 :                 xPropertySet->setPropertyValue("RightBorderDistance", uno::makeAny(i->second.toInt32() / 360));
     521             :         }
     522        1078 :         else if (i->first == "dyTextBottom")
     523             :         {
     524          36 :             if (xPropertySet.is())
     525          28 :                 xPropertySet->setPropertyValue("BottomBorderDistance", uno::makeAny(i->second.toInt32() / 360));
     526             :         }
     527        1042 :         else if (i->first == "dxWrapDistLeft")
     528             :         {
     529          20 :             if (xPropertySet.is())
     530          20 :                 xPropertySet->setPropertyValue("LeftMargin", uno::makeAny(i->second.toInt32() / 360));
     531             :         }
     532        1022 :         else if (i->first == "dyWrapDistTop")
     533             :         {
     534          20 :             if (xPropertySet.is())
     535          20 :                 xPropertySet->setPropertyValue("TopMargin", uno::makeAny(i->second.toInt32() / 360));
     536             :         }
     537        1002 :         else if (i->first == "dxWrapDistRight")
     538             :         {
     539          20 :             if (xPropertySet.is())
     540          20 :                 xPropertySet->setPropertyValue("RightMargin", uno::makeAny(i->second.toInt32() / 360));
     541             :         }
     542         982 :         else if (i->first == "dyWrapDistBottom")
     543             :         {
     544          20 :             if (xPropertySet.is())
     545          20 :                 xPropertySet->setPropertyValue("BottomMargin", uno::makeAny(i->second.toInt32() / 360));
     546             :         }
     547         962 :         else if (i->first == "fillType")
     548             :         {
     549          12 :             switch (i->second.toInt32())
     550             :             {
     551             :             case 7: // Shade using the fillAngle
     552          12 :                 aFillModel.moType.set(oox::XML_gradient);
     553          12 :                 break;
     554             :             default:
     555             :                 SAL_INFO("writerfilter", "TODO handle fillType value '" << i->second << "'");
     556           0 :                 break;
     557             :             }
     558             :         }
     559         950 :         else if (i->first == "fillFocus")
     560          12 :             aFillModel.moFocus.set(i->second.toDouble() / 100); // percent
     561         938 :         else if (i->first == "fShadow" && xPropertySet.is())
     562             :         {
     563          30 :             if (i->second.toInt32() == 1)
     564          24 :                 aShadowModel.mbHasShadow = true;
     565             :         }
     566         908 :         else if (i->first == "shadowColor")
     567          24 :             aShadowModel.moColor.set(OUString("#") + OStringToOUString(msfilter::util::ConvertColor(msfilter::util::BGRToRGB(i->second.toInt32())), RTL_TEXTENCODING_UTF8));
     568         884 :         else if (i->first == "shadowOffsetX")
     569             :             // EMUs to points
     570          24 :             aShadowModel.moOffset.set(OUString::number(i->second.toDouble() / 12700) + "pt");
     571         860 :         else if (i->first == "posh" || i->first == "posv" || i->first == "fFitShapeToText" || i->first == "fFilled" || i->first == "rotation")
     572          88 :             applyProperty(xShape, i->first, i->second);
     573         772 :         else if (i->first == "posrelh")
     574             :         {
     575          48 :             switch (i->second.toInt32())
     576             :             {
     577             :             case 1:
     578          14 :                 rShape.nHoriOrientRelation = text::RelOrientation::PAGE_FRAME;
     579          14 :                 break;
     580             :             default:
     581          34 :                 break;
     582             :             }
     583             :         }
     584         724 :         else if (i->first == "posrelv")
     585             :         {
     586          44 :             switch (i->second.toInt32())
     587             :             {
     588             :             case 1:
     589          14 :                 rShape.nVertOrientRelation = text::RelOrientation::PAGE_FRAME;
     590          14 :                 break;
     591             :             default:
     592          30 :                 break;
     593             :             }
     594             :         }
     595         680 :         else if (i->first == "groupLeft")
     596          24 :             oGroupLeft.reset(convertTwipToMm100(i->second.toInt32()));
     597         656 :         else if (i->first == "groupTop")
     598          24 :             oGroupTop.reset(convertTwipToMm100(i->second.toInt32()));
     599         632 :         else if (i->first == "groupRight")
     600          24 :             oGroupRight.reset(convertTwipToMm100(i->second.toInt32()));
     601         608 :         else if (i->first == "groupBottom")
     602          24 :             oGroupBottom.reset(convertTwipToMm100(i->second.toInt32()));
     603         584 :         else if (i->first == "relLeft")
     604          24 :             oRelLeft.reset(convertTwipToMm100(i->second.toInt32()));
     605         560 :         else if (i->first == "relTop")
     606          24 :             oRelTop.reset(convertTwipToMm100(i->second.toInt32()));
     607         536 :         else if (i->first == "relRight")
     608          24 :             oRelRight.reset(convertTwipToMm100(i->second.toInt32()));
     609         512 :         else if (i->first == "relBottom")
     610          24 :             oRelBottom.reset(convertTwipToMm100(i->second.toInt32()));
     611         488 :         else if (i->first == "fBehindDocument")
     612          28 :             bOpaque = !i->second.toInt32();
     613         460 :         else if (i->first == "pctHoriz" || i->first == "pctVert")
     614             :         {
     615          12 :             sal_Int16 nPercentage = rtl::math::round(i->second.toDouble() / 10);
     616          12 :             boost::optional<sal_Int16>& rPercentage = i->first == "pctHoriz" ? oRelativeWidth : oRelativeHeight;
     617          12 :             if (nPercentage)
     618          12 :                 rPercentage = nPercentage;
     619             :         }
     620         448 :         else if (i->first == "sizerelh")
     621             :         {
     622           2 :             if (xPropertySet.is())
     623             :             {
     624           2 :                 switch (i->second.toInt32())
     625             :                 {
     626             :                 case 0: // margin
     627           0 :                     nRelativeWidthRelation = text::RelOrientation::FRAME;
     628           0 :                     break;
     629             :                 case 1: // page
     630           2 :                     nRelativeWidthRelation = text::RelOrientation::PAGE_FRAME;
     631           2 :                     break;
     632             :                 default:
     633             :                     SAL_WARN("writerfilter", "RTFSdrImport::resolve: unhandled sizerelh value: " << i->second);
     634           0 :                     break;
     635             :                 }
     636             :             }
     637             :         }
     638         446 :         else if (i->first == "sizerelv")
     639             :         {
     640           6 :             if (xPropertySet.is())
     641             :             {
     642           6 :                 switch (i->second.toInt32())
     643             :                 {
     644             :                 case 0: // margin
     645           6 :                     nRelativeHeightRelation = text::RelOrientation::FRAME;
     646           6 :                     break;
     647             :                 case 1: // page
     648           0 :                     nRelativeHeightRelation = text::RelOrientation::PAGE_FRAME;
     649           0 :                     break;
     650             :                 default:
     651             :                     SAL_WARN("writerfilter", "RTFSdrImport::resolve: unhandled sizerelv value: " << i->second);
     652           0 :                     break;
     653             :                 }
     654             :             }
     655             :         }
     656         440 :         else if (i->first == "fHorizRule") // TODO: what does "fStandardHR" do?
     657             :         {
     658             :             // horizontal rule: relative width defaults to 100% of paragraph
     659             :             // TODO: does it have a default height?
     660           2 :             if (!oRelativeWidth)
     661             :             {
     662           2 :                 oRelativeWidth = 100;
     663             :             }
     664           2 :             nRelativeWidthRelation = text::RelOrientation::FRAME;
     665           2 :             sal_Int16 const nVertOrient = text::VertOrientation::CENTER;
     666           2 :             if (xPropertySet.is())
     667             :             {
     668           2 :                 xPropertySet->setPropertyValue("VertOrient", uno::makeAny(nVertOrient));
     669             :             }
     670             :         }
     671         438 :         else if (i->first == "pctHR")
     672             :         {
     673             :             // horizontal rule relative width in permille
     674           0 :             oRelativeWidth = i->second.toInt32() / 10;
     675             :         }
     676         438 :         else if (i->first == "dxHeightHR")
     677             :         {
     678             :             // horizontal rule height
     679           2 :             sal_uInt32 const nHeight(convertTwipToMm100(i->second.toInt32()));
     680           2 :             rShape.nBottom = rShape.nTop + nHeight;
     681             :         }
     682         436 :         else if (i->first == "dxWidthHR")
     683             :         {
     684             :             // horizontal rule width
     685           0 :             sal_uInt32 const nWidth(convertTwipToMm100(i->second.toInt32()));
     686           0 :             rShape.nRight = rShape.nLeft + nWidth;
     687             :         }
     688         436 :         else if (i->first == "alignHR")
     689             :         {
     690             :             // horizontal orientation *for horizontal rule*
     691           2 :             sal_Int16 nHoriOrient = text::HoriOrientation::NONE;
     692           2 :             switch (i->second.toInt32())
     693             :             {
     694             :             case 0:
     695           0 :                 nHoriOrient = text::HoriOrientation::LEFT;
     696           0 :                 break;
     697             :             case 1:
     698           2 :                 nHoriOrient = text::HoriOrientation::CENTER;
     699           2 :                 break;
     700             :             case 2:
     701           0 :                 nHoriOrient = text::HoriOrientation::RIGHT;
     702           0 :                 break;
     703             :             }
     704           2 :             if (xPropertySet.is() && text::HoriOrientation::NONE != nHoriOrient)
     705             :             {
     706           2 :                 xPropertySet->setPropertyValue("HoriOrient", uno::makeAny(nHoriOrient));
     707             :             }
     708             :         }
     709         434 :         else if (i->first == "pWrapPolygonVertices")
     710             :         {
     711           6 :             RTFSprms aPolygonSprms;
     712           6 :             sal_Int32 nSize = 0; // Size of a token
     713           6 :             sal_Int32 nCount = 0; // Number of tokens
     714           6 :             sal_Int32 nCharIndex = 0; // Character index
     715          78 :             do
     716             :             {
     717          78 :                 OUString aToken = i->second.getToken(0, ';', nCharIndex);
     718          78 :                 if (!nSize)
     719           6 :                     nSize = aToken.toInt32();
     720          72 :                 else if (!nCount)
     721           6 :                     nCount = aToken.toInt32();
     722          66 :                 else if (aToken.getLength())
     723             :                 {
     724             :                     // The coordinates are in an (x,y) form.
     725          66 :                     aToken = aToken.copy(1, aToken.getLength() - 2);
     726          66 :                     sal_Int32 nI = 0;
     727          66 :                     boost::optional<sal_Int32> oX;
     728         132 :                     boost::optional<sal_Int32> oY;
     729         132 :                     do
     730             :                     {
     731         132 :                         OUString aPoint = aToken.getToken(0, ',', nI);
     732         132 :                         if (!oX)
     733          66 :                             oX.reset(aPoint.toInt32());
     734             :                         else
     735          66 :                             oY.reset(aPoint.toInt32());
     736             :                     }
     737         132 :                     while (nI >= 0);
     738         132 :                     RTFSprms aPathAttributes;
     739          66 :                     aPathAttributes.set(NS_ooxml::LN_CT_Point2D_x, RTFValue::Pointer_t(new RTFValue(*oX)));
     740          66 :                     aPathAttributes.set(NS_ooxml::LN_CT_Point2D_y, RTFValue::Pointer_t(new RTFValue(*oY)));
     741         132 :                     aPolygonSprms.set(NS_ooxml::LN_CT_WrapPath_lineTo, RTFValue::Pointer_t(new RTFValue(aPathAttributes)), OVERWRITE_NO_APPEND);
     742          78 :                 }
     743             :             }
     744          78 :             while (nCharIndex >= 0);
     745           6 :             rShape.aWrapPolygonSprms = aPolygonSprms;
     746             :         }
     747             :         else
     748             :             SAL_INFO("writerfilter", "TODO handle shape property '" << i->first << "':'" << i->second << "'");
     749             :     }
     750             : 
     751         192 :     if (xPropertySet.is())
     752             :     {
     753         174 :         if (!m_bTextFrame)
     754             :         {
     755         104 :             xPropertySet->setPropertyValue("LineColor", aLineColor);
     756         104 :             xPropertySet->setPropertyValue("LineWidth", aLineWidth);
     757             :         }
     758             :         else
     759             :         {
     760             :             static const OUString aBorders[] =
     761             :             {
     762             :                 OUString("TopBorder"), OUString("LeftBorder"), OUString("BottomBorder"), OUString("RightBorder")
     763          76 :             };
     764         350 :             for (unsigned int i = 0; i < SAL_N_ELEMENTS(aBorders); ++i)
     765             :             {
     766         280 :                 table::BorderLine2 aBorderLine = xPropertySet->getPropertyValue(aBorders[i]).get<table::BorderLine2>();
     767         280 :                 aBorderLine.Color = aLineColor.get<sal_Int32>();
     768         280 :                 aBorderLine.LineWidth = aLineWidth.get<sal_Int32>();
     769         280 :                 xPropertySet->setPropertyValue(aBorders[i], uno::makeAny(aBorderLine));
     770             :             }
     771             :         }
     772         174 :         if (rShape.oZ)
     773         108 :             resolveDhgt(xPropertySet, *rShape.oZ, /*bOldStyle=*/false);
     774         174 :         if (m_bTextFrame)
     775             :             // Writer textframes implement text::WritingMode2, which is a different data type.
     776          70 :             xPropertySet->setPropertyValue("WritingMode", uno::makeAny(sal_Int16(eWritingMode)));
     777             :         else
     778         104 :             xPropertySet->setPropertyValue("TextWritingMode", uno::makeAny(eWritingMode));
     779             :     }
     780             : 
     781         192 :     if (m_aParents.size() && m_aParents.top().is() && !m_bTextFrame)
     782         104 :         m_aParents.top()->add(xShape);
     783             : 
     784         192 :     if (nType == ESCHER_ShpInst_PictureFrame) // picture frame
     785             :     {
     786             :         assert(!m_bTextFrame);
     787          36 :         if (bPib)
     788             :         {
     789          26 :             m_rImport.resolvePict(false, xShape);
     790             :         }
     791             :         else // ??? not sure if the early return should be removed on else?
     792             :         {
     793          10 :             m_xShape = xShape; // store it for later resolvePict call
     794             :         }
     795          36 :         return;
     796             :     }
     797             : 
     798         156 :     if (bCustom && xShape.is())
     799             :     {
     800          64 :         uno::Reference<drawing::XEnhancedCustomShapeDefaulter> xDefaulter(xShape, uno::UNO_QUERY);
     801          64 :         xDefaulter->createCustomShapeDefaults(OUString::number(nType));
     802             :     }
     803             : 
     804             :     // Creating CustomShapeGeometry property
     805         156 :     comphelper::SequenceAsVector<beans::PropertyValue> aGeometry;
     806         156 :     if (aViewBox.X || aViewBox.Y || aViewBox.Width || aViewBox.Height)
     807             :     {
     808           8 :         aViewBox.Width -= aViewBox.X;
     809           8 :         aViewBox.Height -= aViewBox.Y;
     810           8 :         aPropertyValue.Name = "ViewBox";
     811           8 :         aPropertyValue.Value <<= aViewBox;
     812           8 :         aGeometry.push_back(aPropertyValue);
     813             :     }
     814         156 :     if (!aPath.empty())
     815             :     {
     816          10 :         aPropertyValue.Name = "Path";
     817          10 :         aPropertyValue.Value <<= aPath.getAsConstList();
     818          10 :         aGeometry.push_back(aPropertyValue);
     819             :     }
     820         156 :     if (!aGeometry.empty() && xPropertySet.is() && !m_bTextFrame)
     821           8 :         xPropertySet->setPropertyValue("CustomShapeGeometry", uno::Any(aGeometry.getAsConstList()));
     822             : 
     823             :     // Set position and size
     824         156 :     if (xShape.is())
     825             :     {
     826         142 :         sal_Int32 nLeft = rShape.nLeft;
     827         142 :         sal_Int32 nTop = rShape.nTop;
     828             : 
     829         166 :         bool bInShapeGroup = oGroupLeft && oGroupTop && oGroupRight && oGroupBottom
     830         166 :                              && oRelLeft && oRelTop && oRelRight && oRelBottom;
     831         142 :         if (bInShapeGroup)
     832             :         {
     833             :             // See lclGetAbsPoint() in the VML import: rShape is the group shape, oGroup is its coordinate system, oRel is the relative child shape.
     834          24 :             sal_Int32 nShapeWidth = rShape.nRight - rShape.nLeft;
     835          24 :             sal_Int32 nShapeHeight = rShape.nBottom - rShape.nTop;
     836          24 :             sal_Int32 nCoordSysWidth = *oGroupRight - *oGroupLeft;
     837          24 :             sal_Int32 nCoordSysHeight = *oGroupBottom - *oGroupTop;
     838          24 :             double fWidthRatio = static_cast< double >(nShapeWidth) / nCoordSysWidth;
     839          24 :             double fHeightRatio = static_cast< double >(nShapeHeight) / nCoordSysHeight;
     840          24 :             nLeft = static_cast< sal_Int32 >(rShape.nLeft + fWidthRatio * (*oRelLeft - *oGroupLeft));
     841          24 :             nTop = static_cast< sal_Int32 >(rShape.nTop + fHeightRatio * (*oRelTop - *oGroupTop));
     842             :         }
     843             : 
     844         142 :         if (m_bTextFrame)
     845             :         {
     846          70 :             xPropertySet->setPropertyValue("HoriOrientPosition", uno::makeAny(nLeft));
     847          70 :             xPropertySet->setPropertyValue("VertOrientPosition", uno::makeAny(nTop));
     848             :         }
     849             :         else
     850          72 :             xShape->setPosition(awt::Point(nLeft, nTop));
     851             : 
     852         142 :         if (bInShapeGroup)
     853          24 :             xShape->setSize(awt::Size(*oRelRight - *oRelLeft, *oRelBottom - *oRelTop));
     854             :         else
     855         118 :             xShape->setSize(awt::Size(rShape.nRight - rShape.nLeft, rShape.nBottom - rShape.nTop));
     856             : 
     857         142 :         if (rShape.nHoriOrientRelation != 0)
     858          36 :             xPropertySet->setPropertyValue("HoriOrientRelation", uno::makeAny(rShape.nHoriOrientRelation));
     859         142 :         if (rShape.nVertOrientRelation != 0)
     860          34 :             xPropertySet->setPropertyValue("VertOrientRelation", uno::makeAny(rShape.nVertOrientRelation));
     861         142 :         if (rShape.nWrap != -1)
     862         122 :             xPropertySet->setPropertyValue("Surround", uno::makeAny(text::WrapTextMode(rShape.nWrap)));
     863         142 :         oox::ModelObjectHelper aModelObjectHelper(m_rImport.getModelFactory());
     864         142 :         if (aFillModel.moType.has())
     865             :         {
     866          12 :             oox::drawingml::ShapePropertyMap aPropMap(aModelObjectHelper);
     867          12 :             aFillModel.pushToPropMap(aPropMap, m_rImport.getGraphicHelper());
     868             :             // Sets the FillStyle and FillGradient UNO properties.
     869          12 :             oox::PropertySet(xShape).setProperties(aPropMap);
     870             :         }
     871             : 
     872         142 :         if (aShadowModel.mbHasShadow)
     873             :         {
     874          24 :             oox::drawingml::ShapePropertyMap aPropMap(aModelObjectHelper);
     875          24 :             aShadowModel.pushToPropMap(aPropMap, m_rImport.getGraphicHelper());
     876             :             // Sets the ShadowFormat UNO property.
     877          24 :             oox::PropertySet(xShape).setProperties(aPropMap);
     878             :         }
     879         142 :         xPropertySet->setPropertyValue("AnchorType", uno::makeAny(text::TextContentAnchorType_AT_CHARACTER));
     880         142 :         xPropertySet->setPropertyValue("Opaque", uno::makeAny(bOpaque));
     881         142 :         if (oRelativeWidth)
     882             :         {
     883           8 :             xPropertySet->setPropertyValue("RelativeWidth", uno::makeAny(*oRelativeWidth));
     884           8 :             xPropertySet->setPropertyValue("RelativeWidthRelation", uno::makeAny(nRelativeWidthRelation));
     885             :         }
     886         142 :         if (oRelativeHeight)
     887             :         {
     888           6 :             xPropertySet->setPropertyValue("RelativeHeight", uno::makeAny(*oRelativeHeight));
     889           6 :             xPropertySet->setPropertyValue("RelativeHeightRelation", uno::makeAny(nRelativeHeightRelation));
     890         142 :         }
     891             :     }
     892             : 
     893         156 :     if (m_rImport.isInBackground())
     894             :     {
     895           2 :         RTFSprms aAttributes;
     896           2 :         aAttributes.set(NS_ooxml::LN_CT_Background_color, RTFValue::Pointer_t(new RTFValue(xPropertySet->getPropertyValue("FillColor").get<sal_Int32>())));
     897           4 :         writerfilter::Reference<Properties>::Pointer_t const pProperties(new RTFReferenceProperties(aAttributes));
     898           2 :         m_rImport.Mapper().props(pProperties);
     899             : 
     900           4 :         uno::Reference<lang::XComponent> xComponent(xShape, uno::UNO_QUERY);
     901           2 :         xComponent->dispose();
     902           4 :         return;
     903             :     }
     904             : 
     905             :     // Send it to dmapper
     906         154 :     m_rImport.Mapper().startShape(xShape);
     907         154 :     if (bClose)
     908             :     {
     909          66 :         m_rImport.Mapper().endShape();
     910             :     }
     911         308 :     m_xShape = xShape;
     912             : }
     913             : 
     914          88 : void RTFSdrImport::close()
     915             : {
     916          88 :     m_rImport.Mapper().endShape();
     917          88 : }
     918             : 
     919          20 : void RTFSdrImport::append(const OUString& aKey, const OUString& aValue)
     920             : {
     921          20 :     applyProperty(m_xShape, aKey, aValue);
     922          20 : }
     923             : 
     924           4 : void RTFSdrImport::appendGroupProperty(const OUString& aKey, const OUString& aValue)
     925             : {
     926           4 :     uno::Reference<drawing::XShape> xShape(m_aParents.top(), uno::UNO_QUERY);
     927           4 :     if (xShape.is())
     928           2 :         applyProperty(xShape, aKey, aValue);
     929           4 : }
     930             : 
     931             : } // namespace rtftok
     932         114 : } // namespace writerfilter
     933             : 
     934             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10