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