nss: upgrade to release 3.73
[LibreOffice.git] / sw / source / filter / ww8 / ww8graf2.cxx
blob3cb16f6422b806b4e2966f6236e8329dcb937bb2
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <iterator>
21 #include <numeric>
22 #include <hintids.hxx>
23 #include <svl/urihelper.hxx>
24 #include <svx/svdpage.hxx>
25 #include <svx/svdograf.hxx>
26 #include <svx/svdoole2.hxx>
27 #include <filter/msfilter/msdffimp.hxx>
28 #include <unotools/configmgr.hxx>
29 #include <grfatr.hxx>
30 #include <fmtanchr.hxx>
31 #include <fmtcntnt.hxx>
32 #include <frmfmt.hxx>
33 #include <pam.hxx>
34 #include <doc.hxx>
35 #include <IDocumentLayoutAccess.hxx>
36 #include <mdiexp.hxx>
37 #include "writerwordglue.hxx"
38 #include "ww8struc.hxx"
39 #include "ww8scan.hxx"
40 #include "ww8par.hxx"
41 #include "ww8par2.hxx"
42 #include "ww8graf.hxx"
43 #include <vcl/gdimtf.hxx>
44 #include <vcl/graphicfilter.hxx>
45 #include <vcl/wmf.hxx>
47 using namespace ::com::sun::star;
48 using namespace sw::types;
50 wwZOrderer::wwZOrderer(const sw::util::SetLayer &rSetLayer, SdrPage* pDrawPg,
51 const SvxMSDffShapeOrders *pShapeOrders)
52 : maSetLayer(rSetLayer), mnInlines(0), mpDrawPg(pDrawPg),
53 mpShapeOrders(pShapeOrders)
55 mnNoInitialObjects = mpDrawPg->GetObjCount();
56 OSL_ENSURE(mpDrawPg,"Missing draw page impossible!");
59 void wwZOrderer::InsideEscher(sal_uLong nSpId)
61 maIndexes.push(GetEscherObjectIdx(nSpId));
64 void wwZOrderer::OutsideEscher()
66 maIndexes.pop();
69 // consider new parameter <_bInHeaderFooter>
70 void wwZOrderer::InsertEscherObject( SdrObject* pObject,
71 sal_uLong nSpId,
72 const bool _bInHeaderFooter )
74 sal_uLong nInsertPos = GetEscherObjectPos( nSpId, _bInHeaderFooter );
75 InsertObject(pObject, nInsertPos + mnNoInitialObjects + mnInlines);
78 wwZOrderer::myeiter wwZOrderer::MapEscherIdxToIter(sal_uLong nIdx)
80 return std::find_if(maEscherLayer.begin(), maEscherLayer.end(),
81 [nIdx](const EscherShape& rShape) { return rShape.mnEscherShapeOrder == nIdx; });
84 sal_uInt16 wwZOrderer::GetEscherObjectIdx(sal_uLong nSpId)
86 sal_uInt16 nFound=0;
87 sal_uInt16 nShapeCount = mpShapeOrders ? mpShapeOrders->size() : 0;
88 // First, find out what position this shape is in the Escher order.
89 for (sal_uInt16 nShapePos=0; nShapePos < nShapeCount; nShapePos++)
91 const SvxMSDffShapeOrder& rOrder = *(*mpShapeOrders)[nShapePos];
92 if (rOrder.nShapeId == nSpId)
94 nFound = nShapePos;
95 break;
98 return nFound;
101 // consider new parameter <_bInHeaderFooter>
102 sal_uLong wwZOrderer::GetEscherObjectPos( sal_uLong nSpId,
103 const bool _bInHeaderFooter )
106 EscherObjects have their own ordering which needs to be matched to
107 the actual ordering that should be used when inserting them into the
108 document.
110 sal_uInt16 nFound = GetEscherObjectIdx(nSpId);
111 // Match the ordering position from the ShapeOrders to the ordering of all
112 // objects in the document, there is a complexity when escherobjects
113 // contain inlines objects, we need to consider those as part of the
114 // escher count
115 sal_uLong nRet=0;
116 myeiter aIter = maEscherLayer.begin();
117 myeiter aEnd = maEscherLayer.end();
118 // skip objects in page header|footer,
119 // if current object isn't in page header|footer
120 if ( !_bInHeaderFooter )
122 while ( aIter != aEnd )
124 if ( !aIter->mbInHeaderFooter )
126 break;
128 nRet += aIter->mnNoInlines + 1;
129 ++aIter;
132 while (aIter != aEnd)
134 // insert object in page header|footer
135 // before objects in page body
136 if ( _bInHeaderFooter && !aIter->mbInHeaderFooter )
138 break;
140 if ( aIter->mnEscherShapeOrder > nFound )
141 break;
142 nRet += aIter->mnNoInlines+1;
143 ++aIter;
145 maEscherLayer.insert(aIter, EscherShape( nFound, _bInHeaderFooter ) );
146 return nRet;
149 // InsertObj() adds the object into the Sw-Page and memorize the Z-position
150 // in a VarArr
151 void wwZOrderer::InsertDrawingObject(SdrObject* pObj, short nWwHeight)
153 sal_uLong nPos = GetDrawingObjectPos(nWwHeight);
154 if (nWwHeight & 0x2000) // Heaven ?
155 maSetLayer.SendObjectToHeaven(*pObj);
156 else
157 maSetLayer.SendObjectToHell(*pObj);
159 InsertObject(pObj, nPos + mnNoInitialObjects + mnInlines);
162 void wwZOrderer::InsertTextLayerObject(SdrObject* pObject)
164 maSetLayer.SendObjectToHeaven(*pObject);
165 if (maIndexes.empty())
167 InsertObject(pObject, mnNoInitialObjects + mnInlines);
168 ++mnInlines;
170 else
172 //If we are inside an escher objects, place us just after that
173 //escher obj, and increment its inline count
174 sal_uInt16 nIdx = maIndexes.top();
175 myeiter aEnd = MapEscherIdxToIter(nIdx);
177 sal_uLong nInsertPos = std::accumulate(maEscherLayer.begin(), aEnd, sal_uLong(0),
178 [](const sal_uLong nPos, const EscherShape& rShape) { return nPos + rShape.mnNoInlines + 1; });
180 OSL_ENSURE(aEnd != maEscherLayer.end(), "Something very wrong here");
181 if (aEnd != maEscherLayer.end())
183 aEnd->mnNoInlines++;
184 nInsertPos += aEnd->mnNoInlines;
187 InsertObject(pObject, mnNoInitialObjects + mnInlines + nInsertPos);
191 /* Parallel to the Obj-array in the document I also build an array which
192 * contains the Ww-height (-> what covers what).
193 * Based on this VARARR the position where the insertion happens is
194 * determined.
195 * When inserting the offset in an existing document with a graphic layer the
196 * caller has to increment the index by mnNoInitialObjects, so that the new
197 * objects are added at the end (inserting is faster then)
199 sal_uLong wwZOrderer::GetDrawingObjectPos(short nWwHeight)
201 auto aIter = std::find_if(
202 maDrawHeight.begin(), maDrawHeight.end(),
203 [nWwHeight](short aHeight){ return (aHeight & 0x1fff) > (nWwHeight & 0x1fff); });
205 aIter = maDrawHeight.insert(aIter, nWwHeight);
206 return std::distance(maDrawHeight.begin(), aIter);
209 void wwZOrderer::InsertObject(SdrObject* pObject, sal_uLong nPos)
211 if (!pObject->IsInserted())
213 mpDrawPg->InsertObject(pObject, nPos);
217 static void WW8PicShadowToReal( WW8_PIC_SHADOW const * pPicS, WW8_PIC* pPic );
219 bool SwWW8ImplReader::GetPictGrafFromStream(Graphic& rGraphic, SvStream& rSrc)
221 return ERRCODE_NONE == GraphicFilter::GetGraphicFilter().ImportGraphic(rGraphic, OUString(), rSrc);
224 bool SwWW8ImplReader::ReadGrafFile(OUString& rFileName, std::unique_ptr<Graphic>& rpGraphic,
225 const WW8_PIC& rPic, SvStream* pSt, sal_uLong nFilePos, bool* pbInDoc)
226 { // Write the graphic to the file
227 *pbInDoc = true; // default
229 sal_uLong nPosFc = nFilePos + rPic.cbHeader;
231 switch (rPic.MFP.mm)
233 case 94: // BMP-file ( not embedded ) or GIF
234 case 99: // TIFF-file ( not embedded )
235 pSt->Seek(nPosFc);
236 // read name as P-string
237 rFileName = read_uInt8_PascalString(*pSt, m_eStructCharSet);
238 if (!rFileName.isEmpty())
239 rFileName = URIHelper::SmartRel2Abs(
240 INetURLObject(m_sBaseURL), rFileName,
241 URIHelper::GetMaybeFileHdl());
242 *pbInDoc = false; // Don't delete the file afterwards
243 return !rFileName.isEmpty(); // read was successful
246 GDIMetaFile aWMF;
247 bool bOk = checkSeek(*pSt, nPosFc) && ReadWindowMetafile( *pSt, aWMF );
249 if (!bOk || pSt->GetError() || !aWMF.GetActionSize())
250 return false;
252 //skip duplicate graphics when fuzzing
253 if (utl::ConfigManager::IsFuzzing())
255 if (!m_aGrafPosSet.insert(nPosFc).second)
256 return false;
259 if (m_xWwFib->m_envr != 1) // !MAC as creator
261 rpGraphic.reset(new Graphic(aWMF));
262 return true;
265 // MAC - word as creator
266 // The WMF only says "Please use Word 6.0c" and Mac-Pict follows but without
267 // the first 512 Bytes which are not relevant in a MAC-PICT (they are not
268 // interpreted)
269 bOk = false;
270 tools::Long nData = rPic.lcb - ( pSt->Tell() - nPosFc );
271 if (nData > 0)
273 rpGraphic.reset(new Graphic());
274 bOk = SwWW8ImplReader::GetPictGrafFromStream(*rpGraphic, *pSt);
275 if (!bOk)
276 rpGraphic.reset();
278 return bOk; // Contains graphic
281 struct WW8PicDesc
283 sal_Int16 nCL, nCR, nCT, nCB;
284 tools::Long nWidth, nHeight;
286 explicit WW8PicDesc( const WW8_PIC& rPic );
289 WW8PicDesc::WW8PicDesc( const WW8_PIC& rPic )
290 : nCL(rPic.dxaCropLeft),
291 nCR(rPic.dxaCropRight),
292 nCT(rPic.dyaCropTop),
293 nCB(rPic.dyaCropBottom)
295 //See #i21190# before fiddling with this method
296 tools::Long nOriWidth = rPic.dxaGoal; //Size in 1/100 mm before crop
297 tools::Long nOriHeight = rPic.dyaGoal;
300 tools::Long nCurrentWidth = nOriWidth - (nCL + nCR); // Size after crop
301 tools::Long nCurrentHeight = nOriHeight - (nCT + nCB);
302 if (!nCurrentWidth)
303 nCurrentWidth = 1;
304 if (!nCurrentHeight)
305 nCurrentHeight = 1;
306 nWidth = nCurrentWidth * rPic.mx / 1000; // Writer Size
307 nHeight = nCurrentHeight * rPic.my / 1000;
310 void SwWW8ImplReader::ReplaceObj(const SdrObject &rReplaceObj,
311 SdrObject &rSubObj)
313 // Insert SdrGrafObj instead of SdrTextObj into this group
314 if (SdrObject* pGroupObject = rReplaceObj.getParentSdrObjectFromSdrObject())
316 SdrObjList* pObjectList = pGroupObject->GetSubList();
318 rSubObj.SetLogicRect(rReplaceObj.GetCurrentBoundRect());
319 rSubObj.SetLayer(rReplaceObj.GetLayer());
321 // remove old object from group-list and add new one
322 // (this also exchanges it in the drawing page)
323 pObjectList->ReplaceObject(&rSubObj, rReplaceObj.GetOrdNum());
325 else
327 OSL_ENSURE( false, "Impossible!");
331 // MakeGrafNotInContent inserts a non character bound graphic
332 // ( bGrafApo == true)
333 SwFlyFrameFormat* SwWW8ImplReader::MakeGrafNotInContent(const WW8PicDesc& rPD,
334 const Graphic* pGraph, const OUString& rFileName, const SfxItemSet& rGrfSet)
337 sal_uInt32 nWidth = rPD.nWidth;
338 sal_uInt32 nHeight = rPD.nHeight;
340 // Vertical shift through line spacing
341 sal_Int32 nNetHeight = nHeight + rPD.nCT + rPD.nCB;
342 if (m_xSFlyPara->nLineSpace && m_xSFlyPara->nLineSpace > nNetHeight)
343 m_xSFlyPara->nYPos =
344 static_cast<sal_uInt16>( m_xSFlyPara->nYPos + m_xSFlyPara->nLineSpace - nNetHeight );
346 WW8FlySet aFlySet(*this, m_xWFlyPara.get(), m_xSFlyPara.get(), true);
348 SwFormatAnchor aAnchor(WW8SwFlyPara::eAnchor);
349 aAnchor.SetAnchor(m_pPaM->GetPoint());
350 aFlySet.Put(aAnchor);
352 aFlySet.Put( SwFormatFrameSize( SwFrameSize::Fixed, nWidth, nHeight ) );
354 SwFlyFrameFormat *const pFlyFormat =
355 m_rDoc.getIDocumentContentOperations().InsertGraphic(
356 *m_pPaM, rFileName, OUString(), pGraph,
357 &aFlySet, &rGrfSet, nullptr);
359 // So the frames are generated when inserted in an existing doc:
360 if (m_rDoc.getIDocumentLayoutAccess().GetCurrentViewShell() &&
361 (RndStdIds::FLY_AT_PARA == pFlyFormat->GetAnchor().GetAnchorId()))
363 pFlyFormat->MakeFrames();
365 return pFlyFormat;
368 // MakeGrafInContent inserts a character bound graphic
369 SwFrameFormat* SwWW8ImplReader::MakeGrafInContent(const WW8_PIC& rPic,
370 const WW8PicDesc& rPD, const Graphic* pGraph, const OUString& rFileName,
371 const SfxItemSet& rGrfSet)
373 WW8FlySet aFlySet(*this, m_pPaM, rPic, rPD.nWidth, rPD.nHeight);
375 SwFrameFormat* pFlyFormat = nullptr;
377 if (rFileName.isEmpty() && m_nObjLocFc) // then it should be an OLE-Object
378 pFlyFormat = ImportOle(pGraph, &aFlySet, &rGrfSet);
380 if( !pFlyFormat ) // then just as graphic
383 pFlyFormat = m_rDoc.getIDocumentContentOperations().InsertGraphic(
384 *m_pPaM, rFileName, OUString(), pGraph, &aFlySet,
385 &rGrfSet, nullptr);
388 // Resize the frame to the size of the picture if graphic is inside a frame
389 // (only if auto-width)
390 if (m_xSFlyPara)
391 m_xSFlyPara->BoxUpWidth( rPD.nWidth );
392 return pFlyFormat;
395 SwFrameFormat* SwWW8ImplReader::ImportGraf1(WW8_PIC const & rPic, SvStream* pSt,
396 sal_uLong nFilePos )
398 SwFrameFormat* pRet = nullptr;
399 if( pSt->eof() || rPic.fError || rPic.MFP.mm == 99 )
400 return nullptr;
402 OUString aFileName;
403 bool bInDoc;
404 std::unique_ptr<Graphic> pGraph;
405 bool bOk = ReadGrafFile(aFileName, pGraph, rPic, pSt, nFilePos, &bInDoc);
407 if (!bOk)
409 return nullptr; // Graphic could not be read correctly
412 WW8PicDesc aPD( rPic );
414 SwAttrSet aGrfSet( m_rDoc.GetAttrPool(), RES_GRFATR_BEGIN, RES_GRFATR_END-1);
415 if( aPD.nCL || aPD.nCR || aPD.nCT || aPD.nCB )
417 SwCropGrf aCrop( aPD.nCL, aPD.nCR, aPD.nCT, aPD.nCB) ;
418 aGrfSet.Put( aCrop );
421 if (m_xWFlyPara && m_xWFlyPara->bGrafApo)
422 pRet = MakeGrafNotInContent(aPD, pGraph.get(), aFileName, aGrfSet);
423 else
424 pRet = MakeGrafInContent(rPic, aPD, pGraph.get(), aFileName, aGrfSet);
425 return pRet;
428 void SwWW8ImplReader::PicRead(SvStream *pDataStream, WW8_PIC *pPic,
429 bool bVer67)
431 //Only the first 0x2e bytes are the same between version 6/7 and 8+
432 WW8_PIC_SHADOW aPicS;
433 pDataStream->ReadBytes( &aPicS, sizeof( aPicS ) );
434 WW8PicShadowToReal( &aPicS, pPic );
435 for (WW8_BRC & i : pPic->rgbrc)
436 pDataStream->ReadBytes(&i, bVer67 ? 2 : 4);
437 pDataStream->ReadInt16( pPic->dxaOrigin );
438 pDataStream->ReadInt16( pPic->dyaOrigin );
439 if (!bVer67)
440 pDataStream->SeekRel(2); //cProps
443 namespace
445 SwNodeType GetNodeType(SwFrameFormat const &rSource)
447 const SwNodeIndex* pNodeIndex = rSource.GetContent().GetContentIdx();
448 if (!pNodeIndex)
449 return SwNodeType::NONE;
450 const SwNode& rCSttNd = pNodeIndex->GetNode();
451 SwNodeRange aRg(rCSttNd, 1, *rCSttNd.EndOfSectionNode());
452 return aRg.aStart.GetNode().GetNodeType();
456 SwFrameFormat* SwWW8ImplReader::ImportGraf(SdrTextObj const * pTextObj,
457 SwFrameFormat const * pOldFlyFormat)
459 SwFrameFormat* pRet = nullptr;
460 if (
461 ((m_pStrm == m_pDataStream ) && !m_nPicLocFc) ||
462 (m_nIniFlags & WW8FL_NO_GRAF)
465 return nullptr;
468 ::SetProgressState(m_nProgress, m_pDocShell); // Update
470 GrafikCtor();
473 * Little joke from Microsoft: sometimes a stream named DATA exists. This
474 * stream then contains the PICF and the corresponding graphic!
475 * We otherwise map the variable pDataStream to pStream.
477 auto nOldPos = m_pDataStream->Tell();
478 WW8_PIC aPic;
479 bool bValid = checkSeek(*m_pDataStream, m_nPicLocFc);
481 if (bValid)
482 PicRead( m_pDataStream, &aPic, m_bVer67);
484 // Sanity check is needed because for example check boxes in field results
485 // contain a WMF-like struct
486 if (bValid && m_pDataStream->good() && (aPic.lcb >= 58))
488 if( m_pFlyFormatOfJustInsertedGraphic )
490 // We just added a graphic-link into the doc. Now we need to set
491 // its position and scale it.
492 WW8PicDesc aPD( aPic );
494 WW8FlySet aFlySet( *this, m_pPaM, aPic, aPD.nWidth, aPD.nHeight );
496 // the correct anchor is set in Read_F_IncludePicture and the
497 // current PaM point is after the position if it is anchored in
498 // content; because this anchor add a character into the textnode.
499 // #i2806#
500 if (RndStdIds::FLY_AS_CHAR ==
501 m_pFlyFormatOfJustInsertedGraphic->GetAnchor().GetAnchorId() )
503 aFlySet.ClearItem( RES_ANCHOR );
506 m_pFlyFormatOfJustInsertedGraphic->SetFormatAttr( aFlySet );
508 m_pFlyFormatOfJustInsertedGraphic = nullptr;
510 else if((0x64 == aPic.MFP.mm) || (0x66 == aPic.MFP.mm))
512 // linked graphic in ESCHER-Object
513 SdrObject* pObject = nullptr;
515 WW8PicDesc aPD( aPic );
516 if (!m_xMSDffManager)
517 m_xMSDffManager.reset(new SwMSDffManager(*this, m_bSkipImages));
518 /* ##835##
519 * Disable use of main stream as fallback stream for inline direct
520 * blips as it is known that they are directly after the record
521 * header, testing for existence in main stream may lead to an
522 * incorrect fallback graphic being found if other escher graphics
523 * have been inserted in the document
525 m_xMSDffManager->DisableFallbackStream();
526 if (!m_xMSDffManager->GetModel())
527 m_xMSDffManager->SetModel(m_pDrawModel, 1440);
529 if (0x66 == aPic.MFP.mm)
531 //These ones have names prepended
532 sal_uInt8 nNameLen=0;
533 m_pDataStream->ReadUChar( nNameLen );
534 m_pDataStream->SeekRel( nNameLen );
537 tools::Rectangle aClientRect( 0,0, aPD.nWidth, aPD.nHeight);
538 SvxMSDffImportData aData( aClientRect );
539 pObject = m_xMSDffManager->ImportObj(*m_pDataStream, aData, aClientRect, tools::Rectangle(), /*nCalledByGroup*/0, /*pShapeId*/nullptr );
540 if (pObject)
542 // for the frame
543 SfxItemSet aAttrSet( m_rDoc.GetAttrPool(), svl::Items<RES_FRMATR_BEGIN,
544 RES_FRMATR_END-1>{} );
546 SvxMSDffImportRec const*const pRecord = (1 == aData.size())
547 ? aData.begin()->get() : nullptr;
549 if( pRecord )
552 // Horizontal rule may have its width given as % of page
553 // width (-1 is used if not given, 0 means the object has
554 // fixed width).
555 // Additionally, if it's a horizontal rule without width
556 // given, assume 100.0% width.
557 int relativeWidth = pRecord->relativeHorizontalWidth;
558 if( relativeWidth == -1 )
559 relativeWidth = pRecord->isHorizontalRule ? 1000 : 0;
560 if( relativeWidth != 0 )
562 const sal_Int16 nScale = aPic.dxaGoal ? aPic.dxaGoal : 1000;
563 aPic.mx = msword_cast<sal_uInt16>(
564 m_aSectionManager.GetPageWidth() -
565 m_aSectionManager.GetPageRight() -
566 m_aSectionManager.GetPageLeft()) * relativeWidth / nScale;
567 aPD = WW8PicDesc( aPic );
568 // This SetSnapRect() call adjusts the size of the
569 // object itself, no idea why it's this call (or even
570 // what the call actually does), but that's what
571 // ImportGraf() (called by ImportObj()) uses.
572 pObject->SetSnapRect( tools::Rectangle( 0, 0, aPD.nWidth, aPD.nHeight ));
575 // A graphic of this type in this location is always
576 // inline, and uses the pic in the same module as ww6
577 // graphics.
578 if (m_xWFlyPara && m_xWFlyPara->bGrafApo)
580 WW8FlySet aFlySet(*this, m_xWFlyPara.get(), m_xSFlyPara.get(), true);
582 SwFormatAnchor aAnchor(WW8SwFlyPara::eAnchor);
583 aAnchor.SetAnchor(m_pPaM->GetPoint());
584 aFlySet.Put(aAnchor);
586 aAttrSet.Put(aFlySet);
588 else
590 WW8FlySet aFlySet( *this, m_pPaM, aPic, aPD.nWidth,
591 aPD.nHeight );
593 aAttrSet.Put(aFlySet);
595 // Modified for i120716,for graf importing from MS Word 2003
596 // binary format, there is no border distance.
597 tools::Rectangle aInnerDist(0,0,0,0);
598 MatchSdrItemsIntoFlySet( pObject, aAttrSet,
599 pRecord->eLineStyle, pRecord->eLineDashing,
600 pRecord->eShapeType, aInnerDist );
602 // Set the size from the WinWord PIC-structure as graphic
603 // size
604 aAttrSet.Put( SwFormatFrameSize( SwFrameSize::Fixed, aPD.nWidth,
605 aPD.nHeight ) );
608 // for the graphic
609 SfxItemSet aGrSet( m_rDoc.GetAttrPool(), svl::Items<RES_GRFATR_BEGIN,
610 RES_GRFATR_END-1>{} );
612 if( aPD.nCL || aPD.nCR || aPD.nCT || aPD.nCB )
614 SwCropGrf aCrop( aPD.nCL, aPD.nCR, aPD.nCT, aPD.nCB );
615 aGrSet.Put( aCrop );
618 if (pRecord)
619 MatchEscherMirrorIntoFlySet(*pRecord, aGrSet);
621 // if necessary adopt old AttrSet and correct horizontal
622 // positioning relation
623 if( pOldFlyFormat )
625 aAttrSet.Put( pOldFlyFormat->GetAttrSet() );
626 const SwFormatHoriOrient &rHori = pOldFlyFormat->GetHoriOrient();
627 if( text::RelOrientation::FRAME == rHori.GetRelationOrient() )
629 aAttrSet.Put( SwFormatHoriOrient( rHori.GetPos(),
630 text::HoriOrientation::NONE, text::RelOrientation::PAGE_PRINT_AREA ) );
634 bool bTextObjWasGrouped = false;
635 if (pOldFlyFormat && pTextObj && pTextObj->getParentSdrObjectFromSdrObject())
636 bTextObjWasGrouped = true;
638 if (bTextObjWasGrouped)
639 ReplaceObj(*pTextObj, *pObject);
640 else
642 if (sal_uInt16(OBJ_OLE2) == pObject->GetObjIdentifier())
644 // the size from BLIP, if there is any, should be already set
645 pRet = InsertOle(*static_cast<SdrOle2Obj*>(pObject), aAttrSet, &aGrSet);
647 else
649 if (SdrGrafObj* pGraphObject = dynamic_cast<SdrGrafObj*>( pObject) )
651 // Now add the link or rather the graphic to the doc
652 const Graphic& rGraph = pGraphObject->GetGraphic();
654 if (m_nObjLocFc) // is it an OLE-Object?
655 pRet = ImportOle(&rGraph, &aAttrSet, &aGrSet, pObject->GetBLIPSizeRectangle());
657 if (!pRet)
659 pRet = m_rDoc.getIDocumentContentOperations().InsertGraphic(
660 *m_pPaM, OUString(), OUString(),
661 &rGraph, &aAttrSet, &aGrSet, nullptr );
664 else
665 pRet = m_rDoc.getIDocumentContentOperations().InsertDrawObj(*m_pPaM, *pObject, aAttrSet );
669 // only if we made an *Insert*
670 if (pRet)
672 if (pRecord)
673 SetAttributesAtGrfNode(pRecord, pRet, nullptr);
675 OUString aObjectName(pObject->GetName());
676 if (aObjectName.isEmpty() || !m_rDoc.FindFlyByName(aObjectName, GetNodeType(*pRet)))
677 pRet->SetName(aObjectName);
678 else
679 m_aGrfNameGenerator.SetUniqueGraphName(pRet, aObjectName);
681 // determine the pointer to the new object and update
682 // Z-order-list accordingly (or delete entry)
683 if (SdrObject* pOurNewObject = CreateContactObject(pRet))
685 if (pOurNewObject != pObject)
687 m_xMSDffManager->ExchangeInShapeOrder( pObject, 0,
688 pOurNewObject );
690 // delete and destroy old SdrGrafObj from page
691 if (pObject->getSdrPageFromSdrObject())
692 m_pDrawPg->RemoveObject(pObject->GetOrdNum());
693 SdrObject::Free( pObject );
696 else
697 m_xMSDffManager->RemoveFromShapeOrder( pObject );
699 else
700 m_xMSDffManager->RemoveFromShapeOrder( pObject );
702 // also delete this from the page if not grouped
703 if (pTextObj && !bTextObjWasGrouped && pTextObj->getSdrPageFromSdrObject())
704 m_pDrawPg->RemoveObject( pTextObj->GetOrdNum() );
706 m_xMSDffManager->EnableFallbackStream();
708 else if (aPic.lcb >= 58)
709 pRet = ImportGraf1(aPic, m_pDataStream, m_nPicLocFc);
711 m_pDataStream->Seek( nOldPos );
713 if (pRet)
715 SdrObject* pOurNewObject = CreateContactObject(pRet);
716 m_xWWZOrder->InsertTextLayerObject(pOurNewObject);
719 return AddAutoAnchor(pRet);
722 void WW8PicShadowToReal( WW8_PIC_SHADOW const * pPicS, WW8_PIC * pPic )
724 pPic->lcb = SVBT32ToUInt32( pPicS->lcb );
725 pPic->cbHeader = SVBT16ToUInt16( pPicS->cbHeader );
726 pPic->MFP.mm = SVBT16ToUInt16( pPicS->MFP.mm );
727 pPic->MFP.xExt = SVBT16ToUInt16( pPicS->MFP.xExt );
728 pPic->MFP.yExt = SVBT16ToUInt16( pPicS->MFP.yExt );
729 pPic->MFP.hMF = SVBT16ToUInt16( pPicS->MFP.hMF );
730 for( sal_uInt16 i = 0; i < 14 ; i++ )
731 pPic->rcWinMF[i] = pPicS->rcWinMF[i];
732 pPic->dxaGoal = SVBT16ToUInt16( pPicS->dxaGoal );
733 pPic->dyaGoal = SVBT16ToUInt16( pPicS->dyaGoal );
734 pPic->mx = SVBT16ToUInt16( pPicS->mx );
735 pPic->my = SVBT16ToUInt16( pPicS->my );
736 pPic->dxaCropLeft = SVBT16ToUInt16( pPicS->dxaCropLeft );
737 pPic->dyaCropTop = SVBT16ToUInt16( pPicS->dyaCropTop );
738 pPic->dxaCropRight = SVBT16ToUInt16( pPicS->dxaCropRight );
739 pPic->dyaCropBottom = SVBT16ToUInt16( pPicS->dyaCropBottom );
740 pPic->brcl = pPicS->aBits1 & 0x0f;
741 pPic->fFrameEmpty = (pPicS->aBits1 & 0x10) >> 4;
742 pPic->fBitmap = (pPicS->aBits1 & 0x20) >> 5;
743 pPic->fDrawHatch = (pPicS->aBits1 & 0x40) >> 6;
744 pPic->fError = (pPicS->aBits1 & 0x80) >> 7;
745 pPic->bpp = pPicS->aBits2;
748 void WW8FSPAShadowToReal( WW8_FSPA_SHADOW const * pFSPAS, WW8_FSPA * pFSPA )
750 pFSPA->nSpId = SVBT32ToUInt32( pFSPAS->nSpId );
751 pFSPA->nXaLeft = SVBT32ToUInt32( pFSPAS->nXaLeft );
752 pFSPA->nYaTop = SVBT32ToUInt32( pFSPAS->nYaTop );
753 pFSPA->nXaRight = SVBT32ToUInt32( pFSPAS->nXaRight );
754 pFSPA->nYaBottom = SVBT32ToUInt32( pFSPAS->nYaBottom );
756 sal_uInt16 nBits = SVBT16ToUInt16( pFSPAS->aBits1 );
758 pFSPA->bHdr = sal_uInt16(0 != ( nBits & 0x0001 ));
759 pFSPA->nbx = ( nBits & 0x0006 ) >> 1;
760 pFSPA->nby = ( nBits & 0x0018 ) >> 3;
761 pFSPA->nwr = ( nBits & 0x01E0 ) >> 5;
762 pFSPA->nwrk = ( nBits & 0x1E00 ) >> 9;
763 pFSPA->bRcaSimple = sal_uInt16(0 != ( nBits & 0x2000 ));
764 pFSPA->bBelowText = sal_uInt16(0 != ( nBits & 0x4000 ));
765 pFSPA->bAnchorLock = sal_uInt16(0 != ( nBits & 0x8000 ));
766 pFSPA->nTxbx = SVBT32ToUInt32( pFSPAS->nTxbx );
769 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */