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