1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
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>
29 #include <fmtanchr.hxx>
30 #include <fmtcntnt.hxx>
34 #include <IDocumentLayoutAccess.hxx>
36 #include "writerwordglue.hxx"
37 #include "ww8struc.hxx"
38 #include "ww8scan.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()
68 // consider new parameter <_bInHeaderFooter>
69 void wwZOrderer::InsertEscherObject( SdrObject
* pObject
,
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
)
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
)
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
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
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
)
129 nRet
+= aIter
->mnNoInlines
+ 1;
135 while (aIter
!= aEnd
)
137 if (!aIter
->mbInHellLayer
|| (_bInHeaderFooter
&& !aIter
->mbInHeaderFooter
))
139 nRet
+= aIter
->mnNoInlines
+ 1;
143 while (aIter
!= aEnd
)
145 // insert object in page header|footer
146 // before objects in page body
147 if ( _bInHeaderFooter
&& !aIter
->mbInHeaderFooter
)
151 if ( bInHellLayer
&& !aIter
->mbInHellLayer
)
154 if ( aIter
->mnEscherShapeOrder
> nFound
)
156 nRet
+= aIter
->mnNoInlines
+1;
159 maEscherLayer
.insert(aIter
, EscherShape( nFound
, bInHellLayer
, _bInHeaderFooter
) );
163 // InsertObj() adds the object into the Sw-Page and memorize the Z-position
165 void wwZOrderer::InsertDrawingObject(SdrObject
* pObj
, short nWwHeight
)
167 sal_uLong nPos
= GetDrawingObjectPos(nWwHeight
);
168 if (nWwHeight
& 0x2000) // Heaven ?
169 maSetLayer
.SendObjectToHeaven(*pObj
);
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
);
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())
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
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
;
247 case 94: // BMP-file ( not embedded ) or GIF
248 case 99: // TIFF-file ( not embedded )
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
263 if (!m_aGrafPosSet
.insert(nPosFc
).second
)
268 bool bOk
= checkSeek(*pSt
, nPosFc
) && ReadWindowMetafile( *pSt
, aWMF
);
270 if (!bOk
|| pSt
->GetError() || !aWMF
.GetActionSize())
273 if (m_xWwFib
->m_envr
!= 1) // !MAC as creator
275 roGraphic
.emplace(aWMF
);
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
284 tools::Long nData
= rPic
.lcb
- ( pSt
->Tell() - nPosFc
);
288 bOk
= SwWW8ImplReader::GetPictGrafFromStream(*roGraphic
, *pSt
);
292 return bOk
; // Contains graphic
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
);
320 nWidth
= nCurrentWidth
* rPic
.mx
/ 1000; // Writer Size
321 nHeight
= nCurrentHeight
* rPic
.my
/ 1000;
324 void SwWW8ImplReader::ReplaceObj(const SdrObject
&rReplaceObj
,
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());
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
)
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();
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
,
402 // Resize the frame to the size of the picture if graphic is inside a frame
403 // (only if auto-width)
405 m_xSFlyPara
->BoxUpWidth( rPD
.nWidth
);
409 SwFrameFormat
* SwWW8ImplReader::ImportGraf1(WW8_PIC
const & rPic
, SvStream
* pSt
,
412 SwFrameFormat
* pRet
= nullptr;
413 if( pSt
->eof() || rPic
.fError
|| rPic
.MFP
.mm
== 99 )
418 std::optional
<Graphic
> oGraph
;
419 bool bOk
= ReadGrafFile(aFileName
, oGraph
, rPic
, pSt
, nFilePos
, &bInDoc
);
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
);
438 pRet
= MakeGrafInContent(rPic
, aPD
, oGraph
? &*oGraph
: nullptr, aFileName
, aGrfSet
);
442 bool SwWW8ImplReader::PicRead(SvStream
*pDataStream
, WW8_PIC
*pPic
,
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();
455 pDataStream
->SeekRel(2); //cProps
461 SwNodeType
GetNodeType(SwFrameFormat
const &rSource
)
463 const SwNodeIndex
* pNodeIndex
= rSource
.GetContent().GetContentIdx();
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;
477 ((m_pStrm
== m_pDataStream
) && !m_nPicLocFc
) ||
478 (m_nIniFlags
& WW8FL_NO_GRAF
)
484 ::SetProgressState(m_nProgress
, m_pDocShell
); // Update
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();
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.
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
));
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 );
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;
565 // Horizontal rule may have its width given as % of page
566 // width (-1 is used if not given, 0 means the object has
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
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
);
603 WW8FlySet
aFlySet( *this, m_pPaM
, aPic
, aPD
.nWidth
,
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
617 aAttrSet
.Put( SwFormatFrameSize( SwFrameSize::Fixed
, aPD
.nWidth
,
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
);
631 MatchEscherMirrorIntoFlySet(*pRecord
, aGrSet
);
633 // if necessary adopt old AttrSet and correct horizontal
634 // positioning relation
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
);
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
);
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());
671 pRet
= m_rDoc
.getIDocumentContentOperations().InsertGraphic(
672 *m_pPaM
, OUString(), OUString(),
673 &rGraph
, &aAttrSet
, &aGrSet
, nullptr );
677 pRet
= m_rDoc
.getIDocumentContentOperations().InsertDrawObj(*m_pPaM
, *pObject
, aAttrSet
);
681 // only if we made an *Insert*
685 SetAttributesAtGrfNode(*pRecord
, *pRet
, nullptr);
687 OUString
aObjectName(pObject
->GetName());
688 if (aObjectName
.isEmpty() || !m_rDoc
.FindFlyByName(aObjectName
, GetNodeType(*pRet
)))
689 pRet
->SetFormatName(aObjectName
);
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,
702 // delete and destroy old SdrGrafObj from page
703 if (pObject
->getSdrPageFromSdrObject())
704 m_pDrawPg
->RemoveObject(pObject
->GetOrdNum());
709 m_xMSDffManager
->RemoveFromShapeOrder( pObject
.get() );
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
);
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: */