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