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 <vcl/cvtgrf.hxx>
25 #include <vcl/virdev.hxx>
26 #include <com/sun/star/drawing/XShape.hpp>
27 #include <vcl/svapp.hxx>
28 #include <sot/storage.hxx>
29 #include <vcl/graphicfilter.hxx>
30 #include <svl/itemiter.hxx>
31 #include <svx/svdobj.hxx>
32 #include <svx/svdotext.hxx>
33 #include <svx/svdmodel.hxx>
34 #include <svx/svdpage.hxx>
35 #include <editeng/outlobj.hxx>
36 #include <editeng/editobj.hxx>
37 #include <svx/unoshape.hxx>
38 #include <editeng/brushitem.hxx>
39 #include <editeng/boxitem.hxx>
40 #include <editeng/lrspitem.hxx>
41 #include <editeng/ulspitem.hxx>
42 #include <editeng/fontitem.hxx>
43 #include <editeng/frmdiritem.hxx>
44 #include <svx/svdoole2.hxx>
45 #include <editeng/editeng.hxx>
46 #include <editeng/flditem.hxx>
47 #include <unotools/ucbstreamhelper.hxx>
48 #include <svx/fmglob.hxx>
49 #include <svx/svdouno.hxx>
50 #include <svx/unoapi.hxx>
53 #include <svx/svdview.hxx>
54 #include <fmtcnct.hxx>
55 #include <fmtanchr.hxx>
56 #include <fmtsrnd.hxx>
57 #include <fmtornt.hxx>
58 #include <fmtfsize.hxx>
59 #include <fmtfollowtextflow.hxx> // #i30669#
60 #include <dcontact.hxx>
63 #include <pagefrm.hxx>
65 #include <fmtcntnt.hxx>
66 #include <ndindex.hxx>
74 #include <unodraw.hxx>
75 #include <pagedesc.hxx>
77 #include <breakit.hxx>
78 #include <com/sun/star/i18n/ScriptType.hpp>
79 #include "ww8attributeoutput.hxx"
80 #include "writerhelper.hxx"
81 #include "writerwordglue.hxx"
85 #include "WW8FFData.hxx"
86 #include <com/sun/star/beans/XPropertyContainer.hpp>
87 #include <com/sun/star/beans/XPropertySet.hpp>
88 #include <com/sun/star/beans/PropertyAttribute.hpp>
89 #include <com/sun/star/form/XFormComponent.hpp>
91 #include <oox/ole/olehelper.hxx>
93 #include <unotools/streamwrap.hxx>
96 using ::editeng::SvxBorderLine
;
97 using namespace com::sun::star
;
98 using namespace sw::util
;
99 using namespace sw::types
;
100 using namespace nsFieldFlags
;
104 /// Get the Z ordering number for a DrawObj in a WW8Export.
105 /// @param rWrt The containing WW8Export.
106 /// @param pObj pointer to the drawing object.
107 /// @returns The ordering number.
108 static sal_uLong
lcl_getSdrOrderNumber(const WW8Export
& rWrt
, DrawObj
*pObj
)
110 return rWrt
.GetSdrOrdNum(pObj
->maCntnt
.GetFrmFmt());
113 /// A function object to act as a predicate comparing the ordering numbers
114 /// of two drawing obejcts in a WW8Export.
115 class CompareDrawObjs
118 const WW8Export
& wrt
;
121 CompareDrawObjs(const WW8Export
& rWrt
) : wrt(rWrt
) {};
122 bool operator()(DrawObj
*a
, DrawObj
*b
) const
124 sal_uLong aSort
= lcl_getSdrOrderNumber(wrt
, a
);
125 sal_uLong bSort
= lcl_getSdrOrderNumber(wrt
, b
);
126 return aSort
< bSort
;
130 /// Make a z-order sorted copy of a collection of DrawObj objects.
131 /// @param rWrt The containing WW8Export.
132 /// @param rSrcArr The source array.
133 /// @param rDstArr The destination array.
134 static void lcl_makeZOrderArray(const WW8Export
& rWrt
,
135 std::vector
<DrawObj
> &rSrcArr
,
136 std::vector
<DrawObj
*> &rDstArr
)
139 rDstArr
.reserve(rSrcArr
.size());
140 for(size_t i
= 0; i
< rSrcArr
.size(); ++i
)
142 rDstArr
.push_back( &rSrcArr
[i
] );
144 std::sort(rDstArr
.begin(), rDstArr
.end(), CompareDrawObjs(rWrt
));
149 // get a part fix for this type of element
150 bool WW8Export::MiserableFormFieldExportHack(const SwFrmFmt
& rFrmFmt
)
152 OSL_ENSURE(bWrtWW8
, "Not allowed");
156 const SdrObject
*pObject
= rFrmFmt
.FindRealSdrObject();
157 if (pObject
&& pObject
->GetObjInventor() == FmFormInventor
)
159 if (SdrUnoObj
*pFormObj
= PTR_CAST(SdrUnoObj
,pObject
))
161 uno::Reference
< awt::XControlModel
> xControlModel
=
162 pFormObj
->GetUnoControlModel();
163 uno::Reference
< lang::XServiceInfo
> xInfo(xControlModel
,
165 uno::Reference
<beans::XPropertySet
> xPropSet(xControlModel
, uno::UNO_QUERY
);
166 if (xInfo
->supportsService("com.sun.star.form.component.ComboBox"))
168 DoComboBox(xPropSet
);
171 else if (xInfo
->supportsService("com.sun.star.form.component.CheckBox"))
173 DoCheckBox(xPropSet
);
182 void WW8Export::DoComboBox(uno::Reference
<beans::XPropertySet
> xPropSet
)
185 uno::Sequence
<OUString
> aListItems
;
186 xPropSet
->getPropertyValue("StringItemList") >>= aListItems
;
187 sal_Int32 nNoStrings
= aListItems
.getLength();
190 uno::Any aTmp
= xPropSet
->getPropertyValue("DefaultText");
191 const OUString
*pStr
= (const OUString
*)aTmp
.getValue();
198 uno::Any aTmp
= xPropSet
->getPropertyValue("Name");
199 const OUString
*pStr
= (const OUString
*)aTmp
.getValue();
207 // property "Help" does not exist and due to the no-existence an exception is thrown.
210 uno::Any aTmp
= xPropSet
->getPropertyValue("HelpText");
211 const OUString
*pStr
= (const OUString
*)aTmp
.getValue();
215 catch( const uno::Exception
& )
221 uno::Any aTmp
= xPropSet
->getPropertyValue("Name");
222 const OUString
*pStr
= (const OUString
*)aTmp
.getValue();
227 DoComboBox(sName
, sHelp
, sToolTip
, sSelected
, aListItems
);
230 void WW8Export::DoComboBox(const OUString
&rName
,
231 const OUString
&rHelp
,
232 const OUString
&rToolTip
,
233 const OUString
&rSelected
,
234 uno::Sequence
<OUString
> &rListItems
)
236 OSL_ENSURE(bWrtWW8
, "Not allowed");
239 OutputField(0, ww::eFORMDROPDOWN
, FieldString(ww::eFORMDROPDOWN
),
240 WRITEFIELD_START
| WRITEFIELD_CMD_START
);
241 // write the refence to the "picture" structure
242 sal_uLong nDataStt
= pDataStrm
->Tell();
243 pChpPlc
->AppendFkpEntry( Strm().Tell() );
247 static sal_uInt8 aArr1
[] =
249 0x03, 0x6a, 0,0,0,0, // sprmCPicLocation
250 0x06, 0x08, 0x01, // sprmCFData
251 0x55, 0x08, 0x01, // sprmCFSpec
252 0x02, 0x08, 0x01 // sprmCFFldVanish
254 sal_uInt8
* pDataAdr
= aArr1
+ 2;
255 Set_UInt32( pDataAdr
, nDataStt
);
257 pChpPlc
->AppendFkpEntry(Strm().Tell(), sizeof(aArr1
), aArr1
);
259 OutputField(0, ww::eFORMDROPDOWN
, FieldString(ww::eFORMDROPDOWN
),
262 ::sw::WW8FFData aFFData
;
265 aFFData
.setName(rName
);
266 aFFData
.setHelp(rHelp
);
267 aFFData
.setStatus(rToolTip
);
269 sal_uInt32 nListItems
= rListItems
.getLength();
271 for (sal_uInt32 i
= 0; i
< nListItems
; i
++)
273 if (i
< 0x20 && rSelected
== rListItems
[i
])
274 aFFData
.setResult(::sal::static_int_cast
<sal_uInt8
>(i
));
275 aFFData
.addListboxEntry(rListItems
[i
]);
278 aFFData
.Write(pDataStrm
);
281 void WW8Export::DoCheckBox(uno::Reference
<beans::XPropertySet
> xPropSet
)
283 uno::Reference
<beans::XPropertySetInfo
> xPropSetInfo
=
284 xPropSet
->getPropertySetInfo();
286 OutputField(0, ww::eFORMCHECKBOX
, FieldString(ww::eFORMCHECKBOX
),
287 WRITEFIELD_START
| WRITEFIELD_CMD_START
);
288 // write the refence to the "picture" structure
289 sal_uLong nDataStt
= pDataStrm
->Tell();
290 pChpPlc
->AppendFkpEntry( Strm().Tell() );
293 static sal_uInt8 aArr1
[] = {
294 0x03, 0x6a, 0,0,0,0, // sprmCPicLocation
296 0x06, 0x08, 0x01, // sprmCFData
297 0x55, 0x08, 0x01, // sprmCFSpec
298 0x02, 0x08, 0x01 // sprmCFFldVanish
300 sal_uInt8
* pDataAdr
= aArr1
+ 2;
301 Set_UInt32( pDataAdr
, nDataStt
);
303 pChpPlc
->AppendFkpEntry(Strm().Tell(),
304 sizeof( aArr1
), aArr1
);
306 ::sw::WW8FFData aFFData
;
309 aFFData
.setCheckboxHeight(0x14);
312 xPropSet
->getPropertyValue("DefaultState") >>= nTemp
;
313 aFFData
.setDefaultResult(nTemp
);
315 xPropSet
->getPropertyValue("State") >>= nTemp
;
316 aFFData
.setResult(nTemp
);
319 static OUString
sName("Name");
320 if (xPropSetInfo
->hasPropertyByName(sName
))
322 xPropSet
->getPropertyValue(sName
) >>= aStr
;
323 aFFData
.setName(aStr
);
326 static OUString
sHelpText("HelpText");
327 if (xPropSetInfo
->hasPropertyByName(sHelpText
))
329 xPropSet
->getPropertyValue(sHelpText
) >>= aStr
;
330 aFFData
.setHelp(aStr
);
332 static OUString
sHelpF1Text("HelpF1Text");
333 if (xPropSetInfo
->hasPropertyByName(sHelpF1Text
))
335 xPropSet
->getPropertyValue(sHelpF1Text
) >>= aStr
;
336 aFFData
.setStatus(aStr
);
339 aFFData
.Write(pDataStrm
);
341 OutputField(0, ww::eFORMCHECKBOX
, aEmptyStr
, WRITEFIELD_CLOSE
);
344 void WW8Export::DoFormText(const SwInputField
* pFld
)
346 OutputField(0, ww::eFORMTEXT
, FieldString(ww::eFORMTEXT
),
347 WRITEFIELD_START
| WRITEFIELD_CMD_START
);
348 // write the refence to the "picture" structure
349 sal_uLong nDataStt
= pDataStrm
->Tell();
350 pChpPlc
->AppendFkpEntry( Strm().Tell() );
353 static sal_uInt8 aArr1
[] = {
354 0x02, 0x08, 0x81, // sprmCFFldVanish
355 0x03, 0x6a, 0,0,0,0, // sprmCPicLocation
357 0x06, 0x08, 0x01, // sprmCFData
358 0x55, 0x08, 0x01 // sprmCFSpec
360 sal_uInt8
* pDataAdr
= aArr1
+ 5;
361 Set_UInt32( pDataAdr
, nDataStt
);
363 pChpPlc
->AppendFkpEntry(Strm().Tell(),
364 sizeof( aArr1
), aArr1
);
366 ::sw::WW8FFData aFFData
;
369 aFFData
.setName(pFld
->GetPar2());
370 aFFData
.setHelp(pFld
->GetHelp());
371 aFFData
.setStatus(pFld
->GetToolTip());
372 aFFData
.Write(pDataStrm
);
374 OutputField(0, ww::eFORMTEXT
, aEmptyStr
, WRITEFIELD_CMD_END
);
376 String
const fieldStr( pFld
->ExpandField(true) );
377 SwWW8Writer::WriteString16(Strm(), fieldStr
, false);
379 static sal_uInt8 aArr2
[] = {
380 0x03, 0x6a, 0x00, 0x00, 0x00, 0x00, // sprmCPicLocation
381 0x55, 0x08, 0x01, // sprmCFSpec
382 0x75, 0x08, 0x01 // ???
385 pDataAdr
= aArr2
+ 2;
386 Set_UInt32( pDataAdr
, nDataStt
);
387 pChpPlc
->AppendFkpEntry(Strm().Tell(),
388 sizeof( aArr2
), aArr2
);
390 OutputField(0, ww::eFORMTEXT
, aEmptyStr
, WRITEFIELD_CLOSE
);
393 PlcDrawObj::~PlcDrawObj()
397 //Its irritating to have to change the RTL frames position into LTR ones
398 //so that word will have to place them in the right place. Doubly so that
399 //the SO drawings and writer frames have different ideas themselves as to
400 //how to be positioned when in RTL mode!
401 bool RTLGraphicsHack(SwTwips
&rLeft
, SwTwips nWidth
,
402 sal_Int16 eHoriOri
, sal_Int16 eHoriRel
, SwTwips nPageLeft
,
403 SwTwips nPageRight
, SwTwips nPageSize
)
406 if (eHoriOri
== text::HoriOrientation::NONE
)
408 if (eHoriRel
== text::RelOrientation::PAGE_FRAME
)
410 rLeft
= nPageSize
- rLeft
;
414 (eHoriRel
== text::RelOrientation::PAGE_PRINT_AREA
) ||
415 (eHoriRel
== text::RelOrientation::FRAME
) ||
416 (eHoriRel
== text::RelOrientation::PRINT_AREA
)
419 rLeft
= nPageSize
- nPageLeft
- nPageRight
- rLeft
;
428 bool RTLDrawingsHack(long &rLeft
, long /*nWidth*/,
429 sal_Int16 eHoriOri
, sal_Int16 eHoriRel
, SwTwips nPageLeft
,
430 SwTwips nPageRight
, SwTwips nPageSize
)
433 if (eHoriOri
== text::HoriOrientation::NONE
)
435 if (eHoriRel
== text::RelOrientation::PAGE_FRAME
)
437 rLeft
= nPageSize
+ rLeft
;
441 (eHoriRel
== text::RelOrientation::PAGE_PRINT_AREA
) ||
442 (eHoriRel
== text::RelOrientation::FRAME
) ||
443 (eHoriRel
== text::RelOrientation::PRINT_AREA
)
446 rLeft
= nPageSize
- nPageLeft
- nPageRight
+ rLeft
;
453 bool WW8Export::MiserableRTLFrmFmtHack(SwTwips
&rLeft
, SwTwips
&rRight
,
454 const sw::Frame
&rFrmFmt
)
456 //Require nasty bidi swap
457 if (FRMDIR_HORI_RIGHT_TOP
!= pDoc
->GetTextDirection(rFrmFmt
.GetPosition()))
460 SwTwips nWidth
= rRight
- rLeft
;
461 SwTwips nPageLeft
, nPageRight
;
462 SwTwips nPageSize
= CurrentPageWidth(nPageLeft
, nPageRight
);
464 const SwFmtHoriOrient
& rHOr
= rFrmFmt
.GetFrmFmt().GetHoriOrient();
467 sw::Frame::WriterSource eSource
= rFrmFmt
.GetWriterType();
468 if (eSource
== sw::Frame::eDrawing
|| eSource
== sw::Frame::eFormControl
)
470 if (RTLDrawingsHack(rLeft
, nWidth
, rHOr
.GetHoriOrient(),
471 rHOr
.GetRelationOrient(), nPageLeft
, nPageRight
, nPageSize
))
478 if (RTLGraphicsHack(rLeft
, nWidth
, rHOr
.GetHoriOrient(),
479 rHOr
.GetRelationOrient(), nPageLeft
, nPageRight
, nPageSize
))
485 rRight
= rLeft
+ nWidth
;
489 void PlcDrawObj::WritePlc( WW8Export
& rWrt
) const
491 if (8 > rWrt
.pFib
->nVersion
) // Cannot export drawobject in vers 7-
494 sal_uInt32 nFcStart
= rWrt
.pTableStrm
->Tell();
496 if (!maDrawObjs
.empty())
499 WW8Fib
& rFib
= *rWrt
.pFib
;
500 WW8_CP nCpOffs
= GetCpOffset(rFib
);
502 cDrawObjIter aEnd
= maDrawObjs
.end();
505 for (aIter
= maDrawObjs
.begin(); aIter
< aEnd
; ++aIter
)
506 SwWW8Writer::WriteLong(*rWrt
.pTableStrm
, aIter
->mnCp
- nCpOffs
);
508 SwWW8Writer::WriteLong(*rWrt
.pTableStrm
, rFib
.ccpText
+ rFib
.ccpFtn
+
509 rFib
.ccpHdr
+ rFib
.ccpEdn
+ rFib
.ccpTxbx
+ rFib
.ccpHdrTxbx
+ 1);
511 for (aIter
= maDrawObjs
.begin(); aIter
< aEnd
; ++aIter
)
513 // write the fspa-struct
514 const sw::Frame
&rFrmFmt
= aIter
->maCntnt
;
515 const SwFrmFmt
&rFmt
= rFrmFmt
.GetFrmFmt();
516 const SdrObject
* pObj
= rFmt
.FindRealSdrObject();
519 SwFmtVertOrient rVOr
= rFmt
.GetVertOrient();
520 SwFmtHoriOrient rHOr
= rFmt
.GetHoriOrient();
521 // #i30669# - convert the positioning attributes.
522 // Most positions are converted, if layout information exists.
523 const bool bPosConverted
=
524 WinwordAnchoring::ConvertPosition( rHOr
, rVOr
, rFmt
);
527 if (RES_FLYFRMFMT
== rFmt
.Which())
529 SwRect
aLayRect(rFmt
.FindLayoutRect(false, &aObjPos
));
530 // the Object is not visible - so get the values from
531 // the format. The Position may not be correct.
532 if( aLayRect
.IsEmpty() )
533 aRect
.SetSize( rFmt
.GetFrmSize().GetSize() );
536 // #i56090# Do not only consider the first client
537 // Note that we actually would have to find the maximum size of the
538 // frame format clients. However, this already should work in most cases.
539 const SwRect
aSizeRect(rFmt
.FindLayoutRect());
540 if ( aSizeRect
.Width() > aLayRect
.Width() )
541 aLayRect
.Width( aSizeRect
.Width() );
543 aRect
= aLayRect
.SVRect();
548 OSL_ENSURE(pObj
, "wo ist das SDR-Object?");
551 aRect
= pObj
->GetSnapRect();
555 // #i30669# - use converted position, if conversion is performed.
556 // Unify position determination of Writer fly frames
557 // and drawing objects.
560 aRect
.SetPos( Point( rHOr
.GetPos(), rVOr
.GetPos() ) );
564 aRect
-= aIter
->maParentPos
;
565 aObjPos
= aRect
.TopLeft();
566 if (text::VertOrientation::NONE
== rVOr
.GetVertOrient())
569 sal_Int16 eOri
= rVOr
.GetRelationOrient();
570 if (eOri
== text::RelOrientation::CHAR
|| eOri
== text::RelOrientation::TEXT_LINE
)
571 aObjPos
.Y() = -rVOr
.GetPos();
573 aObjPos
.Y() = rVOr
.GetPos();
575 if (text::HoriOrientation::NONE
== rHOr
.GetHoriOrient())
576 aObjPos
.X() = rHOr
.GetPos();
577 aRect
.SetPos( aObjPos
);
580 sal_Int32 nThick
= aIter
->mnThick
;
582 //If we are being exported as an inline hack, set
583 //corner to 0 and forget about border thickness for positioning
584 if (rFrmFmt
.IsInline())
586 aRect
.SetPos(Point(0,0));
591 SwWW8Writer::WriteLong(*rWrt
.pTableStrm
, aIter
->mnShapeId
);
593 SwTwips nLeft
= aRect
.Left() + nThick
;
594 SwTwips nRight
= aRect
.Right() - nThick
;
596 //Nasty swap for bidi if necessary
597 rWrt
.MiserableRTLFrmFmtHack(nLeft
, nRight
, rFrmFmt
);
599 //xaLeft/yaTop/xaRight/yaBottom - rel. to anchor
600 //(most of) the border is outside the graphic is word, so
601 //change dimensions to fit
602 SwWW8Writer::WriteLong(*rWrt
.pTableStrm
, nLeft
);
603 SwWW8Writer::WriteLong(*rWrt
.pTableStrm
,aRect
.Top() + nThick
);
604 SwWW8Writer::WriteLong(*rWrt
.pTableStrm
, nRight
);
605 SwWW8Writer::WriteLong(*rWrt
.pTableStrm
,aRect
.Bottom() - nThick
);
607 //fHdr/bx/by/wr/wrk/fRcaSimple/fBelowText/fAnchorLock
609 //If nFlags isn't 0x14 its overridden by the escher properties
610 if (FLY_AT_PAGE
== rFmt
.GetAnchor().GetAnchorId())
613 nFlags
= 0x0014; // x-rel to text, y-rel to text
615 const SwFmtSurround
& rSurr
= rFmt
.GetSurround();
616 sal_uInt16 nContour
= rSurr
.IsContour() ? 0x0080 : 0x0040;
617 SwSurround eSurround
= rSurr
.GetSurround();
621 The inline elements being export as anchored to character inside
622 the shape field hack are required to be wrap through so as to flow
623 over the following dummy 0x01 graphic
625 if (rFrmFmt
.IsInline())
626 eSurround
= SURROUND_THROUGHT
;
633 case SURROUND_THROUGHT
:
636 case SURROUND_PARALLEL
:
637 nFlags
|= 0x0000 | nContour
;
640 nFlags
|= 0x0600 | nContour
;
643 nFlags
|= 0x0200 | nContour
;
646 nFlags
|= 0x0400 | nContour
;
649 OSL_ENSURE(!this, "Unsupported surround type for export");
652 if (pObj
&& (pObj
->GetLayer() == rWrt
.pDoc
->GetHellId() ||
653 pObj
->GetLayer() == rWrt
.pDoc
->GetInvisibleHellId()))
659 #i3958# Required to make this inline stuff work in WordXP, not
660 needed for 2003 interestingly
662 if (rFrmFmt
.IsInline())
665 SwWW8Writer::WriteShort(*rWrt
.pTableStrm
, nFlags
);
668 SwWW8Writer::WriteLong(*rWrt
.pTableStrm
, 0);
671 RegisterWithFib(rFib
, nFcStart
, rWrt
.pTableStrm
->Tell() - nFcStart
);
675 void MainTxtPlcDrawObj::RegisterWithFib(WW8Fib
&rFib
, sal_uInt32 nStart
,
676 sal_uInt32 nLen
) const
678 rFib
.fcPlcfspaMom
= nStart
;
679 rFib
.lcbPlcfspaMom
= nLen
;
682 WW8_CP
MainTxtPlcDrawObj::GetCpOffset(const WW8Fib
&) const
687 void HdFtPlcDrawObj::RegisterWithFib(WW8Fib
&rFib
, sal_uInt32 nStart
,
688 sal_uInt32 nLen
) const
690 rFib
.fcPlcfspaHdr
= nStart
;
691 rFib
.lcbPlcfspaHdr
= nLen
;
694 WW8_CP
HdFtPlcDrawObj::GetCpOffset(const WW8Fib
&rFib
) const
696 return rFib
.ccpText
+ rFib
.ccpFtn
;
699 DrawObj
& DrawObj::operator=(const DrawObj
& rOther
)
702 mnShapeId
= rOther
.mnShapeId
;
703 maCntnt
= rOther
.maCntnt
;
704 maParentPos
= rOther
.maParentPos
;
705 mnThick
= rOther
.mnThick
;
706 mnDirection
= rOther
.mnDirection
;
707 mnHdFtIndex
= rOther
.mnHdFtIndex
;
711 bool PlcDrawObj::Append( WW8Export
& rWrt
, WW8_CP nCp
, const sw::Frame
& rFmt
,
712 const Point
& rNdTopLeft
)
715 const SwFrmFmt
&rFormat
= rFmt
.GetFrmFmt();
716 if (TXT_HDFT
== rWrt
.nTxtTyp
|| TXT_MAINTEXT
== rWrt
.nTxtTyp
)
718 if (RES_FLYFRMFMT
== rFormat
.Which())
720 // check for textflyframe and if it is the first in a Chain
721 if (rFormat
.GetCntnt().GetCntntIdx())
730 DrawObj
aObj(rFmt
, nCp
, rNdTopLeft
, rWrt
.TrueFrameDirection(rFormat
),
731 rWrt
.GetHdFtIndex());
732 maDrawObjs
.push_back(aObj
);
737 void DrawObj::SetShapeDetails(sal_uInt32 nId
, sal_Int32 nThick
)
743 bool WW8_WrPlcTxtBoxes::WriteTxt( WW8Export
& rWrt
)
745 rWrt
.bInWriteEscher
= true;
746 WW8_CP
& rccp
=TXT_TXTBOX
== nTyp
? rWrt
.pFib
->ccpTxbx
: rWrt
.pFib
->ccpHdrTxbx
;
748 bool bRet
= WriteGenericTxt( rWrt
, nTyp
, rccp
);
750 WW8_CP nCP
= rWrt
.Fc2Cp( rWrt
.Strm().Tell() );
751 WW8Fib
& rFib
= *rWrt
.pFib
;
752 WW8_CP nMyOffset
= rFib
.ccpText
+ rFib
.ccpFtn
+ rFib
.ccpHdr
+ rFib
.ccpAtn
754 if( TXT_TXTBOX
== nTyp
)
755 rWrt
.pFldTxtBxs
->Finish( nCP
, nMyOffset
);
757 rWrt
.pFldHFTxtBxs
->Finish( nCP
, nMyOffset
+ rFib
.ccpTxbx
);
758 rWrt
.bInWriteEscher
= false;
762 void WW8_WrPlcTxtBoxes::Append( const SdrObject
& rObj
, sal_uInt32 nShapeId
)
764 aCntnt
.push_back( &rObj
);
765 aShapeIds
.push_back( nShapeId
);
768 const std::vector
<sal_uInt32
>* WW8_WrPlcTxtBoxes::GetShapeIdArr() const
774 sal_uInt32
WW8Export::GetSdrOrdNum( const SwFrmFmt
& rFmt
) const
777 const SdrObject
* pObj
= rFmt
.FindRealSdrObject();
779 nOrdNum
= pObj
->GetOrdNum();
782 // no Layout for this format, then recalc the ordnum
783 SwFrmFmt
* pFmt
= (SwFrmFmt
*)&rFmt
;
784 nOrdNum
= pDoc
->GetSpzFrmFmts()->GetPos( pFmt
);
786 const SdrModel
* pModel
= pDoc
->GetDrawModel();
788 nOrdNum
+= pModel
->GetPage( 0 )->GetObjCount();
793 void WW8Export::AppendFlyInFlys(const sw::Frame
& rFrmFmt
,
794 const Point
& rNdTopLeft
)
796 OSL_ENSURE(bWrtWW8
, "this has gone horribly wrong");
797 OSL_ENSURE(!pEscher
, "der EscherStream wurde schon geschrieben!");
801 if (TXT_HDFT
== nTxtTyp
)
806 if (rFrmFmt
.IsInline())
808 OutputField(0, ww::eSHAPE
, FieldString(ww::eSHAPE
),
809 WRITEFIELD_START
| WRITEFIELD_CMD_START
| WRITEFIELD_CMD_END
);
812 WW8_CP nCP
= Fc2Cp(Strm().Tell());
813 bool bSuccess
= pDrwO
->Append(*this, nCP
, rFrmFmt
, rNdTopLeft
);
814 OSL_ENSURE(bSuccess
, "Couldn't export a graphical element!");
818 static const sal_uInt8 aSpec8
[] =
820 0x03, 0x6a, 0, 0, 0, 0, // sprmCObjLocation
821 0x55, 0x08, 1 // sprmCFSpec
823 // fSpec-Attribut true
824 // Fuer DrawObjets muss ein Spezial-Zeichen
825 // in den Text und darum ein fSpec-Attribut
826 pChpPlc
->AppendFkpEntry( Strm().Tell() );
828 pChpPlc
->AppendFkpEntry( Strm().Tell(), sizeof( aSpec8
), aSpec8
);
830 //Need dummy picture frame
831 if (rFrmFmt
.IsInline())
835 if (rFrmFmt
.IsInline())
836 OutputField(0, ww::eSHAPE
, aEmptyStr
, WRITEFIELD_CLOSE
);
839 MSWord_SdrAttrIter::MSWord_SdrAttrIter( MSWordExportBase
& rWr
,
840 const EditTextObject
& rEditObj
, sal_uInt8 nTyp
)
841 : MSWordAttrIter( rWr
), pEditObj(&rEditObj
), pEditPool(0), mnTyp(nTyp
)
846 void MSWord_SdrAttrIter::NextPara( sal_Int32 nPar
)
849 // Attributwechsel an Pos 0 wird ignoriert, da davon ausgegangen
850 // wird, dass am Absatzanfang sowieso die Attribute neu ausgegeben
852 aChrTxtAtrArr
.clear();
854 nAktSwPos
= nTmpSwPos
= 0;
856 SfxItemSet
aSet( pEditObj
->GetParaAttribs( nPara
));
857 pEditPool
= aSet
.GetPool();
858 eNdChrSet
= ItemGet
<SvxFontItem
>(aSet
,EE_CHAR_FONTINFO
).GetCharSet();
860 if( g_pBreakIt
->GetBreakIter().is() )
861 nScript
= g_pBreakIt
->GetBreakIter()->getScriptType( pEditObj
->GetText(nPara
), 0);
863 nScript
= i18n::ScriptType::LATIN
;
865 pEditObj
->GetCharAttribs( nPara
, aTxtAtrArr
);
866 nAktSwPos
= SearchNext( 1 );
869 rtl_TextEncoding
MSWord_SdrAttrIter::GetNextCharSet() const
871 if( !aChrSetArr
.empty() )
872 return aChrSetArr
.back();
876 // der erste Parameter in SearchNext() liefert zurueck, ob es ein TxtAtr ist.
877 xub_StrLen
MSWord_SdrAttrIter::SearchNext( xub_StrLen nStartPos
)
879 sal_uInt16 nMinPos
= STRING_MAXLEN
;
880 for(std::vector
<EECharAttrib
>::const_iterator i
= aTxtAtrArr
.begin(); i
< aTxtAtrArr
.end(); ++i
)
882 sal_uInt16 nPos
= i
->nStart
; // gibt erstes Attr-Zeichen
883 if( nPos
>= nStartPos
&& nPos
<= nMinPos
)
886 SetCharSet(*i
, true);
889 nPos
= i
->nEnd
; // gibt letztes Attr-Zeichen + 1
890 if( nPos
>= nStartPos
&& nPos
< nMinPos
)
893 SetCharSet(*i
, false);
899 void MSWord_SdrAttrIter::SetCharSet(const EECharAttrib
& rAttr
, bool bStart
)
901 const SfxPoolItem
& rItem
= *rAttr
.pAttr
;
902 if( rItem
.Which() != EE_CHAR_FONTINFO
)
909 rtl_TextEncoding eChrSet
= ((SvxFontItem
&)rItem
).GetCharSet();
910 aChrSetArr
.push_back( eChrSet
);
911 aChrTxtAtrArr
.push_back( &rAttr
);
915 std::vector
<const EECharAttrib
*>::iterator it
=
916 std::find( aChrTxtAtrArr
.begin(), aChrTxtAtrArr
.end(), &rAttr
);
917 if ( it
!= aChrTxtAtrArr
.end() )
919 aChrTxtAtrArr
.erase( it
);
920 aChrSetArr
.erase( aChrSetArr
.begin() + (it
- aChrTxtAtrArr
.begin()) );
925 void MSWord_SdrAttrIter::OutEEField(const SfxPoolItem
& rHt
)
927 const SvxFieldItem
&rField
= (const SvxFieldItem
&)rHt
;
928 const SvxFieldData
*pFld
= rField
.GetField();
929 if (pFld
&& pFld
->ISA(SvxURLField
))
931 sal_uInt8 nOldTxtTyp
= m_rExport
.nTxtTyp
;
932 m_rExport
.nTxtTyp
= mnTyp
;
933 const SvxURLField
*pURL
= (const SvxURLField
*)pFld
;
934 m_rExport
.AttrOutput().StartURL( pURL
->GetURL(), pURL
->GetTargetFrame() );
936 const String
&rStr
= pURL
->GetRepresentation();
937 m_rExport
.AttrOutput().RawText( rStr
, true, GetNodeCharSet() ); // FIXME kendy: is the 'true' actually correct here? It was here before, but... ;-)
939 m_rExport
.AttrOutput().EndURL();
940 m_rExport
.nTxtTyp
= nOldTxtTyp
;
944 void MSWord_SdrAttrIter::OutAttr( xub_StrLen nSwPos
)
948 if(!aTxtAtrArr
.empty())
950 const SwModify
* pOldMod
= m_rExport
.pOutFmtNode
;
951 m_rExport
.pOutFmtNode
= 0;
953 const SfxItemPool
* pSrcPool
= pEditPool
;
954 const SfxItemPool
& rDstPool
= m_rExport
.pDoc
->GetAttrPool();
957 sal_uInt16 nWhich
, nSlotId
;
958 for(std::vector
<EECharAttrib
>::const_iterator i
= aTxtAtrArr
.begin(); i
< aTxtAtrArr
.end(); ++i
)
960 if (nSwPos
>= i
->nStart
&& nSwPos
< i
->nEnd
)
962 nWhich
= i
->pAttr
->Which();
963 if (nWhich
== EE_FEATURE_FIELD
)
965 OutEEField(*(i
->pAttr
));
968 else if (nWhich
== EE_FEATURE_TAB
)
970 m_rExport
.WriteChar(0x9);
973 nSlotId
= pSrcPool
->GetSlotId(nWhich
);
975 if (nSlotId
&& nWhich
!= nSlotId
)
977 nWhich
= rDstPool
.GetWhich(nSlotId
);
978 if (nWhich
&& nWhich
!= nSlotId
&&
979 nWhich
< RES_UNKNOWNATR_BEGIN
&&
980 m_rExport
.CollapseScriptsforWordOk(nScript
,nWhich
))
982 // use always the SW-Which Id !
983 SfxPoolItem
* pI
= i
->pAttr
->Clone();
984 pI
->SetWhich( nWhich
);
985 m_rExport
.AttrOutput().OutputItem( *pI
);
991 if( nSwPos
< i
->nStart
)
995 nTmpSwPos
= 0; // HasTextItem nur in dem obigen Bereich erlaubt
996 m_rExport
.pOutFmtNode
= pOldMod
;
1000 bool MSWord_SdrAttrIter::IsTxtAttr(xub_StrLen nSwPos
)
1002 for (std::vector
<EECharAttrib
>::const_iterator i
= aTxtAtrArr
.begin(); i
< aTxtAtrArr
.end(); ++i
)
1004 if (nSwPos
>= i
->nStart
&& nSwPos
< i
->nEnd
)
1006 if (i
->pAttr
->Which() == EE_FEATURE_FIELD
||
1007 i
->pAttr
->Which() == EE_FEATURE_TAB
)
1014 // HasItem ist fuer die Zusammenfassung des Doppel-Attributes Underline
1015 // und WordLineMode als TextItems. OutAttr() ruft die Ausgabefunktion,
1016 // die dann ueber HasItem() nach anderen Items an der
1017 // Attribut-Anfangposition fragen kann.
1018 // Es koennen nur Attribute mit Ende abgefragt werden.
1019 // Es wird mit bDeep gesucht
1020 const SfxPoolItem
* MSWord_SdrAttrIter::HasTextItem(sal_uInt16 nWhich
) const
1022 nWhich
= sw::hack::TransformWhichBetweenPools(*pEditPool
,
1023 m_rExport
.pDoc
->GetAttrPool(), nWhich
);
1026 for (std::vector
<EECharAttrib
>::const_iterator i
= aTxtAtrArr
.begin(); i
< aTxtAtrArr
.end(); ++i
)
1028 if (nWhich
== i
->pAttr
->Which() && nTmpSwPos
>= i
->nStart
&& nTmpSwPos
< i
->nEnd
)
1029 return i
->pAttr
; // Found
1030 else if (nTmpSwPos
< i
->nStart
)
1031 return NULL
; // dann kommt da nichts mehr
1037 const SfxPoolItem
& MSWord_SdrAttrIter::GetItem( sal_uInt16 nWhich
) const
1039 using sw::hack::GetSetWhichFromSwDocWhich
;
1040 const SfxPoolItem
* pRet
= HasTextItem(nWhich
);
1043 SfxItemSet
aSet(pEditObj
->GetParaAttribs(nPara
));
1044 nWhich
= GetSetWhichFromSwDocWhich(aSet
, *m_rExport
.pDoc
, nWhich
);
1045 OSL_ENSURE(nWhich
, "Impossible, catastrophic failure imminent");
1046 pRet
= &aSet
.Get(nWhich
);
1051 void MSWord_SdrAttrIter::OutParaAttr(bool bCharAttr
)
1053 SfxItemSet
aSet( pEditObj
->GetParaAttribs( nPara
));
1056 const SfxItemSet
* pOldSet
= m_rExport
.GetCurItemSet();
1057 m_rExport
.SetCurItemSet( &aSet
);
1059 SfxItemIter
aIter( aSet
);
1060 const SfxPoolItem
* pItem
= aIter
.GetCurItem();
1062 const SfxItemPool
* pSrcPool
= pEditPool
,
1063 * pDstPool
= &m_rExport
.pDoc
->GetAttrPool();
1066 sal_uInt16 nWhich
= pItem
->Which(),
1067 nSlotId
= pSrcPool
->GetSlotId( nWhich
);
1069 if ( nSlotId
&& nWhich
!= nSlotId
&&
1070 0 != ( nWhich
= pDstPool
->GetWhich( nSlotId
) ) &&
1071 nWhich
!= nSlotId
&&
1072 ( bCharAttr
? ( nWhich
>= RES_CHRATR_BEGIN
&& nWhich
< RES_TXTATR_END
)
1073 : ( nWhich
>= RES_PARATR_BEGIN
&& nWhich
< RES_FRMATR_END
) ) )
1075 // use always the SW-Which Id !
1076 SfxPoolItem
* pI
= pItem
->Clone();
1077 pI
->SetWhich( nWhich
);
1078 if (m_rExport
.CollapseScriptsforWordOk(nScript
,nWhich
))
1079 m_rExport
.AttrOutput().OutputItem( *pI
);
1082 } while( !aIter
.IsAtEnd() && 0 != ( pItem
= aIter
.NextItem() ) );
1083 m_rExport
.SetCurItemSet( pOldSet
);
1087 void WW8Export::WriteSdrTextObj(const SdrObject
& rObj
, sal_uInt8 nTyp
)
1089 const SdrTextObj
* pTxtObj
= PTR_CAST(SdrTextObj
, &rObj
);
1090 OSL_ENSURE(pTxtObj
, "That is no SdrTextObj!");
1094 const OutlinerParaObject
* pParaObj
= 0;
1095 bool bOwnParaObj
= false;
1099 When the object is actively being edited, that text is not set into
1100 the objects normal text object, but lives in a separate object.
1102 if (pTxtObj
->IsTextEditActive())
1104 pParaObj
= pTxtObj
->GetEditOutlinerParaObject();
1109 pParaObj
= pTxtObj
->GetOutlinerParaObject();
1114 WriteOutliner(*pParaObj
, nTyp
);
1120 void WW8Export::WriteOutliner(const OutlinerParaObject
& rParaObj
, sal_uInt8 nTyp
)
1122 bool bAnyWrite
= false;
1123 const EditTextObject
& rEditObj
= rParaObj
.GetTextObject();
1124 MSWord_SdrAttrIter
aAttrIter( *this, rEditObj
, nTyp
);
1126 sal_Int32 nPara
= rEditObj
.GetParagraphCount();
1128 for( sal_Int32 n
= 0; n
< nPara
; ++n
)
1131 aAttrIter
.NextPara( n
);
1133 rtl_TextEncoding eChrSet
= aAttrIter
.GetNodeCharSet();
1135 OSL_ENSURE( pO
->empty(), " pO ist am Zeilenanfang nicht leer" );
1137 String
aStr( rEditObj
.GetText( n
));
1138 xub_StrLen nAktPos
= 0;
1139 xub_StrLen nEnd
= aStr
.Len();
1141 xub_StrLen nNextAttr
= aAttrIter
.WhereNext();
1142 rtl_TextEncoding eNextChrSet
= aAttrIter
.GetNextCharSet();
1144 if( nNextAttr
> nEnd
)
1147 bool bTxtAtr
= aAttrIter
.IsTxtAttr( nAktPos
);
1149 OutSwString( aStr
, nAktPos
, nNextAttr
- nAktPos
,
1152 // Am Zeilenende werden die Attribute bis ueber das CR
1153 // aufgezogen. Ausnahme: Fussnoten am Zeilenende
1154 if( nNextAttr
== nEnd
&& !bTxtAtr
)
1155 WriteCR(); // CR danach
1157 // Ausgabe der Zeichenattribute
1158 aAttrIter
.OutAttr( nAktPos
); // nAktPos - 1 ??
1159 pChpPlc
->AppendFkpEntry( Strm().Tell(),
1160 pO
->size(), pO
->data() );
1163 // Ausnahme: Fussnoten am Zeilenende
1164 if( nNextAttr
== nEnd
&& bTxtAtr
)
1165 WriteCR(); // CR danach
1166 nAktPos
= nNextAttr
;
1167 eChrSet
= eNextChrSet
;
1168 aAttrIter
.NextPos();
1170 while( nAktPos
< nEnd
);
1172 OSL_ENSURE( pO
->empty(), " pO ist am ZeilenEnde nicht leer" );
1174 pO
->push_back( bNul
); // Style # as short
1175 pO
->push_back( bNul
);
1177 aAttrIter
.OutParaAttr(false);
1179 sal_uLong nPos
= Strm().Tell();
1180 pPapPlc
->AppendFkpEntry( Strm().Tell(),
1181 pO
->size(), pO
->data() );
1183 pChpPlc
->AppendFkpEntry( nPos
);
1186 bAnyWrite
= 0 != nPara
;
1188 WriteStringAsPara( aEmptyStr
);
1191 void WinwordAnchoring::WriteData( EscherEx
& rEx
) const
1193 //Toplevel groups get their winword extra data attached, and sub elements
1195 if (rEx
.GetGroupLevel() <= 1)
1197 SvStream
& rSt
= rEx
.GetStream();
1198 //The last argument denotes the number of sub properties in this atom
1201 rEx
.AddAtom(18, DFF_msofbtUDefProp
, 3, 3); //Prop id is 0xF122
1202 rSt
<< (sal_uInt16
)0x0390 << sal_uInt32(3);
1203 rSt
<< (sal_uInt16
)0x0392 << sal_uInt32(3);
1204 //This sub property is required to be in the dummy inline frame as
1206 rSt
<< (sal_uInt16
)0x053F << nInlineHack
;
1210 rEx
.AddAtom(24, DFF_msofbtUDefProp
, 3, 4 ); //Prop id is 0xF122
1211 rSt
<< (sal_uInt16
)0x038F << mnXAlign
;
1212 rSt
<< (sal_uInt16
)0x0390 << mnXRelTo
;
1213 rSt
<< (sal_uInt16
)0x0391 << mnYAlign
;
1214 rSt
<< (sal_uInt16
)0x0392 << mnYRelTo
;
1220 void WW8Export::CreateEscher()
1222 SfxItemState eBackSet
= pDoc
->GetPageDesc(0).GetMaster().
1223 GetItemState(RES_BACKGROUND
);
1224 if (pHFSdrObjs
->size() || pSdrObjs
->size() || SFX_ITEM_SET
== eBackSet
)
1226 OSL_ENSURE( !pEscher
, "wer hat den Pointer nicht geloescht?" );
1227 SvMemoryStream
* pEscherStrm
= new SvMemoryStream
;
1228 pEscherStrm
->SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN
);
1229 pEscher
= new SwEscherEx(pEscherStrm
, *this);
1233 void WW8Export::WriteEscher()
1237 sal_uLong nStart
= pTableStrm
->Tell();
1239 pEscher
->WritePictures();
1240 pEscher
->FinishEscher();
1242 pFib
->fcDggInfo
= nStart
;
1243 pFib
->lcbDggInfo
= pTableStrm
->Tell() - nStart
;
1244 delete pEscher
, pEscher
= 0;
1248 void SwEscherEx::WritePictures()
1250 if( SvStream
* pPicStrm
= static_cast< SwEscherExGlobal
& >( *mxGlobal
).GetPictureStream() )
1252 // set the blip - entries to the correct stream pos
1253 sal_Int32 nEndPos
= rWrt
.Strm().Tell();
1254 mxGlobal
->SetNewBlipStreamOffset( nEndPos
);
1256 pPicStrm
->Seek( 0 );
1257 rWrt
.Strm() << *pPicStrm
;
1263 // Output- Routines for Escher Export
1265 SwEscherExGlobal::SwEscherExGlobal()
1269 SwEscherExGlobal::~SwEscherExGlobal()
1273 SvStream
* SwEscherExGlobal::ImplQueryPictureStream()
1275 // this function will be called exactly once
1276 mxPicStrm
.reset( new SvMemoryStream
);
1277 mxPicStrm
->SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN
);
1278 return mxPicStrm
.get();
1281 SwBasicEscherEx::SwBasicEscherEx(SvStream
* pStrm
, WW8Export
& rWW8Wrt
)
1282 : EscherEx( EscherExGlobalRef( new SwEscherExGlobal
), pStrm
), rWrt(rWW8Wrt
), pEscherStrm(pStrm
)
1287 SwBasicEscherEx::~SwBasicEscherEx()
1291 void SwBasicEscherEx::WriteFrmExtraData(const SwFrmFmt
&)
1293 AddAtom(4, ESCHER_ClientAnchor
);
1294 GetStream() << (sal_uInt32
)0x80000000;
1297 void SwBasicEscherEx::WriteEmptyFlyFrame(const SwFrmFmt
& rFmt
, sal_uInt32 nShapeId
)
1299 OpenContainer(ESCHER_SpContainer
);
1300 AddShape(ESCHER_ShpInst_PictureFrame
, 0xa00, nShapeId
);
1301 // store anchor attribute
1302 WriteFrmExtraData(rFmt
);
1304 AddAtom(6, DFF_msofbtUDefProp
, 3, 1); //Prop id is 0xF122
1305 GetStream() << (sal_uInt16
)0x053F << nInlineHack
;
1307 CloseContainer(); // ESCHER_SpContainer
1310 sal_uInt32
AddMirrorFlags(sal_uInt32 nFlags
, const SwMirrorGrf
&rMirror
)
1312 switch (rMirror
.GetValue())
1315 case RES_MIRROR_GRAPH_DONT
:
1317 case RES_MIRROR_GRAPH_VERT
:
1318 nFlags
|= SHAPEFLAG_FLIPH
;
1320 case RES_MIRROR_GRAPH_HOR
:
1321 nFlags
|= SHAPEFLAG_FLIPV
;
1323 case RES_MIRROR_GRAPH_BOTH
:
1324 nFlags
|= SHAPEFLAG_FLIPH
;
1325 nFlags
|= SHAPEFLAG_FLIPV
;
1331 //For i120928,this function is added to export graphic of bullet
1332 sal_Int32
SwBasicEscherEx::WriteGrfBullet(const Graphic
& rGrf
)
1334 OpenContainer( ESCHER_SpContainer
);
1335 AddShape(ESCHER_ShpInst_PictureFrame
, 0xa00,0x401);
1336 EscherPropertyContainer aPropOpt
;
1337 GraphicObject
aGraphicObject( rGrf
);
1338 OString aUniqueId
= aGraphicObject
.GetUniqueID();
1339 if ( !aUniqueId
.isEmpty() )
1341 const MapMode
aMap100mm( MAP_100TH_MM
);
1342 Size
aSize( rGrf
.GetPrefSize() );
1343 if ( MAP_PIXEL
== rGrf
.GetPrefMapMode().GetMapUnit() )
1345 aSize
= Application::GetDefaultDevice()->PixelToLogic(aSize
, aMap100mm
);
1349 aSize
= OutputDevice::LogicToLogic( aSize
,rGrf
.GetPrefMapMode(), aMap100mm
);
1351 Point aEmptyPoint
= Point();
1352 Rectangle
aRect( aEmptyPoint
, aSize
);
1353 sal_uInt32 nBlibId
= mxGlobal
->GetBlibID( *(mxGlobal
->QueryPictureStream()), aUniqueId
,aRect
, NULL
, 0 );
1355 aPropOpt
.AddOpt(ESCHER_Prop_pib
, nBlibId
, sal_True
);
1357 aPropOpt
.AddOpt( ESCHER_Prop_pibFlags
, ESCHER_BlipFlagDefault
);
1358 aPropOpt
.AddOpt( ESCHER_Prop_dyTextTop
, DrawModelToEmu(0));
1359 aPropOpt
.AddOpt( ESCHER_Prop_dyTextBottom
, DrawModelToEmu(0));
1360 aPropOpt
.AddOpt( ESCHER_Prop_dxTextLeft
, DrawModelToEmu(0));
1361 aPropOpt
.AddOpt( ESCHER_Prop_dxTextRight
, DrawModelToEmu(0));
1362 aPropOpt
.AddOpt( ESCHER_Prop_fNoLineDrawDash
, 0x80000 );
1363 aPropOpt
.AddOpt( ESCHER_Prop_dyTextTop
, 0 );
1364 aPropOpt
.AddOpt( ESCHER_Prop_dyTextBottom
, 0 );
1365 aPropOpt
.AddOpt( ESCHER_Prop_dxTextLeft
, 0 );
1366 aPropOpt
.AddOpt( ESCHER_Prop_dxTextRight
, 0 );
1367 const Color
aTmpColor( COL_WHITE
);
1368 SvxBrushItem
aBrush( aTmpColor
, RES_BACKGROUND
);
1369 const SvxBrushItem
*pRet
= rWrt
.GetCurrentPageBgBrush();
1370 if (pRet
&& (pRet
->GetGraphic() ||( pRet
->GetColor() != COL_TRANSPARENT
)))
1372 WriteBrushAttr(aBrush
, aPropOpt
);
1374 aPropOpt
.AddOpt( ESCHER_Prop_pictureActive
, 0 );
1375 aPropOpt
.Commit( GetStream() );
1376 AddAtom(4, ESCHER_ClientAnchor
);
1377 GetStream() << (sal_uInt32
)0x80000000;
1383 sal_Int32
SwBasicEscherEx::WriteGrfFlyFrame(const SwFrmFmt
& rFmt
, sal_uInt32 nShapeId
)
1385 sal_Int32 nBorderThick
=0;
1386 SwNoTxtNode
*pNd
= GetNoTxtNodeFromSwFrmFmt(rFmt
);
1387 SwGrfNode
*pGrfNd
= pNd
? pNd
->GetGrfNode() : 0;
1388 OSL_ENSURE(pGrfNd
, "No SwGrfNode ?, suspicious");
1390 return nBorderThick
;
1392 OpenContainer( ESCHER_SpContainer
);
1394 const SwMirrorGrf
&rMirror
= pGrfNd
->GetSwAttrSet().GetMirrorGrf();
1395 AddShape(ESCHER_ShpInst_PictureFrame
, AddMirrorFlags(0xa00, rMirror
),
1398 EscherPropertyContainer aPropOpt
;
1400 sal_uInt32 nFlags
= ESCHER_BlipFlagDefault
;
1402 if (pGrfNd
->IsLinkedFile())
1405 pGrfNd
->GetFileFilterNms( &sURL
, 0 );
1408 SwWW8Writer::InsAsString16( aBuf
, sURL
);
1409 SwWW8Writer::InsUInt16( aBuf
, 0 );
1411 sal_uInt16 nArrLen
= aBuf
.size();
1412 sal_uInt8
* pArr
= new sal_uInt8
[ nArrLen
];
1413 std::copy( aBuf
.begin(), aBuf
.end(), pArr
);
1415 aPropOpt
.AddOpt(ESCHER_Prop_pibName
, true, nArrLen
, pArr
, nArrLen
);
1416 nFlags
= ESCHER_BlipFlagLinkToFile
| ESCHER_BlipFlagURL
|
1417 ESCHER_BlipFlagDoNotSave
;
1421 pGrfNd
->SwapIn(true);
1423 Graphic
aGraphic(pGrfNd
->GetGrf());
1424 GraphicObject
aGraphicObject( aGraphic
);
1425 OString aUniqueId
= aGraphicObject
.GetUniqueID();
1427 if (!aUniqueId
.isEmpty())
1429 const MapMode
aMap100mm( MAP_100TH_MM
);
1430 Size
aSize( aGraphic
.GetPrefSize() );
1432 if ( MAP_PIXEL
== aGraphic
.GetPrefMapMode().GetMapUnit() )
1434 aSize
= Application::GetDefaultDevice()->PixelToLogic(
1439 aSize
= OutputDevice::LogicToLogic( aSize
,
1440 aGraphic
.GetPrefMapMode(), aMap100mm
);
1443 Point aEmptyPoint
= Point();
1444 Rectangle
aRect( aEmptyPoint
, aSize
);
1446 sal_uInt32 nBlibId
= mxGlobal
->GetBlibID( *QueryPictureStream(),
1447 aUniqueId
, aRect
, NULL
, 0 );
1449 aPropOpt
.AddOpt(ESCHER_Prop_pib
, nBlibId
, sal_True
);
1453 aPropOpt
.AddOpt( ESCHER_Prop_pibFlags
, nFlags
);
1454 nBorderThick
= WriteFlyFrameAttr(rFmt
,mso_sptPictureFrame
,aPropOpt
);
1455 WriteGrfAttr(*pGrfNd
, aPropOpt
);
1457 aPropOpt
.Commit( GetStream() );
1459 // store anchor attribute
1460 WriteFrmExtraData( rFmt
);
1462 CloseContainer(); // ESCHER_SpContainer
1463 return nBorderThick
;
1466 void SwBasicEscherEx::WriteGrfAttr(const SwNoTxtNode
& rNd
,
1467 EscherPropertyContainer
& rPropOpt
)
1469 const SfxPoolItem
* pItem
;
1470 sal_uInt32 nMode
= GRAPHICDRAWMODE_STANDARD
;
1471 sal_Int32 nContrast
= 0;
1472 sal_Int16 nBrightness
= 0;
1474 if (SFX_ITEM_SET
== rNd
.GetSwAttrSet().GetItemState(RES_GRFATR_CONTRAST
,
1477 nContrast
= ((SfxInt16Item
*)pItem
)->GetValue();
1480 if (SFX_ITEM_SET
== rNd
.GetSwAttrSet().GetItemState(RES_GRFATR_LUMINANCE
,
1483 nBrightness
= ((SfxInt16Item
*)pItem
)->GetValue();
1487 if (SFX_ITEM_SET
== rNd
.GetSwAttrSet().GetItemState(RES_GRFATR_DRAWMODE
,
1490 nMode
= ((SfxEnumItem
*)pItem
)->GetValue();
1491 if (nMode
== GRAPHICDRAWMODE_WATERMARK
)
1494 There is no real watermark mode in word, we must use standard
1495 mode and modify our ones by 70% extra brightness and 70% less
1496 contrast. This means that unmodified default OOo watermark
1497 will turn back into watermark, and modified OOo watermark will
1498 change into a close visual representation in standardmode
1501 if (nBrightness
> 100)
1504 if (nContrast
< -100)
1506 nMode
= GRAPHICDRAWMODE_STANDARD
;
1510 if (nMode
== GRAPHICDRAWMODE_GREYS
)
1512 else if (nMode
== GRAPHICDRAWMODE_MONO
)
1516 rPropOpt
.AddOpt( ESCHER_Prop_pictureActive
, nMode
);
1521 if (nContrast
== 100)
1522 nContrast
= 0x10000;
1523 else if (nContrast
< 100)
1525 nContrast
*= 0x10000;
1528 else if (nContrast
< 200)
1529 nContrast
= (100 * 0x10000) / (200-nContrast
);
1531 nContrast
= 0x7fffffff;
1532 rPropOpt
.AddOpt( ESCHER_Prop_pictureContrast
, nContrast
);
1535 if (nBrightness
!= 0)
1536 rPropOpt
.AddOpt( ESCHER_Prop_pictureBrightness
, nBrightness
* 327 );
1538 if (SFX_ITEM_SET
== rNd
.GetSwAttrSet().GetItemState(RES_GRFATR_CROPGRF
,
1541 const Size
aSz( rNd
.GetTwipSize() );
1543 if( 0 != ( nVal
= ((SwCropGrf
*)pItem
)->GetLeft() ) )
1544 rPropOpt
.AddOpt( ESCHER_Prop_cropFromLeft
, ToFract16( nVal
, aSz
.Width()) );
1545 if( 0 != ( nVal
= ((SwCropGrf
*)pItem
)->GetRight() ) )
1546 rPropOpt
.AddOpt( ESCHER_Prop_cropFromRight
, ToFract16( nVal
, aSz
.Width()));
1547 if( 0 != ( nVal
= ((SwCropGrf
*)pItem
)->GetTop() ) )
1548 rPropOpt
.AddOpt( ESCHER_Prop_cropFromTop
, ToFract16( nVal
, aSz
.Height()));
1549 if( 0 != ( nVal
= ((SwCropGrf
*)pItem
)->GetBottom() ) )
1550 rPropOpt
.AddOpt( ESCHER_Prop_cropFromBottom
, ToFract16( nVal
, aSz
.Height()));
1554 void SwBasicEscherEx::SetPicId(const SdrObject
&, sal_uInt32
,
1555 EscherPropertyContainer
&)
1559 void SwEscherEx::SetPicId(const SdrObject
&rSdrObj
, sal_uInt32 nShapeId
,
1560 EscherPropertyContainer
&rPropOpt
)
1562 pTxtBxs
->Append(rSdrObj
, nShapeId
);
1563 sal_uInt32 nPicId
= pTxtBxs
->Count();
1565 rPropOpt
.AddOpt( ESCHER_Prop_pictureId
, nPicId
);
1568 sal_Int32
SwBasicEscherEx::WriteOLEFlyFrame(const SwFrmFmt
& rFmt
, sal_uInt32 nShapeId
)
1570 sal_Int32 nBorderThick
= 0;
1571 if (const SdrObject
* pSdrObj
= rFmt
.FindRealSdrObject())
1573 SwNodeIndex
aIdx(*rFmt
.GetCntnt().GetCntntIdx(), 1);
1574 SwOLENode
& rOLENd
= *aIdx
.GetNode().GetOLENode();
1575 sal_Int64 nAspect
= rOLENd
.GetAspect();
1577 uno::Reference
< embed::XEmbeddedObject
> xObj(rOLENd
.GetOLEObj().GetOleRef());
1579 // the rectangle is used to transport the size of the object
1580 // the left, top corner is set to ( 0, 0 ) by default constructor,
1581 // if the width and height are set correctly bRectIsSet should be set to true
1582 awt::Rectangle aRect
;
1583 bool bRectIsSet
= false;
1586 // TODO/LATER: should the icon size be stored in case of iconified object?
1587 if ( xObj
.is() && nAspect
!= embed::Aspects::MSOLE_ICON
)
1591 awt::Size aSize
= xObj
->getVisualAreaSize( nAspect
);
1592 aRect
.Width
= aSize
.Width
;
1593 aRect
.Height
= aSize
.Height
;
1596 catch( const uno::Exception
& )
1602 Export floating ole2 .doc ver 8+ wmf ole2 previews as emf previews
1603 instead ==> allows unicode text to be preserved
1605 #ifdef OLE_PREVIEW_AS_EMF
1606 const Graphic
* pGraphic
= rOLENd
.GetGraphic();
1608 OpenContainer(ESCHER_SpContainer
);
1610 EscherPropertyContainer aPropOpt
;
1611 const SwMirrorGrf
&rMirror
= rOLENd
.GetSwAttrSet().GetMirrorGrf();
1612 WriteOLEPicture(aPropOpt
, AddMirrorFlags(0xa00 | SHAPEFLAG_OLESHAPE
,
1613 rMirror
), pGraphic
? *pGraphic
: Graphic(), *pSdrObj
, nShapeId
, bRectIsSet
? &aRect
: NULL
);
1615 nBorderThick
= WriteFlyFrameAttr(rFmt
, mso_sptPictureFrame
, aPropOpt
);
1616 WriteGrfAttr(rOLENd
, aPropOpt
);
1617 aPropOpt
.Commit(GetStream());
1619 // store anchor attribute
1620 WriteFrmExtraData( rFmt
);
1622 CloseContainer(); // ESCHER_SpContainer
1624 return nBorderThick
;
1627 void SwBasicEscherEx::WriteBrushAttr(const SvxBrushItem
&rBrush
,
1628 EscherPropertyContainer
& rPropOpt
)
1630 bool bSetOpacity
= false;
1631 sal_uInt32 nOpaque
= 0;
1632 if (const GraphicObject
*pGraphicObject
= rBrush
.GetGraphicObject())
1634 OString aUniqueId
= pGraphicObject
->GetUniqueID();
1635 if (!aUniqueId
.isEmpty())
1637 const Graphic
&rGraphic
= pGraphicObject
->GetGraphic();
1638 Size
aSize(rGraphic
.GetPrefSize());
1639 const MapMode
aMap100mm(MAP_100TH_MM
);
1640 if (MAP_PIXEL
== rGraphic
.GetPrefMapMode().GetMapUnit())
1642 aSize
= Application::GetDefaultDevice()->PixelToLogic(
1647 aSize
= OutputDevice::LogicToLogic(aSize
,
1648 rGraphic
.GetPrefMapMode(), aMap100mm
);
1651 Point aEmptyPoint
= Point();
1652 Rectangle
aRect(aEmptyPoint
, aSize
);
1654 sal_uInt32 nBlibId
= mxGlobal
->GetBlibID( *QueryPictureStream(),
1655 aUniqueId
, aRect
, NULL
, 0);
1657 rPropOpt
.AddOpt(ESCHER_Prop_fillBlip
,nBlibId
,sal_True
);
1660 if (0 != (nOpaque
= pGraphicObject
->GetAttr().GetTransparency()))
1663 rPropOpt
.AddOpt( ESCHER_Prop_fillType
, ESCHER_FillPicture
);
1664 rPropOpt
.AddOpt( ESCHER_Prop_fNoFillHitTest
, 0x140014 );
1665 rPropOpt
.AddOpt( ESCHER_Prop_fillBackColor
, 0 );
1669 sal_uInt32 nFillColor
= GetColor(rBrush
.GetColor(), false);
1670 rPropOpt
.AddOpt( ESCHER_Prop_fillColor
, nFillColor
);
1671 rPropOpt
.AddOpt( ESCHER_Prop_fillBackColor
, nFillColor
^ 0xffffff );
1672 rPropOpt
.AddOpt( ESCHER_Prop_fNoFillHitTest
, 0x100010 );
1674 if (0 != (nOpaque
= rBrush
.GetColor().GetTransparency()))
1680 nOpaque
= (nOpaque
* 100) / 0xFE;
1681 nOpaque
= ((100 - nOpaque
) << 16) / 100;
1682 rPropOpt
.AddOpt(ESCHER_Prop_fillOpacity
, nOpaque
);
1686 static bool lcl_isInHeader(const SwFrmFmt
& rFmt
)
1688 const SwFlyFrmFmt
* pFlyFrmFmt
= dynamic_cast<const SwFlyFrmFmt
*>(&rFmt
);
1691 SwFlyFrm
* pFlyFrm
= const_cast<SwFlyFrm
*>(pFlyFrmFmt
->GetFrm());
1692 if (!pFlyFrm
) // fdo#54648: "hidden" drawing object has no layout frame
1696 SwPageFrm
* pPageFrm
= pFlyFrm
->FindPageFrmOfAnchor();
1697 SwFrm
* pHeader
= pPageFrm
->Lower();
1698 if (pHeader
->GetType() == FRM_HEADER
)
1700 const SwFrm
* pFrm
= pFlyFrm
->GetAnchorFrm();
1703 if (pFrm
== pHeader
)
1705 pFrm
= pFrm
->GetUpper();
1711 sal_Int32
SwBasicEscherEx::WriteFlyFrameAttr(const SwFrmFmt
& rFmt
,
1712 MSO_SPT eShapeType
, EscherPropertyContainer
& rPropOpt
)
1714 sal_Int32 nLineWidth
=0;
1715 const SfxPoolItem
* pItem
;
1716 bool bFirstLine
= true;
1717 if (SFX_ITEM_SET
== rFmt
.GetItemState(RES_BOX
, true, &pItem
))
1719 static const sal_uInt16 aExhperProp
[4] =
1721 ESCHER_Prop_dyTextTop
, ESCHER_Prop_dyTextBottom
,
1722 ESCHER_Prop_dxTextLeft
, ESCHER_Prop_dxTextRight
1724 const SvxBorderLine
* pLine
;
1726 for( sal_uInt16 n
= 0; n
< 4; ++n
)
1727 if( 0 != ( pLine
= ((SvxBoxItem
*)pItem
)->GetLine( n
)) )
1731 sal_uInt32 nLineColor
= GetColor(pLine
->GetColor(), false);
1732 rPropOpt
.AddOpt( ESCHER_Prop_lineColor
, nLineColor
);
1733 rPropOpt
.AddOpt( ESCHER_Prop_lineBackColor
,
1734 nLineColor
^ 0xffffff );
1736 MSO_LineStyle eStyle
;
1737 if( pLine
->isDouble() )
1740 nLineWidth
= pLine
->GetWidth();
1741 if( pLine
->GetInWidth() == pLine
->GetOutWidth() )
1742 eStyle
= mso_lineDouble
;
1743 else if( pLine
->GetInWidth() < pLine
->GetOutWidth() )
1744 eStyle
= mso_lineThickThin
;
1746 eStyle
= mso_lineThinThick
;
1751 eStyle
= mso_lineSimple
;
1752 nLineWidth
= pLine
->GetWidth();
1755 rPropOpt
.AddOpt( ESCHER_Prop_lineStyle
, eStyle
);
1756 rPropOpt
.AddOpt( ESCHER_Prop_lineWidth
,
1757 DrawModelToEmu( nLineWidth
));
1759 MSO_LineDashing eDashing
= mso_lineSolid
;
1760 switch (pLine
->GetBorderLineStyle())
1762 case table::BorderLineStyle::DASHED
:
1763 eDashing
= mso_lineDashGEL
;
1765 case table::BorderLineStyle::DOTTED
:
1766 eDashing
= mso_lineDotGEL
;
1768 case table::BorderLineStyle::SOLID
:
1772 rPropOpt
.AddOpt( ESCHER_Prop_lineDashing
, eDashing
);
1773 rPropOpt
.AddOpt( ESCHER_Prop_fNoLineDrawDash
, 0x8000E );
1775 //Use import logic to determine how much of border will go
1777 nLineWidth
= SwMSDffManager::GetEscherLineMatch(
1778 eStyle
,eShapeType
,nLineWidth
);
1781 rPropOpt
.AddOpt( aExhperProp
[ n
], DrawModelToEmu(
1782 ((SvxBoxItem
*)pItem
)->GetDistance( n
) ));
1785 // MM If there is no line the distance should be set to 0
1786 rPropOpt
.AddOpt( aExhperProp
[ n
], DrawModelToEmu(0));
1788 if( bFirstLine
) // no valid line found
1790 rPropOpt
.AddOpt( ESCHER_Prop_fNoLineDrawDash
, 0x80000 );
1791 rPropOpt
.AddOpt( ESCHER_Prop_dyTextTop
, 0 );
1792 rPropOpt
.AddOpt( ESCHER_Prop_dyTextBottom
, 0 );
1793 rPropOpt
.AddOpt( ESCHER_Prop_dxTextLeft
, 0 );
1794 rPropOpt
.AddOpt( ESCHER_Prop_dxTextRight
, 0 );
1797 // SwWW8ImplReader::Read_GrafLayer() imports these as opaque
1798 // unconditionally, so if both are true, don't export the property.
1799 bool bIsInHeader
= lcl_isInHeader(rFmt
);
1800 bool bIsThrought
= rFmt
.GetSurround().GetValue() == SURROUND_THROUGHT
;
1804 const SvxBrushItem
& rBrush(rFmt
.GetBackground());
1805 WriteBrushAttr(rBrush
, rPropOpt
);
1809 SvxBrushItem
aBrush(rWrt
.TrueFrameBgBrush(rFmt
));
1810 WriteBrushAttr(aBrush
, rPropOpt
);
1813 const SdrObject
* pObj
= rFmt
.FindRealSdrObject();
1815 if( pObj
&& (pObj
->GetLayer() == GetHellLayerId() ||
1816 pObj
->GetLayer() == GetInvisibleHellId() ) && !(bIsInHeader
&& bIsThrought
))
1818 rPropOpt
.AddOpt( ESCHER_Prop_fPrint
, 0x200020 );
1824 sal_Int32
SwEscherEx::WriteFlyFrameAttr(const SwFrmFmt
& rFmt
, MSO_SPT eShapeType
,
1825 EscherPropertyContainer
& rPropOpt
)
1827 sal_Int32 nLineWidth
= SwBasicEscherEx::WriteFlyFrameAttr(rFmt
, eShapeType
,
1831 These are not in SwBasicEscherEx::WriteFlyFrameAttr because inline objs
1832 can't do it in word and it hacks it in by stretching the graphic that
1833 way, perhaps we should actually draw in this space into the graphic we
1836 const SfxPoolItem
* pItem
;
1837 if (SFX_ITEM_SET
== rFmt
.GetItemState(RES_LR_SPACE
, true, &pItem
))
1839 rPropOpt
.AddOpt( ESCHER_Prop_dxWrapDistLeft
,
1840 DrawModelToEmu( ((SvxLRSpaceItem
*)pItem
)->GetLeft() ) );
1841 rPropOpt
.AddOpt( ESCHER_Prop_dxWrapDistRight
,
1842 DrawModelToEmu( ((SvxLRSpaceItem
*)pItem
)->GetRight() ) );
1846 rPropOpt
.AddOpt( ESCHER_Prop_dxWrapDistLeft
, 0 );
1847 rPropOpt
.AddOpt( ESCHER_Prop_dxWrapDistRight
, 0 );
1850 if (SFX_ITEM_SET
== rFmt
.GetItemState(RES_UL_SPACE
, true, &pItem
))
1852 rPropOpt
.AddOpt( ESCHER_Prop_dyWrapDistTop
,
1853 DrawModelToEmu( ((SvxULSpaceItem
*)pItem
)->GetUpper() ) );
1854 rPropOpt
.AddOpt( ESCHER_Prop_dyWrapDistBottom
,
1855 DrawModelToEmu( ((SvxULSpaceItem
*)pItem
)->GetLower() ) );
1858 if (rFmt
.GetSurround().IsContour())
1860 if (const SwNoTxtNode
*pNd
= GetNoTxtNodeFromSwFrmFmt(rFmt
))
1862 const PolyPolygon
*pPolyPoly
= pNd
->HasContour();
1863 if (pPolyPoly
&& pPolyPoly
->Count())
1865 Polygon
aPoly(PolygonFromPolyPolygon(*pPolyPoly
));
1866 const Size
&rOrigSize
= pNd
->GetGraphic().GetPrefSize();
1867 Fraction
aMapPolyX(ww::nWrap100Percent
, rOrigSize
.Width());
1868 Fraction
aMapPolyY(ww::nWrap100Percent
, rOrigSize
.Height());
1869 aPoly
.Scale(aMapPolyX
, aMapPolyY
);
1872 a) stretch right bound by 15twips
1873 b) shrink bottom bound to where it would have been in word
1874 c) Move it to the left by 15twips
1876 See the import for details
1878 const Size
&rSize
= pNd
->GetTwipSize();
1879 Fraction
aMoveHack(ww::nWrap100Percent
, rSize
.Width());
1880 aMoveHack
*= Fraction(15, 1);
1881 long nMove(aMoveHack
);
1883 Fraction
aHackX(ww::nWrap100Percent
+ nMove
,
1884 ww::nWrap100Percent
);
1885 Fraction
aHackY(ww::nWrap100Percent
- nMove
,
1886 ww::nWrap100Percent
);
1887 aPoly
.Scale(aHackX
, aHackY
);
1889 aPoly
.Move(-nMove
, 0);
1891 SvMemoryStream aPolyDump
;
1892 aPolyDump
.SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN
);
1894 sal_uInt16 nLen
= aPoly
.GetSize();
1897 aPolyDump
<< sal_uInt16(8);
1898 for (sal_uInt16 nI
= 0; nI
< nLen
; ++nI
)
1900 aPolyDump
<< sal_uInt32(aPoly
[nI
].X());
1901 aPolyDump
<< sal_uInt32(aPoly
[nI
].Y());
1904 sal_uInt16 nArrLen
= msword_cast
<sal_uInt16
>(aPolyDump
.Tell());
1905 void *pArr
= const_cast<void *>(aPolyDump
.GetData());
1906 //PropOpt wants to own the buffer
1907 aPolyDump
.ObjectOwnsMemory(false);
1908 rPropOpt
.AddOpt(DFF_Prop_pWrapPolygonVertices
, false,
1909 nArrLen
, static_cast<sal_uInt8
*>(pArr
), nArrLen
);
1917 void SwBasicEscherEx::Init()
1919 MapUnit eMap
= MAP_TWIP
;
1920 if (SdrModel
*pModel
= rWrt
.pDoc
->GetDrawModel())
1922 // PPT arbeitet nur mit Einheiten zu 576DPI
1923 // WW hingegen verwendet twips, dh. 1440DPI.
1924 eMap
= pModel
->GetScaleUnit();
1927 // MS-DFF-Properties sind grossteils in EMU (English Metric Units) angegeben
1928 // 1mm=36000emu, 1twip=635emu
1929 Fraction
aFact(360, 1);
1930 aFact
/= GetMapFactor(MAP_100TH_MM
, eMap
).X();
1931 // create little values
1932 aFact
= Fraction(aFact
.GetNumerator(), aFact
.GetDenominator());
1933 mnEmuMul
= aFact
.GetNumerator();
1934 mnEmuDiv
= aFact
.GetDenominator();
1936 SetHellLayerId(rWrt
.pDoc
->GetHellId());
1939 sal_Int32
SwBasicEscherEx::ToFract16(sal_Int32 nVal
, sal_uInt32 nMax
) const
1943 sal_Int32 nMSVal
= (nVal
/ 65536) * nMax
;
1944 nMSVal
+= (nVal
* 65536 ) / nMax
;
1950 SdrLayerID
SwBasicEscherEx::GetInvisibleHellId() const
1952 return rWrt
.pDoc
->GetInvisibleHellId();
1955 void SwBasicEscherEx::WritePictures()
1957 if( SvStream
* pPicStrm
= static_cast< SwEscherExGlobal
& >( *mxGlobal
).GetPictureStream() )
1959 // set the blip - entries to the correct stream pos
1960 sal_Int32 nEndPos
= pPicStrm
->Tell();
1961 mxGlobal
->WriteBlibStoreEntry(*pEscherStrm
, 1, sal_True
, nEndPos
);
1964 *pEscherStrm
<< *pPicStrm
;
1968 SwEscherEx::SwEscherEx(SvStream
* pStrm
, WW8Export
& rWW8Wrt
)
1969 : SwBasicEscherEx(pStrm
, rWW8Wrt
),
1972 aHostData
.SetClientData(&aWinwordAnchoring
);
1973 OpenContainer( ESCHER_DggContainer
);
1975 sal_uInt16 nColorCount
= 4;
1976 *pStrm
<< (sal_uInt16
)( nColorCount
<< 4 ) // instance
1977 << (sal_uInt16
)ESCHER_SplitMenuColors
// record type
1978 << (sal_uInt32
)( nColorCount
* 4 ) // size
1979 << (sal_uInt32
)0x08000004
1980 << (sal_uInt32
)0x08000001
1981 << (sal_uInt32
)0x08000002
1982 << (sal_uInt32
)0x100000f7;
1984 CloseContainer(); // ESCHER_DggContainer
1986 sal_uInt8 i
= 2; // for header/footer and the other
1987 PlcDrawObj
*pSdrObjs
= rWrt
.pHFSdrObjs
;
1988 pTxtBxs
= rWrt
.pHFTxtBxs
;
1990 // if no header/footer -> skip over
1991 if (!pSdrObjs
->size())
1994 pSdrObjs
= rWrt
.pSdrObjs
;
1995 pTxtBxs
= rWrt
.pTxtBxs
;
1998 for( ; i
--; pSdrObjs
= rWrt
.pSdrObjs
, pTxtBxs
= rWrt
.pTxtBxs
)
2000 // "dummy char" (or any Count ?) - why? This knows only M$
2001 GetStream() << (sal_Char
)i
;
2003 OpenContainer( ESCHER_DgContainer
);
2007 sal_uLong nSecondShapeId
= pSdrObjs
== rWrt
.pSdrObjs
? GenerateShapeId() : 0;
2009 // write now all Writer-/DrawObjects
2010 DrawObjPointerVector aSorted
;
2011 MakeZOrderArrAndFollowIds(pSdrObjs
->GetObjArr(), aSorted
);
2013 sal_uInt32 nShapeId
=0;
2014 DrawObjPointerIter aEnd
= aSorted
.end();
2015 for (DrawObjPointerIter aIter
= aSorted
.begin(); aIter
!= aEnd
; ++aIter
)
2017 sal_Int32 nBorderThick
=0;
2018 DrawObj
*pObj
= (*aIter
);
2019 OSL_ENSURE(pObj
, "impossible");
2022 const sw::Frame
&rFrame
= pObj
->maCntnt
;
2023 const SwFrmFmt
& rFmt
= rFrame
.GetFrmFmt();
2025 switch (rFrame
.GetWriterType())
2027 case sw::Frame::eTxtBox
:
2028 case sw::Frame::eOle
:
2029 case sw::Frame::eGraphic
:
2030 nBorderThick
= WriteFlyFrm(*pObj
, nShapeId
, aSorted
);
2032 case sw::Frame::eFormControl
:
2033 WriteOCXControl(rFmt
, nShapeId
= GenerateShapeId());
2035 case sw::Frame::eDrawing
:
2037 aWinwordAnchoring
.SetAnchoring(rFmt
);
2038 const SdrObject
* pSdrObj
= rFmt
.FindRealSdrObject();
2041 bool bSwapInPage
= false;
2042 if (!pSdrObj
->GetPage())
2044 if (SdrModel
* pModel
= rWrt
.pDoc
->GetDrawModel())
2046 if (SdrPage
*pPage
= pModel
->GetPage(0))
2049 (const_cast<SdrObject
*>(pSdrObj
))->SetPage(pPage
);
2054 nShapeId
= AddSdrObject(*pSdrObj
);
2057 (const_cast<SdrObject
*>(pSdrObj
))->SetPage(0);
2059 #if OSL_DEBUG_LEVEL > 0
2061 OSL_ENSURE( !this, "Where is the SDR-Object?" );
2071 nShapeId
= AddDummyShape();
2074 pObj
->SetShapeDetails(nShapeId
, nBorderThick
);
2077 EndSdrObjectPage(); // ???? Bugfix for 74724
2079 if( nSecondShapeId
)
2081 OpenContainer( ESCHER_SpContainer
);
2083 AddShape( ESCHER_ShpInst_Rectangle
, 0xe00, nSecondShapeId
);
2085 EscherPropertyContainer aPropOpt
;
2086 const SwFrmFmt
&rFmt
= rWrt
.pDoc
->GetPageDesc(0).GetMaster();
2087 const SfxPoolItem
* pItem
= 0;
2088 SfxItemState eState
= rFmt
.GetItemState(RES_BACKGROUND
, true,
2090 if (SFX_ITEM_SET
== eState
&& pItem
)
2092 const SvxBrushItem
* pBrush
= (const SvxBrushItem
*)pItem
;
2093 WriteBrushAttr(*pBrush
, aPropOpt
);
2095 SvxGraphicPosition ePos
= pBrush
->GetGraphicPos();
2096 if( ePos
!= GPOS_NONE
&& ePos
!= GPOS_AREA
)
2098 /* #i56806# 0x033F parameter specifies a 32-bit field of shape boolean properties.
2099 0x10001 means fBackground and fUsefBackground flag are true thus background
2100 picture will be shown as "tiled" fill.*/
2101 aPropOpt
.AddOpt( ESCHER_Prop_fBackground
, 0x10001 );
2104 aPropOpt
.AddOpt( ESCHER_Prop_lineColor
, 0x8000001 );
2105 aPropOpt
.AddOpt( ESCHER_Prop_fNoLineDrawDash
, 0x00080008 );
2106 aPropOpt
.AddOpt( ESCHER_Prop_shadowColor
, 0x8000002 );
2107 aPropOpt
.AddOpt( ESCHER_Prop_lineWidth
, 0 );
2109 aPropOpt
.Commit( *pStrm
);
2111 AddAtom( 4, ESCHER_ClientData
);
2112 GetStream() << static_cast<sal_Int32
>(1);
2114 CloseContainer(); // ESCHER_SpContainer
2116 CloseContainer(); // ESCHER_DgContainer
2120 SwEscherEx::~SwEscherEx()
2124 void SwEscherEx::FinishEscher()
2126 pEscherStrm
->Seek(0);
2127 *rWrt
.pTableStrm
<< *pEscherStrm
;
2128 delete pEscherStrm
, pEscherStrm
= 0;
2131 /** method to perform conversion of positioning attributes with the help
2132 of corresponding layout information
2135 Because most of the Writer object positions doesn't correspond to the
2136 object positions in WW8, this method converts the positioning
2137 attributes. For this conversion the corresponding layout information
2138 is needed. If no layout information exists - e.g. no layout exists - no
2139 conversion is performed.
2140 No conversion is performed for as-character anchored objects. Whose
2141 object positions are already treated special in method <WriteData(..)>.
2144 input/output parameter - containing the current horizontal position
2145 attributes, which are converted by this method.
2148 input/output parameter - containing the current vertical position
2149 attributes, which are converted by this method.
2152 input parameter - frame format of the anchored object
2154 @return boolean, indicating, if a conversion has been performed.
2156 bool WinwordAnchoring::ConvertPosition( SwFmtHoriOrient
& _iorHoriOri
,
2157 SwFmtVertOrient
& _iorVertOri
,
2158 const SwFrmFmt
& _rFrmFmt
)
2160 const RndStdIds eAnchor
= _rFrmFmt
.GetAnchor().GetAnchorId();
2162 if ( (FLY_AS_CHAR
== eAnchor
) || (FLY_AT_FLY
== eAnchor
) )
2164 // no conversion for as-character or at frame anchored objects
2168 // determine anchored object
2169 SwAnchoredObject
* pAnchoredObj( 0L );
2171 const SwContact
* pContact
= _rFrmFmt
.FindContactObj();
2174 std::list
<SwAnchoredObject
*> aAnchoredObjs
;
2175 pContact
->GetAnchoredObjs( aAnchoredObjs
);
2176 if ( !aAnchoredObjs
.empty() )
2178 pAnchoredObj
= aAnchoredObjs
.front();
2182 if ( !pAnchoredObj
)
2184 // no anchored object found. Thus, the needed layout information can't
2185 // be determined. --> no conversion
2188 // no conversion for anchored drawing object, which aren't attached to an
2190 // This is the case for drawing objects, which are anchored inside a page
2191 // header/footer of an *unused* page style.
2192 if ( dynamic_cast<SwAnchoredDrawObject
*>(pAnchoredObj
) &&
2193 !pAnchoredObj
->GetAnchorFrm() )
2198 bool bConverted( false );
2200 // determine value of attribute 'Follow text flow', because positions aligned
2201 // at page areas have to be converted, if it's set.
2202 const bool bFollowTextFlow
= _rFrmFmt
.GetFollowTextFlow().GetValue();
2204 // check, if horizontal and vertical position have to be converted due to
2205 // the fact, that the object is anchored at a paragraph, which has a "column
2206 // break before" attribute
2207 bool bConvDueToAnchoredAtColBreakPara( false );
2208 if ( ( (eAnchor
== FLY_AT_PARA
) || (eAnchor
== FLY_AT_CHAR
) ) &&
2209 _rFrmFmt
.GetAnchor().GetCntntAnchor() &&
2210 _rFrmFmt
.GetAnchor().GetCntntAnchor()->nNode
.GetNode().IsTxtNode() )
2212 SwTxtNode
& rAnchorTxtNode
=
2213 dynamic_cast<SwTxtNode
&>(_rFrmFmt
.GetAnchor().GetCntntAnchor()->nNode
.GetNode());
2214 const SvxFmtBreakItem
* pBreak
= &(ItemGet
<SvxFmtBreakItem
>(rAnchorTxtNode
, RES_BREAK
));
2216 pBreak
->GetBreak() == SVX_BREAK_COLUMN_BEFORE
)
2218 bConvDueToAnchoredAtColBreakPara
= true;
2222 // convert horizontal position, if needed
2224 enum HoriConv
{ NO_CONV
, CONV2PG
, CONV2COL
, CONV2CHAR
};
2225 HoriConv
eHoriConv( NO_CONV
);
2227 // determine, if conversion has to be performed due to the position orientation
2228 bool bConvDueToOrientation( false );
2230 const sal_Int16 eHOri
= _iorHoriOri
.GetHoriOrient();
2231 bConvDueToOrientation
= eHOri
== text::HoriOrientation::LEFT
|| eHOri
== text::HoriOrientation::RIGHT
||
2232 eHOri
== text::HoriOrientation::INSIDE
|| eHOri
== text::HoriOrientation::OUTSIDE
||
2233 ( eHOri
!= text::HoriOrientation::CENTER
&& _iorHoriOri
.IsPosToggle() );
2236 // determine conversion type due to the position relation
2237 if ( bConvDueToAnchoredAtColBreakPara
)
2239 eHoriConv
= CONV2PG
;
2241 else if ( _iorHoriOri
.IsPosToggle()
2242 && _iorHoriOri
.GetHoriOrient() == text::HoriOrientation::RIGHT
)
2244 eHoriConv
= NO_CONV
;
2245 _iorHoriOri
.SetHoriOrient( text::HoriOrientation::OUTSIDE
);
2249 switch ( _iorHoriOri
.GetRelationOrient() )
2251 case text::RelOrientation::PAGE_FRAME
:
2252 case text::RelOrientation::PAGE_PRINT_AREA
:
2254 if ( bConvDueToOrientation
|| bFollowTextFlow
)
2255 eHoriConv
= CONV2PG
;
2258 case text::RelOrientation::PAGE_LEFT
:
2259 case text::RelOrientation::PAGE_RIGHT
:
2261 // relation not supported by WW8. Thus, conversion always needed.
2262 eHoriConv
= CONV2PG
;
2265 case text::RelOrientation::FRAME
:
2267 if ( bConvDueToOrientation
)
2268 eHoriConv
= CONV2COL
;
2271 case text::RelOrientation::PRINT_AREA
:
2272 case text::RelOrientation::FRAME_LEFT
:
2273 case text::RelOrientation::FRAME_RIGHT
:
2275 // relation not supported by WW8. Thus, conversion always needed.
2276 eHoriConv
= CONV2COL
;
2279 case text::RelOrientation::CHAR
:
2281 if ( bConvDueToOrientation
)
2282 eHoriConv
= CONV2CHAR
;
2286 OSL_FAIL( "<WinwordAnchoring::ConvertPosition(..)> - unknown horizontal relation" );
2289 if ( eHoriConv
!= NO_CONV
)
2291 _iorHoriOri
.SetHoriOrient( text::HoriOrientation::NONE
);
2292 SwTwips
nPosX( 0L );
2295 if ( eHoriConv
== CONV2PG
)
2297 _iorHoriOri
.SetRelationOrient( text::RelOrientation::PAGE_FRAME
);
2299 bool bRelToTableCell( false );
2300 aPos
= pAnchoredObj
->GetRelPosToPageFrm( bFollowTextFlow
,
2302 if ( bRelToTableCell
)
2304 _iorHoriOri
.SetRelationOrient( text::RelOrientation::PAGE_PRINT_AREA
);
2307 else if ( eHoriConv
== CONV2COL
)
2309 _iorHoriOri
.SetRelationOrient( text::RelOrientation::FRAME
);
2310 aPos
= pAnchoredObj
->GetRelPosToAnchorFrm();
2312 else if ( eHoriConv
== CONV2CHAR
)
2314 _iorHoriOri
.SetRelationOrient( text::RelOrientation::CHAR
);
2315 aPos
= pAnchoredObj
->GetRelPosToChar();
2317 // No distinction between layout directions, because of missing
2318 // information about WW8 in vertical layout.
2321 _iorHoriOri
.SetPos( nPosX
);
2326 // convert vertical position, if needed
2328 enum VertConv
{ NO_CONV
, CONV2PG
, CONV2PARA
, CONV2LINE
};
2329 VertConv
eVertConv( NO_CONV
);
2331 // determine, if conversion has to be performed due to the position orientation
2332 bool bConvDueToOrientation( false );
2334 const sal_Int16 eVOri
= _iorVertOri
.GetVertOrient();
2335 bConvDueToOrientation
= ( eVOri
== text::VertOrientation::TOP
||
2336 eVOri
== text::VertOrientation::BOTTOM
||
2337 eVOri
== text::VertOrientation::CHAR_TOP
||
2338 eVOri
== text::VertOrientation::CHAR_BOTTOM
||
2339 eVOri
== text::VertOrientation::CHAR_CENTER
||
2340 eVOri
== text::VertOrientation::LINE_TOP
||
2341 eVOri
== text::VertOrientation::LINE_BOTTOM
||
2342 eVOri
== text::VertOrientation::LINE_CENTER
);
2345 // determine conversion type due to the position relation
2346 if ( bConvDueToAnchoredAtColBreakPara
)
2348 eVertConv
= CONV2PG
;
2352 switch ( _iorVertOri
.GetRelationOrient() )
2354 case text::RelOrientation::PAGE_FRAME
:
2355 case text::RelOrientation::PAGE_PRINT_AREA
:
2357 if ( bConvDueToOrientation
|| bFollowTextFlow
)
2358 eVertConv
= CONV2PG
;
2361 case text::RelOrientation::FRAME
:
2363 if ( bConvDueToOrientation
||
2364 _iorVertOri
.GetVertOrient() == text::VertOrientation::CENTER
)
2366 eVertConv
= CONV2PARA
;
2370 case text::RelOrientation::PRINT_AREA
:
2372 // relation not supported by WW8. Thus, conversion always needed.
2373 eVertConv
= CONV2PARA
;
2376 case text::RelOrientation::CHAR
:
2378 // relation not supported by WW8. Thus, conversion always needed.
2379 eVertConv
= CONV2PARA
;
2382 case text::RelOrientation::TEXT_LINE
:
2384 if ( bConvDueToOrientation
||
2385 _iorVertOri
.GetVertOrient() == text::VertOrientation::NONE
)
2387 eVertConv
= CONV2LINE
;
2391 case text::RelOrientation::PAGE_LEFT
:
2392 case text::RelOrientation::PAGE_RIGHT
:
2393 case text::RelOrientation::FRAME_LEFT
:
2394 case text::RelOrientation::FRAME_RIGHT
:
2396 OSL_FAIL( "<WinwordAnchoring::ConvertPosition(..)> - unknown vertical relation" );
2400 if ( eVertConv
!= NO_CONV
)
2402 _iorVertOri
.SetVertOrient( text::VertOrientation::NONE
);
2403 SwTwips
nPosY( 0L );
2406 if ( eVertConv
== CONV2PG
)
2408 _iorVertOri
.SetRelationOrient( text::RelOrientation::PAGE_FRAME
);
2410 bool bRelToTableCell( false );
2411 aPos
= pAnchoredObj
->GetRelPosToPageFrm( bFollowTextFlow
,
2413 if ( bRelToTableCell
)
2415 _iorVertOri
.SetRelationOrient( text::RelOrientation::PAGE_PRINT_AREA
);
2418 else if ( eVertConv
== CONV2PARA
)
2420 _iorVertOri
.SetRelationOrient( text::RelOrientation::FRAME
);
2421 aPos
= pAnchoredObj
->GetRelPosToAnchorFrm();
2423 else if ( eVertConv
== CONV2LINE
)
2425 _iorVertOri
.SetRelationOrient( text::RelOrientation::TEXT_LINE
);
2426 aPos
= pAnchoredObj
->GetRelPosToLine();
2428 // No distinction between layout directions, because of missing
2429 // information about WW8 in vertical layout.
2432 _iorVertOri
.SetPos( nPosY
);
2440 void WinwordAnchoring::SetAnchoring(const SwFrmFmt
& rFmt
)
2442 const RndStdIds eAnchor
= rFmt
.GetAnchor().GetAnchorId();
2443 mbInline
= (eAnchor
== FLY_AS_CHAR
);
2445 SwFmtHoriOrient rHoriOri
= rFmt
.GetHoriOrient();
2446 SwFmtVertOrient rVertOri
= rFmt
.GetVertOrient();
2448 // #i30669# - convert the positioning attributes.
2449 // Most positions are converted, if layout information exists.
2450 const bool bPosConverted
= ConvertPosition( rHoriOri
, rVertOri
, rFmt
);
2452 const sal_Int16 eHOri
= rHoriOri
.GetHoriOrient();
2453 const sal_Int16 eVOri
= rVertOri
.GetVertOrient(); // #i22673#
2455 const sal_Int16 eHRel
= rHoriOri
.GetRelationOrient();
2456 const sal_Int16 eVRel
= rVertOri
.GetRelationOrient();
2458 // horizontal Adjustment
2462 case text::HoriOrientation::NONE
:
2465 case text::HoriOrientation::LEFT
:
2468 case text::HoriOrientation::CENTER
:
2471 case text::HoriOrientation::RIGHT
:
2474 case text::HoriOrientation::INSIDE
:
2477 case text::HoriOrientation::OUTSIDE
:
2482 // vertical Adjustment
2484 // When adjustment is vertically relative to line or to char
2485 // bottom becomes top and vice versa
2486 const bool bVertSwap
= !bPosConverted
&&
2487 ( (eVRel
== text::RelOrientation::CHAR
) ||
2488 (eVRel
== text::RelOrientation::TEXT_LINE
) );
2492 case text::VertOrientation::NONE
:
2495 case text::VertOrientation::TOP
:
2496 case text::VertOrientation::LINE_TOP
:
2497 case text::VertOrientation::CHAR_TOP
:
2498 mnYAlign
= bVertSwap
? 3 : 1;
2500 case text::VertOrientation::CENTER
:
2501 case text::VertOrientation::LINE_CENTER
:
2504 case text::VertOrientation::BOTTOM
:
2505 case text::VertOrientation::LINE_BOTTOM
:
2506 case text::VertOrientation::CHAR_BOTTOM
:
2507 mnYAlign
= bVertSwap
? 1 : 3;
2511 // Adjustment is horizontally relative to...
2514 case text::RelOrientation::PAGE_PRINT_AREA
:
2517 case text::RelOrientation::PAGE_FRAME
:
2518 case text::RelOrientation::PAGE_LEFT
: //:-(
2519 case text::RelOrientation::PAGE_RIGHT
: //:-(
2522 case text::RelOrientation::FRAME
:
2523 case text::RelOrientation::FRAME_LEFT
: //:-(
2524 case text::RelOrientation::FRAME_RIGHT
: //:-(
2525 if (eAnchor
== FLY_AT_PAGE
)
2530 case text::RelOrientation::PRINT_AREA
:
2531 if (eAnchor
== FLY_AT_PAGE
)
2536 case text::RelOrientation::CHAR
:
2539 case text::RelOrientation::TEXT_LINE
:
2543 // Adjustment is vertically relative to...
2546 case text::RelOrientation::PAGE_PRINT_AREA
:
2549 case text::RelOrientation::PAGE_FRAME
:
2552 case text::RelOrientation::PRINT_AREA
:
2553 if (eAnchor
== FLY_AT_PAGE
)
2558 case text::RelOrientation::FRAME
:
2559 if (eAnchor
== FLY_AT_PAGE
)
2564 case text::RelOrientation::CHAR
:
2565 case text::RelOrientation::TEXT_LINE
: // #i22673# - vertical alignment at top of line
2566 case text::RelOrientation::PAGE_LEFT
: //nonsense
2567 case text::RelOrientation::PAGE_RIGHT
: //nonsense
2568 case text::RelOrientation::FRAME_LEFT
: //nonsense
2569 case text::RelOrientation::FRAME_RIGHT
: //nonsense
2575 void SwEscherEx::WriteFrmExtraData( const SwFrmFmt
& rFmt
)
2577 aWinwordAnchoring
.SetAnchoring(rFmt
);
2578 aWinwordAnchoring
.WriteData(*this);
2580 AddAtom(4, ESCHER_ClientAnchor
);
2581 GetStream() << static_cast<sal_Int32
>(0);
2583 AddAtom(4, ESCHER_ClientData
);
2584 GetStream() << static_cast<sal_Int32
>(1);
2587 sal_Int32
SwEscherEx::WriteFlyFrm(const DrawObj
&rObj
, sal_uInt32
&rShapeId
,
2588 DrawObjPointerVector
&rPVec
)
2590 const SwFrmFmt
&rFmt
= rObj
.maCntnt
.GetFrmFmt();
2592 // check for textflyframe and if it is the first in a Chain
2593 sal_Int32 nBorderThick
= 0;
2594 const SwNodeIndex
* pNdIdx
= rFmt
.GetCntnt().GetCntntIdx();
2597 SwNodeIndex
aIdx( *pNdIdx
, 1 );
2598 switch( aIdx
.GetNode().GetNodeType() )
2601 nBorderThick
= WriteGrfFlyFrame( rFmt
, rShapeId
= GenerateShapeId() );
2604 nBorderThick
= WriteOLEFlyFrame( rFmt
, rShapeId
= GenerateShapeId() );
2607 if (const SdrObject
* pObj
= rFmt
.FindRealSdrObject())
2609 // check for the first in a Chain
2611 sal_uInt16 nOff
= 0;
2612 const SwFrmFmt
* pFmt
= &rFmt
, *pPrev
;
2613 while( 0 != ( pPrev
= pFmt
->GetChain().GetPrev() ))
2619 rShapeId
= GetFlyShapeId(rFmt
, rObj
.mnHdFtIndex
, rPVec
);
2622 nTxtId
= pTxtBxs
->GetPos( pObj
);
2623 if( USHRT_MAX
== nTxtId
)
2625 pTxtBxs
->Append( *pObj
, rShapeId
);
2626 nTxtId
= pTxtBxs
->Count();
2633 const SdrObject
* pPrevObj
= pFmt
->FindRealSdrObject();
2634 nTxtId
= pTxtBxs
->GetPos( pPrevObj
);
2635 if( USHRT_MAX
== nTxtId
)
2637 sal_uInt32 nPrevShapeId
=
2638 GetFlyShapeId(*pFmt
, rObj
.mnHdFtIndex
, rPVec
);
2639 pTxtBxs
->Append( *pPrevObj
, nPrevShapeId
);
2640 nTxtId
= pTxtBxs
->Count();
2648 nBorderThick
= WriteTxtFlyFrame(rObj
, rShapeId
, nTxtId
, rPVec
);
2652 return nBorderThick
;
2655 sal_uInt16
FindPos(const SwFrmFmt
&rFmt
, unsigned int nHdFtIndex
,
2656 DrawObjPointerVector
&rPVec
)
2658 DrawObjPointerIter aEnd
= rPVec
.end();
2659 for (DrawObjPointerIter aIter
= rPVec
.begin(); aIter
!= aEnd
; ++aIter
)
2661 const DrawObj
*pObj
= (*aIter
);
2662 OSL_ENSURE(pObj
, "Impossible");
2666 nHdFtIndex
== pObj
->mnHdFtIndex
&&
2667 &rFmt
== (&pObj
->maCntnt
.GetFrmFmt())
2670 return static_cast< sal_uInt16
>(aIter
- rPVec
.begin());
2676 sal_Int32
SwEscherEx::WriteTxtFlyFrame(const DrawObj
&rObj
, sal_uInt32 nShapeId
,
2677 sal_uInt32 nTxtBox
, DrawObjPointerVector
&rPVec
)
2679 const SwFrmFmt
&rFmt
= rObj
.maCntnt
.GetFrmFmt();
2680 short nDirection
= rObj
.mnDirection
;
2682 sal_Int32 nBorderThick
=0;
2683 OpenContainer( ESCHER_SpContainer
);
2685 AddShape( ESCHER_ShpInst_TextBox
, 0xa00, nShapeId
);
2686 EscherPropertyContainer aPropOpt
;
2687 aPropOpt
.AddOpt(ESCHER_Prop_lTxid
, nTxtBox
);
2688 if (const SwFrmFmt
*pNext
= rFmt
.GetChain().GetNext())
2690 sal_uInt16 nPos
= FindPos(*pNext
, rObj
.mnHdFtIndex
, rPVec
);
2691 if (USHRT_MAX
!= nPos
&& aFollowShpIds
[nPos
])
2692 aPropOpt
.AddOpt(ESCHER_Prop_hspNext
, aFollowShpIds
[nPos
]);
2694 nBorderThick
= WriteFlyFrameAttr( rFmt
, mso_sptTextBox
, aPropOpt
);
2701 OSL_ENSURE(!this, "unknown direction type");
2702 case FRMDIR_HORI_LEFT_TOP
:
2703 nFlow
=mso_txflHorzN
;
2705 case FRMDIR_HORI_RIGHT_TOP
:
2706 nFlow
=mso_txflHorzN
;
2708 case FRMDIR_VERT_TOP_LEFT
: //not really possible in word
2709 case FRMDIR_VERT_TOP_RIGHT
:
2710 nFlow
=mso_txflTtoBA
;
2713 aPropOpt
.AddOpt( ESCHER_Prop_txflTextFlow
, nFlow
);
2715 aPropOpt
.Commit( GetStream() );
2717 // store anchor attribute
2718 WriteFrmExtraData( rFmt
);
2720 AddAtom( 4, ESCHER_ClientTextbox
); GetStream() << nTxtBox
;
2722 CloseContainer(); // ESCHER_SpContainer
2723 return nBorderThick
;
2726 void SwBasicEscherEx::WriteOLEPicture(EscherPropertyContainer
&rPropOpt
,
2727 sal_uInt32 nShapeFlags
, const Graphic
&rGraphic
, const SdrObject
&rObj
,
2728 sal_uInt32 nShapeId
, const awt::Rectangle
* pVisArea
)
2730 //nShapeFlags == 0xA00 + flips and ole active
2731 AddShape(ESCHER_ShpInst_PictureFrame
, nShapeFlags
, nShapeId
);
2733 GraphicObject
aGraphicObject(rGraphic
);
2734 OString aId
= aGraphicObject
.GetUniqueID();
2737 Rectangle aRect
= rObj
.GetLogicRect();
2738 aRect
.SetPos(Point(0,0));
2739 aRect
.Right() = DrawModelToEmu(aRect
.Right());
2740 aRect
.Bottom() = DrawModelToEmu(aRect
.Bottom());
2741 sal_uInt32 nBlibId
= mxGlobal
->GetBlibID( *QueryPictureStream(),
2742 aId
, aRect
, pVisArea
, 0); // SJ: the fourth parameter (VisArea) should be set..
2744 rPropOpt
.AddOpt(ESCHER_Prop_pib
, nBlibId
, sal_True
);
2747 SetPicId(rObj
, nShapeId
, rPropOpt
);
2748 rPropOpt
.AddOpt( ESCHER_Prop_pictureActive
, 0x10000 );
2751 void SwEscherEx::WriteOCXControl( const SwFrmFmt
& rFmt
, sal_uInt32 nShapeId
)
2753 if (const SdrObject
* pSdrObj
= rFmt
.FindRealSdrObject())
2755 OpenContainer( ESCHER_SpContainer
);
2757 SdrModel
*pModel
= rWrt
.pDoc
->GetDrawModel();
2758 OutputDevice
*pDevice
= Application::GetDefaultDevice();
2759 OSL_ENSURE(pModel
&& pDevice
, "no model or device");
2761 // #i71538# use complete SdrViews
2762 // SdrExchangeView aExchange(pModel, pDevice);
2763 SdrView
aExchange(pModel
, pDevice
);
2765 Graphic
aGraphic(aExchange
.GetObjGraphic(pModel
, pSdrObj
));
2767 EscherPropertyContainer aPropOpt
;
2768 WriteOLEPicture(aPropOpt
, 0xa00 | SHAPEFLAG_OLESHAPE
, aGraphic
,
2769 *pSdrObj
, nShapeId
, NULL
);
2771 WriteFlyFrameAttr( rFmt
, mso_sptPictureFrame
, aPropOpt
);
2772 aPropOpt
.Commit( GetStream() );
2774 // store anchor attribute
2775 WriteFrmExtraData( rFmt
);
2777 CloseContainer(); // ESCHER_SpContainer
2781 void SwEscherEx::MakeZOrderArrAndFollowIds(
2782 std::vector
<DrawObj
>& rSrcArr
, std::vector
<DrawObj
*>&rDstArr
)
2784 ::lcl_makeZOrderArray(rWrt
, rSrcArr
, rDstArr
);
2786 //Now set up the follow IDs
2787 aFollowShpIds
.clear();
2789 for (size_t n
= 0; n
< rDstArr
.size(); ++n
)
2791 const SwFrmFmt
&rFmt
= rDstArr
[n
]->maCntnt
.GetFrmFmt();
2792 bool bNeedsShapeId
= false;
2794 if (RES_FLYFRMFMT
== rFmt
.Which())
2796 const SwFmtChain
&rChain
= rFmt
.GetChain();
2797 if (rChain
.GetPrev() || rChain
.GetNext())
2798 bNeedsShapeId
= true;
2801 sal_uLong nShapeId
= bNeedsShapeId
? GenerateShapeId() : 0;
2803 aFollowShpIds
.push_back(nShapeId
);
2807 sal_uInt32
SwEscherEx::GetFlyShapeId(const SwFrmFmt
& rFmt
,
2808 unsigned int nHdFtIndex
, DrawObjPointerVector
&rpVec
)
2810 sal_uInt16 nPos
= FindPos(rFmt
, nHdFtIndex
, rpVec
);
2811 sal_uInt32 nShapeId
;
2812 if (USHRT_MAX
!= nPos
)
2814 if (0 == (nShapeId
= aFollowShpIds
[nPos
]))
2816 nShapeId
= GenerateShapeId();
2817 aFollowShpIds
[ nPos
] = nShapeId
;
2821 nShapeId
= GenerateShapeId();
2825 sal_uInt32
SwEscherEx::QueryTextID(
2826 const uno::Reference
< drawing::XShape
>& xXShapeRef
, sal_uInt32 nShapeId
)
2829 if (SdrObject
* pObj
= GetSdrObjectFromXShape(xXShapeRef
))
2831 pTxtBxs
->Append( *pObj
, nShapeId
);
2832 nId
= pTxtBxs
->Count();
2838 SwMSConvertControls::SwMSConvertControls( SfxObjectShell
*pDSh
,SwPaM
*pP
) : oox
2839 ::ole::MSConvertOCXControls( pDSh
? pDSh
->GetModel() : NULL
), pPaM( pP
), mnObjectId(0)
2843 sal_uInt32
SwMSConvertControls::GenerateObjectID()
2845 return ++mnObjectId
;
2848 // in transitioning away old filter for ole/ocx controls, ReadOCXStream has been made pure virtual in
2849 // filter/source/msocximex.cxx, so.. we need an implementation here
2850 sal_Bool
SwMSConvertControls::ReadOCXStream( SotStorageRef
& rSrc1
,
2851 com::sun::star::uno::Reference
< com::sun::star::drawing::XShape
> *pShapeRef
,
2852 sal_Bool bFloatingCtrl
)
2854 uno::Reference
< form::XFormComponent
> xFComp
;
2855 sal_Bool bRes
= oox::ole::MSConvertOCXControls::ReadOCXStorage( rSrc1
, xFComp
);
2856 if ( bRes
&& xFComp
.is() )
2858 com::sun::star::awt::Size aSz
; // not used in import
2859 bRes
= InsertControl( xFComp
, aSz
,pShapeRef
,bFloatingCtrl
);
2864 bool SwMSConvertControls::ExportControl(WW8Export
&rWW8Wrt
, const SdrObject
*pObj
)
2866 if (!rWW8Wrt
.bWrtWW8
)
2869 SdrUnoObj
*pFormObj
= PTR_CAST(SdrUnoObj
,pObj
);
2870 uno::Reference
< awt::XControlModel
> xControlModel
=
2871 pFormObj
->GetUnoControlModel();
2873 //Why oh lord do we use so many different units ?
2874 //I think I painted myself into a little bit of a
2875 //corner by trying to use the uno interface for
2877 Rectangle aRect
= pFormObj
->GetLogicRect();
2878 aRect
.SetPos(Point(0,0));
2880 aSize
.Width
= TWIPS_TO_MM(aRect
.Right());
2881 aSize
.Height
= TWIPS_TO_MM(aRect
.Bottom());
2883 //Open the ObjectPool
2884 SvStorageRef xObjPool
= rWW8Wrt
.GetWriter().GetStorage().OpenSotStorage(
2885 OUString(SL::aObjectPool
), STREAM_READWRITE
|
2886 STREAM_SHARE_DENYALL
);
2888 //Create a destination storage for the microsoft control
2889 OUStringBuffer sStorageName
;
2890 sal_uInt32 nObjId
= GenerateObjectID();
2891 sStorageName
.append('_').append( static_cast<sal_Int64
>( nObjId
));
2892 SvStorageRef xOleStg
= xObjPool
->OpenSotStorage(sStorageName
.makeStringAndClear(),
2893 STREAM_READWRITE
|STREAM_SHARE_DENYALL
);
2900 if (!WriteOCXStream( mxModel
, xOleStg
,xControlModel
,aSize
,sUName
))
2903 String sName
= sUName
;
2905 sal_uInt8 aSpecOLE
[] =
2907 0x03, 0x6a, 0xFF, 0xFF, 0xFF, 0xFF, // sprmCPicLocation
2908 0x0a, 0x08, 1, // sprmCFOLE2
2909 0x55, 0x08, 1, // sprmCFSpec
2910 0x56, 0x08, 1 // sprmCFObj
2912 //Set the obj id into the sprmCPicLocation
2913 sal_uInt8
*pData
= aSpecOLE
+2;
2914 Set_UInt32(pData
,nObjId
);
2916 String
sFld(FieldString(ww::eCONTROL
));
2917 sFld
.AppendAscii("Forms.");
2919 sFld
.AppendAscii(".1 \\s ");
2921 rWW8Wrt
.OutputField(0, ww::eCONTROL
, sFld
,
2922 WRITEFIELD_START
|WRITEFIELD_CMD_START
|WRITEFIELD_CMD_END
);
2924 rWW8Wrt
.pChpPlc
->AppendFkpEntry(rWW8Wrt
.Strm().Tell(),sizeof(aSpecOLE
),
2926 rWW8Wrt
.WriteChar( 0x1 );
2927 rWW8Wrt
.OutputField(0, ww::eCONTROL
, aEmptyStr
, WRITEFIELD_END
| WRITEFIELD_CLOSE
);
2931 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */