xref: /trunk/main/sw/source/filter/ww8/ww8graf2.cxx (revision 870262e3)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
27 
28 
29 #include <iterator>
30 #include <hintids.hxx>
31 #include <svl/urihelper.hxx>
32 #include <svx/svdpage.hxx>
33 #include <svx/svdmodel.hxx>
34 #include <svx/svdograf.hxx>
35 #include <svx/svdoole2.hxx>
36 #include <editeng/opaqitem.hxx>
37 #include <filter/msfilter/msdffimp.hxx>
38 #include <sfx2/app.hxx>
39 #include <sfx2/docfile.hxx>
40 #include <sfx2/fcontnr.hxx>
41 #include <grfatr.hxx>           // class SwCropGrf
42 #include <fmtflcnt.hxx>
43 #include <fmtanchr.hxx>
44 #include <frmfmt.hxx>
45 #include <fltshell.hxx>
46 #include <pam.hxx>
47 #include <doc.hxx>
48 #include <ndtxt.hxx>            // class SwTxtNode
49 #include <mdiexp.hxx>           // Progress
50 #include "writerwordglue.hxx"
51 #include "ww8struc.hxx"
52 #include "ww8scan.hxx"
53 #include "ww8par.hxx"           // class SwWWImplReader
54 #include "ww8par2.hxx"          // struct WWFlyPara
55 #include "ww8graf.hxx"
56 #include <svtools/filter.hxx>
57 
58 using namespace ::com::sun::star;
59 using namespace sw::types;
60 
wwZOrderer(const sw::util::SetLayer & rSetLayer,SdrPage * pDrawPg,const SvxMSDffShapeOrders * pShapeOrders)61 wwZOrderer::wwZOrderer(const sw::util::SetLayer &rSetLayer, SdrPage* pDrawPg,
62     const SvxMSDffShapeOrders *pShapeOrders)
63     : maSetLayer(rSetLayer), mnInlines(0), mpDrawPg(pDrawPg),
64     mpShapeOrders(pShapeOrders)
65 {
66     mnNoInitialObjects = mpDrawPg->GetObjCount();
67     ASSERT(mpDrawPg,"Missing draw page impossible!");
68 }
69 
InsideEscher(sal_uLong nSpId)70 void wwZOrderer::InsideEscher(sal_uLong nSpId)
71 {
72     maIndexes.push(GetEscherObjectIdx(nSpId));
73 }
74 
OutsideEscher()75 void wwZOrderer::OutsideEscher()
76 {
77     maIndexes.pop();
78 }
79 
80 // --> OD 2004-12-13 #117915# - consider new parameter <_bInHeaderFooter>
InsertEscherObject(SdrObject * pObject,sal_uLong nSpId,const bool _bInHeaderFooter)81 void wwZOrderer::InsertEscherObject( SdrObject* pObject,
82                                      sal_uLong nSpId,
83                                      const bool _bInHeaderFooter )
84 {
85     sal_uLong nInsertPos = GetEscherObjectPos( nSpId, _bInHeaderFooter );
86 // <--
87     InsertObject(pObject, nInsertPos + mnNoInitialObjects + mnInlines);
88 }
89 
MapEscherIdxToIter(sal_uLong nIdx)90 wwZOrderer::myeiter wwZOrderer::MapEscherIdxToIter(sal_uLong nIdx)
91 {
92     myeiter aIter = maEscherLayer.begin();
93     myeiter aEnd = maEscherLayer.end();
94     while (aIter != aEnd)
95     {
96         if (aIter->mnEscherShapeOrder == nIdx)
97             break;
98         ++aIter;
99     }
100     return aIter;
101 }
102 
GetEscherObjectIdx(sal_uLong nSpId)103 sal_uInt16 wwZOrderer::GetEscherObjectIdx(sal_uLong nSpId)
104 {
105     sal_uInt16 nFound=0;
106     sal_uInt16 nShapeCount = mpShapeOrders ? mpShapeOrders->Count() : 0;
107     // First, find out what position this shape is in in the Escher order.
108     for (sal_uInt16 nShapePos=0; nShapePos < nShapeCount; nShapePos++)
109     {
110         const SvxMSDffShapeOrder *pOrder = mpShapeOrders->GetObject(nShapePos);
111         if (pOrder->nShapeId == nSpId)
112         {
113             nFound = nShapePos;
114             break;
115         }
116     }
117     return nFound;
118 }
119 
120 // --> OD 2004-12-13 #117915# - consider new parameter <_bInHeaderFooter>
GetEscherObjectPos(sal_uLong nSpId,const bool _bInHeaderFooter)121 sal_uLong wwZOrderer::GetEscherObjectPos( sal_uLong nSpId,
122                                       const bool _bInHeaderFooter )
123 {
124     /*
125     #97824# EscherObjects have their own ordering which needs to be matched to
126     the actual ordering that should be used when inserting them into the
127     document.
128     */
129     sal_uInt16 nFound = GetEscherObjectIdx(nSpId);
130     // Match the ordering position from the ShapeOrders to the ordering of all
131     // objects in the document, there is a complexity when escherobjects
132     // contain inlines objects, we need to consider thsose as part of the
133     // escher count
134     sal_uLong nRet=0;
135     myeiter aIter = maEscherLayer.begin();
136     myeiter aEnd = maEscherLayer.end();
137     // --> OD 2004-12-13 #117915# - skip objects in page header|footer, if
138     // current object isn't in page header|footer
139     if ( !_bInHeaderFooter )
140     {
141         while ( aIter != aEnd )
142         {
143             if ( !aIter->mbInHeaderFooter )
144             {
145                 break;
146             }
147             nRet += aIter->mnNoInlines + 1;
148             ++aIter;
149         }
150     }
151     // <--
152     while (aIter != aEnd)
153     {
154         // --> OD 2004-12-13 #117915# - insert object in page header|footer
155         // before objects in page body
156         if ( _bInHeaderFooter && !aIter->mbInHeaderFooter )
157         {
158             break;
159         }
160         // <--
161         if ( aIter->mnEscherShapeOrder > nFound )
162             break;
163         nRet += aIter->mnNoInlines+1;
164         ++aIter;
165     }
166     maEscherLayer.insert(aIter, EscherShape( nFound, _bInHeaderFooter ) );
167     return nRet;
168 }
169 // <--
170 
171 // InsertObj() fuegt das Objekt in die Sw-Page ein und merkt sich die Z-Pos in
172 // einem VarArr
InsertDrawingObject(SdrObject * pObj,short nWwHeight)173 void wwZOrderer::InsertDrawingObject(SdrObject* pObj, short nWwHeight)
174 {
175     sal_uLong nPos = GetDrawingObjectPos(nWwHeight);
176     if (nWwHeight & 0x2000)                 // Heaven ?
177         maSetLayer.SendObjectToHeaven(*pObj);
178     else
179         maSetLayer.SendObjectToHell(*pObj);
180 
181     InsertObject(pObj, nPos + mnNoInitialObjects + mnInlines);
182 }
183 
InsertTextLayerObject(SdrObject * pObject)184 void wwZOrderer::InsertTextLayerObject(SdrObject* pObject)
185 {
186     maSetLayer.SendObjectToHeaven(*pObject);
187     if (maIndexes.empty())
188     {
189         InsertObject(pObject, mnNoInitialObjects + mnInlines);
190         ++mnInlines;
191     }
192     else
193     {
194         //If we are inside an escher objects, place us just after that
195         //escher obj, and increment its inline count
196         sal_uInt16 nIdx = maIndexes.top();
197         myeiter aEnd = MapEscherIdxToIter(nIdx);
198 
199         sal_uLong nInsertPos=0;
200         myeiter aIter = maEscherLayer.begin();
201         while (aIter != aEnd)
202         {
203             nInsertPos += aIter->mnNoInlines+1;
204             ++aIter;
205         }
206 
207         ASSERT(aEnd != maEscherLayer.end(), "Something very wrong here");
208         if (aEnd != maEscherLayer.end())
209         {
210             aEnd->mnNoInlines++;
211             nInsertPos += aEnd->mnNoInlines;
212         }
213 
214         InsertObject(pObject, mnNoInitialObjects + mnInlines + nInsertPos);
215     }
216 }
217 
218 // Parallel zu dem Obj-Array im Dokument baue ich ein Array auf,
219 // dass die Ww-Height ( -> Wer ueberdeckt wen ) beinhaltet.
220 // Anhand dieses VARARR wird die Einfuegeposition ermittelt.
221 // Der Offset bei Datei in bestehendes Dokument mit Grafiklayer einfuegen
222 // muss der Aufrufer den Index um mnNoInitialObjects erhoeht werden, damit die
223 // neuen Objekte am Ende landen ( Einfuegen ist dann schneller )
GetDrawingObjectPos(short nWwHeight)224 sal_uLong wwZOrderer::GetDrawingObjectPos(short nWwHeight)
225 {
226     myditer aIter = maDrawHeight.begin();
227     myditer aEnd = maDrawHeight.end();
228 
229     while (aIter != aEnd)
230     {
231         if ((*aIter & 0x1fff) > (nWwHeight & 0x1fff))
232             break;
233         ++aIter;
234     }
235 
236     aIter = maDrawHeight.insert(aIter, nWwHeight);
237     return std::distance(maDrawHeight.begin(), aIter);
238 }
239 
InsertObject(SdrObject * pObject,sal_uLong nPos)240 bool wwZOrderer::InsertObject(SdrObject* pObject, sal_uLong nPos)
241 {
242     if (!pObject->IsInserted())
243     {
244         mpDrawPg->InsertObject(pObject, nPos);
245         return true;
246     }
247     return false;
248 }
249 
250 #ifdef __WW8_NEEDS_COPY
251 extern void WW8PicShadowToReal(  WW8_PIC_SHADOW*  pPicS,  WW8_PIC*  pPic );
252 #endif // defined __WW8_NEEDS_COPY
253 
GetPictGrafFromStream(Graphic & rGraphic,SvStream & rSrc)254 bool SwWW8ImplReader::GetPictGrafFromStream(Graphic& rGraphic, SvStream& rSrc)
255 {
256     return 0 == GraphicFilter::GetGraphicFilter()->ImportGraphic(rGraphic, aEmptyStr, rSrc,
257         GRFILTER_FORMAT_DONTKNOW);
258 }
259 
ReadGrafFile(String & rFileName,Graphic * & rpGraphic,const WW8_PIC & rPic,SvStream * pSt,sal_uLong nFilePos,bool * pbInDoc)260 bool SwWW8ImplReader::ReadGrafFile(String& rFileName, Graphic*& rpGraphic,
261     const WW8_PIC& rPic, SvStream* pSt, sal_uLong nFilePos, bool* pbInDoc)
262 {                                                  // Grafik in File schreiben
263     *pbInDoc = true;                               // default
264 
265     sal_uLong nPosFc = nFilePos + rPic.cbHeader;
266 
267     switch (rPic.MFP.mm)
268     {
269         case 94: // BMP-File ( nicht embeddet ) oder GIF
270         case 99: // TIFF-File ( nicht embeddet )
271             pSt->Seek(nPosFc);
272             // Name als P-String einlesen
273             rFileName = WW8ReadPString(*pSt, eStructCharSet, 0);
274             if (rFileName.Len())
275                 rFileName = URIHelper::SmartRel2Abs(
276                     INetURLObject(sBaseURL), rFileName,
277                     URIHelper::GetMaybeFileHdl());
278             *pbInDoc = false;       // Datei anschliessend nicht loeschen
279             return rFileName.Len() != 0;        // Einlesen OK
280     }
281 
282     GDIMetaFile aWMF;
283     pSt->Seek( nPosFc );
284     bool bOk = ReadWindowMetafile( *pSt, aWMF, NULL ) ? true : false;
285 
286     if (!bOk || pSt->GetError() || !aWMF.GetActionCount())
287         return false;
288 
289     if (pWwFib->envr != 1) // !MAC als Creator
290     {
291 
292 /* SJ: #i40742#, we will use the prefsize from the mtf directly.
293 The scaling has been done in former days, because the wmf filter was sometimes not
294 able to calculate the proper prefsize (especially if the wmf fileheader was missing)
295 
296 
297         aWMF.SetPrefMapMode( MapMode( MAP_100TH_MM ) );
298         // MetaFile auf neue Groesse skalieren und
299         // neue Groesse am MetaFile setzen
300         if (rPic.MFP.xExt && rPic.MFP.yExt)
301         {
302             Size aOldSiz(aWMF.GetPrefSize());
303             Size aNewSiz(rPic.MFP.xExt, rPic.MFP.yExt );
304             Fraction aFracX(aNewSiz.Width(), aOldSiz.Width());
305             Fraction aFracY(aNewSiz.Height(), aOldSiz.Height());
306 
307             aWMF.Scale(aFracX, aFracY);
308             aWMF.SetPrefSize(aNewSiz);
309         }
310 */
311         rpGraphic = new Graphic( aWMF );
312         return true;
313     }
314 
315     // MAC - Word als Creator
316     // im WMF steht nur "Benutzen sie Word 6.0c" Mac-Pict steht dahinter
317     // allerdings ohne die ersten 512 Bytes, bei einem MAC-PICT egal sind (
318     // werden nicht ausgewertet )
319     bOk = false;
320     long nData = rPic.lcb - ( pSt->Tell() - nPosFc );
321     if (nData > 0)
322     {
323         rpGraphic = new Graphic();
324         if (0 == (bOk = SwWW8ImplReader::GetPictGrafFromStream(*rpGraphic, *pSt)))
325             DELETEZ(rpGraphic);
326     }
327     return bOk; // Grafik drin
328 }
329 
330 struct WW8PicDesc
331 {
332     sal_Int16 nCL, nCR, nCT, nCB;
333     long nWidth, nHeight;
334 
335     WW8PicDesc( const WW8_PIC& rPic );
336 };
337 
WW8PicDesc(const WW8_PIC & rPic)338 WW8PicDesc::WW8PicDesc( const WW8_PIC& rPic )
339 {
340     //See #i21190# before fiddling with this method
341     long nOriWidth = rPic.dxaGoal;        //Size in 1/100 mm before crop
342     long nOriHeight = rPic.dyaGoal;
343 
344     nCL = rPic.dxaCropLeft;
345     nCR = rPic.dxaCropRight;
346     nCT = rPic.dyaCropTop;
347     nCB = rPic.dyaCropBottom;
348 
349     long nAktWidth  = nOriWidth - (nCL + nCR);  // Size after crop
350     long nAktHeight = nOriHeight - (nCT + nCB);
351     if (!nAktWidth)
352         nAktWidth  = 1;
353     if (!nAktHeight)
354         nAktHeight = 1;
355     nWidth = nAktWidth * rPic.mx / 1000;        // Writer Size
356     nHeight = nAktHeight * rPic.my / 1000;
357 }
358 
ReplaceObj(const SdrObject & rReplaceObj,SdrObject & rSubObj)359 void SwWW8ImplReader::ReplaceObj(const SdrObject &rReplaceObj,
360     SdrObject &rSubObj)
361 {
362     // SdrGrafObj anstatt des SdrTextObj in dessen Gruppe einsetzen
363     if (SdrObject* pGroupObject = rReplaceObj.GetUpGroup())
364     {
365         SdrObjList* pObjectList = pGroupObject->GetSubList();
366 
367         rSubObj.SetLogicRect(rReplaceObj.GetCurrentBoundRect());
368         rSubObj.SetLayer(rReplaceObj.GetLayer());
369 
370         // altes Objekt raus aus Gruppen-Liste und neues rein
371         // (dies tauscht es ebenfalls in der Drawing-Page aus)
372         pObjectList->ReplaceObject(&rSubObj, rReplaceObj.GetOrdNum());
373     }
374     else
375     {
376         ASSERT( sal_False, "Impossible!");
377     }
378 }
379 
380 // MakeGrafNotInCntnt setzt eine nicht-Zeichengebundene Grafik
381 // ( bGrafApo == true)
MakeGrafNotInCntnt(const WW8PicDesc & rPD,const Graphic * pGraph,const String & rFileName,const SfxItemSet & rGrfSet)382 SwFlyFrmFmt* SwWW8ImplReader::MakeGrafNotInCntnt(const WW8PicDesc& rPD,
383     const Graphic* pGraph, const String& rFileName, const SfxItemSet& rGrfSet)
384 {
385 
386     sal_uInt32 nWidth = rPD.nWidth;
387     sal_uInt32 nHeight = rPD.nHeight;
388 
389     // Vertikale Verschiebung durch Zeilenabstand
390     sal_Int32 nNetHeight = nHeight + rPD.nCT + rPD.nCB;
391     if( pSFlyPara->nLineSpace && pSFlyPara->nLineSpace > nNetHeight )
392         pSFlyPara->nYPos =
393             (sal_uInt16)( pSFlyPara->nYPos + pSFlyPara->nLineSpace - nNetHeight );
394 
395     WW8FlySet aFlySet(*this, pWFlyPara, pSFlyPara, true);
396 
397     SwFmtAnchor aAnchor(pSFlyPara->eAnchor);
398     aAnchor.SetAnchor(pPaM->GetPoint());
399     aFlySet.Put(aAnchor);
400 
401     aFlySet.Put( SwFmtFrmSize( ATT_FIX_SIZE, nWidth, nHeight ) );
402 
403     SwFlyFrmFmt* pFlyFmt = rDoc.Insert(*pPaM, rFileName, aEmptyStr, pGraph,
404         &aFlySet, &rGrfSet, NULL);
405 
406     // Damit die Frames bei Einfuegen in existierendes Doc erzeugt werden:
407     if (rDoc.GetCurrentViewShell() &&	//swmod 071108//swmod 071225
408         (FLY_AT_PARA == pFlyFmt->GetAnchor().GetAnchorId()))
409     {
410         pFlyFmt->MakeFrms();
411     }
412     return pFlyFmt;
413 }
414 
415 
416 // MakeGrafInCntnt fuegt zeichengebundene Grafiken ein
MakeGrafInCntnt(const WW8_PIC & rPic,const WW8PicDesc & rPD,const Graphic * pGraph,const String & rFileName,const SfxItemSet & rGrfSet)417 SwFrmFmt* SwWW8ImplReader::MakeGrafInCntnt(const WW8_PIC& rPic,
418     const WW8PicDesc& rPD, const Graphic* pGraph, const String& rFileName,
419     const SfxItemSet& rGrfSet)
420 {
421     WW8FlySet aFlySet(*this, pPaM, rPic, rPD.nWidth, rPD.nHeight);
422 
423     SwFrmFmt* pFlyFmt = 0;
424 
425     if (!rFileName.Len() && nObjLocFc)      // dann sollte ists ein OLE-Object
426         pFlyFmt = ImportOle(pGraph, &aFlySet, &rGrfSet);
427 
428     if( !pFlyFmt )                          // dann eben als Graphic
429     {
430 
431         pFlyFmt = rDoc.Insert( *pPaM, rFileName, aEmptyStr, pGraph, &aFlySet,
432             &rGrfSet, NULL);
433     }
434 
435     // Grafik im Rahmen ? ok, Rahmen auf Bildgroesse vergroessern
436     //  ( nur wenn Auto-Breite )
437     if( pSFlyPara )
438         pSFlyPara->BoxUpWidth( rPD.nWidth );
439     return pFlyFmt;
440 }
441 
ImportGraf1(WW8_PIC & rPic,SvStream * pSt,sal_uLong nFilePos)442 SwFrmFmt* SwWW8ImplReader::ImportGraf1(WW8_PIC& rPic, SvStream* pSt,
443     sal_uLong nFilePos )
444 {
445     SwFrmFmt* pRet = 0;
446     if( pSt->IsEof() || rPic.fError || rPic.MFP.mm == 99 )
447         return 0;
448 
449     String aFileName;
450     bool bInDoc;
451     Graphic* pGraph = 0;
452     bool bOk = ReadGrafFile(aFileName, pGraph, rPic, pSt, nFilePos, &bInDoc);
453 
454     if (!bOk)
455     {
456         delete pGraph;
457         return 0;                       // Grafik nicht korrekt eingelesen
458     }
459 
460     WW8PicDesc aPD( rPic );
461 
462     SwAttrSet aGrfSet( rDoc.GetAttrPool(), RES_GRFATR_BEGIN, RES_GRFATR_END-1);
463     if( aPD.nCL || aPD.nCR || aPD.nCT || aPD.nCB )
464     {
465         SwCropGrf aCrop( aPD.nCL, aPD.nCR, aPD.nCT, aPD.nCB) ;
466         aGrfSet.Put( aCrop );
467     }
468 
469     if( pWFlyPara && pWFlyPara->bGrafApo )
470         pRet = MakeGrafNotInCntnt(aPD,pGraph,aFileName,aGrfSet);
471     else
472         pRet = MakeGrafInCntnt(rPic,aPD,pGraph,aFileName,aGrfSet);
473     delete pGraph;
474     return pRet;
475 }
476 
PicRead(SvStream * pDataStream,WW8_PIC * pPic,bool bVer67)477 void SwWW8ImplReader::PicRead(SvStream *pDataStream, WW8_PIC *pPic,
478     bool bVer67)
479 {
480     //Only the first 0x2e bytes are the same between version 6/7 and 8+
481 #ifdef __WW8_NEEDS_COPY
482     WW8_PIC_SHADOW aPicS;
483     pDataStream->Read( &aPicS, sizeof( aPicS ) );
484     WW8PicShadowToReal( &aPicS, pPic );
485 #else
486     pDataStream->Read( pPic, 0x2E);
487 #endif // defined __WW8_NEEDS_COPY
488     for (int i=0;i<4;i++)
489         pDataStream->Read( &pPic->rgbrc[i], bVer67 ? 2 : 4);
490     *pDataStream >> pPic->dxaOrigin;
491     *pDataStream >> pPic->dyaOrigin;
492     if (!bVer67)
493         pDataStream->SeekRel(2);  //cProps
494 }
495 
ImportGraf(SdrTextObj * pTextObj,SwFrmFmt * pOldFlyFmt)496 SwFrmFmt* SwWW8ImplReader::ImportGraf(SdrTextObj* pTextObj,
497     SwFrmFmt* pOldFlyFmt)
498 {
499     SwFrmFmt* pRet = 0;
500     if (
501         ((pStrm == pDataStream ) && !nPicLocFc) ||
502         (nIniFlags & WW8FL_NO_GRAF)
503        )
504     {
505         return 0;
506     }
507 
508     ::SetProgressState(nProgress, mpDocShell);         // Update
509 
510     GrafikCtor();
511 
512     /*
513         kleiner Spass von Microsoft: manchmal existiert ein Stream Namens DATA
514         Dieser enthaelt dann den PICF und die entsprechende Grafik !!!
515         Wir mappen ansonsten die Variable pDataStream auf pStream.
516     */
517 
518     sal_uLong nOldPos = pDataStream->Tell();
519     WW8_PIC aPic;
520     pDataStream->Seek( nPicLocFc );
521     PicRead( pDataStream, &aPic, bVer67);
522 
523         // Plausibilitaetstest ist noetig, da z.B. bei CheckBoxen im
524         // Feld-Result ein WMF-aehnliches Struct vorkommt.
525     if ((aPic.lcb >= 58) && !pDataStream->GetError())
526     {
527         if( pFlyFmtOfJustInsertedGraphic )
528         {
529             // Soeben haben wir einen Grafik-Link ins Doc inserted.
530             // Wir muessen ihn jetzt noch Positioniern und Skalieren.
531             //
532             WW8PicDesc aPD( aPic );
533 
534             WW8FlySet aFlySet( *this, pPaM, aPic, aPD.nWidth, aPD.nHeight );
535 
536             //JP 17.1.2002: the correct anchor is set in Read_F_IncludePicture
537             //              and the current PaM point's behind the position if
538             //              it is anchored in content; because this anchor add
539             //              a character into the textnode.
540             //              IussueZilla task 2806
541             if (FLY_AS_CHAR ==
542                 pFlyFmtOfJustInsertedGraphic->GetAnchor().GetAnchorId() )
543             {
544                 aFlySet.ClearItem( RES_ANCHOR );
545             }
546 
547             pFlyFmtOfJustInsertedGraphic->SetFmtAttr( aFlySet );
548 
549             pFlyFmtOfJustInsertedGraphic = 0;
550         }
551         else if((0x64 == aPic.MFP.mm) || (0x66 == aPic.MFP.mm))
552         {
553             // verlinkte Grafik im Escher-Objekt
554             SdrObject* pObject = 0;
555 
556             //#i17200#, a bit of guesswork I'm afraid
557             if (aPic.dxaGoal == 1000 && aPic.mx == 1)  //100% hack ?
558             {
559                 aPic.mx = msword_cast<sal_uInt16>(
560                     maSectionManager.GetPageWidth() -
561                     maSectionManager.GetPageRight() -
562                     maSectionManager.GetPageLeft());
563             }
564 
565             WW8PicDesc aPD( aPic );
566             String aGrName;
567             if (!pMSDffManager)
568                 pMSDffManager = new SwMSDffManager(*this);
569             /*
570             ##835##
571             Disable use of main stream as fallback stream for inline direct
572             blips as it is known that they are directly after the record
573             header, testing for existence in main stream may lead to an
574             incorrect fallback graphic being found if other escher graphics
575             have been inserted in the document
576             */
577             pMSDffManager->DisableFallbackStream();
578             if( !pMSDffManager->GetModel() )
579                 pMSDffManager->SetModel(pDrawModel, 1440);
580 
581             if (0x66 == aPic.MFP.mm)
582             {
583                 //These ones have names prepended
584                 sal_uInt8 nNameLen=0;
585                 *pDataStream >> nNameLen;
586                 pDataStream->SeekRel( nNameLen );
587             }
588 
589 			Rectangle aChildRect;
590             Rectangle aClientRect( 0,0, aPD.nWidth,  aPD.nHeight);
591             SvxMSDffImportData aData( aClientRect );
592             pObject = pMSDffManager->ImportObj(*pDataStream, &aData, aClientRect, aChildRect );
593             if (pObject)
594             {
595                 // fuer den Rahmen
596                 SfxItemSet aAttrSet( rDoc.GetAttrPool(), RES_FRMATR_BEGIN,
597                     RES_FRMATR_END-1 );
598 
599                 SvxMSDffImportRec *pRecord =
600                     (aData.HasRecords() && (1 == aData.GetRecCount() ) ) ?
601                     aData.GetRecord( 0 ) : 0;
602 
603                 if( pRecord )
604                 {
605                     //A graphic of this type in this location is always
606                     //inline, and uses the pic in the same mould as ww6
607                     //graphics.
608                     if (pWFlyPara && pWFlyPara->bGrafApo)
609                     {
610                         WW8FlySet aFlySet(*this, pWFlyPara, pSFlyPara, true);
611 
612                         SwFmtAnchor aAnchor(pSFlyPara->eAnchor);
613                         aAnchor.SetAnchor(pPaM->GetPoint());
614                         aFlySet.Put(aAnchor);
615 
616                         aAttrSet.Put(aFlySet);
617                     }
618                     else
619                     {
620                         WW8FlySet aFlySet( *this, pPaM, aPic, aPD.nWidth,
621                             aPD.nHeight );
622 
623                         aAttrSet.Put(aFlySet);
624                     }
625 			//Modified for i120717,for graf importing from MS Word 2003 binary format,
626 			//there is no border distance.
627                     /*Rectangle aInnerDist(   pRecord->nDxTextLeft,
628                         pRecord->nDyTextTop, pRecord->nDxTextRight,
629                         pRecord->nDyTextBottom  );*/
630 
631 			Rectangle aInnerDist(0,0,0,0);
632 			//End
633                     MatchSdrItemsIntoFlySet( pObject, aAttrSet,
634                         pRecord->eLineStyle, pRecord->eShapeType,
635                         aInnerDist );
636 
637                     //Groesse aus der WinWord PIC-Struktur als
638                     //Grafik-Groesse nehmen
639                     aAttrSet.Put( SwFmtFrmSize( ATT_FIX_SIZE, aPD.nWidth,
640                         aPD.nHeight ) );
641                 }
642 
643                 // for the Grafik
644                 SfxItemSet aGrSet( rDoc.GetAttrPool(), RES_GRFATR_BEGIN,
645                     RES_GRFATR_END-1 );
646 
647                 if( aPD.nCL || aPD.nCR || aPD.nCT || aPD.nCB )
648                 {
649                     SwCropGrf aCrop( aPD.nCL, aPD.nCR, aPD.nCT, aPD.nCB );
650                     aGrSet.Put( aCrop );
651                 }
652 
653                 if (pRecord)
654                     MatchEscherMirrorIntoFlySet(*pRecord, aGrSet);
655 
656                 // ggfs. altes AttrSet uebernehmen und
657                 // horiz. Positionierungs-Relation korrigieren
658                 if( pOldFlyFmt )
659                 {
660                     aAttrSet.Put( pOldFlyFmt->GetAttrSet() );
661                     const SwFmtHoriOrient &rHori = pOldFlyFmt->GetHoriOrient();
662                     if( text::RelOrientation::FRAME == rHori.GetRelationOrient() )
663                     {
664                         aAttrSet.Put( SwFmtHoriOrient( rHori.GetPos(),
665                             text::HoriOrientation::NONE, text::RelOrientation::PAGE_PRINT_AREA ) );
666                     }
667                 }
668 
669                 bool bTextObjWasGrouped = false;
670                 if (pOldFlyFmt && pTextObj && pTextObj->GetUpGroup())
671                     bTextObjWasGrouped = true;
672 
673                 if (bTextObjWasGrouped)
674                     ReplaceObj(*pTextObj, *pObject);
675                 else
676                 {
677                     if (sal_uInt16(OBJ_OLE2) == pObject->GetObjIdentifier())
678 					{
679 						// the size from BLIP, if there is any, should be already set
680                         pRet = InsertOle(*((SdrOle2Obj*)pObject), aAttrSet, aGrSet);
681 					}
682                     else
683                     {
684                         if (SdrGrafObj* pGraphObject = PTR_CAST(SdrGrafObj, pObject))
685                         {
686                             // Nun den Link bzw. die Grafik ins Doc stopfen
687                             const Graphic& rGraph = pGraphObject->GetGraphic();
688 
689                             if (nObjLocFc)  // is it a OLE-Object?
690                                 pRet = ImportOle(&rGraph, &aAttrSet, &aGrSet, pObject->GetBLIPSizeRectangle());
691 
692                             if (!pRet)
693                             {
694                                 pRet = rDoc.Insert(*pPaM, aEmptyStr, aEmptyStr,
695                                     &rGraph, &aAttrSet, &aGrSet, NULL );
696                             }
697                         }
698                         else
699                             pRet = rDoc.InsertDrawObj(*pPaM, *pObject, aAttrSet );
700                     }
701                 }
702 
703                 // also nur, wenn wir ein *Insert* gemacht haben
704                 if (pRet)
705                 {
706                     if (pRecord)
707                         SetAttributesAtGrfNode(pRecord, pRet, 0);
708 
709 					// #i68101#
710 					// removed pObject->HasSetName() usage since always returned true,
711 					// also removed else-part and wrote an informing mail to Henning Brinkmann
712 					// about this to clarify.
713 					pRet->SetName(pObject->GetName());
714 
715                     // Zeiger auf neues Objekt ermitteln und Z-Order-Liste
716                     // entsprechend korrigieren (oder Eintrag loeschen)
717                     if (SdrObject* pOurNewObject = CreateContactObject(pRet))
718                     {
719                         if (pOurNewObject != pObject)
720                         {
721                             pMSDffManager->ExchangeInShapeOrder( pObject, 0, 0,
722                                 pOurNewObject );
723 
724                             // altes SdrGrafObj aus der Page loeschen und
725                             // zerstoeren
726                             if (pObject->GetPage())
727                                 pDrawPg->RemoveObject(pObject->GetOrdNum());
728                             SdrObject::Free( pObject );
729                         }
730                     }
731                     else
732                         pMSDffManager->RemoveFromShapeOrder( pObject );
733                 }
734                 else
735                     pMSDffManager->RemoveFromShapeOrder( pObject );
736 
737                 // auch das ggfs.  Page loeschen, falls nicht gruppiert,
738                 if (pTextObj && !bTextObjWasGrouped && pTextObj->GetPage())
739                     pDrawPg->RemoveObject( pTextObj->GetOrdNum() );
740             }
741             pMSDffManager->EnableFallbackStream();
742         }
743         else if (aPic.lcb >= 58)
744             pRet = ImportGraf1(aPic, pDataStream, nPicLocFc);
745     }
746     pDataStream->Seek( nOldPos );
747 
748     if (pRet)
749     {
750         SdrObject* pOurNewObject = CreateContactObject(pRet);
751         pWWZOrder->InsertTextLayerObject(pOurNewObject);
752     }
753 
754     return AddAutoAnchor(pRet);
755 }
756 
757 #ifdef __WW8_NEEDS_COPY
758 
WW8PicShadowToReal(WW8_PIC_SHADOW * pPicS,WW8_PIC * pPic)759 void WW8PicShadowToReal( WW8_PIC_SHADOW * pPicS, WW8_PIC * pPic )
760 {
761     pPic->lcb = SVBT32ToUInt32( pPicS->lcb );
762     pPic->cbHeader = SVBT16ToShort( pPicS->cbHeader );
763     pPic->MFP.mm = SVBT16ToShort( pPicS->MFP.mm );
764     pPic->MFP.xExt = SVBT16ToShort( pPicS->MFP.xExt );
765     pPic->MFP.yExt = SVBT16ToShort( pPicS->MFP.yExt );
766     pPic->MFP.hMF = SVBT16ToShort( pPicS->MFP.hMF );
767     for( sal_uInt16 i = 0; i < 14 ; i++ )
768         pPic->rcWinMF[i] = SVBT8ToByte( pPicS->rcWinMF[i] );
769     pPic->dxaGoal = SVBT16ToShort( pPicS->dxaGoal );
770     pPic->dyaGoal = SVBT16ToShort( pPicS->dyaGoal );
771     pPic->mx = SVBT16ToShort( pPicS->mx );
772     pPic->my = SVBT16ToShort( pPicS->my );
773     pPic->dxaCropLeft = SVBT16ToShort( pPicS->dxaCropLeft );
774     pPic->dyaCropTop = SVBT16ToShort( pPicS->dyaCropTop );
775     pPic->dxaCropRight = SVBT16ToShort( pPicS->dxaCropRight );
776     pPic->dyaCropBottom = SVBT16ToShort( pPicS->dyaCropBottom );
777     pPic->brcl = pPicS->aBits1[0] & 0x0f;
778     pPic->fFrameEmpty = (pPicS->aBits1[0] & 0x10) >> 4;
779     pPic->fBitmap = (pPicS->aBits1[0] & 0x20) >> 5;
780     pPic->fDrawHatch = (pPicS->aBits1[0] & 0x40) >> 6;
781     pPic->fError = (pPicS->aBits1[0] & 0x80) >> 7;
782     pPic->bpp = pPicS->aBits2[0];
783 }
784 
WW8FSPAShadowToReal(WW8_FSPA_SHADOW * pFSPAS,WW8_FSPA * pFSPA)785 void WW8FSPAShadowToReal( WW8_FSPA_SHADOW * pFSPAS, WW8_FSPA * pFSPA )
786 {
787     //long nSpId;       //Shape Identifier. Used in conjunction with the office art data (found via fcDggInfo in the FIB) to find the actual data for this shape.
788     //long nXaLeft; //left of rectangle enclosing shape relative to the origin of the shape
789     //long nYaTop;      //top of rectangle enclosing shape relative to the origin of the shape
790     //long nXaRight;    //right of rectangle enclosing shape relative to the origin of the shape
791     //long nYaBottom;//bottom of the rectangle enclosing shape relative to the origin of the shape
792     //sal_uInt16 bHdr:1;
793     //sal_uInt16 nbx:2;
794     //sal_uInt16 nby:2;
795     //sal_uInt16 nwr:4;
796     //sal_uInt16 nwrk:4;
797     //sal_uInt16 bRcaSimple:1;
798     //sal_uInt16 bAnchorLock:1;
799     //long nTxbx; //count of textboxes in shape (undo doc only)
800 
801 
802     pFSPA->nSpId        = SVBT32ToUInt32( pFSPAS->nSpId );
803     pFSPA->nXaLeft      = SVBT32ToUInt32( pFSPAS->nXaLeft );
804     pFSPA->nYaTop       = SVBT32ToUInt32( pFSPAS->nYaTop );
805     pFSPA->nXaRight     = SVBT32ToUInt32( pFSPAS->nXaRight );
806     pFSPA->nYaBottom    = SVBT32ToUInt32( pFSPAS->nYaBottom );
807 
808     sal_uInt16 nBits        = SVBT16ToShort( pFSPAS->aBits1 );
809 
810     pFSPA->bHdr         = 0 !=  ( nBits & 0x0001 );
811     pFSPA->nbx          =       ( nBits & 0x0006 ) >> 1;
812     pFSPA->nby          =       ( nBits & 0x0018 ) >> 3;
813     pFSPA->nwr          =       ( nBits & 0x01E0 ) >> 5;
814     pFSPA->nwrk         =       ( nBits & 0x1E00 ) >> 9;
815     pFSPA->bRcaSimple   = 0 !=  ( nBits & 0x2000 );
816     pFSPA->bBelowText   = 0 !=  ( nBits & 0x4000 );
817     pFSPA->bAnchorLock  = 0 !=  ( nBits & 0x8000 );
818     pFSPA->nTxbx = SVBT32ToUInt32( pFSPAS->nTxbx );
819 }
820 #endif // defined __WW8_NEEDS_COPY
821 
822 /* vi:set tabstop=4 shiftwidth=4 expandtab: */
823