LCOV - code coverage report
Current view: top level - libreoffice/sw/source/filter/ww8 - rtfsdrexport.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 179 304 58.9 %
Date: 2012-12-17 Functions: 14 19 73.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "rtfsdrexport.hxx"
      21             : #include "rtfattributeoutput.hxx"
      22             : #include "rtfexportfilter.hxx"
      23             : 
      24             : #include <svtools/rtfkeywd.hxx>
      25             : #include <filter/msfilter/rtfutil.hxx>
      26             : #include <editeng/editobj.hxx>
      27             : #include <svx/svdotext.hxx>
      28             : #include <svx/unoapi.hxx>
      29             : #include <vcl/cvtgrf.hxx>
      30             : 
      31             : using namespace sw::util;
      32             : 
      33          56 : RtfSdrExport::RtfSdrExport( RtfExport &rExport )
      34          56 :     : EscherEx( EscherExGlobalRef( new EscherExGlobal ), 0 ),
      35             :       m_rExport( rExport ),
      36          56 :       m_rAttrOutput( (RtfAttributeOutput&)m_rExport.AttrOutput() ),
      37             :       m_nShapeType( ESCHER_ShpInst_Nil ),
      38          56 :       m_pShapeStyle( new OStringBuffer( 200 ) ),
      39         224 :       m_pShapeTypeWritten( new bool[ ESCHER_ShpInst_COUNT ] )
      40             : {
      41          56 :     mnGroupLevel = 1;
      42          56 :     memset( m_pShapeTypeWritten, 0, ESCHER_ShpInst_COUNT * sizeof( bool ) );
      43          56 : }
      44             : 
      45         168 : RtfSdrExport::~RtfSdrExport()
      46             : {
      47          56 :     delete mpOutStrm, mpOutStrm = NULL;
      48          56 :     delete m_pShapeStyle, m_pShapeStyle = NULL;
      49          56 :     delete[] m_pShapeTypeWritten, m_pShapeTypeWritten = NULL;
      50         112 : }
      51             : 
      52           2 : void RtfSdrExport::OpenContainer( sal_uInt16 nEscherContainer, int nRecInstance )
      53             : {
      54             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC);
      55             : 
      56           2 :     EscherEx::OpenContainer( nEscherContainer, nRecInstance );
      57             : 
      58           2 :     if ( nEscherContainer == ESCHER_SpContainer )
      59             :     {
      60           2 :         m_nShapeType = ESCHER_ShpInst_Nil;
      61           2 :         if ( m_pShapeStyle->getLength() )
      62           0 :             m_pShapeStyle->makeStringAndClear();
      63           2 :         m_pShapeStyle->ensureCapacity( 200 );
      64           2 :         m_aShapeProps.clear();
      65             :     }
      66           2 : }
      67             : 
      68           2 : void RtfSdrExport::CloseContainer()
      69             : {
      70             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC);
      71             : 
      72           2 :     if ( mRecTypes.back() == ESCHER_SpContainer )
      73             :     {
      74             :         // write the shape now when we have all the info
      75           2 :         sal_Int32 nShapeElement = StartShape();
      76           2 :         EndShape( nShapeElement );
      77             : 
      78             :         // cleanup
      79           2 :         m_nShapeType = ESCHER_ShpInst_Nil;
      80             :     }
      81             : 
      82           2 :     EscherEx::CloseContainer();
      83           2 : }
      84             : 
      85           0 : sal_uInt32 RtfSdrExport::EnterGroup( const String& /*rShapeName*/, const Rectangle* /*pRect*/ )
      86             : {
      87             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC);
      88             : 
      89           0 :     return GenerateShapeId();
      90             : }
      91             : 
      92           0 : void RtfSdrExport::LeaveGroup()
      93             : {
      94             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC);
      95             : 
      96             :     /* noop */
      97           0 : }
      98             : 
      99           2 : void RtfSdrExport::AddShape( sal_uInt32 nShapeType, sal_uInt32 nShapeFlags, sal_uInt32 /*nShapeId*/ )
     100             : {
     101             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC);
     102             : 
     103           2 :     m_nShapeType = nShapeType;
     104           2 :     m_nShapeFlags = nShapeFlags;
     105           2 : }
     106             : 
     107          20 : inline sal_uInt16 impl_GetUInt16( const sal_uInt8* &pVal )
     108             : {
     109          20 :     sal_uInt16 nRet = *pVal++;
     110          20 :     nRet += ( *pVal++ ) << 8;
     111          20 :     return nRet;
     112             : }
     113             : 
     114         128 : inline sal_Int32 impl_GetPointComponent( const sal_uInt8* &pVal, sal_uInt16 nPointSize )
     115             : {
     116         128 :     sal_Int32 nRet = 0;
     117         128 :     if ( ( nPointSize == 0xfff0 ) || ( nPointSize == 4 ) )
     118             :     {
     119           0 :         sal_uInt16 nUnsigned = *pVal++;
     120           0 :         nUnsigned += ( *pVal++ ) << 8;
     121             : 
     122           0 :         nRet = sal_Int16( nUnsigned );
     123             :     }
     124         128 :     else if ( nPointSize == 8 )
     125             :     {
     126         128 :         sal_uInt32 nUnsigned = *pVal++;
     127         128 :         nUnsigned += ( *pVal++ ) << 8;
     128         128 :         nUnsigned += ( *pVal++ ) << 16;
     129         128 :         nUnsigned += ( *pVal++ ) << 24;
     130             : 
     131         128 :         nRet = nUnsigned;
     132             :     }
     133             : 
     134         128 :     return nRet;
     135             : }
     136             : 
     137           2 : void RtfSdrExport::Commit( EscherPropertyContainer& rProps, const Rectangle& rRect )
     138             : {
     139             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC);
     140             : 
     141           2 :     if ( m_nShapeType == ESCHER_ShpInst_Nil )
     142           2 :         return;
     143             : 
     144           2 :     if ( m_nShapeType == ESCHER_ShpInst_Line )
     145           0 :         AddLineDimensions( rRect );
     146             :     else
     147           2 :         AddRectangleDimensions( *m_pShapeStyle, rRect );
     148             : 
     149             :     // properties
     150           2 :     const EscherProperties &rOpts = rProps.GetOpts();
     151          36 :     for ( EscherProperties::const_iterator it = rOpts.begin(); it != rOpts.end(); ++it )
     152             :     {
     153          34 :         sal_uInt16 nId = ( it->nPropId & 0x0FFF );
     154             : 
     155          34 :         switch ( nId )
     156             :         {
     157             :             case ESCHER_Prop_WrapText:
     158             :                 {
     159           2 :                     int nWrapType = 0;
     160           2 :                     switch ( it->nPropValue )
     161             :                     {
     162           0 :                         case ESCHER_WrapSquare:    nWrapType = 2; break;
     163           0 :                         case ESCHER_WrapByPoints:  nWrapType = 4; break;
     164           2 :                         case ESCHER_WrapNone:      nWrapType = 3; break;
     165           0 :                         case ESCHER_WrapTopBottom: nWrapType = 1; break;
     166           0 :                         case ESCHER_WrapThrough:   nWrapType = 5; break;
     167             :                     }
     168           2 :                     if ( nWrapType )
     169           2 :                         m_pShapeStyle->append(OOO_STRING_SVTOOLS_RTF_SHPWR).append((sal_Int32)nWrapType);
     170             :                 }
     171           2 :                 break;
     172             :             case ESCHER_Prop_fillColor:
     173           2 :                 m_aShapeProps.insert(std::pair<OString,OString>("fillColor", OString::valueOf(sal_Int32(it->nPropValue))));
     174           2 :                 break;
     175             :             case ESCHER_Prop_fillBackColor:
     176           2 :                 m_aShapeProps.insert(std::pair<OString,OString>("fillBackColor", OString::valueOf(sal_Int32(it->nPropValue))));
     177           2 :                 break;
     178             :             case ESCHER_Prop_AnchorText:
     179           2 :                 m_aShapeProps.insert(std::pair<OString,OString>("anchorText", OString::valueOf(sal_Int32(it->nPropValue))));
     180           2 :                 break;
     181             :             case ESCHER_Prop_fNoFillHitTest:
     182           2 :                 if (it->nPropValue)
     183           2 :                     m_aShapeProps.insert(std::pair<OString,OString>("fNoFillHitTest", OString::valueOf(sal_Int32(1))));
     184           2 :                 break;
     185             :             case ESCHER_Prop_fNoLineDrawDash:
     186             :                 // for some reason the value is set to 0x90000 if lines are switched off
     187           2 :                 if( it->nPropValue == 0x90000 )
     188           0 :                     m_aShapeProps.insert(std::pair<OString,OString>("fLine", OString::valueOf(sal_Int32(0))));
     189           2 :                 break;
     190             :             case ESCHER_Prop_lineColor:
     191           2 :                 m_aShapeProps.insert(std::pair<OString,OString>("lineColor", OString::valueOf(sal_Int32(it->nPropValue))));
     192           2 :                 break;
     193             :             case ESCHER_Prop_lineBackColor:
     194           2 :                 m_aShapeProps.insert(std::pair<OString,OString>("lineBackColor", OString::valueOf(sal_Int32(it->nPropValue))));
     195           2 :                 break;
     196             :             case ESCHER_Prop_lineJoinStyle:
     197           2 :                 m_aShapeProps.insert(std::pair<OString,OString>("lineJoinStyle", OString::valueOf(sal_Int32(it->nPropValue))));
     198           2 :                 break;
     199             :             case ESCHER_Prop_fshadowObscured:
     200           2 :                 if (it->nPropValue)
     201           2 :                     m_aShapeProps.insert(std::pair<OString,OString>("fshadowObscured", "1"));
     202           2 :                 break;
     203             :             case ESCHER_Prop_geoLeft:
     204             :             case ESCHER_Prop_geoTop:
     205             :                 {
     206           4 :                     sal_uInt32 nLeft = 0, nTop = 0;
     207             : 
     208           4 :                     if ( nId == ESCHER_Prop_geoLeft )
     209             :                     {
     210           2 :                         nLeft = it->nPropValue;
     211           2 :                         rProps.GetOpt( ESCHER_Prop_geoTop, nTop );
     212             :                     }
     213             :                     else
     214             :                     {
     215           2 :                         nTop = it->nPropValue;
     216           2 :                         rProps.GetOpt( ESCHER_Prop_geoLeft, nLeft );
     217             :                     }
     218             : 
     219             :                     m_aShapeProps.insert(std::pair<OString,OString>("geoLeft",
     220           4 :                                 OString::valueOf(sal_Int32(sal_Int32( nLeft )))));
     221             :                     m_aShapeProps.insert(std::pair<OString,OString>("geoTop",
     222           4 :                                 OString::valueOf(sal_Int32(sal_Int32( nTop )))));
     223             :                 }
     224           4 :                 break;
     225             : 
     226             :             case ESCHER_Prop_geoRight:
     227             :             case ESCHER_Prop_geoBottom:
     228             :                 {
     229           4 :                     sal_uInt32 nLeft = 0, nRight = 0, nTop = 0, nBottom = 0;
     230           4 :                     rProps.GetOpt( ESCHER_Prop_geoLeft, nLeft );
     231           4 :                     rProps.GetOpt( ESCHER_Prop_geoTop, nTop );
     232             : 
     233           4 :                     if ( nId == ESCHER_Prop_geoRight )
     234             :                     {
     235           2 :                         nRight = it->nPropValue;
     236           2 :                         rProps.GetOpt( ESCHER_Prop_geoBottom, nBottom );
     237             :                     }
     238             :                     else
     239             :                     {
     240           2 :                         nBottom = it->nPropValue;
     241           2 :                         rProps.GetOpt( ESCHER_Prop_geoRight, nRight );
     242             :                     }
     243             : 
     244             :                     m_aShapeProps.insert(std::pair<OString,OString>("geoRight",
     245           4 :                                 OString::valueOf(sal_Int32(sal_Int32( nRight ) - sal_Int32( nLeft )))));
     246             :                     m_aShapeProps.insert(std::pair<OString,OString>("geoBottom",
     247           4 :                                 OString::valueOf(sal_Int32(sal_Int32( nBottom ) - sal_Int32( nTop )))));
     248             :                 }
     249           4 :                 break;
     250             :             case ESCHER_Prop_pVertices:
     251             :             case ESCHER_Prop_pSegmentInfo:
     252             :                 {
     253             :                     EscherPropSortStruct aVertices;
     254             :                     EscherPropSortStruct aSegments;
     255             : 
     256           8 :                     if ( rProps.GetOpt( ESCHER_Prop_pVertices, aVertices ) &&
     257           4 :                          rProps.GetOpt( ESCHER_Prop_pSegmentInfo, aSegments ) )
     258             :                     {
     259           4 :                         const sal_uInt8 *pVerticesIt = aVertices.pBuf + 6;
     260           4 :                         const sal_uInt8 *pSegmentIt = aSegments.pBuf;
     261             : 
     262           4 :                         OStringBuffer aSegmentInfo( 512 );
     263           4 :                         OStringBuffer aVerticies( 512 );
     264             : 
     265           4 :                         sal_uInt16 nPointSize = aVertices.pBuf[4] + ( aVertices.pBuf[5] << 8 );
     266             : 
     267             :                         // number of segments
     268           4 :                         sal_uInt16 nSegments = impl_GetUInt16( pSegmentIt );
     269           4 :                         sal_Int32 nVertices = 0;
     270           4 :                         aSegmentInfo.append("2;").append((sal_Int32)nSegments);
     271           4 :                         pSegmentIt += 4;
     272             : 
     273          20 :                         for ( ; nSegments; --nSegments )
     274             :                         {
     275          16 :                             sal_uInt16 nSeg = impl_GetUInt16( pSegmentIt );
     276          16 :                             aSegmentInfo.append(';').append((sal_Int32)nSeg);
     277          16 :                             switch ( nSeg )
     278             :                             {
     279             :                                 case 0x0001: // lineto
     280             :                                 case 0x4000: // moveto
     281             :                                     {
     282           4 :                                         sal_Int32 nX = impl_GetPointComponent( pVerticesIt, nPointSize );
     283           4 :                                         sal_Int32 nY = impl_GetPointComponent( pVerticesIt, nPointSize );
     284           4 :                                         aVerticies.append( ";(" ).append( nX ).append( "," ).append( nY ).append( ")" );
     285           4 :                                         nVertices ++;
     286             :                                     }
     287           4 :                                     break;
     288             :                                 case 0x2001: // curveto
     289             :                                     {
     290           0 :                                         for (int i = 0; i < 3; i++)
     291             :                                         {
     292           0 :                                             sal_Int32 nX = impl_GetPointComponent( pVerticesIt, nPointSize );
     293           0 :                                             sal_Int32 nY = impl_GetPointComponent( pVerticesIt, nPointSize );
     294           0 :                                             aVerticies.append( ";(" ).append( nX ).append( "," ).append( nY ).append( ")" );
     295           0 :                                             nVertices ++;
     296             :                                         }
     297             :                                     }
     298           0 :                                     break;
     299             :                                 case 0xb300:
     300             :                                 case 0xac00:
     301             :                                 case 0xaa00: // nofill
     302             :                                 case 0xab00: // nostroke
     303             :                                 case 0x6001: // close
     304             :                                 case 0x8000: // end
     305           8 :                                     break;
     306             :                                 default:
     307             :                                     // See EscherPropertyContainer::CreateCustomShapeProperties, by default nSeg is simply the number of points.
     308          64 :                                     for (int i = 0; i < nSeg; ++i)
     309             :                                     {
     310          60 :                                         sal_Int32 nX = impl_GetPointComponent(pVerticesIt, nPointSize);
     311          60 :                                         sal_Int32 nY = impl_GetPointComponent(pVerticesIt, nPointSize);
     312          60 :                                         aVerticies.append(";(").append(nX).append(",").append(nY).append(")");
     313          60 :                                         ++nVertices;
     314             :                                     }
     315           4 :                                     break;
     316             :                             }
     317             :                         }
     318             : 
     319           4 :                         if (aVerticies.getLength() )
     320             :                         {
     321             :                             // We know the number of vertices at the end only, so we have to prepend them here.
     322           4 :                             OStringBuffer aBuf;
     323           4 :                             aBuf.append("8;").append((sal_Int32)nVertices);
     324           4 :                             aBuf.append(aVerticies.makeStringAndClear());
     325           4 :                             m_aShapeProps.insert(std::pair<OString,OString>("pVerticies", aBuf.makeStringAndClear()));
     326             :                         }
     327           4 :                         if ( aSegmentInfo.getLength() )
     328           4 :                             m_aShapeProps.insert(std::pair<OString,OString>("pSegmentInfo", aSegmentInfo.makeStringAndClear()));
     329             :                     }
     330             :                     else
     331             :                         SAL_INFO("sw.rtf", OSL_THIS_FUNC << ": unhandled shape path, missing either pVertices or pSegmentInfo");
     332             :                 }
     333           4 :                 break;
     334             :             case ESCHER_Prop_shapePath:
     335             :                 // noop, we use pSegmentInfo instead
     336           0 :                 break;
     337             :             case ESCHER_Prop_fFillOK:
     338           0 :                 if (!it->nPropValue)
     339           0 :                     m_aShapeProps.insert(std::pair<OString,OString>("fFillOK", "0"));
     340           0 :                 break;
     341             :             case ESCHER_Prop_dxTextLeft:
     342           0 :                 m_aShapeProps.insert(std::pair<OString,OString>("dxTextLeft", OString::valueOf(sal_Int32(it->nPropValue))));
     343           0 :                 break;
     344             :             case ESCHER_Prop_dyTextTop:
     345           0 :                 m_aShapeProps.insert(std::pair<OString,OString>("dyTextTop", OString::valueOf(sal_Int32(it->nPropValue))));
     346           0 :                 break;
     347             :             case ESCHER_Prop_dxTextRight:
     348           0 :                 m_aShapeProps.insert(std::pair<OString,OString>("dxTextRight", OString::valueOf(sal_Int32(it->nPropValue))));
     349           0 :                 break;
     350             :             case ESCHER_Prop_dyTextBottom:
     351           0 :                 m_aShapeProps.insert(std::pair<OString,OString>("dyTextBottom", OString::valueOf(sal_Int32(it->nPropValue))));
     352           0 :                 break;
     353             :             case ESCHER_Prop_FitTextToShape:
     354             :                 // Size text to fit shape size: not supported by RTF
     355           0 :                 break;
     356             :             case ESCHER_Prop_adjustValue:
     357           0 :                 m_aShapeProps.insert(std::pair<OString,OString>("adjustValue", OString::valueOf(sal_Int32(it->nPropValue))));
     358           0 :                 break;
     359             :             case ESCHER_Prop_txflTextFlow:
     360           0 :                 m_aShapeProps.insert(std::pair<OString,OString>("txflTextFlow", OString::valueOf(sal_Int32(it->nPropValue))));
     361           0 :                 break;
     362             :             case ESCHER_Prop_fillType:
     363           0 :                 m_aShapeProps.insert(std::pair<OString,OString>("fillType", OString::valueOf(sal_Int32(it->nPropValue))));
     364           0 :                 break;
     365             :             case ESCHER_Prop_fillOpacity:
     366           0 :                 m_aShapeProps.insert(std::pair<OString,OString>("fillOpacity", OString::valueOf(sal_Int32(it->nPropValue))));
     367           0 :                 break;
     368             :             case ESCHER_Prop_fillBlip:
     369             :                 {
     370           0 :                     OStringBuffer aBuf;
     371           0 :                     aBuf.append('{').append(OOO_STRING_SVTOOLS_RTF_PICT).append(OOO_STRING_SVTOOLS_RTF_PNGBLIP).append(RtfExport::sNewLine);
     372           0 :                     int nHeaderSize = 25; // The first bytes are WW8-specific, we're only interested in the PNG
     373           0 :                     aBuf.append(RtfAttributeOutput::WriteHex(it->pBuf + nHeaderSize, it->nPropSize - nHeaderSize));
     374           0 :                     aBuf.append('}');
     375           0 :                     m_aShapeProps.insert(std::pair<OString,OString>("fillBlip", aBuf.makeStringAndClear()));
     376             :                 }
     377           0 :                 break;
     378             :             default:
     379             :                 SAL_INFO("sw.rtf", OSL_THIS_FUNC << ": unhandled property: " << nId << " (value: " << it->nPropValue << ")");
     380           2 :                 break;
     381             :         }
     382           2 :     }
     383             : }
     384             : 
     385           0 : void RtfSdrExport::AddLineDimensions( const Rectangle& rRectangle )
     386             : {
     387             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC);
     388             : 
     389             :     // We get the position relative to (the current?) character
     390           0 :     m_aShapeProps.insert(std::pair<OString,OString>("posrelh", "3"));
     391             : 
     392           0 :     switch ( m_nShapeFlags & 0xC0 )
     393             :     {
     394             :         case 0x40:
     395           0 :             m_aShapeProps.insert(std::pair<OString,OString>("fFlipV", "1"));
     396           0 :             break;
     397             :         case 0x80:
     398           0 :             m_aShapeProps.insert(std::pair<OString,OString>("fFlipH", "1"));
     399           0 :             break;
     400             :         case 0xC0:
     401           0 :             m_aShapeProps.insert(std::pair<OString,OString>("fFlipV", "1"));
     402           0 :             m_aShapeProps.insert(std::pair<OString,OString>("fFlipH", "1"));
     403           0 :             break;
     404             :     }
     405             : 
     406             :     // the actual dimensions
     407           0 :     m_pShapeStyle->append(OOO_STRING_SVTOOLS_RTF_SHPLEFT).append(rRectangle.Left());
     408           0 :     m_pShapeStyle->append(OOO_STRING_SVTOOLS_RTF_SHPTOP).append(rRectangle.Top());
     409           0 :     m_pShapeStyle->append(OOO_STRING_SVTOOLS_RTF_SHPRIGHT).append(rRectangle.Right());
     410           0 :     m_pShapeStyle->append(OOO_STRING_SVTOOLS_RTF_SHPBOTTOM).append(rRectangle.Bottom());
     411           0 : }
     412             : 
     413           2 : void RtfSdrExport::AddRectangleDimensions( rtl::OStringBuffer& rBuffer, const Rectangle& rRectangle )
     414             : {
     415             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC);
     416             : 
     417             :     // We get the position relative to (the current?) character
     418           2 :     m_aShapeProps.insert(std::pair<OString,OString>("posrelh", "3"));
     419             : 
     420           2 :     rBuffer.append(OOO_STRING_SVTOOLS_RTF_SHPLEFT).append(rRectangle.Left());
     421           2 :     rBuffer.append(OOO_STRING_SVTOOLS_RTF_SHPTOP).append(rRectangle.Top());
     422           2 :     rBuffer.append(OOO_STRING_SVTOOLS_RTF_SHPRIGHT).append(rRectangle.Right());
     423           2 :     rBuffer.append(OOO_STRING_SVTOOLS_RTF_SHPBOTTOM).append(rRectangle.Bottom());
     424           2 : }
     425             : 
     426             : extern const char* pShapeTypes[];
     427             : 
     428          36 : static void lcl_AppendSP( ::rtl::OStringBuffer& rRunText, const char cName[], const ::rtl::OString& rValue)
     429             : {
     430          36 :     rRunText.append('{').append(OOO_STRING_SVTOOLS_RTF_SP)
     431          36 :         .append('{').append(OOO_STRING_SVTOOLS_RTF_SN " ").append(cName).append('}')
     432          36 :         .append('{').append(OOO_STRING_SVTOOLS_RTF_SV " ").append(rValue).append('}')
     433          36 :         .append('}');
     434          36 : }
     435             : 
     436           0 : void RtfSdrExport::impl_writeGraphic()
     437             : {
     438             :     // Get the Graphic object from the Sdr one.
     439           0 :     uno::Reference<drawing::XShape> xShape = GetXShapeForSdrObject(const_cast<SdrObject*>(m_pSdrObject));
     440           0 :     uno::Reference<beans::XPropertySet> xPropertySet(xShape, uno::UNO_QUERY);
     441           0 :     OUString sGraphicURL;
     442           0 :     xPropertySet->getPropertyValue("GraphicURL") >>= sGraphicURL;
     443           0 :     OString aURLBS(OUStringToOString(sGraphicURL, RTL_TEXTENCODING_UTF8));
     444           0 :     const char aURLBegin[] = "vnd.sun.star.GraphicObject:";
     445           0 :     Graphic aGraphic = GraphicObject(aURLBS.copy(RTL_CONSTASCII_LENGTH(aURLBegin))).GetTransformedGraphic();
     446             : 
     447             :     // Export it to a stream.
     448           0 :     SvMemoryStream aStream;
     449           0 :     GraphicConverter::Export(aStream, aGraphic, CVT_PNG);
     450           0 :     aStream.Seek(STREAM_SEEK_TO_END);
     451           0 :     sal_uInt32 nSize = aStream.Tell();
     452           0 :     const sal_uInt8* pGraphicAry = (sal_uInt8*)aStream.GetData();
     453             : 
     454           0 :     Size aMapped(aGraphic.GetPrefSize());
     455             : 
     456             :     // Add it to the properties.
     457           0 :     RtfStringBuffer aBuf;
     458           0 :     aBuf->append('{').append(OOO_STRING_SVTOOLS_RTF_PICT).append(OOO_STRING_SVTOOLS_RTF_PNGBLIP);
     459           0 :     aBuf->append(OOO_STRING_SVTOOLS_RTF_PICW).append(sal_Int32(aMapped.Width()));
     460           0 :     aBuf->append(OOO_STRING_SVTOOLS_RTF_PICH).append(sal_Int32(aMapped.Height())).append(RtfExport::sNewLine);
     461           0 :     aBuf->append(RtfAttributeOutput::WriteHex(pGraphicAry, nSize));
     462           0 :     aBuf->append('}');
     463           0 :     m_aShapeProps.insert(std::pair<OString,OString>("pib", aBuf.makeStringAndClear()));
     464           0 : }
     465             : 
     466           2 : sal_Int32 RtfSdrExport::StartShape()
     467             : {
     468             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC);
     469             : 
     470           2 :     if ( m_nShapeType == ESCHER_ShpInst_Nil )
     471           0 :         return -1;
     472             : 
     473           2 :     m_aShapeProps.insert(std::pair<OString,OString>("shapeType", OString::valueOf(sal_Int32(m_nShapeType))));
     474           2 :     if (ESCHER_ShpInst_PictureFrame == m_nShapeType)
     475           0 :         impl_writeGraphic();
     476             : 
     477           2 :     m_rAttrOutput.RunText().append('{').append(OOO_STRING_SVTOOLS_RTF_SHP);
     478           2 :     m_rAttrOutput.RunText().append('{').append(OOO_STRING_SVTOOLS_RTF_IGNORE).append(OOO_STRING_SVTOOLS_RTF_SHPINST);
     479             : 
     480           2 :     m_rAttrOutput.RunText().append(m_pShapeStyle->makeStringAndClear());
     481             :     // Ignore \shpbxpage, \shpbxmargin, and \shpbxcolumn, in favor of the posrelh property.
     482           2 :     m_rAttrOutput.RunText().append(OOO_STRING_SVTOOLS_RTF_SHPBXIGNORE);
     483             :     // Ignore \shpbypage, \shpbymargin, and \shpbycolumn, in favor of the posrelh property.
     484           2 :     m_rAttrOutput.RunText().append(OOO_STRING_SVTOOLS_RTF_SHPBYIGNORE);
     485             : 
     486          34 :     for(std::map<OString,OString>::reverse_iterator i = m_aShapeProps.rbegin(); i != m_aShapeProps.rend(); ++i)
     487          32 :         lcl_AppendSP(m_rAttrOutput.RunText(), (*i).first.getStr(), (*i).second );
     488             : 
     489           2 :     lcl_AppendSP(m_rAttrOutput.RunText(), "wzDescription", msfilter::rtfutil::OutString( m_pSdrObject->GetDescription(), m_rExport.eCurrentEncoding));
     490           2 :     lcl_AppendSP(m_rAttrOutput.RunText(), "wzName", msfilter::rtfutil::OutString( m_pSdrObject->GetTitle(), m_rExport.eCurrentEncoding));
     491             : 
     492             :     // now check if we have some text
     493           2 :     const SdrTextObj* pTxtObj = PTR_CAST(SdrTextObj, m_pSdrObject);
     494           2 :     if (pTxtObj)
     495             :     {
     496           2 :         const OutlinerParaObject* pParaObj = 0;
     497           2 :         bool bOwnParaObj = false;
     498             : 
     499             :         /*
     500             :         #i13885#
     501             :         When the object is actively being edited, that text is not set into
     502             :         the objects normal text object, but lives in a seperate object.
     503             :         */
     504           2 :         if (pTxtObj->IsTextEditActive())
     505             :         {
     506           0 :             pParaObj = pTxtObj->GetEditOutlinerParaObject();
     507           0 :             bOwnParaObj = true;
     508             :         }
     509             :         else
     510             :         {
     511           2 :             pParaObj = pTxtObj->GetOutlinerParaObject();
     512             :         }
     513             : 
     514           2 :         if( pParaObj )
     515             :         {
     516             :             // this is reached only in case some text is attached to the shape
     517           0 :             WriteOutliner(*pParaObj);
     518           0 :             if( bOwnParaObj )
     519           0 :                 delete pParaObj;
     520             :         }
     521             :     }
     522             : 
     523           2 :     return m_nShapeType;
     524             : }
     525             : 
     526           0 : void RtfSdrExport::WriteOutliner(const OutlinerParaObject& rParaObj)
     527             : {
     528             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC << " start");
     529             : 
     530           0 :     const EditTextObject& rEditObj = rParaObj.GetTextObject();
     531           0 :     MSWord_SdrAttrIter aAttrIter( m_rExport, rEditObj, TXT_HFTXTBOX );
     532             : 
     533           0 :     sal_uInt16 nPara = rEditObj.GetParagraphCount();
     534             : 
     535           0 :     m_rAttrOutput.RunText().append('{').append(OOO_STRING_SVTOOLS_RTF_SHPTXT).append(' ');
     536           0 :     for (sal_uInt16 n = 0; n < nPara; ++n)
     537             :     {
     538           0 :         if( n )
     539           0 :             aAttrIter.NextPara( n );
     540             : 
     541           0 :         rtl_TextEncoding eChrSet = aAttrIter.GetNodeCharSet();
     542             : 
     543           0 :         String aStr( rEditObj.GetText( n ));
     544           0 :         xub_StrLen nAktPos = 0;
     545           0 :         xub_StrLen nEnd = aStr.Len();
     546             : 
     547           0 :         aAttrIter.OutParaAttr(false);
     548           0 :         m_rAttrOutput.RunText().append(m_rAttrOutput.Styles().makeStringAndClear());
     549             : 
     550           0 :         do {
     551           0 :             xub_StrLen nNextAttr = aAttrIter.WhereNext();
     552           0 :             rtl_TextEncoding eNextChrSet = aAttrIter.GetNextCharSet();
     553             : 
     554           0 :             if( nNextAttr > nEnd )
     555           0 :                 nNextAttr = nEnd;
     556             : 
     557           0 :             aAttrIter.OutAttr( nAktPos );
     558           0 :             m_rAttrOutput.RunText().append('{').append(m_rAttrOutput.Styles().makeStringAndClear()).append(m_rExport.sNewLine);
     559           0 :             bool bTxtAtr = aAttrIter.IsTxtAttr( nAktPos );
     560           0 :             if( !bTxtAtr )
     561             :             {
     562           0 :                 String aOut( aStr.Copy( nAktPos, nNextAttr - nAktPos ) );
     563           0 :                 m_rAttrOutput.RunText().append( msfilter::rtfutil::OutString( aOut, eChrSet ) );
     564             :             }
     565             : 
     566           0 :             m_rAttrOutput.RunText().append('}');
     567             : 
     568           0 :             nAktPos = nNextAttr;
     569           0 :             eChrSet = eNextChrSet;
     570           0 :             aAttrIter.NextPos();
     571             :         }
     572             :         while( nAktPos < nEnd );
     573           0 :     }
     574           0 :     m_rAttrOutput.RunText().append(OOO_STRING_SVTOOLS_RTF_PAR).append('}');
     575             : 
     576           0 :     SAL_INFO("sw.rtf", OSL_THIS_FUNC << " end");
     577           0 : }
     578             : 
     579           2 : void RtfSdrExport::EndShape( sal_Int32 nShapeElement )
     580             : {
     581             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC);
     582             : 
     583           2 :     if ( nShapeElement >= 0 )
     584             :     {
     585             :         // end of the shape
     586           2 :         m_rAttrOutput.RunText().append('}').append('}');
     587             :     }
     588           2 : }
     589             : 
     590           2 : sal_uInt32 RtfSdrExport::AddSdrObject( const SdrObject& rObj )
     591             : {
     592           2 :     m_pSdrObject = &rObj;
     593           2 :     return EscherEx::AddSdrObject(rObj);
     594             : }
     595             : 
     596             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10