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 .
20 #include <com/sun/star/embed/Aspects.hpp>
22 #include <hintids.hxx>
24 #include <o3tl/any.hxx>
25 #include <vcl/cvtgrf.hxx>
26 #include <vcl/virdev.hxx>
27 #include <com/sun/star/drawing/XShape.hpp>
28 #include <vcl/svapp.hxx>
29 #include <sot/storage.hxx>
30 #include <vcl/graphicfilter.hxx>
31 #include <svl/itemiter.hxx>
32 #include <svl/whiter.hxx>
33 #include <svx/svdobj.hxx>
34 #include <svx/svdotext.hxx>
35 #include <svx/svdmodel.hxx>
36 #include <svx/svdpage.hxx>
37 #include <editeng/outlobj.hxx>
38 #include <editeng/editobj.hxx>
39 #include <svx/unoshape.hxx>
40 #include <editeng/brushitem.hxx>
41 #include <editeng/boxitem.hxx>
42 #include <editeng/lrspitem.hxx>
43 #include <editeng/ulspitem.hxx>
44 #include <editeng/fontitem.hxx>
45 #include <editeng/frmdiritem.hxx>
46 #include <svx/svdoole2.hxx>
47 #include <editeng/editeng.hxx>
48 #include <editeng/flditem.hxx>
49 #include <editeng/shaditem.hxx>
50 #include <unotools/ucbstreamhelper.hxx>
51 #include <svx/fmglob.hxx>
52 #include <svx/svdouno.hxx>
53 #include <svx/unoapi.hxx>
54 #include <svx/svdview.hxx>
55 #include <fmtcnct.hxx>
56 #include <fmtanchr.hxx>
57 #include <fmtsrnd.hxx>
58 #include <fmtornt.hxx>
59 #include <fmtfsize.hxx>
60 #include <fmtfollowtextflow.hxx>
61 #include <dcontact.hxx>
64 #include <fmtcntnt.hxx>
65 #include <ndindex.hxx>
67 #include <drawdoc.hxx>
68 #include <IDocumentSettingAccess.hxx>
69 #include <IDocumentDrawModelAccess.hxx>
76 #include <unodraw.hxx>
77 #include <pagedesc.hxx>
79 #include <breakit.hxx>
80 #include <com/sun/star/i18n/ScriptType.hpp>
81 #include "ww8attributeoutput.hxx"
82 #include "writerhelper.hxx"
83 #include "writerwordglue.hxx"
87 #include "WW8FFData.hxx"
88 #include <com/sun/star/beans/XPropertyContainer.hpp>
89 #include <com/sun/star/beans/XPropertySet.hpp>
90 #include <com/sun/star/beans/PropertyAttribute.hpp>
91 #include <com/sun/star/form/XFormComponent.hpp>
93 #include "IDocumentStylePoolAccess.hxx"
94 #include <oox/ole/olehelper.hxx>
96 #include <unotools/streamwrap.hxx>
97 #include <fmtinfmt.hxx>
99 #include "sfx2/sfxsids.hrc"
100 #include <svl/urihelper.hxx>
101 #include <unotools/saveopt.hxx>
102 #include <o3tl/enumrange.hxx>
103 #include <o3tl/enumarray.hxx>
107 using ::editeng::SvxBorderLine
;
108 using namespace com::sun::star
;
109 using namespace sw::util
;
110 using namespace sw::types
;
111 using namespace nsFieldFlags
;
112 using ::com::sun::star::beans::XPropertySet
;
113 using ::com::sun::star::drawing::XShape
;
115 bool SwBasicEscherEx::IsRelUrl()
117 SvtSaveOptions aSaveOpt
;
118 bool bRelUrl
= false;
119 SfxMedium
* pMedium
= rWrt
.GetWriter().GetMedia();
121 bRelUrl
= pMedium
->IsRemote() ? aSaveOpt
.IsSaveRelINet() : aSaveOpt
.IsSaveRelFSys();
125 OUString
SwBasicEscherEx::GetBasePath()
128 SfxMedium
* pMedium
= rWrt
.GetWriter().GetMedia();
131 const SfxItemSet
* pPItemSet
= pMedium
->GetItemSet();
134 const SfxStringItem
* pPItem
= dynamic_cast< const SfxStringItem
* >( pPItemSet
->GetItem( SID_FILE_NAME
) );
136 sDocUrl
= pPItem
->GetValue();
140 return sDocUrl
.copy(0, sDocUrl
.lastIndexOf('/') + 1);
143 OUString
SwBasicEscherEx::BuildFileName(sal_uInt16
& rnLevel
, bool& rbRel
, const OUString
& rUrl
)
145 OUString
aDosName( INetURLObject( rUrl
).getFSysPath( INetURLObject::FSYS_DOS
) );
151 // try to convert to relative file name
152 OUString
aTmpName( aDosName
);
153 aDosName
= INetURLObject::GetRelURL( GetBasePath(), rUrl
,
154 INetURLObject::EncodeMechanism::WasEncoded
, INetURLObject::DecodeMechanism::WithCharset
);
156 if (aDosName
.startsWith(INET_FILE_SCHEME
))
158 // not converted to rel -> back to old, return absolute flag
162 else if (aDosName
.startsWith("./"))
164 aDosName
= aDosName
.copy(2);
168 while (aDosName
.startsWith("../"))
171 aDosName
= aDosName
.copy(3);
178 void SwBasicEscherEx::WriteHyperlinkWithinFly( SvMemoryStream
& rStrm
, const SwFormatURL
* pINetFormatArg
)
180 if ( !pINetFormatArg
) return;
182 sal_uInt8 aGuidStdLink
[ 16 ] ={
183 0xD0, 0xC9, 0xEA, 0x79, 0xF9, 0xBA, 0xCE, 0x11, 0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B };
184 sal_uInt8 aGuidUrlMoniker
[ 16 ] = {
185 0xE0, 0xC9, 0xEA, 0x79, 0xF9, 0xBA, 0xCE, 0x11, 0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B };
187 sal_uInt8 aGuidFileMoniker
[ 16 ] = {
188 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 };
189 sal_uInt8 aGuidFileTail
[] = {
190 0xFF, 0xFF, 0xAD, 0xDE, 0x00, 0x00, 0x00, 0x00,
191 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
192 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
194 //const sal_uInt18 WW8_ID_HLINK = 0x01B8;
195 const sal_uInt32 WW8_HLINK_BODY
= 0x00000001; /// Contains file link or URL.
196 const sal_uInt32 WW8_HLINK_ABS
= 0x00000002; /// Absolute path.
197 //const sal_uInt32 WW8_HLINK_DESCR = 0x00000014; /// Description.
198 const sal_uInt32 WW8_HLINK_MARK
= 0x00000008; /// Text mark.
199 const sal_uInt32 WW8_HLINK_FRAME
= 0x00000080; /// Target frame.
200 //const sal_uInt32 WW8_HLINK_UNC = 0x00000100; /// UNC path.
201 SvMemoryStream tmpStrm
;
202 OUString tmpTextMark
;
204 OUString rUrl
= pINetFormatArg
->GetURL();
205 OUString rTarFrame
= pINetFormatArg
->GetTargetFrameName();
206 sal_uInt32 nFlags
= 0;
208 INetURLObject
aUrlObj( rUrl
);
209 const INetProtocol eProtocol
= aUrlObj
.GetProtocol();
212 if (!rTarFrame
.isEmpty())
214 SwWW8Writer::WriteLong(tmpStrm
, rTarFrame
.getLength()+1);
215 SwWW8Writer::WriteString16(tmpStrm
, rTarFrame
, false);
217 tmpStrm
.WriteUInt16( 0 );
219 nFlags
|= WW8_HLINK_FRAME
;
223 if (eProtocol
== INetProtocol::File
|| (eProtocol
== INetProtocol::NotValid
&& rUrl
[0] != '#'))
227 OUString
aFileName( BuildFileName( nLevel
, bRel
, rUrl
));
230 nFlags
|= WW8_HLINK_ABS
;
232 nFlags
|= WW8_HLINK_BODY
;
234 tmpStrm
.WriteBytes(aGuidFileMoniker
, sizeof(aGuidFileMoniker
));
235 tmpStrm
.WriteUInt16( nLevel
);
236 SwWW8Writer::WriteLong(tmpStrm
, aFileName
.getLength()+1);
237 SwWW8Writer::WriteString8( tmpStrm
, aFileName
, true, RTL_TEXTENCODING_MS_1252
);
238 tmpStrm
.WriteBytes(aGuidFileTail
, sizeof(aGuidFileTail
));
241 SwWW8Writer::WriteLong(tmpStrm
, 2*aFileName
.getLength()+6);
242 SwWW8Writer::WriteLong(tmpStrm
, 2*aFileName
.getLength());
243 tmpStrm
.WriteUInt16( 0x0003 );
244 SwWW8Writer::WriteString16(tmpStrm
, aFileName
, false);
246 else if( eProtocol
!= INetProtocol::NotValid
)
248 tmpStrm
.WriteBytes(aGuidUrlMoniker
, sizeof(aGuidUrlMoniker
));
249 SwWW8Writer::WriteLong(tmpStrm
, 2*(rUrl
.getLength()+1));
251 SwWW8Writer::WriteString16(tmpStrm
, rUrl
, true);
252 nFlags
|= WW8_HLINK_BODY
| WW8_HLINK_ABS
;
254 else if (rUrl
[0] == '#' )
256 OUString
aTextMark(rUrl
.copy( 1 ));
257 aTextMark
= aTextMark
.replaceFirst(".", "!");
258 tmpTextMark
= aTextMark
;
261 if (tmpTextMark
.isEmpty() && aUrlObj
.HasMark())
263 tmpTextMark
= aUrlObj
.GetMark();
266 if (!tmpTextMark
.isEmpty())
268 SwWW8Writer::WriteLong(tmpStrm
, tmpTextMark
.getLength()+1);
269 SwWW8Writer::WriteString16(tmpStrm
, tmpTextMark
, true);
271 nFlags
|= WW8_HLINK_MARK
;
274 rStrm
.WriteBytes(aGuidStdLink
, 16);
275 rStrm
.WriteUInt32( 2 )
276 .WriteUInt32( nFlags
);
277 tmpStrm
.Seek( STREAM_SEEK_TO_BEGIN
);
278 sal_uInt32
const nLen
= tmpStrm
.remainingSize();
281 std::unique_ptr
<sal_uInt8
[]> pBuffer( new sal_uInt8
[ nLen
] );
282 tmpStrm
.ReadBytes(pBuffer
.get(), nLen
);
283 rStrm
.WriteBytes(pBuffer
.get(), nLen
);
286 void SwBasicEscherEx::PreWriteHyperlinkWithinFly(const SwFrameFormat
& rFormat
,EscherPropertyContainer
& rPropOpt
)
288 const SfxPoolItem
* pItem
;
289 const SwAttrSet
& rAttrSet
= rFormat
.GetAttrSet();
290 if (SfxItemState::SET
== rAttrSet
.GetItemState(RES_URL
, true, &pItem
))
292 const SwFormatURL
*pINetFormat
= dynamic_cast<const SwFormatURL
*>(pItem
);
293 if (pINetFormat
&& !pINetFormat
->GetURL().isEmpty())
295 SvMemoryStream
*rStrm
= new SvMemoryStream
;
296 WriteHyperlinkWithinFly( *rStrm
, pINetFormat
);
297 sal_uInt8
const * pBuf
= static_cast<sal_uInt8
const *>(rStrm
->GetData());
298 sal_uInt32 nSize
= rStrm
->Seek( STREAM_SEEK_TO_END
);
299 rPropOpt
.AddOpt( ESCHER_Prop_pihlShape
, true, nSize
, const_cast<sal_uInt8
*>(pBuf
), nSize
);
301 OUString aNamestr
= pINetFormat
->GetName();
302 if (!aNamestr
.isEmpty())
304 rPropOpt
.AddOpt(ESCHER_Prop_wzName
, aNamestr
);
306 if(rPropOpt
.GetOpt( ESCHER_Prop_fPrint
, nValue
))
309 rPropOpt
.AddOpt(ESCHER_Prop_fPrint
, nValue
);
312 rPropOpt
.AddOpt(ESCHER_Prop_fPrint
, 0x03080008 );
319 /// Get the Z ordering number for a DrawObj in a WW8Export.
320 /// @param rWrt The containing WW8Export.
321 /// @param pObj pointer to the drawing object.
322 /// @returns The ordering number.
323 sal_uLong
lcl_getSdrOrderNumber(const WW8Export
& rWrt
, DrawObj
*pObj
)
325 return rWrt
.GetSdrOrdNum(pObj
->maContent
.GetFrameFormat());
328 /// A function object to act as a predicate comparing the ordering numbers
329 /// of two drawing obejcts in a WW8Export.
330 class CompareDrawObjs
333 const WW8Export
& wrt
;
336 explicit CompareDrawObjs(const WW8Export
& rWrt
) : wrt(rWrt
) {};
337 bool operator()(DrawObj
*a
, DrawObj
*b
) const
339 sal_uLong aSort
= lcl_getSdrOrderNumber(wrt
, a
);
340 sal_uLong bSort
= lcl_getSdrOrderNumber(wrt
, b
);
341 return aSort
< bSort
;
345 /// Make a z-order sorted copy of a collection of DrawObj objects.
346 /// @param rWrt The containing WW8Export.
347 /// @param rSrcArr The source array.
348 /// @param rDstArr The destination array.
349 void lcl_makeZOrderArray(const WW8Export
& rWrt
,
350 std::vector
<DrawObj
> &rSrcArr
,
351 std::vector
<DrawObj
*> &rDstArr
)
354 rDstArr
.reserve(rSrcArr
.size());
355 for(DrawObj
& i
: rSrcArr
)
357 rDstArr
.push_back( &i
);
359 std::sort(rDstArr
.begin(), rDstArr
.end(), CompareDrawObjs(rWrt
));
364 // get a part fix for this type of element
365 bool WW8Export::MiserableFormFieldExportHack(const SwFrameFormat
& rFrameFormat
)
367 const SdrObject
*pObject
= rFrameFormat
.FindRealSdrObject();
368 if (!pObject
|| pObject
->GetObjInventor() != SdrInventor::FmForm
)
371 const SdrUnoObj
*pFormObj
= dynamic_cast< const SdrUnoObj
* >(pObject
);
375 uno::Reference
< awt::XControlModel
> xControlModel
=
376 pFormObj
->GetUnoControlModel();
377 uno::Reference
< lang::XServiceInfo
> xInfo(xControlModel
,
379 uno::Reference
<beans::XPropertySet
> xPropSet(xControlModel
, uno::UNO_QUERY
);
383 if (xInfo
->supportsService("com.sun.star.form.component.ComboBox"))
385 DoComboBox(xPropSet
);
392 void WW8Export::DoComboBox(uno::Reference
<beans::XPropertySet
> const & xPropSet
)
395 uno::Sequence
<OUString
> aListItems
;
396 xPropSet
->getPropertyValue("StringItemList") >>= aListItems
;
397 sal_Int32 nNoStrings
= aListItems
.getLength();
400 uno::Any aTmp
= xPropSet
->getPropertyValue("DefaultText");
401 auto pStr
= o3tl::tryAccess
<OUString
>(aTmp
);
408 uno::Any aTmp
= xPropSet
->getPropertyValue("Name");
409 auto pStr
= o3tl::tryAccess
<OUString
>(aTmp
);
416 // property "Help" does not exist and due to the no-existence an exception is thrown.
419 uno::Any aTmp
= xPropSet
->getPropertyValue("HelpText");
420 auto pStr
= o3tl::tryAccess
<OUString
>(aTmp
);
424 catch( const uno::Exception
& )
430 uno::Any aTmp
= xPropSet
->getPropertyValue("Name");
431 auto pStr
= o3tl::tryAccess
<OUString
>(aTmp
);
436 DoComboBox(sName
, sHelp
, sToolTip
, sSelected
, aListItems
);
439 void WW8Export::DoComboBox(const OUString
&rName
,
440 const OUString
&rHelp
,
441 const OUString
&rToolTip
,
442 const OUString
&rSelected
,
443 uno::Sequence
<OUString
> &rListItems
)
445 OutputField(nullptr, ww::eFORMDROPDOWN
, FieldString(ww::eFORMDROPDOWN
),
446 WRITEFIELD_START
| WRITEFIELD_CMD_START
);
447 // write the refence to the "picture" structure
448 sal_uLong nDataStt
= pDataStrm
->Tell();
449 m_pChpPlc
->AppendFkpEntry( Strm().Tell() );
453 static sal_uInt8 aArr1
[] =
455 0x03, 0x6a, 0,0,0,0, // sprmCPicLocation
456 0x06, 0x08, 0x01, // sprmCFData
457 0x55, 0x08, 0x01, // sprmCFSpec
458 0x02, 0x08, 0x01 // sprmCFFieldVanish
460 sal_uInt8
* pDataAdr
= aArr1
+ 2;
461 Set_UInt32( pDataAdr
, nDataStt
);
463 m_pChpPlc
->AppendFkpEntry(Strm().Tell(), sizeof(aArr1
), aArr1
);
465 OutputField(nullptr, ww::eFORMDROPDOWN
, FieldString(ww::eFORMDROPDOWN
),
468 ::sw::WW8FFData aFFData
;
471 aFFData
.setName(rName
);
472 aFFData
.setHelp(rHelp
);
473 aFFData
.setStatus(rToolTip
);
475 sal_uInt32 nListItems
= rListItems
.getLength();
477 for (sal_uInt32 i
= 0; i
< nListItems
; i
++)
479 if (i
< 0x20 && rSelected
== rListItems
[i
])
480 aFFData
.setResult(::sal::static_int_cast
<sal_uInt8
>(i
));
481 aFFData
.addListboxEntry(rListItems
[i
]);
484 aFFData
.Write(pDataStrm
);
487 void WW8Export::DoFormText(const SwInputField
* pField
)
489 OutputField(nullptr, ww::eFORMTEXT
, FieldString(ww::eFORMTEXT
),
490 WRITEFIELD_START
| WRITEFIELD_CMD_START
);
491 // write the refence to the "picture" structure
492 sal_uLong nDataStt
= pDataStrm
->Tell();
493 m_pChpPlc
->AppendFkpEntry( Strm().Tell() );
496 static sal_uInt8 aArr1
[] = {
497 0x02, 0x08, 0x81, // sprmCFFieldVanish
498 0x03, 0x6a, 0,0,0,0, // sprmCPicLocation
500 0x06, 0x08, 0x01, // sprmCFData
501 0x55, 0x08, 0x01 // sprmCFSpec
503 sal_uInt8
* pDataAdr
= aArr1
+ 5;
504 Set_UInt32( pDataAdr
, nDataStt
);
506 m_pChpPlc
->AppendFkpEntry(Strm().Tell(),
507 sizeof( aArr1
), aArr1
);
509 ::sw::WW8FFData aFFData
;
512 aFFData
.setName(pField
->GetPar2());
513 aFFData
.setHelp(pField
->GetHelp());
514 aFFData
.setStatus(pField
->GetToolTip());
515 aFFData
.Write(pDataStrm
);
517 OutputField(nullptr, ww::eFORMTEXT
, OUString(), WRITEFIELD_CMD_END
);
519 const OUString
fieldStr( pField
->ExpandField(true) );
520 SwWW8Writer::WriteString16(Strm(), fieldStr
, false);
522 static sal_uInt8 aArr2
[] = {
523 0x55, 0x08, 0x01, // sprmCFSpec
524 0x75, 0x08, 0x01 // ???
527 pDataAdr
= aArr2
+ 2;
528 Set_UInt32( pDataAdr
, nDataStt
);
529 m_pChpPlc
->AppendFkpEntry(Strm().Tell(),
530 sizeof( aArr2
), aArr2
);
532 OutputField(nullptr, ww::eFORMTEXT
, OUString(), WRITEFIELD_CLOSE
);
535 PlcDrawObj::~PlcDrawObj()
539 //Its irritating to have to change the RTL frames position into LTR ones
540 //so that word will have to place them in the right place. Doubly so that
541 //the SO drawings and writer frames have different ideas themselves as to
542 //how to be positioned when in RTL mode!
543 bool RTLGraphicsHack(SwTwips
&rLeft
, SwTwips nWidth
,
544 sal_Int16 eHoriOri
, sal_Int16 eHoriRel
, SwTwips nPageLeft
,
545 SwTwips nPageRight
, SwTwips nPageSize
)
548 if (eHoriOri
== text::HoriOrientation::NONE
)
550 if (eHoriRel
== text::RelOrientation::PAGE_FRAME
)
552 rLeft
= nPageSize
- rLeft
;
556 (eHoriRel
== text::RelOrientation::PAGE_PRINT_AREA
) ||
557 (eHoriRel
== text::RelOrientation::FRAME
) ||
558 (eHoriRel
== text::RelOrientation::PRINT_AREA
)
561 rLeft
= nPageSize
- nPageLeft
- nPageRight
- rLeft
;
570 bool RTLDrawingsHack(long &rLeft
, long /*nWidth*/,
571 sal_Int16 eHoriOri
, sal_Int16 eHoriRel
, SwTwips nPageLeft
,
572 SwTwips nPageRight
, SwTwips nPageSize
)
575 if (eHoriOri
== text::HoriOrientation::NONE
)
577 if (eHoriRel
== text::RelOrientation::PAGE_FRAME
)
579 rLeft
= nPageSize
+ rLeft
;
583 (eHoriRel
== text::RelOrientation::PAGE_PRINT_AREA
) ||
584 (eHoriRel
== text::RelOrientation::FRAME
) ||
585 (eHoriRel
== text::RelOrientation::PRINT_AREA
)
588 rLeft
= nPageSize
- nPageLeft
- nPageRight
+ rLeft
;
595 void WW8Export::MiserableRTLFrameFormatHack(SwTwips
&rLeft
, SwTwips
&rRight
,
596 const ww8::Frame
&rFrameFormat
)
598 //Require nasty bidi swap
599 if (FRMDIR_HORI_RIGHT_TOP
!= m_pDoc
->GetTextDirection(rFrameFormat
.GetPosition()))
602 SwTwips nWidth
= rRight
- rLeft
;
603 SwTwips nPageLeft
, nPageRight
;
604 SwTwips nPageSize
= CurrentPageWidth(nPageLeft
, nPageRight
);
606 const SwFormatHoriOrient
& rHOr
= rFrameFormat
.GetFrameFormat().GetHoriOrient();
609 ww8::Frame::WriterSource eSource
= rFrameFormat
.GetWriterType();
610 if (eSource
== ww8::Frame::eDrawing
|| eSource
== ww8::Frame::eFormControl
)
612 if (RTLDrawingsHack(rLeft
, nWidth
, rHOr
.GetHoriOrient(),
613 rHOr
.GetRelationOrient(), nPageLeft
, nPageRight
, nPageSize
))
620 if (RTLGraphicsHack(rLeft
, nWidth
, rHOr
.GetHoriOrient(),
621 rHOr
.GetRelationOrient(), nPageLeft
, nPageRight
, nPageSize
))
627 rRight
= rLeft
+ nWidth
;
630 void PlcDrawObj::WritePlc( WW8Export
& rWrt
) const
632 if (8 > rWrt
.pFib
->m_nVersion
) // Cannot export drawobject in vers 7-
635 sal_uInt32 nFcStart
= rWrt
.pTableStrm
->Tell();
637 if (!maDrawObjs
.empty())
640 WW8Fib
& rFib
= *rWrt
.pFib
;
641 WW8_CP nCpOffs
= GetCpOffset(rFib
);
643 cDrawObjIter aEnd
= maDrawObjs
.end();
646 for (aIter
= maDrawObjs
.begin(); aIter
< aEnd
; ++aIter
)
647 SwWW8Writer::WriteLong(*rWrt
.pTableStrm
, aIter
->mnCp
- nCpOffs
);
649 SwWW8Writer::WriteLong(*rWrt
.pTableStrm
, rFib
.m_ccpText
+ rFib
.m_ccpFootnote
+
650 rFib
.m_ccpHdr
+ rFib
.m_ccpEdn
+ rFib
.m_ccpTxbx
+ rFib
.m_ccpHdrTxbx
+ 1);
652 for (aIter
= maDrawObjs
.begin(); aIter
< aEnd
; ++aIter
)
654 // write the fspa-struct
655 const ww8::Frame
&rFrameFormat
= aIter
->maContent
;
656 const SwFrameFormat
&rFormat
= rFrameFormat
.GetFrameFormat();
657 const SdrObject
* pObj
= rFormat
.FindRealSdrObject();
660 SwFormatVertOrient rVOr
= rFormat
.GetVertOrient();
661 SwFormatHoriOrient rHOr
= rFormat
.GetHoriOrient();
662 // #i30669# - convert the positioning attributes.
663 // Most positions are converted, if layout information exists.
664 const bool bPosConverted
=
665 WinwordAnchoring::ConvertPosition( rHOr
, rVOr
, rFormat
);
668 if (RES_FLYFRMFMT
== rFormat
.Which())
670 SwRect
aLayRect(rFormat
.FindLayoutRect(false, &aObjPos
));
671 // the Object is not visible - so get the values from
672 // the format. The Position may not be correct.
673 if( aLayRect
.IsEmpty() )
674 aRect
.SetSize( rFormat
.GetFrameSize().GetSize() );
677 // #i56090# Do not only consider the first client
678 // Note that we actually would have to find the maximum size of the
679 // frame format clients. However, this already should work in most cases.
680 const SwRect
aSizeRect(rFormat
.FindLayoutRect());
681 if ( aSizeRect
.Width() > aLayRect
.Width() )
682 aLayRect
.Width( aSizeRect
.Width() );
684 aRect
= aLayRect
.SVRect();
689 OSL_ENSURE(pObj
, "wo ist das SDR-Object?");
692 aRect
= pObj
->GetLogicRect();
696 // #i30669# - use converted position, if conversion is performed.
697 // Unify position determination of Writer fly frames
698 // and drawing objects.
701 aRect
.SetPos( Point( rHOr
.GetPos(), rVOr
.GetPos() ) );
705 aRect
-= aIter
->maParentPos
;
706 aObjPos
= aRect
.TopLeft();
707 if (text::VertOrientation::NONE
== rVOr
.GetVertOrient())
710 sal_Int16 eOri
= rVOr
.GetRelationOrient();
711 if (eOri
== text::RelOrientation::CHAR
|| eOri
== text::RelOrientation::TEXT_LINE
)
712 aObjPos
.Y() = -rVOr
.GetPos();
714 aObjPos
.Y() = rVOr
.GetPos();
716 if (text::HoriOrientation::NONE
== rHOr
.GetHoriOrient())
717 aObjPos
.X() = rHOr
.GetPos();
718 aRect
.SetPos( aObjPos
);
721 sal_Int32 nThick
= aIter
->mnThick
;
723 //If we are being exported as an inline hack, set
724 //corner to 0 and forget about border thickness for positioning
725 if (rFrameFormat
.IsInline())
727 aRect
.SetPos(Point(0,0));
732 SwWW8Writer::WriteLong(*rWrt
.pTableStrm
, aIter
->mnShapeId
);
734 SwTwips nLeft
= aRect
.Left() + nThick
;
735 SwTwips nRight
= aRect
.Right() - nThick
;
736 SwTwips nTop
= aRect
.Top() + nThick
;
737 SwTwips nBottom
= aRect
.Bottom() - nThick
;
739 // tdf#93675, 0 below line/paragraph and/or top line/paragraph with
740 // wrap top+bottom or other wraps is affecting the line directly
741 // above the anchor line, which seems odd, but a tiny adjustment
742 // here to bring the top down convinces msoffice to wrap like us
743 if (nTop
== 0 && !rFrameFormat
.IsInline() &&
744 rVOr
.GetVertOrient() == text::VertOrientation::NONE
&&
745 rVOr
.GetRelationOrient() == text::RelOrientation::FRAME
)
750 //Nasty swap for bidi if necessary
751 rWrt
.MiserableRTLFrameFormatHack(nLeft
, nRight
, rFrameFormat
);
753 //xaLeft/yaTop/xaRight/yaBottom - rel. to anchor
754 //(most of) the border is outside the graphic is word, so
755 //change dimensions to fit
756 SwWW8Writer::WriteLong(*rWrt
.pTableStrm
, nLeft
);
757 SwWW8Writer::WriteLong(*rWrt
.pTableStrm
, nTop
);
758 SwWW8Writer::WriteLong(*rWrt
.pTableStrm
, nRight
);
759 SwWW8Writer::WriteLong(*rWrt
.pTableStrm
, nBottom
);
761 //fHdr/bx/by/wr/wrk/fRcaSimple/fBelowText/fAnchorLock
763 //If nFlags isn't 0x14 its overridden by the escher properties
764 if (FLY_AT_PAGE
== rFormat
.GetAnchor().GetAnchorId())
767 nFlags
= 0x0014; // x-rel to text, y-rel to text
769 const SwFormatSurround
& rSurr
= rFormat
.GetSurround();
770 sal_uInt16 nContour
= rSurr
.IsContour() ? 0x0080 : 0x0040;
771 SwSurround eSurround
= rSurr
.GetSurround();
775 The inline elements being export as anchored to character inside
776 the shape field hack are required to be wrap through so as to flow
777 over the following dummy 0x01 graphic
779 if (rFrameFormat
.IsInline())
780 eSurround
= SURROUND_THROUGHT
;
787 case SURROUND_THROUGHT
:
790 case SURROUND_PARALLEL
:
791 nFlags
|= 0x0000 | nContour
;
794 nFlags
|= 0x0600 | nContour
;
797 nFlags
|= 0x0200 | nContour
;
800 nFlags
|= 0x0400 | nContour
;
803 OSL_ENSURE(false, "Unsupported surround type for export");
806 if (pObj
&& (pObj
->GetLayer() == rWrt
.m_pDoc
->getIDocumentDrawModelAccess().GetHellId() ||
807 pObj
->GetLayer() == rWrt
.m_pDoc
->getIDocumentDrawModelAccess().GetInvisibleHellId()))
813 #i3958# Required to make this inline stuff work in WordXP, not
814 needed for 2003 interestingly
816 if (rFrameFormat
.IsInline())
819 SwWW8Writer::WriteShort(*rWrt
.pTableStrm
, nFlags
);
822 SwWW8Writer::WriteLong(*rWrt
.pTableStrm
, 0);
825 RegisterWithFib(rFib
, nFcStart
, rWrt
.pTableStrm
->Tell() - nFcStart
);
829 void MainTextPlcDrawObj::RegisterWithFib(WW8Fib
&rFib
, sal_uInt32 nStart
,
830 sal_uInt32 nLen
) const
832 rFib
.m_fcPlcfspaMom
= nStart
;
833 rFib
.m_lcbPlcfspaMom
= nLen
;
836 WW8_CP
MainTextPlcDrawObj::GetCpOffset(const WW8Fib
&) const
841 void HdFtPlcDrawObj::RegisterWithFib(WW8Fib
&rFib
, sal_uInt32 nStart
,
842 sal_uInt32 nLen
) const
844 rFib
.m_fcPlcfspaHdr
= nStart
;
845 rFib
.m_lcbPlcfspaHdr
= nLen
;
848 WW8_CP
HdFtPlcDrawObj::GetCpOffset(const WW8Fib
&rFib
) const
850 return rFib
.m_ccpText
+ rFib
.m_ccpFootnote
;
853 DrawObj
& DrawObj::operator=(const DrawObj
& rOther
)
856 mnShapeId
= rOther
.mnShapeId
;
857 maContent
= rOther
.maContent
;
858 maParentPos
= rOther
.maParentPos
;
859 mnThick
= rOther
.mnThick
;
860 mnDirection
= rOther
.mnDirection
;
861 mnHdFtIndex
= rOther
.mnHdFtIndex
;
865 bool PlcDrawObj::Append( WW8Export
& rWrt
, WW8_CP nCp
, const ww8::Frame
& rFormat
,
866 const Point
& rNdTopLeft
)
869 const SwFrameFormat
&rFrameFormat
= rFormat
.GetFrameFormat();
870 if (TXT_HDFT
== rWrt
.m_nTextTyp
|| TXT_MAINTEXT
== rWrt
.m_nTextTyp
)
872 if (RES_FLYFRMFMT
== rFrameFormat
.Which())
874 // check for textflyframe and if it is the first in a Chain
875 if (rFrameFormat
.GetContent().GetContentIdx())
884 DrawObj
aObj(rFormat
, nCp
, rNdTopLeft
, rWrt
.TrueFrameDirection(rFrameFormat
),
885 rWrt
.GetHdFtIndex());
886 maDrawObjs
.push_back(aObj
);
891 void DrawObj::SetShapeDetails(sal_uInt32 nId
, sal_Int32 nThick
)
897 bool WW8_WrPlcTextBoxes::WriteText( WW8Export
& rWrt
)
899 rWrt
.m_bInWriteEscher
= true;
900 WW8_CP
& rccp
=TXT_TXTBOX
== nTyp
? rWrt
.pFib
->m_ccpTxbx
: rWrt
.pFib
->m_ccpHdrTxbx
;
902 bool bRet
= WriteGenericText( rWrt
, nTyp
, rccp
);
904 WW8_CP nCP
= rWrt
.Fc2Cp( rWrt
.Strm().Tell() );
905 WW8Fib
& rFib
= *rWrt
.pFib
;
906 WW8_CP nMyOffset
= rFib
.m_ccpText
+ rFib
.m_ccpFootnote
+ rFib
.m_ccpHdr
+ rFib
.m_ccpAtn
908 if( TXT_TXTBOX
== nTyp
)
909 rWrt
.m_pFieldTextBxs
->Finish( nCP
, nMyOffset
);
911 rWrt
.m_pFieldHFTextBxs
->Finish( nCP
, nMyOffset
+ rFib
.m_ccpTxbx
);
912 rWrt
.m_bInWriteEscher
= false;
916 void WW8_WrPlcTextBoxes::Append( const SdrObject
& rObj
, sal_uInt32 nShapeId
)
918 aContent
.push_back( &rObj
);
919 aShapeIds
.push_back( nShapeId
);
920 //save NULL, if we have an actual SdrObject
921 aSpareFormats
.push_back(nullptr);
924 void WW8_WrPlcTextBoxes::Append( const SwFrameFormat
* pFormat
, sal_uInt32 nShapeId
)
926 //no sdr object, we insert a NULL in the aContent and save the real fmt in aSpareFormats.
927 aContent
.push_back( nullptr );
928 aShapeIds
.push_back( nShapeId
);
929 aSpareFormats
.push_back(pFormat
);
932 const std::vector
<sal_uInt32
>* WW8_WrPlcTextBoxes::GetShapeIdArr() const
937 sal_uInt32
WW8Export::GetSdrOrdNum( const SwFrameFormat
& rFormat
) const
940 const SdrObject
* pObj
= rFormat
.FindRealSdrObject();
942 nOrdNum
= pObj
->GetOrdNum();
945 // no Layout for this format, then recalc the ordnum
946 SwFrameFormat
* pFormat
= const_cast<SwFrameFormat
*>(&rFormat
);
947 nOrdNum
= std::distance(m_pDoc
->GetSpzFrameFormats()->begin(),
948 m_pDoc
->GetSpzFrameFormats()->find( pFormat
) );
950 const SwDrawModel
* pModel
= m_pDoc
->getIDocumentDrawModelAccess().GetDrawModel();
952 nOrdNum
+= pModel
->GetPage( 0 )->GetObjCount();
957 void WW8Export::AppendFlyInFlys(const ww8::Frame
& rFrameFormat
,
958 const Point
& rNdTopLeft
)
960 OSL_ENSURE(!m_pEscher
, "der EscherStream wurde schon geschrieben!");
964 if (TXT_HDFT
== m_nTextTyp
)
965 pDrwO
= m_pHFSdrObjs
;
969 if (rFrameFormat
.IsInline())
971 OutputField(nullptr, ww::eSHAPE
, FieldString(ww::eSHAPE
),
972 WRITEFIELD_START
| WRITEFIELD_CMD_START
| WRITEFIELD_CMD_END
);
975 WW8_CP nCP
= Fc2Cp(Strm().Tell());
976 bool bSuccess
= pDrwO
->Append(*this, nCP
, rFrameFormat
, rNdTopLeft
);
977 OSL_ENSURE(bSuccess
, "Couldn't export a graphical element!");
981 static const sal_uInt8 aSpec8
[] =
983 0x03, 0x6a, 0, 0, 0, 0, // sprmCObjLocation
984 0x55, 0x08, 1 // sprmCFSpec
986 // fSpec-Attribut true
987 // Fuer DrawObjets muss ein Spezial-Zeichen
988 // in den Text und darum ein fSpec-Attribut
989 m_pChpPlc
->AppendFkpEntry( Strm().Tell() );
991 m_pChpPlc
->AppendFkpEntry( Strm().Tell(), sizeof( aSpec8
), aSpec8
);
993 //Need dummy picture frame
994 if (rFrameFormat
.IsInline())
995 OutGrf(rFrameFormat
);
998 if (rFrameFormat
.IsInline())
999 OutputField(nullptr, ww::eSHAPE
, OUString(), WRITEFIELD_CLOSE
);
1002 MSWord_SdrAttrIter::MSWord_SdrAttrIter( MSWordExportBase
& rWr
,
1003 const EditTextObject
& rEditObj
, sal_uInt8 nTyp
)
1004 : MSWordAttrIter( rWr
), pEditObj(&rEditObj
), pEditPool(nullptr), mnTyp(nTyp
)
1009 void MSWord_SdrAttrIter::NextPara( sal_Int32 nPar
)
1012 // Attributwechsel an Pos 0 wird ignoriert, da davon ausgegangen
1013 // wird, dass am Absatzanfang sowieso die Attribute neu ausgegeben
1015 aChrTextAtrArr
.clear();
1017 nAktSwPos
= nTmpSwPos
= 0;
1019 SfxItemSet
aSet( pEditObj
->GetParaAttribs( nPara
));
1020 pEditPool
= aSet
.GetPool();
1021 eNdChrSet
= ItemGet
<SvxFontItem
>(aSet
,EE_CHAR_FONTINFO
).GetCharSet();
1023 if( g_pBreakIt
->GetBreakIter().is() )
1024 nScript
= g_pBreakIt
->GetBreakIter()->getScriptType( pEditObj
->GetText(nPara
), 0);
1026 nScript
= i18n::ScriptType::LATIN
;
1028 pEditObj
->GetCharAttribs( nPara
, aTextAtrArr
);
1029 nAktSwPos
= SearchNext( 1 );
1032 rtl_TextEncoding
MSWord_SdrAttrIter::GetNextCharSet() const
1034 if( !aChrSetArr
.empty() )
1035 return aChrSetArr
.back();
1039 // der erste Parameter in SearchNext() liefert zurueck, ob es ein TextAtr ist.
1040 sal_Int32
MSWord_SdrAttrIter::SearchNext( sal_Int32 nStartPos
)
1042 sal_Int32 nMinPos
= SAL_MAX_INT32
;
1043 for(std::vector
<EECharAttrib
>::const_iterator i
= aTextAtrArr
.begin(); i
< aTextAtrArr
.end(); ++i
)
1045 sal_Int32 nPos
= i
->nStart
; // gibt erstes Attr-Zeichen
1046 if( nPos
>= nStartPos
&& nPos
<= nMinPos
)
1049 SetCharSet(*i
, true);
1052 nPos
= i
->nEnd
; // gibt letztes Attr-Zeichen + 1
1053 if( nPos
>= nStartPos
&& nPos
< nMinPos
)
1056 SetCharSet(*i
, false);
1062 void MSWord_SdrAttrIter::SetCharSet(const EECharAttrib
& rAttr
, bool bStart
)
1064 const SfxPoolItem
& rItem
= *rAttr
.pAttr
;
1065 if( rItem
.Which() != EE_CHAR_FONTINFO
)
1072 rtl_TextEncoding eChrSet
= static_cast<const SvxFontItem
&>(rItem
).GetCharSet();
1073 aChrSetArr
.push_back( eChrSet
);
1074 aChrTextAtrArr
.push_back( &rAttr
);
1078 std::vector
<const EECharAttrib
*>::iterator it
=
1079 std::find( aChrTextAtrArr
.begin(), aChrTextAtrArr
.end(), &rAttr
);
1080 if ( it
!= aChrTextAtrArr
.end() )
1082 aChrSetArr
.erase( aChrSetArr
.begin() + (it
- aChrTextAtrArr
.begin()) );
1083 aChrTextAtrArr
.erase( it
);
1088 void MSWord_SdrAttrIter::OutEEField(const SfxPoolItem
& rHt
)
1090 const SvxFieldItem
&rField
= static_cast<const SvxFieldItem
&>(rHt
);
1091 const SvxFieldData
*pField
= rField
.GetField();
1092 if (pField
&& dynamic_cast< const SvxURLField
*>( pField
) != nullptr)
1094 sal_uInt8 nOldTextTyp
= m_rExport
.m_nTextTyp
;
1095 m_rExport
.m_nTextTyp
= mnTyp
;
1096 const SvxURLField
*pURL
= static_cast<const SvxURLField
*>(pField
);
1097 m_rExport
.AttrOutput().StartURL( pURL
->GetURL(), pURL
->GetTargetFrame() );
1099 const OUString
&rStr
= pURL
->GetRepresentation();
1100 m_rExport
.AttrOutput().RawText(rStr
, GetNodeCharSet());
1102 m_rExport
.AttrOutput().EndURL(false);
1103 m_rExport
.m_nTextTyp
= nOldTextTyp
;
1107 void MSWord_SdrAttrIter::OutAttr( sal_Int32 nSwPos
)
1109 //Collect the which ids belong to the run that we will export after
1110 //outputting the underlying paragraph attributes. We will exclude
1111 //writing these from the underlying paragraph attributes to avoid
1112 //duplicate attributes in docx export. Doesn't matter in doc
1113 //export as later props just override earlier ones.
1114 std::set
<sal_uInt16
> aUsedRunWhichs
;
1115 if (!aTextAtrArr
.empty())
1117 for(std::vector
<EECharAttrib
>::const_iterator i
= aTextAtrArr
.begin(); i
< aTextAtrArr
.end(); ++i
)
1119 if (nSwPos
>= i
->nStart
&& nSwPos
< i
->nEnd
)
1121 sal_uInt16 nWhich
= i
->pAttr
->Which();
1122 aUsedRunWhichs
.insert(nWhich
);
1125 if( nSwPos
< i
->nStart
)
1130 OutParaAttr(true, &aUsedRunWhichs
);
1132 if (!aTextAtrArr
.empty())
1134 const SwModify
* pOldMod
= m_rExport
.m_pOutFormatNode
;
1135 m_rExport
.m_pOutFormatNode
= nullptr;
1137 const SfxItemPool
* pSrcPool
= pEditPool
;
1138 const SfxItemPool
& rDstPool
= m_rExport
.m_pDoc
->GetAttrPool();
1141 // Did we already produce a <w:sz> element?
1142 m_rExport
.m_bFontSizeWritten
= false;
1143 for(std::vector
<EECharAttrib
>::const_iterator i
= aTextAtrArr
.begin(); i
< aTextAtrArr
.end(); ++i
)
1145 if (nSwPos
>= i
->nStart
&& nSwPos
< i
->nEnd
)
1147 sal_uInt16 nWhich
= i
->pAttr
->Which();
1148 if (nWhich
== EE_FEATURE_FIELD
)
1150 OutEEField(*(i
->pAttr
));
1153 if (nWhich
== EE_FEATURE_TAB
)
1155 m_rExport
.WriteChar(0x9);
1159 const sal_uInt16 nSlotId
= pSrcPool
->GetSlotId(nWhich
);
1160 if (nSlotId
&& nWhich
!= nSlotId
)
1162 nWhich
= rDstPool
.GetWhich(nSlotId
);
1163 if (nWhich
&& nWhich
!= nSlotId
&&
1164 nWhich
< RES_UNKNOWNATR_BEGIN
&&
1165 m_rExport
.CollapseScriptsforWordOk(nScript
,nWhich
))
1167 // use always the SW-Which Id !
1168 SfxPoolItem
* pI
= i
->pAttr
->Clone();
1169 pI
->SetWhich( nWhich
);
1170 // Will this item produce a <w:sz> element?
1171 bool bFontSizeItem
= nWhich
== RES_CHRATR_FONTSIZE
|| nWhich
== RES_CHRATR_CJK_FONTSIZE
;
1172 if (!m_rExport
.m_bFontSizeWritten
|| !bFontSizeItem
)
1173 m_rExport
.AttrOutput().OutputItem( *pI
);
1175 m_rExport
.m_bFontSizeWritten
= true;
1181 if( nSwPos
< i
->nStart
)
1184 m_rExport
.m_bFontSizeWritten
= false;
1186 nTmpSwPos
= 0; // HasTextItem nur in dem obigen Bereich erlaubt
1187 m_rExport
.m_pOutFormatNode
= pOldMod
;
1191 bool MSWord_SdrAttrIter::IsTextAttr(sal_Int32 nSwPos
)
1193 for (std::vector
<EECharAttrib
>::const_iterator i
= aTextAtrArr
.begin(); i
< aTextAtrArr
.end(); ++i
)
1195 if (nSwPos
>= i
->nStart
&& nSwPos
< i
->nEnd
)
1197 if (i
->pAttr
->Which() == EE_FEATURE_FIELD
||
1198 i
->pAttr
->Which() == EE_FEATURE_TAB
)
1205 // HasItem ist fuer die Zusammenfassung des Doppel-Attributes Underline
1206 // und WordLineMode als TextItems. OutAttr() ruft die Ausgabefunktion,
1207 // die dann ueber HasItem() nach anderen Items an der
1208 // Attribut-Anfangposition fragen kann.
1209 // Es koennen nur Attribute mit Ende abgefragt werden.
1210 // Es wird mit bDeep gesucht
1211 const SfxPoolItem
* MSWord_SdrAttrIter::HasTextItem(sal_uInt16 nWhich
) const
1213 nWhich
= sw::hack::TransformWhichBetweenPools(*pEditPool
,
1214 m_rExport
.m_pDoc
->GetAttrPool(), nWhich
);
1217 for (std::vector
<EECharAttrib
>::const_iterator i
= aTextAtrArr
.begin(); i
< aTextAtrArr
.end(); ++i
)
1219 if (nWhich
== i
->pAttr
->Which() && nTmpSwPos
>= i
->nStart
&& nTmpSwPos
< i
->nEnd
)
1220 return i
->pAttr
; // Found
1221 if (nTmpSwPos
< i
->nStart
)
1222 return nullptr; // dann kommt da nichts mehr
1228 const SfxPoolItem
& MSWord_SdrAttrIter::GetItem( sal_uInt16 nWhich
) const
1230 using sw::hack::GetSetWhichFromSwDocWhich
;
1231 const SfxPoolItem
* pRet
= HasTextItem(nWhich
);
1234 SfxItemSet
aSet(pEditObj
->GetParaAttribs(nPara
));
1235 nWhich
= GetSetWhichFromSwDocWhich(aSet
, *m_rExport
.m_pDoc
, nWhich
);
1236 OSL_ENSURE(nWhich
, "Impossible, catastrophic failure imminent");
1237 pRet
= &aSet
.Get(nWhich
);
1242 //Drawing shapes properties inherit from a different pool that the document
1243 //styles. On export to .doc[x] they will default to style "Normal". Here explicitly
1244 //set any items which are not already set, but differ from "Normal".
1245 void MSWord_SdrAttrIter::SetItemsThatDifferFromStandard(bool bCharAttr
, SfxItemSet
& rSet
)
1247 SwTextFormatColl
* pC
= m_rExport
.m_pDoc
->getIDocumentStylePoolAccess().GetTextCollFromPool
1248 (RES_POOLCOLL_STANDARD
, false);
1250 SfxWhichIter
aWhichIter(rSet
);
1251 for (sal_uInt16 nEEWhich
= aWhichIter
.FirstWhich(); nEEWhich
; nEEWhich
= aWhichIter
.NextWhich())
1253 if (SfxItemState::SET
!= rSet
.GetItemState(nEEWhich
, false))
1255 sal_uInt16 nSwWhich
= sw::hack::TransformWhichBetweenPools(m_rExport
.m_pDoc
->GetAttrPool(),
1256 *pEditPool
, nEEWhich
);
1259 bool bWanted
= ( bCharAttr
? ( nSwWhich
>= RES_CHRATR_BEGIN
&& nSwWhich
< RES_TXTATR_END
)
1260 : ( nSwWhich
>= RES_PARATR_BEGIN
&& nSwWhich
< RES_FRMATR_END
) );
1264 const SfxPoolItem
& rDrawItem
= rSet
.Get(nEEWhich
);
1265 const SfxPoolItem
& rStandardItem
= pC
->GetFormatAttr(nSwWhich
);
1266 if (rDrawItem
!= rStandardItem
)
1267 rSet
.Put(rDrawItem
);
1272 void MSWord_SdrAttrIter::OutParaAttr(bool bCharAttr
, const std::set
<sal_uInt16
>* pWhichsToIgnore
)
1274 SfxItemSet
aSet( pEditObj
->GetParaAttribs( nPara
));
1276 SetItemsThatDifferFromStandard(bCharAttr
, aSet
);
1280 const SfxItemSet
* pOldSet
= m_rExport
.GetCurItemSet();
1281 m_rExport
.SetCurItemSet( &aSet
);
1283 SfxItemIter
aIter( aSet
);
1284 const SfxPoolItem
* pItem
= aIter
.GetCurItem();
1286 const SfxItemPool
* pSrcPool
= pEditPool
,
1287 * pDstPool
= &m_rExport
.m_pDoc
->GetAttrPool();
1291 sal_uInt16 nWhich
= pItem
->Which();
1292 if (pWhichsToIgnore
&& pWhichsToIgnore
->find(nWhich
) != pWhichsToIgnore
->end())
1295 sal_uInt16 nSlotId
= pSrcPool
->GetSlotId(nWhich
);
1297 if ( nSlotId
&& nWhich
!= nSlotId
&&
1298 0 != ( nWhich
= pDstPool
->GetWhich( nSlotId
) ) &&
1299 nWhich
!= nSlotId
&&
1300 ( bCharAttr
? ( nWhich
>= RES_CHRATR_BEGIN
&& nWhich
< RES_TXTATR_END
)
1301 : ( nWhich
>= RES_PARATR_BEGIN
&& nWhich
< RES_FRMATR_END
) ) )
1303 // use always the SW-Which Id !
1304 SfxPoolItem
* pI
= pItem
->Clone();
1305 pI
->SetWhich( nWhich
);
1306 if (m_rExport
.CollapseScriptsforWordOk(nScript
,nWhich
))
1307 m_rExport
.AttrOutput().OutputItem(*pI
);
1310 } while( !aIter
.IsAtEnd() && nullptr != ( pItem
= aIter
.NextItem() ) );
1311 m_rExport
.SetCurItemSet( pOldSet
);
1315 void WW8Export::WriteSdrTextObj(const SdrTextObj
& rTextObj
, sal_uInt8 nTyp
)
1317 const OutlinerParaObject
* pParaObj
= nullptr;
1318 bool bOwnParaObj
= false;
1322 When the object is actively being edited, that text is not set into
1323 the objects normal text object, but lives in a separate object.
1325 if (rTextObj
.IsTextEditActive())
1327 pParaObj
= rTextObj
.GetEditOutlinerParaObject();
1332 pParaObj
= rTextObj
.GetOutlinerParaObject();
1337 WriteOutliner(*pParaObj
, nTyp
);
1343 void WW8Export::WriteOutliner(const OutlinerParaObject
& rParaObj
, sal_uInt8 nTyp
)
1345 bool bAnyWrite
= false;
1346 const EditTextObject
& rEditObj
= rParaObj
.GetTextObject();
1347 MSWord_SdrAttrIter
aAttrIter( *this, rEditObj
, nTyp
);
1349 sal_Int32 nPara
= rEditObj
.GetParagraphCount();
1351 for( sal_Int32 n
= 0; n
< nPara
; ++n
)
1354 aAttrIter
.NextPara( n
);
1356 OSL_ENSURE( pO
->empty(), " pO ist am Zeilenanfang nicht leer" );
1358 OUString
aStr( rEditObj
.GetText( n
));
1359 sal_Int32 nAktPos
= 0;
1360 const sal_Int32 nEnd
= aStr
.getLength();
1362 const sal_Int32 nNextAttr
= std::min(aAttrIter
.WhereNext(), nEnd
);
1364 bool bTextAtr
= aAttrIter
.IsTextAttr( nAktPos
);
1366 OutSwString(aStr
, nAktPos
, nNextAttr
- nAktPos
);
1368 // Am Zeilenende werden die Attribute bis ueber das CR
1369 // aufgezogen. Ausnahme: Fussnoten am Zeilenende
1370 if( nNextAttr
== nEnd
&& !bTextAtr
)
1371 WriteCR(); // CR danach
1373 // Ausgabe der Zeichenattribute
1374 aAttrIter
.OutAttr( nAktPos
); // nAktPos - 1 ??
1375 m_pChpPlc
->AppendFkpEntry( Strm().Tell(),
1376 pO
->size(), pO
->data() );
1379 // Ausnahme: Fussnoten am Zeilenende
1380 if( nNextAttr
== nEnd
&& bTextAtr
)
1381 WriteCR(); // CR danach
1382 nAktPos
= nNextAttr
;
1383 aAttrIter
.NextPos();
1385 while( nAktPos
< nEnd
);
1387 OSL_ENSURE( pO
->empty(), " pO ist am ZeilenEnde nicht leer" );
1389 pO
->push_back( bNul
); // Style # as short
1390 pO
->push_back( bNul
);
1392 aAttrIter
.OutParaAttr(false);
1394 sal_uLong nPos
= Strm().Tell();
1395 m_pPapPlc
->AppendFkpEntry( Strm().Tell(),
1396 pO
->size(), pO
->data() );
1398 m_pChpPlc
->AppendFkpEntry( nPos
);
1401 bAnyWrite
= 0 != nPara
;
1403 WriteStringAsPara( OUString() );
1406 void WinwordAnchoring::WriteData( EscherEx
& rEx
) const
1408 //Toplevel groups get their winword extra data attached, and sub elements
1410 if (rEx
.GetGroupLevel() <= 1)
1412 SvStream
& rSt
= rEx
.GetStream();
1413 //The last argument denotes the number of sub properties in this atom
1416 rEx
.AddAtom(18, DFF_msofbtUDefProp
, 3, 3); //Prop id is 0xF122
1417 rSt
.WriteUInt16( 0x0390 ).WriteUInt32( 3 );
1418 rSt
.WriteUInt16( 0x0392 ).WriteUInt32( 3 );
1419 //This sub property is required to be in the dummy inline frame as
1421 rSt
.WriteUInt16( 0x053F ).WriteUInt32( nInlineHack
);
1425 rEx
.AddAtom(24, DFF_msofbtUDefProp
, 3, 4 ); //Prop id is 0xF122
1426 rSt
.WriteUInt16( 0x038F ).WriteUInt32( mnXAlign
);
1427 rSt
.WriteUInt16( 0x0390 ).WriteUInt32( mnXRelTo
);
1428 rSt
.WriteUInt16( 0x0391 ).WriteUInt32( mnYAlign
);
1429 rSt
.WriteUInt16( 0x0392 ).WriteUInt32( mnYRelTo
);
1434 void WW8Export::CreateEscher()
1436 SfxItemState eBackSet
= m_pDoc
->GetPageDesc(0).GetMaster().
1437 GetItemState(RES_BACKGROUND
);
1438 if (m_pHFSdrObjs
->size() || m_pSdrObjs
->size() || SfxItemState::SET
== eBackSet
)
1440 OSL_ENSURE( !m_pEscher
, "wer hat den Pointer nicht geloescht?" );
1441 SvMemoryStream
* pEscherStrm
= new SvMemoryStream
;
1442 pEscherStrm
->SetEndian(SvStreamEndian::LITTLE
);
1443 m_pEscher
= new SwEscherEx(pEscherStrm
, *this);
1447 void WW8Export::WriteEscher()
1451 sal_uLong nStart
= pTableStrm
->Tell();
1453 m_pEscher
->WritePictures();
1454 m_pEscher
->FinishEscher();
1456 pFib
->m_fcDggInfo
= nStart
;
1457 pFib
->m_lcbDggInfo
= pTableStrm
->Tell() - nStart
;
1459 m_pEscher
= nullptr;
1463 void SwEscherEx::WritePictures()
1465 if( SvStream
* pPicStrm
= static_cast< SwEscherExGlobal
& >( *mxGlobal
).GetPictureStream() )
1467 // set the blip - entries to the correct stream pos
1468 sal_Int32 nEndPos
= rWrt
.Strm().Tell();
1469 mxGlobal
->SetNewBlipStreamOffset( nEndPos
);
1471 pPicStrm
->Seek( 0 );
1472 rWrt
.Strm().WriteStream( *pPicStrm
);
1477 // Output- Routines for Escher Export
1479 SwEscherExGlobal::SwEscherExGlobal()
1483 SwEscherExGlobal::~SwEscherExGlobal()
1487 SvStream
* SwEscherExGlobal::ImplQueryPictureStream()
1489 // this function will be called exactly once
1490 mxPicStrm
.reset( new SvMemoryStream
);
1491 mxPicStrm
->SetEndian(SvStreamEndian::LITTLE
);
1492 return mxPicStrm
.get();
1495 SwBasicEscherEx::SwBasicEscherEx(SvStream
* pStrm
, WW8Export
& rWW8Wrt
)
1496 : EscherEx( std::shared_ptr
<EscherExGlobal
>( new SwEscherExGlobal
), pStrm
), rWrt(rWW8Wrt
), pEscherStrm(pStrm
)
1501 SwBasicEscherEx::~SwBasicEscherEx()
1505 void SwBasicEscherEx::WriteFrameExtraData(const SwFrameFormat
&)
1507 AddAtom(4, ESCHER_ClientAnchor
);
1508 GetStream().WriteUInt32( 0x80000000 );
1511 void SwBasicEscherEx::WriteEmptyFlyFrame(const SwFrameFormat
& rFormat
, sal_uInt32 nShapeId
)
1513 OpenContainer(ESCHER_SpContainer
);
1514 AddShape(ESCHER_ShpInst_PictureFrame
, 0xa00, nShapeId
);
1515 // store anchor attribute
1516 WriteFrameExtraData(rFormat
);
1518 AddAtom(6, DFF_msofbtUDefProp
, 3, 1); //Prop id is 0xF122
1519 GetStream().WriteUInt16( 0x053F ).WriteUInt32( nInlineHack
);
1521 CloseContainer(); // ESCHER_SpContainer
1524 sal_uInt32
AddMirrorFlags(sal_uInt32 nFlags
, const SwMirrorGrf
&rMirror
)
1526 switch (rMirror
.GetValue())
1529 case RES_MIRROR_GRAPH_DONT
:
1531 case RES_MIRROR_GRAPH_VERT
:
1532 nFlags
|= SHAPEFLAG_FLIPH
;
1534 case RES_MIRROR_GRAPH_HOR
:
1535 nFlags
|= SHAPEFLAG_FLIPV
;
1537 case RES_MIRROR_GRAPH_BOTH
:
1538 nFlags
|= SHAPEFLAG_FLIPH
;
1539 nFlags
|= SHAPEFLAG_FLIPV
;
1545 //For i120928,this function is added to export graphic of bullet
1546 void SwBasicEscherEx::WriteGrfBullet(const Graphic
& rGrf
)
1548 OpenContainer( ESCHER_SpContainer
);
1549 AddShape(ESCHER_ShpInst_PictureFrame
, 0xa00,0x401);
1550 EscherPropertyContainer aPropOpt
;
1551 GraphicObject
aGraphicObject( rGrf
);
1552 OString aUniqueId
= aGraphicObject
.GetUniqueID();
1553 if ( !aUniqueId
.isEmpty() )
1555 const MapMode
aMap100mm( MapUnit::Map100thMM
);
1556 Size
aSize( rGrf
.GetPrefSize() );
1557 if ( MapUnit::MapPixel
== rGrf
.GetPrefMapMode().GetMapUnit() )
1559 aSize
= Application::GetDefaultDevice()->PixelToLogic(aSize
, aMap100mm
);
1563 aSize
= OutputDevice::LogicToLogic( aSize
,rGrf
.GetPrefMapMode(), aMap100mm
);
1566 Rectangle
aRect( aEmptyPoint
, aSize
);
1567 sal_uInt32 nBlibId
= mxGlobal
->GetBlibID( *(mxGlobal
->QueryPictureStream()), aUniqueId
,aRect
);
1569 aPropOpt
.AddOpt(ESCHER_Prop_pib
, nBlibId
, true);
1571 aPropOpt
.AddOpt( ESCHER_Prop_pibFlags
, ESCHER_BlipFlagDefault
);
1572 aPropOpt
.AddOpt( ESCHER_Prop_dyTextTop
, DrawModelToEmu(0));
1573 aPropOpt
.AddOpt( ESCHER_Prop_dyTextBottom
, DrawModelToEmu(0));
1574 aPropOpt
.AddOpt( ESCHER_Prop_dxTextLeft
, DrawModelToEmu(0));
1575 aPropOpt
.AddOpt( ESCHER_Prop_dxTextRight
, DrawModelToEmu(0));
1576 aPropOpt
.AddOpt( ESCHER_Prop_fNoLineDrawDash
, 0x80000 );
1577 aPropOpt
.AddOpt( ESCHER_Prop_dyTextTop
, 0 );
1578 aPropOpt
.AddOpt( ESCHER_Prop_dyTextBottom
, 0 );
1579 aPropOpt
.AddOpt( ESCHER_Prop_dxTextLeft
, 0 );
1580 aPropOpt
.AddOpt( ESCHER_Prop_dxTextRight
, 0 );
1581 const Color
aTmpColor( COL_WHITE
);
1582 SvxBrushItem
aBrush( aTmpColor
, RES_BACKGROUND
);
1583 const SvxBrushItem
*pRet
= rWrt
.GetCurrentPageBgBrush();
1584 if (pRet
&& (pRet
->GetGraphic() ||( pRet
->GetColor() != COL_TRANSPARENT
)))
1586 WriteBrushAttr(aBrush
, aPropOpt
);
1588 aPropOpt
.AddOpt( ESCHER_Prop_pictureActive
, 0 );
1589 aPropOpt
.Commit( GetStream() );
1590 AddAtom(4, ESCHER_ClientAnchor
);
1591 GetStream().WriteUInt32( 0x80000000 );
1595 sal_Int32
SwBasicEscherEx::WriteGrfFlyFrame(const SwFrameFormat
& rFormat
, sal_uInt32 nShapeId
)
1597 sal_Int32 nBorderThick
=0;
1598 SwNoTextNode
*pNd
= GetNoTextNodeFromSwFrameFormat(rFormat
);
1599 SwGrfNode
*pGrfNd
= pNd
? pNd
->GetGrfNode() : nullptr;
1600 OSL_ENSURE(pGrfNd
, "No SwGrfNode ?, suspicious");
1602 return nBorderThick
;
1604 OpenContainer( ESCHER_SpContainer
);
1606 const SwMirrorGrf
&rMirror
= pGrfNd
->GetSwAttrSet().GetMirrorGrf();
1607 AddShape(ESCHER_ShpInst_PictureFrame
, AddMirrorFlags(0xa00, rMirror
),
1610 EscherPropertyContainer aPropOpt
;
1612 sal_uInt32 nFlags
= ESCHER_BlipFlagDefault
;
1614 if (pGrfNd
->IsLinkedFile())
1617 pGrfNd
->GetFileFilterNms( &sURL
, nullptr );
1620 SwWW8Writer::InsAsString16( aBuf
, sURL
);
1621 SwWW8Writer::InsUInt16( aBuf
, 0 );
1623 sal_uInt16 nArrLen
= aBuf
.size();
1624 sal_uInt8
* pArr
= new sal_uInt8
[ nArrLen
];
1625 std::copy( aBuf
.begin(), aBuf
.end(), pArr
);
1627 aPropOpt
.AddOpt(ESCHER_Prop_pibName
, true, nArrLen
, pArr
, nArrLen
);
1628 nFlags
= ESCHER_BlipFlagLinkToFile
| ESCHER_BlipFlagURL
|
1629 ESCHER_BlipFlagDoNotSave
;
1633 Graphic
aGraphic(pGrfNd
->GetGrf());
1634 GraphicObject
aGraphicObject( aGraphic
);
1635 OString aUniqueId
= aGraphicObject
.GetUniqueID();
1637 if (!aUniqueId
.isEmpty())
1639 const MapMode
aMap100mm( MapUnit::Map100thMM
);
1640 Size
aSize( aGraphic
.GetPrefSize() );
1642 if ( MapUnit::MapPixel
== aGraphic
.GetPrefMapMode().GetMapUnit() )
1644 aSize
= Application::GetDefaultDevice()->PixelToLogic(
1649 aSize
= OutputDevice::LogicToLogic( aSize
,
1650 aGraphic
.GetPrefMapMode(), aMap100mm
);
1654 Rectangle
aRect( aEmptyPoint
, aSize
);
1656 sal_uInt32 nBlibId
= mxGlobal
->GetBlibID( *QueryPictureStream(),
1659 aPropOpt
.AddOpt(ESCHER_Prop_pib
, nBlibId
, true);
1663 aPropOpt
.AddOpt( ESCHER_Prop_pibFlags
, nFlags
);
1664 nBorderThick
= WriteFlyFrameAttr(rFormat
,mso_sptPictureFrame
,aPropOpt
);
1665 WriteGrfAttr(*pGrfNd
, rFormat
, aPropOpt
);
1667 aPropOpt
.Commit( GetStream() );
1669 // store anchor attribute
1670 WriteFrameExtraData( rFormat
);
1672 CloseContainer(); // ESCHER_SpContainer
1673 return nBorderThick
;
1676 void SwBasicEscherEx::WriteGrfAttr(const SwNoTextNode
& rNd
, const SwFrameFormat
& rFormat
,
1677 EscherPropertyContainer
& rPropOpt
)
1679 const SfxPoolItem
* pItem
;
1680 sal_uInt32 nMode
= GRAPHICDRAWMODE_STANDARD
;
1681 sal_Int32 nContrast
= 0;
1682 sal_Int16 nBrightness
= 0;
1684 if (SfxItemState::SET
== rNd
.GetSwAttrSet().GetItemState(RES_GRFATR_CONTRAST
,
1687 nContrast
= static_cast<const SfxInt16Item
*>(pItem
)->GetValue();
1690 if (SfxItemState::SET
== rNd
.GetSwAttrSet().GetItemState(RES_GRFATR_LUMINANCE
,
1693 nBrightness
= static_cast<const SfxInt16Item
*>(pItem
)->GetValue();
1696 if (SfxItemState::SET
== rNd
.GetSwAttrSet().GetItemState(RES_GRFATR_DRAWMODE
,
1699 nMode
= static_cast<const SfxEnumItem
*>(pItem
)->GetValue();
1700 if (nMode
== GRAPHICDRAWMODE_WATERMARK
)
1703 There is no real watermark mode in word, we must use standard
1704 mode and modify our ones by 70% extra brightness and 70% less
1705 contrast. This means that unmodified default OOo watermark
1706 will turn back into watermark, and modified OOo watermark will
1707 change into a close visual representation in standardmode
1710 if (nBrightness
> 100)
1713 if (nContrast
< -100)
1715 nMode
= GRAPHICDRAWMODE_STANDARD
;
1719 if (nMode
== GRAPHICDRAWMODE_GREYS
)
1721 else if (nMode
== GRAPHICDRAWMODE_MONO
)
1725 rPropOpt
.AddOpt( ESCHER_Prop_pictureActive
, nMode
);
1730 if (nContrast
== 100)
1731 nContrast
= 0x10000;
1732 else if (nContrast
< 100)
1734 nContrast
*= 0x10000;
1737 else if (nContrast
< 200)
1738 nContrast
= (100 * 0x10000) / (200-nContrast
);
1740 nContrast
= 0x7fffffff;
1741 rPropOpt
.AddOpt( ESCHER_Prop_pictureContrast
, nContrast
);
1744 if (nBrightness
!= 0)
1745 rPropOpt
.AddOpt( ESCHER_Prop_pictureBrightness
, nBrightness
* 327 );
1747 sal_Int32 nCropL
= 0;
1748 sal_Int32 nCropR
= 0;
1749 sal_Int32 nCropT
= 0;
1750 sal_Int32 nCropB
= 0;
1751 if (SfxItemState::SET
== rNd
.GetSwAttrSet().GetItemState(RES_GRFATR_CROPGRF
,
1754 const SwCropGrf
& rCrop
= *static_cast<const SwCropGrf
*>(pItem
);
1755 nCropL
+= rCrop
.GetLeft();
1756 nCropR
+= rCrop
.GetRight();
1757 nCropT
+= rCrop
.GetTop();
1758 nCropB
+= rCrop
.GetBottom();
1761 // simulate border padding as a negative crop.
1762 if (SfxItemState::SET
== rFormat
.GetItemState(RES_BOX
, false, &pItem
))
1764 const SvxBoxItem
& rBox
= *static_cast<const SvxBoxItem
*>(pItem
);
1765 nCropL
-= rBox
.GetDistance( SvxBoxItemLine::LEFT
);
1766 nCropR
-= rBox
.GetDistance( SvxBoxItemLine::RIGHT
);
1767 nCropT
-= rBox
.GetDistance( SvxBoxItemLine::TOP
);
1768 nCropB
-= rBox
.GetDistance( SvxBoxItemLine::BOTTOM
);
1771 const Size
aSz( rNd
.GetTwipSize() );
1773 rPropOpt
.AddOpt( ESCHER_Prop_cropFromLeft
, ToFract16( nCropL
, aSz
.Width()) );
1775 rPropOpt
.AddOpt( ESCHER_Prop_cropFromRight
, ToFract16( nCropR
, aSz
.Width()));
1777 rPropOpt
.AddOpt( ESCHER_Prop_cropFromTop
, ToFract16( nCropT
, aSz
.Height()));
1779 rPropOpt
.AddOpt( ESCHER_Prop_cropFromBottom
, ToFract16( nCropB
, aSz
.Height()));
1782 void SwBasicEscherEx::SetPicId(const SdrObject
&, sal_uInt32
,
1783 EscherPropertyContainer
&)
1787 void SwEscherEx::SetPicId(const SdrObject
&rSdrObj
, sal_uInt32 nShapeId
,
1788 EscherPropertyContainer
&rPropOpt
)
1790 pTextBxs
->Append(rSdrObj
, nShapeId
);
1791 sal_uInt32 nPicId
= pTextBxs
->Count();
1793 rPropOpt
.AddOpt( ESCHER_Prop_pictureId
, nPicId
);
1796 sal_Int32
SwBasicEscherEx::WriteOLEFlyFrame(const SwFrameFormat
& rFormat
, sal_uInt32 nShapeId
)
1798 sal_Int32 nBorderThick
= 0;
1799 if (const SdrObject
* pSdrObj
= rFormat
.FindRealSdrObject())
1801 SwNodeIndex
aIdx(*rFormat
.GetContent().GetContentIdx(), 1);
1802 SwOLENode
& rOLENd
= *aIdx
.GetNode().GetOLENode();
1803 sal_Int64 nAspect
= rOLENd
.GetAspect();
1805 uno::Reference
< embed::XEmbeddedObject
> xObj(rOLENd
.GetOLEObj().GetOleRef());
1807 // the rectangle is used to transport the size of the object
1808 // the left, top corner is set to ( 0, 0 ) by default constructor,
1809 // if the width and height are set correctly bRectIsSet should be set to true
1810 awt::Rectangle aRect
;
1811 bool bRectIsSet
= false;
1813 // TODO/LATER: should the icon size be stored in case of iconified object?
1814 if ( xObj
.is() && nAspect
!= embed::Aspects::MSOLE_ICON
)
1818 awt::Size aSize
= xObj
->getVisualAreaSize( nAspect
);
1819 aRect
.Width
= aSize
.Width
;
1820 aRect
.Height
= aSize
.Height
;
1823 catch( const uno::Exception
& )
1829 Export floating ole2 .doc ver 8+ wmf ole2 previews as emf previews
1830 instead ==> allows unicode text to be preserved
1832 #ifdef OLE_PREVIEW_AS_EMF
1833 const Graphic
* pGraphic
= rOLENd
.GetGraphic();
1835 OpenContainer(ESCHER_SpContainer
);
1837 EscherPropertyContainer aPropOpt
;
1838 const SwMirrorGrf
&rMirror
= rOLENd
.GetSwAttrSet().GetMirrorGrf();
1839 WriteOLEPicture(aPropOpt
, AddMirrorFlags(0xa00 | SHAPEFLAG_OLESHAPE
,
1840 rMirror
), pGraphic
? *pGraphic
: Graphic(), *pSdrObj
, nShapeId
, bRectIsSet
? &aRect
: nullptr );
1842 nBorderThick
= WriteFlyFrameAttr(rFormat
, mso_sptPictureFrame
, aPropOpt
);
1843 WriteGrfAttr(rOLENd
, rFormat
, aPropOpt
);
1844 aPropOpt
.Commit(GetStream());
1846 // store anchor attribute
1847 WriteFrameExtraData( rFormat
);
1849 CloseContainer(); // ESCHER_SpContainer
1851 return nBorderThick
;
1854 void SwBasicEscherEx::WriteBrushAttr(const SvxBrushItem
&rBrush
,
1855 EscherPropertyContainer
& rPropOpt
)
1857 bool bSetOpacity
= false;
1858 sal_uInt32 nOpaque
= 0;
1859 if (const GraphicObject
*pGraphicObject
= rBrush
.GetGraphicObject())
1861 OString aUniqueId
= pGraphicObject
->GetUniqueID();
1862 if (!aUniqueId
.isEmpty())
1864 const Graphic
&rGraphic
= pGraphicObject
->GetGraphic();
1865 Size
aSize(rGraphic
.GetPrefSize());
1866 const MapMode
aMap100mm(MapUnit::Map100thMM
);
1867 if (MapUnit::MapPixel
== rGraphic
.GetPrefMapMode().GetMapUnit())
1869 aSize
= Application::GetDefaultDevice()->PixelToLogic(
1874 aSize
= OutputDevice::LogicToLogic(aSize
,
1875 rGraphic
.GetPrefMapMode(), aMap100mm
);
1879 Rectangle
aRect(aEmptyPoint
, aSize
);
1881 sal_uInt32 nBlibId
= mxGlobal
->GetBlibID( *QueryPictureStream(),
1884 rPropOpt
.AddOpt(ESCHER_Prop_fillBlip
,nBlibId
,true);
1887 if (0 != (nOpaque
= pGraphicObject
->GetAttr().GetTransparency()))
1890 rPropOpt
.AddOpt( ESCHER_Prop_fillType
, ESCHER_FillPicture
);
1891 rPropOpt
.AddOpt( ESCHER_Prop_fNoFillHitTest
, 0x140014 );
1892 rPropOpt
.AddOpt( ESCHER_Prop_fillBackColor
, 0 );
1896 sal_uInt32 nFillColor
= GetColor(rBrush
.GetColor(), false);
1897 rPropOpt
.AddOpt( ESCHER_Prop_fillColor
, nFillColor
);
1898 rPropOpt
.AddOpt( ESCHER_Prop_fillBackColor
, nFillColor
^ 0xffffff );
1899 rPropOpt
.AddOpt( ESCHER_Prop_fNoFillHitTest
, 0x100010 );
1901 if (0 != (nOpaque
= rBrush
.GetColor().GetTransparency()))
1907 nOpaque
= (nOpaque
* 100) / 0xFE;
1908 nOpaque
= ((100 - nOpaque
) << 16) / 100;
1909 rPropOpt
.AddOpt(ESCHER_Prop_fillOpacity
, nOpaque
);
1913 sal_Int32
SwBasicEscherEx::WriteFlyFrameAttr(const SwFrameFormat
& rFormat
,
1914 MSO_SPT eShapeType
, EscherPropertyContainer
& rPropOpt
)
1916 sal_Int32 nLineWidth
=0;
1917 const SfxPoolItem
* pItem
;
1918 bool bFirstLine
= true;
1919 if (SfxItemState::SET
== rFormat
.GetItemState(RES_BOX
, true, &pItem
))
1921 static const o3tl::enumarray
<SvxBoxItemLine
, sal_uInt16
> aExhperProp
=
1923 ESCHER_Prop_dyTextTop
, ESCHER_Prop_dyTextBottom
,
1924 ESCHER_Prop_dxTextLeft
, ESCHER_Prop_dxTextRight
1926 const SvxBorderLine
* pLine
;
1928 for( SvxBoxItemLine n
: o3tl::enumrange
<SvxBoxItemLine
>() )
1929 if( nullptr != ( pLine
= static_cast<const SvxBoxItem
*>(pItem
)->GetLine( n
)) )
1933 sal_uInt32 nLineColor
= GetColor(pLine
->GetColor(), false);
1934 rPropOpt
.AddOpt( ESCHER_Prop_lineColor
, nLineColor
);
1935 rPropOpt
.AddOpt( ESCHER_Prop_lineBackColor
,
1936 nLineColor
^ 0xffffff );
1938 MSO_LineStyle eStyle
;
1939 if( pLine
->isDouble() )
1942 nLineWidth
= pLine
->GetWidth();
1943 if( pLine
->GetInWidth() == pLine
->GetOutWidth() )
1944 eStyle
= mso_lineDouble
;
1945 else if( pLine
->GetInWidth() < pLine
->GetOutWidth() )
1946 eStyle
= mso_lineThickThin
;
1948 eStyle
= mso_lineThinThick
;
1953 eStyle
= mso_lineSimple
;
1954 nLineWidth
= pLine
->GetWidth();
1957 rPropOpt
.AddOpt( ESCHER_Prop_lineStyle
, eStyle
);
1958 rPropOpt
.AddOpt( ESCHER_Prop_lineWidth
,
1959 DrawModelToEmu( nLineWidth
));
1961 MSO_LineDashing eDashing
= mso_lineSolid
;
1962 switch (pLine
->GetBorderLineStyle())
1964 case table::BorderLineStyle::DASHED
:
1965 eDashing
= mso_lineDashGEL
;
1967 case table::BorderLineStyle::DOTTED
:
1968 eDashing
= mso_lineDotGEL
;
1970 case table::BorderLineStyle::SOLID
:
1974 rPropOpt
.AddOpt( ESCHER_Prop_lineDashing
, eDashing
);
1975 rPropOpt
.AddOpt( ESCHER_Prop_fNoLineDrawDash
, 0x8000E );
1977 //Use import logic to determine how much of border will go
1979 nLineWidth
= SwMSDffManager::GetEscherLineMatch(
1980 eStyle
,eShapeType
,nLineWidth
);
1983 rPropOpt
.AddOpt( aExhperProp
[ n
], DrawModelToEmu(
1984 static_cast<const SvxBoxItem
*>(pItem
)->GetDistance( n
) ));
1987 rPropOpt
.AddOpt( aExhperProp
[ n
], DrawModelToEmu(static_cast<const SvxBoxItem
*>(pItem
)->GetDistance( n
)) );
1991 rPropOpt
.AddOpt( ESCHER_Prop_dyTextTop
, 0 );
1992 rPropOpt
.AddOpt( ESCHER_Prop_dyTextBottom
, 0 );
1993 rPropOpt
.AddOpt( ESCHER_Prop_dxTextLeft
, 0 );
1994 rPropOpt
.AddOpt( ESCHER_Prop_dxTextRight
, 0 );
1997 if( bFirstLine
) // no valid line found
1999 rPropOpt
.AddOpt( ESCHER_Prop_fNoLineDrawDash
, 0x80000 );
2001 const SwAttrSet
& rAttrSet
= rFormat
.GetAttrSet();
2002 if (SfxItemState::SET
== rAttrSet
.GetItemState(RES_BOX
, false, &pItem
))
2004 const SvxBoxItem
* pBox
= static_cast<const SvxBoxItem
*>(pItem
);
2007 const SfxPoolItem
* pShadItem
;
2008 if (SfxItemState::SET
2009 == rAttrSet
.GetItemState(RES_SHADOW
, true, &pShadItem
))
2011 const SvxShadowItem
* pSI
= static_cast<const SvxShadowItem
*>(pShadItem
);
2013 const sal_uInt16 nCstScale
= 635; // unit scale between AOO and MS Word
2014 const sal_uInt32 nShadowType
= 131074; // shadow type of ms word. need to set the default value.
2016 sal_uInt32 nColor
= (sal_uInt32
)(pSI
->GetColor().GetColor()) ;
2017 sal_Int32 nOffX
= pSI
->GetWidth() * nCstScale
;
2018 sal_Int32 nOffY
= pSI
->GetWidth() * nCstScale
;
2019 sal_uInt32 nShadow
= nShadowType
;
2021 SvxShadowLocation eLocation
= pSI
->GetLocation();
2022 if( (eLocation
!=SVX_SHADOW_NONE
) && (pSI
->GetWidth()!=0) )
2026 case SVX_SHADOW_TOPLEFT
:
2032 case SVX_SHADOW_TOPRIGHT
:
2037 case SVX_SHADOW_BOTTOMLEFT
:
2042 case SVX_SHADOW_BOTTOMRIGHT
:
2048 rPropOpt
.AddOpt( DFF_Prop_shadowColor
, wwUtility::RGBToBGR((nColor
)));
2049 rPropOpt
.AddOpt( DFF_Prop_shadowOffsetX
, nOffX
);
2050 rPropOpt
.AddOpt( DFF_Prop_shadowOffsetY
, nOffY
);
2051 rPropOpt
.AddOpt( DFF_Prop_fshadowObscured
, nShadow
);
2057 // SwWW8ImplReader::Read_GrafLayer() imports these as opaque
2058 // unconditionally, so if both are true, don't export the property.
2059 bool bIsInHeader
= sw::IsFlyFrameFormatInHeader(rFormat
);
2060 bool bIsThrought
= rFormat
.GetSurround().GetValue() == SURROUND_THROUGHT
;
2064 SvxBrushItem
aBrush(rFormat
.makeBackgroundBrushItem());
2065 WriteBrushAttr(aBrush
, rPropOpt
);
2069 SvxBrushItem
aBrush(rWrt
.TrueFrameBgBrush(rFormat
));
2070 WriteBrushAttr(aBrush
, rPropOpt
);
2073 const SdrObject
* pObj
= rFormat
.FindRealSdrObject();
2075 if( pObj
&& (pObj
->GetLayer() == GetHellLayerId() ||
2076 pObj
->GetLayer() == GetInvisibleHellId() ) && !(bIsInHeader
&& bIsThrought
))
2078 rPropOpt
.AddOpt( ESCHER_Prop_fPrint
, 0x200020 );
2081 PreWriteHyperlinkWithinFly(rFormat
,rPropOpt
);
2086 sal_Int32
SwEscherEx::WriteFlyFrameAttr(const SwFrameFormat
& rFormat
, MSO_SPT eShapeType
,
2087 EscherPropertyContainer
& rPropOpt
)
2089 sal_Int32 nLineWidth
= SwBasicEscherEx::WriteFlyFrameAttr(rFormat
, eShapeType
,
2093 These are not in SwBasicEscherEx::WriteFlyFrameAttr because inline objs
2094 can't do it in word and it hacks it in by stretching the graphic that
2095 way, perhaps we should actually draw in this space into the graphic we
2098 const SfxPoolItem
* pItem
;
2099 if (SfxItemState::SET
== rFormat
.GetItemState(RES_LR_SPACE
, true, &pItem
))
2101 rPropOpt
.AddOpt( ESCHER_Prop_dxWrapDistLeft
,
2102 DrawModelToEmu( static_cast<const SvxLRSpaceItem
*>(pItem
)->GetLeft() ) );
2103 rPropOpt
.AddOpt( ESCHER_Prop_dxWrapDistRight
,
2104 DrawModelToEmu( static_cast<const SvxLRSpaceItem
*>(pItem
)->GetRight() ) );
2108 rPropOpt
.AddOpt( ESCHER_Prop_dxWrapDistLeft
, 0 );
2109 rPropOpt
.AddOpt( ESCHER_Prop_dxWrapDistRight
, 0 );
2112 if (SfxItemState::SET
== rFormat
.GetItemState(RES_UL_SPACE
, true, &pItem
))
2114 rPropOpt
.AddOpt( ESCHER_Prop_dyWrapDistTop
,
2115 DrawModelToEmu( static_cast<const SvxULSpaceItem
*>(pItem
)->GetUpper() ) );
2116 rPropOpt
.AddOpt( ESCHER_Prop_dyWrapDistBottom
,
2117 DrawModelToEmu( static_cast<const SvxULSpaceItem
*>(pItem
)->GetLower() ) );
2120 if (rFormat
.GetSurround().IsContour())
2122 if (const SwNoTextNode
*pNd
= GetNoTextNodeFromSwFrameFormat(rFormat
))
2124 const tools::PolyPolygon
*pPolyPoly
= pNd
->HasContour();
2125 if (pPolyPoly
&& pPolyPoly
->Count())
2127 tools::Polygon aPoly
= CorrectWordWrapPolygonForExport(*pPolyPoly
, pNd
);
2128 SvMemoryStream aPolyDump
;
2129 aPolyDump
.SetEndian(SvStreamEndian::LITTLE
);
2131 sal_uInt16 nLen
= aPoly
.GetSize();
2132 aPolyDump
.WriteUInt16( nLen
);
2133 aPolyDump
.WriteUInt16( nLen
);
2134 aPolyDump
.WriteUInt16( 8 );
2135 for (sal_uInt16 nI
= 0; nI
< nLen
; ++nI
)
2137 aPolyDump
.WriteUInt32( aPoly
[nI
].X() );
2138 aPolyDump
.WriteUInt32( aPoly
[nI
].Y() );
2141 sal_uInt16 nArrLen
= msword_cast
<sal_uInt16
>(aPolyDump
.Tell());
2142 void *pArr
= const_cast<void *>(aPolyDump
.GetData());
2143 //PropOpt wants to own the buffer
2144 aPolyDump
.ObjectOwnsMemory(false);
2145 rPropOpt
.AddOpt(DFF_Prop_pWrapPolygonVertices
, false,
2146 nArrLen
, static_cast<sal_uInt8
*>(pArr
), nArrLen
);
2151 PreWriteHyperlinkWithinFly(rFormat
,rPropOpt
);
2156 void SwBasicEscherEx::Init()
2158 MapUnit eMap
= MapUnit::MapTwip
;
2159 if (SwDrawModel
*pModel
= rWrt
.m_pDoc
->getIDocumentDrawModelAccess().GetDrawModel())
2161 // PPT arbeitet nur mit Einheiten zu 576DPI
2162 // WW hingegen verwendet twips, dh. 1440DPI.
2163 eMap
= pModel
->GetScaleUnit();
2166 // MS-DFF-Properties sind grossteils in EMU (English Metric Units) angegeben
2167 // 1mm=36000emu, 1twip=635emu
2168 Fraction
aFact(360, 1);
2169 aFact
/= GetMapFactor(MapUnit::Map100thMM
, eMap
).X();
2170 // create little values
2171 aFact
= Fraction(aFact
.GetNumerator(), aFact
.GetDenominator());
2172 mnEmuMul
= aFact
.GetNumerator();
2173 mnEmuDiv
= aFact
.GetDenominator();
2175 SetHellLayerId(rWrt
.m_pDoc
->getIDocumentDrawModelAccess().GetHellId());
2178 sal_Int32
SwBasicEscherEx::ToFract16(sal_Int32 nVal
, sal_uInt32 nMax
)
2184 sal_Int32 nMSVal
= (nVal
/ 65536) * nMax
;
2185 nMSVal
+= (nVal
* 65536) / nMax
;
2188 // negative fraction does not have "-0", fractional part is always
2189 // positive: -0.4 represented as -1 + 0.6
2190 sal_Int32
const nDiv
= (nVal
/ sal_Int32(nMax
)) - 1;
2191 sal_uInt32 nMSVal
= (sal_uInt32(nDiv
) << 16) & 0xffff0000;
2192 nMSVal
+= (nVal
* 65536) / sal_Int32(nMax
) + (-nDiv
* 65536);
2199 SdrLayerID
SwBasicEscherEx::GetInvisibleHellId() const
2201 return rWrt
.m_pDoc
->getIDocumentDrawModelAccess().GetInvisibleHellId();
2204 void SwBasicEscherEx::WritePictures()
2206 if( SvStream
* pPicStrm
= static_cast< SwEscherExGlobal
& >( *mxGlobal
).GetPictureStream() )
2208 // set the blip - entries to the correct stream pos
2209 sal_Int32 nEndPos
= pPicStrm
->Tell();
2210 mxGlobal
->WriteBlibStoreEntry(*pEscherStrm
, 1, true, nEndPos
);
2213 pEscherStrm
->WriteStream( *pPicStrm
);
2217 SwEscherEx::SwEscherEx(SvStream
* pStrm
, WW8Export
& rWW8Wrt
)
2218 : SwBasicEscherEx(pStrm
, rWW8Wrt
),
2221 aHostData
.SetClientData(&aWinwordAnchoring
);
2222 OpenContainer( ESCHER_DggContainer
);
2224 sal_uInt16 nColorCount
= 4;
2225 pStrm
->WriteUInt16( nColorCount
<< 4 ) // instance
2226 .WriteUInt16( ESCHER_SplitMenuColors
) // record type
2227 .WriteUInt32( nColorCount
* 4 ) // size
2228 .WriteUInt32( 0x08000004 )
2229 .WriteUInt32( 0x08000001 )
2230 .WriteUInt32( 0x08000002 )
2231 .WriteUInt32( 0x100000f7 );
2233 CloseContainer(); // ESCHER_DggContainer
2235 sal_uInt8 i
= 2; // for header/footer and the other
2236 PlcDrawObj
*pSdrObjs
= rWrt
.m_pHFSdrObjs
;
2237 pTextBxs
= rWrt
.m_pHFTextBxs
;
2239 // if no header/footer -> skip over
2240 if (!pSdrObjs
->size())
2243 pSdrObjs
= rWrt
.m_pSdrObjs
;
2244 pTextBxs
= rWrt
.m_pTextBxs
;
2247 for( ; i
--; pSdrObjs
= rWrt
.m_pSdrObjs
, pTextBxs
= rWrt
.m_pTextBxs
)
2249 // "dummy char" (or any Count ?) - why? Only Microsoft knows it.
2250 GetStream().WriteChar( i
);
2252 OpenContainer( ESCHER_DgContainer
);
2256 sal_uLong nSecondShapeId
= pSdrObjs
== rWrt
.m_pSdrObjs
? GenerateShapeId() : 0;
2258 // write now all Writer-/DrawObjects
2259 DrawObjPointerVector aSorted
;
2260 MakeZOrderArrAndFollowIds(pSdrObjs
->GetObjArr(), aSorted
);
2262 sal_uInt32 nShapeId
=0;
2263 DrawObjPointerIter aEnd
= aSorted
.end();
2264 for (DrawObjPointerIter aIter
= aSorted
.begin(); aIter
!= aEnd
; ++aIter
)
2266 sal_Int32 nBorderThick
=0;
2267 DrawObj
*pObj
= (*aIter
);
2268 OSL_ENSURE(pObj
, "impossible");
2271 const ww8::Frame
&rFrame
= pObj
->maContent
;
2272 const SwFrameFormat
& rFormat
= rFrame
.GetFrameFormat();
2274 switch (rFrame
.GetWriterType())
2276 case ww8::Frame::eTextBox
:
2277 case ww8::Frame::eOle
:
2278 case ww8::Frame::eGraphic
:
2279 nBorderThick
= WriteFlyFrame(*pObj
, nShapeId
, aSorted
);
2281 case ww8::Frame::eFormControl
:
2282 WriteOCXControl(rFormat
, nShapeId
= GenerateShapeId());
2284 case ww8::Frame::eDrawing
:
2286 aWinwordAnchoring
.SetAnchoring(rFormat
);
2287 const SdrObject
* pSdrObj
= rFormat
.FindRealSdrObject();
2290 bool bSwapInPage
= false;
2291 if (!pSdrObj
->GetPage())
2293 if (SwDrawModel
* pModel
= rWrt
.m_pDoc
->getIDocumentDrawModelAccess().GetDrawModel())
2295 if (SdrPage
*pPage
= pModel
->GetPage(0))
2298 (const_cast<SdrObject
*>(pSdrObj
))->SetPage(pPage
);
2303 nShapeId
= AddSdrObject(*pSdrObj
);
2306 (const_cast<SdrObject
*>(pSdrObj
))->SetPage(nullptr);
2308 #if OSL_DEBUG_LEVEL > 0
2310 OSL_ENSURE( false, "Where is the SDR-Object?" );
2320 nShapeId
= AddDummyShape();
2323 pObj
->SetShapeDetails(nShapeId
, nBorderThick
);
2326 EndSdrObjectPage(); // ???? Bugfix for 74724
2328 if( nSecondShapeId
)
2330 OpenContainer( ESCHER_SpContainer
);
2332 AddShape( ESCHER_ShpInst_Rectangle
, 0xe00, nSecondShapeId
);
2334 EscherPropertyContainer aPropOpt
;
2335 const SwFrameFormat
&rFormat
= rWrt
.m_pDoc
->GetPageDesc(0).GetMaster();
2336 const SfxPoolItem
* pItem
= nullptr;
2337 SfxItemState eState
= rFormat
.GetItemState(RES_BACKGROUND
, true,
2339 if (SfxItemState::SET
== eState
&& pItem
)
2341 const SvxBrushItem
* pBrush
= static_cast<const SvxBrushItem
*>(pItem
);
2342 WriteBrushAttr(*pBrush
, aPropOpt
);
2344 SvxGraphicPosition ePos
= pBrush
->GetGraphicPos();
2345 if( ePos
!= GPOS_NONE
&& ePos
!= GPOS_AREA
)
2347 /* #i56806# 0x033F parameter specifies a 32-bit field of shape boolean properties.
2348 0x10001 means fBackground and fUsefBackground flag are true thus background
2349 picture will be shown as "tiled" fill.*/
2350 aPropOpt
.AddOpt( ESCHER_Prop_fBackground
, 0x10001 );
2353 aPropOpt
.AddOpt( ESCHER_Prop_lineColor
, 0x8000001 );
2354 aPropOpt
.AddOpt( ESCHER_Prop_fNoLineDrawDash
, 0x00080008 );
2355 aPropOpt
.AddOpt( ESCHER_Prop_shadowColor
, 0x8000002 );
2356 aPropOpt
.AddOpt( ESCHER_Prop_lineWidth
, 0 );
2358 aPropOpt
.Commit( *pStrm
);
2360 AddAtom( 4, ESCHER_ClientData
);
2361 GetStream().WriteInt32( 1 );
2363 CloseContainer(); // ESCHER_SpContainer
2365 CloseContainer(); // ESCHER_DgContainer
2369 SwEscherEx::~SwEscherEx()
2373 void SwEscherEx::FinishEscher()
2375 pEscherStrm
->Seek(0);
2376 rWrt
.pTableStrm
->WriteStream( *pEscherStrm
);
2378 pEscherStrm
= nullptr;
2381 /** method to perform conversion of positioning attributes with the help
2382 of corresponding layout information
2385 Because most of the Writer object positions doesn't correspond to the
2386 object positions in WW8, this method converts the positioning
2387 attributes. For this conversion the corresponding layout information
2388 is needed. If no layout information exists - e.g. no layout exists - no
2389 conversion is performed.
2390 No conversion is performed for as-character anchored objects. Whose
2391 object positions are already treated special in method <WriteData(..)>.
2394 input/output parameter - containing the current horizontal position
2395 attributes, which are converted by this method.
2398 input/output parameter - containing the current vertical position
2399 attributes, which are converted by this method.
2401 @param _rFrameFormat
2402 input parameter - frame format of the anchored object
2404 @return boolean, indicating, if a conversion has been performed.
2406 bool WinwordAnchoring::ConvertPosition( SwFormatHoriOrient
& _iorHoriOri
,
2407 SwFormatVertOrient
& _iorVertOri
,
2408 const SwFrameFormat
& _rFrameFormat
)
2410 const RndStdIds eAnchor
= _rFrameFormat
.GetAnchor().GetAnchorId();
2412 if ( (FLY_AS_CHAR
== eAnchor
) || (FLY_AT_FLY
== eAnchor
) )
2414 // no conversion for as-character or at frame anchored objects
2418 // determine anchored object
2419 SwAnchoredObject
* pAnchoredObj( nullptr );
2421 const SwContact
* pContact
= _rFrameFormat
.FindContactObj();
2424 std::list
<SwAnchoredObject
*> aAnchoredObjs
;
2425 pContact
->GetAnchoredObjs( aAnchoredObjs
);
2426 if ( !aAnchoredObjs
.empty() )
2428 pAnchoredObj
= aAnchoredObjs
.front();
2432 if ( !pAnchoredObj
)
2434 // no anchored object found. Thus, the needed layout information can't
2435 // be determined. --> no conversion
2438 // no conversion for anchored drawing object, which aren't attached to an
2440 // This is the case for drawing objects, which are anchored inside a page
2441 // header/footer of an *unused* page style.
2442 if ( dynamic_cast<SwAnchoredDrawObject
*>(pAnchoredObj
) &&
2443 !pAnchoredObj
->GetAnchorFrame() )
2448 bool bConverted( false );
2450 // determine value of attribute 'Follow text flow', because positions aligned
2451 // at page areas have to be converted, if it's set.
2452 const bool bFollowTextFlow
= _rFrameFormat
.GetFollowTextFlow().GetValue();
2454 // check, if horizontal and vertical position have to be converted due to
2455 // the fact, that the object is anchored at a paragraph, which has a "column
2456 // break before" attribute
2457 bool bConvDueToAnchoredAtColBreakPara( false );
2458 if ( ( (eAnchor
== FLY_AT_PARA
) || (eAnchor
== FLY_AT_CHAR
) ) &&
2459 _rFrameFormat
.GetAnchor().GetContentAnchor() &&
2460 _rFrameFormat
.GetAnchor().GetContentAnchor()->nNode
.GetNode().IsTextNode() )
2462 SwTextNode
& rAnchorTextNode
=
2463 dynamic_cast<SwTextNode
&>(_rFrameFormat
.GetAnchor().GetContentAnchor()->nNode
.GetNode());
2464 const SvxFormatBreakItem
* pBreak
= &(ItemGet
<SvxFormatBreakItem
>(rAnchorTextNode
, RES_BREAK
));
2466 pBreak
->GetBreak() == SvxBreak::ColumnBefore
)
2468 bConvDueToAnchoredAtColBreakPara
= true;
2472 // convert horizontal position, if needed
2474 enum HoriConv
{ NO_CONV
, CONV2PG
, CONV2COL
, CONV2CHAR
};
2475 HoriConv
eHoriConv( NO_CONV
);
2477 // determine, if conversion has to be performed due to the position orientation
2478 bool bConvDueToOrientation( false );
2480 const sal_Int16 eHOri
= _iorHoriOri
.GetHoriOrient();
2481 bConvDueToOrientation
= eHOri
== text::HoriOrientation::LEFT
|| eHOri
== text::HoriOrientation::RIGHT
||
2482 eHOri
== text::HoriOrientation::INSIDE
|| eHOri
== text::HoriOrientation::OUTSIDE
||
2483 ( eHOri
!= text::HoriOrientation::CENTER
&& _iorHoriOri
.IsPosToggle() );
2486 // determine conversion type due to the position relation
2487 if ( bConvDueToAnchoredAtColBreakPara
)
2489 eHoriConv
= CONV2PG
;
2491 else if ( _iorHoriOri
.IsPosToggle()
2492 && _iorHoriOri
.GetHoriOrient() == text::HoriOrientation::RIGHT
)
2494 eHoriConv
= NO_CONV
;
2495 _iorHoriOri
.SetHoriOrient( text::HoriOrientation::OUTSIDE
);
2499 switch ( _iorHoriOri
.GetRelationOrient() )
2501 case text::RelOrientation::PAGE_FRAME
:
2502 case text::RelOrientation::PAGE_PRINT_AREA
:
2504 if ( bConvDueToOrientation
|| bFollowTextFlow
)
2505 eHoriConv
= CONV2PG
;
2508 case text::RelOrientation::PAGE_LEFT
:
2509 case text::RelOrientation::PAGE_RIGHT
:
2511 // relation not supported by WW8. Thus, conversion always needed.
2512 eHoriConv
= CONV2PG
;
2515 case text::RelOrientation::FRAME
:
2517 if ( bConvDueToOrientation
)
2518 eHoriConv
= CONV2COL
;
2521 case text::RelOrientation::PRINT_AREA
:
2522 case text::RelOrientation::FRAME_LEFT
:
2523 case text::RelOrientation::FRAME_RIGHT
:
2525 // relation not supported by WW8. Thus, conversion always needed.
2526 eHoriConv
= CONV2COL
;
2529 case text::RelOrientation::CHAR
:
2531 if ( bConvDueToOrientation
)
2532 eHoriConv
= CONV2CHAR
;
2536 OSL_FAIL( "<WinwordAnchoring::ConvertPosition(..)> - unknown horizontal relation" );
2539 if ( eHoriConv
!= NO_CONV
)
2541 _iorHoriOri
.SetHoriOrient( text::HoriOrientation::NONE
);
2542 SwTwips
nPosX( 0L );
2545 if ( eHoriConv
== CONV2PG
)
2547 _iorHoriOri
.SetRelationOrient( text::RelOrientation::PAGE_FRAME
);
2549 bool bRelToTableCell( false );
2550 aPos
= pAnchoredObj
->GetRelPosToPageFrame( bFollowTextFlow
,
2552 if ( bRelToTableCell
)
2554 _iorHoriOri
.SetRelationOrient( text::RelOrientation::PAGE_PRINT_AREA
);
2557 else if ( eHoriConv
== CONV2COL
)
2559 _iorHoriOri
.SetRelationOrient( text::RelOrientation::FRAME
);
2560 aPos
= pAnchoredObj
->GetRelPosToAnchorFrame();
2562 else if ( eHoriConv
== CONV2CHAR
)
2564 _iorHoriOri
.SetRelationOrient( text::RelOrientation::CHAR
);
2565 aPos
= pAnchoredObj
->GetRelPosToChar();
2567 // No distinction between layout directions, because of missing
2568 // information about WW8 in vertical layout.
2571 _iorHoriOri
.SetPos( nPosX
);
2576 // convert vertical position, if needed
2578 enum VertConv
{ NO_CONV
, CONV2PG
, CONV2PARA
, CONV2LINE
};
2579 VertConv
eVertConv( NO_CONV
);
2581 // determine, if conversion has to be performed due to the position orientation
2582 bool bConvDueToOrientation( false );
2584 const sal_Int16 eVOri
= _iorVertOri
.GetVertOrient();
2585 bConvDueToOrientation
= ( eVOri
== text::VertOrientation::TOP
||
2586 eVOri
== text::VertOrientation::BOTTOM
||
2587 eVOri
== text::VertOrientation::CHAR_TOP
||
2588 eVOri
== text::VertOrientation::CHAR_BOTTOM
||
2589 eVOri
== text::VertOrientation::CHAR_CENTER
||
2590 eVOri
== text::VertOrientation::LINE_TOP
||
2591 eVOri
== text::VertOrientation::LINE_BOTTOM
||
2592 eVOri
== text::VertOrientation::LINE_CENTER
);
2595 // determine conversion type due to the position relation
2596 if ( bConvDueToAnchoredAtColBreakPara
)
2598 eVertConv
= CONV2PG
;
2602 switch ( _iorVertOri
.GetRelationOrient() )
2604 case text::RelOrientation::PAGE_FRAME
:
2605 case text::RelOrientation::PAGE_PRINT_AREA
:
2607 if ( bConvDueToOrientation
|| bFollowTextFlow
)
2608 eVertConv
= CONV2PG
;
2611 case text::RelOrientation::FRAME
:
2613 if ( bConvDueToOrientation
||
2614 _iorVertOri
.GetVertOrient() == text::VertOrientation::CENTER
)
2616 eVertConv
= CONV2PARA
;
2620 case text::RelOrientation::PRINT_AREA
:
2622 // relation not supported by WW8. Thus, conversion always needed.
2623 eVertConv
= CONV2PARA
;
2626 case text::RelOrientation::CHAR
:
2628 // relation not supported by WW8. Thus, conversion always needed.
2629 eVertConv
= CONV2PARA
;
2632 case text::RelOrientation::TEXT_LINE
:
2634 if ( bConvDueToOrientation
||
2635 _iorVertOri
.GetVertOrient() == text::VertOrientation::NONE
)
2637 eVertConv
= CONV2LINE
;
2641 case text::RelOrientation::PAGE_LEFT
:
2642 case text::RelOrientation::PAGE_RIGHT
:
2643 case text::RelOrientation::FRAME_LEFT
:
2644 case text::RelOrientation::FRAME_RIGHT
:
2646 OSL_FAIL( "<WinwordAnchoring::ConvertPosition(..)> - unknown vertical relation" );
2650 if ( eVertConv
!= NO_CONV
)
2652 _iorVertOri
.SetVertOrient( text::VertOrientation::NONE
);
2653 SwTwips
nPosY( 0L );
2656 if ( eVertConv
== CONV2PG
)
2658 _iorVertOri
.SetRelationOrient( text::RelOrientation::PAGE_FRAME
);
2660 bool bRelToTableCell( false );
2661 aPos
= pAnchoredObj
->GetRelPosToPageFrame( bFollowTextFlow
,
2663 if ( bRelToTableCell
)
2665 _iorVertOri
.SetRelationOrient( text::RelOrientation::PAGE_PRINT_AREA
);
2668 else if ( eVertConv
== CONV2PARA
)
2670 _iorVertOri
.SetRelationOrient( text::RelOrientation::FRAME
);
2671 aPos
= pAnchoredObj
->GetRelPosToAnchorFrame();
2673 else if ( eVertConv
== CONV2LINE
)
2675 _iorVertOri
.SetRelationOrient( text::RelOrientation::TEXT_LINE
);
2676 aPos
= pAnchoredObj
->GetRelPosToLine();
2678 // No distinction between layout directions, because of missing
2679 // information about WW8 in vertical layout.
2682 _iorVertOri
.SetPos( nPosY
);
2690 void WinwordAnchoring::SetAnchoring(const SwFrameFormat
& rFormat
)
2692 const RndStdIds eAnchor
= rFormat
.GetAnchor().GetAnchorId();
2693 mbInline
= (eAnchor
== FLY_AS_CHAR
);
2695 SwFormatHoriOrient rHoriOri
= rFormat
.GetHoriOrient();
2696 SwFormatVertOrient rVertOri
= rFormat
.GetVertOrient();
2698 // #i30669# - convert the positioning attributes.
2699 // Most positions are converted, if layout information exists.
2700 const bool bPosConverted
= ConvertPosition( rHoriOri
, rVertOri
, rFormat
);
2702 const sal_Int16 eHOri
= rHoriOri
.GetHoriOrient();
2703 const sal_Int16 eVOri
= rVertOri
.GetVertOrient(); // #i22673#
2705 const sal_Int16 eHRel
= rHoriOri
.GetRelationOrient();
2706 const sal_Int16 eVRel
= rVertOri
.GetRelationOrient();
2708 // horizontal Adjustment
2712 case text::HoriOrientation::NONE
:
2715 case text::HoriOrientation::LEFT
:
2718 case text::HoriOrientation::CENTER
:
2721 case text::HoriOrientation::RIGHT
:
2724 case text::HoriOrientation::INSIDE
:
2727 case text::HoriOrientation::OUTSIDE
:
2732 // vertical Adjustment
2734 // When adjustment is vertically relative to line or to char
2735 // bottom becomes top and vice versa
2736 const bool bVertSwap
= !bPosConverted
&&
2737 ( (eVRel
== text::RelOrientation::CHAR
) ||
2738 (eVRel
== text::RelOrientation::TEXT_LINE
) );
2742 case text::VertOrientation::NONE
:
2745 case text::VertOrientation::TOP
:
2746 case text::VertOrientation::LINE_TOP
:
2747 case text::VertOrientation::CHAR_TOP
:
2748 mnYAlign
= bVertSwap
? 3 : 1;
2750 case text::VertOrientation::CENTER
:
2751 case text::VertOrientation::LINE_CENTER
:
2754 case text::VertOrientation::BOTTOM
:
2755 case text::VertOrientation::LINE_BOTTOM
:
2756 case text::VertOrientation::CHAR_BOTTOM
:
2757 mnYAlign
= bVertSwap
? 1 : 3;
2761 // Adjustment is horizontally relative to...
2764 case text::RelOrientation::PAGE_PRINT_AREA
:
2767 case text::RelOrientation::PAGE_FRAME
:
2768 case text::RelOrientation::PAGE_LEFT
: //:-(
2769 case text::RelOrientation::PAGE_RIGHT
: //:-(
2772 case text::RelOrientation::FRAME
:
2773 case text::RelOrientation::FRAME_LEFT
: //:-(
2774 case text::RelOrientation::FRAME_RIGHT
: //:-(
2775 if (eAnchor
== FLY_AT_PAGE
)
2780 case text::RelOrientation::PRINT_AREA
:
2781 if (eAnchor
== FLY_AT_PAGE
)
2786 case text::RelOrientation::CHAR
:
2789 case text::RelOrientation::TEXT_LINE
:
2793 // Adjustment is vertically relative to...
2796 case text::RelOrientation::PAGE_PRINT_AREA
:
2799 case text::RelOrientation::PAGE_FRAME
:
2802 case text::RelOrientation::PRINT_AREA
:
2803 if (eAnchor
== FLY_AT_PAGE
)
2808 case text::RelOrientation::FRAME
:
2809 if (eAnchor
== FLY_AT_PAGE
)
2814 case text::RelOrientation::CHAR
:
2815 case text::RelOrientation::TEXT_LINE
: // #i22673# - vertical alignment at top of line
2816 case text::RelOrientation::PAGE_LEFT
: //nonsense
2817 case text::RelOrientation::PAGE_RIGHT
: //nonsense
2818 case text::RelOrientation::FRAME_LEFT
: //nonsense
2819 case text::RelOrientation::FRAME_RIGHT
: //nonsense
2825 void SwEscherEx::WriteFrameExtraData( const SwFrameFormat
& rFormat
)
2827 aWinwordAnchoring
.SetAnchoring(rFormat
);
2828 aWinwordAnchoring
.WriteData(*this);
2830 AddAtom(4, ESCHER_ClientAnchor
);
2831 GetStream().WriteInt32( 0 );
2833 AddAtom(4, ESCHER_ClientData
);
2834 GetStream().WriteInt32( 1 );
2837 sal_Int32
SwEscherEx::WriteFlyFrame(const DrawObj
&rObj
, sal_uInt32
&rShapeId
,
2838 DrawObjPointerVector
&rPVec
)
2840 const SwFrameFormat
&rFormat
= rObj
.maContent
.GetFrameFormat();
2842 // check for textflyframe and if it is the first in a Chain
2843 sal_Int32 nBorderThick
= 0;
2844 const SwNodeIndex
* pNdIdx
= rFormat
.GetContent().GetContentIdx();
2847 SwNodeIndex
aIdx( *pNdIdx
, 1 );
2848 switch( aIdx
.GetNode().GetNodeType() )
2850 case SwNodeType::Grf
:
2851 nBorderThick
= WriteGrfFlyFrame( rFormat
, rShapeId
= GenerateShapeId() );
2853 case SwNodeType::Ole
:
2854 nBorderThick
= WriteOLEFlyFrame( rFormat
, rShapeId
= GenerateShapeId() );
2857 if (const SdrObject
* pObj
= rFormat
.FindRealSdrObject())
2859 // check for the first in a Chain
2861 sal_uInt16 nOff
= 0;
2862 const SwFrameFormat
* pFormat
= &rFormat
, *pPrev
;
2863 while( nullptr != ( pPrev
= pFormat
->GetChain().GetPrev() ))
2869 rShapeId
= GetFlyShapeId(rFormat
, rObj
.mnHdFtIndex
, rPVec
);
2872 nTextId
= pTextBxs
->GetPos( pObj
);
2873 if( USHRT_MAX
== nTextId
)
2875 pTextBxs
->Append( *pObj
, rShapeId
);
2876 nTextId
= pTextBxs
->Count();
2883 const SdrObject
* pPrevObj
= pFormat
->FindRealSdrObject();
2884 nTextId
= pTextBxs
->GetPos( pPrevObj
);
2885 if( USHRT_MAX
== nTextId
)
2887 sal_uInt32 nPrevShapeId
=
2888 GetFlyShapeId(*pFormat
, rObj
.mnHdFtIndex
, rPVec
);
2889 pTextBxs
->Append( *pPrevObj
, nPrevShapeId
);
2890 nTextId
= pTextBxs
->Count();
2898 nBorderThick
= WriteTextFlyFrame(rObj
, rShapeId
, nTextId
, rPVec
);
2901 //In browse mode the sdr object doesn't always exist. For example, the
2902 //object is in the hidden header/footer. We save the fmt directly
2903 //in such cases; we copy most of the logic from the block above
2904 const bool bBrowseMode
= rFormat
.getIDocumentSettingAccess().get(DocumentSettingId::BROWSE_MODE
);
2905 if( bBrowseMode
&& rFormat
.GetDoc())
2907 if( !rFormat
.GetChain().GetPrev() )//obj in header/footer?
2909 rShapeId
= GetFlyShapeId(rFormat
, rObj
.mnHdFtIndex
, rPVec
);
2910 pTextBxs
->Append( &rFormat
, rShapeId
);
2911 sal_uInt32 nTextId
= pTextBxs
->Count();
2914 nBorderThick
= WriteTextFlyFrame(rObj
, rShapeId
, nTextId
, rPVec
);
2920 return nBorderThick
;
2923 sal_uInt16
FindPos(const SwFrameFormat
&rFormat
, unsigned int nHdFtIndex
,
2924 DrawObjPointerVector
&rPVec
)
2926 DrawObjPointerIter aEnd
= rPVec
.end();
2927 for (DrawObjPointerIter aIter
= rPVec
.begin(); aIter
!= aEnd
; ++aIter
)
2929 const DrawObj
*pObj
= (*aIter
);
2930 OSL_ENSURE(pObj
, "Impossible");
2934 nHdFtIndex
== pObj
->mnHdFtIndex
&&
2935 &rFormat
== (&pObj
->maContent
.GetFrameFormat())
2938 return static_cast< sal_uInt16
>(aIter
- rPVec
.begin());
2944 sal_Int32
SwEscherEx::WriteTextFlyFrame(const DrawObj
&rObj
, sal_uInt32 nShapeId
,
2945 sal_uInt32 nTextBox
, DrawObjPointerVector
&rPVec
)
2947 const SwFrameFormat
&rFormat
= rObj
.maContent
.GetFrameFormat();
2948 short nDirection
= rObj
.mnDirection
;
2950 sal_Int32 nBorderThick
=0;
2951 OpenContainer( ESCHER_SpContainer
);
2953 AddShape( ESCHER_ShpInst_TextBox
, 0xa00, nShapeId
);
2954 EscherPropertyContainer aPropOpt
;
2955 aPropOpt
.AddOpt(ESCHER_Prop_lTxid
, nTextBox
);
2956 if (const SwFrameFormat
*pNext
= rFormat
.GetChain().GetNext())
2958 sal_uInt16 nPos
= FindPos(*pNext
, rObj
.mnHdFtIndex
, rPVec
);
2959 if (USHRT_MAX
!= nPos
&& aFollowShpIds
[nPos
])
2960 aPropOpt
.AddOpt(ESCHER_Prop_hspNext
, aFollowShpIds
[nPos
]);
2962 nBorderThick
= WriteFlyFrameAttr( rFormat
, mso_sptTextBox
, aPropOpt
);
2969 OSL_ENSURE(false, "unknown direction type");
2971 case FRMDIR_HORI_LEFT_TOP
:
2972 nFlow
=mso_txflHorzN
;
2974 case FRMDIR_HORI_RIGHT_TOP
:
2975 nFlow
=mso_txflHorzN
;
2977 case FRMDIR_VERT_TOP_LEFT
: //not really possible in word
2978 case FRMDIR_VERT_TOP_RIGHT
:
2979 nFlow
=mso_txflTtoBA
;
2982 aPropOpt
.AddOpt( ESCHER_Prop_txflTextFlow
, nFlow
);
2984 aPropOpt
.Commit( GetStream() );
2986 // store anchor attribute
2987 WriteFrameExtraData( rFormat
);
2989 AddAtom( 4, ESCHER_ClientTextbox
); GetStream().WriteUInt32( nTextBox
);
2991 CloseContainer(); // ESCHER_SpContainer
2992 return nBorderThick
;
2995 void SwBasicEscherEx::WriteOLEPicture(EscherPropertyContainer
&rPropOpt
,
2996 sal_uInt32 nShapeFlags
, const Graphic
&rGraphic
, const SdrObject
&rObj
,
2997 sal_uInt32 nShapeId
, const awt::Rectangle
* pVisArea
)
2999 //nShapeFlags == 0xA00 + flips and ole active
3000 AddShape(ESCHER_ShpInst_PictureFrame
, nShapeFlags
, nShapeId
);
3002 GraphicObject
aGraphicObject(rGraphic
);
3003 OString aId
= aGraphicObject
.GetUniqueID();
3006 Rectangle aRect
= rObj
.GetLogicRect();
3007 aRect
.SetPos(Point(0,0));
3008 aRect
.Right() = DrawModelToEmu(aRect
.Right());
3009 aRect
.Bottom() = DrawModelToEmu(aRect
.Bottom());
3010 sal_uInt32 nBlibId
= mxGlobal
->GetBlibID( *QueryPictureStream(),
3011 aId
, aRect
, pVisArea
); // SJ: the fourth parameter (VisArea) should be set..
3013 rPropOpt
.AddOpt(ESCHER_Prop_pib
, nBlibId
, true);
3016 SetPicId(rObj
, nShapeId
, rPropOpt
);
3017 rPropOpt
.AddOpt( ESCHER_Prop_pictureActive
, 0x10000 );
3020 void SwEscherEx::WriteOCXControl( const SwFrameFormat
& rFormat
, sal_uInt32 nShapeId
)
3022 if (const SdrObject
* pSdrObj
= rFormat
.FindRealSdrObject())
3024 OpenContainer( ESCHER_SpContainer
);
3026 SwDrawModel
*pModel
= rWrt
.m_pDoc
->getIDocumentDrawModelAccess().GetDrawModel();
3027 OutputDevice
*pDevice
= Application::GetDefaultDevice();
3028 OSL_ENSURE(pModel
&& pDevice
, "no model or device");
3030 // #i71538# use complete SdrViews
3031 // SdrExchangeView aExchange(pModel, pDevice);
3032 SdrView
aExchange(pModel
, pDevice
);
3034 Graphic
aGraphic(SdrExchangeView::GetObjGraphic(pModel
, pSdrObj
));
3036 EscherPropertyContainer aPropOpt
;
3037 WriteOLEPicture(aPropOpt
, 0xa00 | SHAPEFLAG_OLESHAPE
, aGraphic
,
3038 *pSdrObj
, nShapeId
, nullptr );
3040 WriteFlyFrameAttr( rFormat
, mso_sptPictureFrame
, aPropOpt
);
3041 aPropOpt
.Commit( GetStream() );
3043 // store anchor attribute
3044 WriteFrameExtraData( rFormat
);
3046 CloseContainer(); // ESCHER_SpContainer
3050 void SwEscherEx::MakeZOrderArrAndFollowIds(
3051 std::vector
<DrawObj
>& rSrcArr
, std::vector
<DrawObj
*>&rDstArr
)
3053 ::lcl_makeZOrderArray(rWrt
, rSrcArr
, rDstArr
);
3055 //Now set up the follow IDs
3056 aFollowShpIds
.clear();
3058 for (DrawObj
* p
: rDstArr
)
3060 const SwFrameFormat
&rFormat
= p
->maContent
.GetFrameFormat();
3061 bool bNeedsShapeId
= false;
3063 if (RES_FLYFRMFMT
== rFormat
.Which())
3065 const SwFormatChain
&rChain
= rFormat
.GetChain();
3066 if (rChain
.GetPrev() || rChain
.GetNext())
3067 bNeedsShapeId
= true;
3070 sal_uLong nShapeId
= bNeedsShapeId
? GenerateShapeId() : 0;
3072 aFollowShpIds
.push_back(nShapeId
);
3076 sal_uInt32
SwEscherEx::GetFlyShapeId(const SwFrameFormat
& rFormat
,
3077 unsigned int nHdFtIndex
, DrawObjPointerVector
&rpVec
)
3079 sal_uInt16 nPos
= FindPos(rFormat
, nHdFtIndex
, rpVec
);
3080 sal_uInt32 nShapeId
;
3081 if (USHRT_MAX
!= nPos
)
3083 if (0 == (nShapeId
= aFollowShpIds
[nPos
]))
3085 nShapeId
= GenerateShapeId();
3086 aFollowShpIds
[ nPos
] = nShapeId
;
3090 nShapeId
= GenerateShapeId();
3094 sal_uInt32
SwEscherEx::QueryTextID(
3095 const uno::Reference
< drawing::XShape
>& xXShapeRef
, sal_uInt32 nShapeId
)
3098 if (SdrObject
* pObj
= GetSdrObjectFromXShape(xXShapeRef
))
3100 pTextBxs
->Append( *pObj
, nShapeId
);
3101 nId
= pTextBxs
->Count();
3107 SwMSConvertControls::SwMSConvertControls( SfxObjectShell
*pDSh
,SwPaM
*pP
) : oox
3108 ::ole::MSConvertOCXControls( pDSh
? pDSh
->GetModel() : nullptr ), pPaM( pP
), mnObjectId(0)
3113 // in transitioning away old filter for ole/ocx controls, ReadOCXStream has been made pure virtual in
3114 // filter/source/msocximex.cxx, so.. we need an implementation here
3115 bool SwMSConvertControls::ReadOCXStream( tools::SvRef
<SotStorage
>& rSrc1
,
3116 css::uno::Reference
< css::drawing::XShape
> *pShapeRef
,
3117 bool bFloatingCtrl
)
3119 uno::Reference
< form::XFormComponent
> xFComp
;
3120 bool bRes
= oox::ole::MSConvertOCXControls::ReadOCXStorage( rSrc1
, xFComp
);
3121 if ( bRes
&& xFComp
.is() )
3123 css::awt::Size aSz
; // not used in import
3124 bRes
= InsertControl( xFComp
, aSz
,pShapeRef
,bFloatingCtrl
);
3129 void SwMSConvertControls::ExportControl(WW8Export
&rWW8Wrt
, const SdrUnoObj
& rFormObj
)
3131 const uno::Reference
< awt::XControlModel
>& xControlModel
=
3132 rFormObj
.GetUnoControlModel();
3134 //Why oh lord do we use so many different units ?
3135 //I think I painted myself into a little bit of a
3136 //corner by trying to use the uno interface for
3138 Rectangle aRect
= rFormObj
.GetLogicRect();
3139 aRect
.SetPos(Point(0,0));
3141 aSize
.Width
= TWIPS_TO_MM(aRect
.Right());
3142 aSize
.Height
= TWIPS_TO_MM(aRect
.Bottom());
3144 //Open the ObjectPool
3145 tools::SvRef
<SotStorage
> xObjPool
= rWW8Wrt
.GetWriter().GetStorage().OpenSotStorage(
3146 OUString(SL::aObjectPool
));
3148 //Create a destination storage for the microsoft control
3149 OUStringBuffer sStorageName
;
3150 sal_uInt32 nObjId
= ++mnObjectId
;
3151 sStorageName
.append('_').append( static_cast<sal_Int64
>( nObjId
));
3152 tools::SvRef
<SotStorage
> xOleStg
= xObjPool
->OpenSotStorage(sStorageName
.makeStringAndClear());
3158 if (!WriteOCXStream( mxModel
, xOleStg
,xControlModel
,aSize
,sUName
))
3161 sal_uInt8 aSpecOLE
[] =
3163 0x03, 0x6a, 0xFF, 0xFF, 0xFF, 0xFF, // sprmCPicLocation
3164 0x0a, 0x08, 1, // sprmCFOLE2
3165 0x55, 0x08, 1, // sprmCFSpec
3166 0x56, 0x08, 1 // sprmCFObj
3168 //Set the obj id into the sprmCPicLocation
3169 sal_uInt8
*pData
= aSpecOLE
+2;
3170 Set_UInt32(pData
,nObjId
);
3172 OUString sField
= FieldString(ww::eCONTROL
) + "Forms." + sUName
+ ".1 \\s ";
3174 rWW8Wrt
.OutputField(nullptr, ww::eCONTROL
, sField
,
3175 WRITEFIELD_START
|WRITEFIELD_CMD_START
|WRITEFIELD_CMD_END
);
3177 rWW8Wrt
.m_pChpPlc
->AppendFkpEntry(rWW8Wrt
.Strm().Tell(),sizeof(aSpecOLE
),
3179 rWW8Wrt
.WriteChar( 0x1 );
3180 rWW8Wrt
.OutputField(nullptr, ww::eCONTROL
, OUString(), WRITEFIELD_END
| WRITEFIELD_CLOSE
);
3183 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */