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

Generated by: LCOV version 1.10