LCOV - code coverage report
Current view: top level - sw/source/filter/ww8 - wrtww8gr.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 152 473 32.1 %
Date: 2014-04-11 Functions: 9 15 60.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             :  * 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 <com/sun/star/embed/XEmbedPersist.hpp>
      21             : #include <com/sun/star/embed/Aspects.hpp>
      22             : #include <com/sun/star/embed/ElementModes.hpp>
      23             : #include <rtl/math.hxx>
      24             : #include <vcl/graphicfilter.hxx>
      25             : #include <vcl/wmf.hxx>
      26             : #include <svl/itemiter.hxx>
      27             : #include "svl/urihelper.hxx"
      28             : 
      29             : #include <svtools/embedhlp.hxx>
      30             : 
      31             : #include <vcl/virdev.hxx>
      32             : #include <vcl/svapp.hxx>
      33             : 
      34             : #include <hintids.hxx>
      35             : #include <editeng/boxitem.hxx>
      36             : #include <editeng/shaditem.hxx>
      37             : #include <filter/msfilter/msoleexp.hxx>
      38             : #include <editeng/lrspitem.hxx>
      39             : #include <editeng/ulspitem.hxx>
      40             : #include <editeng/fhgtitem.hxx>
      41             : #include <svx/svdoole2.hxx>
      42             : 
      43             : #include <unotools/ucbstreamhelper.hxx>
      44             : #include <fmtanchr.hxx>
      45             : #include <ndgrf.hxx>
      46             : #include <frmfmt.hxx>
      47             : #include <grfatr.hxx>
      48             : #include <ndole.hxx>
      49             : #include <ndtxt.hxx>
      50             : #include <fmtfsize.hxx>
      51             : #include <fmtornt.hxx>
      52             : 
      53             : #include <filter/msfilter/sprmids.hxx>
      54             : 
      55             : #include <doc.hxx>
      56             : #include "writerhelper.hxx"
      57             : #include "writerwordglue.hxx"
      58             : #include "ww8struc.hxx"
      59             : #include "wrtww8.hxx"
      60             : #include "ww8par.hxx"
      61             : #include "escher.hxx"
      62             : //Added for i120568
      63             : #include "ww8attributeoutput.hxx"
      64             : #include "fmturl.hxx"
      65             : 
      66             : #include "docsh.hxx"
      67             : #include <cstdio>
      68             : 
      69             : #if OSL_DEBUG_LEVEL > 1
      70             : #include <stdio.h>
      71             : #endif
      72             : 
      73             : using namespace ::com::sun::star;
      74             : using namespace nsFieldFlags;
      75             : 
      76             : // TODO:
      77             : // 5. convert the MapModes that Widows can't handle
      78             : 
      79             : // OutGrf () is called for every GrafNode in the document. Es wird ein PicLocFc-Sprm
      80             : // eingefuegt, der statt Adresse ein Magic sal_uLong enthaelt. Ausserdem wird
      81             : // in der Graf-Klasse der GrfNode-Ptr gemerkt ( fuers spaetere Ausgeben der
      82             : // Grafiken und Patchen der PicLocFc-Attribute )
      83             : 
      84           1 : void WW8Export::OutputGrfNode( const SwGrfNode& /*rNode*/ )
      85             : {
      86             :     OSL_TRACE("WW8Export::OutputGrfNode( const SwGrfNode& )" );
      87             :     OSL_ENSURE( mpParentFrame, "frame not set!" );
      88           1 :     if ( mpParentFrame )
      89             :     {
      90           1 :         OutGrf( *mpParentFrame );
      91           1 :         pFib->fHasPic = true;
      92             :     }
      93           1 : }
      94             : 
      95           0 : bool WW8Export::TestOleNeedsGraphic(const SwAttrSet& rSet,
      96             :     SvStorageRef xOleStg, SvStorageRef xObjStg, OUString &rStorageName,
      97             :     SwOLENode *pOLENd)
      98             : {
      99           0 :     bool bGraphicNeeded = false;
     100           0 :     SfxItemIter aIter( rSet );
     101           0 :     const SfxPoolItem* pItem = aIter.GetCurItem();
     102             : 
     103           0 :     do {
     104           0 :         switch (pItem->Which())
     105             :         {
     106             :             /*
     107             :             For an inline object these properties are irrelevent because they
     108             :             will be the same as the defaults that msword applies in their
     109             :             absence, so if that is all that there is for these inline objects
     110             :             then if there turns out to be enough information in the object
     111             :             itself to regenerate the correct size and preview of the object
     112             :             then we will not need to provide an additional graphics preview in
     113             :             the data stream, which can save a lot of disk space.
     114             :             */
     115             :             case RES_FRM_SIZE:
     116             :             case RES_CNTNT:
     117             :             case RES_VERT_ORIENT:
     118             :             case RES_ANCHOR:
     119           0 :                 break;
     120             :             default:
     121           0 :                 bGraphicNeeded = true;
     122             :         }
     123           0 :     } while( !bGraphicNeeded && !aIter.IsAtEnd() &&
     124             :         0 != ( pItem = aIter.NextItem() ) );
     125             : 
     126             :     /*
     127             :     Now we must see if the object contains a preview itself which is equal to
     128             :     the preview that we are currently using. If the graphics are equal then we
     129             :     dont need to store another preview
     130             :     */
     131           0 :     GDIMetaFile aWMF;
     132           0 :     long nX=0,nY=0;
     133           0 :     if (!bGraphicNeeded && SwWW8ImplReader::ImportOleWMF(xOleStg,aWMF,nX,nY))
     134             :     {
     135             :         // bGraphicNeeded set to true is right / fixes #i51670#.
     136           0 :         bGraphicNeeded = true;
     137           0 :         Point aTmpPoint;
     138           0 :         Rectangle aRect( aTmpPoint, Size( nX, nY ) );
     139           0 :         Graphic aGraph(aWMF);
     140             : 
     141           0 :         ErrCode nErr = ERRCODE_NONE;
     142           0 :         Rectangle aVisArea;
     143           0 :         sal_Int64 nAspect = embed::Aspects::MSOLE_CONTENT;
     144           0 :         if ( pOLENd )
     145           0 :             nAspect = pOLENd->GetAspect();
     146             :         SdrOle2Obj *pRet = SvxMSDffManager::CreateSdrOLEFromStorage(
     147           0 :             rStorageName,xObjStg,pDoc->GetDocStorage(),aGraph,aRect,aVisArea,0,nErr,0,nAspect);
     148             : 
     149           0 :         if (pRet)
     150             :         {
     151           0 :             uno::Reference< embed::XEmbeddedObject > xObj = pOLENd->GetOLEObj().GetOleRef();
     152           0 :             if ( xObj.is() )
     153             :             {
     154           0 :                 SvStream* pGraphicStream = NULL;
     155           0 :                 comphelper::EmbeddedObjectContainer aCnt( pDoc->GetDocStorage() );
     156             :                 try
     157             :                 {
     158             :                     uno::Reference< embed::XEmbedPersist > xPersist(
     159             :                             xObj,
     160           0 :                             uno::UNO_QUERY_THROW );
     161             : 
     162             :                     // it makes no sence to search the object in the container by reference since the object was created
     163             :                     // outside of the container and was not inserted there, only the name makes sence
     164             :                     pGraphicStream =
     165           0 :                             ::utl::UcbStreamHelper::CreateStream( aCnt.GetGraphicStream( xPersist->getEntryName() ) );
     166             :                 }
     167           0 :                 catch( const uno::Exception& )
     168             :                 {}
     169             : 
     170             :                 OSL_ENSURE( pGraphicStream && !pGraphicStream->GetError(), "No graphic stream available!" );
     171           0 :                 if ( pGraphicStream && !pGraphicStream->GetError() )
     172             :                 {
     173           0 :                     Graphic aGr1;
     174           0 :                     GraphicFilter& rGF = GraphicFilter::GetGraphicFilter();
     175           0 :                     if( rGF.ImportGraphic( aGr1, OUString(), *pGraphicStream, GRFILTER_FORMAT_DONTKNOW ) == GRFILTER_OK )
     176             :                     {
     177           0 :                         Graphic aGr2;
     178           0 :                         delete pGraphicStream;
     179             :                         pGraphicStream =
     180           0 :                                 ::utl::UcbStreamHelper::CreateStream( aCnt.GetGraphicStream( pRet->GetObjRef() ) );
     181           0 :                         if( rGF.ImportGraphic( aGr2, OUString(), *pGraphicStream, GRFILTER_FORMAT_DONTKNOW ) == GRFILTER_OK )
     182             :                         {
     183           0 :                             if ( aGr1 == aGr2 )
     184           0 :                                 bGraphicNeeded = false;
     185           0 :                         }
     186           0 :                     }
     187             :                 }
     188             :                 else
     189           0 :                     delete pGraphicStream;
     190             :             }
     191             : 
     192           0 :             delete pRet;
     193           0 :         }
     194             :     }
     195             :     else
     196           0 :         bGraphicNeeded = true;
     197           0 :     return bGraphicNeeded;
     198             : }
     199             : 
     200           0 : void WW8Export::OutputOLENode( const SwOLENode& rOLENode )
     201             : {
     202             :     OSL_TRACE("WW8Export::OutputOLENode( const SwOLENode& rOLENode )" );
     203             :     sal_uInt8 *pSpecOLE;
     204             :     sal_uInt8 *pDataAdr;
     205             :     short nSize;
     206             :     static sal_uInt8 aSpecOLE_WW8[] = {
     207             :             0x03, 0x6a, 0, 0, 0, 0, // sprmCPicLocation
     208             :             0x0a, 0x08, 1,          // sprmCFOLE2
     209             :             0x56, 0x08, 1           // sprmCFObj
     210             :         };
     211             :     static sal_uInt8 aSpecOLE_WW6[] = {
     212             :             68, 4, 0, 0, 0, 0,      // sprmCPicLocation (len is 4)
     213             :             75, 1,                  // sprmCFOLE2
     214             :             118, 1                  // sprmCFObj
     215             :         };
     216             : 
     217           0 :     if ( bWrtWW8 )
     218             :     {
     219           0 :         pSpecOLE = aSpecOLE_WW8;
     220           0 :         nSize = sizeof( aSpecOLE_WW8 );
     221             :     }
     222             :     else
     223             :     {
     224           0 :         pSpecOLE = aSpecOLE_WW6;
     225           0 :         nSize = sizeof( aSpecOLE_WW6 );
     226             :     }
     227           0 :     pDataAdr = pSpecOLE + 2; //WW6 sprm is 1 but has 1 byte len as well.
     228             : 
     229           0 :     SvStorageRef xObjStg = GetWriter().GetStorage().OpenSotStorage(
     230             :         OUString(SL::aObjectPool), STREAM_READWRITE |
     231           0 :         STREAM_SHARE_DENYALL );
     232             : 
     233           0 :     if( xObjStg.Is()  )
     234             :     {
     235           0 :         uno::Reference < embed::XEmbeddedObject > xObj(const_cast<SwOLENode&>(rOLENode).GetOLEObj().GetOleRef());
     236           0 :         if( xObj.is() )
     237             :         {
     238           0 :             const embed::XEmbeddedObject *pObj = xObj.get();
     239           0 :             WW8OleMap& rPointerToObjId = GetOLEMap();
     240             :             //Don't want to use pointer ids, as is traditional, because we need
     241             :             //to put this into a 32bit value, and on 64bit the bottom bits
     242             :             //might collide and two unrelated ole objects end up considered the
     243             :             //same.  Don't want to simply start at 0 which is a special value
     244           0 :             sal_Int32 nPictureId = SAL_MAX_INT32 - rPointerToObjId.size();
     245           0 :             WW8OleMap::value_type entry = std::make_pair(pObj, nPictureId);
     246           0 :             std::pair<WW8OleMap::iterator, bool> aRes = rPointerToObjId.insert(entry);
     247           0 :             bool bIsNotDuplicate = aRes.second; //.second is false when element already existed
     248           0 :             nPictureId = aRes.first->second;
     249           0 :             Set_UInt32(pDataAdr, nPictureId);
     250           0 :             OUString sStorageName('_');
     251           0 :             sStorageName += OUString::number( nPictureId );
     252             :             SvStorageRef xOleStg = xObjStg->OpenSotStorage( sStorageName,
     253           0 :                                 STREAM_READWRITE| STREAM_SHARE_DENYALL );
     254           0 :             if( xOleStg.Is() )
     255             :             {
     256             :                 /*
     257             :                 If this object storage has been written already don't
     258             :                 waste time rewriting it
     259             :                 */
     260           0 :                 if (bIsNotDuplicate)
     261             :                 {
     262           0 :                     sal_Int64 nAspect = rOLENode.GetAspect();
     263           0 :                     svt::EmbeddedObjectRef aObjRef( xObj, nAspect );
     264           0 :                     GetOLEExp().ExportOLEObject( aObjRef, *xOleStg );
     265           0 :                     if ( nAspect == embed::Aspects::MSOLE_ICON )
     266             :                     {
     267           0 :                         OUString aObjInfo( "\3ObjInfo" );
     268           0 :                         if ( !xOleStg->IsStream( aObjInfo ) )
     269             :                         {
     270           0 :                             const sal_uInt8 pObjInfoData[] = { 0x40, 0x00, 0x03, 0x00 };
     271           0 :                             SvStorageStreamRef rObjInfoStream = xOleStg->OpenSotStream( aObjInfo );
     272           0 :                             if ( rObjInfoStream.Is() && !rObjInfoStream->GetError() )
     273             :                             {
     274           0 :                                 rObjInfoStream->Write( pObjInfoData, sizeof( pObjInfoData ) );
     275           0 :                                 xOleStg->Commit();
     276           0 :                             }
     277           0 :                         }
     278           0 :                     }
     279             :                 }
     280             : 
     281             :                 // write as embedded field - the other things will be done
     282             :                 // in the escher export
     283           0 :                 OUString sServer = FieldString(ww::eEMBED) + xOleStg->GetUserName() + " ";
     284             : 
     285             :                 OutputField(0, ww::eEMBED, sServer, WRITEFIELD_START |
     286           0 :                     WRITEFIELD_CMD_START | WRITEFIELD_CMD_END);
     287             : 
     288           0 :                 pChpPlc->AppendFkpEntry( Strm().Tell(),
     289           0 :                         nSize, pSpecOLE );
     290             : 
     291           0 :                 bool bEndCR = true;
     292             :                 /*
     293             :                 In the word filter we only need a preview image for
     294             :                 floating images, and then only (the usual case) if the
     295             :                 object doesn't contain enough information to reconstruct
     296             :                 what we need.
     297             : 
     298             :                 We don't need a graphic for inline objects, so we don't
     299             :                 even need the overhead of a graphic in that case.
     300             :                 */
     301           0 :                 bool bGraphicNeeded = false;
     302             : 
     303           0 :                 if (mpParentFrame)
     304             :                 {
     305           0 :                     bGraphicNeeded = true;
     306             : 
     307           0 :                     if (mpParentFrame->IsInline())
     308             :                     {
     309             :                         const SwAttrSet& rSet =
     310           0 :                             mpParentFrame->GetFrmFmt().GetAttrSet();
     311           0 :                         bEndCR = false;
     312             :                         bGraphicNeeded = TestOleNeedsGraphic(rSet,
     313           0 :                             xOleStg, xObjStg, sStorageName, const_cast<SwOLENode*>(&rOLENode));
     314             :                     }
     315             :                 }
     316             : 
     317           0 :                 if (!bGraphicNeeded)
     318           0 :                     WriteChar(0x1);
     319             :                 else
     320             :                 {
     321             :                     /*
     322             :                     ##897##
     323             :                     We need to insert the graphic representation of
     324             :                     this object for the inline case, otherwise word
     325             :                     has no place to find the dimensions of the ole
     326             :                     object, and will not be able to draw it
     327             :                     */
     328           0 :                     OutGrf(*mpParentFrame);
     329             :                 }
     330             : 
     331             :                 OutputField(0, ww::eEMBED, OUString(),
     332           0 :                     WRITEFIELD_END | WRITEFIELD_CLOSE);
     333             : 
     334           0 :                 if (bEndCR) //No newline in inline case
     335           0 :                     WriteCR();
     336           0 :             }
     337           0 :         }
     338           0 :     }
     339           0 : }
     340             : 
     341           0 : void WW8Export::OutputLinkedOLE( const OUString& rOleId )
     342             : {
     343           0 :     uno::Reference< embed::XStorage > xDocStg = pDoc->GetDocStorage();
     344           0 :     uno::Reference< embed::XStorage > xOleStg = xDocStg->openStorageElement( "OLELinks", embed::ElementModes::READ );
     345           0 :     SotStorageRef xObjSrc = SotStorage::OpenOLEStorage( xOleStg, rOleId, STREAM_READ );
     346             : 
     347           0 :     SotStorageRef xObjStg = GetWriter().GetStorage().OpenSotStorage(
     348             :         OUString(SL::aObjectPool), STREAM_READWRITE |
     349           0 :         STREAM_SHARE_DENYALL );
     350             : 
     351           0 :     if( xObjStg.Is() && xObjSrc.Is() )
     352             :     {
     353             :         SotStorageRef xOleDst = xObjStg->OpenSotStorage( rOleId,
     354           0 :                 STREAM_READWRITE | STREAM_SHARE_DENYALL );
     355           0 :         if ( xOleDst.Is() )
     356           0 :             xObjSrc->CopyTo( xOleDst );
     357             : 
     358           0 :         if ( !xOleDst->GetError( ) )
     359             :         {
     360           0 :             xOleDst->Commit();
     361             : 
     362             :             // Ouput the cPicLocation attribute
     363           0 :             ww::bytes* pBuf = new ww::bytes();
     364           0 :             GetWriter().InsUInt16( *pBuf, NS_sprm::LN_CPicLocation );
     365           0 :             GetWriter().InsUInt32( *pBuf, rOleId.copy( 1 ).toInt32() );
     366             : 
     367           0 :             GetWriter().InsUInt16( *pBuf, NS_sprm::LN_CFOle2 );
     368           0 :             pBuf->push_back( 1 );
     369             : 
     370           0 :             GetWriter().InsUInt16( *pBuf, NS_sprm::LN_CFSpec );
     371           0 :             pBuf->push_back( 1 );
     372             : 
     373           0 :             GetWriter().InsUInt16( *pBuf, NS_sprm::LN_CFObj );
     374           0 :             pBuf->push_back( 1 );
     375             : 
     376           0 :             pChpPlc->AppendFkpEntry( Strm().Tell(), pBuf->size(), pBuf->data() );
     377           0 :             delete pBuf;
     378           0 :         }
     379           0 :     }
     380           0 : }
     381             : 
     382           1 : void WW8Export::OutGrf(const sw::Frame &rFrame)
     383             : {
     384             :     //Added for i120568,the hyperlink info within a graphic whose anchor type is "As character"
     385             :     //will be exported to ensure the fidelity
     386           1 :     const SwFmtURL& rURL = rFrame.GetFrmFmt().GetAttrSet().GetURL();
     387           1 :     bool bURLStarted = false;
     388           1 :     if( !rURL.GetURL().isEmpty() && rFrame.GetWriterType() == sw::Frame::eGraphic)
     389             :     {
     390           0 :         bURLStarted = true;
     391           0 :         m_pAttrOutput->StartURL( rURL.GetURL(), rURL.GetTargetFrameName() );
     392             :     }
     393             : 
     394             :     // Store the graphic settings in GrfNode so they may be written-out later
     395           1 :     pGrf->Insert(rFrame);
     396             : 
     397           1 :     pChpPlc->AppendFkpEntry( Strm().Tell(), pO->size(), pO->data() );
     398           1 :     pO->clear();
     399             : 
     400             :     // #i29408#
     401             :     // linked, as-character anchored graphics have to be exported as fields.
     402           2 :     const SwGrfNode* pGrfNd = rFrame.IsInline() && rFrame.GetContent()
     403           2 :                               ? rFrame.GetContent()->GetGrfNode() : 0;
     404           1 :     if ( pGrfNd && pGrfNd->IsLinkedFile() )
     405             :     {
     406           0 :         OUString sStr( FieldString(ww::eINCLUDEPICTURE) );
     407           0 :         sStr += " \"";
     408             :         {
     409           0 :             if ( pGrfNd )
     410             :             {
     411           0 :                 OUString aFileURL;
     412           0 :                 pGrfNd->GetFileFilterNms( &aFileURL, 0 );
     413           0 :                 sStr += aFileURL;
     414             :             }
     415             :         }
     416           0 :         sStr += "\" \\d";
     417             : 
     418             :         OutputField( 0, ww::eINCLUDEPICTURE, sStr,
     419           0 :                    WRITEFIELD_START | WRITEFIELD_CMD_START | WRITEFIELD_CMD_END );
     420             :     }
     421             : 
     422           1 :     WriteChar( (char)1 );   // paste graphic symbols in the main text
     423             : 
     424             :     sal_uInt8 aArr[ 18 ];
     425           1 :     sal_uInt8* pArr = aArr;
     426             : 
     427           1 :     const SwFrmFmt &rFlyFmt = rFrame.GetFrmFmt();
     428           1 :     const RndStdIds eAn = rFlyFmt.GetAttrSet().GetAnchor(false).GetAnchorId();
     429           1 :     if (eAn == FLY_AS_CHAR)
     430             :     {
     431           1 :         sal_Int16 eVert = rFlyFmt.GetVertOrient().GetVertOrient();
     432           1 :         if ((eVert == text::VertOrientation::CHAR_CENTER) || (eVert == text::VertOrientation::LINE_CENTER))
     433             :         {
     434           0 :             bool bVert = false;
     435             :             //The default for word in vertical text mode is to center,
     436             :             //otherwise a sub/super script hack is employed
     437           0 :             if (pOutFmtNode && pOutFmtNode->ISA(SwCntntNode) )
     438             :             {
     439           0 :                 const SwTxtNode* pTxtNd = (const SwTxtNode*)pOutFmtNode;
     440           0 :                 SwPosition aPos(*pTxtNd);
     441           0 :                 bVert = pDoc->IsInVerticalText(aPos);
     442             :             }
     443           0 :             if (!bVert)
     444             :             {
     445           0 :                 SwTwips nHeight = rFlyFmt.GetFrmSize().GetHeight();
     446           0 :                 nHeight/=20; //nHeight was in twips, want it in half points, but
     447             :                              //then half of total height.
     448             :                 long nFontHeight = ((const SvxFontHeightItem&)
     449           0 :                     GetItem(RES_CHRATR_FONTSIZE)).GetHeight();
     450           0 :                 nHeight-=nFontHeight/20;
     451             : 
     452           0 :                 if (bWrtWW8)
     453           0 :                     Set_UInt16( pArr, NS_sprm::LN_CHpsPos );
     454             :                 else
     455           0 :                     Set_UInt8( pArr, 101 );
     456           0 :                 Set_UInt16( pArr, -((sal_Int16)nHeight));
     457             :             }
     458             :         }
     459             :     }
     460             : 
     461             :     // sprmCFSpec
     462           1 :     if( bWrtWW8 )
     463           1 :         Set_UInt16( pArr, 0x855 );
     464             :     else
     465           0 :         Set_UInt8( pArr, 117 );
     466           1 :     Set_UInt8( pArr, 1 );
     467             : 
     468             :     // sprmCPicLocation
     469           1 :     if( bWrtWW8 )
     470           1 :         Set_UInt16( pArr, NS_sprm::LN_CPicLocation );
     471             :     else
     472             :     {
     473           0 :         Set_UInt8( pArr, 68 );
     474           0 :         Set_UInt8( pArr, 4 );
     475             :     }
     476           1 :     Set_UInt32( pArr, GRF_MAGIC_321 );
     477             : 
     478             :     // vary Magic, so that different graphic attributes will not be merged
     479             :     static sal_uInt8 nAttrMagicIdx = 0;
     480           1 :     --pArr;
     481           1 :     Set_UInt8( pArr, nAttrMagicIdx++ );
     482           1 :     pChpPlc->AppendFkpEntry( Strm().Tell(), static_cast< short >(pArr - aArr), aArr );
     483             : 
     484             :     // #i75464#
     485             :     // Check, if graphic isn't exported as-character anchored.
     486             :     // Otherwise, an additional paragraph is exported for a graphic, which is
     487             :     // forced to be treated as inline, because it's anchored inside another frame.
     488           1 :     if ( !rFrame.IsInline() &&
     489           0 :          ( ((eAn == FLY_AT_PARA) && ( bWrtWW8 || !IsInTable() )) ||
     490             :            (eAn == FLY_AT_PAGE)) )
     491             :     {
     492           0 :         WriteChar( (char)0x0d ); // close the surrounding frame with CR
     493             : 
     494             :         static sal_uInt8 nSty[2] = { 0, 0 };
     495           0 :         pO->insert( pO->end(), nSty, nSty+2 );     // Style #0
     496           0 :         bool bOldGrf = bOutGrf;
     497           0 :         bOutGrf = true;
     498             : 
     499           0 :         OutputFormat( rFrame.GetFrmFmt(), false, false, true ); // Fly-Attrs
     500             : 
     501           0 :         bOutGrf = bOldGrf;
     502           0 :         pPapPlc->AppendFkpEntry( Strm().Tell(), pO->size(), pO->data() );
     503           0 :         pO->clear();
     504             :     }
     505             :     // #i29408#
     506             :     // linked, as-character anchored graphics have to be exported as fields.
     507           1 :     else if ( pGrfNd && pGrfNd->IsLinkedFile() )
     508             :     {
     509           0 :         OutputField( 0, ww::eINCLUDEPICTURE, OUString(), WRITEFIELD_CLOSE );
     510             :     }
     511             :     //Added for i120568,the hyperlink info within a graphic whose anchor type is
     512             :     //"As character" will be exported to ensure the fidelity
     513           1 :     if( bURLStarted )
     514           0 :         m_pAttrOutput->EndURL();
     515           1 : }
     516             : 
     517           0 : GraphicDetails& GraphicDetails::operator=(const GraphicDetails &rOther)
     518             : {
     519           0 :     maFly = rOther.maFly;
     520           0 :     mnPos = rOther.mnPos;
     521           0 :     mnWid = rOther.mnWid;
     522           0 :     mnHei = rOther.mnHei;
     523           0 :     return *this;
     524             : }
     525             : 
     526           1 : void SwWW8WrGrf::Insert(const sw::Frame &rFly)
     527             : {
     528           1 :     const Size aSize( rFly.GetLayoutSize() );
     529           1 :     const sal_uInt16 nWidth = static_cast< sal_uInt16 >(aSize.Width());
     530           1 :     const sal_uInt16 nHeight = static_cast< sal_uInt16 >(aSize.Height());
     531           1 :     maDetails.push_back(GraphicDetails(rFly, nWidth, nHeight));
     532           1 : }
     533             : 
     534           1 : void SwWW8WrGrf::WritePICFHeader(SvStream& rStrm, const sw::Frame &rFly,
     535             :     sal_uInt16 mm, sal_uInt16 nWidth, sal_uInt16 nHeight, const SwAttrSet* pAttrSet)
     536             : {
     537           1 :     sal_Int16 nXSizeAdd = 0, nYSizeAdd = 0;
     538           1 :     sal_Int16 nCropL = 0, nCropR = 0, nCropT = 0, nCropB = 0;
     539             : 
     540             :             // write Crop-Attribut content in Header ( if available )
     541             :     const SfxPoolItem* pItem;
     542           2 :     if (pAttrSet && (SFX_ITEM_ON
     543           1 :         == pAttrSet->GetItemState(RES_GRFATR_CROPGRF, false, &pItem)))
     544             :     {
     545           1 :         const SwCropGrf& rCr = *(SwCropGrf*)pItem;
     546           1 :         nCropL = (sal_Int16)rCr.GetLeft();
     547           1 :         nCropR = (sal_Int16)rCr.GetRight();
     548           1 :         nCropT = (sal_Int16)rCr.GetTop();
     549           1 :         nCropB = (sal_Int16)rCr.GetBottom();
     550           1 :         nXSizeAdd = nXSizeAdd - (sal_Int16)( rCr.GetLeft() + rCr.GetRight() );
     551           1 :         nYSizeAdd = nYSizeAdd - (sal_Int16)( rCr.GetTop() + rCr.GetBottom() );
     552             :     }
     553             : 
     554           1 :     Size aGrTwipSz(rFly.GetSize());
     555           1 :     bool bWrtWW8 = rWrt.bWrtWW8;
     556           1 :     sal_uInt16 nHdrLen = bWrtWW8 ? 0x44 : 0x3A;
     557             : 
     558           1 :     sal_uInt8 aArr[ 0x44 ] = { 0 };
     559             : 
     560           1 :     sal_uInt8* pArr = aArr + 0x2E;  // Do borders first
     561             : 
     562           1 :     const SwAttrSet& rAttrSet = rFly.GetFrmFmt().GetAttrSet();
     563           1 :     if (SFX_ITEM_ON == rAttrSet.GetItemState(RES_BOX, false, &pItem))
     564             :     {
     565           1 :         const SvxBoxItem* pBox = (const SvxBoxItem*)pItem;
     566           1 :         if( pBox )
     567             :         {
     568           1 :             bool bShadow = false;               // Shadow ?
     569             :             const SvxShadowItem* pSI =
     570           1 :                 sw::util::HasItem<SvxShadowItem>(rAttrSet, RES_SHADOW);
     571           1 :             if (pSI)
     572             :             {
     573           1 :                 bShadow = (pSI->GetLocation() != SVX_SHADOW_NONE) &&
     574           1 :                     (pSI->GetWidth() != 0);
     575             :             }
     576             : 
     577             :             sal_uInt8 aLnArr[4] = { BOX_LINE_TOP, BOX_LINE_LEFT,
     578           1 :                                 BOX_LINE_BOTTOM, BOX_LINE_RIGHT };
     579           5 :             for( sal_uInt8 i = 0; i < 4; ++i )
     580             :             {
     581           4 :                 const ::editeng::SvxBorderLine* pLn = pBox->GetLine( aLnArr[ i ] );
     582           4 :                 WW8_BRC aBrc;
     583           4 :                 if (pLn)
     584             :                 {
     585             :                     WW8_BRCVer9 aBrc90 = rWrt.TranslateBorderLine( *pLn,
     586           4 :                         pBox->GetDistance( aLnArr[ i ] ), bShadow );
     587             :                     sal_uInt8 ico = rWrt.TransCol(msfilter::util::BGRToRGB(
     588           4 :                         aBrc90.cv()));
     589           8 :                     aBrc = WW8_BRC(ico, aBrc90.dptLineWidth(), aBrc90.brcType(),
     590          12 :                         aBrc90.dptSpace(), aBrc90.fShadow(), aBrc90.fFrame());
     591             :                 }
     592             : 
     593             :                 // use importer logic to determine how large the exported
     594             :                 // border will really be in word and adjust accordingly
     595             :                 short nSpacing;
     596           4 :                 short nThick = aBrc.DetermineBorderProperties(&nSpacing);
     597           4 :                 switch (aLnArr[ i ])
     598             :                 {
     599             :                     case BOX_LINE_TOP:
     600             :                     case BOX_LINE_BOTTOM:
     601           2 :                         nHeight -= bShadow ? nThick*2 : nThick;
     602           2 :                         nHeight = nHeight - nSpacing;
     603           2 :                         break;
     604             :                     case BOX_LINE_LEFT:
     605             :                     case BOX_LINE_RIGHT:
     606             :                     default:
     607           2 :                         nWidth -= bShadow ? nThick*2 : nThick;
     608           2 :                         nWidth = nWidth - nSpacing;
     609           2 :                         break;
     610             :                 }
     611           4 :                 memcpy( pArr, &aBrc.aBits1, 2);
     612           4 :                 pArr+=2;
     613             : 
     614           4 :                 if( bWrtWW8 )
     615             :                 {
     616           4 :                     memcpy( pArr, &aBrc.aBits2, 2);
     617           4 :                     pArr+=2;
     618             :                 }
     619             :             }
     620             :         }
     621             :     }
     622             : 
     623           1 :     pArr = aArr + 4;                                // skip lcb
     624           1 :     Set_UInt16( pArr, nHdrLen );                    // set cbHeader
     625             : 
     626           1 :     Set_UInt16( pArr, mm );                         // set mm
     627             : 
     628             :     /*
     629             :     Just in case our original size is too big to fit inside a ushort we can
     630             :     substitute the final size and loose on retaining the scaling factor but
     631             :     still keep the correct display size anyway.
     632             :     */
     633           3 :     const bool bIsSubstitutedSize = (aGrTwipSz.Width() > SHRT_MAX) || (aGrTwipSz.Height() > SHRT_MAX) ||
     634           3 :                                     (aGrTwipSz.Width() < 0 ) || (aGrTwipSz.Height() < 0);
     635           1 :     if ( bIsSubstitutedSize )
     636             :     {
     637           0 :         aGrTwipSz.Width() = nWidth;
     638           0 :         aGrTwipSz.Height() = nHeight;
     639             :     }
     640             :     using namespace sw::types;
     641             :     // set xExt & yExt
     642           1 :     Set_UInt16(pArr, msword_cast<sal_uInt16>(aGrTwipSz.Width() * 254L / 144));
     643           1 :     Set_UInt16(pArr, msword_cast<sal_uInt16>(aGrTwipSz.Height() * 254L / 144));
     644           1 :     pArr += 16;
     645             :     // skip hMF & rcWinMF
     646             :     // set dxaGoal & dyaGoal
     647           1 :     Set_UInt16(pArr, msword_cast<sal_uInt16>(aGrTwipSz.Width()));
     648           1 :     Set_UInt16(pArr, msword_cast<sal_uInt16>(aGrTwipSz.Height()));
     649             : 
     650           1 :     if ( aGrTwipSz.Width() + nXSizeAdd )             // set mx
     651             :     {
     652           1 :         if ( !bIsSubstitutedSize )
     653             :         {
     654           1 :             const double fVal = nWidth * 1000.0 / (aGrTwipSz.Width() + nXSizeAdd );
     655           1 :             Set_UInt16( pArr, (sal_uInt16)::rtl::math::round(fVal) );
     656             :         }
     657             :         else
     658             :         {
     659           0 :             Set_UInt16( pArr, 1000 );
     660             :         }
     661             :     }
     662             :     else
     663             :     {
     664           0 :         pArr += 2;
     665             :     }
     666             : 
     667           1 :     if ( aGrTwipSz.Height() + nYSizeAdd )            // set my
     668             :     {
     669           1 :         if ( !bIsSubstitutedSize )
     670             :         {
     671           1 :             const double fVal = nHeight * 1000.0 / (aGrTwipSz.Height() + nYSizeAdd);
     672           1 :             Set_UInt16( pArr, (sal_uInt16)::rtl::math::round(fVal) );
     673             :         }
     674             :         else
     675             :         {
     676           0 :             Set_UInt16( pArr, 1000 );
     677             :         }
     678             :     }
     679             :     else
     680             :     {
     681           0 :         pArr += 2;
     682             :     }
     683             : 
     684           1 :     if ( !bIsSubstitutedSize )
     685             :     {
     686           1 :         Set_UInt16( pArr, nCropL );                     // set dxaCropLeft
     687           1 :         Set_UInt16( pArr, nCropT );                     // set dyaCropTop
     688           1 :         Set_UInt16( pArr, nCropR );                     // set dxaCropRight
     689           1 :         Set_UInt16( pArr, nCropB );                     // set dyaCropBottom
     690             :     }
     691             :     else
     692             :     {
     693           0 :         pArr += 8;
     694             :     }
     695             : 
     696           1 :     rStrm.Write( aArr, nHdrLen );
     697           1 : }
     698             : 
     699           1 : void SwWW8WrGrf::WriteGrfFromGrfNode(SvStream& rStrm, const SwGrfNode &rGrfNd,
     700             :     const sw::Frame &rFly, sal_uInt16 nWidth, sal_uInt16 nHeight)
     701             : {
     702           1 :     if (rGrfNd.IsLinkedFile())     // Linked File
     703             :     {
     704           0 :         OUString aFileN;
     705           0 :         rGrfNd.GetFileFilterNms( &aFileN, 0 );
     706             : 
     707           0 :             sal_uInt16 mm = 94;                    // 94 = BMP, GIF
     708             : 
     709             :         WritePICFHeader(rStrm, rFly, mm, nWidth, nHeight,
     710           0 :             rGrfNd.GetpSwAttrSet());
     711           0 :         rStrm.WriteUChar( (sal_uInt8)aFileN.getLength() );    // write Pascal-String
     712             :         SwWW8Writer::WriteString8(rStrm, aFileN, false,
     713           0 :             RTL_TEXTENCODING_MS_1252);
     714             :     }
     715             :     else                                // Embedded File or DDE or something like that
     716             :     {
     717           1 :         if (rWrt.bWrtWW8)
     718             :         {
     719             :             WritePICFHeader(rStrm, rFly, 0x64, nWidth, nHeight,
     720           1 :                 rGrfNd.GetpSwAttrSet());
     721           1 :             SwBasicEscherEx aInlineEscher(&rStrm, rWrt);
     722           1 :             aInlineEscher.WriteGrfFlyFrame(rFly.GetFrmFmt(), 0x401);
     723           1 :             aInlineEscher.WritePictures();
     724             :         }
     725             :         else
     726             :         {
     727           0 :             Graphic& rGrf = const_cast<Graphic&>(rGrfNd.GetGrf());
     728           0 :             bool bSwapped = rGrf.IsSwapOut() ? true : false;
     729             :             // immer ueber den Node einswappen!
     730           0 :             const_cast<SwGrfNode&>(rGrfNd).SwapIn();
     731             : 
     732           0 :             GDIMetaFile aMeta;
     733           0 :             switch (rGrf.GetType())
     734             :             {
     735             :                 case GRAPHIC_BITMAP:        // Bitmap -> play in Metafile
     736             :                     {
     737           0 :                         VirtualDevice aVirt;
     738           0 :                         aMeta.Record(&aVirt);
     739           0 :                         aVirt.DrawBitmap( Point( 0,0 ), rGrf.GetBitmap() );
     740           0 :                         aMeta.Stop();
     741           0 :                         aMeta.WindStart();
     742           0 :                         aMeta.SetPrefMapMode( rGrf.GetPrefMapMode());
     743           0 :                         aMeta.SetPrefSize( rGrf.GetPrefSize());
     744             :                     }
     745           0 :                     break;
     746             :                 case GRAPHIC_GDIMETAFILE :      // GDI ( =SV ) Metafile
     747           0 :                     aMeta = rGrf.GetGDIMetaFile();
     748           0 :                     break;
     749             :                 default:
     750           1 :                     return;
     751             :             }
     752             : 
     753             :             WritePICFHeader(rStrm, rFly, 8, nWidth, nHeight,
     754           0 :                 rGrfNd.GetpSwAttrSet());
     755           0 :             WriteWindowMetafileBits(rStrm, aMeta);
     756             : 
     757           0 :             if (bSwapped)
     758           0 :                 rGrf.SwapOut();
     759             :         }
     760             :     }
     761             : }
     762             : //For i120928,export graphic info of bullet
     763           0 : void SwWW8WrGrf::WritePICBulletFHeader(SvStream& rStrm, const Graphic &rGrf,
     764             :             sal_uInt16 mm, sal_uInt16 nWidth, sal_uInt16 nHeight)
     765             : {
     766           0 :     sal_Int16 nXSizeAdd = 0, nYSizeAdd = 0;
     767           0 :     sal_Int16 nCropL = 0, nCropR = 0, nCropT = 0, nCropB = 0;
     768             : 
     769           0 :     Size aGrTwipSz(rGrf.GetPrefSize());
     770           0 :     bool bWrtWW8 = rWrt.bWrtWW8;
     771           0 :     sal_uInt16 nHdrLen = bWrtWW8 ? 0x44 : 0x3A;
     772             : 
     773           0 :     sal_uInt8 aArr[ 0x44 ] = { 0 };
     774             : 
     775           0 :     sal_uInt8* pArr = aArr + 0x2E;  //Do borders first
     776             : 
     777             :     sal_uInt8 aLnArr[4] = { BOX_LINE_TOP, BOX_LINE_LEFT,
     778           0 :     BOX_LINE_BOTTOM, BOX_LINE_RIGHT };
     779           0 :     for( sal_uInt8 i = 0; i < 4; ++i )
     780             :     {
     781           0 :         WW8_BRC aBrc;
     782             : 
     783             :         short nSpacing;
     784           0 :         short nThick = aBrc.DetermineBorderProperties(&nSpacing);
     785           0 :         switch (aLnArr[ i ])
     786             :         {
     787             :             case BOX_LINE_TOP:
     788             :             case BOX_LINE_BOTTOM:
     789           0 :             nHeight -= nThick;
     790           0 :             nHeight = nHeight - nSpacing;
     791           0 :             break;
     792             :             case BOX_LINE_LEFT:
     793             :             case BOX_LINE_RIGHT:
     794             :             default:
     795           0 :             nWidth -= nThick;
     796           0 :             nWidth = nWidth - nSpacing;
     797           0 :             break;
     798             :         }
     799           0 :         memcpy( pArr, &aBrc.aBits1, 2);
     800           0 :         pArr+=2;
     801             : 
     802           0 :         if( bWrtWW8 )
     803             :         {
     804           0 :             memcpy( pArr, &aBrc.aBits2, 2);
     805           0 :             pArr+=2;
     806             :         }
     807             :     }
     808             : 
     809           0 :     pArr = aArr + 4;                                //skip lcb
     810           0 :     Set_UInt16( pArr, nHdrLen );                    // set cbHeader
     811             : 
     812           0 :     Set_UInt16( pArr, mm );                         // set mm
     813             : 
     814           0 :     if ( (aGrTwipSz.Width() * 254L / 144 > USHRT_MAX) || (aGrTwipSz.Height()  * 254L / 144 > USHRT_MAX)
     815           0 :         || (aGrTwipSz.Width() < 0 ) || (aGrTwipSz.Height() < 0) )
     816             :     {
     817           0 :         aGrTwipSz.Width() = nWidth;
     818           0 :         aGrTwipSz.Height() = nHeight;
     819             :     }
     820             :     using namespace sw::types;
     821             :     // set xExt & yExt
     822           0 :     Set_UInt16(pArr, msword_cast<sal_uInt16>(aGrTwipSz.Width() * 254L / 144));
     823           0 :     Set_UInt16(pArr, msword_cast<sal_uInt16>(aGrTwipSz.Height() * 254L / 144));
     824           0 :     pArr += 16;
     825             :     // skip hMF & rcWinMF
     826             :     // set dxaGoal & dyaGoal
     827           0 :     Set_UInt16(pArr, msword_cast<sal_uInt16>(aGrTwipSz.Width()));
     828           0 :     Set_UInt16(pArr, msword_cast<sal_uInt16>(aGrTwipSz.Height()));
     829             : 
     830           0 :     if( aGrTwipSz.Width() + nXSizeAdd )             // set mx
     831             :     {
     832           0 :         double fVal = nWidth * 1000.0 / (aGrTwipSz.Width() + nXSizeAdd);
     833           0 :         Set_UInt16( pArr, (sal_uInt16)::rtl::math::round(fVal) );
     834             :     }
     835             :     else
     836           0 :         pArr += 2;
     837             : 
     838           0 :     if( aGrTwipSz.Height() + nYSizeAdd )            // set my
     839             :     {
     840           0 :         double fVal = nHeight * 1000.0 / (aGrTwipSz.Height() + nYSizeAdd);
     841           0 :         Set_UInt16( pArr, (sal_uInt16)::rtl::math::round(fVal) );
     842             :     }
     843             :     else
     844           0 :         pArr += 2;
     845             : 
     846           0 :     Set_UInt16( pArr, nCropL );                     // set dxaCropLeft
     847           0 :     Set_UInt16( pArr, nCropT );                     // set dyaCropTop
     848           0 :     Set_UInt16( pArr, nCropR );                     // set dxaCropRight
     849           0 :     Set_UInt16( pArr, nCropB );                     // set dyaCropBottom
     850             : 
     851           0 :     rStrm.Write( aArr, nHdrLen );
     852           0 : }
     853             : 
     854           0 : void SwWW8WrGrf::WriteGrfForBullet(SvStream& rStrm, const Graphic &rGrf, sal_uInt16 nWidth, sal_uInt16 nHeight)
     855             : {
     856           0 :     if (rWrt.bWrtWW8)
     857             :     {
     858           0 :         WritePICBulletFHeader(rStrm,rGrf, 0x64,nWidth,nHeight);
     859           0 :         SwBasicEscherEx aInlineEscher(&rStrm, rWrt);
     860           0 :         aInlineEscher.WriteGrfBullet(rGrf);
     861           0 :         aInlineEscher.WritePictures();
     862             :     }
     863             :     else
     864             :     {
     865           0 :         GDIMetaFile aMeta;
     866           0 :         switch (rGrf.GetType())
     867             :         {
     868             :             case GRAPHIC_BITMAP:        // Bitmap -> in Metafile abspielen
     869             :             {
     870           0 :                 VirtualDevice aVirt;
     871           0 :                 aMeta.Record(&aVirt);
     872           0 :                 aVirt.DrawBitmap( Point( 0,0 ), rGrf.GetBitmap() );
     873           0 :                 aMeta.Stop();
     874           0 :                 aMeta.WindStart();
     875           0 :                 aMeta.SetPrefMapMode( rGrf.GetPrefMapMode());
     876           0 :                 aMeta.SetPrefSize( rGrf.GetPrefSize());
     877             :             }
     878           0 :             break;
     879             :             case GRAPHIC_GDIMETAFILE :      // GDI ( =SV ) Metafile
     880           0 :                 aMeta = rGrf.GetGDIMetaFile();
     881           0 :             break;
     882             :             default:
     883           0 :                 return;
     884             :         }
     885           0 :         WritePICBulletFHeader(rStrm, rGrf, 8, nWidth, nHeight);
     886           0 :         WriteWindowMetafileBits(rStrm, aMeta);
     887             :     }
     888             : }
     889             : 
     890           1 : void SwWW8WrGrf::WriteGraphicNode(SvStream& rStrm, const GraphicDetails &rItem)
     891             : {
     892           1 :     sal_uInt16 nWidth = rItem.mnWid;
     893           1 :     sal_uInt16 nHeight = rItem.mnHei;
     894           1 :     sal_uInt32 nPos = rStrm.Tell();         // store start of graphic
     895             : 
     896           1 :     const sw::Frame &rFly = rItem.maFly;
     897           1 :     switch (rFly.GetWriterType())
     898             :     {
     899             :         case sw::Frame::eGraphic:
     900             :         {
     901           1 :             const SwNode *pNode = rItem.maFly.GetContent();
     902           1 :             const SwGrfNode *pNd = pNode ? pNode->GetGrfNode() : 0;
     903             :             OSL_ENSURE(pNd, "Impossible");
     904           1 :             if (pNd)
     905           1 :                 WriteGrfFromGrfNode(rStrm, *pNd, rItem.maFly, nWidth, nHeight);
     906             :         }
     907           1 :         break;
     908             :         //For i120928,add branch to export graphic of bullet
     909             :         case sw::Frame::eBulletGrf:
     910             :         {
     911           0 :             if (rItem.maFly.HasGraphic())
     912             :             {
     913           0 :                 const Graphic& rGrf = rItem.maFly.GetGraphic();
     914           0 :                 WriteGrfForBullet(rStrm, rGrf, nWidth, nHeight);
     915             :             }
     916             :         }
     917           0 :         break;
     918             : 
     919             :         case sw::Frame::eOle:
     920             :         {
     921             : #ifdef OLE_PREVIEW_AS_EMF
     922           0 :             const SwNode *pNode = rItem.maFly.GetContent();
     923           0 :             const SwOLENode *pNd = pNode ? pNode->GetOLENode() : 0;
     924             :             OSL_ENSURE(pNd, "Impossible");
     925           0 :             if (!rWrt.bWrtWW8)
     926             :             {
     927           0 :                 SwOLENode *pOleNd = const_cast<SwOLENode*>(pNd);
     928             :                 OSL_ENSURE( pOleNd, " Wer hat den OleNode versteckt ?" );
     929           0 :                 SwOLEObj&                   rSObj= pOleNd->GetOLEObj();
     930           0 :                 uno::Reference < embed::XEmbeddedObject > rObj(  rSObj.GetOleRef() );
     931             : 
     932           0 :                 comphelper::EmbeddedObjectContainer aCnt( pOleNd->GetDoc()->GetDocStorage() );
     933             : 
     934           0 :                 SvStream* pGraphicStream = ::utl::UcbStreamHelper::CreateStream( aCnt.GetGraphicStream( rObj ) );
     935             :                 OSL_ENSURE( pGraphicStream && !pGraphicStream->GetError(), "No graphic stream available!" );
     936           0 :                 if ( pGraphicStream && !pGraphicStream->GetError() )
     937             :                 {
     938           0 :                     Graphic aGr;
     939           0 :                     GraphicFilter& rGF = GraphicFilter::GetGraphicFilter();
     940           0 :                     if( rGF.ImportGraphic( aGr, OUString(), *pGraphicStream, GRFILTER_FORMAT_DONTKNOW ) == GRFILTER_OK )
     941             :                     {
     942             :                         //TODO/LATER: do we really want to use GDIMetafile?!
     943           0 :                         GDIMetaFile aMtf;
     944           0 :                         aMtf = aGr.GetGDIMetaFile();
     945           0 :                         aMtf.WindStart();
     946             :                         aMtf.Play(Application::GetDefaultDevice(), Point(0, 0),
     947           0 :                             Size(2880, 2880));
     948             :                         WritePICFHeader(rStrm, rFly, 8, nWidth, nHeight,
     949           0 :                             pNd->GetpSwAttrSet());
     950           0 :                         WriteWindowMetafileBits(rStrm, aMtf);
     951           0 :                     }
     952             :                 }
     953             :                 else
     954           0 :                     delete pGraphicStream;
     955             :             }
     956             :             else
     957             :             {
     958             :                 //Convert this ole2 preview in ww8+ to an EMF for better unicode
     959             :                 //support (note that at this moment this breaks StarSymbol
     960             :                 //using graphics because I need to embed starsymbol in exported
     961             :                 //documents.
     962             :                 WritePICFHeader(rStrm, rFly, 0x64, nWidth, nHeight,
     963           0 :                     pNd->GetpSwAttrSet());
     964           0 :                 SwBasicEscherEx aInlineEscher(&rStrm, rWrt);
     965           0 :                 aInlineEscher.WriteOLEFlyFrame(rFly.GetFrmFmt(), 0x401);
     966           0 :                 aInlineEscher.WritePictures();
     967             :             }
     968             : #else
     969             :             // cast away const
     970             :             SwOLENode *pOleNd = const_cast<SwOLENode*>(pNd);
     971             :             OSL_ENSURE( pOleNd, " Wer hat den OleNode versteckt ?" );
     972             :             SwOLEObj&                   rSObj= pOleNd->GetOLEObj();
     973             : 
     974             :             // TODO/LATER: do we need to load object?
     975             :             Graphic* pGr = SdrOle2Obj::GetGraphicFromObject( pOleNd->GetDoc()->GetDocStorage(), rObj );
     976             : 
     977             :             //TODO/LATER: do we really want to use GDIMetafile?!
     978             :             GDIMetaFile aMtf;
     979             :             if ( pGr )
     980             :                 aMtf = pGr->GetGDIMetaFile();
     981             : 
     982             :             Size aS(aMtf.GetPrefSize());
     983             :             aMtf.WindStart();
     984             :             aMtf.Play(Application::GetDefaultDevice(), Point(0, 0),
     985             :                 Size(2880, 2880));
     986             : 
     987             :             WritePICFHeader(rStrm, rFly, 8, nWidth, nHeight,
     988             :                 pNd->GetpSwAttrSet());
     989             :             WriteWindowMetafileBits(rStrm, aMtf);
     990             :             delete pGr;
     991             : #endif
     992             :         }
     993           0 :         break;
     994             :         case sw::Frame::eDrawing:
     995             :         case sw::Frame::eTxtBox:
     996             :         case sw::Frame::eFormControl:
     997             :             OSL_ENSURE(rWrt.bWrtWW8,
     998             :                 "You can't try and export these in WW8 format, a filter bug");
     999             :             /*
    1000             :             #i3958# We only export an empty dummy picture frame here, this is
    1001             :             what word does the escher export should contain an anchored to
    1002             :             character element which is drawn over this dummy and the whole
    1003             :             shebang surrounded with a SHAPE field. This isn't *my* hack :-),
    1004             :             its what word does.
    1005             :             */
    1006           0 :             if (rWrt.bWrtWW8)
    1007             :             {
    1008           0 :                 WritePICFHeader(rStrm, rFly, 0x64, nWidth, nHeight);
    1009           0 :                 SwBasicEscherEx aInlineEscher(&rStrm, rWrt);
    1010           0 :                 aInlineEscher.WriteEmptyFlyFrame(rFly.GetFrmFmt(), 0x401);
    1011             :             }
    1012           0 :             break;
    1013             :         default:
    1014             :             OSL_ENSURE(!this,
    1015             :            "Some inline export not implemented, remind cmc before we ship :-)");
    1016           0 :             break;
    1017             :     }
    1018             : 
    1019           1 :     sal_uInt32 nPos2 = rStrm.Tell();                    // store the end
    1020           1 :     rStrm.Seek( nPos );
    1021             :     SVBT32 nLen;
    1022           1 :     UInt32ToSVBT32( nPos2 - nPos, nLen );             // calculate graphic length
    1023           1 :     rStrm.Write( nLen, 4 );                         // patch it in the header
    1024           1 :     rStrm.Seek( nPos2 );                            // restore Pos
    1025           1 : }
    1026             : 
    1027             : // SwWW8WrGrf::Write() is called after the text.
    1028             : // It writes out all the graphics and remembers the file locations of the graphics,
    1029             : // so when writing the attributes of the items it can be patched into PicLocFc-SPRMs.
    1030             : // The search in the attributes for the Magic sal_uLong and patching
    1031             : // happens when writing the attributes. Class SwWW8WrGrf-Klasse provides with
    1032             : // GetFPos() sequentially the positions
    1033          12 : void SwWW8WrGrf::Write()
    1034             : {
    1035          12 :     SvStream& rStrm = *rWrt.pDataStrm;
    1036          12 :     myiter aEnd = maDetails.end();
    1037          13 :     for (myiter aIter = maDetails.begin(); aIter != aEnd; ++aIter)
    1038             :     {
    1039           1 :         sal_uInt32 nPos = rStrm.Tell();                 // align to 4 Bytes
    1040           1 :         if( nPos & 0x3 )
    1041           0 :             SwWW8Writer::FillCount( rStrm, 4 - ( nPos & 0x3 ) );
    1042             : 
    1043           1 :         bool bDuplicated = false;
    1044           1 :         for (myiter aIter2 = maDetails.begin(); aIter2 != aIter; ++aIter2)
    1045             :         {
    1046           0 :             if (*aIter2 == *aIter)
    1047             :             {
    1048           0 :                 aIter->mnPos = aIter2->mnPos;
    1049           0 :                 bDuplicated = true;
    1050           0 :                 break;
    1051             :             }
    1052             :         }
    1053             : 
    1054           1 :         if (!bDuplicated)
    1055             :         {
    1056           1 :             aIter->mnPos = rStrm.Tell();
    1057           1 :             WriteGraphicNode(rStrm, *aIter);
    1058             :         }
    1059             :     }
    1060          45 : }
    1061             : 
    1062             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10