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