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

Generated by: LCOV version 1.10