LCOV - code coverage report
Current view: top level - sw/source/filter/ww8 - ww8graf.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 789 1372 57.5 %
Date: 2015-06-13 12:38:46 Functions: 41 57 71.9 %
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 <comphelper/string.hxx>
      21             : #include <svl/urihelper.hxx>
      22             : #include <hintids.hxx>
      23             : #include <osl/endian.h>
      24             : #include <svx/fmglob.hxx>
      25             : #include <svx/sdtaitm.hxx>
      26             : #include <editeng/lrspitem.hxx>
      27             : #include <editeng/udlnitem.hxx>
      28             : #include <svx/xlineit.hxx>
      29             : #include <svx/xfillit.hxx>
      30             : #include <svx/svdmodel.hxx>
      31             : #include <svx/svdocapt.hxx>
      32             : #include <svx/sxctitm.hxx>
      33             : #include <editeng/editeng.hxx>
      34             : #include <svx/svdpage.hxx>
      35             : #include <svx/svdopath.hxx>
      36             : #include <svx/svdocirc.hxx>
      37             : #include <editeng/outlobj.hxx>
      38             : #include <svx/svdogrp.hxx>
      39             : #include <svx/svdograf.hxx>
      40             : #include <svx/svdoole2.hxx>
      41             : #include <editeng/colritem.hxx>
      42             : #include <editeng/fhgtitem.hxx>
      43             : #include <editeng/postitem.hxx>
      44             : #include <editeng/adjustitem.hxx>
      45             : #include <editeng/wghtitem.hxx>
      46             : #include <editeng/crossedoutitem.hxx>
      47             : #include <editeng/contouritem.hxx>
      48             : #include <editeng/shdditem.hxx>
      49             : #include <editeng/fontitem.hxx>
      50             : #include <editeng/ulspitem.hxx>
      51             : #include <svx/svdoattr.hxx>
      52             : #include <editeng/brushitem.hxx>
      53             : #include <svx/rectenum.hxx>
      54             : #include <editeng/opaqitem.hxx>
      55             : #include <editeng/shaditem.hxx>
      56             : #include <editeng/boxitem.hxx>
      57             : #include <editeng/outliner.hxx>
      58             : #include <editeng/frmdiritem.hxx>
      59             : #include <svx/xfltrit.hxx>
      60             : #include <filter/msfilter/msdffimp.hxx>
      61             : #include <grfatr.hxx>
      62             : #include <fmtornt.hxx>
      63             : #include <fmtcntnt.hxx>
      64             : #include <frmfmt.hxx>
      65             : #include <fmtanchr.hxx>
      66             : #include <pam.hxx>
      67             : #include <doc.hxx>
      68             : #include <drawdoc.hxx>
      69             : #include <IDocumentDrawModelAccess.hxx>
      70             : #include <docary.hxx>
      71             : #include <ndgrf.hxx>
      72             : #include <ndtxt.hxx>
      73             : #include <dcontact.hxx>
      74             : #include <docsh.hxx>
      75             : #include <mdiexp.hxx>
      76             : #include <fmtcnct.hxx>
      77             : #include "ww8struc.hxx"
      78             : #include "ww8scan.hxx"
      79             : #include "ww8par.hxx"
      80             : #include "ww8par2.hxx"
      81             : #include "ww8graf.hxx"
      82             : #include <fmtinfmt.hxx>
      83             : #include <editeng/eeitem.hxx>
      84             : #include <editeng/flditem.hxx>
      85             : #include <fmtfollowtextflow.hxx>
      86             : #include "writerhelper.hxx"
      87             : #include "writerwordglue.hxx"
      88             : #include <basegfx/point/b2dpoint.hxx>
      89             : #include <basegfx/polygon/b2dpolygon.hxx>
      90             : #include <editeng/editobj.hxx>
      91             : #include <boost/scoped_ptr.hpp>
      92             : #include <math.h>
      93             : #include <fmturl.hxx>
      94             : #include <svx/hlnkitem.hxx>
      95             : #include <svl/whiter.hxx>
      96             : #include <o3tl/enumrange.hxx>
      97             : 
      98             : using ::editeng::SvxBorderLine;
      99             : using namespace ::com::sun::star;
     100             : using namespace sw::types;
     101             : using namespace sw::util;
     102             : 
     103             : // helper methods
     104           0 : Color WW8TransCol(SVBT32 nWC)
     105             : {
     106             : #if 1               // 1 = use predefined color, 0 = ignore
     107             : 
     108             :     // Farbtabelle zum Umrechnen RGB-Werte in vordefinierte Farben
     109             :     // ( Damit bei der Writer-UI die Farbnamen stimmen )
     110             :     // Die Tabelle int im *3er-System* aufgeteilt. Die Grauwerte fehlen,
     111             :     // da sie nicht ins 3er-System passen ( 4 Werte: sw, ws, 2 * grau )
     112             :     static const ColorData eColA[] = {              //  B G R  B G R  B G R
     113             :         COL_BLACK, COL_RED, COL_LIGHTRED,           //  0 0 0, 0 0 1, 0 0 2
     114             :         COL_GREEN, COL_BROWN, COL_BLACK,            //  0 1 0, 0 1 1, 0 1 2
     115             :         COL_LIGHTGREEN, COL_BLACK, COL_YELLOW,      //  0 2 0, 0 2 1, 0 2 2
     116             :         COL_BLUE, COL_MAGENTA, COL_BLACK,           //  1 0 0, 1 0 1, 1 0 2
     117             :         COL_CYAN, COL_LIGHTGRAY, COL_BLACK,         //  1 1 0, 1 1 1, 1 1 2
     118             :         COL_BLACK, COL_BLACK, COL_BLACK,            //  1 2 0, 1 2 1, 1 2 2
     119             :         COL_LIGHTBLUE, COL_BLACK, COL_LIGHTMAGENTA, //  2 0 0, 2 0 1, 2 0 2
     120             :         COL_BLACK, COL_BLACK, COL_BLACK,            //  2 1 0, 2 1 1, 2 1 2
     121             :         COL_LIGHTCYAN, COL_BLACK, COL_WHITE };      //  2 2 0, 2 2 1, 2 2 2
     122             : 
     123             :     // In nWC[3] steht ein Byte, dass in der WW-Doku nicht beschrieben ist.
     124             :     // Die Bedeutung ist anscheinend folgende: Bei 0 ist es eine normale
     125             :     // Farbe, dessen RGB-Wert in nWC[0..2] steht. stehen in nWC[3] die
     126             :     // Werte 0x1, 0x7d oder 0x83, dann ist es ein Grauwert, dessen
     127             :     // Schwarzanteil in 1/2 % in nWC[0] steht.
     128             :     // Ich vermute, dass es auf Bit0 in nWV[3] ankommt, ob es RGB oder Grau ist.
     129             : 
     130           0 :     if( !( nWC[3] & 0x1 ) &&                        // keine Spezial-Farbe (grau)
     131           0 :         (    ( nWC[0] == 0 ||  nWC[0]== 0x80 || nWC[0] == 0xff )    // R-Anteil
     132           0 :           && ( nWC[1] == 0 ||  nWC[1]== 0x80 || nWC[1] == 0xff )    // G-Anteil
     133           0 :           && ( nWC[2] == 0 ||  nWC[2]== 0x80 || nWC[2] == 0xff ) ) ){// B-Anteil
     134           0 :         int nIdx = 0;       // and now: Idx-calculation im 3er-System
     135           0 :         for (int i = 2; i >= 0; i--)
     136             :         {
     137           0 :             nIdx *= 3;
     138           0 :             if (nWC[i])
     139           0 :                 nIdx += ((nWC[i] == 0xff) ? 2 : 1);
     140             :         }
     141           0 :         if (eColA[nIdx] != COL_BLACK)
     142           0 :             return Color(eColA[nIdx]);  // default color
     143             :     }
     144             : #endif
     145             : 
     146           0 :     if (nWC[3] & 0x1)
     147             :     {
     148             :         // Special color gray
     149           0 :         sal_uInt8 u = (sal_uInt8)( (sal_uLong)( 200 - nWC[0] ) * 256 / 200 );
     150           0 :         return Color(u, u, u);
     151             :     }
     152             : 
     153             :     // User-Color
     154           0 :     return Color(nWC[0], nWC[1], nWC[2]);
     155             : }
     156             : 
     157          30 : void wwFrameNamer::SetUniqueGraphName(SwFrameFormat *pFrameFormat, const OUString &rFixed)
     158             : {
     159          30 :     if (mbIsDisabled || rFixed.isEmpty())
     160          60 :         return;
     161             : 
     162           0 :     pFrameFormat->SetName(msSeed+OUString::number(++mnImportedGraphicsCount) + ": " + rFixed);
     163             : }
     164             : 
     165             : // ReadGrafStart liest die ObjektDaten ein und erzeugt falls noetig einen Anker
     166           0 : bool SwWW8ImplReader::ReadGrafStart(void* pData, short nDataSiz,
     167             :     WW8_DPHEAD* pHd, SfxAllItemSet &rSet)
     168             : {
     169           0 :     if (SVBT16ToShort(pHd->cb) < sizeof(WW8_DPHEAD) + nDataSiz)
     170             :     {
     171             :         OSL_ENSURE( false, "+Grafik-Element: Size ?" );
     172           0 :         m_pStrm->SeekRel(SVBT16ToShort(pHd->cb) - sizeof(WW8_DPHEAD));
     173           0 :         return false;
     174             :     }
     175             : 
     176           0 :     bool bCouldRead = checkRead(*m_pStrm, pData, nDataSiz);
     177             :     OSL_ENSURE(bCouldRead, "Short Graphic header");
     178           0 :     if (!bCouldRead)
     179           0 :         return false;
     180             : 
     181           0 :     SwFormatAnchor aAnchor( FLY_AT_CHAR );
     182           0 :     aAnchor.SetAnchor( m_pPaM->GetPoint() );
     183           0 :     rSet.Put( aAnchor );
     184             : 
     185           0 :     m_nDrawXOfs2 = m_nDrawXOfs;
     186           0 :     m_nDrawYOfs2 = m_nDrawYOfs;
     187             : 
     188           0 :     return true;
     189             : }
     190             : 
     191             : // SetStdAttr() setzt die Attribute, die jedes Objekt hat
     192           0 : static void SetStdAttr( SfxItemSet& rSet, WW8_DP_LINETYPE& rL,
     193             :                         WW8_DP_SHADOW& rSh )
     194             : {
     195           0 :     if( SVBT16ToShort( rL.lnps ) == 5 ){            // invisible
     196           0 :         rSet.Put( XLineStyleItem( drawing::LineStyle_NONE ) );
     197             :     }else{                                          // sichtbar
     198           0 :         Color aCol( WW8TransCol( rL.lnpc ) );           // LinienFarbe
     199           0 :         rSet.Put( XLineColorItem( OUString(), aCol ) );
     200           0 :         rSet.Put( XLineWidthItem( SVBT16ToShort( rL.lnpw ) ) );
     201             :                                                     // line thickness
     202           0 :         if( SVBT16ToShort( rL.lnps ) >= 1
     203           0 :             && SVBT16ToShort(rL.lnps ) <= 4 ){      // line style
     204           0 :             rSet.Put( XLineStyleItem( drawing::LineStyle_DASH ) );
     205           0 :             sal_Int16 nLen = SVBT16ToShort( rL.lnpw );
     206           0 :             XDash aD( css::drawing::DashStyle_RECT, 1, 2 * nLen, 1, 5 * nLen, 5 * nLen );
     207           0 :             switch( SVBT16ToShort( rL.lnps ) ){
     208           0 :             case 1: aD.SetDots( 0 );            // Dash
     209           0 :                     aD.SetDashLen( 6 * nLen );
     210           0 :                     aD.SetDistance( 4 * nLen );
     211           0 :                     break;
     212           0 :             case 2: aD.SetDashes( 0 ); break;   // Dot
     213           0 :             case 3: break;                      // Dash Dot
     214           0 :             case 4: aD.SetDots( 2 ); break;     // Dash Dot Dot
     215             :             }
     216           0 :             rSet.Put( XLineDashItem( OUString(), aD ) );
     217             :         }else{
     218           0 :             rSet.Put( XLineStyleItem( drawing::LineStyle_SOLID ) );  // needed for TextBox
     219             :         }
     220             :     }
     221           0 :     if( SVBT16ToShort( rSh.shdwpi ) ){                  // shadow
     222           0 :         rSet.Put(makeSdrShadowItem(true));
     223           0 :         rSet.Put( makeSdrShadowXDistItem( SVBT16ToShort( rSh.xaOffset ) ) );
     224           0 :         rSet.Put( makeSdrShadowYDistItem( SVBT16ToShort( rSh.yaOffset ) ) );
     225             :     }
     226           0 : }
     227             : 
     228             : // SetFill setzt Fuellattribute wie Vordergrund- und Hintergrund-Farbe
     229             : // und Muster durch Reduktion auf eine Farbe.
     230             : // SetFill() setzt z.Zt kein Muster, da Sdr das nur sehr umstaendlich kann
     231             : // und die Sdr-Schraffur ( XDash ) noch nicht fertig ist.
     232             : // Statt dessen wird eine Mischfarbe gewaehlt, die auf den entsprechenden
     233             : // Farbton zwischen den Farben liegt.
     234             : 
     235           0 : static void SetFill( SfxItemSet& rSet, WW8_DP_FILL& rFill )
     236             : {
     237             :     static const sal_uInt8 nPatA[] =
     238             :     {
     239             :              0,  0,  5, 10, 20, 25, 30, 40, 50, 60, 70, 75, 80,
     240             :             90, 50, 50, 50, 50, 50, 50, 33, 33, 33, 33, 33, 33
     241             :     };
     242           0 :     sal_uInt16 nPat = SVBT16ToShort(rFill.flpp);
     243             : 
     244           0 :     if (nPat == 0) // transparent
     245           0 :         rSet.Put(XFillStyleItem(drawing::FillStyle_NONE));
     246             :     else
     247             :     {
     248           0 :         rSet.Put(XFillStyleItem(drawing::FillStyle_SOLID));  // necessary for textbox
     249           0 :         if (nPat <= 1 || ((sizeof(nPatA)/sizeof(nPatA[0])) <= nPat))
     250             :         {
     251             :             // Solid background or unknown
     252           0 :             rSet.Put(XFillColorItem(OUString(), WW8TransCol(rFill.dlpcBg)));
     253             :         }
     254             :         else
     255             :         {                                      // Brush -> color mix
     256           0 :             Color aB( WW8TransCol( rFill.dlpcBg ) );
     257           0 :             Color aF( WW8TransCol( rFill.dlpcFg ) );
     258           0 :             aB.SetRed( (sal_uInt8)( ( (sal_uLong)aF.GetRed() * nPatA[nPat]
     259           0 :                         + (sal_uLong)aB.GetRed() * ( 100 - nPatA[nPat] ) ) / 100 ) );
     260           0 :             aB.SetGreen( (sal_uInt8)( ( (sal_uLong)aF.GetGreen() * nPatA[nPat]
     261           0 :                         + (sal_uLong)aB.GetGreen() * ( 100 - nPatA[nPat] ) ) / 100 ) );
     262           0 :             aB.SetBlue( (sal_uInt8)( ( (sal_uLong)aF.GetBlue() * nPatA[nPat]
     263           0 :                         + (sal_uLong)aB.GetBlue() * ( 100 - nPatA[nPat] ) ) / 100 ) );
     264           0 :             rSet.Put( XFillColorItem( OUString(), aB ) );
     265             :         }
     266             :     }
     267           0 : }
     268             : 
     269           0 : static void SetLineEndAttr( SfxItemSet& rSet, WW8_DP_LINEEND& rLe,
     270             :                             WW8_DP_LINETYPE& rLt )
     271             : {
     272           0 :     sal_uInt16 aSB = SVBT16ToShort( rLe.aStartBits );
     273           0 :     if( aSB & 0x3 )
     274             :     {
     275           0 :         ::basegfx::B2DPolygon aPolygon;
     276           0 :         aPolygon.append(::basegfx::B2DPoint(0.0, 330.0));
     277           0 :         aPolygon.append(::basegfx::B2DPoint(100.0, 0.0));
     278           0 :         aPolygon.append(::basegfx::B2DPoint(200.0, 330.0));
     279           0 :         aPolygon.setClosed(true);
     280           0 :         rSet.Put( XLineEndItem( OUString(), ::basegfx::B2DPolyPolygon(aPolygon) ) );
     281           0 :         sal_uInt16 nSiz = SVBT16ToShort( rLt.lnpw )
     282           0 :                         * ( ( aSB >> 2 & 0x3 ) + ( aSB >> 4 & 0x3 ) );
     283           0 :         if( nSiz < 220 ) nSiz = 220;
     284           0 :         rSet.Put(XLineEndWidthItem(nSiz));
     285           0 :         rSet.Put(XLineEndCenterItem(false));
     286             :     }
     287             : 
     288           0 :     sal_uInt16 aEB = SVBT16ToShort( rLe.aEndBits );
     289           0 :     if( aEB & 0x3 ){
     290           0 :         ::basegfx::B2DPolygon aPolygon;
     291           0 :         aPolygon.append(::basegfx::B2DPoint(0.0, 330.0));
     292           0 :         aPolygon.append(::basegfx::B2DPoint(100.0, 0.0));
     293           0 :         aPolygon.append(::basegfx::B2DPoint(200.0, 330.0));
     294           0 :         aPolygon.setClosed(true);
     295           0 :         rSet.Put( XLineStartItem( OUString(), ::basegfx::B2DPolyPolygon(aPolygon) ) );
     296           0 :         sal_uInt16 nSiz = SVBT16ToShort( rLt.lnpw )
     297           0 :                         * ( ( aEB >> 2 & 0x3 ) + ( aEB >> 4 & 0x3 ) );
     298           0 :         if( nSiz < 220 ) nSiz = 220;
     299           0 :         rSet.Put(XLineStartWidthItem(nSiz));
     300           0 :         rSet.Put(XLineStartCenterItem(false));
     301             :     }
     302           0 : }
     303             : 
     304             : // Ab hier folgen die Routinen fuer die einzelnen Objekte
     305           0 : SdrObject* SwWW8ImplReader::ReadLine(WW8_DPHEAD* pHd, SfxAllItemSet &rSet)
     306             : {
     307             :     WW8_DP_LINE aLine;
     308             : 
     309           0 :     if( !ReadGrafStart( static_cast<void*>(&aLine), sizeof( aLine ), pHd, rSet ) )
     310           0 :         return 0;
     311             : 
     312           0 :     Point aP[2];
     313             :     {
     314           0 :         Point& rP0 = aP[0];
     315           0 :         Point& rP1 = aP[1];
     316             : 
     317           0 :         rP0.X() = (sal_Int16)SVBT16ToShort( pHd->xa ) + m_nDrawXOfs2;
     318           0 :         rP0.Y() = (sal_Int16)SVBT16ToShort( pHd->ya ) + m_nDrawYOfs2;
     319           0 :         rP1 = rP0;
     320           0 :         rP0.X() += (sal_Int16)SVBT16ToShort( aLine.xaStart );
     321           0 :         rP0.Y() += (sal_Int16)SVBT16ToShort( aLine.yaStart );
     322           0 :         rP1.X() += (sal_Int16)SVBT16ToShort( aLine.xaEnd );
     323           0 :         rP1.Y() += (sal_Int16)SVBT16ToShort( aLine.yaEnd );
     324             :     }
     325             : 
     326           0 :     ::basegfx::B2DPolygon aPolygon;
     327           0 :     aPolygon.append(::basegfx::B2DPoint(aP[0].X(), aP[0].Y()));
     328           0 :     aPolygon.append(::basegfx::B2DPoint(aP[1].X(), aP[1].Y()));
     329           0 :     SdrObject* pObj = new SdrPathObj(OBJ_LINE, ::basegfx::B2DPolyPolygon(aPolygon));
     330             : 
     331           0 :     SetStdAttr( rSet, aLine.aLnt, aLine.aShd );
     332           0 :     SetLineEndAttr( rSet, aLine.aEpp, aLine.aLnt );
     333             : 
     334           0 :     return pObj;
     335             : }
     336             : 
     337           0 : SdrObject* SwWW8ImplReader::ReadRect(WW8_DPHEAD* pHd, SfxAllItemSet &rSet)
     338             : {
     339             :     WW8_DP_RECT aRect;
     340             : 
     341           0 :     if( !ReadGrafStart( static_cast<void*>(&aRect), sizeof( aRect ), pHd, rSet ) )
     342           0 :         return 0;
     343             : 
     344           0 :     Point aP0( (sal_Int16)SVBT16ToShort( pHd->xa ) + m_nDrawXOfs2,
     345           0 :                (sal_Int16)SVBT16ToShort( pHd->ya ) + m_nDrawYOfs2 );
     346           0 :     Point aP1( aP0 );
     347           0 :     aP1.X() += (sal_Int16)SVBT16ToShort( pHd->dxa );
     348           0 :     aP1.Y() += (sal_Int16)SVBT16ToShort( pHd->dya );
     349             : 
     350           0 :     SdrObject* pObj = new SdrRectObj( Rectangle( aP0, aP1 ) );
     351             : 
     352           0 :     SetStdAttr( rSet, aRect.aLnt, aRect.aShd );
     353           0 :     SetFill( rSet, aRect.aFill );
     354             : 
     355           0 :     return pObj;
     356             : }
     357             : 
     358           0 : SdrObject* SwWW8ImplReader::ReadElipse(WW8_DPHEAD* pHd, SfxAllItemSet &rSet)
     359             : {
     360             :     WW8_DP_ELIPSE aElipse;
     361             : 
     362           0 :     if( !ReadGrafStart( static_cast<void*>(&aElipse), sizeof( aElipse ), pHd, rSet ) )
     363           0 :         return 0;
     364             : 
     365           0 :     Point aP0( (sal_Int16)SVBT16ToShort( pHd->xa ) + m_nDrawXOfs2,
     366           0 :                (sal_Int16)SVBT16ToShort( pHd->ya ) + m_nDrawYOfs2 );
     367           0 :     Point aP1( aP0 );
     368           0 :     aP1.X() += (sal_Int16)SVBT16ToShort( pHd->dxa );
     369           0 :     aP1.Y() += (sal_Int16)SVBT16ToShort( pHd->dya );
     370             : 
     371           0 :     SdrObject* pObj = new SdrCircObj( OBJ_CIRC, Rectangle( aP0, aP1 ) );
     372             : 
     373           0 :     SetStdAttr( rSet, aElipse.aLnt, aElipse.aShd );
     374           0 :     SetFill( rSet, aElipse.aFill );
     375             : 
     376           0 :     return pObj;
     377             : }
     378             : 
     379           0 : SdrObject* SwWW8ImplReader::ReadArc(WW8_DPHEAD* pHd, SfxAllItemSet &rSet)
     380             : {
     381             :     WW8_DP_ARC aArc;
     382             : 
     383           0 :     if( !ReadGrafStart( static_cast<void*>(&aArc), sizeof( aArc ), pHd, rSet ) )
     384           0 :         return 0;
     385             : 
     386           0 :     Point aP0( (sal_Int16)SVBT16ToShort( pHd->xa ) + m_nDrawXOfs2,
     387           0 :                (sal_Int16)SVBT16ToShort( pHd->ya ) + m_nDrawYOfs2 );
     388           0 :     Point aP1( aP0 );
     389           0 :     aP1.X() += (sal_Int16)SVBT16ToShort( pHd->dxa ) * 2;
     390           0 :     aP1.Y() += (sal_Int16)SVBT16ToShort( pHd->dya ) * 2;
     391             : 
     392           0 :     short nA[] = { 2, 3, 1, 0 };
     393           0 :     short nW = nA[ ( ( aArc.fLeft & 1 ) << 1 ) + ( aArc.fUp & 1 ) ];
     394           0 :     if( !aArc.fLeft ){
     395           0 :         aP0.Y() -= (sal_Int16)SVBT16ToShort( pHd->dya );
     396           0 :         aP1.Y() -= (sal_Int16)SVBT16ToShort( pHd->dya );
     397             :     }
     398           0 :     if( aArc.fUp ){
     399           0 :         aP0.X() -= (sal_Int16)SVBT16ToShort( pHd->dxa );
     400           0 :         aP1.X() -= (sal_Int16)SVBT16ToShort( pHd->dxa );
     401             :     }
     402             : 
     403             :     SdrObject* pObj = new SdrCircObj( OBJ_SECT, Rectangle( aP0, aP1 ),
     404           0 :                                nW * 9000, ( ( nW + 1 ) & 3 ) * 9000 );
     405             : 
     406           0 :     SetStdAttr( rSet, aArc.aLnt, aArc.aShd );
     407           0 :     SetFill( rSet, aArc.aFill );
     408             : 
     409           0 :     return pObj;
     410             : }
     411             : 
     412           0 : SdrObject* SwWW8ImplReader::ReadPolyLine(WW8_DPHEAD* pHd, SfxAllItemSet &rSet)
     413             : {
     414             :     WW8_DP_POLYLINE aPoly;
     415             : 
     416           0 :     if( !ReadGrafStart( static_cast<void*>(&aPoly), sizeof( aPoly ), pHd, rSet ) )
     417           0 :         return 0;
     418             : 
     419           0 :     sal_uInt16 nCount = SVBT16ToShort( aPoly.aBits1 ) >> 1 & 0x7fff;
     420           0 :     boost::scoped_array<SVBT16> xP(new SVBT16[nCount * 2]);
     421             : 
     422           0 :     bool bCouldRead = checkRead(*m_pStrm, xP.get(), nCount * 4);      // Punkte einlesen
     423             :     OSL_ENSURE(bCouldRead, "Short PolyLine header");
     424           0 :     if (!bCouldRead)
     425           0 :         return 0;
     426             : 
     427           0 :     Polygon aP( nCount );
     428           0 :     Point aPt;
     429           0 :     for (sal_uInt16 i=0; i<nCount; ++i)
     430             :     {
     431           0 :         aPt.X() = SVBT16ToShort( xP[i << 1] ) + m_nDrawXOfs2
     432           0 :                   + (sal_Int16)SVBT16ToShort( pHd->xa );
     433           0 :         aPt.Y() = SVBT16ToShort( xP[( i << 1 ) + 1] ) + m_nDrawYOfs2
     434           0 :                   + (sal_Int16)SVBT16ToShort( pHd->ya );
     435           0 :         aP[i] = aPt;
     436             :     }
     437           0 :     xP.reset();
     438             : 
     439           0 :     SdrObject* pObj = new SdrPathObj(( SVBT16ToShort( aPoly.aBits1 ) & 0x1 ) ? OBJ_POLY : OBJ_PLIN, ::basegfx::B2DPolyPolygon(aP.getB2DPolygon()));
     440           0 :     SetStdAttr( rSet, aPoly.aLnt, aPoly.aShd );
     441           0 :     SetFill( rSet, aPoly.aFill );
     442             : 
     443           0 :     return pObj;
     444             : }
     445             : 
     446         267 : ESelection SwWW8ImplReader::GetESelection( long nCpStart, long nCpEnd )
     447             : {
     448         267 :     sal_Int32 nPCnt = m_pDrawEditEngine->GetParagraphCount();
     449         267 :     sal_Int32 nSP = 0;
     450         267 :     sal_Int32 nEP = 0;
     451         542 :     while(      (nSP < nPCnt)
     452         275 :             &&  (nCpStart >= m_pDrawEditEngine->GetTextLen( nSP ) + 1) )
     453             :     {
     454           8 :         nCpStart -= m_pDrawEditEngine->GetTextLen( nSP ) + 1;
     455           8 :         nSP++;
     456             :     }
     457             :         // Beim Ende erst 1 Zeichen spaeter auf naechste Zeile umschalten,
     458             :         // da sonst Zeilenattribute immer eine Zeile zu weit reichen.
     459         542 :     while(      (nEP < nPCnt)
     460         275 :             &&  (nCpEnd > m_pDrawEditEngine->GetTextLen( nEP ) + 1) )
     461             :     {
     462           8 :         nCpEnd -= m_pDrawEditEngine->GetTextLen( nEP ) + 1;
     463           8 :         nEP++;
     464             :     }
     465         267 :     return ESelection( nSP, nCpStart, nEP, nCpEnd );
     466             : }
     467             : 
     468             : // InsertTxbxStyAttrs() setzt die Style-Attribute in den uebergebenen ItemSet.
     469             : // Es werden die SW-Styles genommen, die Import-WW-Styles sind zu diesem
     470             : // Zeitpunkt schon destruiert.
     471             : // Die SW-Styles werden per Tiefensuche, d.h. mit Parent-Styles nach den
     472             : // in aSrcTab angegebenen Attributen untersucht. Diese werden per Clone
     473             : // dupliziert, bei den Duplikaten werden die Which-IDs
     474             : // gemaess der Tabelle aDstTab umgesetzt, damit die EditEngine sie nicht
     475             : // ignoriert.
     476             : // Es werden hierbei sowohl Para- wie auch Zeichen-Attribute in den
     477             : // ItemSet gestopft.
     478         263 : void SwWW8ImplReader::InsertTxbxStyAttrs( SfxItemSet& rS, sal_uInt16 nColl )
     479             : {
     480         263 :     SwWW8StyInf * pStyInf = GetStyle(nColl);
     481         263 :     if( pStyInf != NULL && pStyInf->pFormat && pStyInf->bColl )
     482             :     {
     483             :         const SfxPoolItem* pItem;
     484       39713 :         for( sal_uInt16 i = POOLATTR_BEGIN; i < POOLATTR_END; i++ )
     485             :         {
     486             :             // If we are set in the source and not set in the destination
     487             :             // then add it in.
     488       39450 :             if ( SfxItemState::SET == pStyInf->pFormat->GetItemState(
     489       39450 :                 i, true, &pItem ) )
     490             :             {
     491        3425 :                 SfxItemPool *pEditPool = rS.GetPool();
     492        3425 :                 sal_uInt16 nWhich = i;
     493        3425 :                 sal_uInt16 nSlotId = m_rDoc.GetAttrPool().GetSlotId(nWhich);
     494        3425 :                 if (
     495        6850 :                     nSlotId && nWhich != nSlotId &&
     496        6850 :                     0 != (nWhich = pEditPool->GetWhich(nSlotId)) &&
     497        6266 :                     nWhich != nSlotId &&
     498        2841 :                     ( SfxItemState::SET != rS.GetItemState(nWhich, false) )
     499             :                    )
     500             :                 {
     501        2159 :                     SfxPoolItem* pCopy = pItem->Clone();
     502        2159 :                     pCopy->SetWhich( nWhich );
     503        2159 :                     rS.Put( *pCopy );
     504        2159 :                     delete pCopy;
     505             :                 }
     506             :             }
     507             :         }
     508             :     }
     509             : 
     510         263 : }
     511             : 
     512         106 : static void lcl_StripFields(OUString &rString, long &rNewStartCp)
     513             : {
     514         106 :     sal_Int32 nStartPos = 0;
     515             :     for (;;)
     516             :     {
     517         114 :         nStartPos = rString.indexOf(0x13, nStartPos);
     518         114 :         if (nStartPos<0)
     519         212 :             return;
     520             : 
     521           8 :         const sal_Unicode cStops[] = {0x14, 0x15, 0};
     522           8 :         const sal_Int32 nStopPos = comphelper::string::indexOfAny(rString, cStops, nStartPos);
     523           8 :         if (nStopPos<0)
     524             :         {
     525           0 :             rNewStartCp += rString.getLength()-nStartPos;
     526           0 :             rString = rString.copy(0, nStartPos);
     527           0 :             return;
     528             :         }
     529             : 
     530           8 :         const bool was0x14 = rString[nStopPos]==0x14;
     531           8 :         rString = rString.replaceAt(nStartPos, nStopPos+1-nStartPos, "");
     532           8 :         rNewStartCp += nStopPos-nStartPos;
     533             : 
     534           8 :         if (was0x14)
     535             :         {
     536           8 :             ++rNewStartCp;
     537           8 :             nStartPos = rString.indexOf(0x15, nStartPos);
     538           8 :             if (nStartPos<0)
     539           0 :                 return;
     540           8 :             rString = rString.replaceAt(nStartPos, 1, "");
     541             :         }
     542           8 :     }
     543             : }
     544             : 
     545          12 : class Chunk
     546             : {
     547             : private:
     548             :     OUString msURL;
     549             :     long mnStartPos; // 0x13
     550             :     long mnEndPos;   // 0x15
     551             : public:
     552           4 :     explicit Chunk(long nStart, const OUString &rURL)
     553           4 :         : msURL(rURL), mnStartPos(nStart), mnEndPos(0)  {}
     554             : 
     555           4 :     void SetEndPos(long nEnd) { mnEndPos = nEnd; }
     556           4 :     long GetStartPos() const {return mnStartPos;}
     557           4 :     long GetEndPos() const {return mnEndPos;}
     558           4 :     const OUString &GetURL() const {return msURL;}
     559           0 :     void Adjust(sal_Int32 nAdjust)
     560             :     {
     561           0 :         mnStartPos-=nAdjust;
     562           0 :         mnEndPos-=nAdjust;
     563           0 :     }
     564             : };
     565             : 
     566             : // InsertAttrsAsDrawingAttrs() setzt zwischen StartCp und EndCp die Attribute.
     567             : // Dabei werden Style-Attribute als harte Attribute, Absatz- und Zeichen-
     568             : // attribute gesetzt.
     569          96 : void SwWW8ImplReader::InsertAttrsAsDrawingAttrs(long nStartCp, long nEndCp,
     570             :     ManTypes eType, bool bONLYnPicLocFc)
     571             : {
     572             :     /*
     573             :      Save and create new plcxman for this drawing object, of the type that
     574             :      will include the para end mark inside a paragraph property range, as
     575             :      drawing boxes have real paragraph marks as part of their text, while
     576             :      normal writer has separate nodes for each paragraph and so has no actual
     577             :      paragraph mark as part of the paragraph text.
     578             :     */
     579          96 :     WW8ReaderSave aSave(this);
     580          96 :     m_pPlcxMan = new WW8PLCFMan(m_pSBase, eType, nStartCp, true);
     581             : 
     582          96 :     WW8_CP nStart = m_pPlcxMan->Where();
     583          96 :     WW8_CP nNext, nStartReplace=0;
     584             : 
     585          96 :     bool bDoingSymbol = false;
     586          96 :     sal_Unicode cReplaceSymbol = m_cSymbol;
     587             : 
     588          96 :     SfxItemSet *pS = new SfxItemSet(m_pDrawEditEngine->GetEmptyItemSet());
     589             :     WW8PLCFManResult aRes;
     590             : 
     591         192 :     std::deque<Chunk> aChunks;
     592             : 
     593             :     // Here store stack location
     594          96 :     size_t nCurrentCount = m_pCtrlStck->size();
     595        2385 :     while (nStart < nEndCp)
     596             :     {
     597             :         // nStart is the beginning of the attributes for this range, and
     598             :         // may be before the text itself. So watch out for that
     599        2197 :         WW8_CP nTextStart = nStart;
     600        2197 :         if (nTextStart < nStartCp)
     601          85 :             nTextStart = nStartCp;
     602             : 
     603             :         // get position of next SPRM
     604        2197 :         bool bStartAttr = m_pPlcxMan->Get(&aRes);
     605        2197 :         m_nAktColl = m_pPlcxMan->GetColl();
     606        2197 :         if (aRes.nSprmId)
     607             :         {
     608        1913 :             if( bONLYnPicLocFc )
     609             :             {
     610           8 :                 if ( (68 == aRes.nSprmId) || (0x6A03 == aRes.nSprmId) )
     611             :                 {
     612             :                     Read_PicLoc(aRes.nSprmId, aRes.pMemPos +
     613           4 :                         m_pSprmParser->DistanceToData(aRes.nSprmId), 4);
     614             :                      // Ok, that's what we were looking for.  Now let's get
     615             :                      // out of here!
     616           4 :                     break;
     617             :                 }
     618             :             }
     619        3810 :             else if ( aRes.nSprmId && (
     620        3810 :                 (eFTN >  aRes.nSprmId) || (0x0800 <= aRes.nSprmId) ) )
     621             :             {
     622             :                 // Here place them onto our usual stack and we will pop them
     623             :                 // off and convert them later
     624        1886 :                 if (bStartAttr)
     625             :                 {
     626        1502 :                     ImportSprm(aRes.pMemPos, aRes.nSprmId);
     627        1502 :                     if (!bDoingSymbol && m_bSymbol)
     628             :                     {
     629           0 :                         bDoingSymbol = true;
     630           0 :                         nStartReplace = nTextStart;
     631           0 :                         cReplaceSymbol = m_cSymbol;
     632             :                     }
     633             :                 }
     634             :                 else
     635             :                 {
     636         384 :                     EndSprm( aRes.nSprmId );
     637         384 :                     if (!m_bSymbol && bDoingSymbol)
     638             :                     {
     639           0 :                         bDoingSymbol = false;
     640           0 :                         OUStringBuffer sTemp;
     641             :                         comphelper::string::padToLength(sTemp,
     642           0 :                             nTextStart - nStartReplace, cReplaceSymbol);
     643             :                         m_pDrawEditEngine->QuickInsertText(sTemp.makeStringAndClear(),
     644             :                             GetESelection(nStartReplace - nStartCp,
     645           0 :                             nTextStart - nStartCp ) );
     646             :                     }
     647        1886 :                 }
     648             :             }
     649          19 :             else if (aRes.nSprmId == eFLD)
     650             :             {
     651          19 :                 if (bStartAttr)
     652             :                 {
     653          11 :                     size_t nCount = m_pCtrlStck->size();
     654          11 :                     if (m_aFieldStack.empty() && Read_Field(&aRes))
     655             :                     {
     656           4 :                         OUString sURL;
     657           4 :                         for (size_t nI = m_pCtrlStck->size(); nI > nCount; --nI)
     658             :                         {
     659           0 :                             const SfxPoolItem *pItem = ((*m_pCtrlStck)[nI-1]).pAttr;
     660           0 :                             sal_uInt16 nWhich = pItem->Which();
     661           0 :                             if (nWhich == RES_TXTATR_INETFMT)
     662             :                             {
     663             :                                 const SwFormatINetFormat *pURL =
     664           0 :                                     static_cast<const SwFormatINetFormat *>(pItem);
     665           0 :                                 sURL = pURL->GetValue();
     666             :                             }
     667           0 :                             m_pCtrlStck->DeleteAndDestroy(nI-1);
     668             :                         }
     669           4 :                         aChunks.push_back(Chunk(nStart, sURL));
     670             :                     }
     671             :                 }
     672             :                 else
     673             :                 {
     674           8 :                     if (!m_aFieldStack.empty() && End_Field())
     675           4 :                         aChunks.back().SetEndPos(nStart+1);
     676             :                 }
     677             :             }
     678             :         }
     679             : 
     680        2193 :         m_pPlcxMan->advance();
     681        2193 :         nNext = m_pPlcxMan->Where();
     682             : 
     683        2193 :         const WW8_CP nEnd = ( nNext < nEndCp ) ? nNext : nEndCp;
     684        2193 :         if (!bONLYnPicLocFc && nNext != nStart && nEnd >= nStartCp)
     685             :         {
     686         263 :             SfxItemPool *pEditPool = pS->GetPool();
     687             : 
     688             :             // Here read current properties and convert them into pS
     689             :             // and put those attrs into the draw box if they can be converted
     690             :             // to draw attributes
     691         263 :             if (m_pCtrlStck->size() - nCurrentCount)
     692             :             {
     693        1241 :                 for (size_t i = nCurrentCount; i < m_pCtrlStck->size(); ++i)
     694             :                 {
     695        1075 :                     const SfxPoolItem *pItem = ((*m_pCtrlStck)[i]).pAttr;
     696        1075 :                     sal_uInt16 nWhich = pItem->Which();
     697        1075 :                     if( nWhich < RES_FLTRATTR_BEGIN ||
     698             :                         nWhich >= RES_FLTRATTR_END )
     699             :                     {
     700        1075 :                         sal_uInt16 nSlotId = m_rDoc.GetAttrPool().GetSlotId(nWhich);
     701        1075 :                         if (
     702        2148 :                             nSlotId && nWhich != nSlotId &&
     703        3221 :                             0 != (nWhich = pEditPool->GetWhich(nSlotId)) &&
     704             :                             nWhich != nSlotId
     705             :                         )
     706             :                         {
     707        1073 :                             SfxPoolItem* pCopy = pItem->Clone();
     708        1073 :                             pCopy->SetWhich( nWhich );
     709        1073 :                             pS->Put( *pCopy );
     710        1073 :                             delete pCopy;
     711             :                         }
     712             :                     }
     713             :                 }
     714             :             }
     715             :             // Fill in the remainder from the style
     716         263 :             InsertTxbxStyAttrs(*pS, m_nAktColl);
     717             : 
     718         263 :             if( pS->Count() )
     719             :             {
     720             :                 m_pDrawEditEngine->QuickSetAttribs( *pS,
     721         263 :                     GetESelection( nTextStart - nStartCp, nEnd - nStartCp ) );
     722         263 :                 delete pS;
     723         263 :                 pS = new SfxItemSet(m_pDrawEditEngine->GetEmptyItemSet());
     724             :             }
     725             :         }
     726        2193 :         nStart = nNext;
     727             :     }
     728          96 :     delete pS;
     729             : 
     730             :     // pop off as far as recorded location just in case there were some left
     731             :     // unclosed
     732         830 :     for (size_t nI = m_pCtrlStck->size(); nI > nCurrentCount; --nI)
     733         734 :         m_pCtrlStck->DeleteAndDestroy(nI-1);
     734             : 
     735             :     typedef std::deque<Chunk>::iterator myIter;
     736          96 :     myIter aEnd = aChunks.end();
     737         100 :     for (myIter aIter = aChunks.begin(); aIter != aEnd; ++aIter)
     738             :     {
     739           4 :         ESelection aSel(GetESelection(aIter->GetStartPos()-nStartCp,
     740           8 :             aIter->GetEndPos()-nStartCp));
     741           4 :         OUString aString(m_pDrawEditEngine->GetText(aSel));
     742           4 :         const sal_Int32 nOrigLen = aString.getLength();
     743           4 :         long nDummy(0);
     744           4 :         lcl_StripFields(aString, nDummy);
     745             : 
     746             :         sal_Int32 nChanged;
     747           4 :         if (!aIter->GetURL().isEmpty())
     748             :         {
     749           0 :             SvxURLField aURL(aIter->GetURL(), aString,
     750           0 :                 SVXURLFORMAT_APPDEFAULT);
     751           0 :             m_pDrawEditEngine->QuickInsertField(SvxFieldItem(aURL, EE_FEATURE_FIELD), aSel);
     752           0 :             nChanged = nOrigLen - 1;
     753             :         }
     754             :         else
     755             :         {
     756           4 :             m_pDrawEditEngine->QuickInsertText(aString, aSel);
     757           4 :             nChanged = nOrigLen - aString.getLength();
     758             :         }
     759           4 :         for (myIter aIter2 = aIter+1; aIter2 != aEnd; ++aIter2)
     760           0 :             aIter2->Adjust(nChanged);
     761           4 :         }
     762             : 
     763             :     /*
     764             :      Don't worry about the new pPlcxMan, the restorer removes it when
     765             :      replacing the current one with the old one.
     766             :     */
     767         192 :     aSave.Restore(this);
     768          96 : }
     769             : 
     770          92 : bool SwWW8ImplReader::GetTxbxTextSttEndCp(WW8_CP& rStartCp, WW8_CP& rEndCp,
     771             :     sal_uInt16 nTxBxS, sal_uInt16 nSequence)
     772             : {
     773             :     // grab the TextBox-PLCF quickly
     774          92 :     WW8PLCFspecial* pT = m_pPlcxMan ? m_pPlcxMan->GetTxbx() : 0;
     775          92 :     if( !pT )
     776             :     {
     777             :         OSL_ENSURE( false, "+Wo ist der Grafik-Text (1) ?" );
     778           0 :         return false;
     779             :     }
     780             : 
     781             :     // ggfs. zuerst die richtige TextBox-Story finden
     782          92 :     bool bCheckTextBoxStory = ( nTxBxS && pT->GetIMax() >= nTxBxS );
     783          92 :     if(  bCheckTextBoxStory )
     784          92 :         pT->SetIdx( nTxBxS-1 );
     785             : 
     786             :     // then determine start and end
     787             :     void* pT0;
     788          92 :     if( !pT->Get( rStartCp, pT0 ) )
     789             :     {
     790             :         OSL_ENSURE( false, "+Wo ist der Grafik-Text (2) ?" );
     791           0 :         return false;
     792             :     }
     793             : 
     794          92 :     if( bCheckTextBoxStory )
     795             :     {
     796          92 :         bool bReusable = (0 != SVBT16ToShort( static_cast<WW8_TXBXS*>(pT0)->fReusable ));
     797         184 :         while( bReusable )
     798             :         {
     799           0 :             pT->advance();
     800           0 :             if( !pT->Get( rStartCp, pT0 ) )
     801             :             {
     802             :                 OSL_ENSURE( false, "+Wo ist der Grafik-Text (2-a) ?" );
     803           0 :                 return false;
     804             :             }
     805           0 :             bReusable = (0 != SVBT16ToShort( static_cast<WW8_TXBXS*>(pT0)->fReusable ));
     806             :         }
     807             :     }
     808          92 :     pT->advance();
     809          92 :     if( !pT->Get( rEndCp, pT0 ) )
     810             :     {
     811             :         OSL_ENSURE( false, "+Wo ist der Grafik-Text (3) ?" );
     812           0 :         return false;
     813             :     }
     814             : 
     815             :     // jetzt ggfs. die passende Page in der Break-Table finden
     816          92 :     if( bCheckTextBoxStory )
     817             :     {
     818             :         // Sonderfall: gesamte(!) Kette soll ermittelt werden,
     819             :         //             dann sind wir hier schon fertig!
     820          92 :         if( USHRT_MAX > nSequence )
     821             :         {
     822          82 :             long nMinStartCp = rStartCp;
     823          82 :             long nMaxEndCp   = rEndCp;
     824             :             // rasch den TextBox-Break-Deskriptor-PLCF greifen
     825          82 :             pT = m_pPlcxMan->GetTxbxBkd();
     826          82 :             if (!pT) // It can occur on occasion, Caolan
     827           0 :                 return false;
     828             : 
     829             :             // den ersten Eintrag fuer diese TextBox-Story finden
     830          82 :             if( !pT->SeekPos( rStartCp ) )
     831             :             {
     832             :                 OSL_ENSURE( false, "+Wo ist der Grafik-Text (4) ?" );
     833           0 :                 return false;
     834             :             }
     835             :             // ggfs. entsprechende Anzahl Eintraege weitergehen
     836          82 :             for (sal_uInt16 iSequence = 0; iSequence < nSequence; ++iSequence)
     837           0 :                 pT->advance();
     838             :             // dann die tatsaechlichen Start und Ende ermitteln
     839         164 :             if(    (!pT->Get( rStartCp, pT0 ))
     840          82 :                 || ( nMinStartCp > rStartCp  ) )
     841             :             {
     842             :                 OSL_ENSURE( false, "+Wo ist der Grafik-Text (5) ?" );
     843           0 :                 return false;
     844             :             }
     845          82 :             if( rStartCp >= nMaxEndCp )
     846           0 :                 rEndCp = rStartCp;  // kein Error: leerer String!
     847             :             else
     848             :             {
     849          82 :                 pT->advance();
     850          82 :                 if ( (!pT->Get(rEndCp, pT0)) || (nMaxEndCp < rEndCp-1) )
     851             :                 {
     852             :                     OSL_ENSURE( false, "+Wo ist der Grafik-Text (6) ?" );
     853           0 :                     return false;
     854             :                 }
     855          82 :                 rEndCp -= 1;
     856             :             }
     857             :         }
     858             :         else
     859          10 :             rEndCp -= 1;
     860             :     }
     861             :     else
     862           0 :         rEndCp -= 1;
     863          92 :     return true;
     864             : }
     865             : 
     866             : // TxbxText() holt aus WW-File den Text und gibt diesen und den Anfangs- und
     867             : // den um -2 (bzw. -1 bei Ver8) korrigierten End-Cp zurueck
     868         104 : bool SwWW8ImplReader::GetRangeAsDrawingString(OUString& rString, long nStartCp, long nEndCp, ManTypes eType)
     869             : {
     870         104 :     WW8_CP nOffset = m_pWwFib->GetBaseCp(eType);
     871             : 
     872             :     OSL_ENSURE(nStartCp <= nEndCp, "+Wo ist der Grafik-Text (7) ?");
     873         104 :     if (nStartCp == nEndCp)
     874           2 :         rString.clear();      // leerer String: durchaus denkbar!
     875         102 :     else if (nStartCp < nEndCp)
     876             :     {
     877             :         // den Text einlesen: kann sich ueber mehrere Pieces erstrecken!!!
     878             :         const sal_Int32 nLen = m_pSBase->WW8ReadString(*m_pStrm, rString,
     879         102 :             nStartCp + nOffset, nEndCp - nStartCp, GetCurrentCharSet());
     880             :         OSL_ENSURE(nLen, "+Wo ist der Grafik-Text (8) ?");
     881         102 :         if (nLen>0)
     882             :         {
     883         102 :             if( rString[nLen-1]==0x0d )
     884         102 :                 rString = rString.copy(0, nLen-1);
     885             : 
     886         102 :             rString = rString.replace( 0xb, 0xa );
     887         102 :             return true;
     888             :         }
     889             :     }
     890           2 :     return false;
     891             : }
     892             : 
     893          24 : OutlinerParaObject* SwWW8ImplReader::ImportAsOutliner(OUString &rString, WW8_CP nStartCp, WW8_CP nEndCp, ManTypes eType)
     894             : {
     895          24 :     OutlinerParaObject* pRet = 0;
     896             : 
     897          24 :     if (GetRangeAsDrawingString( rString, nStartCp, nEndCp, eType ))
     898             :     {
     899          24 :         if (!m_pDrawEditEngine)
     900          10 :             m_pDrawEditEngine = new EditEngine(0);
     901             : 
     902          24 :         m_pDrawEditEngine->SetText(rString);
     903          24 :         InsertAttrsAsDrawingAttrs(nStartCp, nEndCp, eType);
     904             : 
     905             :         // Annotations typically begin with a (useless) 0x5
     906          24 :         if ((eType == MAN_AND) && m_pDrawEditEngine->GetTextLen())
     907             :         {
     908          24 :             ESelection aFirstChar(0, 0, 0, 1);
     909          24 :             if (comphelper::string::equals(m_pDrawEditEngine->GetText( aFirstChar ), 0x5))
     910          18 :                 m_pDrawEditEngine->QuickDelete(aFirstChar);
     911             :         }
     912             : 
     913          24 :         EditTextObject* pTemporaryText = m_pDrawEditEngine->CreateTextObject();
     914          24 :         pRet = new OutlinerParaObject(*pTemporaryText);
     915          24 :         pRet->SetOutlinerMode( OUTLINERMODE_TEXTOBJECT );
     916          24 :         delete pTemporaryText;
     917             : 
     918          24 :         m_pDrawEditEngine->SetText( OUString() );
     919          24 :         m_pDrawEditEngine->SetParaAttribs(0, m_pDrawEditEngine->GetEmptyItemSet());
     920             : 
     921             :         // Strip out fields, leaving the result
     922          24 :         long nDummy(0);
     923          24 :         lcl_StripFields(rString, nDummy);
     924             :         // Strip out word's special characters for the simple string
     925          24 :         rString = rString.replaceAll(OUString(0x1), "");
     926          24 :         rString = rString.replaceAll(OUString(0x5), "");
     927          24 :         rString = rString.replaceAll(OUString(0x8), "");
     928          24 :         rString = rString.replaceAll("\007\007", "\007\012");
     929          24 :         rString = rString.replace(0x7, ' ');
     930             :     }
     931             : 
     932          24 :     return pRet;
     933             : }
     934             : 
     935             : // InsertTxbxText() fuegt fuer TextBoxen und CaptionBoxen den Text
     936             : // und die Attribute ein
     937          80 : SwFrameFormat* SwWW8ImplReader::InsertTxbxText(SdrTextObj* pTextObj,
     938             :     Size* pObjSiz, sal_uInt16 nTxBxS, sal_uInt16 nSequence, long nPosCp,
     939             :     SwFrameFormat* pOldFlyFormat, bool bMakeSdrGrafObj, bool& rbEraseTextObj,
     940             :     bool* pbTestTxbxContainsText, long* pnStartCp, long* pnEndCp,
     941             :     bool* pbContainsGraphics, SvxMSDffImportRec* pRecord)
     942             : {
     943          80 :     SwFrameFormat* pFlyFormat = 0;
     944          80 :     sal_uLong nOld = m_pStrm->Tell();
     945             : 
     946          80 :     ManTypes eType = m_pPlcxMan->GetManType() == MAN_HDFT ? MAN_TXBX_HDFT : MAN_TXBX;
     947             : 
     948          80 :     rbEraseTextObj = false;
     949             : 
     950          80 :     OUString aString;
     951             :     WW8_CP nStartCp, nEndCp;
     952          80 :     bool bContainsGraphics = false;
     953             :     bool bTextWasRead = GetTxbxTextSttEndCp( nStartCp, nEndCp, nTxBxS,
     954          80 :         nSequence ) && GetRangeAsDrawingString( aString, nStartCp, nEndCp, eType );
     955             : 
     956          80 :     if (!m_pDrawEditEngine)
     957          11 :         m_pDrawEditEngine = new EditEngine(0);
     958          80 :     if( pObjSiz )
     959          70 :         m_pDrawEditEngine->SetPaperSize( *pObjSiz );
     960             : 
     961         160 :     const OUString aOrigString(aString);
     962          80 :     if( bTextWasRead )
     963             :     {
     964          78 :         long nNewStartCp = nStartCp;
     965          78 :         lcl_StripFields(aString, nNewStartCp);
     966             : 
     967          78 :         if (aString.getLength()!=1)
     968             :         {
     969          50 :             bContainsGraphics = aString.indexOf(0x1)<0 || aString.indexOf(0x8)<0;
     970             :         }
     971             :         else        // May be a single graphic or object
     972             :         {
     973          28 :             bool bDone = true;
     974          28 :             switch( aString[0] )
     975             :             {
     976             :                 case 0x1:
     977           4 :                     if (!pbTestTxbxContainsText)
     978             :                     {
     979           4 :                         WW8ReaderSave aSave(this, nNewStartCp -1);
     980           4 :                         bool bOldEmbeddObj = m_bEmbeddObj;
     981             :                         // bEmbedd Ordinarily would have been set by field
     982             :                         // parse, but this is impossible here so...
     983           4 :                         m_bEmbeddObj = true;
     984             : 
     985             :                         // 1st look for OLE- or Graph-Indicator Sprms
     986           4 :                         WW8PLCFx_Cp_FKP* pChp = m_pPlcxMan->GetChpPLCF();
     987           4 :                         WW8PLCFxDesc aDesc;
     988           4 :                         pChp->GetSprms( &aDesc );
     989             :                         WW8SprmIter aSprmIter(aDesc.pMemPos, aDesc.nSprmsLen,
     990           4 :                             *m_pSprmParser);
     991             : 
     992          12 :                         for( int nLoop = 0; nLoop < 2; ++nLoop )
     993             :                         {
     994             :                             const sal_uInt8* pParams;
     995          72 :                             while( aSprmIter.GetSprms()
     996          32 :                                 && (0 != (pParams = aSprmIter.GetAktParams())) )
     997             :                             {
     998          24 :                                 sal_uInt16 nAktId = aSprmIter.GetAktId();
     999          24 :                                 switch( nAktId )
    1000             :                                 {
    1001             :                                     case     75:
    1002             :                                     case    118:
    1003             :                                     case 0x080A:
    1004             :                                     case 0x0856:
    1005           0 :                                             Read_Obj(nAktId, pParams, 1);
    1006           0 :                                         break;
    1007             :                                     case     68:  // Read_Pic()
    1008             :                                     case 0x6A03:
    1009             :                                     case 0x680E:
    1010           0 :                                             Read_PicLoc(nAktId, pParams, 1);
    1011           0 :                                         break;
    1012             :                                 }
    1013          24 :                                 aSprmIter.advance();
    1014             :                             }
    1015             : 
    1016           8 :                             if( !nLoop )
    1017             :                             {
    1018           4 :                                 pChp->GetPCDSprms(  aDesc );
    1019             :                                 aSprmIter.SetSprms( aDesc.pMemPos,
    1020           4 :                                     aDesc.nSprmsLen );
    1021             :                             }
    1022             :                         }
    1023           4 :                         aSave.Restore(this);
    1024           4 :                         m_bEmbeddObj=bOldEmbeddObj;
    1025             : 
    1026             :                         // then import either an OLE of a Graphic
    1027           4 :                         if( m_bObj )
    1028             :                         {
    1029           0 :                             if( bMakeSdrGrafObj && pTextObj &&
    1030           0 :                                 pTextObj->GetUpGroup() )
    1031             :                             {
    1032             :                                 // SdrOleObj/SdrGrafObj anstatt des
    1033             :                                 // SdrTextObj in dessen Gruppe einsetzen
    1034             : 
    1035           0 :                                 Graphic aGraph;
    1036           0 :                                 SdrObject* pNew = ImportOleBase(aGraph);
    1037             : 
    1038           0 :                                 if( !pNew )
    1039             :                                 {
    1040           0 :                                     pNew = new SdrGrafObj;
    1041           0 :                                     static_cast<SdrGrafObj*>(pNew)->SetGraphic(aGraph);
    1042             :                                 }
    1043             : 
    1044           0 :                                 GrafikCtor();
    1045             : 
    1046           0 :                                 pNew->SetModel( m_pDrawModel );
    1047           0 :                                 pNew->SetLogicRect( pTextObj->GetCurrentBoundRect() );
    1048           0 :                                 pNew->SetLayer( pTextObj->GetLayer() );
    1049             : 
    1050           0 :                                 pTextObj->GetUpGroup()->GetSubList()->
    1051           0 :                                     ReplaceObject(pNew, pTextObj->GetOrdNum());
    1052             :                             }
    1053             :                             else
    1054           0 :                                 pFlyFormat = ImportOle();
    1055           0 :                             m_bObj = false;
    1056             :                         }
    1057             :                         else
    1058             :                         {
    1059             :                             InsertAttrsAsDrawingAttrs(nNewStartCp, nNewStartCp+1,
    1060           4 :                                 eType, true);
    1061             :                             pFlyFormat = ImportGraf(bMakeSdrGrafObj ? pTextObj : 0,
    1062           4 :                                 pOldFlyFormat);
    1063           4 :                         }
    1064             :                     }
    1065           4 :                     break;
    1066             :                 case 0x8:
    1067           0 :                     if ( (!pbTestTxbxContainsText) && (!m_bObj) )
    1068           0 :                         pFlyFormat = Read_GrafLayer( nPosCp );
    1069           0 :                     break;
    1070             :                 default:
    1071          24 :                     bDone = false;
    1072          24 :                     break;
    1073             :             }
    1074             : 
    1075          28 :             if( bDone )
    1076             :             {
    1077           4 :                 if( pFlyFormat )
    1078             :                 {
    1079           0 :                     if( pRecord )
    1080             :                     {
    1081           0 :                         SfxItemSet aFlySet( m_rDoc.GetAttrPool(),
    1082           0 :                             RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
    1083             : 
    1084             :                         Rectangle aInnerDist(   pRecord->nDxTextLeft,
    1085             :                                                 pRecord->nDyTextTop,
    1086             :                                                 pRecord->nDxTextRight,
    1087           0 :                                                 pRecord->nDyTextBottom  );
    1088             :                         MatchSdrItemsIntoFlySet( pTextObj,
    1089             :                                                  aFlySet,
    1090             :                                                  pRecord->eLineStyle,
    1091             :                                                  pRecord->eLineDashing,
    1092             :                                                  pRecord->eShapeType,
    1093           0 :                                                  aInnerDist );
    1094             : 
    1095           0 :                         pFlyFormat->SetFormatAttr( aFlySet );
    1096             : 
    1097           0 :                         MapWrapIntoFlyFormat(pRecord, pFlyFormat);
    1098             :                     }
    1099             :                 }
    1100           4 :                 aString.clear();
    1101           4 :                 rbEraseTextObj = (0 != pFlyFormat);
    1102             :             }
    1103             :         }
    1104             :     }
    1105             : 
    1106          80 :     if( pnStartCp )
    1107          10 :         *pnStartCp = nStartCp;
    1108          80 :     if( pnEndCp )
    1109          10 :         *pnEndCp = nEndCp;
    1110             : 
    1111          80 :     if( pbTestTxbxContainsText )
    1112          10 :         *pbTestTxbxContainsText = bTextWasRead && ! rbEraseTextObj;
    1113          70 :     else if( !rbEraseTextObj )
    1114             :     {
    1115          70 :         if( bTextWasRead )
    1116             :         {
    1117          68 :             m_pDrawEditEngine->SetText(aOrigString);
    1118          68 :             InsertAttrsAsDrawingAttrs(nStartCp, nEndCp, eType);
    1119             :         }
    1120             : 
    1121          70 :         bool bVertical = pTextObj->IsVerticalWriting();
    1122          70 :         EditTextObject* pTemporaryText = m_pDrawEditEngine->CreateTextObject();
    1123          70 :         OutlinerParaObject* pOp = new OutlinerParaObject(*pTemporaryText);
    1124          70 :         pOp->SetOutlinerMode( OUTLINERMODE_TEXTOBJECT );
    1125          70 :         pOp->SetVertical( bVertical );
    1126          70 :         delete pTemporaryText;
    1127          70 :         pTextObj->NbcSetOutlinerParaObject( pOp );
    1128          70 :         pTextObj->SetVerticalWriting(bVertical);
    1129             : 
    1130             :         // Fuer die naechste Textbox noch die alten Absatz-Attribute
    1131             :         // und Styles entfernen, sonst startet die naechste Box
    1132             :         // mit falschen Attributen.
    1133             :         // Vorgehen: Text loeschen = auf 1 Absatz reduzieren
    1134             :         // und an diesem Absatz die Absatzattribute und Styles loeschen
    1135             :         // (Empfehlung JOE)
    1136          70 :         m_pDrawEditEngine->SetText( OUString() );
    1137          70 :         m_pDrawEditEngine->SetParaAttribs(0, m_pDrawEditEngine->GetEmptyItemSet());
    1138             :     }
    1139             : 
    1140          80 :     m_pStrm->Seek( nOld );
    1141          80 :     if (pbContainsGraphics)
    1142           0 :         *pbContainsGraphics = bContainsGraphics;
    1143         160 :     return pFlyFormat;
    1144             : }
    1145             : 
    1146          10 : bool SwWW8ImplReader::TxbxChainContainsRealText(sal_uInt16 nTxBxS, long& rStartCp,
    1147             :     long&  rEndCp)
    1148             : {
    1149             :     bool bErase, bContainsText;
    1150             :     InsertTxbxText( 0,0,nTxBxS,USHRT_MAX,0,0,false, bErase, &bContainsText,
    1151          10 :         &rStartCp, &rEndCp );
    1152          10 :     return bContainsText;
    1153             : }
    1154             : 
    1155             : // TextBoxes only for Ver67 !!
    1156           0 : SdrObject* SwWW8ImplReader::ReadTextBox(WW8_DPHEAD* pHd, SfxAllItemSet &rSet)
    1157             : {
    1158             :     bool bDummy;
    1159             :     WW8_DP_TXTBOX aTextB;
    1160             : 
    1161           0 :     if( !ReadGrafStart( static_cast<void*>(&aTextB), sizeof( aTextB ), pHd, rSet ) )
    1162           0 :         return 0;
    1163             : 
    1164           0 :     Point aP0( (sal_Int16)SVBT16ToShort( pHd->xa ) + m_nDrawXOfs2,
    1165           0 :                (sal_Int16)SVBT16ToShort( pHd->ya ) + m_nDrawYOfs2 );
    1166           0 :     Point aP1( aP0 );
    1167           0 :     aP1.X() += (sal_Int16)SVBT16ToShort( pHd->dxa );
    1168           0 :     aP1.Y() += (sal_Int16)SVBT16ToShort( pHd->dya );
    1169             : 
    1170           0 :     SdrObject* pObj = new SdrRectObj( OBJ_TEXT, Rectangle( aP0, aP1 ) );
    1171           0 :     pObj->SetModel( m_pDrawModel );
    1172           0 :     pObj->NbcSetSnapRect(Rectangle(aP0, aP1));
    1173           0 :     Size aSize( (sal_Int16)SVBT16ToShort( pHd->dxa ) ,
    1174           0 :         (sal_Int16)SVBT16ToShort( pHd->dya ) );
    1175             : 
    1176             :     long nStartCpFly,nEndCpFly;
    1177             :     bool bContainsGraphics;
    1178             :     InsertTxbxText(dynamic_cast<SdrTextObj*>(pObj), &aSize, 0, 0, 0, 0, false,
    1179           0 :         bDummy,0,&nStartCpFly,&nEndCpFly,&bContainsGraphics);
    1180             : 
    1181           0 :     SetStdAttr( rSet, aTextB.aLnt, aTextB.aShd );
    1182           0 :     SetFill( rSet, aTextB.aFill );
    1183             : 
    1184           0 :     rSet.Put( SdrTextFitToSizeTypeItem( SDRTEXTFIT_NONE ) );
    1185           0 :     rSet.Put( makeSdrTextAutoGrowWidthItem(false));
    1186           0 :     rSet.Put( makeSdrTextAutoGrowHeightItem(false));
    1187           0 :     rSet.Put( makeSdrTextLeftDistItem(  MIN_BORDER_DIST*2 ) );
    1188           0 :     rSet.Put( makeSdrTextRightDistItem( MIN_BORDER_DIST*2 ) );
    1189           0 :     rSet.Put( makeSdrTextUpperDistItem( MIN_BORDER_DIST ) );
    1190           0 :     rSet.Put( makeSdrTextLowerDistItem( MIN_BORDER_DIST ) );
    1191             : 
    1192           0 :     return pObj;
    1193             : }
    1194             : 
    1195           0 : SdrObject* SwWW8ImplReader::ReadCaptionBox(WW8_DPHEAD* pHd, SfxAllItemSet &rSet)
    1196             : {
    1197             :     static const SdrCaptionType aCaptA[] = { SDRCAPT_TYPE1, SDRCAPT_TYPE2,
    1198             :                                        SDRCAPT_TYPE3, SDRCAPT_TYPE4 };
    1199             : 
    1200             :     WW8_DP_CALLOUT_TXTBOX aCallB;
    1201             : 
    1202           0 :     if( !ReadGrafStart( static_cast<void*>(&aCallB), sizeof( aCallB ), pHd, rSet ) )
    1203           0 :         return 0;
    1204             : 
    1205           0 :     sal_uInt16 nCount = SVBT16ToShort( aCallB.dpPolyLine.aBits1 ) >> 1 & 0x7fff;
    1206           0 :     boost::scoped_array<SVBT16> xP(new SVBT16[nCount * 2]);
    1207             : 
    1208           0 :     bool bCouldRead = checkRead(*m_pStrm, xP.get(), nCount * 4);      // Punkte einlesen
    1209             :     OSL_ENSURE(bCouldRead, "Short CaptionBox header");
    1210           0 :     if (!bCouldRead)
    1211           0 :         return 0;
    1212             : 
    1213           0 :     sal_uInt8 nTyp = (sal_uInt8)nCount - 1;
    1214           0 :     if( nTyp == 1 && SVBT16ToShort( xP[0] ) == SVBT16ToShort( xP[2] ) )
    1215           0 :         nTyp = 0;
    1216             : 
    1217           0 :     Point aP0( (sal_Int16)SVBT16ToShort( pHd->xa ) +
    1218           0 :                (sal_Int16)SVBT16ToShort( aCallB.dpheadTxbx.xa ) + m_nDrawXOfs2,
    1219           0 :                (sal_Int16)SVBT16ToShort( pHd->ya )
    1220           0 :                + (sal_Int16)SVBT16ToShort( aCallB.dpheadTxbx.ya ) + m_nDrawYOfs2 );
    1221           0 :     Point aP1( aP0 );
    1222           0 :     aP1.X() += (sal_Int16)SVBT16ToShort( aCallB.dpheadTxbx.dxa );
    1223           0 :     aP1.Y() += (sal_Int16)SVBT16ToShort( aCallB.dpheadTxbx.dya );
    1224           0 :     Point aP2( (sal_Int16)SVBT16ToShort( pHd->xa )
    1225           0 :                 + (sal_Int16)SVBT16ToShort( aCallB.dpheadPolyLine.xa )
    1226           0 :                 + m_nDrawXOfs2 + (sal_Int16)SVBT16ToShort( xP[0] ),
    1227           0 :                (sal_Int16)SVBT16ToShort( pHd->ya )
    1228           0 :                + (sal_Int16)SVBT16ToShort( aCallB.dpheadPolyLine.ya )
    1229           0 :                + m_nDrawYOfs2 + (sal_Int16)SVBT16ToShort( xP[1] ) );
    1230           0 :     xP.reset();
    1231             : 
    1232           0 :     SdrCaptionObj* pObj = new SdrCaptionObj( Rectangle( aP0, aP1 ), aP2 );
    1233           0 :     pObj->SetModel( m_pDrawModel );
    1234           0 :     pObj->NbcSetSnapRect(Rectangle(aP0, aP1));
    1235           0 :     Size aSize( (sal_Int16)SVBT16ToShort( aCallB.dpheadTxbx.dxa ),
    1236           0 :                            (sal_Int16)SVBT16ToShort(  aCallB.dpheadTxbx.dya ) );
    1237             :     bool bEraseThisObject;
    1238             : 
    1239           0 :     InsertTxbxText(pObj, &aSize, 0, 0, 0, 0, false, bEraseThisObject );
    1240             : 
    1241           0 :     if( SVBT16ToShort( aCallB.dptxbx.aLnt.lnps ) != 5 ) // Umrandung sichtbar ?
    1242           0 :         SetStdAttr( rSet, aCallB.dptxbx.aLnt, aCallB.dptxbx.aShd );
    1243             :     else                                                // nein -> Nimm Linie
    1244           0 :         SetStdAttr( rSet, aCallB.dpPolyLine.aLnt, aCallB.dptxbx.aShd );
    1245           0 :     SetFill( rSet, aCallB.dptxbx.aFill );
    1246           0 :     rSet.Put( SdrCaptionTypeItem( aCaptA[nTyp] ) );
    1247             : 
    1248           0 :     return pObj;
    1249             : }
    1250             : 
    1251           0 : SdrObject *SwWW8ImplReader::ReadGroup(WW8_DPHEAD* pHd, SfxAllItemSet &rSet)
    1252             : {
    1253             :     sal_Int16 nGrouped;
    1254             : 
    1255           0 :     if( !ReadGrafStart( static_cast<void*>(&nGrouped), sizeof( nGrouped ), pHd, rSet ) )
    1256           0 :         return 0;
    1257             : 
    1258             : #ifdef OSL_BIGENDIAN
    1259             :     nGrouped = (sal_Int16)OSL_SWAPWORD( nGrouped );
    1260             : #endif
    1261             : 
    1262           0 :     m_nDrawXOfs = m_nDrawXOfs + (sal_Int16)SVBT16ToShort( pHd->xa );
    1263           0 :     m_nDrawYOfs = m_nDrawYOfs + (sal_Int16)SVBT16ToShort( pHd->ya );
    1264             : 
    1265           0 :     SdrObject* pObj = new SdrObjGroup;
    1266             : 
    1267           0 :     short nLeft = (sal_Int16)SVBT16ToShort( pHd->cb ) - sizeof( WW8_DPHEAD );
    1268           0 :     for (int i = 0; i < nGrouped; i++)
    1269             :     {
    1270           0 :         SfxAllItemSet aSet(m_pDrawModel->GetItemPool());
    1271           0 :         if (SdrObject *pObject = ReadGrafPrimitive(nLeft, aSet))
    1272             :         {
    1273             :             // first add and then set ItemSet
    1274           0 :             SdrObjList *pSubGroup = pObj->GetSubList();
    1275             :             OSL_ENSURE(pSubGroup, "Why no sublist available?");
    1276           0 :             if (pSubGroup)
    1277           0 :                 pSubGroup->InsertObject(pObject, 0);
    1278           0 :             pObject->SetMergedItemSetAndBroadcast(aSet);
    1279             :         }
    1280           0 :     }
    1281             : 
    1282           0 :     m_nDrawXOfs = m_nDrawXOfs - (sal_Int16)SVBT16ToShort( pHd->xa );
    1283           0 :     m_nDrawYOfs = m_nDrawYOfs - (sal_Int16)SVBT16ToShort( pHd->ya );
    1284             : 
    1285           0 :     return pObj;
    1286             : }
    1287             : 
    1288           0 : SdrObject* SwWW8ImplReader::ReadGrafPrimitive(short& rLeft, SfxAllItemSet &rSet)
    1289             : {
    1290             :     // cmc: This whole archaic word 6 graphic import can probably be refactored
    1291             :     // into an object hierarachy with a little effort.
    1292           0 :     SdrObject *pRet=0;
    1293             :     WW8_DPHEAD aHd;                         // Lese Draw-Primitive-Header
    1294           0 :     bool bCouldRead = checkRead(*m_pStrm, &aHd, sizeof(WW8_DPHEAD));
    1295             :     OSL_ENSURE(bCouldRead, "Graphic Primitive header short read" );
    1296           0 :     if (!bCouldRead)
    1297             :     {
    1298           0 :         rLeft=0;
    1299           0 :         return pRet;
    1300             :     }
    1301             : 
    1302           0 :     if( rLeft >= SVBT16ToShort(aHd.cb) )    // Vorsichtsmassmahme
    1303             :     {
    1304           0 :         rSet.Put(SwFormatSurround(SURROUND_THROUGHT));
    1305           0 :         switch (SVBT16ToShort(aHd.dpk) & 0xff )
    1306             :         {
    1307             :             case 0:
    1308           0 :                 pRet = ReadGroup(&aHd, rSet);
    1309           0 :                 break;
    1310             :             case 1:
    1311           0 :                 pRet = ReadLine(&aHd, rSet);
    1312           0 :                 break;
    1313             :             case 2:
    1314           0 :                 pRet = ReadTextBox(&aHd, rSet);
    1315           0 :                 break;
    1316             :             case 3:
    1317           0 :                 pRet = ReadRect(&aHd, rSet);
    1318           0 :                 break;
    1319             :             case 4:
    1320           0 :                 pRet = ReadElipse(&aHd, rSet);
    1321           0 :                 break;
    1322             :             case 5:
    1323           0 :                 pRet = ReadArc(&aHd, rSet);
    1324           0 :                 break;
    1325             :             case 6:
    1326           0 :                 pRet = ReadPolyLine(&aHd, rSet);
    1327           0 :                 break;
    1328             :             case 7:
    1329           0 :                 pRet = ReadCaptionBox(&aHd, rSet);
    1330           0 :                 break;
    1331             :             default:    // unbekannt
    1332           0 :                 m_pStrm->SeekRel(SVBT16ToShort(aHd.cb) - sizeof(WW8_DPHEAD));
    1333           0 :                 break;
    1334             :         }
    1335             :     }
    1336             :     else
    1337             :     {
    1338             :         OSL_ENSURE( false, "+Grafik-Overlap" );
    1339             :     }
    1340           0 :     rLeft = rLeft - SVBT16ToShort( aHd.cb );
    1341           0 :     return pRet;
    1342             : }
    1343             : 
    1344           0 : void SwWW8ImplReader::ReadGrafLayer1( WW8PLCFspecial* pPF, long nGrafAnchorCp )
    1345             : {
    1346           0 :     pPF->SeekPos( nGrafAnchorCp );
    1347             :     WW8_FC nStartFc;
    1348             :     void* pF0;
    1349           0 :     if( !pPF->Get( nStartFc, pF0 ) )
    1350             :     {
    1351             :         OSL_ENSURE( false, "+Wo ist die Grafik (2) ?" );
    1352           0 :         return;
    1353             :     }
    1354           0 :     WW8_FDOA* pF = static_cast<WW8_FDOA*>(pF0);
    1355           0 :     if( !SVBT32ToUInt32( pF->fc ) )
    1356             :     {
    1357             :         OSL_ENSURE( false, "+Wo ist die Grafik (3) ?" );
    1358           0 :         return;
    1359             :     }
    1360             : 
    1361           0 :     bool bCouldSeek = checkSeek(*m_pStrm, SVBT32ToUInt32(pF->fc));
    1362             :     OSL_ENSURE(bCouldSeek, "Invalid Graphic offset");
    1363           0 :     if (!bCouldSeek)
    1364           0 :         return;
    1365             : 
    1366             :     // Lese Draw-Header
    1367             :     WW8_DO aDo;
    1368           0 :     bool bCouldRead = checkRead(*m_pStrm, &aDo, sizeof(WW8_DO));
    1369             :     OSL_ENSURE(bCouldRead, "Short Graphic header");
    1370           0 :     if (!bCouldRead)
    1371           0 :         return;
    1372             : 
    1373           0 :     short nLeft = SVBT16ToShort( aDo.cb ) - sizeof( WW8_DO );
    1374           0 :     while (nLeft > static_cast<short>(sizeof(WW8_DPHEAD)))
    1375             :     {
    1376           0 :         SfxAllItemSet aSet( m_pDrawModel->GetItemPool() );
    1377           0 :         if (SdrObject *pObject = ReadGrafPrimitive(nLeft, aSet))
    1378             :         {
    1379           0 :             m_pWWZOrder->InsertDrawingObject(pObject, SVBT16ToShort(aDo.dhgt));
    1380             : 
    1381           0 :             Rectangle aRect(pObject->GetSnapRect());
    1382             : 
    1383           0 :             const sal_uInt32 nCntRelTo = 3;
    1384             : 
    1385             :             // Adjustment is horizontally relative to...
    1386             :             static const sal_Int16 aHoriRelOriTab[nCntRelTo] =
    1387             :             {
    1388             :                 text::RelOrientation::PAGE_PRINT_AREA, // 0 is page textarea margin
    1389             :                 text::RelOrientation::PAGE_FRAME,   // 1 is page margin
    1390             :                 text::RelOrientation::FRAME,          // 2 is relative to paragraph
    1391             :             };
    1392             : 
    1393             :             // Adjustment is vertically relative to...
    1394             :             static const sal_Int16 aVertRelOriTab[nCntRelTo] =
    1395             :             {
    1396             :                 text::RelOrientation::PAGE_PRINT_AREA, // 0 is page textarea margin
    1397             :                 text::RelOrientation::PAGE_FRAME,   // 1 is page margin
    1398             :                 text::RelOrientation::FRAME,          // 2 is relative to paragraph
    1399             :             };
    1400             : 
    1401           0 :             const int nXAlign = aDo.bx < nCntRelTo ? aDo.bx : 0;
    1402           0 :             const int nYAlign = aDo.by < nCntRelTo ? aDo.by : 0;
    1403             : 
    1404           0 :             aSet.Put(SwFormatHoriOrient(aRect.Left(), text::HoriOrientation::NONE,
    1405           0 :                 aHoriRelOriTab[ nXAlign ]));
    1406           0 :             aSet.Put(SwFormatVertOrient(aRect.Top(), text::VertOrientation::NONE,
    1407           0 :                 aVertRelOriTab[ nYAlign ]));
    1408             : 
    1409           0 :             SwFrameFormat *pFrm = m_rDoc.getIDocumentContentOperations().InsertDrawObj( *m_pPaM, *pObject, aSet );
    1410           0 :             pObject->SetMergedItemSet(aSet);
    1411             : 
    1412           0 :             if (pFrm->ISA(SwDrawFrameFormat))
    1413             :             {
    1414           0 :                 static_cast<SwDrawFrameFormat*>(pFrm)->PosAttrSet();
    1415             :             }
    1416             : 
    1417           0 :             AddAutoAnchor(pFrm);
    1418             :         }
    1419           0 :     }
    1420             : }
    1421             : 
    1422          81 : sal_Int32 SwMSDffManager::GetEscherLineMatch(MSO_LineStyle eStyle,
    1423             :     MSO_SPT eShapeType, sal_Int32 &rThick)
    1424             : {
    1425          81 :     sal_Int32 nOutsideThick = 0;
    1426             :     /*
    1427             :     Beachte: im Gegensatz zu den Winword-ueblichen Tabellen- und
    1428             :     Rahmen-Randbreiten-Angaben, bei denen jeweils aus der Staerke *einer*
    1429             :     Linie die Gesamt-Randbreite zu errechnen ist, liegen die aus dem ESCHER
    1430             :     stammenden Daten bereits als Gesamt-Breite [twips] vor!
    1431             : 
    1432             :     Der Winword default ist 15 tw. Wir nehmen hierfuer unsere 20 tw Linie.  (
    1433             :     0.75 pt uns 1.0 pt sehen sich auf dem Ausdruck naemlich aehnlicher als
    1434             :     etwas 0.75 pt und unsere 0.05 pt Haarlinie. ) Die Haarlinie setzen wir nur
    1435             :     bei Winword-Staerken bis zu maximal 0.5 pt ein.
    1436             :     */
    1437          81 :     switch( eStyle )
    1438             :     {
    1439             :     case mso_lineTriple:
    1440             :     case mso_lineSimple:
    1441          23 :         nOutsideThick = eShapeType != mso_sptTextBox ? rThick : rThick/2;
    1442          23 :         break;
    1443             :     case mso_lineDouble:
    1444           0 :         if (eShapeType == mso_sptTextBox)
    1445             :         {
    1446           0 :             nOutsideThick = rThick/6;
    1447           0 :             rThick = rThick*2/3;
    1448             :         }
    1449             :         else
    1450           0 :             nOutsideThick = rThick*2/3;
    1451           0 :         break;
    1452             :     case mso_lineThickThin:
    1453           0 :         if (eShapeType == mso_sptTextBox)
    1454             :         {
    1455           0 :             nOutsideThick = rThick*3/10;
    1456           0 :             rThick = rThick*4/5;
    1457             :         }
    1458             :         else
    1459           0 :             nOutsideThick = rThick*4/5;
    1460           0 :         break;
    1461             :     case mso_lineThinThick:
    1462             :         {
    1463           0 :         if (eShapeType == mso_sptTextBox)
    1464             :         {
    1465           0 :             nOutsideThick = rThick/10;
    1466           0 :             rThick = rThick*3/5;
    1467             :         }
    1468             :         else
    1469           0 :             nOutsideThick = rThick*3/5;
    1470             :         }
    1471           0 :         break;
    1472             :     default:
    1473          58 :         break;
    1474             :     }
    1475          81 :     return nOutsideThick;
    1476             : }
    1477             : 
    1478             : // Returns the thickness of the line outside the frame, the logic of
    1479             : // words positioning of borders around floating objects is that of a
    1480             : // disturbed mind.
    1481          80 : sal_Int32 SwWW8ImplReader::MatchSdrBoxIntoFlyBoxItem(const Color& rLineColor,
    1482             :     MSO_LineStyle eLineStyle, MSO_LineDashing eDashing, MSO_SPT eShapeType, sal_Int32 &rLineThick,
    1483             :     SvxBoxItem& rBox )
    1484             : {
    1485          80 :     sal_Int32 nOutsideThick = 0;
    1486          80 :     if( !rLineThick )
    1487           0 :         return nOutsideThick;
    1488             : 
    1489          80 :     ::editeng::SvxBorderStyle nIdx = table::BorderLineStyle::NONE;
    1490             : 
    1491          80 :     sal_Int32 nLineThick=rLineThick;
    1492             :     nOutsideThick = SwMSDffManager::GetEscherLineMatch(eLineStyle,
    1493          80 :         eShapeType, rLineThick);
    1494             : 
    1495             :     /*
    1496             :     Beachte: im Gegensatz zu den Winword-ueblichen Tabellen- und
    1497             :     Rahmen-Randbreiten-Angaben, bei denen jeweils aus der Staerke *einer*
    1498             :     Linie die Gesamt-Randbreite zu errechnen ist, liegen die aus dem ESCHER
    1499             :     stammenden Daten bereits als Gesamt-Breite [twips] vor!
    1500             : 
    1501             :     Der Winword default ist 15 tw. Wir nehmen hierfuer unsere 20 tw Linie.  (
    1502             :     0.75 pt uns 1.0 pt sehen sich auf dem Ausdruck naemlich aehnlicher als
    1503             :     etwas 0.75 pt und unsere 0.05 pt Haarlinie. ) Die Haarlinie setzen wir nur
    1504             :     bei Winword-Staerken bis zu maximal 0.5 pt ein.
    1505             :     */
    1506          80 :     switch( +eLineStyle )
    1507             :     {
    1508             :     // zuerst die Einzel-Linien
    1509             :     case mso_lineSimple:
    1510          22 :         nIdx = table::BorderLineStyle::SOLID;
    1511          22 :     break;
    1512             :     // dann die Doppel-Linien, fuer die wir feine Entsprechungen haben :-)))
    1513             :     case mso_lineDouble:
    1514           0 :         nIdx = table::BorderLineStyle::DOUBLE;
    1515           0 :     break;
    1516             :     case mso_lineThickThin:
    1517           0 :         nIdx = table::BorderLineStyle::THICKTHIN_SMALLGAP;
    1518           0 :     break;
    1519             :     case mso_lineThinThick:
    1520           0 :         nIdx = table::BorderLineStyle::THINTHICK_SMALLGAP;
    1521           0 :     break;
    1522             :     // We have no triple border, use double instead.
    1523             :     case mso_lineTriple:
    1524           0 :         nIdx = table::BorderLineStyle::DOUBLE;
    1525           0 :     break;
    1526             :     // no line style is set
    1527             :     case (MSO_LineStyle)USHRT_MAX:
    1528          58 :         break;
    1529             :     // erroneously not implemented line style is set
    1530             :     default:
    1531             :         OSL_ENSURE(false, "eLineStyle is not (yet) implemented!");
    1532           0 :         break;
    1533             :     }
    1534             : 
    1535          80 :     switch( eDashing )
    1536             :     {
    1537             :         case mso_lineDashGEL:
    1538           0 :             nIdx = table::BorderLineStyle::DASHED;
    1539           0 :             break;
    1540             :         case mso_lineDotGEL:
    1541           1 :             nIdx = table::BorderLineStyle::DOTTED;
    1542           1 :             break;
    1543             :         default:
    1544          79 :             break;
    1545             :     }
    1546             : 
    1547          80 :     if (table::BorderLineStyle::NONE != nIdx)
    1548             :     {
    1549          22 :         SvxBorderLine aLine;
    1550          22 :         aLine.SetColor( rLineColor );
    1551             : 
    1552          22 :         aLine.SetWidth( nLineThick ); // No conversion here, nLineThick is already in twips
    1553          22 :         aLine.SetBorderLineStyle(nIdx);
    1554             : 
    1555         110 :         for(SvxBoxItemLine nLine : o3tl::enumrange<SvxBoxItemLine>())
    1556             :         {
    1557             :             // aLine is cloned by SetLine
    1558          88 :             rBox.SetLine(&aLine, nLine);
    1559             :         }
    1560             :     }
    1561             : 
    1562          80 :     return nOutsideThick;
    1563             : }
    1564             : 
    1565             : #define WW8ITEMVALUE(ItemSet,Id,Cast)  static_cast<const Cast&>((ItemSet).Get(Id)).GetValue()
    1566             : 
    1567          80 : void SwWW8ImplReader::MatchSdrItemsIntoFlySet( SdrObject* pSdrObj,
    1568             :     SfxItemSet& rFlySet, MSO_LineStyle eLineStyle, MSO_LineDashing eDashing, MSO_SPT eShapeType,
    1569             :     Rectangle& rInnerDist )
    1570             : {
    1571             : /*
    1572             :     am Rahmen zu setzende Frame-Attribute
    1573             :     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    1574             :     SwFormatFrmSize            falls noch nicht gesetzt, hier setzen
    1575             :     SvxLRSpaceItem          hier setzen
    1576             :     SvxULSpaceItem          hier setzen
    1577             :     SvxOpaqueItem           (Derzeit bei Rahmen nicht moeglich! khz 10.2.1999)
    1578             :     SwFormatSurround           bereits gesetzt
    1579             :     SwFormatVertOrient         bereits gesetzt
    1580             :     SwFormatHoriOrient         bereits gesetzt
    1581             :     SwFormatAnchor             bereits gesetzt
    1582             :     SvxBoxItem              hier setzen
    1583             :     SvxBrushItem            hier setzen
    1584             :     SvxShadowItem           hier setzen
    1585             : */
    1586             : 
    1587             :     // 1. GrafikObjekt des Docs?
    1588          80 :     GrafikCtor();
    1589             : 
    1590          80 :     const SfxItemSet& rOldSet = pSdrObj->GetMergedItemSet();
    1591             : 
    1592             :     // einige Items koennen direkt so uebernommen werden
    1593          80 :     const sal_uInt16 nDirectMatch = 2;
    1594             :     static RES_FRMATR const aDirectMatch[ nDirectMatch ] =
    1595             :     {
    1596             :         RES_LR_SPACE,   // Aussenabstand links/rechts: SvxLRSpaceItem
    1597             :         RES_UL_SPACE    // Aussenabstand Oben/unten:   SvxULSpaceItem
    1598             :     };
    1599             :     const SfxPoolItem* pPoolItem;
    1600         240 :     for(sal_uInt16 nItem = 0; nItem < nDirectMatch; ++nItem)
    1601         160 :         if( SfxItemState::SET == rOldSet.GetItemState(
    1602         160 :                     static_cast< sal_uInt16 >(aDirectMatch[ nItem ]), false, &pPoolItem) )
    1603             :         {
    1604           0 :             rFlySet.Put( *pPoolItem );
    1605             :         }
    1606             : 
    1607             :     // jetzt die Umrandung berechnen und die Box bauen: Das Mass wird fuer die
    1608             :     // Rahmen-GROESSE benoetigt!
    1609          80 :     SvxBoxItem aBox(sw::util::ItemGet<SvxBoxItem>(rFlySet, RES_BOX));
    1610             :     // dashed oder solid wird zu solid
    1611             :     // WW-default: 0.75 pt = 15 twips
    1612          80 :     sal_Int32 nLineThick = 15, nOutside=0;
    1613             : 
    1614             :     // check if LineStyle is *really* set!
    1615             :     const SfxPoolItem* pItem;
    1616             : 
    1617          80 :     SfxItemState eState = rOldSet.GetItemState(XATTR_LINESTYLE,true,&pItem);
    1618          80 :     if( eState == SfxItemState::SET )
    1619             :     {
    1620             :         // Now, that we know there is a line style we will make use the
    1621             :         // parameter given to us when calling the method...  :-)
    1622             :         const Color aLineColor = static_cast< XLineColorItem const & >(
    1623          80 :             rOldSet.Get(XATTR_LINECOLOR)).GetColorValue();
    1624          80 :         nLineThick = WW8ITEMVALUE(rOldSet, XATTR_LINEWIDTH, XLineWidthItem);
    1625             : 
    1626          80 :         if( !nLineThick )
    1627          75 :             nLineThick = 1; // for Writer, zero is "no border", so set a minimal value
    1628             : 
    1629             :         nOutside = MatchSdrBoxIntoFlyBoxItem(aLineColor, eLineStyle,
    1630          80 :             eDashing, eShapeType, nLineThick, aBox);
    1631             :     }
    1632             : 
    1633          80 :     rInnerDist.Left()+=nLineThick;
    1634          80 :     rInnerDist.Top()+=nLineThick;
    1635          80 :     rInnerDist.Right()+=nLineThick;
    1636          80 :     rInnerDist.Bottom()+=nLineThick;
    1637             : 
    1638             :     const SvxBorderLine *pLine;
    1639          80 :     if (0 != (pLine = aBox.GetLine(SvxBoxItemLine::LEFT)))
    1640             :     {
    1641          23 :         rInnerDist.Left() -= (pLine->GetScaledWidth());
    1642             :     }
    1643             : 
    1644          80 :     if (0 != (pLine = aBox.GetLine(SvxBoxItemLine::TOP)))
    1645             :     {
    1646          23 :         rInnerDist.Top() -= (pLine->GetScaledWidth());
    1647             :     }
    1648             : 
    1649          80 :     if (0 != (pLine = aBox.GetLine(SvxBoxItemLine::RIGHT)))
    1650             :     {
    1651          23 :         rInnerDist.Right() -= (pLine->GetScaledWidth());
    1652             :     }
    1653             : 
    1654          80 :     if (0 != (pLine = aBox.GetLine(SvxBoxItemLine::BOTTOM)))
    1655             :     {
    1656          23 :         rInnerDist.Bottom() -= (pLine->GetScaledWidth());
    1657             :     }
    1658             : 
    1659             :     // set distances from box's border to text contained within the box
    1660          80 :     if( 0 < rInnerDist.Left() )
    1661          61 :         aBox.SetDistance( (sal_uInt16)rInnerDist.Left(), SvxBoxItemLine::LEFT );
    1662          80 :     if( 0 < rInnerDist.Top() )
    1663          61 :         aBox.SetDistance( (sal_uInt16)rInnerDist.Top(), SvxBoxItemLine::TOP );
    1664          80 :     if( 0 < rInnerDist.Right() )
    1665          77 :         aBox.SetDistance( (sal_uInt16)rInnerDist.Right(), SvxBoxItemLine::RIGHT );
    1666          80 :     if( 0 < rInnerDist.Bottom() )
    1667          77 :         aBox.SetDistance( (sal_uInt16)rInnerDist.Bottom(), SvxBoxItemLine::BOTTOM );
    1668             : 
    1669          80 :     bool bFixSize = !(WW8ITEMVALUE(rOldSet, SDRATTR_TEXT_AUTOGROWHEIGHT,
    1670          80 :         SdrOnOffItem));
    1671             : 
    1672             :     // Size: SwFormatFrmSize
    1673          80 :     if( SfxItemState::SET != rFlySet.GetItemState(RES_FRM_SIZE, false) )
    1674             :     {
    1675           0 :         const Rectangle& rSnapRect = pSdrObj->GetSnapRect();
    1676             :         // if necessary adapt width and position of the framework: The
    1677             :         // recorded interior is to remain equally large despite thick edges.
    1678             :         rFlySet.Put( SwFormatFrmSize(bFixSize ? ATT_FIX_SIZE : ATT_VAR_SIZE,
    1679           0 :             rSnapRect.GetWidth()  + 2*nOutside,
    1680           0 :             rSnapRect.GetHeight() + 2*nOutside) );
    1681             :     }
    1682             :     else // If a size is set, adjust it to consider border thickness
    1683             :     {
    1684          80 :         SwFormatFrmSize aSize = static_cast<const SwFormatFrmSize &>(rFlySet.Get(RES_FRM_SIZE));
    1685             : 
    1686             :         SwFormatFrmSize aNewSize = SwFormatFrmSize(bFixSize ? ATT_FIX_SIZE : ATT_VAR_SIZE,
    1687          80 :             aSize.GetWidth()  + 2*nOutside,
    1688         240 :             aSize.GetHeight() + 2*nOutside);
    1689          80 :         aNewSize.SetWidthSizeType(aSize.GetWidthSizeType());
    1690         160 :         rFlySet.Put( aNewSize );
    1691             :     }
    1692             : 
    1693             :     // Sadly word puts escher borders outside the graphic, but orients the
    1694             :     // graphic in relation to the top left inside the border. We don't
    1695          80 :     if (nOutside)
    1696             :     {
    1697             :         SwFormatHoriOrient aHori = static_cast<const SwFormatHoriOrient &>(rFlySet.Get(
    1698          19 :             RES_HORI_ORIENT));
    1699          19 :         aHori.SetPos(MakeSafePositioningValue(aHori.GetPos()-nOutside));
    1700          19 :         rFlySet.Put(aHori);
    1701             : 
    1702             :         SwFormatVertOrient aVert = static_cast<const SwFormatVertOrient &>(rFlySet.Get(
    1703          38 :             RES_VERT_ORIENT));
    1704          19 :         aVert.SetPos(aVert.GetPos()-nOutside);
    1705          38 :         rFlySet.Put(aVert);
    1706             :     }
    1707             : 
    1708             :     // jetzt die Umrandung setzen
    1709          80 :     rFlySet.Put( aBox );
    1710             : 
    1711             :     // Schattenwurf der Box: SvxShadowItem
    1712          80 :     if( WW8ITEMVALUE(rOldSet, SDRATTR_SHADOW, SdrOnOffItem) )
    1713             :     {
    1714           2 :         SvxShadowItem aShadow( RES_SHADOW );
    1715             : 
    1716             :         const Color aShdColor = static_cast< XColorItem const & >(
    1717           2 :             rOldSet.Get(SDRATTR_SHADOWCOLOR)).GetColorValue();
    1718           2 :         const sal_Int32 nShdDistX = WW8ITEMVALUE(rOldSet, SDRATTR_SHADOWXDIST,
    1719             :             SdrMetricItem);
    1720           2 :         const sal_Int32 nShdDistY = WW8ITEMVALUE(rOldSet, SDRATTR_SHADOWYDIST,
    1721             :             SdrMetricItem);
    1722             : 
    1723           2 :         aShadow.SetColor( Color( aShdColor ) );
    1724             : 
    1725           4 :         aShadow.SetWidth(writer_cast<sal_uInt16>((std::abs( nShdDistX) +
    1726           4 :             std::abs( nShdDistY )) / 2 ));
    1727             : 
    1728             :         SvxShadowLocation eShdPosi;
    1729           2 :         if( 0 <= nShdDistX )
    1730             :         {
    1731           2 :             if( 0 <= nShdDistY )
    1732           2 :                 eShdPosi = SVX_SHADOW_BOTTOMRIGHT;
    1733             :             else
    1734           0 :                 eShdPosi = SVX_SHADOW_TOPRIGHT;
    1735             :         }
    1736             :         else
    1737             :         {
    1738           0 :             if( 0 <= nShdDistY )
    1739           0 :                 eShdPosi = SVX_SHADOW_BOTTOMLEFT;
    1740             :             else
    1741           0 :                 eShdPosi = SVX_SHADOW_TOPLEFT;
    1742             :         }
    1743           2 :         aShadow.SetLocation( eShdPosi );
    1744             : 
    1745           2 :         rFlySet.Put( aShadow );
    1746             :     }
    1747          80 :     Color Temp(COL_WHITE);
    1748         160 :     SvxBrushItem aBrushItem(Temp, RES_BACKGROUND);
    1749          80 :     bool bBrushItemOk = false;
    1750          80 :     sal_uInt8 nTrans = 0;
    1751             : 
    1752             :     // Separate transparency
    1753          80 :     eState = rOldSet.GetItemState(XATTR_FILLTRANSPARENCE, true, &pItem);
    1754          80 :     if (eState == SfxItemState::SET)
    1755             :     {
    1756           3 :         sal_uInt16 nRes = WW8ITEMVALUE(rOldSet, XATTR_FILLTRANSPARENCE,
    1757             :             XFillTransparenceItem);
    1758           3 :         nTrans = sal_uInt8((nRes * 0xFE) / 100);
    1759           3 :         aBrushItem.GetColor().SetTransparency(nTrans);
    1760           3 :         bBrushItemOk = true;
    1761             :     }
    1762             : 
    1763             :     // Hintergrund: SvxBrushItem
    1764          80 :     eState = rOldSet.GetItemState(XATTR_FILLSTYLE, true, &pItem);
    1765          80 :     if (eState == SfxItemState::SET)
    1766             :     {
    1767          80 :         const drawing::FillStyle eFill = static_cast<const XFillStyleItem*>(pItem)->GetValue();
    1768             : 
    1769          80 :         switch (eFill)
    1770             :         {
    1771             :             default:
    1772             :             case drawing::FillStyle_NONE:
    1773             :                 // Writer graphics don't have it yet
    1774          33 :                 if (eShapeType != mso_sptPictureFrame)
    1775             :                 {
    1776           1 :                     aBrushItem.GetColor().SetTransparency(0xFE);
    1777           1 :                     bBrushItemOk = true;
    1778             :                 }
    1779          33 :             break;
    1780             :             case drawing::FillStyle_SOLID:
    1781             :             case drawing::FillStyle_GRADIENT:
    1782             :                 {
    1783             :                     const Color aColor = static_cast< XFillColorItem const & >(
    1784          47 :                         rOldSet.Get(XATTR_FILLCOLOR)).GetColorValue();
    1785          47 :                     aBrushItem.SetColor(aColor);
    1786             : 
    1787          47 :                     if (bBrushItemOk) // has trans
    1788           3 :                         aBrushItem.GetColor().SetTransparency(nTrans);
    1789             : 
    1790          47 :                     bBrushItemOk = true;
    1791             :                 }
    1792          47 :             break;
    1793             :             case drawing::FillStyle_HATCH:
    1794           0 :             break;
    1795             :             case drawing::FillStyle_BITMAP:
    1796             :                 {
    1797           0 :                     GraphicObject aGrfObj(static_cast< XFillBitmapItem const & >(rOldSet.Get(XATTR_FILLBITMAP)).GetGraphicObject());
    1798           0 :                     const bool bTile(WW8ITEMVALUE(rOldSet, XATTR_FILLBMP_TILE, SfxBoolItem));
    1799             : 
    1800           0 :                     if(bBrushItemOk) // has trans
    1801             :                     {
    1802           0 :                         GraphicAttr aAttr(aGrfObj.GetAttr());
    1803             : 
    1804           0 :                         aAttr.SetTransparency(nTrans);
    1805           0 :                         aGrfObj.SetAttr(aAttr);
    1806             :                     }
    1807             : 
    1808           0 :                     aBrushItem.SetGraphicObject(aGrfObj);
    1809           0 :                     aBrushItem.SetGraphicPos(bTile ? GPOS_TILED : GPOS_AREA);
    1810           0 :                     bBrushItemOk = true;
    1811             :                 }
    1812           0 :             break;
    1813             :         }
    1814             :     }
    1815             : 
    1816          80 :     if (bBrushItemOk)
    1817         128 :         rFlySet.Put(aBrushItem, RES_BACKGROUND);
    1818          80 : }
    1819             : 
    1820          86 : void SwWW8ImplReader::AdjustLRWrapForWordMargins(
    1821             :     const SvxMSDffImportRec &rRecord, SvxLRSpaceItem &rLR)
    1822             : {
    1823          86 :     sal_uInt32 nXRelTo = SvxMSDffImportRec::RELTO_DEFAULT;
    1824          86 :     if ( rRecord.pXRelTo )
    1825             :     {
    1826          73 :         nXRelTo = *(rRecord.pXRelTo);
    1827             :     }
    1828             : 
    1829             :     // Left adjustments - if horizontally aligned to left of
    1830             :     // margin or column then remove the left wrapping
    1831          86 :     if (rRecord.nXAlign == 1)
    1832             :     {
    1833           1 :         if ((nXRelTo == 0) || (nXRelTo == 2))
    1834           0 :             rLR.SetLeft((sal_uInt16)0);
    1835             :     }
    1836             : 
    1837             :     // Right adjustments - if horizontally aligned to right of
    1838             :     // margin or column then remove the right wrapping
    1839          86 :     if (rRecord.nXAlign == 3)
    1840             :     {
    1841           0 :         if ((nXRelTo == 0) || (nXRelTo == 2))
    1842           0 :             rLR.SetRight((sal_uInt16)0);
    1843             :     }
    1844             : 
    1845             :     // Inside margin, remove left wrapping
    1846          86 :     if ((rRecord.nXAlign == 4) && (nXRelTo == 0))
    1847             :     {
    1848           0 :         rLR.SetLeft((sal_uInt16)0);
    1849             :     }
    1850             : 
    1851             :     // Outside margin, remove left wrapping
    1852          86 :     if ((rRecord.nXAlign == 5) && (nXRelTo == 0))
    1853             :     {
    1854           0 :         rLR.SetRight((sal_uInt16)0);
    1855             :     }
    1856          86 : }
    1857             : 
    1858           2 : void SwWW8ImplReader::AdjustULWrapForWordMargins(
    1859             :     const SvxMSDffImportRec &rRecord, SvxULSpaceItem &rUL)
    1860             : {
    1861           2 :     sal_uInt32 nYRelTo = SvxMSDffImportRec::RELTO_DEFAULT;
    1862           2 :     if ( rRecord.pYRelTo )
    1863             :     {
    1864           2 :         nYRelTo = *(rRecord.pYRelTo);
    1865             :     }
    1866             : 
    1867             :     // Top adjustment - remove upper wrapping if aligned to page
    1868             :     // printable area or to page
    1869           2 :     if (rRecord.nYAlign == 1)
    1870             :     {
    1871           0 :         if ((nYRelTo == 0) || (nYRelTo == 1))
    1872           0 :             rUL.SetUpper((sal_uInt16)0);
    1873             :     }
    1874             : 
    1875             :     // Bottom adjustment - remove bottom wrapping if aligned to page or
    1876             :     // printable area or to page
    1877           2 :     if (rRecord.nYAlign == 3)
    1878             :     {
    1879           0 :         if ((nYRelTo == 0) || (nYRelTo == 1))
    1880           0 :             rUL.SetLower((sal_uInt16)0);
    1881             :     }
    1882             : 
    1883             :     // Remove top margin if aligned vertically inside margin
    1884           2 :     if ((rRecord.nYAlign == 4) && (nYRelTo == 0))
    1885           0 :         rUL.SetUpper((sal_uInt16)0);
    1886           2 : }
    1887             : 
    1888         106 : void SwWW8ImplReader::MapWrapIntoFlyFormat(SvxMSDffImportRec* pRecord,
    1889             :     SwFrameFormat* pFlyFormat)
    1890             : {
    1891         106 :     if (!pRecord || !pFlyFormat)
    1892         106 :         return;
    1893             : 
    1894         106 :     if (pRecord->nDxWrapDistLeft || pRecord->nDxWrapDistRight)
    1895             :     {
    1896          86 :         SvxLRSpaceItem aLR(writer_cast<sal_uInt16>(pRecord->nDxWrapDistLeft),
    1897         172 :             writer_cast<sal_uInt16>(pRecord->nDxWrapDistRight), 0, 0, RES_LR_SPACE);
    1898          86 :         AdjustLRWrapForWordMargins(*pRecord, aLR);
    1899          86 :         pFlyFormat->SetFormatAttr(aLR);
    1900             :     }
    1901         106 :     if (pRecord->nDyWrapDistTop || pRecord->nDyWrapDistBottom)
    1902             :     {
    1903           2 :         SvxULSpaceItem aUL(writer_cast<sal_uInt16>(pRecord->nDyWrapDistTop),
    1904           4 :             writer_cast<sal_uInt16>(pRecord->nDyWrapDistBottom), RES_UL_SPACE);
    1905           2 :         AdjustULWrapForWordMargins(*pRecord, aUL);
    1906           2 :         pFlyFormat->SetFormatAttr(aUL);
    1907             :     }
    1908             : 
    1909             :     // If we are contoured and have a custom polygon...
    1910         106 :     if (pRecord->pWrapPolygon && pFlyFormat->GetSurround().IsContour())
    1911             :     {
    1912           0 :         if (SwNoTextNode *pNd = GetNoTextNodeFromSwFrameFormat(*pFlyFormat))
    1913             :         {
    1914             : 
    1915             :             /*
    1916             :              Gather round children and hear of a tale that will raise the
    1917             :              hairs on the back of your neck this dark halloween night.
    1918             : 
    1919             :              There is a polygon in word that describes the wraping around
    1920             :              the graphic.
    1921             : 
    1922             :              Here are some sample values for the simplest case of a square
    1923             :              around some solid coloured graphics
    1924             : 
    1925             :                                 X       Y       Pixel size of graphic
    1926             :                 TopLeft         -54     21600   400x400
    1927             :                 Bottom Right    0       21546
    1928             : 
    1929             :                 TopLeft         -108    21600   200x200
    1930             :                 Bottom Right    0       21492
    1931             : 
    1932             :                 TopLeft         -216    21600   100x100
    1933             :                 Bottom Right    0       21384
    1934             : 
    1935             :                 TopLeft         -432    21600   50x50
    1936             :                 Bottom Right    0       21168
    1937             : 
    1938             :                 TopLeft         -76     21600   283x212
    1939             :                 Bottom Right    0       21498
    1940             : 
    1941             :              So given that the size of the values remains pretty much the
    1942             :              same despite the size of the graphic, we can tell that the
    1943             :              polygon is measured in units that are independent of the
    1944             :              graphic. But why does the left corner move a different value
    1945             :              to the left each time, and why does the bottom move upwards
    1946             :              each time, when the right and top remain at the same value ?
    1947             : 
    1948             :              I have no idea, but clearly once we calculate the values out
    1949             :              we see that the left margin is always a fixed realworld
    1950             :              distance from the true left and the polygon bottom is the same
    1951             :              fixed value from the bottom. i.e. 15twips.
    1952             : 
    1953             :              So here we take our word provided polygon, shift it to the
    1954             :              right by 15twips and rescale it widthwise to shrink the width
    1955             :              a little to fit the now moved right margin back to where it
    1956             :              was, and stretch the height a little to make the bottom move
    1957             :              down the missing 15twips then we get a polygon that matches
    1958             :              what I actually see in word
    1959             :             */
    1960             : 
    1961           0 :             tools::PolyPolygon aPoly(*pRecord->pWrapPolygon);
    1962           0 :             const Size &rSize = pNd->GetTwipSize();
    1963             :             /*
    1964             :              Move to the left by 15twips, and rescale to
    1965             :              a) shrink right bound back to orig position
    1966             :              b) stretch bottom bound to where I think it should have been
    1967             :              in the first place
    1968             :             */
    1969           0 :             Fraction aMoveHack(ww::nWrap100Percent, rSize.Width());
    1970           0 :             aMoveHack *= Fraction(15, 1);
    1971           0 :             long nMove(aMoveHack);
    1972           0 :             aPoly.Move(nMove, 0);
    1973             : 
    1974           0 :             Fraction aHackX(ww::nWrap100Percent, ww::nWrap100Percent + nMove);
    1975           0 :             Fraction aHackY(ww::nWrap100Percent, ww::nWrap100Percent - nMove);
    1976           0 :             aPoly.Scale(aHackX, aHackY);
    1977             : 
    1978             :             // Turn polygon back into units that match the graphic's
    1979           0 :             const Size &rOrigSize = pNd->GetGraphic().GetPrefSize();
    1980           0 :             Fraction aMapPolyX(rOrigSize.Width(), ww::nWrap100Percent);
    1981           0 :             Fraction aMapPolyY(rOrigSize.Height(), ww::nWrap100Percent);
    1982           0 :             aPoly.Scale(aMapPolyX, aMapPolyY);
    1983             : 
    1984             :             // #i47277# - contour is already in unit of the
    1985             :             // graphic preferred unit. Thus, call method <SetContour(..)>
    1986           0 :             pNd->SetContour(&aPoly);
    1987             :         }
    1988             :     }
    1989             : }
    1990             : 
    1991          24 : static sal_Int32 lcl_ConvertCrop(sal_uInt32 const nCrop, sal_Int32 const nSize)
    1992             : {
    1993             :     // cast to sal_Int32 to handle negative crop properly
    1994          24 :     sal_Int32 const nIntegral(static_cast<sal_Int32>(nCrop) >> 16);
    1995             :     // fdo#77454: heuristic to detect mangled values written by old OOo/LO
    1996          24 :     if (abs(nIntegral) >= 50) // FIXME: what's a good cut-off?
    1997             :     {
    1998             :         SAL_INFO("sw.ww8", "ignoring suspiciously large crop: " << nIntegral);
    1999           0 :         return 0;
    2000             :     }
    2001          24 :     return (nIntegral * nSize) + (((nCrop & 0xffff) * nSize) >> 16);
    2002             : }
    2003             : 
    2004             : void
    2005          39 : SwWW8ImplReader::SetAttributesAtGrfNode(SvxMSDffImportRec const*const pRecord,
    2006             :     SwFrameFormat *pFlyFormat, WW8_FSPA *pF )
    2007             : {
    2008          39 :     const SwNodeIndex* pIdx = pFlyFormat->GetContent(false).GetContentIdx();
    2009             :     SwGrfNode* pGrfNd;
    2010          39 :     if( pIdx && 0 != (pGrfNd = m_rDoc.GetNodes()[pIdx->GetIndex() + 1]->GetGrfNode() ))
    2011             :     {
    2012          26 :         Size aSz(pGrfNd->GetTwipSize());
    2013             :         // use type <sal_uInt64> instead of sal_uLong to get correct results
    2014             :         // in the following calculations.
    2015          26 :         sal_uInt64 rHeight = aSz.Height();
    2016          26 :         sal_uInt64 rWidth  = aSz.Width();
    2017          26 :         if( !rWidth && pF)
    2018           1 :             rWidth  = pF->nXaRight  - pF->nXaLeft;
    2019          25 :         else if( !rHeight && pF)
    2020           0 :             rHeight = pF->nYaBottom - pF->nYaTop;
    2021             : 
    2022          26 :         if( pRecord->nCropFromTop || pRecord->nCropFromBottom ||
    2023          20 :             pRecord->nCropFromLeft || pRecord->nCropFromRight )
    2024             :         {
    2025           6 :             SwCropGrf aCrop;            // Cropping is stored in 'fixed floats'
    2026             :                                         // 16.16 (fraction times total
    2027           6 :             if( pRecord->nCropFromTop ) //        image width or height resp.)
    2028             :             {
    2029           6 :                 aCrop.SetTop(lcl_ConvertCrop(pRecord->nCropFromTop, rHeight));
    2030             :             }
    2031           6 :             if( pRecord->nCropFromBottom )
    2032             :             {
    2033           6 :                 aCrop.SetBottom(lcl_ConvertCrop(pRecord->nCropFromBottom, rHeight));
    2034             :             }
    2035           6 :             if( pRecord->nCropFromLeft )
    2036             :             {
    2037           6 :                 aCrop.SetLeft(lcl_ConvertCrop(pRecord->nCropFromLeft, rWidth));
    2038             :             }
    2039           6 :             if( pRecord->nCropFromRight )
    2040             :             {
    2041           6 :                 aCrop.SetRight(lcl_ConvertCrop(pRecord->nCropFromRight,rWidth));
    2042             :             }
    2043             : 
    2044           6 :             pGrfNd->SetAttr( aCrop );
    2045             :         }
    2046             : 
    2047          26 :         if (pRecord->pObj)
    2048             :         {
    2049          26 :             const SfxItemSet& rOldSet = pRecord->pObj->GetMergedItemSet();
    2050             :             // contrast
    2051          26 :             if (WW8ITEMVALUE(rOldSet, SDRATTR_GRAFCONTRAST,
    2052             :                 SdrGrafContrastItem))
    2053             :             {
    2054             :                 SwContrastGrf aContrast(
    2055           0 :                     WW8ITEMVALUE(rOldSet,
    2056           0 :                     SDRATTR_GRAFCONTRAST, SdrGrafContrastItem));
    2057           0 :                 pGrfNd->SetAttr( aContrast );
    2058             :             }
    2059             : 
    2060             :             // luminance
    2061          26 :             if (WW8ITEMVALUE(rOldSet, SDRATTR_GRAFLUMINANCE,
    2062             :                 SdrGrafLuminanceItem))
    2063             :             {
    2064           0 :                 SwLuminanceGrf aLuminance(WW8ITEMVALUE(rOldSet,
    2065           0 :                     SDRATTR_GRAFLUMINANCE, SdrGrafLuminanceItem));
    2066           0 :                 pGrfNd->SetAttr( aLuminance );
    2067             :             }
    2068             :             // gamma
    2069          26 :             if (WW8ITEMVALUE(rOldSet, SDRATTR_GRAFGAMMA, SdrGrafGamma100Item))
    2070             :             {
    2071          26 :                 double fVal = WW8ITEMVALUE(rOldSet, SDRATTR_GRAFGAMMA,
    2072             :                     SdrGrafGamma100Item);
    2073          26 :                 pGrfNd->SetAttr(SwGammaGrf(fVal/100.));
    2074             :             }
    2075             : 
    2076             :             // drawmode
    2077          26 :             if (WW8ITEMVALUE(rOldSet, SDRATTR_GRAFMODE, SdrGrafModeItem))
    2078             :             {
    2079           0 :                 SwDrawModeGrf aDrawMode( static_cast< sal_uInt16 >(WW8ITEMVALUE(rOldSet,
    2080           0 :                     SDRATTR_GRAFMODE, SdrGrafModeItem)) );
    2081           0 :                 pGrfNd->SetAttr( aDrawMode );
    2082             :             }
    2083             :         }
    2084             :     }
    2085          39 : }
    2086             : 
    2087          89 : SdrObject* SwWW8ImplReader::CreateContactObject(SwFrameFormat* pFlyFormat)
    2088             : {
    2089          89 :     if (pFlyFormat)
    2090             :     {
    2091          89 :         SdrObject* pNewObject = m_bNewDoc ? 0 : pFlyFormat->FindRealSdrObject();
    2092          89 :         if (!pNewObject)
    2093          89 :             pNewObject = pFlyFormat->FindSdrObject();
    2094          89 :         if (!pNewObject && pFlyFormat->ISA(SwFlyFrameFormat))
    2095             :         {
    2096             :             SwFlyDrawContact* pContactObject
    2097             :                 = new SwFlyDrawContact(static_cast<SwFlyFrameFormat*>(pFlyFormat),
    2098          59 :                 m_pDrawModel);
    2099          59 :             pNewObject = pContactObject->GetMaster();
    2100             :         }
    2101          89 :         return pNewObject;
    2102             :     }
    2103           0 :     return 0;
    2104             : }
    2105             : 
    2106             : // Miserable miserable hack to fudge word's graphic layout in RTL mode to ours.
    2107         121 : bool SwWW8ImplReader::MiserableRTLGraphicsHack(SwTwips &rLeft, SwTwips nWidth,
    2108             :     sal_Int16 eHoriOri, sal_Int16 eHoriRel)
    2109             : {
    2110         121 :     if (!IsRightToLeft())
    2111         113 :         return false;
    2112             :     return RTLGraphicsHack(rLeft, nWidth, eHoriOri, eHoriRel,
    2113           8 :             m_aSectionManager.GetPageLeft(),
    2114           8 :             m_aSectionManager.GetPageRight(),
    2115          24 :             m_aSectionManager.GetPageWidth());
    2116             : }
    2117             : 
    2118         109 : RndStdIds SwWW8ImplReader::ProcessEscherAlign(SvxMSDffImportRec* pRecord,
    2119             :     WW8_FSPA *pFSPA, SfxItemSet &rFlySet, bool /*bOrgObjectWasReplace*/)
    2120             : {
    2121             :     OSL_ENSURE(pRecord || pFSPA, "give me something! to work with for anchoring");
    2122         109 :     if (!pRecord && !pFSPA)
    2123           0 :         return FLY_AT_PAGE;
    2124         109 :     bool bCurSectionVertical = m_aSectionManager.CurrentSectionIsVertical();
    2125             : 
    2126         109 :     SvxMSDffImportRec aRecordFromFSPA;
    2127         109 :     if (!pRecord)
    2128           0 :         pRecord = &aRecordFromFSPA;
    2129         109 :     if (!(pRecord->pXRelTo) && pFSPA)
    2130             :     {
    2131          57 :         pRecord->pXRelTo = new sal_uInt32;
    2132          57 :         *(pRecord->pXRelTo) = pFSPA->nbx;
    2133             :     }
    2134         109 :     if (!(pRecord->pYRelTo) && pFSPA)
    2135             :     {
    2136          57 :         pRecord->pYRelTo = new sal_uInt32;
    2137          57 :         *(pRecord->pYRelTo) = pFSPA->nby;
    2138             :     }
    2139             : 
    2140             :     // nXAlign - abs. Position, Left,  Centered,  Right,  Inside, Outside
    2141             :     // nYAlign - abs. Position, Top,   Centered,  Bottom, Inside, Outside
    2142             : 
    2143             :     // nXRelTo - Page printable area, Page,  Column,    Character
    2144             :     // nYRelTo - Page printable area, Page,  Paragraph, Line
    2145             : 
    2146         109 :     const sal_uInt32 nCntXAlign = 6;
    2147         109 :     const sal_uInt32 nCntYAlign = 6;
    2148             : 
    2149         109 :     const sal_uInt32 nCntRelTo  = 4;
    2150             : 
    2151         109 :     sal_uInt32 nXAlign = nCntXAlign > pRecord->nXAlign ? pRecord->nXAlign : 1;
    2152         109 :     sal_uInt32 nYAlign = nCntYAlign > pRecord->nYAlign ? pRecord->nYAlign : 1;
    2153             : 
    2154         109 :     if (pFSPA)
    2155             :     {
    2156             :         // #i52565# - try to handle special case for objects in tables regarding its X Rel
    2157             : 
    2158             :         // if X and Y Rel values are on default take it as a hint, that they have not been set
    2159             :         // by <SwMSDffManager::ProcessObj(..)>
    2160         109 :         const bool bXYRelHaveDefaultValues = *(pRecord->pXRelTo) == 2 && *(pRecord->pYRelTo) == 2;
    2161         109 :         if ( bXYRelHaveDefaultValues
    2162         104 :              && m_nInTable > 0
    2163          19 :              && !bCurSectionVertical )
    2164             :         {
    2165          19 :             if ( pFSPA->nby != *(pRecord->pYRelTo) )
    2166             :             {
    2167           0 :                 *(pRecord->pYRelTo) = pFSPA->nby;
    2168             :             }
    2169             :         }
    2170             :     }
    2171             : 
    2172         109 :     sal_uInt32 nXRelTo = (pRecord->pXRelTo && nCntRelTo > *(pRecord->pXRelTo)) ? *(pRecord->pXRelTo) : 1;
    2173         109 :     sal_uInt32 nYRelTo = (pRecord->pYRelTo && nCntRelTo > *(pRecord->pYRelTo)) ? *(pRecord->pYRelTo) : 1;
    2174             : 
    2175         109 :     RndStdIds eAnchor = IsInlineEscherHack() ? FLY_AS_CHAR : FLY_AT_CHAR; // #i43718#
    2176             : 
    2177         218 :     SwFormatAnchor aAnchor( eAnchor );
    2178         109 :     aAnchor.SetAnchor( m_pPaM->GetPoint() );
    2179         109 :     rFlySet.Put( aAnchor );
    2180             : 
    2181         109 :     if (pFSPA)
    2182             :     {
    2183             :         // #i18732#
    2184             :         // Given new layout where everything is changed to be anchored to
    2185             :         // character the following 4 tables may need to be changed.
    2186             : 
    2187             :         // horizontal Adjustment
    2188             :         static const sal_Int16 aHoriOriTab[ nCntXAlign ] =
    2189             :         {
    2190             :             text::HoriOrientation::NONE,     // From left position
    2191             :             text::HoriOrientation::LEFT,     // left
    2192             :             text::HoriOrientation::CENTER,   // centered
    2193             :             text::HoriOrientation::RIGHT,    // right
    2194             :             // #i36649#
    2195             :             // - inside -> text::HoriOrientation::LEFT and outside -> text::HoriOrientation::RIGHT
    2196             :             text::HoriOrientation::LEFT,   // inside
    2197             :             text::HoriOrientation::RIGHT   // outside
    2198             :         };
    2199             : 
    2200             :         // generic vertical Adjustment
    2201             :         static const sal_Int16 aVertOriTab[ nCntYAlign ] =
    2202             :         {
    2203             :             text::VertOrientation::NONE,         // From Top position
    2204             :             text::VertOrientation::TOP,          // top
    2205             :             text::VertOrientation::CENTER,       // centered
    2206             :             text::VertOrientation::BOTTOM,       // bottom
    2207             :             text::VertOrientation::LINE_TOP,     // inside (obscure)
    2208             :             text::VertOrientation::LINE_BOTTOM   // outside (obscure)
    2209             :         };
    2210             : 
    2211             :         // #i22673# - to-line vertical alignment
    2212             :         static const sal_Int16 aToLineVertOriTab[ nCntYAlign ] =
    2213             :         {
    2214             :             text::VertOrientation::NONE,         // below
    2215             :             text::VertOrientation::LINE_BOTTOM,  // top
    2216             :             text::VertOrientation::LINE_CENTER,  // centered
    2217             :             text::VertOrientation::LINE_TOP,     // bottom
    2218             :             text::VertOrientation::LINE_BOTTOM,  // inside (obscure)
    2219             :             text::VertOrientation::LINE_TOP      // outside (obscure)
    2220             :         };
    2221             : 
    2222             :         // Adjustment is horizontally relative to...
    2223             :         static const sal_Int16 aHoriRelOriTab[nCntRelTo] =
    2224             :         {
    2225             :             text::RelOrientation::PAGE_PRINT_AREA,    // 0 is page textarea margin
    2226             :             text::RelOrientation::PAGE_FRAME,  // 1 is page margin
    2227             :             text::RelOrientation::FRAME,         // 2 is relative to column
    2228             :             text::RelOrientation::CHAR       // 3 is relative to character
    2229             :         };
    2230             : 
    2231             :         // Adjustment is vertically relative to...
    2232             :         // #i22673# - adjustment for new vertical alignment at top of line.
    2233             :         static const sal_Int16 aVertRelOriTab[nCntRelTo] =
    2234             :         {
    2235             :             text::RelOrientation::PAGE_PRINT_AREA, // 0 is page textarea margin
    2236             :             text::RelOrientation::PAGE_FRAME,   // 1 is page margin
    2237             :             text::RelOrientation::FRAME,          // 2 is relative to paragraph
    2238             :             text::RelOrientation::TEXT_LINE   // 3 is relative to line
    2239             :         };
    2240             : 
    2241         109 :         sal_Int16 eHoriOri = aHoriOriTab[ nXAlign ];
    2242         109 :         sal_Int16 eHoriRel = aHoriRelOriTab[  nXRelTo ];
    2243             : 
    2244             :         // #i36649# - adjustments for certain alignments
    2245         109 :         if ( eHoriOri == text::HoriOrientation::LEFT && eHoriRel == text::RelOrientation::PAGE_FRAME )
    2246             :         {
    2247             :             // convert 'left to page' to 'from left -<width> to page text area'
    2248           1 :             eHoriOri = text::HoriOrientation::NONE;
    2249           1 :             eHoriRel = text::RelOrientation::PAGE_PRINT_AREA;
    2250           1 :             const long nWidth = pFSPA->nXaRight - pFSPA->nXaLeft;
    2251           1 :             pFSPA->nXaLeft = -nWidth;
    2252           1 :             pFSPA->nXaRight = 0;
    2253             :         }
    2254         108 :         else if ( eHoriOri == text::HoriOrientation::RIGHT && eHoriRel == text::RelOrientation::PAGE_FRAME )
    2255             :         {
    2256             :             // convert 'right to page' to 'from left 0 to right page border'
    2257           0 :             eHoriOri = text::HoriOrientation::NONE;
    2258           0 :             eHoriRel = text::RelOrientation::PAGE_RIGHT;
    2259           0 :             const long nWidth = pFSPA->nXaRight - pFSPA->nXaLeft;
    2260           0 :             pFSPA->nXaLeft = 0;
    2261           0 :             pFSPA->nXaRight = nWidth;
    2262             :         }
    2263             : 
    2264             :         // #i24255# - position of floating screen objects in
    2265             :         // R2L layout are given in L2R layout, thus convert them of all
    2266             :         // floating screen objects, which are imported.
    2267             :         {
    2268             :             // Miserable miserable hack.
    2269         109 :             SwTwips nWidth = (pFSPA->nXaRight - pFSPA->nXaLeft);
    2270         109 :             SwTwips nLeft = pFSPA->nXaLeft;
    2271         109 :             if (MiserableRTLGraphicsHack(nLeft, nWidth, eHoriOri,
    2272         109 :                 eHoriRel))
    2273             :             {
    2274           5 :                 pFSPA->nXaLeft = nLeft;
    2275           5 :                 pFSPA->nXaRight = pFSPA->nXaLeft + nWidth;
    2276             :             }
    2277             :         }
    2278             : 
    2279             :         // if the object is anchored inside a table cell, is horizontal aligned
    2280             :         // at frame|character and has wrap through, but its attribute
    2281             :         // 'layout in table cell' isn't set, convert its horizontal alignment to page text area.
    2282             :         // #i84783# - use new method <IsObjectLayoutInTableCell()>
    2283         128 :         if ( m_nInTable &&
    2284          19 :              ( eHoriRel == text::RelOrientation::FRAME || eHoriRel == text::RelOrientation::CHAR ) &&
    2285         147 :              pFSPA->nwr == 3 &&
    2286          19 :              !IsObjectLayoutInTableCell( pRecord->nLayoutInTableCell ) )
    2287             :         {
    2288           0 :             eHoriRel = text::RelOrientation::PAGE_PRINT_AREA;
    2289             :         }
    2290             : 
    2291             :         // Writer honours this wrap distance when aligned as "left" or "right",
    2292             :         // Word doesn't. Writer doesn't honour it when its "from left".
    2293         109 :         if (eHoriOri == text::HoriOrientation::LEFT)
    2294           0 :             pRecord->nDxWrapDistLeft=0;
    2295         109 :         else if (eHoriOri == text::HoriOrientation::RIGHT)
    2296           0 :             pRecord->nDxWrapDistRight=0;
    2297             : 
    2298             :         sal_Int16 eVertRel;
    2299             : 
    2300         109 :         eVertRel = aVertRelOriTab[  nYRelTo ]; // #i18732#
    2301         109 :         if ( bCurSectionVertical && nYRelTo == 2 )
    2302           0 :             eVertRel = text::RelOrientation::PAGE_PRINT_AREA;
    2303             :         // #i22673# - fill <eVertOri> in dependence of <eVertRel>
    2304             :         sal_Int16 eVertOri;
    2305         109 :         if ( eVertRel == text::RelOrientation::TEXT_LINE )
    2306             :         {
    2307           3 :             eVertOri = aToLineVertOriTab[ nYAlign ];
    2308             :         }
    2309             :         else
    2310             :         {
    2311         106 :             eVertOri = aVertOriTab[ nYAlign ];
    2312             :         }
    2313             : 
    2314             :         // Below line in word is a positive value, while in writer its
    2315             :         // negative
    2316         109 :         long nYPos = pFSPA->nYaTop;
    2317             :         // #i22673#
    2318         109 :         if ((eVertRel == text::RelOrientation::TEXT_LINE) && (eVertOri == text::VertOrientation::NONE))
    2319           3 :             nYPos = -nYPos;
    2320             : 
    2321             :         SwFormatHoriOrient aHoriOri(MakeSafePositioningValue(  bCurSectionVertical ? nYPos : pFSPA->nXaLeft ),
    2322             :                                                             bCurSectionVertical ? eVertOri : eHoriOri,
    2323         109 :                                                             bCurSectionVertical ? eVertRel : eHoriRel);
    2324         109 :         if( 4 <= nXAlign )
    2325           0 :             aHoriOri.SetPosToggle(true);
    2326         109 :         rFlySet.Put( aHoriOri );
    2327             : 
    2328             :         rFlySet.Put(SwFormatVertOrient(MakeSafePositioningValue( !bCurSectionVertical ? nYPos : -pFSPA->nXaRight ),
    2329         109 :                                                                 !bCurSectionVertical ? eVertOri : eHoriOri,
    2330         218 :                                                                 !bCurSectionVertical ? eVertRel : eHoriRel ));
    2331             :     }
    2332             : 
    2333         218 :     return eAnchor;
    2334             : }
    2335             : 
    2336             : // #i84783#
    2337          38 : bool SwWW8ImplReader::IsObjectLayoutInTableCell( const sal_uInt32 nLayoutInTableCell ) const
    2338             : {
    2339          38 :     bool bIsObjectLayoutInTableCell = false;
    2340             : 
    2341          38 :     if ( m_bVer8 )
    2342             :     {
    2343          38 :         const sal_uInt16 nWWVersion = m_pWwFib->nProduct & 0xE000;
    2344          38 :         switch ( nWWVersion )
    2345             :         {
    2346             :             case 0x0000: // version 8 aka Microsoft Word 97
    2347             :             {
    2348           0 :                 bIsObjectLayoutInTableCell = false;
    2349             :                 OSL_ENSURE( nLayoutInTableCell == 0xFFFFFFFF,
    2350             :                         "no explicit object attribute layout in table cell expected." );
    2351             :             }
    2352           0 :             break;
    2353             :             case 0x2000: // version 9 aka Microsoft Word 2000
    2354             :             case 0x4000: // version 10 aka Microsoft Word 2002
    2355             :             case 0x6000: // version 11 aka Microsoft Word 2003
    2356             :             case 0x8000: // version 12 aka Microsoft Word 2007
    2357             :             case 0xC000: // version 14 aka Microsoft Word 2010
    2358             :             {
    2359             :                 // #i98037#
    2360             :                 // adjustment of conditions needed after deeper analysis of
    2361             :                 // certain test cases.
    2362          38 :                 if ( nLayoutInTableCell == 0xFFFFFFFF || // no explicit attribute value given
    2363           0 :                      nLayoutInTableCell == 0x80008000 ||
    2364           0 :                      ( nLayoutInTableCell & 0x02000000 &&
    2365           0 :                        !(nLayoutInTableCell & 0x80000000 ) ) )
    2366             :                 {
    2367          38 :                     bIsObjectLayoutInTableCell = true;
    2368             :                 }
    2369             :                 else
    2370             :                 {
    2371           0 :                     bIsObjectLayoutInTableCell = false;
    2372             :                 }
    2373             :             }
    2374          38 :             break;
    2375             :             default:
    2376             :             {
    2377             :                 OSL_FAIL( "unknown version." );
    2378             :             }
    2379             :         }
    2380             :     }
    2381             : 
    2382          38 :     return bIsObjectLayoutInTableCell;
    2383             : }
    2384             : 
    2385         109 : SwFrameFormat* SwWW8ImplReader::Read_GrafLayer( long nGrafAnchorCp )
    2386             : {
    2387         109 :     if( m_nIniFlags & WW8FL_NO_GRAFLAYER )
    2388           0 :         return 0;
    2389             : 
    2390         109 :     ::SetProgressState(m_nProgress, m_pDocShell);     // Update
    2391             : 
    2392         109 :     m_nDrawCpO = m_pWwFib->GetBaseCp(m_pPlcxMan->GetManType() == MAN_HDFT ? MAN_TXBX_HDFT : MAN_TXBX);
    2393             : 
    2394         109 :     GrafikCtor();
    2395             : 
    2396         109 :     WW8PLCFspecial* pPF = m_pPlcxMan->GetFdoa();
    2397         109 :     if( !pPF )
    2398             :     {
    2399             :         OSL_ENSURE( false, "Where is the graphic (1) ?" );
    2400           0 :         return 0;
    2401             :     }
    2402             : 
    2403         109 :     if( m_bVer67 )
    2404             :     {
    2405           0 :         long nOldPos = m_pStrm->Tell();
    2406             : 
    2407           0 :         m_nDrawXOfs = m_nDrawYOfs = 0;
    2408           0 :         ReadGrafLayer1( pPF, nGrafAnchorCp );
    2409             : 
    2410           0 :         m_pStrm->Seek( nOldPos );
    2411           0 :         return 0;
    2412             :     }
    2413             : 
    2414             :     // Normal case of Word 8+ version stuff
    2415         109 :     pPF->SeekPos( nGrafAnchorCp );
    2416             : 
    2417             :     WW8_FC nStartFc;
    2418             :     void* pF0;
    2419         109 :     if( !pPF->Get( nStartFc, pF0 ) ){
    2420             :         OSL_ENSURE( false, "+Wo ist die Grafik (2) ?" );
    2421           0 :         return 0;
    2422             :     }
    2423             : 
    2424         109 :     WW8_FSPA_SHADOW* pFS = static_cast<WW8_FSPA_SHADOW*>(pF0);
    2425             :     WW8_FSPA*        pF;
    2426             :     WW8_FSPA aFSFA;
    2427         109 :     pF = &aFSFA;
    2428         109 :     WW8FSPAShadowToReal( pFS, pF );
    2429         109 :     if( !pF->nSpId )
    2430             :     {
    2431             :         OSL_ENSURE( false, "+Wo ist die Grafik (3) ?" );
    2432           0 :         return 0;
    2433             :     }
    2434             : 
    2435         109 :     if (!m_pMSDffManager->GetModel())
    2436           0 :          m_pMSDffManager->SetModel(m_pDrawModel, 1440);
    2437             : 
    2438         109 :     Rectangle aRect(pF->nXaLeft,  pF->nYaTop, pF->nXaRight, pF->nYaBottom);
    2439         109 :     SvxMSDffImportData aData( aRect );
    2440             : 
    2441             :     /*
    2442             :     #i20540#
    2443             :     The SdrOle2Obj will try and manage any ole objects it finds, causing all
    2444             :     sorts of trouble later on
    2445             :     */
    2446         109 :     SwDocShell* pPersist = m_rDoc.GetDocShell();
    2447         109 :     m_rDoc.SetDocShell(0);         // #i20540# Persist guard
    2448             : 
    2449         109 :     SdrObject* pObject = 0;
    2450         109 :     bool bOk = (m_pMSDffManager->GetShape(pF->nSpId, pObject, aData) && pObject);
    2451             : 
    2452         109 :     m_rDoc.SetDocShell(pPersist);  // #i20540# Persist guard
    2453             : 
    2454         109 :     if (!bOk)
    2455             :     {
    2456             :         OSL_ENSURE( false, "Where is the Shape ?" );
    2457           0 :         return 0;
    2458             :     }
    2459             : 
    2460         109 :     bool bDone = false;
    2461         109 :     SdrObject* pOurNewObject = 0;
    2462         109 :     bool bReplaceable = false;
    2463             : 
    2464         109 :     switch (SdrObjKind(pObject->GetObjIdentifier()))
    2465             :     {
    2466             :         case OBJ_GRAF:
    2467          19 :             bReplaceable = true;
    2468          19 :             bDone = true;
    2469          19 :             break;
    2470             :         case OBJ_OLE2:
    2471          11 :             bReplaceable = true;
    2472          11 :             break;
    2473             :         default:
    2474          79 :             break;
    2475             : 
    2476             :     }
    2477             : 
    2478             :     // when in a header or footer word appears to treat all elements as wrap through
    2479             : 
    2480             :     // Umfluss-Modus ermitteln
    2481         109 :     SfxItemSet aFlySet(m_rDoc.GetAttrPool(), RES_FRMATR_BEGIN, RES_FRMATR_END-1);
    2482         109 :     SwSurround eSurround = SURROUND_PARALLEL;
    2483         109 :     bool bContour = false;
    2484         109 :     switch (pF->nwr)
    2485             :     {
    2486             :         case 0: // 0 like 2, but doesn't require absolute object
    2487             :         case 2: // 2 wrap around absolute object
    2488          17 :             eSurround = SURROUND_PARALLEL;
    2489          17 :             break;
    2490             :         case 1: // 1 no text next to shape
    2491           8 :             eSurround = SURROUND_NONE;
    2492           8 :             break;
    2493             :         case 3: // 3 wrap as if no object present
    2494          84 :             eSurround = SURROUND_THROUGHT;
    2495          84 :             break;
    2496             :         case 4: // 4 wrap tightly around object
    2497             :         case 5: // 5 wrap tightly, but allow holes
    2498           0 :             eSurround = SURROUND_PARALLEL;
    2499           0 :             bContour = true;
    2500           0 :             break;
    2501             :     }
    2502             : 
    2503             :     // bei Modus 2 oder 4 auch den Zusatzparameter beruecksichtigen
    2504         109 :     if ( (2 == pF->nwr) || (4 == pF->nwr) )
    2505             :     {
    2506          17 :         switch( pF->nwrk )
    2507             :         {
    2508             :             // 0 wrap both sides
    2509             :             case 0:
    2510           2 :                 eSurround = SURROUND_PARALLEL;
    2511           2 :                 break;
    2512             :             // 1 wrap only on left
    2513             :             case 1:
    2514           0 :                 eSurround = SURROUND_LEFT;
    2515           0 :                 break;
    2516             :             // 2 wrap only on right
    2517             :             case 2:
    2518           0 :                 eSurround = SURROUND_RIGHT;
    2519           0 :                 break;
    2520             :             // 3 wrap only on largest side
    2521             :             case 3:
    2522          15 :                 eSurround = SURROUND_IDEAL;
    2523          15 :                 break;
    2524             :         }
    2525             :     }
    2526             : 
    2527         109 :     SwFormatSurround aSur( eSurround );
    2528         109 :     aSur.SetContour( bContour );
    2529         109 :     aSur.SetOutside(true); // Winword kann nur Aussen-Konturen
    2530         109 :     aFlySet.Put( aSur );
    2531             : 
    2532             :     // eingelesenes Objekt (kann eine ganze Gruppe sein) jetzt korrekt
    2533             :     // positionieren usw.
    2534             : 
    2535             :     OSL_ENSURE(!((aData.size() != 1) && bReplaceable),
    2536             :         "Replaceable drawing with > 1 entries ?");
    2537             : 
    2538         109 :     if (aData.size() != 1)
    2539          15 :         bReplaceable = false;
    2540             : 
    2541         109 :     SvxMSDffImportRec* pRecord = 0;
    2542             :     /*
    2543             :         Get the record for top level object, so we can get the word anchoring
    2544             :         and wrapping information for it.
    2545             :     */
    2546         333 :     for (MSDffImportRecords::const_iterator it = aData.begin();
    2547         222 :             it != aData.end(); ++it) // MSVC2008 wants const_iterator here???
    2548             :     {
    2549         111 :         if (it->pObj == pObject)
    2550             :         {
    2551         109 :             pRecord = &const_cast<SvxMSDffImportRec&>(*it);
    2552         109 :             break;
    2553             :         }
    2554             :     }
    2555             : 
    2556             :     OSL_ENSURE(pRecord, "how did that happen?");
    2557         109 :     if (!pRecord)
    2558           0 :         return 0;
    2559             : 
    2560             :     const bool bLayoutInTableCell =
    2561         109 :         m_nInTable && IsObjectLayoutInTableCell( pRecord->nLayoutInTableCell );
    2562             : 
    2563             :     // #i18732# - Switch on 'follow text flow', if object is laid out
    2564             :     // inside table cell and its wrapping isn't 'SURROUND_THROUGH'
    2565         109 :     if (bLayoutInTableCell && eSurround != SURROUND_THROUGHT)
    2566             :     {
    2567           0 :         SwFormatFollowTextFlow aFollowTextFlow( true );
    2568           0 :         aFlySet.Put( aFollowTextFlow );
    2569             :     }
    2570             : 
    2571             :     // #i21847#
    2572             :     // Some shapes are set to *hidden*, don't import those ones.
    2573         109 :     if (pRecord->bHidden)
    2574           0 :         return 0;
    2575             : 
    2576         109 :     sal_uInt16 nCount = pObject->GetUserDataCount();
    2577         109 :     if(nCount)
    2578             :     {
    2579           0 :         OUString lnName, aObjName, aTarFrm;
    2580           0 :         for (sal_uInt16 i = 0; i < nCount; i++ )
    2581             :         {
    2582           0 :             SdrObjUserData* pData = pObject->GetUserData( i );
    2583           0 :             if( pData && pData->GetInventor() == SW_DRAWLAYER
    2584           0 :                     && pData->GetId() == SW_UD_IMAPDATA)
    2585             :             {
    2586           0 :                 SwMacroInfo* macInf = dynamic_cast<SwMacroInfo*>(pData);
    2587           0 :                 if( macInf )// && macInf->GetShapeId() == pF->nSpId)
    2588             :                 {
    2589           0 :                     sal_Int32 nShapeId = macInf->GetShapeId();
    2590           0 :                     if ( nShapeId ==  pF->nSpId )
    2591             :                     {
    2592           0 :                         lnName = macInf->GetHlink();
    2593           0 :                         aObjName = macInf->GetName();
    2594           0 :                         aTarFrm = macInf->GetTarFrm();
    2595           0 :                         break;
    2596             :                     }
    2597             :                 }
    2598             :             }
    2599             :         }
    2600           0 :         SwFormatURL* pFormatURL = new SwFormatURL();
    2601           0 :         pFormatURL->SetURL( lnName, false );
    2602           0 :         if (!aObjName.isEmpty())
    2603           0 :             pFormatURL->SetName(aObjName);
    2604           0 :         if (!aTarFrm.isEmpty())
    2605           0 :             pFormatURL->SetTargetFrameName(aTarFrm);
    2606           0 :         pFormatURL->SetMap(0);
    2607           0 :         aFlySet.Put(*pFormatURL);
    2608             :     }
    2609             : 
    2610             :     // If we are to be "below text" then we are not to be opaque
    2611             :     // #i14045# MM If we are in a header or footer then make the object transparent
    2612             :     // Not exactly like word but close enough for now
    2613             : 
    2614             :     // both flags <bBelowText> and <bDrawHell> have to be set to move object into the background.
    2615             :     // #i46794# - it reveals that value of flag <bBelowText> can be neglected.
    2616         112 :     const bool bMoveToBackgrd = pRecord->bDrawHell ||
    2617         215 :                                 ( ( m_bIsHeader || m_bIsFooter ) && pF->nwr == 3 );
    2618         109 :     if ( bMoveToBackgrd )
    2619           3 :         aFlySet.Put(SvxOpaqueItem(RES_OPAQUE,false));
    2620             : 
    2621         218 :     OUString aObjName = pObject->GetName();
    2622             : 
    2623         109 :     SwFrameFormat* pRetFrameFormat = 0;
    2624         109 :     if (bReplaceable)
    2625             :     {
    2626             :         // Single graphics or ole objects
    2627             :         pRetFrameFormat = ImportReplaceableDrawables(pObject, pOurNewObject, pRecord,
    2628          30 :             pF, aFlySet);
    2629             :     }
    2630             :     else
    2631             :     {
    2632             :         // Drawing objects, (e.g. ovals or drawing groups)
    2633          79 :         if (pF->bRcaSimple)
    2634             :         {
    2635           0 :             pF->nbx = WW8_FSPA::RelPageBorder;
    2636           0 :             pF->nby = WW8_FSPA::RelPageBorder;
    2637             :         }
    2638             : 
    2639             :         RndStdIds eAnchor = ProcessEscherAlign(pRecord, pF, aFlySet,
    2640          79 :             bReplaceable);
    2641             : 
    2642             :         // Should we, and is it possible to make this into a writer textbox
    2643          79 :         if ((!(m_nIniFlags1 & WW8FL_NO_FLY_FOR_TXBX)) && pRecord->bReplaceByFly)
    2644             :         {
    2645             :             pRetFrameFormat = ConvertDrawTextToFly(pObject, pOurNewObject, pRecord,
    2646          10 :                 eAnchor, pF, aFlySet);
    2647          10 :             if (pRetFrameFormat)
    2648          10 :                 bDone = true;
    2649             :         }
    2650             : 
    2651          79 :         if (!bDone)
    2652             :         {
    2653          69 :             sw::util::SetLayer aSetLayer(m_rDoc);
    2654          69 :             if ( bMoveToBackgrd )
    2655           0 :                 aSetLayer.SendObjectToHell(*pObject);
    2656             :             else
    2657          69 :                 aSetLayer.SendObjectToHeaven(*pObject);
    2658             : 
    2659          69 :             if (!IsInlineEscherHack())
    2660             :             {
    2661             :                 /* Need to make sure that the correct layer ordering is applied. */
    2662             :                 //  pass information, if object is in page header|footer to method.
    2663             :                 m_pWWZOrder->InsertEscherObject( pObject, pF->nSpId,
    2664          66 :                                                m_bIsHeader || m_bIsFooter );
    2665             :             }
    2666             :             else
    2667             :             {
    2668           3 :                 m_pWWZOrder->InsertTextLayerObject(pObject);
    2669             :             }
    2670             : 
    2671          69 :             pRetFrameFormat = m_rDoc.getIDocumentContentOperations().InsertDrawObj(*m_pPaM, *pObject, aFlySet );
    2672             : 
    2673             :             OSL_ENSURE(pRetFrameFormat->GetAnchor().GetAnchorId() ==
    2674             :                 eAnchor, "Not the anchor type requested!");
    2675             : 
    2676             :             /*
    2677             :                 Insert text if necessary into textboxes contained in groups.
    2678             :             */
    2679          69 :             if (!aData.empty())
    2680             :             {
    2681         966 :                 for (MSDffImportRecords::const_iterator it = aData.begin();
    2682         644 :                         it != aData.end(); ++it)
    2683             :                 {
    2684         253 :                     pRecord = &const_cast<SvxMSDffImportRec&>(*it);
    2685         253 :                     if (pRecord->pObj && pRecord->aTextId.nTxBxS)
    2686             :                     { // #i52825# pRetFrameFormat can be NULL
    2687             :                         pRetFrameFormat = MungeTextIntoDrawBox(pRecord->pObj,
    2688          70 :                             pRecord, nGrafAnchorCp, pRetFrameFormat);
    2689             :                     }
    2690             :                 }
    2691             :             }
    2692             :         }
    2693             :     }
    2694             : 
    2695             :     // #i44344#, #i44681# - positioning attributes already set
    2696         109 :     if ( pRetFrameFormat /*#i52825# */ && pRetFrameFormat->ISA(SwDrawFrameFormat) )
    2697             :     {
    2698          69 :         static_cast<SwDrawFrameFormat*>(pRetFrameFormat)->PosAttrSet();
    2699             :     }
    2700         109 :     if (!IsInlineEscherHack())
    2701         106 :         MapWrapIntoFlyFormat(pRecord, pRetFrameFormat);
    2702             : 
    2703             :     // Set frame name with object name
    2704         109 :     if( pRetFrameFormat /*#i52825# */ && !aObjName.isEmpty() )
    2705           3 :         pRetFrameFormat->SetName( aObjName );
    2706         218 :     return AddAutoAnchor(pRetFrameFormat);
    2707             : }
    2708             : 
    2709         134 : SwFrameFormat *SwWW8ImplReader::AddAutoAnchor(SwFrameFormat *pFormat)
    2710             : {
    2711             :     /*
    2712             :      * anchored to character at the current position will move along the
    2713             :      * paragraph as text is added because we are at the insertion point.
    2714             :      *
    2715             :      * Leave to later and set the correct location then.
    2716             :      */
    2717         134 :     if ((pFormat) && (pFormat->GetAnchor().GetAnchorId() != FLY_AS_CHAR))
    2718             :     {
    2719         107 :         m_pAnchorStck->AddAnchor(*m_pPaM->GetPoint(), pFormat);
    2720             :     }
    2721         134 :     return pFormat;
    2722             : }
    2723             : 
    2724          70 : SwFrameFormat* SwWW8ImplReader::MungeTextIntoDrawBox(SdrObject* pTrueObject,
    2725             :     SvxMSDffImportRec *pRecord, long nGrafAnchorCp, SwFrameFormat* pRetFrameFormat)
    2726             : {
    2727             :     SdrTextObj* pSdrTextObj;
    2728             : 
    2729             :     // Pruefen, ob Gruppenobjekt (z.B. zwei Klammern) vorliegt
    2730          70 :     if (SdrObjGroup* pThisGroup = PTR_CAST(SdrObjGroup, pRecord->pObj))
    2731             :     {
    2732             :         // Gruppenobjekte haben keinen Text. Fuege ein Textobjekt in die
    2733             :         // Gruppe ein, um den Text zu halten.
    2734           0 :         pSdrTextObj = new SdrRectObj( OBJ_TEXT, pThisGroup->GetCurrentBoundRect());
    2735             : 
    2736           0 :         SfxItemSet aSet(m_pDrawModel->GetItemPool());
    2737           0 :         aSet.Put(XFillStyleItem(drawing::FillStyle_NONE));
    2738           0 :         aSet.Put(XLineStyleItem(drawing::LineStyle_NONE));
    2739           0 :         aSet.Put(SdrTextFitToSizeTypeItem( SDRTEXTFIT_NONE ));
    2740           0 :         aSet.Put(makeSdrTextAutoGrowHeightItem(false));
    2741           0 :         aSet.Put(makeSdrTextAutoGrowWidthItem(false));
    2742           0 :         pSdrTextObj->SetMergedItemSet(aSet);
    2743             : 
    2744           0 :         long nAngle = pRecord->nTextRotationAngle;
    2745           0 :         if ( nAngle )
    2746             :         {
    2747           0 :             double a = nAngle*nPi180;
    2748           0 :             pSdrTextObj->NbcRotate(pSdrTextObj->GetCurrentBoundRect().Center(), nAngle,
    2749           0 :                 sin(a), cos(a) );
    2750             :         }
    2751             : 
    2752           0 :         pSdrTextObj->NbcSetLayer( pThisGroup->GetLayer() );
    2753           0 :         pThisGroup->GetSubList()->NbcInsertObject(pSdrTextObj);
    2754             :     }
    2755             :     else
    2756          70 :         pSdrTextObj = PTR_CAST(SdrTextObj, pRecord->pObj);
    2757             : 
    2758          70 :     if( pSdrTextObj )
    2759             :     {
    2760          70 :         Size aObjSize(pSdrTextObj->GetSnapRect().GetWidth(),
    2761         140 :             pSdrTextObj->GetSnapRect().GetHeight());
    2762             : 
    2763             :         // Objekt ist Bestandteil einer Gruppe?
    2764          70 :         SdrObject* pGroupObject = pSdrTextObj->GetUpGroup();
    2765             : 
    2766          70 :         const size_t nOrdNum = pSdrTextObj->GetOrdNum();
    2767             :         bool bEraseThisObject;
    2768             :         InsertTxbxText( pSdrTextObj, &aObjSize, pRecord->aTextId.nTxBxS,
    2769             :             pRecord->aTextId.nSequence, nGrafAnchorCp, pRetFrameFormat,
    2770          70 :             (pSdrTextObj != pTrueObject) || (0 != pGroupObject),
    2771          70 :             bEraseThisObject, 0, 0, 0, 0, pRecord);
    2772             : 
    2773             :         // wurde dieses Objekt ersetzt ??
    2774          70 :         if (bEraseThisObject)
    2775             :         {
    2776           0 :             if( pGroupObject || (pSdrTextObj != pTrueObject) )
    2777             :             {
    2778             :                 // Objekt wurde bereits (in der Gruppe und) der Drawing-Page
    2779             :                 // durch ein neues SdrGrafObj ersetzt.
    2780             : 
    2781             :                 SdrObject* pNewObj = pGroupObject ?
    2782           0 :                     pGroupObject->GetSubList()->GetObj(nOrdNum) : pTrueObject;
    2783           0 :                 if (pSdrTextObj != pNewObj)
    2784             :                 {
    2785             :                     // Objekt in der Z-Order-Liste ersetzen
    2786           0 :                     m_pMSDffManager->ExchangeInShapeOrder(pSdrTextObj, 0,0, pNewObj);
    2787             :                     // Objekt jetzt noch loeschen
    2788           0 :                     SdrObject::Free( pRecord->pObj );
    2789             :                     // und das neue Objekt merken.
    2790           0 :                     pRecord->pObj = pNewObj;
    2791           0 :                 }
    2792             :             }
    2793             :             else
    2794             :             {
    2795             :                 // Objekt aus der Z-Order-Liste loeschen
    2796           0 :                 m_pMSDffManager->RemoveFromShapeOrder( pSdrTextObj );
    2797             :                 // Objekt aus der Drawing-Page rausnehmen
    2798           0 :                 if( pSdrTextObj->GetPage() )
    2799           0 :                     m_pDrawPg->RemoveObject( pSdrTextObj->GetOrdNum() );
    2800             :                 // und FrameFormat entfernen, da durch Grafik ersetzt (dies
    2801             :                 // loescht auch das Objekt)
    2802           0 :                 m_rDoc.DelFrameFormat( pRetFrameFormat );
    2803           0 :                 pRetFrameFormat = 0;
    2804             :                 // auch den Objektmerker loeschen
    2805           0 :                 pRecord->pObj = 0;
    2806             :             }
    2807             :         }
    2808             :         else
    2809             :         {
    2810             :             // ww8-default Randabstand einsetzen
    2811          70 :             SfxItemSet aItemSet(m_pDrawModel->GetItemPool(),
    2812          70 :                 SDRATTR_TEXT_LEFTDIST, SDRATTR_TEXT_LOWERDIST);
    2813          70 :             aItemSet.Put( makeSdrTextLeftDistItem( pRecord->nDxTextLeft ) );
    2814          70 :             aItemSet.Put( makeSdrTextRightDistItem( pRecord->nDxTextRight  ) );
    2815          70 :             aItemSet.Put( makeSdrTextUpperDistItem( pRecord->nDyTextTop    ) );
    2816          70 :             aItemSet.Put( makeSdrTextLowerDistItem( pRecord->nDyTextBottom ) );
    2817          70 :             pSdrTextObj->SetMergedItemSetAndBroadcast(aItemSet);
    2818             :         }
    2819             :     }
    2820          70 :     return pRetFrameFormat;
    2821             : }
    2822             : 
    2823          10 : SwFlyFrameFormat* SwWW8ImplReader::ConvertDrawTextToFly(SdrObject* &rpObject,
    2824             :     SdrObject* &rpOurNewObject, SvxMSDffImportRec* pRecord, RndStdIds eAnchor,
    2825             :     WW8_FSPA *pF, SfxItemSet &rFlySet)
    2826             : {
    2827          10 :     SwFlyFrameFormat* pRetFrameFormat = 0;
    2828             :     long nStartCp;
    2829             :     long nEndCp;
    2830             : 
    2831             :     // Check if this textbox chain contains text as conversion of an empty
    2832             :     // chain would not make sense.
    2833          10 :     if ( TxbxChainContainsRealText(pRecord->aTextId.nTxBxS,nStartCp,nEndCp) )
    2834             :     {
    2835             :         // The Text is not read into SdrTextObj!  Rather insert a frame and
    2836             :         // insert the text from nStartCp to nEndCp.
    2837             : 
    2838             :         // More attributes can be used in a frame compared to the
    2839             :         // Edit-Engine, and it can contain field, OLEs or graphics...
    2840             :         Rectangle aInnerDist(pRecord->nDxTextLeft, pRecord->nDyTextTop,
    2841          10 :             pRecord->nDxTextRight, pRecord->nDyTextBottom);
    2842             : 
    2843          10 :         SwFormatFrmSize aFrmSize(ATT_FIX_SIZE, pF->nXaRight - pF->nXaLeft, pF->nYaBottom - pF->nYaTop);
    2844          10 :         aFrmSize.SetWidthSizeType(pRecord->bAutoWidth ? ATT_VAR_SIZE : ATT_FIX_SIZE);
    2845          10 :         rFlySet.Put(aFrmSize);
    2846             : 
    2847             :         MatchSdrItemsIntoFlySet( rpObject, rFlySet, pRecord->eLineStyle,
    2848          10 :             pRecord->eLineDashing, pRecord->eShapeType, aInnerDist );
    2849             : 
    2850          10 :         SdrTextObj *pSdrTextObj = dynamic_cast<SdrTextObj*>(rpObject);
    2851          10 :         if (pSdrTextObj && pSdrTextObj->IsVerticalWriting())
    2852           0 :             rFlySet.Put(SvxFrameDirectionItem(FRMDIR_VERT_TOP_RIGHT, RES_FRAMEDIR));
    2853             : 
    2854          10 :         pRetFrameFormat = m_rDoc.MakeFlySection(eAnchor, m_pPaM->GetPoint(), &rFlySet);
    2855             :         OSL_ENSURE(pRetFrameFormat->GetAnchor().GetAnchorId() == eAnchor,
    2856             :             "Not the anchor type requested!");
    2857             : 
    2858             :         // if everything is OK, find pointer on new object and correct
    2859             :         // Z-order list (oder delete entry)
    2860          10 :         rpOurNewObject = CreateContactObject(pRetFrameFormat);
    2861             : 
    2862             :         // remove old object from the Z-Order list
    2863          10 :         m_pMSDffManager->RemoveFromShapeOrder( rpObject );
    2864             : 
    2865             :         // and delete the object
    2866          10 :         SdrObject::Free( rpObject );
    2867             :         /*
    2868             :             NB: only query pOrgShapeObject starting here!
    2869             :         */
    2870             : 
    2871          10 :         if (rpOurNewObject)
    2872             :         {
    2873             :             /*
    2874             :             We do not store our rpOutNewObject in the ShapeOrder because we
    2875             :             have a FrameFormat from which we can regenerate the contact object when
    2876             :             we need it. Because, we can have frames anchored to paragraphs in
    2877             :             header/footers and we can copy header/footers, if we do copy a
    2878             :             header/footer with a nonpage anchored frame in it then the contact
    2879             :             objects are invalidated. Under this condition the FrameFormat will be
    2880             :             updated to reflect this change and can be used to get a new
    2881             :             contact object, while a raw rpOutNewObject stored here becomes
    2882             :             deleted and useless.
    2883             :             */
    2884             :             m_pMSDffManager->StoreShapeOrder(pF->nSpId,
    2885          10 :                 (((sal_uLong)pRecord->aTextId.nTxBxS) << 16) +
    2886          10 :                 pRecord->aTextId.nSequence, 0, pRetFrameFormat);
    2887             : 
    2888             :             // The Contact object has to be inserted into the draw page, so
    2889             :             // SwWW8ImplReader::LoadDoc1() can determine the z-order.
    2890          10 :             if (!rpOurNewObject->IsInserted())
    2891             :             {
    2892             :                 // pass information, if object is in page header|footer to method.
    2893             :                 m_pWWZOrder->InsertEscherObject( rpOurNewObject, pF->nSpId,
    2894          10 :                                                m_bIsHeader || m_bIsFooter );
    2895             :             }
    2896             :         }
    2897             : 
    2898             :         // Box-0 receives the text for the whole chain!
    2899          10 :         if( !pRecord->aTextId.nSequence )
    2900             :         {
    2901             :             // save flags etc and reset them
    2902          10 :             WW8ReaderSave aSave( this );
    2903             : 
    2904          10 :             MoveInsideFly(pRetFrameFormat);
    2905             : 
    2906          20 :             SwNodeIndex aStart(m_pPaM->GetPoint()->nNode);
    2907             : 
    2908          10 :             m_pWWZOrder->InsideEscher(pF->nSpId);
    2909             : 
    2910             :             // read in the text
    2911          10 :             m_bTxbxFlySection = true;
    2912             :             bool bJoined = ReadText(nStartCp, (nEndCp-nStartCp),
    2913          10 :                 MAN_MAINTEXT == m_pPlcxMan->GetManType() ?
    2914          10 :                         MAN_TXBX : MAN_TXBX_HDFT);
    2915             : 
    2916          10 :             m_pWWZOrder->OutsideEscher();
    2917             : 
    2918          10 :             MoveOutsideFly(pRetFrameFormat, aSave.GetStartPos(),!bJoined);
    2919             : 
    2920          10 :             aSave.Restore( this );
    2921             : 
    2922          20 :             StripNegativeAfterIndent(pRetFrameFormat);
    2923          10 :         }
    2924             : 
    2925             :     }
    2926          10 :     return pRetFrameFormat;
    2927             : }
    2928             : 
    2929          54 : void MatchEscherMirrorIntoFlySet(const SvxMSDffImportRec &rRecord,
    2930             :     SfxItemSet &rFlySet)
    2931             : {
    2932          54 :     if (rRecord.bVFlip || rRecord.bHFlip)
    2933             :     {
    2934           0 :         MirrorGraph eType(RES_MIRROR_GRAPH_DONT);
    2935           0 :         if (rRecord.bVFlip && rRecord.bHFlip)
    2936           0 :             eType = RES_MIRROR_GRAPH_BOTH;
    2937           0 :         else if (rRecord.bVFlip)
    2938           0 :             eType = RES_MIRROR_GRAPH_HOR;
    2939             :         else
    2940           0 :             eType = RES_MIRROR_GRAPH_VERT;
    2941           0 :         rFlySet.Put( SwMirrorGrf(eType) );
    2942             :     }
    2943          54 : }
    2944             : 
    2945          30 : SwFlyFrameFormat* SwWW8ImplReader::ImportReplaceableDrawables( SdrObject* &rpObject,
    2946             :     SdrObject* &rpOurNewObject, SvxMSDffImportRec* pRecord, WW8_FSPA *pF,
    2947             :     SfxItemSet &rFlySet )
    2948             : {
    2949          30 :     SwFlyFrameFormat* pRetFrameFormat = 0;
    2950          30 :     long nWidthTw  = pF->nXaRight - pF->nXaLeft;
    2951          30 :     if (0 > nWidthTw)
    2952           0 :         nWidthTw = 0;
    2953          30 :     long nHeightTw = pF->nYaBottom - pF->nYaTop;
    2954          30 :     if (0 > nHeightTw)
    2955           0 :         nHeightTw = 0;
    2956             : 
    2957          30 :     ProcessEscherAlign(pRecord, pF, rFlySet, true);
    2958             : 
    2959          30 :     rFlySet.Put(SwFormatFrmSize(ATT_FIX_SIZE, nWidthTw, nHeightTw));
    2960             : 
    2961          30 :     SfxItemSet aGrSet(m_rDoc.GetAttrPool(), RES_GRFATR_BEGIN, RES_GRFATR_END-1);
    2962             : 
    2963          30 :     if (pRecord)
    2964             :     {
    2965             :         // Note that the escher inner distance only seems to be honoured in
    2966             :         // word for textboxes, not for graphics and ole objects.
    2967          30 :         Rectangle aInnerDist(0, 0, 0, 0);
    2968             : 
    2969             :         MatchSdrItemsIntoFlySet(rpObject, rFlySet, pRecord->eLineStyle,
    2970          30 :             pRecord->eLineDashing, pRecord->eShapeType, aInnerDist);
    2971             : 
    2972          30 :         MatchEscherMirrorIntoFlySet(*pRecord, aGrSet);
    2973             :     }
    2974             : 
    2975          60 :     OUString aObjectName(rpObject->GetName());
    2976          30 :     if (OBJ_OLE2 == SdrObjKind(rpObject->GetObjIdentifier()))
    2977          11 :         pRetFrameFormat = InsertOle(*static_cast<SdrOle2Obj*>(rpObject), rFlySet, aGrSet);
    2978             :     else
    2979             :     {
    2980          19 :         const SdrGrafObj *pGrf = static_cast<const SdrGrafObj*>(rpObject);
    2981          19 :         bool bDone = false;
    2982          19 :         if (pGrf->IsLinkedGraphic() && !pGrf->GetFileName().isEmpty())
    2983             :         {
    2984           1 :             GraphicType eType = pGrf->GetGraphicType();
    2985             :             OUString aGrfName(
    2986             :                 URIHelper::SmartRel2Abs(
    2987           1 :                     INetURLObject(m_sBaseURL), pGrf->GetFileName(),
    2988           2 :                     URIHelper::GetMaybeFileHdl()));
    2989             :             // correction of fix for issue #i10939#:
    2990             :             // One of the two conditions have to be true to insert the graphic
    2991             :             // as a linked graphic -
    2992           1 :             if (GRAPHIC_NONE == eType || CanUseRemoteLink(aGrfName))
    2993             :             {
    2994           1 :                 pRetFrameFormat = m_rDoc.getIDocumentContentOperations().Insert(*m_pPaM, aGrfName, OUString(), 0,
    2995           1 :                     &rFlySet, &aGrSet, NULL);
    2996           1 :                 bDone = true;
    2997           1 :             }
    2998             :         }
    2999          19 :         if (!bDone)
    3000             :         {
    3001          18 :             const Graphic& rGraph = pGrf->GetGraphic();
    3002          18 :             pRetFrameFormat = m_rDoc.getIDocumentContentOperations().Insert(*m_pPaM, OUString(), OUString(), &rGraph,
    3003          18 :                 &rFlySet, &aGrSet, NULL);
    3004             :         }
    3005             :     }
    3006             : 
    3007          30 :     if (pRetFrameFormat)
    3008             :     {
    3009          30 :         if( pRecord )
    3010             :         {
    3011          30 :             if( OBJ_OLE2 != SdrObjKind(rpObject->GetObjIdentifier()) )
    3012          19 :                 SetAttributesAtGrfNode( pRecord, pRetFrameFormat, pF );
    3013             :         }
    3014             :         // mehrfaches Auftreten gleicher Grafik-Namen vermeiden
    3015          30 :         m_aGrfNameGenerator.SetUniqueGraphName(pRetFrameFormat, aObjectName);
    3016             :     }
    3017             :     // falls alles Ok, Zeiger auf neues Objekt ermitteln und Z-Order-Liste
    3018             :     // entsprechend korrigieren (oder Eintrag loeschen)
    3019          30 :     rpOurNewObject = CreateContactObject(pRetFrameFormat);
    3020             : 
    3021             :     // altes Objekt aus der Z-Order-Liste entfernen
    3022          30 :     m_pMSDffManager->RemoveFromShapeOrder( rpObject );
    3023             :     // aus der Drawing-Page rausnehmen
    3024          30 :     if( rpObject->GetPage() )
    3025           0 :         m_pDrawPg->RemoveObject( rpObject->GetOrdNum() );
    3026             : 
    3027             :     // und das Objekt loeschen
    3028          30 :     SdrObject::Free( rpObject );
    3029             :     /*
    3030             :         Achtung: ab jetzt nur noch pOrgShapeObject abfragen!
    3031             :     */
    3032             : 
    3033             :     // Kontakt-Objekt in die Z-Order-Liste und die Page aufnehmen
    3034          30 :     if (rpOurNewObject)
    3035             :     {
    3036          30 :         if (!m_bHdFtFootnoteEdn)
    3037          27 :             m_pMSDffManager->StoreShapeOrder(pF->nSpId, 0, rpOurNewObject, 0 );
    3038             : 
    3039             :         // Das Kontakt-Objekt MUSS in die Draw-Page gesetzt werden, damit in
    3040             :         // SwWW8ImplReader::LoadDoc1() die Z-Order festgelegt werden kann !!!
    3041          30 :         if (!rpOurNewObject->IsInserted())
    3042             :         {
    3043             :             // pass information, if object is in page header|footer to method.
    3044             :             m_pWWZOrder->InsertEscherObject( rpOurNewObject, pF->nSpId,
    3045          30 :                                            m_bIsHeader || m_bIsFooter );
    3046             :         }
    3047             :     }
    3048          60 :     return pRetFrameFormat;
    3049             : }
    3050             : 
    3051         283 : void SwWW8ImplReader::GrafikCtor()  // Fuer SVDraw und VCControls und Escher
    3052             : {
    3053         283 :     if (!m_pDrawModel)
    3054             :     {
    3055          73 :         m_rDoc.getIDocumentDrawModelAccess().GetOrCreateDrawModel(); // #i52858# - method name changed
    3056          73 :         m_pDrawModel  = m_rDoc.getIDocumentDrawModelAccess().GetDrawModel();
    3057             :         OSL_ENSURE(m_pDrawModel, "Kann DrawModel nicht anlegen");
    3058          73 :         m_pDrawPg = m_pDrawModel->GetPage(0);
    3059             : 
    3060          73 :         m_pMSDffManager = new SwMSDffManager(*this, m_bSkipImages);
    3061          73 :         m_pMSDffManager->SetModel(m_pDrawModel, 1440);
    3062             :         /*
    3063             :          Now the dff manager always needs a controls // converter as well, but a
    3064             :          control converter may still exist // without a dffmanager. cmc
    3065             :         */
    3066          73 :         m_pFormImpl = new SwMSConvertControls(m_pDocShell, m_pPaM);
    3067             : 
    3068             :         m_pWWZOrder = new wwZOrderer(sw::util::SetLayer(m_rDoc), m_pDrawPg,
    3069          73 :             m_pMSDffManager->GetShapeOrders());
    3070             :     }
    3071         283 : }
    3072             : 
    3073         125 : void SwWW8ImplReader::GrafikDtor()
    3074             : {
    3075         125 :     DELETEZ(m_pDrawEditEngine); // evtl. von Grafik angelegt
    3076         125 :     DELETEZ(m_pWWZOrder);       // dito
    3077         125 : }
    3078             : 
    3079         114 : void SwWW8FltAnchorStack::AddAnchor(const SwPosition& rPos, SwFrameFormat *pFormat)
    3080             : {
    3081             :     OSL_ENSURE(pFormat->GetAnchor().GetAnchorId() != FLY_AS_CHAR,
    3082             :         "Don't use fltanchors with inline frames, slap!");
    3083         114 :     NewAttr(rPos, SwFltAnchor(pFormat));
    3084         114 : }
    3085             : 
    3086        3090 : void SwWW8FltAnchorStack::Flush()
    3087             : {
    3088        3090 :     size_t nCnt = size();
    3089        3204 :     for (size_t i=0; i < nCnt; ++i)
    3090             :     {
    3091         114 :         SwFltStackEntry &rEntry = (*this)[i];
    3092         114 :         SwPosition aDummy(rEntry.m_aMkPos.m_nNode);
    3093         114 :         SetAttrInDoc(aDummy, rEntry);
    3094         114 :         DeleteAndDestroy(i--);
    3095         114 :         --nCnt;
    3096         114 :     }
    3097        3150 : }
    3098             : 
    3099             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11