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>
28 #include <unotools/configmgr.hxx>
30 #include <fmtanchr.hxx>
31 #include <fmtcntnt.hxx>
35 #include <IDocumentLayoutAccess.hxx>
37 #include "writerwordglue.hxx"
38 #include "ww8struc.hxx"
39 #include "ww8scan.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()
69 // consider new parameter <_bInHeaderFooter>
70 void wwZOrderer::InsertEscherObject( SdrObject
* pObject
,
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
)
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 _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
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
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
)
128 nRet
+= aIter
->mnNoInlines
+ 1;
132 while (aIter
!= aEnd
)
134 // insert object in page header|footer
135 // before objects in page body
136 if ( _bInHeaderFooter
&& !aIter
->mbInHeaderFooter
)
140 if ( aIter
->mnEscherShapeOrder
> nFound
)
142 nRet
+= aIter
->mnNoInlines
+1;
145 maEscherLayer
.insert(aIter
, EscherShape( nFound
, _bInHeaderFooter
) );
149 // InsertObj() adds the object into the Sw-Page and memorize the Z-position
151 void wwZOrderer::InsertDrawingObject(SdrObject
* pObj
, short nWwHeight
)
153 sal_uLong nPos
= GetDrawingObjectPos(nWwHeight
);
154 if (nWwHeight
& 0x2000) // Heaven ?
155 maSetLayer
.SendObjectToHeaven(*pObj
);
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
);
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())
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
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
;
233 case 94: // BMP-file ( not embedded ) or GIF
234 case 99: // TIFF-file ( not embedded )
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
247 bool bOk
= checkSeek(*pSt
, nPosFc
) && ReadWindowMetafile( *pSt
, aWMF
);
249 if (!bOk
|| pSt
->GetError() || !aWMF
.GetActionSize())
252 //skip duplicate graphics when fuzzing
253 if (utl::ConfigManager::IsFuzzing())
255 if (!m_aGrafPosSet
.insert(nPosFc
).second
)
259 if (m_xWwFib
->m_envr
!= 1) // !MAC as creator
261 rpGraphic
.reset(new Graphic(aWMF
));
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
270 tools::Long nData
= rPic
.lcb
- ( pSt
->Tell() - nPosFc
);
273 rpGraphic
.reset(new Graphic());
274 bOk
= SwWW8ImplReader::GetPictGrafFromStream(*rpGraphic
, *pSt
);
278 return bOk
; // Contains graphic
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
);
306 nWidth
= nCurrentWidth
* rPic
.mx
/ 1000; // Writer Size
307 nHeight
= nCurrentHeight
* rPic
.my
/ 1000;
310 void SwWW8ImplReader::ReplaceObj(const SdrObject
&rReplaceObj
,
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());
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
)
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();
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
,
388 // Resize the frame to the size of the picture if graphic is inside a frame
389 // (only if auto-width)
391 m_xSFlyPara
->BoxUpWidth( rPD
.nWidth
);
395 SwFrameFormat
* SwWW8ImplReader::ImportGraf1(WW8_PIC
const & rPic
, SvStream
* pSt
,
398 SwFrameFormat
* pRet
= nullptr;
399 if( pSt
->eof() || rPic
.fError
|| rPic
.MFP
.mm
== 99 )
404 std::unique_ptr
<Graphic
> pGraph
;
405 bool bOk
= ReadGrafFile(aFileName
, pGraph
, rPic
, pSt
, nFilePos
, &bInDoc
);
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
);
424 pRet
= MakeGrafInContent(rPic
, aPD
, pGraph
.get(), aFileName
, aGrfSet
);
428 void SwWW8ImplReader::PicRead(SvStream
*pDataStream
, WW8_PIC
*pPic
,
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
);
440 pDataStream
->SeekRel(2); //cProps
445 SwNodeType
GetNodeType(SwFrameFormat
const &rSource
)
447 const SwNodeIndex
* pNodeIndex
= rSource
.GetContent().GetContentIdx();
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;
461 ((m_pStrm
== m_pDataStream
) && !m_nPicLocFc
) ||
462 (m_nIniFlags
& WW8FL_NO_GRAF
)
468 ::SetProgressState(m_nProgress
, m_pDocShell
); // Update
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();
479 bool bValid
= checkSeek(*m_pDataStream
, m_nPicLocFc
);
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.
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
));
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 );
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;
552 // Horizontal rule may have its width given as % of page
553 // width (-1 is used if not given, 0 means the object has
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
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
);
590 WW8FlySet
aFlySet( *this, m_pPaM
, aPic
, aPD
.nWidth
,
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
604 aAttrSet
.Put( SwFormatFrameSize( SwFrameSize::Fixed
, aPD
.nWidth
,
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
);
619 MatchEscherMirrorIntoFlySet(*pRecord
, aGrSet
);
621 // if necessary adopt old AttrSet and correct horizontal
622 // positioning relation
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
);
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
);
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());
659 pRet
= m_rDoc
.getIDocumentContentOperations().InsertGraphic(
660 *m_pPaM
, OUString(), OUString(),
661 &rGraph
, &aAttrSet
, &aGrSet
, nullptr );
665 pRet
= m_rDoc
.getIDocumentContentOperations().InsertDrawObj(*m_pPaM
, *pObject
, aAttrSet
);
669 // only if we made an *Insert*
673 SetAttributesAtGrfNode(pRecord
, pRet
, nullptr);
675 OUString
aObjectName(pObject
->GetName());
676 if (aObjectName
.isEmpty() || !m_rDoc
.FindFlyByName(aObjectName
, GetNodeType(*pRet
)))
677 pRet
->SetName(aObjectName
);
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,
690 // delete and destroy old SdrGrafObj from page
691 if (pObject
->getSdrPageFromSdrObject())
692 m_pDrawPg
->RemoveObject(pObject
->GetOrdNum());
693 SdrObject::Free( pObject
);
697 m_xMSDffManager
->RemoveFromShapeOrder( pObject
);
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
);
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: */