LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/writerfilter/source/rtftok - rtfsdrimport.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 393 417 94.2 %
Date: 2013-07-09 Functions: 14 14 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/EnhancedCustomShapeParameterPair.hpp>
      16             : #include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.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             : 
      25             : #include <ooxml/resourceids.hxx> // NS_ooxml namespace
      26             : #include <filter/msfilter/escherex.hxx>
      27             : #include <filter/msfilter/util.hxx>
      28             : 
      29             : #include <dmapper/DomainMapper.hxx>
      30             : #include "../dmapper/GraphicHelpers.hxx"
      31             : #include <rtfsdrimport.hxx>
      32             : #include <rtfreferenceproperties.hxx>
      33             : 
      34             : #include <oox/vml/vmlformatting.hxx>
      35             : #include <oox/helper/modelobjecthelper.hxx>
      36             : #include <oox/drawingml/shapepropertymap.hxx>
      37             : #include <oox/helper/propertyset.hxx>
      38             : 
      39             : #define TWIP_TO_MM100(TWIP)     ((TWIP) >= 0 ? (((TWIP)*127L+36L)/72L) : (((TWIP)*127L-36L)/72L))
      40             : 
      41             : namespace writerfilter {
      42             : namespace rtftok {
      43             : 
      44         206 : RTFSdrImport::RTFSdrImport(RTFDocumentImpl& rDocument,
      45             :         uno::Reference<lang::XComponent> const& xDstDoc)
      46         206 :     : m_rImport(rDocument)
      47             : {
      48         206 :     uno::Reference<drawing::XDrawPageSupplier> xDrawings(xDstDoc, uno::UNO_QUERY);
      49         206 :     if (xDrawings.is())
      50         193 :         m_xDrawPage.set(xDrawings->getDrawPage(), uno::UNO_QUERY);
      51         206 : }
      52             : 
      53         412 : RTFSdrImport::~RTFSdrImport()
      54             : {
      55         412 : }
      56             : 
      57          68 : void RTFSdrImport::createShape(OUString aStr, uno::Reference<drawing::XShape>& xShape, uno::Reference<beans::XPropertySet>& xPropertySet)
      58             : {
      59          68 :     if (m_rImport.getModelFactory().is())
      60          67 :         xShape.set(m_rImport.getModelFactory()->createInstance(aStr), uno::UNO_QUERY);
      61          68 :     xPropertySet.set(xShape, uno::UNO_QUERY);
      62          68 : }
      63             : 
      64          27 : std::vector<beans::PropertyValue> RTFSdrImport::getTextFrameDefaults(bool bNew)
      65             : {
      66          27 :     std::vector<beans::PropertyValue> aRet;
      67          54 :     beans::PropertyValue aPropertyValue;
      68             : 
      69          27 :     aPropertyValue.Name = "HoriOrient";
      70          27 :     aPropertyValue.Value <<= text::HoriOrientation::NONE;
      71          27 :     aRet.push_back(aPropertyValue);
      72          27 :     aPropertyValue.Name = "HoriOrientRelation";
      73          27 :     aPropertyValue.Value <<= text::RelOrientation::FRAME;
      74          27 :     aRet.push_back(aPropertyValue);
      75          27 :     aPropertyValue.Name = "VertOrient";
      76          27 :     aPropertyValue.Value <<= text::VertOrientation::NONE;
      77          27 :     aRet.push_back(aPropertyValue);
      78          27 :     aPropertyValue.Name = "VertOrientRelation";
      79          27 :     aPropertyValue.Value <<= text::RelOrientation::FRAME;
      80          27 :     aRet.push_back(aPropertyValue);
      81          27 :     if (!bNew)
      82             :     {
      83           7 :         aPropertyValue.Name = "BackColorTransparency";
      84           7 :         aPropertyValue.Value <<= sal_Int32(100);
      85           7 :         aRet.push_back(aPropertyValue);
      86             :     }
      87             :     // See the spec, new-style frame default margins are specified in EMUs.
      88          27 :     aPropertyValue.Name = "LeftBorderDistance";
      89          27 :     aPropertyValue.Value <<= sal_Int32(bNew ? (91440 / 360) : 0);
      90          27 :     aRet.push_back(aPropertyValue);
      91          27 :     aPropertyValue.Name = "RightBorderDistance";
      92          27 :     aPropertyValue.Value <<= sal_Int32(bNew ? (91440 / 360) : 0);
      93          27 :     aRet.push_back(aPropertyValue);
      94          27 :     aPropertyValue.Name = "TopBorderDistance";
      95          27 :     aPropertyValue.Value <<= sal_Int32(bNew ? (45720 / 360) : 0);
      96          27 :     aRet.push_back(aPropertyValue);
      97          27 :     aPropertyValue.Name = "BottomBorderDistance";
      98          27 :     aPropertyValue.Value <<= sal_Int32(bNew ? (45720 / 360) : 0);
      99          27 :     aRet.push_back(aPropertyValue);
     100          27 :     aPropertyValue.Name = "SizeType";
     101          27 :     aPropertyValue.Value <<= text::SizeType::FIX;
     102          27 :     aRet.push_back(aPropertyValue);
     103          54 :     return aRet;
     104             : }
     105             : 
     106          42 : void RTFSdrImport::resolveDhgt(uno::Reference<beans::XPropertySet> xPropertySet, sal_Int32 nZOrder)
     107             : {
     108          42 :     writerfilter::dmapper::DomainMapper& rMapper = (writerfilter::dmapper::DomainMapper&)m_rImport.Mapper();
     109          42 :     writerfilter::dmapper::GraphicZOrderHelper* pHelper = rMapper.graphicZOrderHelper();
     110          42 :     xPropertySet->setPropertyValue("ZOrder", uno::makeAny(pHelper->findZOrder(nZOrder)));
     111          42 :     pHelper->addItem(xPropertySet, nZOrder);
     112          42 : }
     113             : 
     114          23 : void RTFSdrImport::resolveFLine(uno::Reference<beans::XPropertySet> xPropertySet, sal_Int32 nFLine)
     115             : {
     116          23 :     if (nFLine == 0)
     117          10 :         xPropertySet->setPropertyValue("LineStyle", uno::makeAny(drawing::LineStyle_NONE));
     118          23 : }
     119             : 
     120          22 : void RTFSdrImport::applyProperty(uno::Reference<drawing::XShape> xShape, OUString aKey, OUString aValue)
     121             : {
     122          22 :     uno::Reference<beans::XPropertySet> xPropertySet(xShape, uno::UNO_QUERY);
     123          22 :     sal_Int16 nHoriOrient = 0;
     124          22 :     sal_Int16 nVertOrient = 0;
     125          44 :     boost::optional<bool> obFitShapeToText;
     126          22 :     bool bFilled = true;
     127             : 
     128          22 :     if (aKey == "posh")
     129             :     {
     130           5 :         switch (aValue.toInt32())
     131             :         {
     132             :             case 1:
     133           0 :                 nHoriOrient = text::HoriOrientation::LEFT;
     134           0 :                 break;
     135             :             case 2:
     136           5 :                 nHoriOrient = text::HoriOrientation::CENTER;
     137           5 :                 break;
     138             :             case 3:
     139           0 :                 nHoriOrient = text::HoriOrientation::RIGHT;
     140           0 :                 break;
     141             :             case 4:
     142           0 :                 nHoriOrient = text::HoriOrientation::INSIDE;
     143           0 :                 break;
     144             :             case 5:
     145           0 :                 nHoriOrient = text::HoriOrientation::OUTSIDE;
     146           0 :                 break;
     147             :             default:
     148           0 :                 break;
     149             :         }
     150             :     }
     151          17 :     else if (aKey == "posv")
     152             :     {
     153           3 :         switch (aValue.toInt32())
     154             :         {
     155             :             case 1:
     156           2 :                 nVertOrient = text::VertOrientation::TOP;
     157           2 :                 break;
     158             :             case 2:
     159           1 :                 nVertOrient = text::VertOrientation::CENTER;
     160           1 :                 break;
     161             :             case 3:
     162           0 :                 nVertOrient = text::VertOrientation::BOTTOM;
     163           0 :                 break;
     164             :             default:
     165           0 :                 break;
     166             :         }
     167             :     }
     168          14 :     else if (aKey == "fFitShapeToText")
     169           3 :         obFitShapeToText.reset(aValue.toInt32() == 1);
     170          11 :     else if (aKey == "fFilled")
     171          11 :         bFilled = aValue.toInt32() == 1;
     172             : 
     173          22 :     if (nHoriOrient != 0)
     174           5 :         xPropertySet->setPropertyValue("HoriOrient", uno::makeAny(nHoriOrient));
     175          22 :     if (nVertOrient != 0)
     176           3 :         xPropertySet->setPropertyValue("VertOrient", uno::makeAny(nVertOrient));
     177          22 :     if (obFitShapeToText)
     178             :     {
     179           3 :         xPropertySet->setPropertyValue("SizeType", uno::makeAny(*obFitShapeToText ? text::SizeType::MIN : text::SizeType::FIX));
     180           3 :         xPropertySet->setPropertyValue("FrameIsAutomaticHeight", uno::makeAny(*obFitShapeToText));
     181             :     }
     182          22 :     if (!bFilled)
     183          30 :         xPropertySet->setPropertyValue("BackColorTransparency", uno::makeAny(sal_Int32(100)));
     184          22 : }
     185             : 
     186          45 : void RTFSdrImport::resolve(RTFShape& rShape, bool bClose)
     187             : {
     188          45 :     int nType = -1;
     189          45 :     bool bPib = false;
     190          45 :     bool bCustom = false;
     191          45 :     bool bTextFrame = false;
     192             : 
     193          45 :     uno::Reference<drawing::XShape> xShape;
     194          84 :     uno::Reference<beans::XPropertySet> xPropertySet;
     195             :     // Create this early, as custom shapes may have properties before the type arrives.
     196          45 :     createShape("com.sun.star.drawing.CustomShape", xShape, xPropertySet);
     197          84 :     uno::Any aAny;
     198          84 :     beans::PropertyValue aPropertyValue;
     199          45 :     awt::Rectangle aViewBox;
     200          84 :     std::vector<beans::PropertyValue> aPathPropVec;
     201             :     // Default line color is black in Word, blue in Writer.
     202          84 :     uno::Any aLineColor = uno::makeAny(COL_BLACK);
     203             :     // Default line width is 0.75 pt (26 mm100) in Word, 0 in Writer.
     204          84 :     uno::Any aLineWidth = uno::makeAny(sal_Int32(26));
     205          45 :     text::WritingMode eWritingMode = text::WritingMode_LR_TB;
     206             :     // Groupshape support
     207          84 :     boost::optional<sal_Int32> oGroupLeft, oGroupTop, oGroupRight, oGroupBottom;
     208          84 :     boost::optional<sal_Int32> oRelLeft, oRelTop, oRelRight, oRelBottom;
     209             : 
     210             :     // Importing these are not trivial, let the VML import do the hard work.
     211          84 :     oox::vml::FillModel aFillModel; // Gradient.
     212          84 :     oox::vml::ShadowModel aShadowModel; // Shadow.
     213             : 
     214        1392 :     for (std::vector< std::pair<OUString, OUString> >::iterator i = rShape.aProperties.begin();
     215         928 :             i != rShape.aProperties.end(); ++i)
     216             :     {
     217         419 :         if ( i->first == "shapeType" )
     218             :         {
     219          43 :             nType = i->second.toInt32();
     220          43 :             switch (nType)
     221             :             {
     222             :                 case ESCHER_ShpInst_Line:
     223           3 :                     createShape("com.sun.star.drawing.LineShape", xShape, xPropertySet);
     224           3 :                     break;
     225             :                 case ESCHER_ShpInst_Rectangle:
     226             :                 case ESCHER_ShpInst_TextBox:
     227          31 :                     if (!bClose)
     228             :                     {
     229          20 :                         createShape("com.sun.star.text.TextFrame", xShape, xPropertySet);
     230          20 :                         bTextFrame = true;
     231          20 :                         std::vector<beans::PropertyValue> aDefaults = getTextFrameDefaults(true);
     232         200 :                         for (size_t j = 0; j < aDefaults.size(); ++j)
     233         200 :                             xPropertySet->setPropertyValue(aDefaults[j].Name, aDefaults[j].Value);
     234             :                     }
     235             :                     else
     236          11 :                         bCustom = true;
     237          31 :                     break;
     238             :                 default:
     239           9 :                     bCustom = true;
     240           9 :                     break;
     241             :             }
     242             : 
     243             :             // Defaults
     244          43 :             aAny <<= (sal_uInt32)0xffffff; // White in Word, kind of blue in Writer.
     245          43 :             if (xPropertySet.is() && !bTextFrame)
     246          23 :                 xPropertySet->setPropertyValue("FillColor", aAny);
     247             :         }
     248         376 :         else if ( i->first == "wzName" )
     249             :         {
     250           2 :             if (bTextFrame)
     251             :             {
     252           0 :                 uno::Reference<container::XNamed> xNamed(xShape, uno::UNO_QUERY);
     253           0 :                 xNamed->setName(i->second);
     254             :             }
     255             :             else
     256           2 :                 xPropertySet->setPropertyValue("Name", uno::makeAny(i->second));
     257             :         }
     258         374 :         else if ( i->first == "wzDescription" )
     259           8 :             xPropertySet->setPropertyValue("Description", uno::makeAny(i->second));
     260         366 :         else if ( i->first == "pib" )
     261             :         {
     262           4 :             m_rImport.setDestinationText(i->second);
     263           4 :             bPib = true;
     264             :         }
     265         362 :         else if (i->first == "fillColor" && xPropertySet.is())
     266             :         {
     267          16 :             aAny <<= msfilter::util::BGRToRGB(i->second.toInt32());
     268          16 :             if (bTextFrame)
     269           8 :                 xPropertySet->setPropertyValue("BackColor", aAny);
     270             :             else
     271           8 :                 xPropertySet->setPropertyValue("FillColor", aAny);
     272             : 
     273             :             // fillType will decide, possible it'll be the start color of a gradient.
     274          16 :             aFillModel.moColor.set(OUString("#") + OStringToOUString(msfilter::util::ConvertColor(aAny.get<sal_Int32>()), RTL_TEXTENCODING_UTF8));
     275             :         }
     276         346 :         else if ( i->first == "fillBackColor" )
     277             :             // fillType will decide, possible it'll be the end color of a gradient.
     278           6 :             aFillModel.moColor2.set(OUString("#") + OStringToOUString(msfilter::util::ConvertColor(msfilter::util::BGRToRGB(i->second.toInt32())), RTL_TEXTENCODING_UTF8));
     279         340 :         else if (i->first == "lineColor")
     280          17 :             aLineColor <<= msfilter::util::BGRToRGB(i->second.toInt32());
     281         323 :         else if ( i->first == "lineBackColor" )
     282             :             ; // Ignore: complementer of lineColor
     283         322 :         else if (i->first == "txflTextFlow" && xPropertySet.is())
     284             :         {
     285           2 :             if (i->second.toInt32() == 1)
     286           0 :                 eWritingMode = text::WritingMode_TB_RL;
     287             :         }
     288         320 :         else if (i->first == "fLine" && xPropertySet.is())
     289           5 :             resolveFLine(xPropertySet, i->second.toInt32());
     290         315 :         else if (i->first == "fillOpacity" && xPropertySet.is())
     291             :         {
     292           0 :            int opacity = 100 - (i->second.toInt32())*100/65536;
     293           0 :            aAny <<= uno::makeAny(sal_uInt32(opacity));
     294           0 :            xPropertySet->setPropertyValue("FillTransparence", aAny);
     295             :         }
     296         315 :         else if (i->first == "rotation" && xPropertySet.is())
     297             :         {
     298           0 :             aAny <<= i->second.toInt32()*100/65536;
     299           0 :             xPropertySet->setPropertyValue("RotateAngle", aAny);
     300             :         }
     301         315 :         else if (i->first == "lineWidth")
     302          19 :             aLineWidth <<= i->second.toInt32()/360;
     303         296 :         else if ( i->first == "pVerticies" )
     304             :         {
     305           3 :             uno::Sequence<drawing::EnhancedCustomShapeParameterPair> aCoordinates;
     306           3 :             sal_Int32 nSize = 0; // Size of a token (it's value is hardwired in the exporter)
     307           3 :             sal_Int32 nCount = 0; // Number of tokens
     308           3 :             sal_Int32 nCharIndex = 0; // Character index
     309           3 :             sal_Int32 nIndex = 0; // Array index
     310         122 :             do
     311             :             {
     312         122 :                 OUString aToken = i->second.getToken(0, ';', nCharIndex);
     313         122 :                 if (!nSize)
     314           3 :                     nSize = aToken.toInt32();
     315         119 :                 else if (!nCount)
     316             :                 {
     317           3 :                     nCount = aToken.toInt32();
     318           3 :                     aCoordinates.realloc(nCount);
     319             :                 }
     320             :                 else
     321             :                 {
     322             :                     // The coordinates are in an (x,y) form.
     323         116 :                     aToken = aToken.copy(1, aToken.getLength() - 2);
     324         116 :                     sal_Int32 nI = 0;
     325         116 :                     boost::optional<sal_Int32> oX;
     326         232 :                     boost::optional<sal_Int32> oY;
     327         232 :                     do
     328             :                     {
     329         232 :                         OUString aPoint = aToken.getToken(0, ',', nI);
     330         232 :                         if (!oX)
     331         116 :                             oX.reset(aPoint.toInt32());
     332             :                         else
     333         116 :                             oY.reset(aPoint.toInt32());
     334             :                     }
     335         232 :                     while (nI >= 0);
     336         116 :                     aCoordinates[nIndex].First.Value <<= *oX;
     337         116 :                     aCoordinates[nIndex].Second.Value <<= *oY;
     338         232 :                     nIndex++;
     339         122 :                 }
     340             :             }
     341         122 :             while (nCharIndex >= 0);
     342           3 :             aPropertyValue.Name = "Coordinates";
     343           3 :             aPropertyValue.Value <<= aCoordinates;
     344           3 :             aPathPropVec.push_back(aPropertyValue);
     345             :         }
     346         293 :         else if ( i->first == "pSegmentInfo" )
     347             :         {
     348           3 :             uno::Sequence<drawing::EnhancedCustomShapeSegment> aSegments;
     349           3 :             sal_Int32 nSize = 0;
     350           3 :             sal_Int32 nCount = 0;
     351           3 :             sal_Int32 nCharIndex = 0;
     352           3 :             sal_Int32 nIndex = 0;
     353          24 :             do
     354             :             {
     355          24 :                 sal_Int32 nSeg = i->second.getToken(0, ';', nCharIndex).toInt32();
     356          24 :                 if (!nSize)
     357           3 :                     nSize = nSeg;
     358          21 :                 else if (!nCount)
     359             :                 {
     360           3 :                     nCount = nSeg;
     361           3 :                     aSegments.realloc(nCount);
     362             :                 }
     363             :                 else
     364             :                 {
     365          18 :                     sal_Int32 nPoints = 1;
     366          18 :                     if (nSeg >= 0x2000 && nSeg < 0x20FF)
     367             :                     {
     368           3 :                         nPoints = nSeg & 0x0FFF;
     369           3 :                         nSeg &= 0xFF00;
     370             :                     }
     371             : 
     372          18 :                     switch (nSeg)
     373             :                     {
     374             :                         case 0x0001: // lineto
     375           3 :                             aSegments[nIndex].Command = drawing::EnhancedCustomShapeSegmentCommand::LINETO;
     376           3 :                             aSegments[nIndex].Count = sal_Int32(1);
     377           3 :                             break;
     378             :                         case 0x4000: // moveto
     379           5 :                             aSegments[nIndex].Command = drawing::EnhancedCustomShapeSegmentCommand::MOVETO;
     380           5 :                             aSegments[nIndex].Count = sal_Int32(1);
     381           5 :                             break;
     382             :                         case 0x2000: // curveto
     383           3 :                             aSegments[nIndex].Command = drawing::EnhancedCustomShapeSegmentCommand::CURVETO;
     384           3 :                             aSegments[nIndex].Count = sal_Int32(nPoints);
     385           3 :                             break;
     386             :                         case 0xb300: // arcto
     387           0 :                             aSegments[nIndex].Command = drawing::EnhancedCustomShapeSegmentCommand::ARCTO;
     388           0 :                             aSegments[nIndex].Count = sal_Int32(0);
     389           0 :                             break;
     390             :                         case 0xac00:
     391             :                         case 0xaa00: // nofill
     392             :                         case 0xab00: // nostroke
     393             :                         case 0x6001: // close
     394           1 :                             break;
     395             :                         case 0x8000: // end
     396           5 :                             aSegments[nIndex].Command = drawing::EnhancedCustomShapeSegmentCommand::ENDSUBPATH;
     397           5 :                             aSegments[nIndex].Count = sal_Int32(0);
     398           5 :                             break;
     399             :                         default: // given number of lineto elements
     400           1 :                             aSegments[nIndex].Command = drawing::EnhancedCustomShapeSegmentCommand::LINETO;
     401           1 :                             aSegments[nIndex].Count = nSeg;
     402           1 :                             break;
     403             :                     }
     404          18 :                     nIndex++;
     405             :                 }
     406             :             }
     407          24 :             while (nCharIndex >= 0);
     408           3 :             aPropertyValue.Name = "Segments";
     409           3 :             aPropertyValue.Value <<= aSegments;
     410           3 :             aPathPropVec.push_back(aPropertyValue);
     411             :         }
     412         290 :         else if ( i->first == "geoLeft" )
     413           2 :             aViewBox.X = i->second.toInt32();
     414         288 :         else if ( i->first == "geoTop" )
     415           2 :             aViewBox.Y = i->second.toInt32();
     416         286 :         else if ( i->first == "geoRight" )
     417           3 :             aViewBox.Width = i->second.toInt32();
     418         283 :         else if ( i->first == "geoBottom" )
     419           3 :             aViewBox.Height = i->second.toInt32();
     420         280 :         else if ( i->first == "dhgt" )
     421             :         {
     422           7 :             resolveDhgt(xPropertySet, i->second.toInt32());
     423             :             // dhgt is Word 2007, \shpz is Word 97-2003, the previous has priority.
     424           7 :             rShape.oZ.reset();
     425             :         }
     426             :         // These are in EMU, convert to mm100.
     427         273 :         else if (i->first == "dxTextLeft")
     428          11 :             xPropertySet->setPropertyValue("LeftBorderDistance", uno::makeAny(i->second.toInt32() / 360));
     429         262 :         else if (i->first == "dyTextTop")
     430          11 :             xPropertySet->setPropertyValue("TopBorderDistance", uno::makeAny(i->second.toInt32() / 360));
     431         251 :         else if (i->first == "dxTextRight")
     432          11 :             xPropertySet->setPropertyValue("RightBorderDistance", uno::makeAny(i->second.toInt32() / 360));
     433         240 :         else if (i->first == "dyTextBottom")
     434          11 :             xPropertySet->setPropertyValue("BottomBorderDistance", uno::makeAny(i->second.toInt32() / 360));
     435         229 :         else if (i->first == "dxWrapDistLeft")
     436           8 :             xPropertySet->setPropertyValue("LeftMargin", uno::makeAny(i->second.toInt32() / 360));
     437         221 :         else if (i->first == "dyWrapDistTop")
     438           8 :             xPropertySet->setPropertyValue("TopMargin", uno::makeAny(i->second.toInt32() / 360));
     439         213 :         else if (i->first == "dxWrapDistRight")
     440           8 :             xPropertySet->setPropertyValue("RightMargin", uno::makeAny(i->second.toInt32() / 360));
     441         205 :         else if (i->first == "dyWrapDistBottom")
     442           8 :             xPropertySet->setPropertyValue("BottomMargin", uno::makeAny(i->second.toInt32() / 360));
     443         197 :         else if (i->first == "fillType")
     444             :         {
     445           4 :             switch (i->second.toInt32())
     446             :             {
     447             :                 case 7: // Shade using the fillAngle
     448           4 :                     aFillModel.moType.set(oox::XML_gradient);
     449           4 :                 break;
     450             :                 default:
     451             :                     SAL_INFO("writerfilter", "TODO handle fillType value '" << i->second << "'");
     452           0 :                 break;
     453             :             }
     454             :         }
     455         193 :         else if (i->first == "fillFocus")
     456           4 :             aFillModel.moFocus.set(i->second.toDouble() / 100); // percent
     457         189 :         else if (i->first == "fShadow" && xPropertySet.is())
     458             :         {
     459          12 :             if (i->second.toInt32() == 1)
     460           9 :                 aShadowModel.mbHasShadow = true;
     461             :         }
     462         177 :         else if (i->first == "shadowColor")
     463           9 :             aShadowModel.moColor.set(OUString("#") + OStringToOUString(msfilter::util::ConvertColor(msfilter::util::BGRToRGB(i->second.toInt32())), RTL_TEXTENCODING_UTF8));
     464         168 :         else if (i->first == "shadowOffsetX")
     465             :             // EMUs to points
     466           9 :             aShadowModel.moOffset.set(OUString::number(i->second.toDouble() / 12700) + "pt");
     467         159 :         else if (i->first == "posh" || i->first == "posv" || i->first == "fFitShapeToText" || i->first == "fFilled")
     468          14 :             applyProperty(xShape, i->first, i->second);
     469         145 :         else if (i->first == "posrelh")
     470             :         {
     471          13 :             switch (i->second.toInt32())
     472             :             {
     473             :                 case 1:
     474           5 :                     rShape.nHoriOrientRelation = text::RelOrientation::PAGE_FRAME;
     475           5 :                     break;
     476             :                 default:
     477           8 :                     break;
     478             :             }
     479             :         }
     480         132 :         else if (i->first == "posrelv")
     481             :         {
     482          12 :             switch (i->second.toInt32())
     483             :             {
     484             :                 case 1:
     485           5 :                     rShape.nVertOrientRelation = text::RelOrientation::PAGE_FRAME;
     486           5 :                     break;
     487             :                 default:
     488           7 :                     break;
     489             :             }
     490             :         }
     491         120 :         else if (i->first == "groupLeft")
     492           2 :             oGroupLeft.reset(TWIP_TO_MM100(i->second.toInt32()));
     493         118 :         else if (i->first == "groupTop")
     494           2 :             oGroupTop.reset(TWIP_TO_MM100(i->second.toInt32()));
     495         116 :         else if (i->first == "groupRight")
     496           2 :             oGroupRight.reset(TWIP_TO_MM100(i->second.toInt32()));
     497         114 :         else if (i->first == "groupBottom")
     498           2 :             oGroupBottom.reset(TWIP_TO_MM100(i->second.toInt32()));
     499         112 :         else if (i->first == "relLeft")
     500           2 :             oRelLeft.reset(TWIP_TO_MM100(i->second.toInt32()));
     501         110 :         else if (i->first == "relTop")
     502           2 :             oRelTop.reset(TWIP_TO_MM100(i->second.toInt32()));
     503         108 :         else if (i->first == "relRight")
     504           2 :             oRelRight.reset(TWIP_TO_MM100(i->second.toInt32()));
     505         106 :         else if (i->first == "relBottom")
     506           2 :             oRelBottom.reset(TWIP_TO_MM100(i->second.toInt32()));
     507             :         else
     508             :             SAL_INFO("writerfilter", "TODO handle shape property '" << i->first << "':'" << i->second << "'");
     509             :     }
     510             : 
     511          45 :     if (xPropertySet.is())
     512             :     {
     513          44 :         if (!bTextFrame)
     514             :         {
     515          24 :             xPropertySet->setPropertyValue("LineColor", aLineColor);
     516          24 :             xPropertySet->setPropertyValue("LineWidth", aLineWidth);
     517             :         }
     518             :         else
     519             :         {
     520             :             static OUString aBorders[] = {
     521             :                 OUString("TopBorder"), OUString("LeftBorder"), OUString("BottomBorder"), OUString("RightBorder")
     522          22 :             };
     523         100 :             for (unsigned int i = 0; i < SAL_N_ELEMENTS(aBorders); ++i)
     524             :             {
     525          80 :                 table::BorderLine2 aBorderLine = xPropertySet->getPropertyValue(aBorders[i]).get<table::BorderLine2>();
     526          80 :                 aBorderLine.Color = aLineColor.get<sal_Int32>();
     527          80 :                 aBorderLine.LineWidth = aLineWidth.get<sal_Int32>();
     528          80 :                 xPropertySet->setPropertyValue(aBorders[i], uno::makeAny(aBorderLine));
     529             :             }
     530             :         }
     531          44 :         if (rShape.oZ)
     532          17 :             resolveDhgt(xPropertySet, *rShape.oZ);
     533          44 :         if (bTextFrame)
     534             :             // Writer textframes implement text::WritingMode2, which is a different data type.
     535          20 :             xPropertySet->setPropertyValue("WritingMode", uno::makeAny(sal_Int16(eWritingMode)));
     536             :         else
     537          24 :             xPropertySet->setPropertyValue("TextWritingMode", uno::makeAny(eWritingMode));
     538             :     }
     539             : 
     540          45 :     if (nType == ESCHER_ShpInst_PictureFrame) // picture frame
     541             :     {
     542           5 :         if (bPib)
     543           4 :             m_rImport.resolvePict(false);
     544           5 :         return;
     545             :     }
     546             : 
     547          40 :     if (m_xDrawPage.is() && !bTextFrame)
     548          19 :         m_xDrawPage->add(xShape);
     549          40 :     if (bCustom && xShape.is())
     550             :     {
     551          15 :         uno::Reference<drawing::XEnhancedCustomShapeDefaulter> xDefaulter(xShape, uno::UNO_QUERY);
     552          15 :         xDefaulter->createCustomShapeDefaults(OUString::valueOf(sal_Int32(nType)));
     553             :     }
     554             : 
     555             :     // Creating Path property
     556          40 :     uno::Sequence<beans::PropertyValue> aPathPropSeq(aPathPropVec.size());
     557          40 :     beans::PropertyValue* pPathValues = aPathPropSeq.getArray();
     558          46 :     for (std::vector<beans::PropertyValue>::iterator i = aPathPropVec.begin(); i != aPathPropVec.end(); ++i)
     559           6 :         *pPathValues++ = *i;
     560             : 
     561             :     // Creating CustomShapeGeometry property
     562          79 :     std::vector<beans::PropertyValue> aGeomPropVec;
     563          40 :     if (aViewBox.X || aViewBox.Y || aViewBox.Width || aViewBox.Height)
     564             :     {
     565           3 :         aViewBox.Width -= aViewBox.X;
     566           3 :         aViewBox.Height -= aViewBox.Y;
     567           3 :         aPropertyValue.Name = "ViewBox";
     568           3 :         aPropertyValue.Value <<= aViewBox;
     569           3 :         aGeomPropVec.push_back(aPropertyValue);
     570             :     }
     571          40 :     if (aPathPropSeq.getLength())
     572             :     {
     573           3 :         aPropertyValue.Name = "Path";
     574           3 :         aPropertyValue.Value <<= aPathPropSeq;
     575           3 :         aGeomPropVec.push_back(aPropertyValue);
     576             :     }
     577          79 :     uno::Sequence<beans::PropertyValue> aGeomPropSeq(aGeomPropVec.size());
     578          40 :     beans::PropertyValue* pGeomValues = aGeomPropSeq.getArray();
     579          46 :     for (std::vector<beans::PropertyValue>::iterator i = aGeomPropVec.begin(); i != aGeomPropVec.end(); ++i)
     580           6 :         *pGeomValues++ = *i;
     581          40 :     if (aGeomPropSeq.getLength() && xPropertySet.is())
     582           3 :         xPropertySet->setPropertyValue("CustomShapeGeometry", uno::Any(aGeomPropSeq));
     583             : 
     584             :     // Set position and size
     585          40 :     if (xShape.is())
     586             :     {
     587          39 :         sal_Int32 nLeft = rShape.nLeft;
     588          39 :         sal_Int32 nTop = rShape.nTop;
     589             : 
     590          41 :         bool bInShapeGroup = oGroupLeft && oGroupTop && oGroupRight && oGroupBottom
     591          41 :             && oRelLeft && oRelTop && oRelRight && oRelBottom;
     592          39 :         if (bInShapeGroup)
     593             :         {
     594             :             // See lclGetAbsPoint() in the VML import: rShape is the group shape, oGroup is its coordinate system, oRel is the relative child shape.
     595           2 :             sal_Int32 nShapeWidth = rShape.nRight - rShape.nLeft;
     596           2 :             sal_Int32 nShapeHeight = rShape.nBottom - rShape.nTop;
     597           2 :             sal_Int32 nCoordSysWidth = *oGroupRight - *oGroupLeft;
     598           2 :             sal_Int32 nCoordSysHeight = *oGroupBottom - *oGroupTop;
     599           2 :             double fWidthRatio = static_cast< double >( nShapeWidth ) / nCoordSysWidth;
     600           2 :             double fHeightRatio = static_cast< double >( nShapeHeight ) / nCoordSysHeight;
     601           2 :             nLeft = static_cast< sal_Int32 >( rShape.nLeft + fWidthRatio * (*oRelLeft - *oGroupLeft) );
     602           2 :             nTop = static_cast< sal_Int32 >( rShape.nTop + fHeightRatio * (*oRelTop - *oGroupTop) );
     603             :         }
     604             : 
     605          39 :         if (bTextFrame)
     606             :         {
     607          20 :             xPropertySet->setPropertyValue("HoriOrientPosition", uno::makeAny(nLeft));
     608          20 :             xPropertySet->setPropertyValue("VertOrientPosition", uno::makeAny(nTop));
     609             :         }
     610             :         else
     611          19 :             xShape->setPosition(awt::Point(nLeft, nTop));
     612             : 
     613          39 :         if (bInShapeGroup)
     614           2 :             xShape->setSize(awt::Size(*oRelRight - *oRelLeft, *oRelBottom - *oRelTop));
     615             :         else
     616          37 :             xShape->setSize(awt::Size(rShape.nRight - rShape.nLeft, rShape.nBottom - rShape.nTop));
     617             : 
     618          39 :         if (rShape.nHoriOrientRelation != 0)
     619          14 :             xPropertySet->setPropertyValue("HoriOrientRelation", uno::makeAny(rShape.nHoriOrientRelation));
     620          39 :         if (rShape.nVertOrientRelation != 0)
     621          13 :             xPropertySet->setPropertyValue("VertOrientRelation", uno::makeAny(rShape.nVertOrientRelation));
     622          39 :         if (rShape.nWrap != -1)
     623          24 :             xPropertySet->setPropertyValue("Surround", uno::makeAny(text::WrapTextMode(rShape.nWrap)));
     624          39 :         oox::ModelObjectHelper aModelObjectHelper(m_rImport.getModelFactory());
     625          39 :         if (aFillModel.moType.has())
     626             :         {
     627           4 :             oox::drawingml::ShapePropertyMap aPropMap(aModelObjectHelper);
     628           4 :             aFillModel.pushToPropMap(aPropMap, m_rImport.getGraphicHelper());
     629             :             // Sets the FillStyle and FillGradient UNO properties.
     630           4 :             oox::PropertySet(xShape).setProperties(aPropMap);
     631             :         }
     632             : 
     633          39 :         if (aShadowModel.mbHasShadow)
     634             :         {
     635           9 :             oox::drawingml::ShapePropertyMap aPropMap(aModelObjectHelper);
     636           9 :             aShadowModel.pushToPropMap(aPropMap, m_rImport.getGraphicHelper());
     637             :             // Sets the ShadowFormat UNO property.
     638           9 :             oox::PropertySet(xShape).setProperties(aPropMap);
     639          39 :         }
     640             :     }
     641             : 
     642          40 :     if (m_rImport.isInBackground())
     643             :     {
     644           1 :         RTFSprms aAttributes;
     645           1 :         aAttributes.set(NS_ooxml::LN_CT_Background_color, RTFValue::Pointer_t(new RTFValue(xPropertySet->getPropertyValue("FillColor").get<sal_Int32>())));
     646           2 :         writerfilter::Reference<Properties>::Pointer_t const pProperties(new RTFReferenceProperties(aAttributes));
     647           1 :         m_rImport.Mapper().props(pProperties);
     648             : 
     649           2 :         uno::Reference<lang::XComponent> xComponent(xShape, uno::UNO_QUERY);
     650           1 :         xComponent->dispose();
     651           2 :         return;
     652             :     }
     653             : 
     654             :     // Send it to dmapper
     655          39 :     m_rImport.Mapper().startShape(xShape);
     656          39 :     if (bClose)
     657             :     {
     658          19 :         m_rImport.Mapper().endShape();
     659             :     }
     660         117 :     m_xShape = xShape;
     661             : }
     662             : 
     663          20 : void RTFSdrImport::close()
     664             : {
     665          20 :     m_rImport.Mapper().endShape();
     666          20 : }
     667             : 
     668           8 : void RTFSdrImport::append(OUString aKey, OUString aValue)
     669             : {
     670           8 :     applyProperty(m_xShape, aKey, aValue);
     671           8 : }
     672             : 
     673             : } // namespace rtftok
     674          24 : } // namespace writerfilter
     675             : 
     676             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10