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