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