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