1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: wrtw8esh.cxx,v $
10 * $Revision: 1.105.10.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
33 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
34 #include <com/sun/star/embed/Aspects.hpp>
37 #include <hintids.hxx>
39 #define _SVSTDARR_ULONGSSORT
40 #define _SVSTDARR_USHORTS
41 #include <svtools/svstdarr.hxx>
42 #include <vcl/cvtgrf.hxx>
43 #include <vcl/virdev.hxx>
44 #include <com/sun/star/drawing/XShape.hpp>
45 #include <vcl/svapp.hxx>
46 #include <sot/storage.hxx>
47 #include <svtools/filter.hxx>
48 #include <svtools/itemiter.hxx>
49 #include <svx/svdobj.hxx>
50 #include <svx/svdotext.hxx>
51 #include <svx/svdmodel.hxx>
52 #include <svx/svdpage.hxx>
53 #include <svx/outlobj.hxx>
54 #include <svx/editobj.hxx>
55 #include <svx/unoshape.hxx>
56 #include <svx/brshitem.hxx>
57 #include <svx/boxitem.hxx>
58 #include <svx/lrspitem.hxx>
59 #include <svx/ulspitem.hxx>
60 #include <svx/fontitem.hxx>
61 #include <svx/frmdiritem.hxx>
62 #include <svx/svdoole2.hxx>
63 #include <svx/editeng.hxx>
64 #ifndef _SVX_FLDITEM_HXX
65 //miserable hack to get around #98519#
67 #include <svx/flditem.hxx>
70 #include <comphelper/seqstream.hxx>
71 #include <unotools/ucbstreamhelper.hxx>
72 #include <svtools/filter.hxx>
73 #include <svx/fmglob.hxx>
74 #include <svx/svdouno.hxx>
75 #include <svx/unoapi.hxx>
78 #include <svx/svdview.hxx>
79 #include <fmtcnct.hxx>
80 #include <fmtanchr.hxx>
81 #include <fmtsrnd.hxx>
82 #include <fmtornt.hxx>
83 #include <fmtfsize.hxx>
84 // --> OD 2005-01-06 #i30669#
85 #include <fmtfollowtextflow.hxx>
87 #include <dcontact.hxx>
89 #include <fmtcntnt.hxx>
90 #include <ndindex.hxx>
98 #include <unodraw.hxx>
99 #include <pagedesc.hxx>
100 #include <ww8par.hxx>
101 #include <breakit.hxx>
102 #include <com/sun/star/i18n/ScriptType.hdl>
103 #include "ww8attributeoutput.hxx"
104 #include "writerhelper.hxx"
105 #include "writerwordglue.hxx"
106 #include "wrtww8.hxx"
107 #include "escher.hxx"
108 // --> OD 2007-07-24 #148096#
111 #include "WW8FFData.hxx"
113 using namespace com::sun::star
;
114 using namespace sw::util
;
115 using namespace sw::types
;
116 using namespace nsFieldFlags
;
118 //#110185# get a part fix for this type of element
119 bool WW8Export::MiserableFormFieldExportHack(const SwFrmFmt
& rFrmFmt
)
121 ASSERT(bWrtWW8
, "Not allowed");
125 const SdrObject
*pObject
= rFrmFmt
.FindRealSdrObject();
126 if (pObject
&& pObject
->GetObjInventor() == FmFormInventor
)
128 if (SdrUnoObj
*pFormObj
= PTR_CAST(SdrUnoObj
,pObject
))
130 uno::Reference
< awt::XControlModel
> xControlModel
=
131 pFormObj
->GetUnoControlModel();
132 uno::Reference
< lang::XServiceInfo
> xInfo(xControlModel
,
134 uno::Reference
<beans::XPropertySet
> xPropSet(xControlModel
, uno::UNO_QUERY
);
135 if (xInfo
->supportsService(C2U("com.sun.star.form.component.ComboBox")))
137 DoComboBox(xPropSet
);
140 else if (xInfo
->supportsService(C2U("com.sun.star.form.component.CheckBox")))
142 DoCheckBox(xPropSet
);
151 void WW8Export::DoComboBox(uno::Reference
<beans::XPropertySet
> xPropSet
)
153 rtl::OUString sSelected
;
154 uno::Sequence
<rtl::OUString
> aListItems
;
155 xPropSet
->getPropertyValue(C2U("StringItemList")) >>= aListItems
;
156 sal_Int32 nNoStrings
= aListItems
.getLength();
159 uno::Any aTmp
= xPropSet
->getPropertyValue(C2U("DefaultText"));
160 const rtl::OUString
*pStr
= (const rtl::OUString
*)aTmp
.getValue();
167 uno::Any aTmp
= xPropSet
->getPropertyValue(C2U("Name"));
168 const rtl::OUString
*pStr
= (const rtl::OUString
*)aTmp
.getValue();
176 uno::Any aTmp
= xPropSet
->getPropertyValue(C2U("Help"));
177 const rtl::OUString
*pStr
= (const rtl::OUString
*)aTmp
.getValue();
182 rtl::OUString sToolTip
;
184 uno::Any aTmp
= xPropSet
->getPropertyValue(C2U("Name"));
185 const rtl::OUString
*pStr
= (const rtl::OUString
*)aTmp
.getValue();
190 DoComboBox(sName
, sHelp
, sToolTip
, sSelected
, aListItems
);
193 void WW8Export::DoComboBox(const rtl::OUString
&rName
,
194 const rtl::OUString
&rHelp
,
195 const rtl::OUString
&rToolTip
,
196 const rtl::OUString
&rSelected
,
197 uno::Sequence
<rtl::OUString
> &rListItems
)
199 ASSERT(bWrtWW8
, "Not allowed");
202 OutputField(0, ww::eFORMDROPDOWN
, FieldString(ww::eFORMDROPDOWN
),
203 WRITEFIELD_START
| WRITEFIELD_CMD_START
);
204 // write the refence to the "picture" structure
205 ULONG nDataStt
= pDataStrm
->Tell();
206 pChpPlc
->AppendFkpEntry( Strm().Tell() );
210 static BYTE aArr1
[] =
212 0x03, 0x6a, 0,0,0,0, // sprmCPicLocation
213 0x06, 0x08, 0x01, // sprmCFData
214 0x55, 0x08, 0x01, // sprmCFSpec
215 0x02, 0x08, 0x01 // sprmCFFldVanish
217 BYTE
* pDataAdr
= aArr1
+ 2;
218 Set_UInt32( pDataAdr
, nDataStt
);
220 pChpPlc
->AppendFkpEntry(Strm().Tell(), sizeof(aArr1
), aArr1
);
222 OutputField(0, ww::eFORMDROPDOWN
, FieldString(ww::eFORMDROPDOWN
),
225 ::sw::WW8FFData aFFData
;
228 aFFData
.setName(rName
);
229 aFFData
.setHelp(rHelp
);
230 aFFData
.setStatus(rToolTip
);
232 sal_uInt32 nListItems
= rListItems
.getLength();
234 for (sal_uInt32 i
= 0; i
< nListItems
; i
++)
236 if (i
< 0x20 && rSelected
== rListItems
[i
])
237 aFFData
.setResult(::sal::static_int_cast
<sal_uInt8
>(i
));
238 aFFData
.addListboxEntry(rListItems
[i
]);
241 aFFData
.Write(pDataStrm
);
244 void WW8Export::DoCheckBox(uno::Reference
<beans::XPropertySet
> xPropSet
)
246 uno::Reference
<beans::XPropertySetInfo
> xPropSetInfo
=
247 xPropSet
->getPropertySetInfo();
249 OutputField(0, ww::eFORMCHECKBOX
, FieldString(ww::eFORMCHECKBOX
),
250 WRITEFIELD_START
| WRITEFIELD_CMD_START
);
251 // write the refence to the "picture" structure
252 ULONG nDataStt
= pDataStrm
->Tell();
253 pChpPlc
->AppendFkpEntry( Strm().Tell() );
256 static BYTE aArr1
[] = {
257 0x03, 0x6a, 0,0,0,0, // sprmCPicLocation
259 0x06, 0x08, 0x01, // sprmCFData
260 0x55, 0x08, 0x01, // sprmCFSpec
261 0x02, 0x08, 0x01 // sprmCFFldVanish
263 BYTE
* pDataAdr
= aArr1
+ 2;
264 Set_UInt32( pDataAdr
, nDataStt
);
266 pChpPlc
->AppendFkpEntry(Strm().Tell(),
267 sizeof( aArr1
), aArr1
);
269 ::sw::WW8FFData aFFData
;
272 aFFData
.setCheckboxHeight(0x14);
275 xPropSet
->getPropertyValue(C2U("DefaultState")) >>= nTemp
;
276 sal_uInt32
nIsDefaultChecked(nTemp
);
278 xPropSet
->getPropertyValue(C2U("State")) >>= nTemp
;
279 sal_uInt32
nIsChecked(nTemp
);
281 if (nIsDefaultChecked
!= nIsChecked
)
286 aFFData
.setResult(0);
289 aFFData
.setResult(1);
292 ASSERT(!this, "how did that happen");
296 ::rtl::OUString aStr
;
297 static ::rtl::OUString
sName(C2U("Name"));
298 if (xPropSetInfo
->hasPropertyByName(sName
))
300 xPropSet
->getPropertyValue(sName
) >>= aStr
;
301 aFFData
.setName(aStr
);
304 static ::rtl::OUString
sHelpText(C2U("HelpText"));
305 if (xPropSetInfo
->hasPropertyByName(sHelpText
))
307 xPropSet
->getPropertyValue(sHelpText
) >>= aStr
;
308 aFFData
.setHelp(aStr
);
310 static ::rtl::OUString
sHelpF1Text(C2U("HelpF1Text"));
311 if (xPropSetInfo
->hasPropertyByName(sHelpF1Text
))
313 xPropSet
->getPropertyValue(sHelpF1Text
) >>= aStr
;
314 aFFData
.setStatus(aStr
);
317 aFFData
.Write(pDataStrm
);
319 OutputField(0, ww::eFORMCHECKBOX
, aEmptyStr
, WRITEFIELD_CLOSE
);
322 void WW8Export::DoFormText(const SwInputField
* pFld
)
324 OutputField(0, ww::eFORMTEXT
, FieldString(ww::eFORMTEXT
),
325 WRITEFIELD_START
| WRITEFIELD_CMD_START
);
326 // write the refence to the "picture" structure
327 ULONG nDataStt
= pDataStrm
->Tell();
328 pChpPlc
->AppendFkpEntry( Strm().Tell() );
331 static BYTE aArr1
[] = {
332 0x02, 0x08, 0x81, // sprmCFFldVanish
333 0x03, 0x6a, 0,0,0,0, // sprmCPicLocation
335 0x06, 0x08, 0x01, // sprmCFData
336 0x55, 0x08, 0x01 // sprmCFSpec
338 BYTE
* pDataAdr
= aArr1
+ 5;
339 Set_UInt32( pDataAdr
, nDataStt
);
341 pChpPlc
->AppendFkpEntry(Strm().Tell(),
342 sizeof( aArr1
), aArr1
);
344 ::sw::WW8FFData aFFData
;
347 aFFData
.setName(pFld
->GetPar2());
348 aFFData
.setHelp(pFld
->GetHelp());
349 aFFData
.setStatus(pFld
->GetToolTip());
350 aFFData
.Write(pDataStrm
);
352 OutputField(0, ww::eFORMTEXT
, aEmptyStr
, WRITEFIELD_CMD_END
);
354 SwWW8Writer::WriteString16(Strm(), pFld
->Expand(), false);
356 static BYTE aArr2
[] = {
357 0x03, 0x6a, 0x00, 0x00, 0x00, 0x00, // sprmCPicLocation
358 0x55, 0x08, 0x01, // sprmCFSpec
359 0x75, 0x08, 0x01 // ???
362 pDataAdr
= aArr2
+ 2;
363 Set_UInt32( pDataAdr
, nDataStt
);
364 pChpPlc
->AppendFkpEntry(Strm().Tell(),
365 sizeof( aArr2
), aArr2
);
367 OutputField(0, ww::eFORMTEXT
, aEmptyStr
, WRITEFIELD_CLOSE
);
370 PlcDrawObj::~PlcDrawObj()
374 //Its irritating to have to change the RTL frames position into LTR ones
375 //so that word will have to place them in the right place. Doubly so that
376 //the SO drawings and writer frames have different ideas themselves as to
377 //how to be positioned when in RTL mode!
378 bool RTLGraphicsHack(SwTwips
&rLeft
, SwTwips nWidth
,
379 sal_Int16 eHoriOri
, sal_Int16 eHoriRel
, SwTwips nPageLeft
,
380 SwTwips nPageRight
, SwTwips nPageSize
)
383 if (eHoriOri
== text::HoriOrientation::NONE
)
385 if (eHoriRel
== text::RelOrientation::PAGE_FRAME
)
387 rLeft
= nPageSize
- rLeft
;
391 (eHoriRel
== text::RelOrientation::PAGE_PRINT_AREA
) ||
392 (eHoriRel
== text::RelOrientation::FRAME
) ||
393 (eHoriRel
== text::RelOrientation::PRINT_AREA
)
396 rLeft
= nPageSize
- nPageLeft
- nPageRight
- rLeft
;
405 bool RTLDrawingsHack(long &rLeft
, long /*nWidth*/,
406 sal_Int16 eHoriOri
, sal_Int16 eHoriRel
, SwTwips nPageLeft
,
407 SwTwips nPageRight
, SwTwips nPageSize
)
410 if (eHoriOri
== text::HoriOrientation::NONE
)
412 if (eHoriRel
== text::RelOrientation::PAGE_FRAME
)
414 rLeft
= nPageSize
+ rLeft
;
418 (eHoriRel
== text::RelOrientation::PAGE_PRINT_AREA
) ||
419 (eHoriRel
== text::RelOrientation::FRAME
) ||
420 (eHoriRel
== text::RelOrientation::PRINT_AREA
)
423 rLeft
= nPageSize
- nPageLeft
- nPageRight
+ rLeft
;
430 bool WW8Export::MiserableRTLFrmFmtHack(SwTwips
&rLeft
, SwTwips
&rRight
,
431 const sw::Frame
&rFrmFmt
)
433 //Require nasty bidi swap
434 if (FRMDIR_HORI_RIGHT_TOP
!= pDoc
->GetTextDirection(rFrmFmt
.GetPosition()))
437 SwTwips nWidth
= rRight
- rLeft
;
438 SwTwips nPageLeft
, nPageRight
;
439 SwTwips nPageSize
= CurrentPageWidth(nPageLeft
, nPageRight
);
441 const SwFmtHoriOrient
& rHOr
= rFrmFmt
.GetFrmFmt().GetHoriOrient();
444 sw::Frame::WriterSource eSource
= rFrmFmt
.GetWriterType();
445 if (eSource
== sw::Frame::eDrawing
|| eSource
== sw::Frame::eFormControl
)
447 if (RTLDrawingsHack(rLeft
, nWidth
, rHOr
.GetHoriOrient(),
448 rHOr
.GetRelationOrient(), nPageLeft
, nPageRight
, nPageSize
))
455 if (RTLGraphicsHack(rLeft
, nWidth
, rHOr
.GetHoriOrient(),
456 rHOr
.GetRelationOrient(), nPageLeft
, nPageRight
, nPageSize
))
462 rRight
= rLeft
+ nWidth
;
466 void PlcDrawObj::WritePlc( WW8Export
& rWrt
) const
468 if (8 > rWrt
.pFib
->nVersion
) // Cannot export drawobject in vers 7-
471 sal_uInt32 nFcStart
= rWrt
.pTableStrm
->Tell();
473 if (!maDrawObjs
.empty())
476 WW8Fib
& rFib
= *rWrt
.pFib
;
477 WW8_CP nCpOffs
= GetCpOffset(rFib
);
479 cDrawObjIter aEnd
= maDrawObjs
.end();
482 for (aIter
= maDrawObjs
.begin(); aIter
< aEnd
; ++aIter
)
483 SwWW8Writer::WriteLong(*rWrt
.pTableStrm
, aIter
->mnCp
- nCpOffs
);
485 SwWW8Writer::WriteLong(*rWrt
.pTableStrm
, rFib
.ccpText
+ rFib
.ccpFtn
+
486 rFib
.ccpHdr
+ rFib
.ccpEdn
+ rFib
.ccpTxbx
+ rFib
.ccpHdrTxbx
+ 1);
488 for (aIter
= maDrawObjs
.begin(); aIter
< aEnd
; ++aIter
)
490 // write the fspa-struct
491 const sw::Frame
&rFrmFmt
= aIter
->maCntnt
;
492 const SwFrmFmt
&rFmt
= rFrmFmt
.GetFrmFmt();
493 const SdrObject
* pObj
= rFmt
.FindRealSdrObject();
496 SwFmtVertOrient rVOr
= rFmt
.GetVertOrient();
497 SwFmtHoriOrient rHOr
= rFmt
.GetHoriOrient();
498 // --> OD 2005-01-06 #i30669# - convert the positioning attributes.
499 // Most positions are converted, if layout information exists.
500 const bool bPosConverted
=
501 WinwordAnchoring::ConvertPosition( rHOr
, rVOr
, rFmt
);
505 if (RES_FLYFRMFMT
== rFmt
.Which())
507 SwRect
aLayRect(rFmt
.FindLayoutRect(false, &aObjPos
));
508 // the Object is not visible - so get the values from
509 // the format. The Position may not be correct.
510 if( aLayRect
.IsEmpty() )
511 aRect
.SetSize( rFmt
.GetFrmSize().GetSize() );
514 // --> FME 2007-06-20 #i56090# Do not only consider the first client
515 // Note that we actually would have to find the maximum size of the
516 // frame format clients. However, this already should work in most cases.
517 const SwRect
aSizeRect(rFmt
.FindLayoutRect());
518 if ( aSizeRect
.Width() > aLayRect
.Width() )
519 aLayRect
.Width( aSizeRect
.Width() );
522 aRect
= aLayRect
.SVRect();
527 ASSERT(pObj
, "wo ist das SDR-Object?");
530 aRect
= pObj
->GetSnapRect();
534 // --> OD 2005-01-06 #i30669# - use converted position, if conversion
535 // is performed. Unify position determination of Writer fly frames
536 // and drawing objects.
539 aRect
.SetPos( Point( rHOr
.GetPos(), rVOr
.GetPos() ) );
543 aRect
-= aIter
->maParentPos
;
544 aObjPos
= aRect
.TopLeft();
545 if (text::VertOrientation::NONE
== rVOr
.GetVertOrient())
547 // CMC, OD 24.11.2003 #i22673#
548 sal_Int16 eOri
= rVOr
.GetRelationOrient();
549 if (eOri
== text::RelOrientation::CHAR
|| eOri
== text::RelOrientation::TEXT_LINE
)
550 aObjPos
.Y() = -rVOr
.GetPos();
552 aObjPos
.Y() = rVOr
.GetPos();
554 if (text::HoriOrientation::NONE
== rHOr
.GetHoriOrient())
555 aObjPos
.X() = rHOr
.GetPos();
556 aRect
.SetPos( aObjPos
);
560 INT32 nThick
= aIter
->mnThick
;
562 //If we are being exported as an inline hack, set
563 //corner to 0 and forget about border thickness for positioning
564 if (rFrmFmt
.IsInline())
566 aRect
.SetPos(Point(0,0));
571 SwWW8Writer::WriteLong(*rWrt
.pTableStrm
, aIter
->mnShapeId
);
573 SwTwips nLeft
= aRect
.Left() + nThick
;
574 SwTwips nRight
= aRect
.Right() - nThick
;
576 //Nasty swap for bidi if neccessary
577 rWrt
.MiserableRTLFrmFmtHack(nLeft
, nRight
, rFrmFmt
);
579 //xaLeft/yaTop/xaRight/yaBottom - rel. to anchor
580 //(most of) the border is outside the graphic is word, so
581 //change dimensions to fit
582 SwWW8Writer::WriteLong(*rWrt
.pTableStrm
, nLeft
);
583 SwWW8Writer::WriteLong(*rWrt
.pTableStrm
,aRect
.Top() + nThick
);
584 SwWW8Writer::WriteLong(*rWrt
.pTableStrm
, nRight
);
585 SwWW8Writer::WriteLong(*rWrt
.pTableStrm
,aRect
.Bottom() - nThick
);
587 //fHdr/bx/by/wr/wrk/fRcaSimple/fBelowText/fAnchorLock
589 //If nFlags isn't 0x14 its overridden by the escher properties
590 if( FLY_PAGE
== rFmt
.GetAnchor().GetAnchorId())
593 nFlags
= 0x0014; // x-rel to text, y-rel to text
595 const SwFmtSurround
& rSurr
= rFmt
.GetSurround();
596 USHORT nContour
= rSurr
.IsContour() ? 0x0080 : 0x0040;
597 SwSurround eSurround
= rSurr
.GetSurround();
601 The inline elements being export as anchored to character inside
602 the shape field hack are required to be wrap through so as to flow
603 over the following dummy 0x01 graphic
605 if (rFrmFmt
.IsInline())
606 eSurround
= SURROUND_THROUGHT
;
613 case SURROUND_THROUGHT
:
616 case SURROUND_PARALLEL
:
617 nFlags
|= 0x0000 | nContour
;
620 nFlags
|= 0x0600 | nContour
;
623 nFlags
|= 0x0200 | nContour
;
626 nFlags
|= 0x0400 | nContour
;
629 ASSERT(!this, "Unsupported surround type for export");
632 if (pObj
&& (pObj
->GetLayer() == rWrt
.pDoc
->GetHellId() ||
633 pObj
->GetLayer() == rWrt
.pDoc
->GetInvisibleHellId()))
639 #i3958# Required to make this inline stuff work in WordXP, not
640 needed for 2003 interestingly
642 if (rFrmFmt
.IsInline())
645 SwWW8Writer::WriteShort(*rWrt
.pTableStrm
, nFlags
);
648 SwWW8Writer::WriteLong(*rWrt
.pTableStrm
, 0);
651 RegisterWithFib(rFib
, nFcStart
, rWrt
.pTableStrm
->Tell() - nFcStart
);
655 void MainTxtPlcDrawObj::RegisterWithFib(WW8Fib
&rFib
, sal_uInt32 nStart
,
656 sal_uInt32 nLen
) const
658 rFib
.fcPlcfspaMom
= nStart
;
659 rFib
.lcbPlcfspaMom
= nLen
;
662 WW8_CP
MainTxtPlcDrawObj::GetCpOffset(const WW8Fib
&) const
667 void HdFtPlcDrawObj::RegisterWithFib(WW8Fib
&rFib
, sal_uInt32 nStart
,
668 sal_uInt32 nLen
) const
670 rFib
.fcPlcfspaHdr
= nStart
;
671 rFib
.lcbPlcfspaHdr
= nLen
;
674 WW8_CP
HdFtPlcDrawObj::GetCpOffset(const WW8Fib
&rFib
) const
676 return rFib
.ccpText
+ rFib
.ccpFtn
;
679 DrawObj
& DrawObj::operator=(const DrawObj
& rOther
)
682 mnShapeId
= rOther
.mnShapeId
;
683 maCntnt
= rOther
.maCntnt
;
684 maParentPos
= rOther
.maParentPos
;
685 mnThick
= rOther
.mnThick
;
686 mnDirection
= rOther
.mnDirection
;
687 mnHdFtIndex
= rOther
.mnHdFtIndex
;
691 bool PlcDrawObj::Append( WW8Export
& rWrt
, WW8_CP nCp
, const sw::Frame
& rFmt
,
692 const Point
& rNdTopLeft
)
695 const SwFrmFmt
&rFormat
= rFmt
.GetFrmFmt();
696 if (TXT_HDFT
== rWrt
.nTxtTyp
|| TXT_MAINTEXT
== rWrt
.nTxtTyp
)
698 if (RES_FLYFRMFMT
== rFormat
.Which())
700 // check for textflyframe and if it is the first in a Chain
701 if (rFormat
.GetCntnt().GetCntntIdx())
710 DrawObj
aObj(rFmt
, nCp
, rNdTopLeft
, rWrt
.TrueFrameDirection(rFormat
),
711 rWrt
.GetHdFtIndex());
712 maDrawObjs
.push_back(aObj
);
717 void DrawObj::SetShapeDetails(UINT32 nId
, INT32 nThick
)
723 bool WW8_WrPlcTxtBoxes::WriteTxt( WW8Export
& rWrt
)
726 rWrt
.bInWriteEscher
= true;
727 WW8_CP
& rccp
=TXT_TXTBOX
== nTyp
? rWrt
.pFib
->ccpTxbx
: rWrt
.pFib
->ccpHdrTxbx
;
729 bRet
= WriteGenericTxt( rWrt
, nTyp
, rccp
);
731 WW8_CP nCP
= rWrt
.Fc2Cp( rWrt
.Strm().Tell() );
732 WW8Fib
& rFib
= *rWrt
.pFib
;
733 WW8_CP nMyOffset
= rFib
.ccpText
+ rFib
.ccpFtn
+ rFib
.ccpHdr
+ rFib
.ccpAtn
735 if( TXT_TXTBOX
== nTyp
)
736 rWrt
.pFldTxtBxs
->Finish( nCP
, nMyOffset
);
738 rWrt
.pFldHFTxtBxs
->Finish( nCP
, nMyOffset
+ rFib
.ccpTxbx
);
739 rWrt
.bInWriteEscher
= false;
743 void WW8_WrPlcTxtBoxes::Append( const SdrObject
& rObj
, UINT32 nShapeId
)
745 void* p
= (void*)&rObj
;
746 aCntnt
.Insert( p
, aCntnt
.Count() );
747 aShapeIds
.Insert( nShapeId
, aShapeIds
.Count() );
750 const SvULongs
* WW8_WrPlcTxtBoxes::GetShapeIdArr() const
757 UINT32
WW8Export::GetSdrOrdNum( const SwFrmFmt
& rFmt
) const
760 const SdrObject
* pObj
= rFmt
.FindRealSdrObject();
762 nOrdNum
= pObj
->GetOrdNum();
765 // no Layout for this format, then recalc the ordnum
766 SwFrmFmt
* pFmt
= (SwFrmFmt
*)&rFmt
;
767 nOrdNum
= pDoc
->GetSpzFrmFmts()->GetPos( pFmt
);
769 const SdrModel
* pModel
= pDoc
->GetDrawModel();
771 nOrdNum
+= pModel
->GetPage( 0 )->GetObjCount();
776 void WW8Export::AppendFlyInFlys(const sw::Frame
& rFrmFmt
,
777 const Point
& rNdTopLeft
)
779 ASSERT(bWrtWW8
, "this has gone horribly wrong");
780 ASSERT(!pEscher
, "der EscherStream wurde schon geschrieben!");
784 if (TXT_HDFT
== nTxtTyp
)
789 if (rFrmFmt
.IsInline())
791 OutputField(0, ww::eSHAPE
, FieldString(ww::eSHAPE
),
792 WRITEFIELD_START
| WRITEFIELD_CMD_START
| WRITEFIELD_CMD_END
);
795 WW8_CP nCP
= Fc2Cp(Strm().Tell());
796 bool bSuccess
= pDrwO
->Append(*this, nCP
, rFrmFmt
, rNdTopLeft
);
797 ASSERT(bSuccess
, "Couldn't export a graphical element!");
801 static const sal_uInt8 aSpec8
[] =
803 0x03, 0x6a, 0, 0, 0, 0, // sprmCObjLocation
804 0x55, 0x08, 1 // sprmCFSpec
806 // fSpec-Attribut true
807 // Fuer DrawObjets muss ein Spezial-Zeichen
808 // in den Text und darum ein fSpec-Attribut
809 pChpPlc
->AppendFkpEntry( Strm().Tell() );
811 pChpPlc
->AppendFkpEntry( Strm().Tell(), sizeof( aSpec8
), aSpec8
);
813 //Need dummy picture frame
814 if (rFrmFmt
.IsInline())
818 if (rFrmFmt
.IsInline())
819 OutputField(0, ww::eSHAPE
, aEmptyStr
, WRITEFIELD_CLOSE
);
822 class WW8_SdrAttrIter
: public MSWordAttrIter
825 const EditTextObject
* pEditObj
;
826 const SfxItemPool
* pEditPool
;
827 EECharAttribArray aTxtAtrArr
;
828 SvPtrarr aChrTxtAtrArr
;
829 SvUShorts aChrSetArr
;
831 xub_StrLen nAktSwPos
;
832 xub_StrLen nTmpSwPos
; // fuer HasItem()
833 rtl_TextEncoding eNdChrSet
;
837 xub_StrLen
SearchNext( xub_StrLen nStartPos
);
838 void SetCharSet(const EECharAttrib
& rTxtAttr
, bool bStart
);
841 WW8_SdrAttrIter(const WW8_SdrAttrIter
&);
842 WW8_SdrAttrIter
& operator=(const WW8_SdrAttrIter
&);
844 WW8_SdrAttrIter( WW8Export
& rWr
, const EditTextObject
& rEditObj
,
846 void NextPara( USHORT nPar
);
847 void OutParaAttr(bool bCharAttr
);
848 void OutEEField(const SfxPoolItem
& rHt
);
850 bool IsTxtAttr(xub_StrLen nSwPos
);
852 void NextPos() { nAktSwPos
= SearchNext( nAktSwPos
+ 1 ); }
854 void OutAttr( xub_StrLen nSwPos
);
855 virtual const SfxPoolItem
* HasTextItem( USHORT nWhich
) const;
856 virtual const SfxPoolItem
& GetItem( USHORT nWhich
) const;
857 bool OutAttrWithRange(xub_StrLen nPos
);
858 xub_StrLen
WhereNext() const { return nAktSwPos
; }
859 rtl_TextEncoding
GetNextCharSet() const;
860 rtl_TextEncoding
GetNodeCharSet() const { return eNdChrSet
; }
864 WW8_SdrAttrIter::WW8_SdrAttrIter( WW8Export
& rWr
,
865 const EditTextObject
& rEditObj
, BYTE nTyp
)
866 : MSWordAttrIter( rWr
), pEditObj(&rEditObj
), pEditPool(0),
867 aTxtAtrArr( 0, 4 ), aChrTxtAtrArr( 0, 4 ), aChrSetArr( 0, 4 ),
873 void WW8_SdrAttrIter::NextPara( USHORT nPar
)
876 // Attributwechsel an Pos 0 wird ignoriert, da davon ausgegangen
877 // wird, dass am Absatzanfang sowieso die Attribute neu ausgegeben
879 aChrTxtAtrArr
.Remove( 0, aChrTxtAtrArr
.Count() );
880 aChrSetArr
.Remove( 0, aChrSetArr
.Count() );
881 nAktSwPos
= nTmpSwPos
= 0;
883 SfxItemSet
aSet( pEditObj
->GetParaAttribs( nPara
));
884 pEditPool
= aSet
.GetPool();
885 eNdChrSet
= ItemGet
<SvxFontItem
>(aSet
,EE_CHAR_FONTINFO
).GetCharSet();
887 if( pBreakIt
->GetBreakIter().is() )
888 nScript
= pBreakIt
->GetBreakIter()->getScriptType( pEditObj
->GetText(nPara
), 0);
890 nScript
= i18n::ScriptType::LATIN
;
892 pEditObj
->GetCharAttribs( nPara
, aTxtAtrArr
);
893 nAktSwPos
= SearchNext( 1 );
896 rtl_TextEncoding
WW8_SdrAttrIter::GetNextCharSet() const
898 if( aChrSetArr
.Count() )
899 return (rtl_TextEncoding
)aChrSetArr
[ aChrSetArr
.Count() - 1 ];
903 // der erste Parameter in SearchNext() liefert zurueck, ob es ein TxtAtr ist.
904 xub_StrLen
WW8_SdrAttrIter::SearchNext( xub_StrLen nStartPos
)
907 xub_StrLen nMinPos
= STRING_MAXLEN
;
910 for( i
= 0; i
< aTxtAtrArr
.Count(); i
++ )
912 const EECharAttrib
& rHt
= aTxtAtrArr
[ i
];
913 nPos
= rHt
.nStart
; // gibt erstes Attr-Zeichen
914 if( nPos
>= nStartPos
&& nPos
<= nMinPos
)
917 SetCharSet(rHt
, true);
920 //?? if( pHt->GetEnd() ) // Attr mit Ende
922 nPos
= rHt
.nEnd
; // gibt letztes Attr-Zeichen + 1
923 if( nPos
>= nStartPos
&& nPos
< nMinPos
)
926 SetCharSet(rHt
, false);
931 nPos = rHt.nStart + 1; // Laenge 1 wegen CH_TXTATR im Text
932 if( nPos >= nStartPos && nPos < nMinPos )
935 SetCharSet(rHt, false);
943 void WW8_SdrAttrIter::SetCharSet(const EECharAttrib
& rAttr
, bool bStart
)
946 rtl_TextEncoding eChrSet
;
947 const SfxPoolItem
& rItem
= *rAttr
.pAttr
;
948 switch( rItem
.Which() )
950 case EE_CHAR_FONTINFO
:
952 eChrSet
= ((SvxFontItem
&)rItem
).GetCharSet();
961 nPos
= aChrSetArr
.Count();
962 aChrSetArr
.Insert( eChrSet
, nPos
);
963 aChrTxtAtrArr
.Insert( p
, nPos
);
965 else if( USHRT_MAX
!= ( nPos
= aChrTxtAtrArr
.GetPos( p
)) )
967 aChrTxtAtrArr
.Remove( nPos
);
968 aChrSetArr
.Remove( nPos
);
973 void WW8_SdrAttrIter::OutEEField(const SfxPoolItem
& rHt
)
975 const SvxFieldItem
&rField
= (const SvxFieldItem
&)rHt
;
976 const SvxFieldData
*pFld
= rField
.GetField();
977 if (pFld
&& pFld
->ISA(SvxURLField
))
979 BYTE nOldTxtTyp
= m_rExport
.nTxtTyp
;
980 m_rExport
.nTxtTyp
= mnTyp
;
981 const SvxURLField
*pURL
= (const SvxURLField
*)pFld
;
982 m_rExport
.AttrOutput().StartURL( pURL
->GetURL(), pURL
->GetTargetFrame() );
984 const String
&rStr
= pURL
->GetRepresentation();
985 m_rExport
.AttrOutput().RawText( rStr
, true, GetNodeCharSet() ); // FIXME kendy: is the 'true' actually correct here? It was here before, but... ;-)
987 m_rExport
.AttrOutput().EndURL();
988 m_rExport
.nTxtTyp
= nOldTxtTyp
;
992 void WW8_SdrAttrIter::OutAttr( xub_StrLen nSwPos
)
996 if( aTxtAtrArr
.Count() )
998 const SwModify
* pOldMod
= m_rExport
.pOutFmtNode
;
999 m_rExport
.pOutFmtNode
= 0;
1001 const SfxItemPool
* pSrcPool
= pEditPool
;
1002 const SfxItemPool
& rDstPool
= m_rExport
.pDoc
->GetAttrPool();
1005 USHORT i
, nWhich
, nSlotId
;
1006 for( i
= 0; i
< aTxtAtrArr
.Count(); i
++ )
1008 const EECharAttrib
& rHt
= aTxtAtrArr
[ i
];
1009 if (nSwPos
>= rHt
.nStart
&& nSwPos
< rHt
.nEnd
)
1011 nWhich
= rHt
.pAttr
->Which();
1012 if (nWhich
== EE_FEATURE_FIELD
)
1014 OutEEField(*rHt
.pAttr
);
1017 else if (nWhich
== EE_FEATURE_TAB
)
1019 m_rExport
.WriteChar(0x9);
1022 nSlotId
= pSrcPool
->GetSlotId(nWhich
);
1024 if (nSlotId
&& nWhich
!= nSlotId
)
1026 nWhich
= rDstPool
.GetWhich(nSlotId
);
1027 if (nWhich
&& nWhich
!= nSlotId
&&
1028 nWhich
< RES_UNKNOWNATR_BEGIN
&&
1029 m_rExport
.CollapseScriptsforWordOk(nScript
,nWhich
))
1031 // use always the SW-Which Id !
1032 SfxPoolItem
* pI
= rHt
.pAttr
->Clone();
1033 pI
->SetWhich( nWhich
);
1034 m_rExport
.AttrOutput().OutputItem( *pI
);
1040 if( nSwPos
< rHt
.nStart
)
1044 nTmpSwPos
= 0; // HasTextItem nur in dem obigen Bereich erlaubt
1045 m_rExport
.pOutFmtNode
= pOldMod
;
1049 bool WW8_SdrAttrIter::IsTxtAttr(xub_StrLen nSwPos
)
1051 for (USHORT i
= 0; i
< aTxtAtrArr
.Count(); ++i
)
1053 const EECharAttrib
& rHt
= aTxtAtrArr
[ i
];
1054 if (nSwPos
>= rHt
.nStart
&& nSwPos
< rHt
.nEnd
)
1057 (rHt
.pAttr
->Which() == EE_FEATURE_FIELD
) ||
1058 (rHt
.pAttr
->Which() == EE_FEATURE_TAB
)
1068 // HasItem ist fuer die Zusammenfassung des Doppel-Attributes Underline
1069 // und WordLineMode als TextItems. OutAttr() ruft die Ausgabefunktion,
1070 // die dann ueber HasItem() nach anderen Items an der
1071 // Attribut-Anfangposition fragen kann.
1072 // Es koennen nur Attribute mit Ende abgefragt werden.
1073 // Es wird mit bDeep gesucht
1074 const SfxPoolItem
* WW8_SdrAttrIter::HasTextItem(USHORT nWhich
) const
1076 const SfxPoolItem
* pRet
= 0;
1077 nWhich
= sw::hack::TransformWhichBetweenPools(*pEditPool
,
1078 m_rExport
.pDoc
->GetAttrPool(), nWhich
);
1081 for (USHORT i
= 0; i
< aTxtAtrArr
.Count(); ++i
)
1083 const EECharAttrib
& rHt
= aTxtAtrArr
[i
];
1085 nWhich
== rHt
.pAttr
->Which() && nTmpSwPos
>= rHt
.nStart
&&
1086 nTmpSwPos
< rHt
.nEnd
1089 pRet
= rHt
.pAttr
; // Found
1092 else if (nTmpSwPos
< rHt
.nStart
)
1093 break; // dann kommt da nichts mehr
1099 const SfxPoolItem
& WW8_SdrAttrIter::GetItem( USHORT nWhich
) const
1101 using sw::hack::GetSetWhichFromSwDocWhich
;
1102 const SfxPoolItem
* pRet
= HasTextItem(nWhich
);
1105 SfxItemSet
aSet(pEditObj
->GetParaAttribs(nPara
));
1106 nWhich
= GetSetWhichFromSwDocWhich(aSet
, *m_rExport
.pDoc
, nWhich
);
1107 ASSERT(nWhich
, "Impossible, catastrophic failure imminent");
1108 pRet
= &aSet
.Get(nWhich
);
1113 void WW8_SdrAttrIter::OutParaAttr(bool bCharAttr
)
1115 SfxItemSet
aSet( pEditObj
->GetParaAttribs( nPara
));
1118 const SfxItemSet
* pOldSet
= m_rExport
.GetCurItemSet();
1119 m_rExport
.SetCurItemSet( &aSet
);
1121 SfxItemIter
aIter( aSet
);
1122 const SfxPoolItem
* pItem
= aIter
.GetCurItem();
1124 const SfxItemPool
* pSrcPool
= pEditPool
,
1125 * pDstPool
= &m_rExport
.pDoc
->GetAttrPool();
1128 USHORT nWhich
= pItem
->Which(),
1129 nSlotId
= pSrcPool
->GetSlotId( nWhich
);
1131 if ( nSlotId
&& nWhich
!= nSlotId
&&
1132 0 != ( nWhich
= pDstPool
->GetWhich( nSlotId
) ) &&
1133 nWhich
!= nSlotId
&&
1134 ( bCharAttr
? ( nWhich
>= RES_CHRATR_BEGIN
&& nWhich
< RES_TXTATR_END
)
1135 : ( nWhich
>= RES_PARATR_BEGIN
&& nWhich
< RES_FRMATR_END
) ) )
1137 // use always the SW-Which Id !
1138 SfxPoolItem
* pI
= pItem
->Clone();
1139 pI
->SetWhich( nWhich
);
1140 if (m_rExport
.CollapseScriptsforWordOk(nScript
,nWhich
))
1141 m_rExport
.AttrOutput().OutputItem( *pI
);
1144 } while( !aIter
.IsAtEnd() && 0 != ( pItem
= aIter
.NextItem() ) );
1145 m_rExport
.SetCurItemSet( pOldSet
);
1149 void WW8Export::WriteSdrTextObj(const SdrObject
& rObj
, BYTE nTyp
)
1151 const SdrTextObj
* pTxtObj
= PTR_CAST(SdrTextObj
, &rObj
);
1152 ASSERT(pTxtObj
, "That is no SdrTextObj!");
1156 const OutlinerParaObject
* pParaObj
= 0;
1157 bool bOwnParaObj
= false;
1161 When the object is actively being edited, that text is not set into
1162 the objects normal text object, but lives in a seperate object.
1164 if (pTxtObj
->IsTextEditActive())
1166 pParaObj
= pTxtObj
->GetEditOutlinerParaObject();
1171 pParaObj
= pTxtObj
->GetOutlinerParaObject();
1176 WriteOutliner(*pParaObj
, nTyp
);
1182 void WW8Export::WriteOutliner(const OutlinerParaObject
& rParaObj
, BYTE nTyp
)
1184 bool bAnyWrite
= false;
1185 const EditTextObject
& rEditObj
= rParaObj
.GetTextObject();
1186 WW8_SdrAttrIter
aAttrIter( *this, rEditObj
, nTyp
);
1188 USHORT nPara
= rEditObj
.GetParagraphCount();
1190 for( USHORT n
= 0; n
< nPara
; ++n
)
1193 aAttrIter
.NextPara( n
);
1195 rtl_TextEncoding eChrSet
= aAttrIter
.GetNodeCharSet();
1197 ASSERT( !pO
->Count(), " pO ist am Zeilenanfang nicht leer" );
1199 String
aStr( rEditObj
.GetText( n
));
1200 xub_StrLen nAktPos
= 0;
1201 xub_StrLen nEnd
= aStr
.Len();
1203 xub_StrLen nNextAttr
= aAttrIter
.WhereNext();
1204 rtl_TextEncoding eNextChrSet
= aAttrIter
.GetNextCharSet();
1206 if( nNextAttr
> nEnd
)
1209 bool bTxtAtr
= aAttrIter
.IsTxtAttr( nAktPos
);
1211 OutSwString( aStr
, nAktPos
, nNextAttr
- nAktPos
,
1214 // Am Zeilenende werden die Attribute bis ueber das CR
1215 // aufgezogen. Ausnahme: Fussnoten am Zeilenende
1216 if( nNextAttr
== nEnd
&& !bTxtAtr
)
1217 WriteCR(); // CR danach
1219 // Ausgabe der Zeichenattribute
1220 aAttrIter
.OutAttr( nAktPos
); // nAktPos - 1 ??
1221 pChpPlc
->AppendFkpEntry( Strm().Tell(),
1222 pO
->Count(), pO
->GetData() );
1223 pO
->Remove( 0, pO
->Count() ); // leeren
1225 // Ausnahme: Fussnoten am Zeilenende
1226 if( nNextAttr
== nEnd
&& bTxtAtr
)
1227 WriteCR(); // CR danach
1228 nAktPos
= nNextAttr
;
1229 eChrSet
= eNextChrSet
;
1230 aAttrIter
.NextPos();
1232 while( nAktPos
< nEnd
);
1234 ASSERT( !pO
->Count(), " pO ist am ZeilenEnde nicht leer" );
1236 pO
->Insert( bNul
, pO
->Count() ); // Style # as short
1237 pO
->Insert( bNul
, pO
->Count() );
1239 aAttrIter
.OutParaAttr(false);
1241 ULONG nPos
= Strm().Tell();
1242 pPapPlc
->AppendFkpEntry( Strm().Tell(),
1243 pO
->Count(), pO
->GetData() );
1244 pO
->Remove( 0, pO
->Count() ); // leeren
1245 pChpPlc
->AppendFkpEntry( nPos
);
1248 bAnyWrite
= 0 != nPara
;
1250 WriteStringAsPara( aEmptyStr
);
1253 void WinwordAnchoring::WriteData( EscherEx
& rEx
) const
1255 //Toplevel groups get their winword extra data attached, and sub elements
1257 if (rEx
.GetGroupLevel() <= 1)
1259 SvStream
& rSt
= rEx
.GetStream();
1260 //The last argument denotes the number of sub properties in this atom
1263 rEx
.AddAtom(18, DFF_msofbtUDefProp
, 3, 3); //Prop id is 0xF122
1264 rSt
<< (UINT16
)0x0390 << sal_uInt32(3);
1265 rSt
<< (UINT16
)0x0392 << sal_uInt32(3);
1266 //This sub property is required to be in the dummy inline frame as
1268 rSt
<< (UINT16
)0x053F << nInlineHack
;
1272 rEx
.AddAtom(24, DFF_msofbtUDefProp
, 3, 4 ); //Prop id is 0xF122
1273 rSt
<< (UINT16
)0x038F << mnXAlign
;
1274 rSt
<< (UINT16
)0x0390 << mnXRelTo
;
1275 rSt
<< (UINT16
)0x0391 << mnYAlign
;
1276 rSt
<< (UINT16
)0x0392 << mnYRelTo
;
1283 void WW8Export::CreateEscher()
1285 SfxItemState eBackSet
=
1286 (const_cast<const SwDoc
*>(pDoc
))->GetPageDesc(0).GetMaster().
1287 GetItemState(RES_BACKGROUND
);
1288 if (pHFSdrObjs
->size() || pSdrObjs
->size() || SFX_ITEM_SET
== eBackSet
)
1290 ASSERT( !pEscher
, "wer hat den Pointer nicht geloescht?" );
1291 SvMemoryStream
* pEscherStrm
= new SvMemoryStream
;
1292 pEscherStrm
->SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN
);
1293 pEscher
= new SwEscherEx(pEscherStrm
, *this);
1297 void WW8Export::WriteEscher()
1301 ULONG nStart
= pTableStrm
->Tell();
1303 pEscher
->WritePictures();
1304 pEscher
->FinishEscher();
1306 pFib
->fcDggInfo
= nStart
;
1307 pFib
->lcbDggInfo
= pTableStrm
->Tell() - nStart
;
1308 delete pEscher
, pEscher
= 0;
1312 void SwEscherEx::WritePictures()
1316 // set the blip - entries to the correct stream pos
1317 INT32 nEndPos
= rWrt
.Strm().Tell();
1318 SetNewBlipStreamOffset( nEndPos
);
1320 pPictStrm
->Seek( 0 );
1321 rWrt
.Strm() << *pPictStrm
;
1323 delete pPictStrm
, pPictStrm
= 0;
1330 // Output- Routines for Escher Export
1332 SwBasicEscherEx::SwBasicEscherEx(SvStream
* pStrm
, WW8Export
& rWW8Wrt
,
1334 : EscherEx(*pStrm
, nDrawings
), rWrt(rWW8Wrt
), pEscherStrm(pStrm
),
1340 SwBasicEscherEx::~SwBasicEscherEx()
1344 void SwBasicEscherEx::WriteFrmExtraData(const SwFrmFmt
&)
1346 AddAtom(4, ESCHER_ClientAnchor
);
1347 GetStream() << (sal_uInt32
)0x80000000;
1350 void SwBasicEscherEx::WriteEmptyFlyFrame(const SwFrmFmt
& rFmt
, UINT32 nShapeId
)
1352 OpenContainer(ESCHER_SpContainer
);
1353 AddShape(ESCHER_ShpInst_PictureFrame
, 0xa00, nShapeId
);
1354 // store anchor attribute
1355 WriteFrmExtraData(rFmt
);
1357 AddAtom(6, DFF_msofbtUDefProp
, 3, 1); //Prop id is 0xF122
1358 GetStream() << (UINT16
)0x053F << nInlineHack
;
1360 CloseContainer(); // ESCHER_SpContainer
1363 UINT32
AddMirrorFlags(UINT32 nFlags
, const SwMirrorGrf
&rMirror
)
1365 switch (rMirror
.GetValue())
1368 case RES_MIRROR_GRAPH_DONT
:
1370 case RES_MIRROR_GRAPH_VERT
:
1371 nFlags
|= SHAPEFLAG_FLIPH
;
1373 case RES_MIRROR_GRAPH_HOR
:
1374 nFlags
|= SHAPEFLAG_FLIPV
;
1376 case RES_MIRROR_GRAPH_BOTH
:
1377 nFlags
|= SHAPEFLAG_FLIPH
;
1378 nFlags
|= SHAPEFLAG_FLIPV
;
1385 INT32
SwBasicEscherEx::WriteGrfFlyFrame(const SwFrmFmt
& rFmt
, UINT32 nShapeId
)
1387 INT32 nBorderThick
=0;
1388 SwNoTxtNode
*pNd
= GetNoTxtNodeFromSwFrmFmt(rFmt
);
1389 SwGrfNode
*pGrfNd
= pNd
? pNd
->GetGrfNode() : 0;
1390 ASSERT(pGrfNd
, "No SwGrfNode ?, suspicious");
1392 return nBorderThick
;
1394 OpenContainer( ESCHER_SpContainer
);
1396 const SwMirrorGrf
&rMirror
= pGrfNd
->GetSwAttrSet().GetMirrorGrf();
1397 AddShape(ESCHER_ShpInst_PictureFrame
, AddMirrorFlags(0xa00, rMirror
),
1400 EscherPropertyContainer aPropOpt
;
1402 UINT32 nFlags
= ESCHER_BlipFlagDefault
;
1404 if (pGrfNd
->IsLinkedFile())
1407 pGrfNd
->GetFileFilterNms( &sURL
, 0 );
1410 SwWW8Writer::InsAsString16( aBuf
, sURL
);
1411 SwWW8Writer::InsUInt16( aBuf
, 0 );
1413 USHORT nArrLen
= aBuf
.Count();
1414 BYTE
* pArr
= new BYTE
[ nArrLen
];
1415 memcpy( pArr
, aBuf
.GetData(), nArrLen
);
1417 aPropOpt
.AddOpt(ESCHER_Prop_pibName
, true, nArrLen
, pArr
, nArrLen
);
1418 nFlags
= ESCHER_BlipFlagLinkToFile
| ESCHER_BlipFlagURL
|
1419 ESCHER_BlipFlagDoNotSave
;
1423 pGrfNd
->SwapIn(true);
1425 Graphic
aGraphic(pGrfNd
->GetGrf());
1426 GraphicObject
aGraphicObject( aGraphic
);
1427 ByteString aUniqueId
= aGraphicObject
.GetUniqueID();
1429 if ( aUniqueId
.Len() )
1431 const MapMode
aMap100mm( MAP_100TH_MM
);
1432 Size
aSize( aGraphic
.GetPrefSize() );
1434 if ( MAP_PIXEL
== aGraphic
.GetPrefMapMode().GetMapUnit() )
1436 aSize
= Application::GetDefaultDevice()->PixelToLogic(
1441 aSize
= OutputDevice::LogicToLogic( aSize
,
1442 aGraphic
.GetPrefMapMode(), aMap100mm
);
1445 Point aEmptyPoint
= Point();
1446 Rectangle
aRect( aEmptyPoint
, aSize
);
1448 sal_uInt32 nBlibId
= GetBlibID( *QueryPicStream(), aUniqueId
,
1451 aPropOpt
.AddOpt(ESCHER_Prop_pib
, nBlibId
, sal_True
);
1455 aPropOpt
.AddOpt( ESCHER_Prop_pibFlags
, nFlags
);
1456 nBorderThick
= WriteFlyFrameAttr(rFmt
,mso_sptPictureFrame
,aPropOpt
);
1457 WriteGrfAttr(*pGrfNd
, aPropOpt
);
1459 aPropOpt
.Commit( GetStream() );
1461 // store anchor attribute
1462 WriteFrmExtraData( rFmt
);
1464 CloseContainer(); // ESCHER_SpContainer
1465 return nBorderThick
;
1468 void SwBasicEscherEx::WriteGrfAttr(const SwNoTxtNode
& rNd
,
1469 EscherPropertyContainer
& rPropOpt
)
1471 const SfxPoolItem
* pItem
;
1472 sal_uInt32 nMode
= GRAPHICDRAWMODE_STANDARD
;
1473 sal_Int32 nContrast
= 0;
1474 sal_Int16 nBrightness
= 0;
1476 if (SFX_ITEM_SET
== rNd
.GetSwAttrSet().GetItemState(RES_GRFATR_CONTRAST
,
1479 nContrast
= ((SfxInt16Item
*)pItem
)->GetValue();
1482 if (SFX_ITEM_SET
== rNd
.GetSwAttrSet().GetItemState(RES_GRFATR_LUMINANCE
,
1485 nBrightness
= ((SfxInt16Item
*)pItem
)->GetValue();
1489 if (SFX_ITEM_SET
== rNd
.GetSwAttrSet().GetItemState(RES_GRFATR_DRAWMODE
,
1492 nMode
= ((SfxEnumItem
*)pItem
)->GetValue();
1493 if (nMode
== GRAPHICDRAWMODE_WATERMARK
)
1496 There is no real watermark mode in word, we must use standard
1497 mode and modify our ones by 70% extra brightness and 70% less
1498 contrast. This means that unmodified default OOo watermark
1499 will turn back into watermark, and modified OOo watermark will
1500 change into a close visual representation in standardmode
1503 if (nBrightness
> 100)
1506 if (nContrast
< -100)
1508 nMode
= GRAPHICDRAWMODE_STANDARD
;
1512 if (nMode
== GRAPHICDRAWMODE_GREYS
)
1514 else if (nMode
== GRAPHICDRAWMODE_MONO
)
1518 rPropOpt
.AddOpt( ESCHER_Prop_pictureActive
, nMode
);
1523 if (nContrast
== 100)
1524 nContrast
= 0x10000;
1525 else if (nContrast
< 100)
1527 nContrast
*= 0x10000;
1530 else if (nContrast
< 200)
1531 nContrast
= (100 * 0x10000) / (200-nContrast
);
1533 nContrast
= 0x7fffffff;
1534 rPropOpt
.AddOpt( ESCHER_Prop_pictureContrast
, nContrast
);
1537 if (nBrightness
!= 0)
1538 rPropOpt
.AddOpt( ESCHER_Prop_pictureBrightness
, nBrightness
* 327 );
1540 if (SFX_ITEM_SET
== rNd
.GetSwAttrSet().GetItemState(RES_GRFATR_CROPGRF
,
1543 const Size
aSz( rNd
.GetTwipSize() );
1545 if( 0 != ( nVal
= ((SwCropGrf
*)pItem
)->GetLeft() ) )
1546 rPropOpt
.AddOpt( ESCHER_Prop_cropFromLeft
, ToFract16( nVal
, aSz
.Width()) );
1547 if( 0 != ( nVal
= ((SwCropGrf
*)pItem
)->GetRight() ) )
1548 rPropOpt
.AddOpt( ESCHER_Prop_cropFromRight
, ToFract16( nVal
, aSz
.Width()));
1549 if( 0 != ( nVal
= ((SwCropGrf
*)pItem
)->GetTop() ) )
1550 rPropOpt
.AddOpt( ESCHER_Prop_cropFromTop
, ToFract16( nVal
, aSz
.Height()));
1551 if( 0 != ( nVal
= ((SwCropGrf
*)pItem
)->GetBottom() ) )
1552 rPropOpt
.AddOpt( ESCHER_Prop_cropFromBottom
, ToFract16( nVal
, aSz
.Height()));
1556 void SwBasicEscherEx::SetPicId(const SdrObject
&, UINT32
,
1557 EscherPropertyContainer
&)
1561 void SwEscherEx::SetPicId(const SdrObject
&rSdrObj
, UINT32 nShapeId
,
1562 EscherPropertyContainer
&rPropOpt
)
1564 pTxtBxs
->Append(rSdrObj
, nShapeId
);
1565 UINT32 nPicId
= pTxtBxs
->Count();
1567 rPropOpt
.AddOpt( ESCHER_Prop_pictureId
, nPicId
);
1570 INT32
SwBasicEscherEx::WriteOLEFlyFrame(const SwFrmFmt
& rFmt
, UINT32 nShapeId
)
1572 INT32 nBorderThick
= 0;
1573 if (const SdrObject
* pSdrObj
= rFmt
.FindRealSdrObject())
1575 SwNodeIndex
aIdx(*rFmt
.GetCntnt().GetCntntIdx(), 1);
1576 SwOLENode
& rOLENd
= *aIdx
.GetNode().GetOLENode();
1577 sal_Int64 nAspect
= rOLENd
.GetAspect();
1579 uno::Reference
< embed::XEmbeddedObject
> xObj(rOLENd
.GetOLEObj().GetOleRef());
1581 // the rectangle is used to transport the size of the object
1582 // the left, top corner is set to ( 0, 0 ) by default constructor,
1583 // if the width and height are set correctly bRectIsSet should be set to true
1584 awt::Rectangle aRect
;
1585 sal_Bool bRectIsSet
= sal_False
;
1588 // TODO/LATER: should the icon size be stored in case of iconified object?
1589 if ( xObj
.is() && nAspect
!= embed::Aspects::MSOLE_ICON
)
1593 awt::Size aSize
= xObj
->getVisualAreaSize( nAspect
);
1594 aRect
.Width
= aSize
.Width
;
1595 aRect
.Height
= aSize
.Height
;
1596 bRectIsSet
= sal_True
;
1598 catch( uno::Exception
& )
1604 Export floating ole2 .doc ver 8+ wmf ole2 previews as emf previews
1605 instead ==> allows unicode text to be preserved
1607 #ifdef OLE_PREVIEW_AS_EMF
1608 //Graphic aGraphic = wwUtility::MakeSafeGDIMetaFile(xObj);
1609 Graphic
* pGraphic
= rOLENd
.GetGraphic();
1611 OpenContainer(ESCHER_SpContainer
);
1613 EscherPropertyContainer aPropOpt
;
1614 const SwMirrorGrf
&rMirror
= rOLENd
.GetSwAttrSet().GetMirrorGrf();
1615 WriteOLEPicture(aPropOpt
, AddMirrorFlags(0xa00 | SHAPEFLAG_OLESHAPE
,
1616 rMirror
), pGraphic
? *pGraphic
: Graphic(), *pSdrObj
, nShapeId
, bRectIsSet
? &aRect
: NULL
);
1618 nBorderThick
= WriteFlyFrameAttr(rFmt
, mso_sptPictureFrame
, aPropOpt
);
1619 WriteGrfAttr(rOLENd
, aPropOpt
);
1620 aPropOpt
.Commit(GetStream());
1622 // store anchor attribute
1623 WriteFrmExtraData( rFmt
);
1625 CloseContainer(); // ESCHER_SpContainer
1627 return nBorderThick
;
1630 void SwBasicEscherEx::WriteBrushAttr(const SvxBrushItem
&rBrush
,
1631 EscherPropertyContainer
& rPropOpt
)
1633 bool bSetOpacity
= false;
1634 sal_uInt32 nOpaque
= 0;
1635 if (const GraphicObject
*pGraphicObject
= rBrush
.GetGraphicObject())
1637 ByteString aUniqueId
= pGraphicObject
->GetUniqueID();
1638 if (aUniqueId
.Len())
1640 const Graphic
&rGraphic
= pGraphicObject
->GetGraphic();
1641 Size
aSize(rGraphic
.GetPrefSize());
1642 const MapMode
aMap100mm(MAP_100TH_MM
);
1643 if (MAP_PIXEL
== rGraphic
.GetPrefMapMode().GetMapUnit())
1645 aSize
= Application::GetDefaultDevice()->PixelToLogic(
1650 aSize
= OutputDevice::LogicToLogic(aSize
,
1651 rGraphic
.GetPrefMapMode(), aMap100mm
);
1654 Point aEmptyPoint
= Point();
1655 Rectangle
aRect(aEmptyPoint
, aSize
);
1657 sal_uInt32 nBlibId
= GetBlibID(*QueryPicStream(), aUniqueId
,
1660 rPropOpt
.AddOpt(ESCHER_Prop_fillBlip
,nBlibId
,sal_True
);
1663 if (0 != (nOpaque
= pGraphicObject
->GetAttr().GetTransparency()))
1666 rPropOpt
.AddOpt( ESCHER_Prop_fillType
, ESCHER_FillPicture
);
1667 rPropOpt
.AddOpt( ESCHER_Prop_fNoFillHitTest
, 0x140014 );
1668 rPropOpt
.AddOpt( ESCHER_Prop_fillBackColor
, 0 );
1672 UINT32 nFillColor
= GetColor(rBrush
.GetColor(), false);
1673 rPropOpt
.AddOpt( ESCHER_Prop_fillColor
, nFillColor
);
1674 rPropOpt
.AddOpt( ESCHER_Prop_fillBackColor
, nFillColor
^ 0xffffff );
1675 rPropOpt
.AddOpt( ESCHER_Prop_fNoFillHitTest
, 0x100010 );
1677 if (0 != (nOpaque
= rBrush
.GetColor().GetTransparency()))
1683 nOpaque
= (nOpaque
* 100) / 0xFE;
1684 nOpaque
= ((100 - nOpaque
) << 16) / 100;
1685 rPropOpt
.AddOpt(ESCHER_Prop_fillOpacity
, nOpaque
);
1689 INT32
SwBasicEscherEx::WriteFlyFrameAttr(const SwFrmFmt
& rFmt
,
1690 MSO_SPT eShapeType
, EscherPropertyContainer
& rPropOpt
)
1693 const SfxPoolItem
* pItem
;
1694 bool bFirstLine
= true;
1695 if (SFX_ITEM_SET
== rFmt
.GetItemState(RES_BOX
, true, &pItem
))
1697 static const UINT16 aExhperProp
[4] =
1699 ESCHER_Prop_dyTextTop
, ESCHER_Prop_dyTextBottom
,
1700 ESCHER_Prop_dxTextLeft
, ESCHER_Prop_dxTextRight
1702 const SvxBorderLine
* pLine
;
1704 for( USHORT n
= 0; n
< 4; ++n
)
1705 if( 0 != ( pLine
= ((SvxBoxItem
*)pItem
)->GetLine( n
)) )
1709 UINT32 nLineColor
= GetColor(pLine
->GetColor(), false);
1710 rPropOpt
.AddOpt( ESCHER_Prop_lineColor
, nLineColor
);
1711 rPropOpt
.AddOpt( ESCHER_Prop_lineBackColor
,
1712 nLineColor
^ 0xffffff );
1714 MSO_LineStyle eStyle
;
1715 if( pLine
->GetInWidth() )
1718 nLineWidth
= pLine
->GetInWidth() + pLine
->GetOutWidth()
1719 + pLine
->GetDistance();
1720 if( pLine
->GetInWidth() == pLine
->GetOutWidth() )
1721 eStyle
= mso_lineDouble
;
1722 else if( pLine
->GetInWidth() < pLine
->GetOutWidth() )
1723 eStyle
= mso_lineThickThin
;
1725 eStyle
= mso_lineThinThick
;
1730 eStyle
= mso_lineSimple
;
1731 nLineWidth
= pLine
->GetOutWidth();
1734 rPropOpt
.AddOpt( ESCHER_Prop_lineStyle
, eStyle
);
1735 rPropOpt
.AddOpt( ESCHER_Prop_lineWidth
,
1736 DrawModelToEmu( nLineWidth
));
1737 rPropOpt
.AddOpt( ESCHER_Prop_fNoLineDrawDash
, 0x8000E );
1739 //Use import logic to determine how much of border will go
1741 nLineWidth
= SwMSDffManager::GetEscherLineMatch(
1742 eStyle
,eShapeType
,nLineWidth
);
1745 rPropOpt
.AddOpt( aExhperProp
[ n
], DrawModelToEmu(
1746 ((SvxBoxItem
*)pItem
)->GetDistance( n
) ));
1749 // MM If there is no line the distance should be set to 0
1750 rPropOpt
.AddOpt( aExhperProp
[ n
], DrawModelToEmu(0));
1752 if( bFirstLine
) // no valid line found
1754 rPropOpt
.AddOpt( ESCHER_Prop_fNoLineDrawDash
, 0x80000 );
1755 rPropOpt
.AddOpt( ESCHER_Prop_dyTextTop
, 0 );
1756 rPropOpt
.AddOpt( ESCHER_Prop_dyTextBottom
, 0 );
1757 rPropOpt
.AddOpt( ESCHER_Prop_dxTextLeft
, 0 );
1758 rPropOpt
.AddOpt( ESCHER_Prop_dxTextRight
, 0 );
1761 SvxBrushItem
aBrush(rWrt
.TrueFrameBgBrush(rFmt
));
1762 WriteBrushAttr(aBrush
, rPropOpt
);
1764 const SdrObject
* pObj
= rFmt
.FindRealSdrObject();
1765 if( pObj
&& (pObj
->GetLayer() == GetHellLayerId() ||
1766 pObj
->GetLayer() == GetInvisibleHellId() ))
1768 rPropOpt
.AddOpt( ESCHER_Prop_fPrint
, 0x200020 );
1774 INT32
SwEscherEx::WriteFlyFrameAttr(const SwFrmFmt
& rFmt
, MSO_SPT eShapeType
,
1775 EscherPropertyContainer
& rPropOpt
)
1777 INT32 nLineWidth
= SwBasicEscherEx::WriteFlyFrameAttr(rFmt
, eShapeType
,
1781 These are not in SwBasicEscherEx::WriteFlyFrameAttr because inline objs
1782 can't do it in word and it hacks it in by stretching the graphic that
1783 way, perhaps we should actually draw in this space into the graphic we
1786 const SfxPoolItem
* pItem
;
1787 if (SFX_ITEM_SET
== rFmt
.GetItemState(RES_LR_SPACE
, true, &pItem
))
1789 rPropOpt
.AddOpt( ESCHER_Prop_dxWrapDistLeft
,
1790 DrawModelToEmu( ((SvxLRSpaceItem
*)pItem
)->GetLeft() ) );
1791 rPropOpt
.AddOpt( ESCHER_Prop_dxWrapDistRight
,
1792 DrawModelToEmu( ((SvxLRSpaceItem
*)pItem
)->GetRight() ) );
1796 rPropOpt
.AddOpt( ESCHER_Prop_dxWrapDistLeft
, 0 );
1797 rPropOpt
.AddOpt( ESCHER_Prop_dxWrapDistRight
, 0 );
1800 if (SFX_ITEM_SET
== rFmt
.GetItemState(RES_UL_SPACE
, true, &pItem
))
1802 rPropOpt
.AddOpt( ESCHER_Prop_dyWrapDistTop
,
1803 DrawModelToEmu( ((SvxULSpaceItem
*)pItem
)->GetUpper() ) );
1804 rPropOpt
.AddOpt( ESCHER_Prop_dyWrapDistBottom
,
1805 DrawModelToEmu( ((SvxULSpaceItem
*)pItem
)->GetLower() ) );
1808 if (rFmt
.GetSurround().IsContour())
1810 if (const SwNoTxtNode
*pNd
= GetNoTxtNodeFromSwFrmFmt(rFmt
))
1812 const PolyPolygon
*pPolyPoly
= pNd
->HasContour();
1813 if (pPolyPoly
&& pPolyPoly
->Count())
1815 Polygon
aPoly(PolygonFromPolyPolygon(*pPolyPoly
));
1816 const Size
&rOrigSize
= pNd
->GetGraphic().GetPrefSize();
1817 Fraction
aMapPolyX(ww::nWrap100Percent
, rOrigSize
.Width());
1818 Fraction
aMapPolyY(ww::nWrap100Percent
, rOrigSize
.Height());
1819 aPoly
.Scale(aMapPolyX
, aMapPolyY
);
1822 a) stretch right bound by 15twips
1823 b) shrink bottom bound to where it would have been in word
1824 c) Move it to the left by 15twips
1826 See the import for details
1828 const Size
&rSize
= pNd
->GetTwipSize();
1829 Fraction
aMoveHack(ww::nWrap100Percent
, rSize
.Width());
1830 aMoveHack
*= Fraction(15, 1);
1831 long nMove(aMoveHack
);
1833 Fraction
aHackX(ww::nWrap100Percent
+ nMove
,
1834 ww::nWrap100Percent
);
1835 Fraction
aHackY(ww::nWrap100Percent
- nMove
,
1836 ww::nWrap100Percent
);
1837 aPoly
.Scale(aHackX
, aHackY
);
1839 aPoly
.Move(-nMove
, 0);
1841 SvMemoryStream aPolyDump
;
1842 aPolyDump
.SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN
);
1844 sal_uInt16 nLen
= aPoly
.GetSize();
1847 aPolyDump
<< sal_uInt16(8);
1848 for (sal_uInt16 nI
= 0; nI
< nLen
; ++nI
)
1850 aPolyDump
<< sal_uInt32(aPoly
[nI
].X());
1851 aPolyDump
<< sal_uInt32(aPoly
[nI
].Y());
1854 sal_uInt16 nArrLen
= msword_cast
<sal_uInt16
>(aPolyDump
.Tell());
1855 void *pArr
= const_cast<void *>(aPolyDump
.GetData());
1856 //PropOpt wants to own the buffer
1857 aPolyDump
.ObjectOwnsMemory(false);
1858 rPropOpt
.AddOpt(DFF_Prop_pWrapPolygonVertices
, false,
1859 nArrLen
, static_cast<BYTE
*>(pArr
), nArrLen
);
1867 void SwBasicEscherEx::Init()
1869 MapUnit eMap
= MAP_TWIP
;
1870 if (SdrModel
*pModel
= rWrt
.pDoc
->GetDrawModel())
1872 // PPT arbeitet nur mit Einheiten zu 576DPI
1873 // WW hingegen verwendet twips, dh. 1440DPI.
1874 eMap
= pModel
->GetScaleUnit();
1877 // MS-DFF-Properties sind grossteils in EMU (English Metric Units) angegeben
1878 // 1mm=36000emu, 1twip=635emu
1879 Fraction
aFact(360, 1);
1880 aFact
/= GetMapFactor(MAP_100TH_MM
, eMap
).X();
1881 // create little values
1882 aFact
= Fraction(aFact
.GetNumerator(), aFact
.GetDenominator());
1883 mnEmuMul
= aFact
.GetNumerator();
1884 mnEmuDiv
= aFact
.GetDenominator();
1886 SetHellLayerId(rWrt
.pDoc
->GetHellId());
1889 INT32
SwBasicEscherEx::ToFract16(INT32 nVal
, UINT32 nMax
) const
1893 INT32 nMSVal
= (nVal
/ 65536) * nMax
;
1894 nMSVal
+= (nVal
* 65536 ) / nMax
;
1900 SvStream
* SwBasicEscherEx::QueryPicStream()
1904 pPictStrm
= new SvMemoryStream
;
1905 pPictStrm
->SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN
);
1910 SdrLayerID
SwBasicEscherEx::GetInvisibleHellId() const
1912 return rWrt
.pDoc
->GetInvisibleHellId();
1915 void SwBasicEscherEx::WritePictures()
1917 ASSERT(pPictStrm
, "no picture!");
1920 // set the blip - entries to the correct stream pos
1921 INT32 nEndPos
= pPictStrm
->Tell();
1922 WriteBlibStoreEntry(*pEscherStrm
, 1, sal_True
, nEndPos
);
1925 *pEscherStrm
<< *pPictStrm
;
1927 delete pPictStrm
, pPictStrm
= 0;
1931 SwEscherEx::SwEscherEx(SvStream
* pStrm
, WW8Export
& rWW8Wrt
)
1932 : SwBasicEscherEx(pStrm
, rWW8Wrt
, rWW8Wrt
.pHFSdrObjs
->size() ? 2 : 1),
1935 aHostData
.SetClientData(&aWinwordAnchoring
);
1936 OpenContainer( ESCHER_DggContainer
);
1938 sal_uInt16 nColorCount
= 4;
1939 *pStrm
<< (sal_uInt16
)( nColorCount
<< 4 ) // instance
1940 << (sal_uInt16
)ESCHER_SplitMenuColors
// record type
1941 << (sal_uInt32
)( nColorCount
* 4 ) // size
1942 << (sal_uInt32
)0x08000004
1943 << (sal_uInt32
)0x08000001
1944 << (sal_uInt32
)0x08000002
1945 << (sal_uInt32
)0x100000f7;
1947 CloseContainer(); // ESCHER_DggContainer
1949 BYTE i
= 2; // for header/footer and the other
1950 PlcDrawObj
*pSdrObjs
= rWrt
.pHFSdrObjs
;
1951 pTxtBxs
= rWrt
.pHFTxtBxs
;
1953 // if no header/footer -> skip over
1954 if (!pSdrObjs
->size())
1957 pSdrObjs
= rWrt
.pSdrObjs
;
1958 pTxtBxs
= rWrt
.pTxtBxs
;
1961 for( ; i
--; pSdrObjs
= rWrt
.pSdrObjs
, pTxtBxs
= rWrt
.pTxtBxs
)
1963 // "dummy char" (or any Count ?) - why? This knows only M$
1964 GetStream() << (sal_Char
)i
;
1966 OpenContainer( ESCHER_DgContainer
);
1970 ULONG nSecondShapeId
= pSdrObjs
== rWrt
.pSdrObjs
? GetShapeID() : 0;
1972 // write now all Writer-/DrawObjects
1973 DrawObjPointerVector aSorted
;
1974 MakeZOrderArrAndFollowIds(pSdrObjs
->GetObjArr(), aSorted
);
1976 sal_uInt32 nShapeId
=0;
1977 DrawObjPointerIter aEnd
= aSorted
.end();
1978 for (DrawObjPointerIter aIter
= aSorted
.begin(); aIter
!= aEnd
; ++aIter
)
1980 INT32 nBorderThick
=0;
1981 DrawObj
*pObj
= (*aIter
);
1982 ASSERT(pObj
, "impossible");
1985 const sw::Frame
&rFrame
= pObj
->maCntnt
;
1986 const SwFrmFmt
& rFmt
= rFrame
.GetFrmFmt();
1988 switch (rFrame
.GetWriterType())
1990 case sw::Frame::eTxtBox
:
1991 case sw::Frame::eOle
:
1992 case sw::Frame::eGraphic
:
1993 nBorderThick
= WriteFlyFrm(*pObj
, nShapeId
, aSorted
);
1995 case sw::Frame::eFormControl
:
1996 WriteOCXControl(rFmt
, nShapeId
=GetShapeID());
1998 case sw::Frame::eDrawing
:
1999 aWinwordAnchoring
.SetAnchoring(rFmt
);
2000 const SdrObject
* pSdrObj
= rFmt
.FindRealSdrObject();
2003 bool bSwapInPage
= false;
2004 if (!pSdrObj
->GetPage())
2006 if (SdrModel
* pModel
= rWrt
.pDoc
->GetDrawModel())
2008 if (SdrPage
*pPage
= pModel
->GetPage(0))
2011 (const_cast<SdrObject
*>(pSdrObj
))->SetPage(pPage
);
2016 nShapeId
= AddSdrObject(*pSdrObj
);
2019 (const_cast<SdrObject
*>(pSdrObj
))->SetPage(0);
2023 ASSERT( !this, "Where is the SDR-Object?" );
2029 nShapeId
= AddDummyShape();
2032 pObj
->SetShapeDetails(nShapeId
, nBorderThick
);
2035 EndSdrObjectPage(); // ???? Bugfix for 74724
2037 if( nSecondShapeId
)
2039 OpenContainer( ESCHER_SpContainer
);
2041 AddShape( ESCHER_ShpInst_Rectangle
, 0xe00, nSecondShapeId
);
2043 EscherPropertyContainer aPropOpt
;
2044 const SwFrmFmt
&rFmt
= const_cast<const SwDoc
*>(rWrt
.pDoc
)->GetPageDesc(0).GetMaster();
2045 const SfxPoolItem
* pItem
= 0;
2046 SfxItemState eState
= rFmt
.GetItemState(RES_BACKGROUND
, true,
2048 if (SFX_ITEM_SET
== eState
&& pItem
)
2050 const SvxBrushItem
* pBrush
= (const SvxBrushItem
*)pItem
;
2051 WriteBrushAttr(*pBrush
, aPropOpt
);
2053 aPropOpt
.AddOpt( ESCHER_Prop_lineColor
, 0x8000001 );
2054 aPropOpt
.AddOpt( ESCHER_Prop_fNoLineDrawDash
, 0x00080008 );
2055 aPropOpt
.AddOpt( ESCHER_Prop_shadowColor
, 0x8000002 );
2056 aPropOpt
.AddOpt( ESCHER_Prop_lineWidth
, 0 );
2058 // winword defaults!
2059 // aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x100000 );
2060 // aPropOpt.AddOpt( ESCHER_Prop_lineWidth, 0 );
2061 // aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x80000 );
2062 // aPropOpt.AddOpt( ESCHER_Prop_bWMode, 0x9 );
2063 // aPropOpt.AddOpt( ESCHER_Prop_fBackground, 0x10001 );
2065 aPropOpt
.Commit( *pStrm
);
2067 AddAtom( 4, ESCHER_ClientData
);
2070 CloseContainer(); // ESCHER_SpContainer
2072 CloseContainer(); // ESCHER_DgContainer
2076 SwEscherEx::~SwEscherEx()
2080 void SwEscherEx::FinishEscher()
2082 pEscherStrm
->Seek(0);
2083 *rWrt
.pTableStrm
<< *pEscherStrm
;
2084 delete pEscherStrm
, pEscherStrm
= 0;
2087 /** method to perform conversion of positioning attributes with the help
2088 of corresponding layout information
2090 OD 2005-01-06 #i30669#
2091 Because most of the Writer object positions doesn't correspond to the
2092 object positions in WW8, this method converts the positioning
2093 attributes. For this conversion the corresponding layout information
2094 is needed. If no layout information exists - e.g. no layout exists - no
2095 conversion is performed.
2096 No conversion is performed for as-character anchored objects. Whose
2097 object positions are already treated special in method <WriteData(..)>.
2102 input/output parameter - containing the current horizontal position
2103 attributes, which are converted by this method.
2106 input/output parameter - containing the current vertical position
2107 attributes, which are converted by this method.
2110 input parameter - frame format of the anchored object
2112 @return boolean, indicating, if a conversion has been performed.
2114 bool WinwordAnchoring::ConvertPosition( SwFmtHoriOrient
& _iorHoriOri
,
2115 SwFmtVertOrient
& _iorVertOri
,
2116 const SwFrmFmt
& _rFrmFmt
)
2118 const RndStdIds eAnchor
= _rFrmFmt
.GetAnchor().GetAnchorId();
2120 if ( FLY_IN_CNTNT
== eAnchor
|| FLY_AT_FLY
== eAnchor
)
2122 // no conversion for as-character or at frame anchored objects
2126 // determine anchored object
2127 SwAnchoredObject
* pAnchoredObj( 0L );
2129 const SwContact
* pContact
= _rFrmFmt
.FindContactObj();
2132 std::vector
<SwAnchoredObject
*> aAnchoredObjs
;
2133 pContact
->GetAnchoredObjs( aAnchoredObjs
);
2134 if ( !aAnchoredObjs
.empty() )
2136 pAnchoredObj
= aAnchoredObjs
.front();
2140 if ( !pAnchoredObj
)
2142 // no anchored object found. Thus, the needed layout information can't
2143 // be determined. --> no conversion
2146 // --> OD 2006-09-26 #141404#
2147 // no conversion for anchored drawing object, which aren't attached to an
2149 // This is the case for drawing objects, which are anchored inside a page
2150 // header/footer of an *unused* page style.
2151 if ( dynamic_cast<SwAnchoredDrawObject
*>(pAnchoredObj
) &&
2152 !pAnchoredObj
->GetAnchorFrm() )
2158 bool bConverted( false );
2160 // determine value of attribute 'Follow text flow', because positions aligned
2161 // at page areas have to be converted, if it's set.
2162 const bool bFollowTextFlow
= _rFrmFmt
.GetFollowTextFlow().GetValue();
2164 // --> OD 2007-07-24 #148096#
2165 // check, if horizontal and vertical position have to be converted due to
2166 // the fact, that the object is anchored at a paragraph, which has a "column
2167 // break before" attribute
2168 bool bConvDueToAnchoredAtColBreakPara( false );
2169 if ( ( eAnchor
== FLY_AT_CNTNT
|| eAnchor
== FLY_AUTO_CNTNT
) &&
2170 _rFrmFmt
.GetAnchor().GetCntntAnchor() &&
2171 _rFrmFmt
.GetAnchor().GetCntntAnchor()->nNode
.GetNode().IsTxtNode() )
2173 SwTxtNode
& rAnchorTxtNode
=
2174 dynamic_cast<SwTxtNode
&>(_rFrmFmt
.GetAnchor().GetCntntAnchor()->nNode
.GetNode());
2175 const SvxFmtBreakItem
* pBreak
= &(ItemGet
<SvxFmtBreakItem
>(rAnchorTxtNode
, RES_BREAK
));
2177 pBreak
->GetBreak() == SVX_BREAK_COLUMN_BEFORE
)
2179 bConvDueToAnchoredAtColBreakPara
= true;
2184 // convert horizontal position, if needed
2186 enum HoriConv
{ NO_CONV
, CONV2PG
, CONV2COL
, CONV2CHAR
};
2187 HoriConv
eHoriConv( NO_CONV
);
2189 // determine, if conversion has to be performed due to the position orientation
2190 bool bConvDueToOrientation( false );
2192 const sal_Int16 eHOri
= _iorHoriOri
.GetHoriOrient();
2193 bConvDueToOrientation
= eHOri
== text::HoriOrientation::LEFT
|| eHOri
== text::HoriOrientation::RIGHT
||
2194 eHOri
== text::HoriOrientation::INSIDE
|| eHOri
== text::HoriOrientation::OUTSIDE
||
2195 ( eHOri
!= text::HoriOrientation::CENTER
&& _iorHoriOri
.IsPosToggle() );
2198 // determine conversion type due to the position relation
2199 // --> OD 2007-07-24 #148096#
2200 if ( bConvDueToAnchoredAtColBreakPara
)
2202 eHoriConv
= CONV2PG
;
2206 switch ( _iorHoriOri
.GetRelationOrient() )
2208 case text::RelOrientation::PAGE_FRAME
:
2209 case text::RelOrientation::PAGE_PRINT_AREA
:
2211 if ( bConvDueToOrientation
|| bFollowTextFlow
)
2212 eHoriConv
= CONV2PG
;
2215 case text::RelOrientation::PAGE_LEFT
:
2216 case text::RelOrientation::PAGE_RIGHT
:
2218 // relation not supported by WW8. Thus, conversion always needed.
2219 eHoriConv
= CONV2PG
;
2222 case text::RelOrientation::FRAME
:
2224 if ( bConvDueToOrientation
)
2225 eHoriConv
= CONV2COL
;
2228 case text::RelOrientation::PRINT_AREA
:
2229 case text::RelOrientation::FRAME_LEFT
:
2230 case text::RelOrientation::FRAME_RIGHT
:
2232 // relation not supported by WW8. Thus, conversion always needed.
2233 eHoriConv
= CONV2COL
;
2236 case text::RelOrientation::CHAR
:
2238 if ( bConvDueToOrientation
)
2239 eHoriConv
= CONV2CHAR
;
2244 "<WinwordAnchoring::ConvertPosition(..)> - unknown horizontal relation" );
2248 if ( eHoriConv
!= NO_CONV
)
2250 _iorHoriOri
.SetHoriOrient( text::HoriOrientation::NONE
);
2251 SwTwips
nPosX( 0L );
2254 if ( eHoriConv
== CONV2PG
)
2256 _iorHoriOri
.SetRelationOrient( text::RelOrientation::PAGE_FRAME
);
2257 // --> OD 2005-01-27 #i33818#
2258 bool bRelToTableCell( false );
2259 aPos
= pAnchoredObj
->GetRelPosToPageFrm( bFollowTextFlow
,
2261 if ( bRelToTableCell
)
2263 _iorHoriOri
.SetRelationOrient( text::RelOrientation::PAGE_PRINT_AREA
);
2267 else if ( eHoriConv
== CONV2COL
)
2269 _iorHoriOri
.SetRelationOrient( text::RelOrientation::FRAME
);
2270 aPos
= pAnchoredObj
->GetRelPosToAnchorFrm();
2272 else if ( eHoriConv
== CONV2CHAR
)
2274 _iorHoriOri
.SetRelationOrient( text::RelOrientation::CHAR
);
2275 aPos
= pAnchoredObj
->GetRelPosToChar();
2277 // No distinction between layout directions, because of missing
2278 // information about WW8 in vertical layout.
2281 _iorHoriOri
.SetPos( nPosX
);
2286 // convert vertical position, if needed
2288 enum VertConv
{ NO_CONV
, CONV2PG
, CONV2PARA
, CONV2LINE
};
2289 VertConv
eVertConv( NO_CONV
);
2291 // determine, if conversion has to be performed due to the position orientation
2292 bool bConvDueToOrientation( false );
2294 const sal_Int16 eVOri
= _iorVertOri
.GetVertOrient();
2295 bConvDueToOrientation
= ( eVOri
== text::VertOrientation::TOP
||
2296 eVOri
== text::VertOrientation::BOTTOM
||
2297 eVOri
== text::VertOrientation::CHAR_TOP
||
2298 eVOri
== text::VertOrientation::CHAR_BOTTOM
||
2299 eVOri
== text::VertOrientation::CHAR_CENTER
||
2300 eVOri
== text::VertOrientation::LINE_TOP
||
2301 eVOri
== text::VertOrientation::LINE_BOTTOM
||
2302 eVOri
== text::VertOrientation::LINE_CENTER
);
2305 // determine conversion type due to the position relation
2306 // --> OD 2007-07-24 #148096#
2307 if ( bConvDueToAnchoredAtColBreakPara
)
2309 eVertConv
= CONV2PG
;
2313 switch ( _iorVertOri
.GetRelationOrient() )
2315 case text::RelOrientation::PAGE_FRAME
:
2316 case text::RelOrientation::PAGE_PRINT_AREA
:
2318 if ( bConvDueToOrientation
|| bFollowTextFlow
)
2319 eVertConv
= CONV2PG
;
2322 case text::RelOrientation::FRAME
:
2324 if ( bConvDueToOrientation
||
2325 _iorVertOri
.GetVertOrient() == text::VertOrientation::CENTER
)
2327 eVertConv
= CONV2PARA
;
2331 case text::RelOrientation::PRINT_AREA
:
2333 // relation not supported by WW8. Thus, conversion always needed.
2334 eVertConv
= CONV2PARA
;
2337 case text::RelOrientation::CHAR
:
2339 // relation not supported by WW8. Thus, conversion always needed.
2340 eVertConv
= CONV2PARA
;
2343 case text::RelOrientation::TEXT_LINE
:
2345 if ( bConvDueToOrientation
||
2346 _iorVertOri
.GetVertOrient() == text::VertOrientation::NONE
)
2348 eVertConv
= CONV2LINE
;
2352 case text::RelOrientation::PAGE_LEFT
:
2353 case text::RelOrientation::PAGE_RIGHT
:
2354 case text::RelOrientation::FRAME_LEFT
:
2355 case text::RelOrientation::FRAME_RIGHT
:
2358 "<WinwordAnchoring::ConvertPosition(..)> - unknown vertical relation" );
2362 if ( eVertConv
!= NO_CONV
)
2364 _iorVertOri
.SetVertOrient( text::VertOrientation::NONE
);
2365 SwTwips
nPosY( 0L );
2368 if ( eVertConv
== CONV2PG
)
2370 _iorVertOri
.SetRelationOrient( text::RelOrientation::PAGE_FRAME
);
2371 // --> OD 2005-01-27 #i33818#
2372 bool bRelToTableCell( false );
2373 aPos
= pAnchoredObj
->GetRelPosToPageFrm( bFollowTextFlow
,
2375 if ( bRelToTableCell
)
2377 _iorVertOri
.SetRelationOrient( text::RelOrientation::PAGE_PRINT_AREA
);
2381 else if ( eVertConv
== CONV2PARA
)
2383 _iorVertOri
.SetRelationOrient( text::RelOrientation::FRAME
);
2384 aPos
= pAnchoredObj
->GetRelPosToAnchorFrm();
2386 else if ( eVertConv
== CONV2LINE
)
2388 _iorVertOri
.SetRelationOrient( text::RelOrientation::TEXT_LINE
);
2389 aPos
= pAnchoredObj
->GetRelPosToLine();
2391 // No distinction between layout directions, because of missing
2392 // information about WW8 in vertical layout.
2395 _iorVertOri
.SetPos( nPosY
);
2403 void WinwordAnchoring::SetAnchoring(const SwFrmFmt
& rFmt
)
2405 const RndStdIds eAnchor
= rFmt
.GetAnchor().GetAnchorId();
2406 mbInline
= (eAnchor
== FLY_IN_CNTNT
);
2408 SwFmtHoriOrient rHoriOri
= rFmt
.GetHoriOrient();
2409 SwFmtVertOrient rVertOri
= rFmt
.GetVertOrient();
2411 // --> OD 2005-01-06 #i30669# - convert the positioning attributes.
2412 // Most positions are converted, if layout information exists.
2413 const bool bPosConverted
= ConvertPosition( rHoriOri
, rVertOri
, rFmt
);
2416 const sal_Int16 eHOri
= rHoriOri
.GetHoriOrient();
2417 // CMC, OD 24.11.2003 #i22673#
2418 const sal_Int16 eVOri
= rVertOri
.GetVertOrient();
2420 const sal_Int16 eHRel
= rHoriOri
.GetRelationOrient();
2421 const sal_Int16 eVRel
= rVertOri
.GetRelationOrient();
2423 // horizontal Adjustment
2427 case text::HoriOrientation::NONE
:
2430 case text::HoriOrientation::LEFT
:
2433 case text::HoriOrientation::CENTER
:
2436 case text::HoriOrientation::RIGHT
:
2439 case text::HoriOrientation::INSIDE
:
2442 case text::HoriOrientation::OUTSIDE
:
2447 // vertical Adjustment
2448 // CMC, OD 24.11.2003 #i22673#
2449 // When adjustment is vertically relative to line or to char
2450 // bottom becomes top and vice versa
2451 const bool bVertSwap
= !bPosConverted
&&
2452 ( (eVRel
== text::RelOrientation::CHAR
) ||
2453 (eVRel
== text::RelOrientation::TEXT_LINE
) );
2457 case text::VertOrientation::NONE
:
2460 case text::VertOrientation::TOP
:
2461 case text::VertOrientation::LINE_TOP
:
2462 case text::VertOrientation::CHAR_TOP
:
2463 mnYAlign
= bVertSwap
? 3 : 1;
2465 case text::VertOrientation::CENTER
:
2466 case text::VertOrientation::LINE_CENTER
:
2469 case text::VertOrientation::BOTTOM
:
2470 case text::VertOrientation::LINE_BOTTOM
:
2471 case text::VertOrientation::CHAR_BOTTOM
:
2472 mnYAlign
= bVertSwap
? 1 : 3;
2476 // Adjustment is horizontally relative to...
2479 case text::RelOrientation::PAGE_PRINT_AREA
:
2482 case text::RelOrientation::PAGE_FRAME
:
2483 case text::RelOrientation::PAGE_LEFT
: //:-(
2484 case text::RelOrientation::PAGE_RIGHT
: //:-(
2487 case text::RelOrientation::FRAME
:
2488 case text::RelOrientation::FRAME_LEFT
: //:-(
2489 case text::RelOrientation::FRAME_RIGHT
: //:-(
2490 if (eAnchor
== FLY_PAGE
)
2495 case text::RelOrientation::PRINT_AREA
:
2496 if (eAnchor
== FLY_PAGE
)
2501 case text::RelOrientation::CHAR
:
2504 case text::RelOrientation::TEXT_LINE
:
2508 // Adjustment is vertically relative to...
2511 case text::RelOrientation::PAGE_PRINT_AREA
:
2514 case text::RelOrientation::PAGE_FRAME
:
2517 case text::RelOrientation::PRINT_AREA
:
2518 if (eAnchor
== FLY_PAGE
)
2523 case text::RelOrientation::FRAME
:
2524 if (eAnchor
== FLY_PAGE
)
2529 case text::RelOrientation::CHAR
:
2530 case text::RelOrientation::TEXT_LINE
: // CMC, OD 24.11.2003 #i22673# - vertical alignment at top of line
2531 case text::RelOrientation::PAGE_LEFT
: //nonsense
2532 case text::RelOrientation::PAGE_RIGHT
: //nonsense
2533 case text::RelOrientation::FRAME_LEFT
: //nonsense
2534 case text::RelOrientation::FRAME_RIGHT
: //nonsense
2540 void SwEscherEx::WriteFrmExtraData( const SwFrmFmt
& rFmt
)
2542 aWinwordAnchoring
.SetAnchoring(rFmt
);
2543 aWinwordAnchoring
.WriteData(*this);
2545 AddAtom(4, ESCHER_ClientAnchor
);
2548 AddAtom(4, ESCHER_ClientData
);
2552 INT32
SwEscherEx::WriteFlyFrm(const DrawObj
&rObj
, UINT32
&rShapeId
,
2553 DrawObjPointerVector
&rPVec
)
2555 const SwFrmFmt
&rFmt
= rObj
.maCntnt
.GetFrmFmt();
2557 // check for textflyframe and if it is the first in a Chain
2558 INT32 nBorderThick
= 0;
2559 const SwNodeIndex
* pNdIdx
= rFmt
.GetCntnt().GetCntntIdx();
2562 SwNodeIndex
aIdx( *pNdIdx
, 1 );
2563 switch( aIdx
.GetNode().GetNodeType() )
2566 nBorderThick
= WriteGrfFlyFrame( rFmt
, rShapeId
= GetShapeID() );
2569 nBorderThick
= WriteOLEFlyFrame( rFmt
, rShapeId
= GetShapeID() );
2572 if (const SdrObject
* pObj
= rFmt
.FindRealSdrObject())
2574 // check for the first in a Chain
2577 const SwFrmFmt
* pFmt
= &rFmt
, *pPrev
;
2578 while( 0 != ( pPrev
= pFmt
->GetChain().GetPrev() ))
2584 rShapeId
= GetFlyShapeId(rFmt
, rObj
.mnHdFtIndex
, rPVec
);
2587 void* p
= (void*)pObj
;
2588 nTxtId
= pTxtBxs
->GetPos( p
);
2589 if( USHRT_MAX
== nTxtId
)
2591 pTxtBxs
->Append( *pObj
, rShapeId
);
2592 nTxtId
= pTxtBxs
->Count();
2599 const SdrObject
* pPrevObj
= pFmt
->FindRealSdrObject();
2600 void* p
= (void*)pPrevObj
;
2601 nTxtId
= pTxtBxs
->GetPos( p
);
2602 if( USHRT_MAX
== nTxtId
)
2604 UINT32 nPrevShapeId
=
2605 GetFlyShapeId(*pFmt
, rObj
.mnHdFtIndex
, rPVec
);
2606 pTxtBxs
->Append( *pPrevObj
, nPrevShapeId
);
2607 nTxtId
= pTxtBxs
->Count();
2615 nBorderThick
= WriteTxtFlyFrame(rObj
, rShapeId
, nTxtId
, rPVec
);
2619 return nBorderThick
;
2622 USHORT
FindPos(const SwFrmFmt
&rFmt
, unsigned int nHdFtIndex
,
2623 DrawObjPointerVector
&rPVec
)
2625 DrawObjPointerIter aEnd
= rPVec
.end();
2626 for (DrawObjPointerIter aIter
= rPVec
.begin(); aIter
!= aEnd
; ++aIter
)
2628 const DrawObj
*pObj
= (*aIter
);
2629 ASSERT(pObj
, "Impossible");
2633 nHdFtIndex
== pObj
->mnHdFtIndex
&&
2634 &rFmt
== (&pObj
->maCntnt
.GetFrmFmt())
2637 return static_cast< USHORT
>(aIter
- rPVec
.begin());
2643 INT32
SwEscherEx::WriteTxtFlyFrame(const DrawObj
&rObj
, UINT32 nShapeId
,
2644 UINT32 nTxtBox
, DrawObjPointerVector
&rPVec
)
2646 const SwFrmFmt
&rFmt
= rObj
.maCntnt
.GetFrmFmt();
2647 short nDirection
= rObj
.mnDirection
;
2649 INT32 nBorderThick
=0;
2650 OpenContainer( ESCHER_SpContainer
);
2652 AddShape( ESCHER_ShpInst_TextBox
, 0xa00, nShapeId
);
2653 EscherPropertyContainer aPropOpt
;
2654 aPropOpt
.AddOpt(ESCHER_Prop_lTxid
, nTxtBox
);
2655 if (const SwFrmFmt
*pNext
= rFmt
.GetChain().GetNext())
2657 USHORT nPos
= FindPos(*pNext
, rObj
.mnHdFtIndex
, rPVec
);
2658 if (USHRT_MAX
!= nPos
&& aFollowShpIds
[nPos
])
2659 aPropOpt
.AddOpt(ESCHER_Prop_hspNext
, aFollowShpIds
[nPos
]);
2661 nBorderThick
= WriteFlyFrameAttr( rFmt
, mso_sptTextBox
, aPropOpt
);
2668 ASSERT(!this, "unknown direction type");
2669 case FRMDIR_HORI_LEFT_TOP
:
2670 nFlow
=mso_txflHorzN
;
2672 case FRMDIR_HORI_RIGHT_TOP
:
2673 nFlow
=mso_txflHorzN
;
2675 case FRMDIR_VERT_TOP_LEFT
: //not really possible in word
2676 case FRMDIR_VERT_TOP_RIGHT
:
2677 nFlow
=mso_txflTtoBA
;
2680 aPropOpt
.AddOpt( ESCHER_Prop_txflTextFlow
, nFlow
);
2682 aPropOpt
.Commit( GetStream() );
2684 // store anchor attribute
2685 WriteFrmExtraData( rFmt
);
2687 AddAtom( 4, ESCHER_ClientTextbox
); GetStream() << nTxtBox
;
2689 CloseContainer(); // ESCHER_SpContainer
2690 return nBorderThick
;
2693 void SwBasicEscherEx::WriteOLEPicture(EscherPropertyContainer
&rPropOpt
,
2694 sal_uInt32 nShapeFlags
, const Graphic
&rGraphic
, const SdrObject
&rObj
,
2695 sal_uInt32 nShapeId
, const awt::Rectangle
* pVisArea
)
2697 //nShapeFlags == 0xA00 + flips and ole active
2698 AddShape(ESCHER_ShpInst_PictureFrame
, nShapeFlags
, nShapeId
);
2700 GraphicObject
aGraphicObject(rGraphic
);
2701 ByteString aId
= aGraphicObject
.GetUniqueID();
2704 Rectangle aRect
= rObj
.GetLogicRect();
2705 aRect
.SetPos(Point(0,0));
2706 aRect
.Right() = DrawModelToEmu(aRect
.Right());
2707 aRect
.Bottom() = DrawModelToEmu(aRect
.Bottom());
2708 sal_uInt32 nBlibId
= GetBlibID(*QueryPicStream(), aId
, aRect
, pVisArea
, 0); // SJ: the fourth parameter (VisArea) should be set..
2710 rPropOpt
.AddOpt(ESCHER_Prop_pib
, nBlibId
, sal_True
);
2713 SetPicId(rObj
, nShapeId
, rPropOpt
);
2714 rPropOpt
.AddOpt( ESCHER_Prop_pictureActive
, 0x10000 );
2717 void SwEscherEx::WriteOCXControl( const SwFrmFmt
& rFmt
, UINT32 nShapeId
)
2719 if (const SdrObject
* pSdrObj
= rFmt
.FindRealSdrObject())
2721 OpenContainer( ESCHER_SpContainer
);
2723 SdrModel
*pModel
= rWrt
.pDoc
->GetDrawModel();
2724 OutputDevice
*pDevice
= Application::GetDefaultDevice();
2725 ASSERT(pModel
&& pDevice
, "no model or device");
2727 // #i71538# use complete SdrViews
2728 // SdrExchangeView aExchange(pModel, pDevice);
2729 SdrView
aExchange(pModel
, pDevice
);
2731 Graphic
aGraphic(aExchange
.GetObjGraphic(pModel
, pSdrObj
));
2733 EscherPropertyContainer aPropOpt
;
2734 WriteOLEPicture(aPropOpt
, 0xa00 | SHAPEFLAG_OLESHAPE
, aGraphic
,
2735 *pSdrObj
, nShapeId
, NULL
);
2737 WriteFlyFrameAttr( rFmt
, mso_sptPictureFrame
, aPropOpt
);
2738 aPropOpt
.Commit( GetStream() );
2740 // store anchor attribute
2741 WriteFrmExtraData( rFmt
);
2743 CloseContainer(); // ESCHER_SpContainer
2747 void SwEscherEx::MakeZOrderArrAndFollowIds(
2748 std::vector
<DrawObj
>& rSrcArr
, std::vector
<DrawObj
*>&rDstArr
)
2750 USHORT n
, nCnt
= static_cast< USHORT
>(rSrcArr
.size());
2751 SvULongsSort
aSort( 255 < nCnt
? 255 : nCnt
, 255 );
2753 rDstArr
.reserve(nCnt
);
2754 for (n
= 0; n
< nCnt
; ++n
)
2756 const SwFrmFmt
&rFmt
= rSrcArr
[n
].maCntnt
.GetFrmFmt();
2757 ULONG nOrdNum
= rWrt
.GetSdrOrdNum(rFmt
);
2759 //returns what will be the index in rDstArr of p as nPos
2760 aSort
.Insert(nOrdNum
, nPos
);
2761 DrawObj
&rObj
= rSrcArr
[n
];
2762 rDstArr
.insert(rDstArr
.begin() + nPos
, &rObj
);
2765 if (aFollowShpIds
.Count())
2766 aFollowShpIds
.Remove(0, aFollowShpIds
.Count());
2768 for (n
= 0; n
< nCnt
; ++n
)
2770 const SwFrmFmt
&rFmt
= rDstArr
[n
]->maCntnt
.GetFrmFmt();
2771 bool bNeedsShapeId
= false;
2773 if (RES_FLYFRMFMT
== rFmt
.Which())
2775 const SwFmtChain
&rChain
= rFmt
.GetChain();
2776 if (rChain
.GetPrev() || rChain
.GetNext())
2777 bNeedsShapeId
= true;
2780 ULONG nShapeId
= bNeedsShapeId
? GetShapeID() : 0;
2782 aFollowShpIds
.Insert(nShapeId
, n
);
2786 UINT32
SwEscherEx::GetFlyShapeId(const SwFrmFmt
& rFmt
,
2787 unsigned int nHdFtIndex
, DrawObjPointerVector
&rpVec
)
2789 USHORT nPos
= FindPos(rFmt
, nHdFtIndex
, rpVec
);
2791 if (USHRT_MAX
!= nPos
)
2793 if (0 == (nShapeId
= aFollowShpIds
[nPos
]))
2795 nShapeId
= GetShapeID();
2796 aFollowShpIds
[ nPos
] = nShapeId
;
2800 nShapeId
= GetShapeID();
2804 UINT32
SwEscherEx::QueryTextID(
2805 const uno::Reference
< drawing::XShape
>& xXShapeRef
, UINT32 nShapeId
)
2808 if (SdrObject
* pObj
= GetSdrObjectFromXShape(xXShapeRef
))
2810 pTxtBxs
->Append( *pObj
, nShapeId
);
2811 nId
= pTxtBxs
->Count();
2817 bool SwMSConvertControls::ExportControl(WW8Export
&rWW8Wrt
, const SdrObject
*pObj
)
2819 if (!rWW8Wrt
.bWrtWW8
)
2822 SdrUnoObj
*pFormObj
= PTR_CAST(SdrUnoObj
,pObj
);
2823 uno::Reference
< awt::XControlModel
> xControlModel
=
2824 pFormObj
->GetUnoControlModel();
2826 //Why oh lord do we use so many different units ?
2827 //I think I painted myself into a little bit of a
2828 //corner by trying to use the uno interface for
2830 Rectangle aRect
= pFormObj
->GetLogicRect();
2831 aRect
.SetPos(Point(0,0));
2833 aSize
.Width
= TWIPS_TO_MM(aRect
.Right());
2834 aSize
.Height
= TWIPS_TO_MM(aRect
.Bottom());
2836 //Open the ObjectPool
2837 SvStorageRef xObjPool
= rWW8Wrt
.GetWriter().GetStorage().OpenSotStorage(
2838 CREATE_CONST_ASC(SL::aObjectPool
), STREAM_READWRITE
|
2839 STREAM_SHARE_DENYALL
);
2841 //Create a destination storage for the microsoft control
2842 String
sStorageName('_');
2843 sStorageName
+= String::CreateFromInt32((sal_uInt32
)(sal_uIntPtr
)pObj
);
2844 SvStorageRef xOleStg
= xObjPool
->OpenSotStorage(sStorageName
,
2845 STREAM_READWRITE
|STREAM_SHARE_DENYALL
);
2851 if (!WriteOCXStream(xOleStg
,xControlModel
,aSize
,sName
))
2856 0x03, 0x6a, 0xFF, 0xFF, 0xFF, 0xFF, // sprmCPicLocation
2857 0x0a, 0x08, 1, // sprmCFOLE2
2858 0x55, 0x08, 1, // sprmCFSpec
2859 0x56, 0x08, 1 // sprmCFObj
2861 //Set the obj id into the sprmCPicLocation
2862 BYTE
*pData
= aSpecOLE
+2;
2863 Set_UInt32(pData
,(sal_uInt32
)(sal_uIntPtr
)pObj
);
2865 String
sFld(FieldString(ww::eCONTROL
));
2866 sFld
.APPEND_CONST_ASC("Forms.");
2868 sFld
.APPEND_CONST_ASC(".1 \\s ");
2870 rWW8Wrt
.OutputField(0, ww::eCONTROL
, sFld
,
2871 WRITEFIELD_START
|WRITEFIELD_CMD_START
|WRITEFIELD_CMD_END
);
2873 rWW8Wrt
.pChpPlc
->AppendFkpEntry(rWW8Wrt
.Strm().Tell(),sizeof(aSpecOLE
),
2875 rWW8Wrt
.WriteChar( 0x1 );
2876 rWW8Wrt
.OutputField(0, ww::eCONTROL
, aEmptyStr
, WRITEFIELD_END
| WRITEFIELD_CLOSE
);
2880 /* vi:set tabstop=4 shiftwidth=4 expandtab: */