LCOV - code coverage report
Current view: top level - libreoffice/writerfilter/source/rtftok - rtfsdrimport.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 187 200 93.5 %
Date: 2012-12-27 Functions: 9 9 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             :  * Version: MPL 1.1 / GPLv3+ / LGPLv3+
       4             :  *
       5             :  * The contents of this file are subject to the Mozilla Public License Version
       6             :  * 1.1 (the "License"); you may not use this file except in compliance with
       7             :  * the License. You may obtain a copy of the License at
       8             :  * http://www.mozilla.org/MPL/
       9             :  *
      10             :  * Software distributed under the License is distributed on an "AS IS" basis,
      11             :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12             :  * for the specific language governing rights and limitations under the
      13             :  * License.
      14             :  *
      15             :  * The Initial Developer of the Original Code is
      16             :  *       Miklos Vajna <vmiklos@frugalware.org>
      17             :  * Portions created by the Initial Developer are Copyright (C) 2011 the
      18             :  * Initial Developer. All Rights Reserved.
      19             :  *
      20             :  * Contributor(s):
      21             :  *
      22             :  * Alternatively, the contents of this file may be used under the terms of
      23             :  * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
      24             :  * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
      25             :  * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
      26             :  * instead of those above.
      27             :  */
      28             : 
      29             : #include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp>
      30             : #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
      31             : #include <com/sun/star/drawing/LineStyle.hpp>
      32             : #include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
      33             : #include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
      34             : #include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
      35             : #include <com/sun/star/text/WrapTextMode.hpp>
      36             : #include <com/sun/star/text/WritingMode.hpp>
      37             : 
      38             : #include <ooxml/resourceids.hxx> // NS_ooxml namespace
      39             : #include <filter/msfilter/escherex.hxx>
      40             : #include <filter/msfilter/util.hxx>
      41             : 
      42             : #include <dmapper/DomainMapper.hxx>
      43             : #include "../dmapper/GraphicHelpers.hxx"
      44             : #include <rtfsdrimport.hxx>
      45             : 
      46             : using rtl::OString;
      47             : using rtl::OStringBuffer;
      48             : using rtl::OUString;
      49             : using rtl::OUStringBuffer;
      50             : using rtl::OUStringToOString;
      51             : 
      52             : namespace writerfilter {
      53             : namespace rtftok {
      54             : 
      55         138 : RTFSdrImport::RTFSdrImport(RTFDocumentImpl& rDocument,
      56             :         uno::Reference<lang::XComponent> const& xDstDoc)
      57         138 :     : m_rImport(rDocument)
      58             : {
      59         138 :     uno::Reference<drawing::XDrawPageSupplier> xDrawings(xDstDoc, uno::UNO_QUERY);
      60         138 :     if (xDrawings.is())
      61         127 :         m_xDrawPage.set(xDrawings->getDrawPage(), uno::UNO_QUERY);
      62         138 : }
      63             : 
      64         276 : RTFSdrImport::~RTFSdrImport()
      65             : {
      66         276 : }
      67             : 
      68          18 : void RTFSdrImport::createShape(OUString aStr, uno::Reference<drawing::XShape>& xShape, uno::Reference<beans::XPropertySet>& xPropertySet)
      69             : {
      70          18 :     if (m_rImport.getModelFactory().is())
      71          17 :         xShape.set(m_rImport.getModelFactory()->createInstance(aStr), uno::UNO_QUERY);
      72          18 :     xPropertySet.set(xShape, uno::UNO_QUERY);
      73          18 : }
      74             : 
      75          14 : void RTFSdrImport::resolveDhgt(uno::Reference<beans::XPropertySet> xPropertySet, sal_Int32 nZOrder)
      76             : {
      77          14 :     writerfilter::dmapper::DomainMapper& rMapper = (writerfilter::dmapper::DomainMapper&)m_rImport.Mapper();
      78          14 :     writerfilter::dmapper::GraphicZOrderHelper* pHelper = rMapper.graphicZOrderHelper();
      79          14 :     xPropertySet->setPropertyValue("ZOrder", uno::makeAny(pHelper->findZOrder(nZOrder)));
      80          14 :     pHelper->addItem(xPropertySet, nZOrder);
      81          14 : }
      82             : 
      83          11 : void RTFSdrImport::resolveFLine(uno::Reference<beans::XPropertySet> xPropertySet, sal_Int32 nFLine)
      84             : {
      85          11 :     if (nFLine == 0)
      86           2 :         xPropertySet->setPropertyValue("LineStyle", uno::makeAny(drawing::LineStyle_NONE));
      87          11 : }
      88             : 
      89          16 : void RTFSdrImport::resolve(RTFShape& rShape)
      90             : {
      91          16 :     int nType = -1;
      92          16 :     bool bPib = false;
      93          16 :     bool bCustom = false;
      94             : 
      95          16 :     uno::Reference<drawing::XShape> xShape;
      96          16 :     uno::Reference<beans::XPropertySet> xPropertySet;
      97             :     // Create this early, as custom shapes may have properties before the type arrives.
      98          16 :     createShape("com.sun.star.drawing.CustomShape", xShape, xPropertySet);
      99          16 :     uno::Any aAny;
     100          16 :     beans::PropertyValue aPropertyValue;
     101          16 :     awt::Rectangle aViewBox;
     102          16 :     std::vector<beans::PropertyValue> aPathPropVec;
     103             : 
     104         537 :     for (std::vector< std::pair<rtl::OUString, rtl::OUString> >::iterator i = rShape.aProperties.begin();
     105         358 :             i != rShape.aProperties.end(); ++i)
     106             :     {
     107         163 :         if ( i->first == "shapeType" )
     108             :         {
     109          15 :             nType = i->second.toInt32();
     110          15 :             switch (nType)
     111             :             {
     112             :                 case 20: // Line
     113           2 :                     createShape("com.sun.star.drawing.LineShape", xShape, xPropertySet);
     114           2 :                     break;
     115             :                 default:
     116          13 :                     bCustom = true;
     117          13 :                     break;
     118             :             }
     119             : 
     120             :             // Defaults
     121          15 :             aAny <<= (sal_uInt32)0xffffff; // White in Word, kind of blue in Writer.
     122          15 :             if (xPropertySet.is())
     123          15 :                 xPropertySet->setPropertyValue("FillColor", aAny);
     124             :         }
     125         148 :         else if ( i->first == "wzName" )
     126           1 :             xPropertySet->setPropertyValue("Name", uno::makeAny(i->second));
     127         147 :         else if ( i->first == "wzDescription" )
     128           5 :             xPropertySet->setPropertyValue("Description", uno::makeAny(i->second));
     129         142 :         else if ( i->first == "pib" )
     130             :         {
     131           2 :             m_rImport.setDestinationText(i->second);
     132           2 :             bPib = true;
     133             :         }
     134         140 :         else if (i->first == "fillColor" && xPropertySet.is())
     135             :         {
     136           5 :             aAny <<= msfilter::util::BGRToRGB(i->second.toInt32());
     137           5 :             xPropertySet->setPropertyValue("FillColor", aAny);
     138             :         }
     139         135 :         else if ( i->first == "fillBackColor" )
     140             :             ; // Ignore: complementer of fillColor
     141         133 :         else if (i->first == "lineColor" && xPropertySet.is())
     142             :         {
     143           6 :             aAny <<= msfilter::util::BGRToRGB(i->second.toInt32());
     144           6 :             xPropertySet->setPropertyValue("LineColor", aAny);
     145             :         }
     146         127 :         else if ( i->first == "lineBackColor" )
     147             :             ; // Ignore: complementer of lineColor
     148         126 :         else if (i->first == "txflTextFlow" && xPropertySet.is())
     149             :         {
     150           2 :             if (i->second.toInt32() == 1)
     151             :             {
     152           0 :                 aAny <<= text::WritingMode_TB_RL;
     153           0 :                 xPropertySet->setPropertyValue("TextWritingMode", aAny);
     154             :             }
     155             :         }
     156         124 :         else if (i->first == "fLine" && xPropertySet.is())
     157           1 :             resolveFLine(xPropertySet, i->second.toInt32());
     158         123 :         else if (i->first == "fillOpacity" && xPropertySet.is())
     159             :         {
     160           0 :            int opacity = 100 - (i->second.toInt32())*100/65536;
     161           0 :            aAny <<= uno::makeAny(sal_uInt32(opacity));
     162           0 :            xPropertySet->setPropertyValue("FillTransparence", aAny);
     163             :         }
     164         123 :         else if (i->first == "rotation" && xPropertySet.is())
     165             :         {
     166           0 :             aAny <<= i->second.toInt32()*100/65536;
     167           0 :             xPropertySet->setPropertyValue("RotateAngle", aAny);
     168             :         }
     169         123 :         else if (i->first == "lineWidth" && xPropertySet.is())
     170             :         {
     171             : 
     172           8 :             aAny <<= i->second.toInt32()/360;
     173           8 :             xPropertySet->setPropertyValue("LineWidth", aAny);
     174             :         }
     175         115 :         else if ( i->first == "pVerticies" )
     176             :         {
     177           2 :             uno::Sequence<drawing::EnhancedCustomShapeParameterPair> aCoordinates;
     178           2 :             sal_Int32 nSize = 0; // Size of a token (it's value is hardwired in the exporter)
     179           2 :             sal_Int32 nCount = 0; // Number of tokens
     180           2 :             sal_Int32 nCharIndex = 0; // Character index
     181           2 :             sal_Int32 nIndex = 0; // Array index
     182         116 :             do
     183             :             {
     184         116 :                 OUString aToken = i->second.getToken(0, ';', nCharIndex);
     185         116 :                 if (!nSize)
     186           2 :                     nSize = aToken.toInt32();
     187         114 :                 else if (!nCount)
     188             :                 {
     189           2 :                     nCount = aToken.toInt32();
     190           2 :                     aCoordinates.realloc(nCount);
     191             :                 }
     192             :                 else
     193             :                 {
     194             :                     // The coordinates are in an (x,y) form.
     195         112 :                     aToken = aToken.copy(1, aToken.getLength() - 2);
     196         112 :                     sal_Int32 nI = 0;
     197         112 :                     sal_Int32 nX = 0;
     198         112 :                     sal_Int32 nY = 0;
     199         224 :                     do
     200             :                     {
     201         224 :                         OUString aPoint = aToken.getToken(0, ',', nI);
     202         224 :                         if (!nX)
     203         113 :                             nX = aPoint.toInt32();
     204             :                         else
     205         111 :                             nY = aPoint.toInt32();
     206             :                     }
     207             :                     while (nI >= 0);
     208         112 :                     aCoordinates[nIndex].First.Value <<= nX;
     209         112 :                     aCoordinates[nIndex].Second.Value <<= nY;
     210         112 :                     nIndex++;
     211         116 :                 }
     212             :             }
     213             :             while (nCharIndex >= 0);
     214           2 :             aPropertyValue.Name = "Coordinates";
     215           2 :             aPropertyValue.Value <<= aCoordinates;
     216           2 :             aPathPropVec.push_back(aPropertyValue);
     217             :         }
     218         113 :         else if ( i->first == "pSegmentInfo" )
     219             :         {
     220           2 :             uno::Sequence<drawing::EnhancedCustomShapeSegment> aSegments;
     221           2 :             sal_Int32 nSize = 0;
     222           2 :             sal_Int32 nCount = 0;
     223           2 :             sal_Int32 nCharIndex = 0;
     224           2 :             sal_Int32 nIndex = 0;
     225          17 :             do
     226             :             {
     227          17 :                 sal_Int32 nSeg = i->second.getToken(0, ';', nCharIndex).toInt32();
     228          17 :                 if (!nSize)
     229           2 :                     nSize = nSeg;
     230          15 :                 else if (!nCount)
     231             :                 {
     232           2 :                     nCount = nSeg;
     233           2 :                     aSegments.realloc(nCount);
     234             :                 }
     235             :                 else
     236             :                 {
     237          13 :                     sal_Int32 nPoints = 1;
     238          13 :                     if (nSeg >= 0x2000 && nSeg < 0x20FF)
     239             :                     {
     240           3 :                         nPoints = nSeg & 0x0FFF;
     241           3 :                         nSeg &= 0xFF00;
     242             :                     }
     243             : 
     244          13 :                     switch (nSeg)
     245             :                     {
     246             :                         case 0x0001: // lineto
     247           0 :                             aSegments[nIndex].Command = drawing::EnhancedCustomShapeSegmentCommand::LINETO;
     248           0 :                             aSegments[nIndex].Count = sal_Int32(1);
     249           0 :                             break;
     250             :                         case 0x4000: // moveto
     251           4 :                             aSegments[nIndex].Command = drawing::EnhancedCustomShapeSegmentCommand::MOVETO;
     252           4 :                             aSegments[nIndex].Count = sal_Int32(1);
     253           4 :                             break;
     254             :                         case 0x2000: // curveto
     255           3 :                             aSegments[nIndex].Command = drawing::EnhancedCustomShapeSegmentCommand::CURVETO;
     256           3 :                             aSegments[nIndex].Count = sal_Int32(nPoints);
     257           3 :                             break;
     258             :                         case 0xb300: // arcto
     259           0 :                             aSegments[nIndex].Command = drawing::EnhancedCustomShapeSegmentCommand::ARCTO;
     260           0 :                             aSegments[nIndex].Count = sal_Int32(0);
     261           0 :                             break;
     262             :                         case 0xac00:
     263             :                         case 0xaa00: // nofill
     264             :                         case 0xab00: // nostroke
     265             :                         case 0x6001: // close
     266           1 :                             break;
     267             :                         case 0x8000: // end
     268           4 :                             aSegments[nIndex].Command = drawing::EnhancedCustomShapeSegmentCommand::ENDSUBPATH;
     269           4 :                             aSegments[nIndex].Count = sal_Int32(0);
     270           4 :                             break;
     271             :                         default: // given number of lineto elements
     272           1 :                             aSegments[nIndex].Command = drawing::EnhancedCustomShapeSegmentCommand::LINETO;
     273           1 :                             aSegments[nIndex].Count = nSeg;
     274           1 :                             break;
     275             :                     }
     276          13 :                     nIndex++;
     277             :                 }
     278             :             }
     279             :             while (nCharIndex >= 0);
     280           2 :             aPropertyValue.Name = "Segments";
     281           2 :             aPropertyValue.Value <<= aSegments;
     282           2 :             aPathPropVec.push_back(aPropertyValue);
     283             :         }
     284         111 :         else if ( i->first == "geoLeft" )
     285           2 :             aViewBox.X = i->second.toInt32();
     286         109 :         else if ( i->first == "geoTop" )
     287           2 :             aViewBox.Y = i->second.toInt32();
     288         107 :         else if ( i->first == "geoRight" )
     289           2 :             aViewBox.Width = i->second.toInt32();
     290         105 :         else if ( i->first == "geoBottom" )
     291           2 :             aViewBox.Height = i->second.toInt32();
     292         103 :         else if ( i->first == "dhgt" )
     293           4 :             resolveDhgt(xPropertySet, i->second.toInt32());
     294             :         else
     295             :             SAL_INFO("writerfilter", OSL_THIS_FUNC << ": TODO handle shape property '" <<
     296             :                     OUStringToOString( i->first, RTL_TEXTENCODING_UTF8 ).getStr() << "':'" <<
     297             :                     OUStringToOString( i->second, RTL_TEXTENCODING_UTF8 ).getStr() << "'");
     298             :     }
     299             : 
     300          16 :     if (nType == ESCHER_ShpInst_PictureFrame) // picture frame
     301             :     {
     302           2 :         if (bPib)
     303           2 :             m_rImport.resolvePict(false);
     304          16 :         return;
     305             :     }
     306             : 
     307          14 :     if (m_xDrawPage.is())
     308          13 :         m_xDrawPage->add(xShape);
     309          14 :     if (bCustom && xShape.is())
     310             :     {
     311          11 :         uno::Reference<drawing::XEnhancedCustomShapeDefaulter> xDefaulter(xShape, uno::UNO_QUERY);
     312          11 :         xDefaulter->createCustomShapeDefaults(OUString::valueOf(sal_Int32(nType)));
     313             :     }
     314             : 
     315             :     // Creating Path property
     316          14 :     uno::Sequence<beans::PropertyValue> aPathPropSeq(aPathPropVec.size());
     317          14 :     beans::PropertyValue* pPathValues = aPathPropSeq.getArray();
     318          18 :     for (std::vector<beans::PropertyValue>::iterator i = aPathPropVec.begin(); i != aPathPropVec.end(); ++i)
     319           4 :         *pPathValues++ = *i;
     320             : 
     321             :     // Creating CustomShapeGeometry property
     322          14 :     std::vector<beans::PropertyValue> aGeomPropVec;
     323          14 :     if (aViewBox.X || aViewBox.Y || aViewBox.Width || aViewBox.Height)
     324             :     {
     325           2 :         aViewBox.Width -= aViewBox.X;
     326           2 :         aViewBox.Height -= aViewBox.Y;
     327           2 :         aPropertyValue.Name = "ViewBox";
     328           2 :         aPropertyValue.Value <<= aViewBox;
     329           2 :         aGeomPropVec.push_back(aPropertyValue);
     330             :     }
     331          14 :     if (aPathPropSeq.getLength())
     332             :     {
     333           2 :         aPropertyValue.Name = "Path";
     334           2 :         aPropertyValue.Value <<= aPathPropSeq;
     335           2 :         aGeomPropVec.push_back(aPropertyValue);
     336             :     }
     337          14 :     uno::Sequence<beans::PropertyValue> aGeomPropSeq(aGeomPropVec.size());
     338          14 :     beans::PropertyValue* pGeomValues = aGeomPropSeq.getArray();
     339          18 :     for (std::vector<beans::PropertyValue>::iterator i = aGeomPropVec.begin(); i != aGeomPropVec.end(); ++i)
     340           4 :         *pGeomValues++ = *i;
     341          14 :     if (aGeomPropSeq.getLength() && xPropertySet.is())
     342           2 :         xPropertySet->setPropertyValue("CustomShapeGeometry", uno::Any(aGeomPropSeq));
     343             : 
     344             :     // Set position and size
     345          14 :     if (xShape.is())
     346             :     {
     347          13 :         xShape->setPosition(awt::Point(rShape.nLeft, rShape.nTop));
     348          13 :         xShape->setSize(awt::Size(rShape.nRight - rShape.nLeft, rShape.nBottom - rShape.nTop));
     349          13 :         if (rShape.nHoriOrientRelation != 0)
     350           5 :             xPropertySet->setPropertyValue("HoriOrientRelation", uno::makeAny(rShape.nHoriOrientRelation));
     351          13 :         if (rShape.nVertOrientRelation != 0)
     352           4 :             xPropertySet->setPropertyValue("VertOrientRelation", uno::makeAny(rShape.nVertOrientRelation));
     353          13 :         if (rShape.nWrap != -1)
     354          10 :             xPropertySet->setPropertyValue("Surround", uno::makeAny(text::WrapTextMode(rShape.nWrap)));
     355             :     }
     356             : 
     357             :     // Send it to dmapper
     358          14 :     m_rImport.Mapper().startShape(xShape);
     359          14 :     m_rImport.replayShapetext();
     360          14 :     m_rImport.Mapper().endShape();
     361             : }
     362             : 
     363             : } // namespace rtftok
     364          15 : } // namespace writerfilter
     365             : 
     366             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10