android: Update app-specific/MIME type icons
[LibreOffice.git] / sw / source / filter / ww8 / ww8graf2.cxx
blob35219922db83a85f7fae1c72be5f8ef5d416be7d
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 <grfatr.hxx>
29 #include <fmtanchr.hxx>
30 #include <fmtcntnt.hxx>
31 #include <frmfmt.hxx>
32 #include <pam.hxx>
33 #include <doc.hxx>
34 #include <IDocumentLayoutAccess.hxx>
35 #include <mdiexp.hxx>
36 #include "writerwordglue.hxx"
37 #include "ww8struc.hxx"
38 #include "ww8scan.hxx"
39 #include "ww8par.hxx"
40 #include "ww8par2.hxx"
41 #include "ww8graf.hxx"
42 #include <vcl/gdimtf.hxx>
43 #include <vcl/graphicfilter.hxx>
44 #include <vcl/wmf.hxx>
46 using namespace ::com::sun::star;
47 using namespace sw::types;
49 wwZOrderer::wwZOrderer(const sw::util::SetLayer &rSetLayer, SdrPage* pDrawPg,
50 const SvxMSDffShapeOrders *pShapeOrders)
51 : maSetLayer(rSetLayer), mnInlines(0), mpDrawPg(pDrawPg),
52 mpShapeOrders(pShapeOrders)
54 mnNoInitialObjects = mpDrawPg->GetObjCount();
55 OSL_ENSURE(mpDrawPg,"Missing draw page impossible!");
58 void wwZOrderer::InsideEscher(sal_uLong nSpId)
60 maIndexes.push(GetEscherObjectIdx(nSpId));
63 void wwZOrderer::OutsideEscher()
65 maIndexes.pop();
68 // consider new parameter <_bInHeaderFooter>
69 void wwZOrderer::InsertEscherObject( SdrObject* pObject,
70 sal_uLong nSpId,
71 const bool bInHellLayer,
72 const bool _bInHeaderFooter )
74 sal_uLong nInsertPos = GetEscherObjectPos( nSpId, bInHellLayer, _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 bInHellLayer,
104 const bool _bInHeaderFooter )
107 EscherObjects have their own ordering which needs to be matched to
108 the actual ordering that should be used when inserting them into the
109 document.
111 sal_uInt16 nFound = GetEscherObjectIdx(nSpId);
112 // Match the ordering position from the ShapeOrders to the ordering of all
113 // objects in the document, there is a complexity when escherobjects
114 // contain inlines objects, we need to consider those as part of the
115 // escher count
116 sal_uLong nRet=0;
117 myeiter aIter = maEscherLayer.begin();
118 myeiter aEnd = maEscherLayer.end();
119 // skip objects in page header|footer,
120 // if current object isn't in page header|footer
121 if ( !_bInHeaderFooter )
123 while ( aIter != aEnd )
125 if ( !aIter->mbInHeaderFooter )
127 break;
129 nRet += aIter->mnNoInlines + 1;
130 ++aIter;
133 if (!bInHellLayer)
135 while (aIter != aEnd)
137 if (!aIter->mbInHellLayer || (_bInHeaderFooter && !aIter->mbInHeaderFooter))
138 break;
139 nRet += aIter->mnNoInlines + 1;
140 ++aIter;
143 while (aIter != aEnd)
145 // insert object in page header|footer
146 // before objects in page body
147 if ( _bInHeaderFooter && !aIter->mbInHeaderFooter )
149 break;
151 if ( bInHellLayer && !aIter->mbInHellLayer )
152 break;
154 if ( aIter->mnEscherShapeOrder > nFound )
155 break;
156 nRet += aIter->mnNoInlines+1;
157 ++aIter;
159 maEscherLayer.insert(aIter, EscherShape( nFound, bInHellLayer, _bInHeaderFooter ) );
160 return nRet;
163 // InsertObj() adds the object into the Sw-Page and memorize the Z-position
164 // in a VarArr
165 void wwZOrderer::InsertDrawingObject(SdrObject* pObj, short nWwHeight)
167 sal_uLong nPos = GetDrawingObjectPos(nWwHeight);
168 if (nWwHeight & 0x2000) // Heaven ?
169 maSetLayer.SendObjectToHeaven(*pObj);
170 else
171 maSetLayer.SendObjectToHell(*pObj);
173 InsertObject(pObj, nPos + mnNoInitialObjects + mnInlines);
176 void wwZOrderer::InsertTextLayerObject(SdrObject* pObject)
178 maSetLayer.SendObjectToHeaven(*pObject);
179 if (maIndexes.empty())
181 InsertObject(pObject, mnNoInitialObjects + mnInlines);
182 ++mnInlines;
184 else
186 //If we are inside an escher objects, place us just after that
187 //escher obj, and increment its inline count
188 sal_uInt16 nIdx = maIndexes.top();
189 myeiter aEnd = MapEscherIdxToIter(nIdx);
191 sal_uLong nInsertPos = std::accumulate(maEscherLayer.begin(), aEnd, sal_uLong(0),
192 [](const sal_uLong nPos, const EscherShape& rShape) { return nPos + rShape.mnNoInlines + 1; });
194 OSL_ENSURE(aEnd != maEscherLayer.end(), "Something very wrong here");
195 if (aEnd != maEscherLayer.end())
197 aEnd->mnNoInlines++;
198 nInsertPos += aEnd->mnNoInlines;
201 InsertObject(pObject, mnNoInitialObjects + mnInlines + nInsertPos);
205 /* Parallel to the Obj-array in the document I also build an array which
206 * contains the Ww-height (-> what covers what).
207 * Based on this VARARR the position where the insertion happens is
208 * determined.
209 * When inserting the offset in an existing document with a graphic layer the
210 * caller has to increment the index by mnNoInitialObjects, so that the new
211 * objects are added at the end (inserting is faster then)
213 sal_uLong wwZOrderer::GetDrawingObjectPos(short nWwHeight)
215 auto aIter = std::find_if(
216 maDrawHeight.begin(), maDrawHeight.end(),
217 [nWwHeight](short aHeight){ return (aHeight & 0x1fff) > (nWwHeight & 0x1fff); });
219 aIter = maDrawHeight.insert(aIter, nWwHeight);
220 return std::distance(maDrawHeight.begin(), aIter);
223 void wwZOrderer::InsertObject(SdrObject* pObject, sal_uLong nPos)
225 if (!pObject->IsInserted())
227 mpDrawPg->InsertObject(pObject, nPos);
231 static void WW8PicShadowToReal( WW8_PIC_SHADOW const * pPicS, WW8_PIC* pPic );
233 bool SwWW8ImplReader::GetPictGrafFromStream(Graphic& rGraphic, SvStream& rSrc)
235 return ERRCODE_NONE == GraphicFilter::GetGraphicFilter().ImportGraphic(rGraphic, u"", rSrc);
238 bool SwWW8ImplReader::ReadGrafFile(OUString& rFileName, std::optional<Graphic>& roGraphic,
239 const WW8_PIC& rPic, SvStream* pSt, sal_uLong nFilePos, bool* pbInDoc)
240 { // Write the graphic to the file
241 *pbInDoc = true; // default
243 sal_uLong nPosFc = nFilePos + rPic.cbHeader;
245 switch (rPic.MFP.mm)
247 case 94: // BMP-file ( not embedded ) or GIF
248 case 99: // TIFF-file ( not embedded )
249 pSt->Seek(nPosFc);
250 // read name as P-string
251 rFileName = read_uInt8_PascalString(*pSt, m_eStructCharSet);
252 if (!rFileName.isEmpty())
253 rFileName = URIHelper::SmartRel2Abs(
254 INetURLObject(m_sBaseURL), rFileName,
255 URIHelper::GetMaybeFileHdl());
256 *pbInDoc = false; // Don't delete the file afterwards
257 return !rFileName.isEmpty(); // read was successful
260 //skip duplicate graphics when fuzzing
261 if (m_bFuzzing)
263 if (!m_aGrafPosSet.insert(nPosFc).second)
264 return false;
267 GDIMetaFile aWMF;
268 bool bOk = checkSeek(*pSt, nPosFc) && ReadWindowMetafile( *pSt, aWMF );
270 if (!bOk || pSt->GetError() || !aWMF.GetActionSize())
271 return false;
273 if (m_xWwFib->m_envr != 1) // !MAC as creator
275 roGraphic.emplace(aWMF);
276 return true;
279 // MAC - word as creator
280 // The WMF only says "Please use Word 6.0c" and Mac-Pict follows but without
281 // the first 512 Bytes which are not relevant in a MAC-PICT (they are not
282 // interpreted)
283 bOk = false;
284 tools::Long nData = rPic.lcb - ( pSt->Tell() - nPosFc );
285 if (nData > 0)
287 roGraphic.emplace();
288 bOk = SwWW8ImplReader::GetPictGrafFromStream(*roGraphic, *pSt);
289 if (!bOk)
290 roGraphic.reset();
292 return bOk; // Contains graphic
295 struct WW8PicDesc
297 sal_Int16 nCL, nCR, nCT, nCB;
298 tools::Long nWidth, nHeight;
300 explicit WW8PicDesc( const WW8_PIC& rPic );
303 WW8PicDesc::WW8PicDesc( const WW8_PIC& rPic )
304 : nCL(rPic.dxaCropLeft),
305 nCR(rPic.dxaCropRight),
306 nCT(rPic.dyaCropTop),
307 nCB(rPic.dyaCropBottom)
309 //See #i21190# before fiddling with this method
310 tools::Long nOriWidth = rPic.dxaGoal; //Size in 1/100 mm before crop
311 tools::Long nOriHeight = rPic.dyaGoal;
314 tools::Long nCurrentWidth = nOriWidth - (nCL + nCR); // Size after crop
315 tools::Long nCurrentHeight = nOriHeight - (nCT + nCB);
316 if (!nCurrentWidth)
317 nCurrentWidth = 1;
318 if (!nCurrentHeight)
319 nCurrentHeight = 1;
320 nWidth = nCurrentWidth * rPic.mx / 1000; // Writer Size
321 nHeight = nCurrentHeight * rPic.my / 1000;
324 void SwWW8ImplReader::ReplaceObj(const SdrObject &rReplaceObj,
325 SdrObject &rSubObj)
327 // Insert SdrGrafObj instead of SdrTextObj into this group
328 if (SdrObject* pGroupObject = rReplaceObj.getParentSdrObjectFromSdrObject())
330 SdrObjList* pObjectList = pGroupObject->GetSubList();
332 rSubObj.SetLogicRect(rReplaceObj.GetCurrentBoundRect());
333 rSubObj.SetLayer(rReplaceObj.GetLayer());
335 // remove old object from group-list and add new one
336 // (this also exchanges it in the drawing page)
337 pObjectList->ReplaceObject(&rSubObj, rReplaceObj.GetOrdNum());
339 else
341 OSL_ENSURE( false, "Impossible!");
345 // MakeGrafNotInContent inserts a non character bound graphic
346 // ( bGrafApo == true)
347 SwFlyFrameFormat* SwWW8ImplReader::MakeGrafNotInContent(const WW8PicDesc& rPD,
348 const Graphic* pGraph, const OUString& rFileName, const SfxItemSet& rGrfSet)
351 sal_uInt32 nWidth = rPD.nWidth;
352 sal_uInt32 nHeight = rPD.nHeight;
354 // Vertical shift through line spacing
355 sal_Int32 nNetHeight = nHeight + rPD.nCT + rPD.nCB;
356 if (m_xSFlyPara->nLineSpace && m_xSFlyPara->nLineSpace > nNetHeight)
357 m_xSFlyPara->nYPos =
358 o3tl::narrowing<sal_uInt16>( m_xSFlyPara->nYPos + m_xSFlyPara->nLineSpace - nNetHeight );
360 WW8FlySet aFlySet(*this, m_xWFlyPara.get(), m_xSFlyPara.get(), true);
362 SwFormatAnchor aAnchor(WW8SwFlyPara::eAnchor);
363 aAnchor.SetAnchor(m_pPaM->GetPoint());
364 aFlySet.Put(aAnchor);
366 aFlySet.Put( SwFormatFrameSize( SwFrameSize::Fixed, nWidth, nHeight ) );
368 SwFlyFrameFormat *const pFlyFormat =
369 m_rDoc.getIDocumentContentOperations().InsertGraphic(
370 *m_pPaM, rFileName, OUString(), pGraph,
371 &aFlySet, &rGrfSet, nullptr);
373 // So the frames are generated when inserted in an existing doc:
374 if (m_rDoc.getIDocumentLayoutAccess().GetCurrentViewShell() &&
375 (RndStdIds::FLY_AT_PARA == pFlyFormat->GetAnchor().GetAnchorId()))
377 pFlyFormat->MakeFrames();
379 return pFlyFormat;
382 // MakeGrafInContent inserts a character bound graphic
383 SwFrameFormat* SwWW8ImplReader::MakeGrafInContent(const WW8_PIC& rPic,
384 const WW8PicDesc& rPD, const Graphic* pGraph, const OUString& rFileName,
385 const SfxItemSet& rGrfSet)
387 WW8FlySet aFlySet(*this, m_pPaM, rPic, rPD.nWidth, rPD.nHeight);
389 SwFrameFormat* pFlyFormat = nullptr;
391 if (rFileName.isEmpty() && m_nObjLocFc) // then it should be an OLE-Object
392 pFlyFormat = ImportOle(pGraph, &aFlySet, &rGrfSet);
394 if( !pFlyFormat ) // then just as graphic
397 pFlyFormat = m_rDoc.getIDocumentContentOperations().InsertGraphic(
398 *m_pPaM, rFileName, OUString(), pGraph, &aFlySet,
399 &rGrfSet, nullptr);
402 // Resize the frame to the size of the picture if graphic is inside a frame
403 // (only if auto-width)
404 if (m_xSFlyPara)
405 m_xSFlyPara->BoxUpWidth( rPD.nWidth );
406 return pFlyFormat;
409 SwFrameFormat* SwWW8ImplReader::ImportGraf1(WW8_PIC const & rPic, SvStream* pSt,
410 sal_uLong nFilePos )
412 SwFrameFormat* pRet = nullptr;
413 if( pSt->eof() || rPic.fError || rPic.MFP.mm == 99 )
414 return nullptr;
416 OUString aFileName;
417 bool bInDoc;
418 std::optional<Graphic> oGraph;
419 bool bOk = ReadGrafFile(aFileName, oGraph, rPic, pSt, nFilePos, &bInDoc);
421 if (!bOk)
423 return nullptr; // Graphic could not be read correctly
426 WW8PicDesc aPD( rPic );
428 SwAttrSet aGrfSet( m_rDoc.GetAttrPool(), RES_GRFATR_BEGIN, RES_GRFATR_END-1);
429 if( aPD.nCL || aPD.nCR || aPD.nCT || aPD.nCB )
431 SwCropGrf aCrop( aPD.nCL, aPD.nCR, aPD.nCT, aPD.nCB) ;
432 aGrfSet.Put( aCrop );
435 if (m_xWFlyPara && m_xWFlyPara->bGrafApo)
436 pRet = MakeGrafNotInContent(aPD, oGraph ? &*oGraph : nullptr, aFileName, aGrfSet);
437 else
438 pRet = MakeGrafInContent(rPic, aPD, oGraph ? &*oGraph : nullptr, aFileName, aGrfSet);
439 return pRet;
442 bool SwWW8ImplReader::PicRead(SvStream *pDataStream, WW8_PIC *pPic,
443 bool bVer67)
445 //Only the first 0x2e bytes are the same between version 6/7 and 8+
446 WW8_PIC_SHADOW aPicS{};
447 pDataStream->ReadBytes( &aPicS, sizeof( aPicS ) );
448 WW8PicShadowToReal( &aPicS, pPic );
449 for (WW8_BRC & i : pPic->rgbrc)
450 pDataStream->ReadBytes(&i, bVer67 ? 2 : 4);
451 pDataStream->ReadInt16( pPic->dxaOrigin );
452 pDataStream->ReadInt16( pPic->dyaOrigin );
453 bool bOk = pDataStream->good();
454 if (!bVer67)
455 pDataStream->SeekRel(2); //cProps
456 return bOk;
459 namespace
461 SwNodeType GetNodeType(SwFrameFormat const &rSource)
463 const SwNodeIndex* pNodeIndex = rSource.GetContent().GetContentIdx();
464 if (!pNodeIndex)
465 return SwNodeType::NONE;
466 const SwNode& rCSttNd = pNodeIndex->GetNode();
467 SwNodeRange aRg(rCSttNd, SwNodeOffset(1), *rCSttNd.EndOfSectionNode());
468 return aRg.aStart.GetNode().GetNodeType();
472 SwFrameFormat* SwWW8ImplReader::ImportGraf(SdrTextObj const * pTextObj,
473 SwFrameFormat const * pOldFlyFormat)
475 SwFrameFormat* pRet = nullptr;
476 if (
477 ((m_pStrm == m_pDataStream ) && !m_nPicLocFc) ||
478 (m_nIniFlags & WW8FL_NO_GRAF)
481 return nullptr;
484 ::SetProgressState(m_nProgress, m_pDocShell); // Update
486 GraphicCtor();
489 * Little joke from Microsoft: sometimes a stream named DATA exists. This
490 * stream then contains the PICF and the corresponding graphic!
491 * We otherwise map the variable pDataStream to pStream.
493 auto nOldPos = m_pDataStream->Tell();
494 WW8_PIC aPic;
495 bool bValid = checkSeek(*m_pDataStream, m_nPicLocFc) &&
496 PicRead(m_pDataStream, &aPic, m_bVer67);
498 // Sanity check is needed because for example check boxes in field results
499 // contain a WMF-like struct
500 if (bValid && aPic.lcb >= 58)
502 if( m_pFlyFormatOfJustInsertedGraphic )
504 // We just added a graphic-link into the doc. Now we need to set
505 // its position and scale it.
506 WW8PicDesc aPD( aPic );
508 WW8FlySet aFlySet( *this, m_pPaM, aPic, aPD.nWidth, aPD.nHeight );
510 // the correct anchor is set in Read_F_IncludePicture and the
511 // current PaM point is after the position if it is anchored in
512 // content; because this anchor add a character into the textnode.
513 // #i2806#
514 if (RndStdIds::FLY_AS_CHAR ==
515 m_pFlyFormatOfJustInsertedGraphic->GetAnchor().GetAnchorId() )
517 aFlySet.ClearItem( RES_ANCHOR );
520 m_pFlyFormatOfJustInsertedGraphic->SetFormatAttr( aFlySet );
522 m_pFlyFormatOfJustInsertedGraphic = nullptr;
524 else if((0x64 == aPic.MFP.mm) || (0x66 == aPic.MFP.mm))
526 // linked graphic in ESCHER-Object
527 rtl::Reference<SdrObject> pObject;
529 WW8PicDesc aPD( aPic );
530 if (!m_xMSDffManager)
531 m_xMSDffManager.reset(new SwMSDffManager(*this, m_bSkipImages));
532 /* ##835##
533 * Disable use of main stream as fallback stream for inline direct
534 * blips as it is known that they are directly after the record
535 * header, testing for existence in main stream may lead to an
536 * incorrect fallback graphic being found if other escher graphics
537 * have been inserted in the document
539 m_xMSDffManager->DisableFallbackStream();
540 if (!m_xMSDffManager->GetModel())
541 m_xMSDffManager->SetModel(m_pDrawModel, 1440);
543 if (0x66 == aPic.MFP.mm)
545 //These ones have names prepended
546 sal_uInt8 nNameLen=0;
547 m_pDataStream->ReadUChar( nNameLen );
548 m_pDataStream->SeekRel( nNameLen );
551 tools::Rectangle aClientRect( 0,0, aPD.nWidth, aPD.nHeight);
552 SvxMSDffImportData aData( aClientRect );
553 pObject = m_xMSDffManager->ImportObj(*m_pDataStream, aData, aClientRect, tools::Rectangle(), /*nCalledByGroup*/0, /*pShapeId*/nullptr );
554 if (pObject)
556 // for the frame
557 SfxItemSetFixed<RES_FRMATR_BEGIN, RES_FRMATR_END-1> aAttrSet( m_rDoc.GetAttrPool() );
559 SvxMSDffImportRec const*const pRecord = (1 == aData.size())
560 ? aData.begin()->get() : nullptr;
562 if( pRecord )
565 // Horizontal rule may have its width given as % of page
566 // width (-1 is used if not given, 0 means the object has
567 // fixed width).
568 // Additionally, if it's a horizontal rule without width
569 // given, assume 100.0% width.
570 int relativeWidth = pRecord->relativeHorizontalWidth;
571 if( relativeWidth == -1 )
572 relativeWidth = pRecord->isHorizontalRule ? 1000 : 0;
573 if( relativeWidth != 0 )
575 const sal_Int16 nScale = aPic.dxaGoal ? aPic.dxaGoal : 1000;
576 aPic.mx = msword_cast<sal_uInt16>(
577 m_aSectionManager.GetPageWidth() -
578 m_aSectionManager.GetPageRight() -
579 m_aSectionManager.GetPageLeft()) * relativeWidth / nScale;
580 aPD = WW8PicDesc( aPic );
581 // This SetSnapRect() call adjusts the size of the
582 // object itself, no idea why it's this call (or even
583 // what the call actually does), but that's what
584 // ImportGraf() (called by ImportObj()) uses.
585 pObject->SetSnapRect( tools::Rectangle( 0, 0, aPD.nWidth, aPD.nHeight ));
588 // A graphic of this type in this location is always
589 // inline, and uses the pic in the same module as ww6
590 // graphics.
591 if (m_xWFlyPara && m_xWFlyPara->bGrafApo)
593 WW8FlySet aFlySet(*this, m_xWFlyPara.get(), m_xSFlyPara.get(), true);
595 SwFormatAnchor aAnchor(WW8SwFlyPara::eAnchor);
596 aAnchor.SetAnchor(m_pPaM->GetPoint());
597 aFlySet.Put(aAnchor);
599 aAttrSet.Put(aFlySet);
601 else
603 WW8FlySet aFlySet( *this, m_pPaM, aPic, aPD.nWidth,
604 aPD.nHeight );
606 aAttrSet.Put(aFlySet);
608 // Modified for i120716,for graf importing from MS Word 2003
609 // binary format, there is no border distance.
610 tools::Rectangle aInnerDist(0,0,0,0);
611 MatchSdrItemsIntoFlySet( pObject.get(), aAttrSet,
612 pRecord->eLineStyle, pRecord->eLineDashing,
613 pRecord->eShapeType, aInnerDist );
615 // Set the size from the WinWord PIC-structure as graphic
616 // size
617 aAttrSet.Put( SwFormatFrameSize( SwFrameSize::Fixed, aPD.nWidth,
618 aPD.nHeight ) );
621 // for the graphic
622 SfxItemSetFixed<RES_GRFATR_BEGIN, RES_GRFATR_END-1> aGrSet( m_rDoc.GetAttrPool() );
624 if( aPD.nCL || aPD.nCR || aPD.nCT || aPD.nCB )
626 SwCropGrf aCrop( aPD.nCL, aPD.nCR, aPD.nCT, aPD.nCB );
627 aGrSet.Put( aCrop );
630 if (pRecord)
631 MatchEscherMirrorIntoFlySet(*pRecord, aGrSet);
633 // if necessary adopt old AttrSet and correct horizontal
634 // positioning relation
635 if( pOldFlyFormat )
637 aAttrSet.Put( pOldFlyFormat->GetAttrSet() );
638 const SwFormatHoriOrient &rHori = pOldFlyFormat->GetHoriOrient();
639 if( text::RelOrientation::FRAME == rHori.GetRelationOrient() )
641 aAttrSet.Put( SwFormatHoriOrient( rHori.GetPos(),
642 text::HoriOrientation::NONE, text::RelOrientation::PAGE_PRINT_AREA ) );
646 bool bTextObjWasGrouped = false;
647 if (pOldFlyFormat && pTextObj && pTextObj->getParentSdrObjectFromSdrObject())
648 bTextObjWasGrouped = true;
650 if (bTextObjWasGrouped)
651 ReplaceObj(*pTextObj, *pObject);
652 else
654 if (SdrObjKind::OLE2 == pObject->GetObjIdentifier())
656 // the size from BLIP, if there is any, should be already set
657 pRet = InsertOle(*static_cast<SdrOle2Obj*>(pObject.get()), aAttrSet, &aGrSet);
659 else
661 if (SdrGrafObj* pGraphObject = dynamic_cast<SdrGrafObj*>( pObject.get()) )
663 // Now add the link or rather the graphic to the doc
664 const Graphic& rGraph = pGraphObject->GetGraphic();
666 if (m_nObjLocFc) // is it an OLE-Object?
667 pRet = ImportOle(&rGraph, &aAttrSet, &aGrSet, pObject->GetBLIPSizeRectangle());
669 if (!pRet)
671 pRet = m_rDoc.getIDocumentContentOperations().InsertGraphic(
672 *m_pPaM, OUString(), OUString(),
673 &rGraph, &aAttrSet, &aGrSet, nullptr );
676 else
677 pRet = m_rDoc.getIDocumentContentOperations().InsertDrawObj(*m_pPaM, *pObject, aAttrSet );
681 // only if we made an *Insert*
682 if (pRet)
684 if (pRecord)
685 SetAttributesAtGrfNode(*pRecord, *pRet, nullptr);
687 OUString aObjectName(pObject->GetName());
688 if (aObjectName.isEmpty() || !m_rDoc.FindFlyByName(aObjectName, GetNodeType(*pRet)))
689 pRet->SetFormatName(aObjectName);
690 else
691 m_aGrfNameGenerator.SetUniqueGraphName(pRet, aObjectName);
693 // determine the pointer to the new object and update
694 // Z-order-list accordingly (or delete entry)
695 if (SdrObject* pOurNewObject = CreateContactObject(pRet))
697 if (pOurNewObject != pObject.get())
699 m_xMSDffManager->ExchangeInShapeOrder( pObject.get(), 0,
700 pOurNewObject );
702 // delete and destroy old SdrGrafObj from page
703 if (pObject->getSdrPageFromSdrObject())
704 m_pDrawPg->RemoveObject(pObject->GetOrdNum());
705 pObject.clear();
708 else
709 m_xMSDffManager->RemoveFromShapeOrder( pObject.get() );
711 else
712 m_xMSDffManager->RemoveFromShapeOrder( pObject.get() );
714 // also delete this from the page if not grouped
715 if (pTextObj && !bTextObjWasGrouped && pTextObj->getSdrPageFromSdrObject())
716 m_pDrawPg->RemoveObject( pTextObj->GetOrdNum() );
718 m_xMSDffManager->EnableFallbackStream();
720 else if (aPic.lcb >= 58)
721 pRet = ImportGraf1(aPic, m_pDataStream, m_nPicLocFc);
723 m_pDataStream->Seek( nOldPos );
725 if (pRet)
727 SdrObject* pOurNewObject = CreateContactObject(pRet);
728 m_xWWZOrder->InsertTextLayerObject(pOurNewObject);
731 return AddAutoAnchor(pRet);
734 void WW8PicShadowToReal( WW8_PIC_SHADOW const * pPicS, WW8_PIC * pPic )
736 pPic->lcb = SVBT32ToUInt32( pPicS->lcb );
737 pPic->cbHeader = SVBT16ToUInt16( pPicS->cbHeader );
738 pPic->MFP.mm = SVBT16ToUInt16( pPicS->MFP.mm );
739 pPic->MFP.xExt = SVBT16ToUInt16( pPicS->MFP.xExt );
740 pPic->MFP.yExt = SVBT16ToUInt16( pPicS->MFP.yExt );
741 pPic->MFP.hMF = SVBT16ToUInt16( pPicS->MFP.hMF );
742 for( sal_uInt16 i = 0; i < 14 ; i++ )
743 pPic->rcWinMF[i] = pPicS->rcWinMF[i];
744 pPic->dxaGoal = SVBT16ToUInt16( pPicS->dxaGoal );
745 pPic->dyaGoal = SVBT16ToUInt16( pPicS->dyaGoal );
746 pPic->mx = SVBT16ToUInt16( pPicS->mx );
747 pPic->my = SVBT16ToUInt16( pPicS->my );
748 pPic->dxaCropLeft = SVBT16ToUInt16( pPicS->dxaCropLeft );
749 pPic->dyaCropTop = SVBT16ToUInt16( pPicS->dyaCropTop );
750 pPic->dxaCropRight = SVBT16ToUInt16( pPicS->dxaCropRight );
751 pPic->dyaCropBottom = SVBT16ToUInt16( pPicS->dyaCropBottom );
752 pPic->brcl = pPicS->aBits1 & 0x0f;
753 pPic->fFrameEmpty = (pPicS->aBits1 & 0x10) >> 4;
754 pPic->fBitmap = (pPicS->aBits1 & 0x20) >> 5;
755 pPic->fDrawHatch = (pPicS->aBits1 & 0x40) >> 6;
756 pPic->fError = (pPicS->aBits1 & 0x80) >> 7;
757 pPic->bpp = pPicS->aBits2;
760 void WW8FSPAShadowToReal(const WW8_FSPA_SHADOW& rFSPAS, WW8_FSPA& rFSPA)
762 rFSPA.nSpId = SVBT32ToUInt32(rFSPAS.nSpId);
763 rFSPA.nXaLeft = SVBT32ToUInt32(rFSPAS.nXaLeft);
764 rFSPA.nYaTop = SVBT32ToUInt32(rFSPAS.nYaTop);
765 rFSPA.nXaRight = SVBT32ToUInt32(rFSPAS.nXaRight);
766 rFSPA.nYaBottom = SVBT32ToUInt32(rFSPAS.nYaBottom);
768 sal_uInt16 nBits = SVBT16ToUInt16(rFSPAS.aBits1);
770 rFSPA.bHdr = sal_uInt16(0 != (nBits & 0x0001));
771 rFSPA.nbx = (nBits & 0x0006) >> 1;
772 rFSPA.nby = (nBits & 0x0018) >> 3;
773 rFSPA.nwr = (nBits & 0x01E0) >> 5;
774 rFSPA.nwrk = (nBits & 0x1E00) >> 9;
775 rFSPA.bRcaSimple = sal_uInt16(0 != (nBits & 0x2000));
776 rFSPA.bBelowText = sal_uInt16(0 != (nBits & 0x4000));
777 rFSPA.bAnchorLock = sal_uInt16(0 != (nBits & 0x8000));
778 rFSPA.nTxbx = SVBT32ToUInt32(rFSPAS.nTxbx);
781 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */