Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <com/sun/star/embed/Aspects.hpp>
21 :
22 : #include <hintids.hxx>
23 :
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 <editeng/shaditem.hxx>
48 : #include <unotools/ucbstreamhelper.hxx>
49 : #include <svx/fmglob.hxx>
50 : #include <svx/svdouno.hxx>
51 : #include <svx/unoapi.hxx>
52 :
53 : // #i71538#
54 : #include <svx/svdview.hxx>
55 : #include <fmtcnct.hxx>
56 : #include <fmtanchr.hxx>
57 : #include <fmtsrnd.hxx>
58 : #include <fmtornt.hxx>
59 : #include <fmtfsize.hxx>
60 : #include <fmtfollowtextflow.hxx>
61 : #include <dcontact.hxx>
62 : #include <frmfmt.hxx>
63 : #include <flyfrm.hxx>
64 : #include <pagefrm.hxx>
65 : #include <frmatr.hxx>
66 : #include <fmtcntnt.hxx>
67 : #include <ndindex.hxx>
68 : #include <doc.hxx>
69 : #include <docary.hxx>
70 : #include <pam.hxx>
71 : #include <swrect.hxx>
72 : #include <ndgrf.hxx>
73 : #include <grfatr.hxx>
74 : #include <ndole.hxx>
75 : #include <unodraw.hxx>
76 : #include <pagedesc.hxx>
77 : #include <ww8par.hxx>
78 : #include <breakit.hxx>
79 : #include <com/sun/star/i18n/ScriptType.hpp>
80 : #include "ww8attributeoutput.hxx"
81 : #include "writerhelper.hxx"
82 : #include "writerwordglue.hxx"
83 : #include "wrtww8.hxx"
84 : #include "escher.hxx"
85 : #include <ndtxt.hxx>
86 : #include "WW8FFData.hxx"
87 : #include <com/sun/star/beans/XPropertyContainer.hpp>
88 : #include <com/sun/star/beans/XPropertySet.hpp>
89 : #include <com/sun/star/beans/PropertyAttribute.hpp>
90 : #include <com/sun/star/form/XFormComponent.hpp>
91 : #include "docsh.hxx"
92 : #include <oox/ole/olehelper.hxx>
93 : #include <fstream>
94 : #include <unotools/streamwrap.hxx>
95 : #include <fmtinfmt.hxx>
96 : #include <fmturl.hxx>
97 : #include "sfx2/sfxsids.hrc"
98 : #include <svl/urihelper.hxx>
99 : #include <unotools/saveopt.hxx>
100 :
101 : #include <algorithm>
102 :
103 : using ::editeng::SvxBorderLine;
104 : using namespace com::sun::star;
105 : using namespace sw::util;
106 : using namespace sw::types;
107 : using namespace nsFieldFlags;
108 : using ::com::sun::star::uno::Reference;
109 : using ::com::sun::star::uno::UNO_QUERY;
110 : using ::com::sun::star::beans::XPropertySet;
111 : using ::com::sun::star::drawing::XShape;
112 :
113 0 : bool SwBasicEscherEx::IsRelUrl()
114 : {
115 0 : SvtSaveOptions aSaveOpt;
116 0 : bool bRelUrl = false;
117 0 : SfxMedium * pMedium = rWrt.GetWriter().GetMedia();
118 0 : if ( pMedium )
119 0 : bRelUrl = pMedium->IsRemote() ? aSaveOpt.IsSaveRelINet() : aSaveOpt.IsSaveRelFSys();
120 0 : return bRelUrl;
121 : }
122 :
123 0 : OUString SwBasicEscherEx::GetBasePath()
124 : {
125 0 : OUString sDocUrl;
126 0 : SfxMedium * pMedium = rWrt.GetWriter().GetMedia();
127 0 : if (pMedium)
128 : {
129 0 : const SfxItemSet* pPItemSet = pMedium->GetItemSet();
130 0 : if( pPItemSet )
131 : {
132 0 : const SfxStringItem* pPItem = dynamic_cast< const SfxStringItem* >( pPItemSet->GetItem( SID_FILE_NAME ) );
133 0 : if ( pPItem )
134 0 : sDocUrl = pPItem->GetValue();
135 : }
136 : }
137 :
138 0 : return sDocUrl.copy(0, sDocUrl.lastIndexOf('/') + 1);
139 : }
140 :
141 0 : OUString SwBasicEscherEx::BuildFileName(sal_uInt16& rnLevel, bool& rbRel, const OUString& rUrl)
142 : {
143 0 : OUString aDosName( INetURLObject( rUrl ).getFSysPath( INetURLObject::FSYS_DOS ) );
144 0 : rnLevel = 0;
145 0 : rbRel = IsRelUrl();
146 :
147 0 : if (rbRel)
148 : {
149 : // try to convert to relative file name
150 0 : OUString aTmpName( aDosName );
151 0 : aDosName = INetURLObject::GetRelURL( GetBasePath(), rUrl,
152 0 : INetURLObject::WAS_ENCODED, INetURLObject::DECODE_WITH_CHARSET );
153 :
154 0 : if (aDosName.startsWith(INET_FILE_SCHEME))
155 : {
156 : // not converted to rel -> back to old, return absolute flag
157 0 : aDosName = aTmpName;
158 0 : rbRel = false;
159 : }
160 0 : else if (aDosName.startsWith("./"))
161 : {
162 0 : aDosName = aDosName.copy(2);
163 : }
164 : else
165 : {
166 0 : while (aDosName.startsWith("../"))
167 : {
168 0 : ++rnLevel;
169 0 : aDosName = aDosName.copy(3);
170 : }
171 0 : }
172 : }
173 0 : return aDosName;
174 : }
175 :
176 0 : void SwBasicEscherEx::WriteHyperlinkWithinFly( SvMemoryStream& rStrm, const SwFmtURL* pINetFmtArg)
177 : {
178 0 : if ( !pINetFmtArg ) return;
179 :
180 : sal_uInt8 maGuidStdLink[ 16 ] ={
181 0 : 0xD0, 0xC9, 0xEA, 0x79, 0xF9, 0xBA, 0xCE, 0x11, 0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B };
182 : sal_uInt8 maGuidUrlMoniker[ 16 ] = {
183 0 : 0xE0, 0xC9, 0xEA, 0x79, 0xF9, 0xBA, 0xCE, 0x11, 0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B };
184 :
185 : sal_uInt8 maGuidFileMoniker[ 16 ] = {
186 0 : 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 };
187 : sal_uInt8 maGuidFileTail[] = {
188 : 0xFF, 0xFF, 0xAD, 0xDE, 0x00, 0x00, 0x00, 0x00,
189 : 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
190 : 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
191 0 : };
192 : //const sal_uInt18 WW8_ID_HLINK = 0x01B8;
193 0 : const sal_uInt32 WW8_HLINK_BODY = 0x00000001; /// Contains file link or URL.
194 0 : const sal_uInt32 WW8_HLINK_ABS = 0x00000002; /// Absolute path.
195 : //const sal_uInt32 WW8_HLINK_DESCR = 0x00000014; /// Description.
196 0 : const sal_uInt32 WW8_HLINK_MARK = 0x00000008; /// Text mark.
197 0 : const sal_uInt32 WW8_HLINK_FRAME = 0x00000080; /// Target frame.
198 : //const sal_uInt32 WW8_HLINK_UNC = 0x00000100; /// UNC path.
199 0 : SvMemoryStream tmpStrm;
200 0 : OUString tmpTextMark;
201 :
202 0 : OUString rUrl = pINetFmtArg->GetURL();
203 0 : OUString rTarFrm = pINetFmtArg->GetTargetFrameName();
204 0 : sal_uInt32 mnFlags = 0;
205 :
206 0 : INetURLObject aUrlObj( rUrl );
207 0 : const INetProtocol eProtocol = aUrlObj.GetProtocol();
208 :
209 : //Target Frame
210 0 : if (!rTarFrm.isEmpty())
211 : {
212 0 : SwWW8Writer::WriteLong(tmpStrm, rTarFrm.getLength()+1);
213 0 : SwWW8Writer::WriteString16(tmpStrm, rTarFrm, false);
214 :
215 0 : tmpStrm.WriteUInt16( sal_uInt16( 0 ) );
216 :
217 0 : mnFlags |= WW8_HLINK_FRAME;
218 : }
219 :
220 : // file link or URL
221 0 : if (eProtocol == INET_PROT_FILE || (eProtocol == INET_PROT_NOT_VALID && rUrl[0] != '#'))
222 : {
223 : sal_uInt16 nLevel;
224 : bool bRel;
225 0 : OUString aFileName( BuildFileName( nLevel, bRel, rUrl ));
226 :
227 0 : if( !bRel )
228 0 : mnFlags |= WW8_HLINK_ABS;
229 :
230 0 : mnFlags |= WW8_HLINK_BODY;
231 :
232 0 : tmpStrm.Write( maGuidFileMoniker,sizeof(maGuidFileMoniker) );
233 0 : tmpStrm.WriteUInt16( nLevel );
234 0 : SwWW8Writer::WriteLong(tmpStrm, aFileName.getLength()+1);
235 0 : SwWW8Writer::WriteString8( tmpStrm, aFileName, true, RTL_TEXTENCODING_MS_1252 );
236 0 : tmpStrm.Write( maGuidFileTail,sizeof(maGuidFileTail) );
237 :
238 : //For UNICODE
239 0 : SwWW8Writer::WriteLong(tmpStrm, 2*aFileName.getLength()+6);
240 0 : SwWW8Writer::WriteLong(tmpStrm, 2*aFileName.getLength());
241 0 : tmpStrm.WriteUInt16( sal_uInt16(0x0003) );
242 0 : SwWW8Writer::WriteString16(tmpStrm, aFileName, false);
243 : }
244 0 : else if( eProtocol != INET_PROT_NOT_VALID )
245 : {
246 0 : tmpStrm.Write( maGuidUrlMoniker,sizeof(maGuidUrlMoniker) );
247 0 : SwWW8Writer::WriteLong(tmpStrm, 2*(rUrl.getLength()+1));
248 :
249 0 : SwWW8Writer::WriteString16(tmpStrm, rUrl, true);
250 0 : mnFlags |= WW8_HLINK_BODY | WW8_HLINK_ABS;
251 : }
252 0 : else if (rUrl[0] == '#' )
253 : {
254 0 : OUString aTextMark(rUrl.copy( 1 ));
255 0 : aTextMark = aTextMark.replaceFirst(".", "!");
256 0 : tmpTextMark = aTextMark;
257 : }
258 :
259 0 : if (tmpTextMark.isEmpty() && aUrlObj.HasMark())
260 : {
261 0 : tmpTextMark = aUrlObj.GetMark();
262 : }
263 :
264 0 : if (!tmpTextMark.isEmpty())
265 : {
266 0 : SwWW8Writer::WriteLong(tmpStrm, tmpTextMark.getLength()+1);
267 0 : SwWW8Writer::WriteString16(tmpStrm, tmpTextMark, true);
268 :
269 0 : mnFlags |= WW8_HLINK_MARK;
270 : }
271 :
272 0 : rStrm.Write( maGuidStdLink,16 );
273 0 : rStrm .WriteUInt32( sal_uInt32( 2 ) )
274 0 : .WriteUInt32( mnFlags );
275 0 : tmpStrm.Seek( STREAM_SEEK_TO_BEGIN );
276 0 : sal_uInt32 nStrmPos = tmpStrm.Tell();
277 0 : tmpStrm.Seek( STREAM_SEEK_TO_END );
278 0 : sal_uInt32 nStrmSize = tmpStrm.Tell();
279 0 : tmpStrm.Seek( nStrmPos );
280 : sal_uInt32 nLen;
281 0 : nLen = nStrmSize - nStrmPos;
282 0 : if(nLen >0)
283 : {
284 0 : sal_uInt8* pBuffer = new sal_uInt8[ nLen ];
285 0 : tmpStrm.Read(pBuffer, nLen);
286 0 : rStrm.Write( pBuffer, nLen );
287 0 : delete[] pBuffer;
288 0 : }
289 : }
290 7 : void SwBasicEscherEx::PreWriteHyperlinkWithinFly(const SwFrmFmt& rFmt,EscherPropertyContainer& rPropOpt)
291 : {
292 : const SfxPoolItem* pItem;
293 7 : const SwAttrSet& rAttrSet = rFmt.GetAttrSet();
294 7 : if (SFX_ITEM_SET == rAttrSet.GetItemState(RES_URL, true, &pItem))
295 : {
296 0 : const SwFmtURL *pINetFmt = dynamic_cast<const SwFmtURL*>(pItem);
297 0 : if (pINetFmt && !pINetFmt->GetURL().isEmpty())
298 : {
299 0 : SvMemoryStream *rStrm = new SvMemoryStream ;
300 0 : WriteHyperlinkWithinFly( *rStrm, pINetFmt );
301 0 : sal_uInt8* pBuf = (sal_uInt8*) rStrm->GetData();
302 0 : sal_uInt32 nSize = rStrm->Seek( STREAM_SEEK_TO_END );
303 0 : rPropOpt.AddOpt( ESCHER_Prop_pihlShape, true, nSize, pBuf, nSize );
304 : sal_uInt32 nValue;
305 0 : OUString aNamestr = pINetFmt->GetName();
306 0 : if (!aNamestr.isEmpty())
307 : {
308 0 : rPropOpt.AddOpt(ESCHER_Prop_wzName, aNamestr );
309 : }
310 0 : if(rPropOpt.GetOpt( ESCHER_Prop_fPrint, nValue))
311 : {
312 0 : nValue|=0x03080008;
313 0 : rPropOpt.AddOpt(ESCHER_Prop_fPrint, nValue );
314 : }
315 : else
316 0 : rPropOpt.AddOpt(ESCHER_Prop_fPrint, 0x03080008 );
317 : }
318 : }
319 7 : }
320 :
321 : namespace
322 : {
323 : /// Get the Z ordering number for a DrawObj in a WW8Export.
324 : /// @param rWrt The containing WW8Export.
325 : /// @param pObj pointer to the drawing object.
326 : /// @returns The ordering number.
327 44 : static sal_uLong lcl_getSdrOrderNumber(const WW8Export& rWrt, DrawObj *pObj)
328 : {
329 44 : return rWrt.GetSdrOrdNum(pObj->maCntnt.GetFrmFmt());
330 : };
331 :
332 : /// A function object to act as a predicate comparing the ordering numbers
333 : /// of two drawing obejcts in a WW8Export.
334 : class CompareDrawObjs
335 : {
336 : private:
337 : const WW8Export& wrt;
338 :
339 : public:
340 4 : CompareDrawObjs(const WW8Export& rWrt) : wrt(rWrt) {};
341 22 : bool operator()(DrawObj *a, DrawObj *b) const
342 : {
343 22 : sal_uLong aSort = lcl_getSdrOrderNumber(wrt, a);
344 22 : sal_uLong bSort = lcl_getSdrOrderNumber(wrt, b);
345 22 : return aSort < bSort;
346 : }
347 : };
348 :
349 : /// Make a z-order sorted copy of a collection of DrawObj objects.
350 : /// @param rWrt The containing WW8Export.
351 : /// @param rSrcArr The source array.
352 : /// @param rDstArr The destination array.
353 4 : static void lcl_makeZOrderArray(const WW8Export& rWrt,
354 : std::vector<DrawObj> &rSrcArr,
355 : std::vector<DrawObj*> &rDstArr)
356 : {
357 4 : rDstArr.clear();
358 4 : rDstArr.reserve(rSrcArr.size());
359 13 : for(size_t i = 0; i < rSrcArr.size(); ++i)
360 : {
361 9 : rDstArr.push_back( &rSrcArr[i] );
362 : }
363 4 : std::sort(rDstArr.begin(), rDstArr.end(), CompareDrawObjs(rWrt));
364 4 : }
365 :
366 : }
367 :
368 : // get a part fix for this type of element
369 0 : bool WW8Export::MiserableFormFieldExportHack(const SwFrmFmt& rFrmFmt)
370 : {
371 : OSL_ENSURE(bWrtWW8, "Not allowed");
372 0 : if (!bWrtWW8)
373 0 : return false;
374 0 : bool bHack = false;
375 0 : const SdrObject *pObject = rFrmFmt.FindRealSdrObject();
376 0 : if (pObject && pObject->GetObjInventor() == FmFormInventor)
377 : {
378 0 : if (SdrUnoObj *pFormObj = PTR_CAST(SdrUnoObj,pObject))
379 : {
380 : uno::Reference< awt::XControlModel > xControlModel =
381 0 : pFormObj->GetUnoControlModel();
382 : uno::Reference< lang::XServiceInfo > xInfo(xControlModel,
383 0 : uno::UNO_QUERY);
384 0 : uno::Reference<beans::XPropertySet> xPropSet(xControlModel, uno::UNO_QUERY);
385 0 : if (xInfo->supportsService("com.sun.star.form.component.ComboBox"))
386 : {
387 0 : DoComboBox(xPropSet);
388 0 : bHack = true;
389 : }
390 0 : else if (xInfo->supportsService("com.sun.star.form.component.CheckBox"))
391 : {
392 0 : DoCheckBox(xPropSet);
393 0 : bHack = true;
394 0 : }
395 : }
396 : }
397 0 : return bHack;
398 : }
399 :
400 0 : void WW8Export::DoComboBox(uno::Reference<beans::XPropertySet> xPropSet)
401 : {
402 0 : OUString sSelected;
403 0 : uno::Sequence<OUString> aListItems;
404 0 : xPropSet->getPropertyValue("StringItemList") >>= aListItems;
405 0 : sal_Int32 nNoStrings = aListItems.getLength();
406 0 : if (nNoStrings)
407 : {
408 0 : uno::Any aTmp = xPropSet->getPropertyValue("DefaultText");
409 0 : const OUString *pStr = (const OUString *)aTmp.getValue();
410 0 : if (pStr)
411 0 : sSelected = *pStr;
412 : }
413 :
414 0 : OUString sName;
415 : {
416 0 : uno::Any aTmp = xPropSet->getPropertyValue("Name");
417 0 : const OUString *pStr = (const OUString *)aTmp.getValue();
418 0 : if (pStr)
419 0 : sName = *pStr;
420 : }
421 :
422 0 : OUString sHelp;
423 : {
424 : // property "Help" does not exist and due to the no-existence an exception is thrown.
425 : try
426 : {
427 0 : uno::Any aTmp = xPropSet->getPropertyValue("HelpText");
428 0 : const OUString *pStr = (const OUString *)aTmp.getValue();
429 0 : if (pStr)
430 0 : sHelp = *pStr;
431 : }
432 0 : catch( const uno::Exception& )
433 : {}
434 : }
435 :
436 0 : OUString sToolTip;
437 : {
438 0 : uno::Any aTmp = xPropSet->getPropertyValue("Name");
439 0 : const OUString *pStr = (const OUString *)aTmp.getValue();
440 0 : if (pStr)
441 0 : sToolTip = *pStr;
442 : }
443 :
444 0 : DoComboBox(sName, sHelp, sToolTip, sSelected, aListItems);
445 0 : }
446 :
447 0 : void WW8Export::DoComboBox(const OUString &rName,
448 : const OUString &rHelp,
449 : const OUString &rToolTip,
450 : const OUString &rSelected,
451 : uno::Sequence<OUString> &rListItems)
452 : {
453 : OSL_ENSURE(bWrtWW8, "Not allowed");
454 0 : if (!bWrtWW8)
455 0 : return;
456 : OutputField(0, ww::eFORMDROPDOWN, FieldString(ww::eFORMDROPDOWN),
457 0 : WRITEFIELD_START | WRITEFIELD_CMD_START);
458 : // write the refence to the "picture" structure
459 0 : sal_uLong nDataStt = pDataStrm->Tell();
460 0 : pChpPlc->AppendFkpEntry( Strm().Tell() );
461 :
462 0 : WriteChar( 0x01 );
463 :
464 : static sal_uInt8 aArr1[] =
465 : {
466 : 0x03, 0x6a, 0,0,0,0, // sprmCPicLocation
467 : 0x06, 0x08, 0x01, // sprmCFData
468 : 0x55, 0x08, 0x01, // sprmCFSpec
469 : 0x02, 0x08, 0x01 // sprmCFFldVanish
470 : };
471 0 : sal_uInt8* pDataAdr = aArr1 + 2;
472 0 : Set_UInt32( pDataAdr, nDataStt );
473 :
474 0 : pChpPlc->AppendFkpEntry(Strm().Tell(), sizeof(aArr1), aArr1);
475 :
476 : OutputField(0, ww::eFORMDROPDOWN, FieldString(ww::eFORMDROPDOWN),
477 0 : WRITEFIELD_CLOSE);
478 :
479 0 : ::sw::WW8FFData aFFData;
480 :
481 0 : aFFData.setType(2);
482 0 : aFFData.setName(rName);
483 0 : aFFData.setHelp(rHelp);
484 0 : aFFData.setStatus(rToolTip);
485 :
486 0 : sal_uInt32 nListItems = rListItems.getLength();
487 :
488 0 : for (sal_uInt32 i = 0; i < nListItems; i++)
489 : {
490 0 : if (i < 0x20 && rSelected == rListItems[i])
491 0 : aFFData.setResult(::sal::static_int_cast<sal_uInt8>(i));
492 0 : aFFData.addListboxEntry(rListItems[i]);
493 : }
494 :
495 0 : aFFData.Write(pDataStrm);
496 : }
497 :
498 0 : void WW8Export::DoCheckBox(uno::Reference<beans::XPropertySet> xPropSet)
499 : {
500 : uno::Reference<beans::XPropertySetInfo> xPropSetInfo =
501 0 : xPropSet->getPropertySetInfo();
502 :
503 : OutputField(0, ww::eFORMCHECKBOX, FieldString(ww::eFORMCHECKBOX),
504 0 : WRITEFIELD_START | WRITEFIELD_CMD_START);
505 : // write the refence to the "picture" structure
506 0 : sal_uLong nDataStt = pDataStrm->Tell();
507 0 : pChpPlc->AppendFkpEntry( Strm().Tell() );
508 :
509 0 : WriteChar( 0x01 );
510 : static sal_uInt8 aArr1[] = {
511 : 0x03, 0x6a, 0,0,0,0, // sprmCPicLocation
512 :
513 : 0x06, 0x08, 0x01, // sprmCFData
514 : 0x55, 0x08, 0x01, // sprmCFSpec
515 : 0x02, 0x08, 0x01 // sprmCFFldVanish
516 : };
517 0 : sal_uInt8* pDataAdr = aArr1 + 2;
518 0 : Set_UInt32( pDataAdr, nDataStt );
519 :
520 0 : pChpPlc->AppendFkpEntry(Strm().Tell(),
521 0 : sizeof( aArr1 ), aArr1 );
522 :
523 0 : ::sw::WW8FFData aFFData;
524 :
525 0 : aFFData.setType(1);
526 0 : aFFData.setCheckboxHeight(0x14);
527 :
528 0 : sal_Int16 nTemp = 0;
529 0 : xPropSet->getPropertyValue("DefaultState") >>= nTemp;
530 0 : aFFData.setDefaultResult(nTemp);
531 :
532 0 : xPropSet->getPropertyValue("State") >>= nTemp;
533 0 : aFFData.setResult(nTemp);
534 :
535 0 : OUString aStr;
536 0 : static OUString sName("Name");
537 0 : if (xPropSetInfo->hasPropertyByName(sName))
538 : {
539 0 : xPropSet->getPropertyValue(sName) >>= aStr;
540 0 : aFFData.setName(aStr);
541 : }
542 :
543 0 : static OUString sHelpText("HelpText");
544 0 : if (xPropSetInfo->hasPropertyByName(sHelpText))
545 : {
546 0 : xPropSet->getPropertyValue(sHelpText) >>= aStr;
547 0 : aFFData.setHelp(aStr);
548 : }
549 0 : static OUString sHelpF1Text("HelpF1Text");
550 0 : if (xPropSetInfo->hasPropertyByName(sHelpF1Text))
551 : {
552 0 : xPropSet->getPropertyValue(sHelpF1Text) >>= aStr;
553 0 : aFFData.setStatus(aStr);
554 : }
555 :
556 0 : aFFData.Write(pDataStrm);
557 :
558 0 : OutputField(0, ww::eFORMCHECKBOX, OUString(), WRITEFIELD_CLOSE);
559 0 : }
560 :
561 0 : void WW8Export::DoFormText(const SwInputField * pFld)
562 : {
563 : OutputField(0, ww::eFORMTEXT, FieldString(ww::eFORMTEXT),
564 0 : WRITEFIELD_START | WRITEFIELD_CMD_START);
565 : // write the refence to the "picture" structure
566 0 : sal_uLong nDataStt = pDataStrm->Tell();
567 0 : pChpPlc->AppendFkpEntry( Strm().Tell() );
568 :
569 0 : WriteChar( 0x01 );
570 : static sal_uInt8 aArr1[] = {
571 : 0x02, 0x08, 0x81, // sprmCFFldVanish
572 : 0x03, 0x6a, 0,0,0,0, // sprmCPicLocation
573 :
574 : 0x06, 0x08, 0x01, // sprmCFData
575 : 0x55, 0x08, 0x01 // sprmCFSpec
576 : };
577 0 : sal_uInt8* pDataAdr = aArr1 + 5;
578 0 : Set_UInt32( pDataAdr, nDataStt );
579 :
580 0 : pChpPlc->AppendFkpEntry(Strm().Tell(),
581 0 : sizeof( aArr1 ), aArr1 );
582 :
583 0 : ::sw::WW8FFData aFFData;
584 :
585 0 : aFFData.setType(0);
586 0 : aFFData.setName(pFld->GetPar2());
587 0 : aFFData.setHelp(pFld->GetHelp());
588 0 : aFFData.setStatus(pFld->GetToolTip());
589 0 : aFFData.Write(pDataStrm);
590 :
591 0 : OutputField(0, ww::eFORMTEXT, OUString(), WRITEFIELD_CMD_END);
592 :
593 0 : const OUString fieldStr( pFld->ExpandField(true) );
594 0 : SwWW8Writer::WriteString16(Strm(), fieldStr, false);
595 :
596 : static sal_uInt8 aArr2[] = {
597 : 0x55, 0x08, 0x01, // sprmCFSpec
598 : 0x75, 0x08, 0x01 // ???
599 : };
600 :
601 0 : pDataAdr = aArr2 + 2;
602 0 : Set_UInt32( pDataAdr, nDataStt );
603 0 : pChpPlc->AppendFkpEntry(Strm().Tell(),
604 0 : sizeof( aArr2 ), aArr2 );
605 :
606 0 : OutputField(0, ww::eFORMTEXT, OUString(), WRITEFIELD_CLOSE);
607 0 : }
608 :
609 24 : PlcDrawObj::~PlcDrawObj()
610 : {
611 24 : }
612 :
613 : //Its irritating to have to change the RTL frames position into LTR ones
614 : //so that word will have to place them in the right place. Doubly so that
615 : //the SO drawings and writer frames have different ideas themselves as to
616 : //how to be positioned when in RTL mode!
617 8 : bool RTLGraphicsHack(SwTwips &rLeft, SwTwips nWidth,
618 : sal_Int16 eHoriOri, sal_Int16 eHoriRel, SwTwips nPageLeft,
619 : SwTwips nPageRight, SwTwips nPageSize)
620 : {
621 8 : bool bRet = false;
622 8 : if (eHoriOri == text::HoriOrientation::NONE)
623 : {
624 7 : if (eHoriRel == text::RelOrientation::PAGE_FRAME)
625 : {
626 0 : rLeft = nPageSize - rLeft;
627 0 : bRet = true;
628 : }
629 7 : else if (
630 6 : (eHoriRel == text::RelOrientation::PAGE_PRINT_AREA) ||
631 2 : (eHoriRel == text::RelOrientation::FRAME) ||
632 : (eHoriRel == text::RelOrientation::PRINT_AREA)
633 : )
634 : {
635 5 : rLeft = nPageSize - nPageLeft - nPageRight - rLeft;
636 5 : bRet = true;
637 : }
638 : }
639 8 : if (bRet)
640 5 : rLeft -= nWidth;
641 8 : return bRet;
642 : }
643 :
644 0 : bool RTLDrawingsHack(long &rLeft, long /*nWidth*/,
645 : sal_Int16 eHoriOri, sal_Int16 eHoriRel, SwTwips nPageLeft,
646 : SwTwips nPageRight, SwTwips nPageSize)
647 : {
648 0 : bool bRet = false;
649 0 : if (eHoriOri == text::HoriOrientation::NONE)
650 : {
651 0 : if (eHoriRel == text::RelOrientation::PAGE_FRAME)
652 : {
653 0 : rLeft = nPageSize + rLeft;
654 0 : bRet = true;
655 : }
656 0 : else if (
657 0 : (eHoriRel == text::RelOrientation::PAGE_PRINT_AREA) ||
658 0 : (eHoriRel == text::RelOrientation::FRAME) ||
659 : (eHoriRel == text::RelOrientation::PRINT_AREA)
660 : )
661 : {
662 0 : rLeft = nPageSize - nPageLeft - nPageRight + rLeft;
663 0 : bRet = true;
664 : }
665 : }
666 0 : return bRet;
667 : }
668 :
669 9 : bool WW8Export::MiserableRTLFrmFmtHack(SwTwips &rLeft, SwTwips &rRight,
670 : const sw::Frame &rFrmFmt)
671 : {
672 : //Require nasty bidi swap
673 9 : if (FRMDIR_HORI_RIGHT_TOP != pDoc->GetTextDirection(rFrmFmt.GetPosition()))
674 9 : return false;
675 :
676 0 : SwTwips nWidth = rRight - rLeft;
677 : SwTwips nPageLeft, nPageRight;
678 0 : SwTwips nPageSize = CurrentPageWidth(nPageLeft, nPageRight);
679 :
680 0 : const SwFmtHoriOrient& rHOr = rFrmFmt.GetFrmFmt().GetHoriOrient();
681 :
682 0 : bool bRet = false;
683 0 : sw::Frame::WriterSource eSource = rFrmFmt.GetWriterType();
684 0 : if (eSource == sw::Frame::eDrawing || eSource == sw::Frame::eFormControl)
685 : {
686 0 : if (RTLDrawingsHack(rLeft, nWidth, rHOr.GetHoriOrient(),
687 0 : rHOr.GetRelationOrient(), nPageLeft, nPageRight, nPageSize))
688 : {
689 0 : bRet = true;
690 : }
691 : }
692 : else
693 : {
694 0 : if (RTLGraphicsHack(rLeft, nWidth, rHOr.GetHoriOrient(),
695 0 : rHOr.GetRelationOrient(), nPageLeft, nPageRight, nPageSize))
696 : {
697 0 : bRet = true;
698 : }
699 : }
700 0 : if (bRet)
701 0 : rRight = rLeft + nWidth;
702 0 : return bRet;
703 : }
704 :
705 24 : void PlcDrawObj::WritePlc( WW8Export& rWrt ) const
706 : {
707 24 : if (8 > rWrt.pFib->nVersion) // Cannot export drawobject in vers 7-
708 24 : return;
709 :
710 24 : sal_uInt32 nFcStart = rWrt.pTableStrm->Tell();
711 :
712 24 : if (!maDrawObjs.empty())
713 : {
714 : // write CPs
715 3 : WW8Fib& rFib = *rWrt.pFib;
716 3 : WW8_CP nCpOffs = GetCpOffset(rFib);
717 :
718 3 : cDrawObjIter aEnd = maDrawObjs.end();
719 3 : cDrawObjIter aIter;
720 :
721 12 : for (aIter = maDrawObjs.begin(); aIter < aEnd; ++aIter)
722 9 : SwWW8Writer::WriteLong(*rWrt.pTableStrm, aIter->mnCp - nCpOffs);
723 :
724 3 : SwWW8Writer::WriteLong(*rWrt.pTableStrm, rFib.ccpText + rFib.ccpFtn +
725 3 : rFib.ccpHdr + rFib.ccpEdn + rFib.ccpTxbx + rFib.ccpHdrTxbx + 1);
726 :
727 12 : for (aIter = maDrawObjs.begin(); aIter < aEnd; ++aIter)
728 : {
729 : // write the fspa-struct
730 9 : const sw::Frame &rFrmFmt = aIter->maCntnt;
731 9 : const SwFrmFmt &rFmt = rFrmFmt.GetFrmFmt();
732 9 : const SdrObject* pObj = rFmt.FindRealSdrObject();
733 :
734 9 : Rectangle aRect;
735 9 : SwFmtVertOrient rVOr = rFmt.GetVertOrient();
736 18 : SwFmtHoriOrient rHOr = rFmt.GetHoriOrient();
737 : // #i30669# - convert the positioning attributes.
738 : // Most positions are converted, if layout information exists.
739 : const bool bPosConverted =
740 9 : WinwordAnchoring::ConvertPosition( rHOr, rVOr, rFmt );
741 :
742 9 : Point aObjPos;
743 9 : if (RES_FLYFRMFMT == rFmt.Which())
744 : {
745 2 : SwRect aLayRect(rFmt.FindLayoutRect(false, &aObjPos));
746 : // the Object is not visible - so get the values from
747 : // the format. The Position may not be correct.
748 2 : if( aLayRect.IsEmpty() )
749 0 : aRect.SetSize( rFmt.GetFrmSize().GetSize() );
750 : else
751 : {
752 : // #i56090# Do not only consider the first client
753 : // Note that we actually would have to find the maximum size of the
754 : // frame format clients. However, this already should work in most cases.
755 2 : const SwRect aSizeRect(rFmt.FindLayoutRect());
756 2 : if ( aSizeRect.Width() > aLayRect.Width() )
757 0 : aLayRect.Width( aSizeRect.Width() );
758 :
759 2 : aRect = aLayRect.SVRect();
760 : }
761 : }
762 : else
763 : {
764 : OSL_ENSURE(pObj, "wo ist das SDR-Object?");
765 7 : if (pObj)
766 : {
767 7 : aRect = pObj->GetSnapRect();
768 : }
769 : }
770 :
771 : // #i30669# - use converted position, if conversion is performed.
772 : // Unify position determination of Writer fly frames
773 : // and drawing objects.
774 9 : if ( bPosConverted )
775 : {
776 0 : aRect.SetPos( Point( rHOr.GetPos(), rVOr.GetPos() ) );
777 : }
778 : else
779 : {
780 9 : aRect -= aIter->maParentPos;
781 9 : aObjPos = aRect.TopLeft();
782 9 : if (text::VertOrientation::NONE == rVOr.GetVertOrient())
783 : {
784 : // #i22673#
785 9 : sal_Int16 eOri = rVOr.GetRelationOrient();
786 9 : if (eOri == text::RelOrientation::CHAR || eOri == text::RelOrientation::TEXT_LINE)
787 0 : aObjPos.Y() = -rVOr.GetPos();
788 : else
789 9 : aObjPos.Y() = rVOr.GetPos();
790 : }
791 9 : if (text::HoriOrientation::NONE == rHOr.GetHoriOrient())
792 9 : aObjPos.X() = rHOr.GetPos();
793 9 : aRect.SetPos( aObjPos );
794 : }
795 :
796 9 : sal_Int32 nThick = aIter->mnThick;
797 :
798 : //If we are being exported as an inline hack, set
799 : //corner to 0 and forget about border thickness for positioning
800 9 : if (rFrmFmt.IsInline())
801 : {
802 0 : aRect.SetPos(Point(0,0));
803 0 : nThick = 0;
804 : }
805 :
806 : // spid
807 9 : SwWW8Writer::WriteLong(*rWrt.pTableStrm, aIter->mnShapeId);
808 :
809 9 : SwTwips nLeft = aRect.Left() + nThick;
810 9 : SwTwips nRight = aRect.Right() - nThick;
811 :
812 : //Nasty swap for bidi if necessary
813 9 : rWrt.MiserableRTLFrmFmtHack(nLeft, nRight, rFrmFmt);
814 :
815 : //xaLeft/yaTop/xaRight/yaBottom - rel. to anchor
816 : //(most of) the border is outside the graphic is word, so
817 : //change dimensions to fit
818 9 : SwWW8Writer::WriteLong(*rWrt.pTableStrm, nLeft);
819 9 : SwWW8Writer::WriteLong(*rWrt.pTableStrm,aRect.Top() + nThick);
820 9 : SwWW8Writer::WriteLong(*rWrt.pTableStrm, nRight);
821 9 : SwWW8Writer::WriteLong(*rWrt.pTableStrm,aRect.Bottom() - nThick);
822 :
823 : //fHdr/bx/by/wr/wrk/fRcaSimple/fBelowText/fAnchorLock
824 9 : sal_uInt16 nFlags=0;
825 : //If nFlags isn't 0x14 its overridden by the escher properties
826 9 : if (FLY_AT_PAGE == rFmt.GetAnchor().GetAnchorId())
827 0 : nFlags = 0x0000;
828 : else
829 9 : nFlags = 0x0014; // x-rel to text, y-rel to text
830 :
831 9 : const SwFmtSurround& rSurr = rFmt.GetSurround();
832 9 : sal_uInt16 nContour = rSurr.IsContour() ? 0x0080 : 0x0040;
833 9 : SwSurround eSurround = rSurr.GetSurround();
834 :
835 : /*
836 : #i3958#
837 : The inline elements being export as anchored to character inside
838 : the shape field hack are required to be wrap through so as to flow
839 : over the following dummy 0x01 graphic
840 : */
841 9 : if (rFrmFmt.IsInline())
842 0 : eSurround = SURROUND_THROUGHT;
843 :
844 9 : switch (eSurround)
845 : {
846 : case SURROUND_NONE:
847 0 : nFlags |= 0x0020;
848 0 : break;
849 : case SURROUND_THROUGHT:
850 8 : nFlags |= 0x0060;
851 8 : break;
852 : case SURROUND_PARALLEL:
853 0 : nFlags |= 0x0000 | nContour;
854 0 : break;
855 : case SURROUND_IDEAL:
856 1 : nFlags |= 0x0600 | nContour;
857 1 : break;
858 : case SURROUND_LEFT:
859 0 : nFlags |= 0x0200 | nContour;
860 0 : break;
861 : case SURROUND_RIGHT:
862 0 : nFlags |= 0x0400 | nContour;
863 0 : break;
864 : default:
865 : OSL_ENSURE(!this, "Unsupported surround type for export");
866 0 : break;
867 : }
868 17 : if (pObj && (pObj->GetLayer() == rWrt.pDoc->GetHellId() ||
869 8 : pObj->GetLayer() == rWrt.pDoc->GetInvisibleHellId()))
870 : {
871 1 : nFlags |= 0x4000;
872 : }
873 :
874 : /*
875 : #i3958# Required to make this inline stuff work in WordXP, not
876 : needed for 2003 interestingly
877 : */
878 9 : if (rFrmFmt.IsInline())
879 0 : nFlags |= 0x8000;
880 :
881 9 : SwWW8Writer::WriteShort(*rWrt.pTableStrm, nFlags);
882 :
883 : // cTxbx
884 9 : SwWW8Writer::WriteLong(*rWrt.pTableStrm, 0);
885 9 : }
886 :
887 3 : RegisterWithFib(rFib, nFcStart, rWrt.pTableStrm->Tell() - nFcStart);
888 : }
889 : }
890 :
891 2 : void MainTxtPlcDrawObj::RegisterWithFib(WW8Fib &rFib, sal_uInt32 nStart,
892 : sal_uInt32 nLen) const
893 : {
894 2 : rFib.fcPlcfspaMom = nStart;
895 2 : rFib.lcbPlcfspaMom = nLen;
896 2 : }
897 :
898 2 : WW8_CP MainTxtPlcDrawObj::GetCpOffset(const WW8Fib &) const
899 : {
900 2 : return 0;
901 : }
902 :
903 1 : void HdFtPlcDrawObj::RegisterWithFib(WW8Fib &rFib, sal_uInt32 nStart,
904 : sal_uInt32 nLen) const
905 : {
906 1 : rFib.fcPlcfspaHdr = nStart;
907 1 : rFib.lcbPlcfspaHdr = nLen;
908 1 : }
909 :
910 1 : WW8_CP HdFtPlcDrawObj::GetCpOffset(const WW8Fib &rFib) const
911 : {
912 1 : return rFib.ccpText + rFib.ccpFtn;
913 : }
914 :
915 0 : DrawObj& DrawObj::operator=(const DrawObj& rOther)
916 : {
917 0 : mnCp = rOther.mnCp;
918 0 : mnShapeId = rOther.mnShapeId;
919 0 : maCntnt = rOther.maCntnt;
920 0 : maParentPos = rOther.maParentPos;
921 0 : mnThick = rOther.mnThick;
922 0 : mnDirection = rOther.mnDirection;
923 0 : mnHdFtIndex = rOther.mnHdFtIndex;
924 0 : return *this;
925 : }
926 :
927 9 : bool PlcDrawObj::Append( WW8Export& rWrt, WW8_CP nCp, const sw::Frame& rFmt,
928 : const Point& rNdTopLeft )
929 : {
930 9 : bool bRet = false;
931 9 : const SwFrmFmt &rFormat = rFmt.GetFrmFmt();
932 9 : if (TXT_HDFT == rWrt.nTxtTyp || TXT_MAINTEXT == rWrt.nTxtTyp)
933 : {
934 9 : if (RES_FLYFRMFMT == rFormat.Which())
935 : {
936 : // check for textflyframe and if it is the first in a Chain
937 2 : if (rFormat.GetCntnt().GetCntntIdx())
938 2 : bRet = true;
939 : }
940 : else
941 7 : bRet = true;
942 : }
943 :
944 9 : if (bRet)
945 : {
946 9 : DrawObj aObj(rFmt, nCp, rNdTopLeft, rWrt.TrueFrameDirection(rFormat),
947 18 : rWrt.GetHdFtIndex());
948 9 : maDrawObjs.push_back(aObj);
949 : }
950 9 : return bRet;
951 : }
952 :
953 9 : void DrawObj::SetShapeDetails(sal_uInt32 nId, sal_Int32 nThick)
954 : {
955 9 : mnShapeId = nId;
956 9 : mnThick = nThick;
957 9 : }
958 :
959 24 : bool WW8_WrPlcTxtBoxes::WriteTxt( WW8Export& rWrt )
960 : {
961 24 : rWrt.bInWriteEscher = true;
962 24 : WW8_CP& rccp=TXT_TXTBOX == nTyp ? rWrt.pFib->ccpTxbx : rWrt.pFib->ccpHdrTxbx;
963 :
964 24 : bool bRet = WriteGenericTxt( rWrt, nTyp, rccp );
965 :
966 24 : WW8_CP nCP = rWrt.Fc2Cp( rWrt.Strm().Tell() );
967 24 : WW8Fib& rFib = *rWrt.pFib;
968 24 : WW8_CP nMyOffset = rFib.ccpText + rFib.ccpFtn + rFib.ccpHdr + rFib.ccpAtn
969 24 : + rFib.ccpEdn;
970 24 : if( TXT_TXTBOX == nTyp )
971 12 : rWrt.pFldTxtBxs->Finish( nCP, nMyOffset );
972 : else
973 12 : rWrt.pFldHFTxtBxs->Finish( nCP, nMyOffset + rFib.ccpTxbx );
974 24 : rWrt.bInWriteEscher = false;
975 24 : return bRet;
976 : }
977 :
978 2 : void WW8_WrPlcTxtBoxes::Append( const SdrObject& rObj, sal_uInt32 nShapeId )
979 : {
980 2 : aCntnt.push_back( &rObj );
981 2 : aShapeIds.push_back( nShapeId );
982 : //save NULL, if we have an actual SdrObject
983 2 : aSpareFmts.push_back(NULL);
984 2 : }
985 :
986 0 : void WW8_WrPlcTxtBoxes::Append( const SwFrmFmt* pFmt, sal_uInt32 nShapeId )
987 : {
988 : //no sdr object, we insert a NULL in the aCntnt and save the real fmt in aSpareFmts.
989 0 : aCntnt.push_back( NULL );
990 0 : aShapeIds.push_back( nShapeId );
991 0 : aSpareFmts.push_back(pFmt);
992 0 : }
993 :
994 2 : const std::vector<sal_uInt32>* WW8_WrPlcTxtBoxes::GetShapeIdArr() const
995 : {
996 2 : return &aShapeIds;
997 : }
998 :
999 44 : sal_uInt32 WW8Export::GetSdrOrdNum( const SwFrmFmt& rFmt ) const
1000 : {
1001 : sal_uInt32 nOrdNum;
1002 44 : const SdrObject* pObj = rFmt.FindRealSdrObject();
1003 44 : if( pObj )
1004 44 : nOrdNum = pObj->GetOrdNum();
1005 : else
1006 : {
1007 : // no Layout for this format, then recalc the ordnum
1008 0 : SwFrmFmt* pFmt = (SwFrmFmt*)&rFmt;
1009 0 : nOrdNum = pDoc->GetSpzFrmFmts()->GetPos( pFmt );
1010 :
1011 0 : const SdrModel* pModel = pDoc->GetDrawModel();
1012 0 : if( pModel )
1013 0 : nOrdNum += pModel->GetPage( 0 )->GetObjCount();
1014 : }
1015 44 : return nOrdNum;
1016 : }
1017 :
1018 9 : void WW8Export::AppendFlyInFlys(const sw::Frame& rFrmFmt,
1019 : const Point& rNdTopLeft)
1020 : {
1021 : OSL_ENSURE(bWrtWW8, "this has gone horribly wrong");
1022 : OSL_ENSURE(!pEscher, "der EscherStream wurde schon geschrieben!");
1023 9 : if (pEscher)
1024 9 : return ;
1025 : PlcDrawObj *pDrwO;
1026 9 : if (TXT_HDFT == nTxtTyp)
1027 1 : pDrwO = pHFSdrObjs;
1028 : else
1029 8 : pDrwO = pSdrObjs;
1030 :
1031 9 : if (rFrmFmt.IsInline())
1032 : {
1033 : OutputField(0, ww::eSHAPE, FieldString(ww::eSHAPE),
1034 0 : WRITEFIELD_START | WRITEFIELD_CMD_START | WRITEFIELD_CMD_END);
1035 : }
1036 :
1037 9 : WW8_CP nCP = Fc2Cp(Strm().Tell());
1038 9 : bool bSuccess = pDrwO->Append(*this, nCP, rFrmFmt, rNdTopLeft);
1039 : OSL_ENSURE(bSuccess, "Couldn't export a graphical element!");
1040 :
1041 9 : if (bSuccess)
1042 : {
1043 : static const sal_uInt8 aSpec8[] =
1044 : {
1045 : 0x03, 0x6a, 0, 0, 0, 0, // sprmCObjLocation
1046 : 0x55, 0x08, 1 // sprmCFSpec
1047 : };
1048 : // fSpec-Attribut true
1049 : // Fuer DrawObjets muss ein Spezial-Zeichen
1050 : // in den Text und darum ein fSpec-Attribut
1051 9 : pChpPlc->AppendFkpEntry( Strm().Tell() );
1052 9 : WriteChar( 0x8 );
1053 9 : pChpPlc->AppendFkpEntry( Strm().Tell(), sizeof( aSpec8 ), aSpec8 );
1054 :
1055 : //Need dummy picture frame
1056 9 : if (rFrmFmt.IsInline())
1057 0 : OutGrf(rFrmFmt);
1058 : }
1059 :
1060 9 : if (rFrmFmt.IsInline())
1061 0 : OutputField(0, ww::eSHAPE, OUString(), WRITEFIELD_CLOSE);
1062 : }
1063 :
1064 196 : MSWord_SdrAttrIter::MSWord_SdrAttrIter( MSWordExportBase& rWr,
1065 : const EditTextObject& rEditObj, sal_uInt8 nTyp )
1066 196 : : MSWordAttrIter( rWr ), pEditObj(&rEditObj), pEditPool(0), mnTyp(nTyp)
1067 : {
1068 196 : NextPara( 0 );
1069 196 : }
1070 :
1071 211 : void MSWord_SdrAttrIter::NextPara( sal_Int32 nPar )
1072 : {
1073 211 : nPara = nPar;
1074 : // Attributwechsel an Pos 0 wird ignoriert, da davon ausgegangen
1075 : // wird, dass am Absatzanfang sowieso die Attribute neu ausgegeben
1076 : // werden.
1077 211 : aChrTxtAtrArr.clear();
1078 211 : aChrSetArr.clear();
1079 211 : nAktSwPos = nTmpSwPos = 0;
1080 :
1081 211 : SfxItemSet aSet( pEditObj->GetParaAttribs( nPara ));
1082 211 : pEditPool = aSet.GetPool();
1083 211 : eNdChrSet = ItemGet<SvxFontItem>(aSet,EE_CHAR_FONTINFO).GetCharSet();
1084 :
1085 211 : if( g_pBreakIt->GetBreakIter().is() )
1086 211 : nScript = g_pBreakIt->GetBreakIter()->getScriptType( pEditObj->GetText(nPara), 0);
1087 : else
1088 0 : nScript = i18n::ScriptType::LATIN;
1089 :
1090 211 : pEditObj->GetCharAttribs( nPara, aTxtAtrArr );
1091 211 : nAktSwPos = SearchNext( 1 );
1092 211 : }
1093 :
1094 12 : rtl_TextEncoding MSWord_SdrAttrIter::GetNextCharSet() const
1095 : {
1096 12 : if( !aChrSetArr.empty() )
1097 0 : return aChrSetArr.back();
1098 12 : return eNdChrSet;
1099 : }
1100 :
1101 : // der erste Parameter in SearchNext() liefert zurueck, ob es ein TxtAtr ist.
1102 407 : sal_Int32 MSWord_SdrAttrIter::SearchNext( sal_Int32 nStartPos )
1103 : {
1104 407 : sal_Int32 nMinPos = SAL_MAX_INT32;
1105 1869 : for(std::vector<EECharAttrib>::const_iterator i = aTxtAtrArr.begin(); i < aTxtAtrArr.end(); ++i)
1106 : {
1107 1462 : sal_Int32 nPos = i->nStart; // gibt erstes Attr-Zeichen
1108 1462 : if( nPos >= nStartPos && nPos <= nMinPos )
1109 : {
1110 0 : nMinPos = nPos;
1111 0 : SetCharSet(*i, true);
1112 : }
1113 :
1114 1462 : nPos = i->nEnd; // gibt letztes Attr-Zeichen + 1
1115 1462 : if( nPos >= nStartPos && nPos < nMinPos )
1116 : {
1117 196 : nMinPos = nPos;
1118 196 : SetCharSet(*i, false);
1119 : }
1120 : }
1121 407 : return nMinPos;
1122 : }
1123 :
1124 196 : void MSWord_SdrAttrIter::SetCharSet(const EECharAttrib& rAttr, bool bStart)
1125 : {
1126 196 : const SfxPoolItem& rItem = *rAttr.pAttr;
1127 196 : if( rItem.Which() != EE_CHAR_FONTINFO )
1128 : {
1129 391 : return;
1130 : }
1131 :
1132 1 : if( bStart )
1133 : {
1134 0 : rtl_TextEncoding eChrSet = ((SvxFontItem&)rItem).GetCharSet();
1135 0 : aChrSetArr.push_back( eChrSet );
1136 0 : aChrTxtAtrArr.push_back( &rAttr );
1137 : }
1138 : else
1139 : {
1140 : std::vector<const EECharAttrib*>::iterator it =
1141 1 : std::find( aChrTxtAtrArr.begin(), aChrTxtAtrArr.end(), &rAttr );
1142 1 : if ( it != aChrTxtAtrArr.end() )
1143 : {
1144 0 : aChrTxtAtrArr.erase( it );
1145 0 : aChrSetArr.erase( aChrSetArr.begin() + (it - aChrTxtAtrArr.begin()) );
1146 : }
1147 : }
1148 : }
1149 :
1150 0 : void MSWord_SdrAttrIter::OutEEField(const SfxPoolItem& rHt)
1151 : {
1152 0 : const SvxFieldItem &rField = (const SvxFieldItem &)rHt;
1153 0 : const SvxFieldData *pFld = rField.GetField();
1154 0 : if (pFld && pFld->ISA(SvxURLField))
1155 : {
1156 0 : sal_uInt8 nOldTxtTyp = m_rExport.nTxtTyp;
1157 0 : m_rExport.nTxtTyp = mnTyp;
1158 0 : const SvxURLField *pURL = (const SvxURLField *)pFld;
1159 0 : m_rExport.AttrOutput().StartURL( pURL->GetURL(), pURL->GetTargetFrame() );
1160 :
1161 0 : const OUString &rStr = pURL->GetRepresentation();
1162 0 : m_rExport.AttrOutput().RawText( rStr, true, GetNodeCharSet() ); // FIXME kendy: is the 'true' actually correct here? It was here before, but... ;-)
1163 :
1164 0 : m_rExport.AttrOutput().EndURL();
1165 0 : m_rExport.nTxtTyp = nOldTxtTyp;
1166 : }
1167 0 : }
1168 :
1169 211 : void MSWord_SdrAttrIter::OutAttr( sal_Int32 nSwPos )
1170 : {
1171 211 : OutParaAttr(true);
1172 :
1173 211 : if(!aTxtAtrArr.empty())
1174 : {
1175 197 : const SwModify* pOldMod = m_rExport.pOutFmtNode;
1176 197 : m_rExport.pOutFmtNode = 0;
1177 :
1178 197 : const SfxItemPool* pSrcPool = pEditPool;
1179 197 : const SfxItemPool& rDstPool = m_rExport.pDoc->GetAttrPool();
1180 :
1181 197 : nTmpSwPos = nSwPos;
1182 936 : for(std::vector<EECharAttrib>::const_iterator i = aTxtAtrArr.begin(); i < aTxtAtrArr.end(); ++i)
1183 : {
1184 739 : if (nSwPos >= i->nStart && nSwPos < i->nEnd)
1185 : {
1186 723 : sal_uInt16 nWhich = i->pAttr->Which();
1187 723 : if (nWhich == EE_FEATURE_FIELD)
1188 : {
1189 0 : OutEEField(*(i->pAttr));
1190 0 : continue;
1191 : }
1192 723 : if (nWhich == EE_FEATURE_TAB)
1193 : {
1194 0 : m_rExport.WriteChar(0x9);
1195 0 : continue;
1196 : }
1197 :
1198 723 : const sal_uInt16 nSlotId = pSrcPool->GetSlotId(nWhich);
1199 723 : if (nSlotId && nWhich != nSlotId)
1200 : {
1201 723 : nWhich = rDstPool.GetWhich(nSlotId);
1202 1446 : if (nWhich && nWhich != nSlotId &&
1203 1446 : nWhich < RES_UNKNOWNATR_BEGIN &&
1204 723 : m_rExport.CollapseScriptsforWordOk(nScript,nWhich))
1205 : {
1206 : // use always the SW-Which Id !
1207 647 : SfxPoolItem* pI = i->pAttr->Clone();
1208 647 : pI->SetWhich( nWhich );
1209 647 : m_rExport.AttrOutput().OutputItem( *pI );
1210 647 : delete pI;
1211 : }
1212 : }
1213 : }
1214 :
1215 739 : if( nSwPos < i->nStart )
1216 0 : break;
1217 : }
1218 :
1219 197 : nTmpSwPos = 0; // HasTextItem nur in dem obigen Bereich erlaubt
1220 197 : m_rExport.pOutFmtNode = pOldMod;
1221 : }
1222 211 : }
1223 :
1224 211 : bool MSWord_SdrAttrIter::IsTxtAttr(sal_Int32 nSwPos)
1225 : {
1226 950 : for (std::vector<EECharAttrib>::const_iterator i = aTxtAtrArr.begin(); i < aTxtAtrArr.end(); ++i)
1227 : {
1228 739 : if (nSwPos >= i->nStart && nSwPos < i->nEnd)
1229 : {
1230 1446 : if (i->pAttr->Which() == EE_FEATURE_FIELD ||
1231 723 : i->pAttr->Which() == EE_FEATURE_TAB)
1232 0 : return true;
1233 : }
1234 : }
1235 211 : return false;
1236 : }
1237 :
1238 : // HasItem ist fuer die Zusammenfassung des Doppel-Attributes Underline
1239 : // und WordLineMode als TextItems. OutAttr() ruft die Ausgabefunktion,
1240 : // die dann ueber HasItem() nach anderen Items an der
1241 : // Attribut-Anfangposition fragen kann.
1242 : // Es koennen nur Attribute mit Ende abgefragt werden.
1243 : // Es wird mit bDeep gesucht
1244 23 : const SfxPoolItem* MSWord_SdrAttrIter::HasTextItem(sal_uInt16 nWhich) const
1245 : {
1246 : nWhich = sw::hack::TransformWhichBetweenPools(*pEditPool,
1247 23 : m_rExport.pDoc->GetAttrPool(), nWhich);
1248 23 : if (nWhich)
1249 : {
1250 95 : for (std::vector<EECharAttrib>::const_iterator i = aTxtAtrArr.begin(); i < aTxtAtrArr.end(); ++i)
1251 : {
1252 94 : if (nWhich == i->pAttr->Which() && nTmpSwPos >= i->nStart && nTmpSwPos < i->nEnd)
1253 44 : return i->pAttr; // Found
1254 72 : if (nTmpSwPos < i->nStart)
1255 0 : return NULL; // dann kommt da nichts mehr
1256 : }
1257 : }
1258 1 : return NULL;
1259 : }
1260 :
1261 22 : const SfxPoolItem& MSWord_SdrAttrIter::GetItem( sal_uInt16 nWhich ) const
1262 : {
1263 : using sw::hack::GetSetWhichFromSwDocWhich;
1264 22 : const SfxPoolItem* pRet = HasTextItem(nWhich);
1265 22 : if (!pRet)
1266 : {
1267 0 : SfxItemSet aSet(pEditObj->GetParaAttribs(nPara));
1268 0 : nWhich = GetSetWhichFromSwDocWhich(aSet, *m_rExport.pDoc, nWhich);
1269 : OSL_ENSURE(nWhich, "Impossible, catastrophic failure imminent");
1270 0 : pRet = &aSet.Get(nWhich);
1271 : }
1272 22 : return *pRet;
1273 : }
1274 :
1275 417 : void MSWord_SdrAttrIter::OutParaAttr(bool bCharAttr)
1276 : {
1277 417 : SfxItemSet aSet( pEditObj->GetParaAttribs( nPara ));
1278 417 : if( aSet.Count() )
1279 : {
1280 417 : const SfxItemSet* pOldSet = m_rExport.GetCurItemSet();
1281 417 : m_rExport.SetCurItemSet( &aSet );
1282 :
1283 417 : SfxItemIter aIter( aSet );
1284 417 : const SfxPoolItem* pItem = aIter.GetCurItem();
1285 :
1286 417 : const SfxItemPool* pSrcPool = pEditPool,
1287 417 : * pDstPool = &m_rExport.pDoc->GetAttrPool();
1288 :
1289 778 : do {
1290 778 : sal_uInt16 nWhich = pItem->Which(),
1291 778 : nSlotId = pSrcPool->GetSlotId( nWhich );
1292 :
1293 2281 : if ( nSlotId && nWhich != nSlotId &&
1294 1450 : 0 != ( nWhich = pDstPool->GetWhich( nSlotId ) ) &&
1295 1991 : nWhich != nSlotId &&
1296 370 : ( bCharAttr ? ( nWhich >= RES_CHRATR_BEGIN && nWhich < RES_TXTATR_END )
1297 355 : : ( nWhich >= RES_PARATR_BEGIN && nWhich < RES_FRMATR_END ) ) )
1298 : {
1299 : // use always the SW-Which Id !
1300 133 : SfxPoolItem* pI = pItem->Clone();
1301 133 : pI->SetWhich( nWhich );
1302 133 : if (m_rExport.CollapseScriptsforWordOk(nScript,nWhich))
1303 133 : m_rExport.AttrOutput().OutputItem( *pI );
1304 133 : delete pI;
1305 : }
1306 778 : } while( !aIter.IsAtEnd() && 0 != ( pItem = aIter.NextItem() ) );
1307 417 : m_rExport.SetCurItemSet( pOldSet );
1308 417 : }
1309 417 : }
1310 :
1311 0 : void WW8Export::WriteSdrTextObj(const SdrObject& rObj, sal_uInt8 nTyp)
1312 : {
1313 0 : const SdrTextObj* pTxtObj = PTR_CAST(SdrTextObj, &rObj);
1314 : OSL_ENSURE(pTxtObj, "That is no SdrTextObj!");
1315 0 : if (!pTxtObj)
1316 0 : return;
1317 :
1318 0 : const OutlinerParaObject* pParaObj = 0;
1319 0 : bool bOwnParaObj = false;
1320 :
1321 : /*
1322 : #i13885#
1323 : When the object is actively being edited, that text is not set into
1324 : the objects normal text object, but lives in a separate object.
1325 : */
1326 0 : if (pTxtObj->IsTextEditActive())
1327 : {
1328 0 : pParaObj = pTxtObj->GetEditOutlinerParaObject();
1329 0 : bOwnParaObj = true;
1330 : }
1331 : else
1332 : {
1333 0 : pParaObj = pTxtObj->GetOutlinerParaObject();
1334 : }
1335 :
1336 0 : if( pParaObj )
1337 : {
1338 0 : WriteOutliner(*pParaObj, nTyp);
1339 0 : if( bOwnParaObj )
1340 0 : delete pParaObj;
1341 : }
1342 : }
1343 :
1344 5 : void WW8Export::WriteOutliner(const OutlinerParaObject& rParaObj, sal_uInt8 nTyp)
1345 : {
1346 5 : bool bAnyWrite = false;
1347 5 : const EditTextObject& rEditObj = rParaObj.GetTextObject();
1348 5 : MSWord_SdrAttrIter aAttrIter( *this, rEditObj, nTyp );
1349 :
1350 5 : sal_Int32 nPara = rEditObj.GetParagraphCount();
1351 5 : sal_uInt8 bNul = 0;
1352 10 : for( sal_Int32 n = 0; n < nPara; ++n )
1353 : {
1354 5 : if( n )
1355 0 : aAttrIter.NextPara( n );
1356 :
1357 5 : rtl_TextEncoding eChrSet = aAttrIter.GetNodeCharSet();
1358 :
1359 : OSL_ENSURE( pO->empty(), " pO ist am Zeilenanfang nicht leer" );
1360 :
1361 5 : OUString aStr( rEditObj.GetText( n ));
1362 5 : sal_Int32 nAktPos = 0;
1363 5 : const sal_Int32 nEnd = aStr.getLength();
1364 5 : do {
1365 5 : const sal_Int32 nNextAttr = std::min(aAttrIter.WhereNext(), nEnd);
1366 5 : rtl_TextEncoding eNextChrSet = aAttrIter.GetNextCharSet();
1367 :
1368 5 : bool bTxtAtr = aAttrIter.IsTxtAttr( nAktPos );
1369 5 : if( !bTxtAtr )
1370 : OutSwString( aStr, nAktPos, nNextAttr - nAktPos,
1371 5 : true, eChrSet );
1372 :
1373 : // Am Zeilenende werden die Attribute bis ueber das CR
1374 : // aufgezogen. Ausnahme: Fussnoten am Zeilenende
1375 5 : if( nNextAttr == nEnd && !bTxtAtr )
1376 5 : WriteCR(); // CR danach
1377 :
1378 : // Ausgabe der Zeichenattribute
1379 5 : aAttrIter.OutAttr( nAktPos ); // nAktPos - 1 ??
1380 5 : pChpPlc->AppendFkpEntry( Strm().Tell(),
1381 10 : pO->size(), pO->data() );
1382 5 : pO->clear();
1383 :
1384 : // Ausnahme: Fussnoten am Zeilenende
1385 5 : if( nNextAttr == nEnd && bTxtAtr )
1386 0 : WriteCR(); // CR danach
1387 5 : nAktPos = nNextAttr;
1388 5 : eChrSet = eNextChrSet;
1389 5 : aAttrIter.NextPos();
1390 : }
1391 5 : while( nAktPos < nEnd );
1392 :
1393 : OSL_ENSURE( pO->empty(), " pO ist am ZeilenEnde nicht leer" );
1394 :
1395 5 : pO->push_back( bNul ); // Style # as short
1396 5 : pO->push_back( bNul );
1397 :
1398 5 : aAttrIter.OutParaAttr(false);
1399 :
1400 5 : sal_uLong nPos = Strm().Tell();
1401 5 : pPapPlc->AppendFkpEntry( Strm().Tell(),
1402 10 : pO->size(), pO->data() );
1403 5 : pO->clear();
1404 5 : pChpPlc->AppendFkpEntry( nPos );
1405 5 : }
1406 :
1407 5 : bAnyWrite = 0 != nPara;
1408 5 : if( !bAnyWrite )
1409 0 : WriteStringAsPara( OUString() );
1410 5 : }
1411 :
1412 9 : void WinwordAnchoring::WriteData( EscherEx& rEx ) const
1413 : {
1414 : //Toplevel groups get their winword extra data attached, and sub elements
1415 : //use the defaults
1416 9 : if (rEx.GetGroupLevel() <= 1)
1417 : {
1418 9 : SvStream& rSt = rEx.GetStream();
1419 : //The last argument denotes the number of sub properties in this atom
1420 9 : if (mbInline)
1421 : {
1422 0 : rEx.AddAtom(18, DFF_msofbtUDefProp, 3, 3); //Prop id is 0xF122
1423 0 : rSt.WriteUInt16( (sal_uInt16)0x0390 ).WriteUInt32( sal_uInt32(3) );
1424 0 : rSt.WriteUInt16( (sal_uInt16)0x0392 ).WriteUInt32( sal_uInt32(3) );
1425 : //This sub property is required to be in the dummy inline frame as
1426 : //well
1427 0 : rSt.WriteUInt16( (sal_uInt16)0x053F ).WriteUInt32( nInlineHack );
1428 : }
1429 : else
1430 : {
1431 9 : rEx.AddAtom(24, DFF_msofbtUDefProp, 3, 4 ); //Prop id is 0xF122
1432 9 : rSt.WriteUInt16( (sal_uInt16)0x038F ).WriteUInt32( mnXAlign );
1433 9 : rSt.WriteUInt16( (sal_uInt16)0x0390 ).WriteUInt32( mnXRelTo );
1434 9 : rSt.WriteUInt16( (sal_uInt16)0x0391 ).WriteUInt32( mnYAlign );
1435 9 : rSt.WriteUInt16( (sal_uInt16)0x0392 ).WriteUInt32( mnYRelTo );
1436 : }
1437 : }
1438 9 : }
1439 :
1440 12 : void WW8Export::CreateEscher()
1441 : {
1442 12 : SfxItemState eBackSet = pDoc->GetPageDesc(0).GetMaster().
1443 12 : GetItemState(RES_BACKGROUND);
1444 12 : if (pHFSdrObjs->size() || pSdrObjs->size() || SFX_ITEM_SET == eBackSet)
1445 : {
1446 : OSL_ENSURE( !pEscher, "wer hat den Pointer nicht geloescht?" );
1447 3 : SvMemoryStream* pEscherStrm = new SvMemoryStream;
1448 3 : pEscherStrm->SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN);
1449 3 : pEscher = new SwEscherEx(pEscherStrm, *this);
1450 : }
1451 12 : }
1452 :
1453 12 : void WW8Export::WriteEscher()
1454 : {
1455 12 : if (pEscher)
1456 : {
1457 3 : sal_uLong nStart = pTableStrm->Tell();
1458 :
1459 3 : pEscher->WritePictures();
1460 3 : pEscher->FinishEscher();
1461 :
1462 3 : pFib->fcDggInfo = nStart;
1463 3 : pFib->lcbDggInfo = pTableStrm->Tell() - nStart;
1464 3 : delete pEscher, pEscher = 0;
1465 : }
1466 12 : }
1467 :
1468 3 : void SwEscherEx::WritePictures()
1469 : {
1470 3 : if( SvStream* pPicStrm = static_cast< SwEscherExGlobal& >( *mxGlobal ).GetPictureStream() )
1471 : {
1472 : // set the blip - entries to the correct stream pos
1473 3 : sal_Int32 nEndPos = rWrt.Strm().Tell();
1474 3 : mxGlobal->SetNewBlipStreamOffset( nEndPos );
1475 :
1476 3 : pPicStrm->Seek( 0 );
1477 3 : rWrt.Strm().WriteStream( *pPicStrm );
1478 : }
1479 3 : Flush();
1480 3 : }
1481 :
1482 : // Output- Routines for Escher Export
1483 :
1484 4 : SwEscherExGlobal::SwEscherExGlobal()
1485 : {
1486 4 : }
1487 :
1488 8 : SwEscherExGlobal::~SwEscherExGlobal()
1489 : {
1490 8 : }
1491 :
1492 4 : SvStream* SwEscherExGlobal::ImplQueryPictureStream()
1493 : {
1494 : // this function will be called exactly once
1495 4 : mxPicStrm.reset( new SvMemoryStream );
1496 4 : mxPicStrm->SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN);
1497 4 : return mxPicStrm.get();
1498 : }
1499 :
1500 4 : SwBasicEscherEx::SwBasicEscherEx(SvStream* pStrm, WW8Export& rWW8Wrt)
1501 4 : : EscherEx( EscherExGlobalRef( new SwEscherExGlobal ), pStrm), rWrt(rWW8Wrt), pEscherStrm(pStrm)
1502 : {
1503 4 : Init();
1504 4 : }
1505 :
1506 4 : SwBasicEscherEx::~SwBasicEscherEx()
1507 : {
1508 4 : }
1509 :
1510 1 : void SwBasicEscherEx::WriteFrmExtraData(const SwFrmFmt&)
1511 : {
1512 1 : AddAtom(4, ESCHER_ClientAnchor);
1513 1 : GetStream().WriteUInt32( (sal_uInt32)0x80000000 );
1514 1 : }
1515 :
1516 0 : void SwBasicEscherEx::WriteEmptyFlyFrame(const SwFrmFmt& rFmt, sal_uInt32 nShapeId)
1517 : {
1518 0 : OpenContainer(ESCHER_SpContainer);
1519 0 : AddShape(ESCHER_ShpInst_PictureFrame, 0xa00, nShapeId);
1520 : // store anchor attribute
1521 0 : WriteFrmExtraData(rFmt);
1522 :
1523 0 : AddAtom(6, DFF_msofbtUDefProp, 3, 1); //Prop id is 0xF122
1524 0 : GetStream().WriteUInt16( (sal_uInt16)0x053F ).WriteUInt32( nInlineHack );
1525 :
1526 0 : CloseContainer(); // ESCHER_SpContainer
1527 0 : }
1528 :
1529 2 : sal_uInt32 AddMirrorFlags(sal_uInt32 nFlags, const SwMirrorGrf &rMirror)
1530 : {
1531 2 : switch (rMirror.GetValue())
1532 : {
1533 : default:
1534 : case RES_MIRROR_GRAPH_DONT:
1535 2 : break;
1536 : case RES_MIRROR_GRAPH_VERT:
1537 0 : nFlags |= SHAPEFLAG_FLIPH;
1538 0 : break;
1539 : case RES_MIRROR_GRAPH_HOR:
1540 0 : nFlags |= SHAPEFLAG_FLIPV;
1541 0 : break;
1542 : case RES_MIRROR_GRAPH_BOTH:
1543 0 : nFlags |= SHAPEFLAG_FLIPH;
1544 0 : nFlags |= SHAPEFLAG_FLIPV;
1545 0 : break;
1546 :
1547 : }
1548 2 : return nFlags;
1549 : }
1550 : //For i120928,this function is added to export graphic of bullet
1551 0 : sal_Int32 SwBasicEscherEx::WriteGrfBullet(const Graphic& rGrf)
1552 : {
1553 0 : OpenContainer( ESCHER_SpContainer );
1554 0 : AddShape(ESCHER_ShpInst_PictureFrame, 0xa00,0x401);
1555 0 : EscherPropertyContainer aPropOpt;
1556 0 : GraphicObject aGraphicObject( rGrf );
1557 0 : OString aUniqueId = aGraphicObject.GetUniqueID();
1558 0 : if ( !aUniqueId.isEmpty() )
1559 : {
1560 0 : const MapMode aMap100mm( MAP_100TH_MM );
1561 0 : Size aSize( rGrf.GetPrefSize() );
1562 0 : if ( MAP_PIXEL == rGrf.GetPrefMapMode().GetMapUnit() )
1563 : {
1564 0 : aSize = Application::GetDefaultDevice()->PixelToLogic(aSize, aMap100mm );
1565 : }
1566 : else
1567 : {
1568 0 : aSize = OutputDevice::LogicToLogic( aSize,rGrf.GetPrefMapMode(), aMap100mm );
1569 : }
1570 0 : Point aEmptyPoint = Point();
1571 0 : Rectangle aRect( aEmptyPoint, aSize );
1572 0 : sal_uInt32 nBlibId = mxGlobal->GetBlibID( *(mxGlobal->QueryPictureStream()), aUniqueId,aRect, NULL, 0 );
1573 0 : if (nBlibId)
1574 0 : aPropOpt.AddOpt(ESCHER_Prop_pib, nBlibId, true);
1575 : }
1576 0 : aPropOpt.AddOpt( ESCHER_Prop_pibFlags, ESCHER_BlipFlagDefault );
1577 0 : aPropOpt.AddOpt( ESCHER_Prop_dyTextTop, DrawModelToEmu(0));
1578 0 : aPropOpt.AddOpt( ESCHER_Prop_dyTextBottom, DrawModelToEmu(0));
1579 0 : aPropOpt.AddOpt( ESCHER_Prop_dxTextLeft, DrawModelToEmu(0));
1580 0 : aPropOpt.AddOpt( ESCHER_Prop_dxTextRight, DrawModelToEmu(0));
1581 0 : aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x80000 );
1582 0 : aPropOpt.AddOpt( ESCHER_Prop_dyTextTop, 0 );
1583 0 : aPropOpt.AddOpt( ESCHER_Prop_dyTextBottom, 0 );
1584 0 : aPropOpt.AddOpt( ESCHER_Prop_dxTextLeft, 0 );
1585 0 : aPropOpt.AddOpt( ESCHER_Prop_dxTextRight, 0 );
1586 0 : const Color aTmpColor( COL_WHITE );
1587 0 : SvxBrushItem aBrush( aTmpColor, RES_BACKGROUND );
1588 0 : const SvxBrushItem *pRet = rWrt.GetCurrentPageBgBrush();
1589 0 : if (pRet && (pRet->GetGraphic() ||( pRet->GetColor() != COL_TRANSPARENT)))
1590 0 : aBrush = *pRet;
1591 0 : WriteBrushAttr(aBrush, aPropOpt);
1592 :
1593 0 : aPropOpt.AddOpt( ESCHER_Prop_pictureActive, 0 );
1594 0 : aPropOpt.Commit( GetStream() );
1595 0 : AddAtom(4, ESCHER_ClientAnchor);
1596 0 : GetStream().WriteUInt32( (sal_uInt32)0x80000000 );
1597 0 : CloseContainer();
1598 :
1599 0 : return 0;
1600 : }
1601 :
1602 2 : sal_Int32 SwBasicEscherEx::WriteGrfFlyFrame(const SwFrmFmt& rFmt, sal_uInt32 nShapeId)
1603 : {
1604 2 : sal_Int32 nBorderThick=0;
1605 2 : SwNoTxtNode *pNd = GetNoTxtNodeFromSwFrmFmt(rFmt);
1606 2 : SwGrfNode *pGrfNd = pNd ? pNd->GetGrfNode() : 0;
1607 : OSL_ENSURE(pGrfNd, "No SwGrfNode ?, suspicious");
1608 2 : if (!pGrfNd)
1609 0 : return nBorderThick;
1610 :
1611 2 : OpenContainer( ESCHER_SpContainer );
1612 :
1613 2 : const SwMirrorGrf &rMirror = pGrfNd->GetSwAttrSet().GetMirrorGrf();
1614 : AddShape(ESCHER_ShpInst_PictureFrame, AddMirrorFlags(0xa00, rMirror),
1615 2 : nShapeId);
1616 :
1617 2 : EscherPropertyContainer aPropOpt;
1618 :
1619 2 : sal_uInt32 nFlags = ESCHER_BlipFlagDefault;
1620 :
1621 2 : if (pGrfNd->IsLinkedFile())
1622 : {
1623 0 : OUString sURL;
1624 0 : pGrfNd->GetFileFilterNms( &sURL, 0 );
1625 :
1626 0 : ww::bytes aBuf;
1627 0 : SwWW8Writer::InsAsString16( aBuf, sURL );
1628 0 : SwWW8Writer::InsUInt16( aBuf, 0 );
1629 :
1630 0 : sal_uInt16 nArrLen = aBuf.size();
1631 0 : sal_uInt8* pArr = new sal_uInt8[ nArrLen ];
1632 0 : std::copy( aBuf.begin(), aBuf.end(), pArr);
1633 :
1634 0 : aPropOpt.AddOpt(ESCHER_Prop_pibName, true, nArrLen, pArr, nArrLen);
1635 : nFlags = ESCHER_BlipFlagLinkToFile | ESCHER_BlipFlagURL |
1636 0 : ESCHER_BlipFlagDoNotSave;
1637 : }
1638 : else
1639 : {
1640 2 : pGrfNd->SwapIn(true);
1641 :
1642 2 : Graphic aGraphic(pGrfNd->GetGrf());
1643 4 : GraphicObject aGraphicObject( aGraphic );
1644 4 : OString aUniqueId = aGraphicObject.GetUniqueID();
1645 :
1646 2 : if (!aUniqueId.isEmpty())
1647 : {
1648 2 : const MapMode aMap100mm( MAP_100TH_MM );
1649 2 : Size aSize( aGraphic.GetPrefSize() );
1650 :
1651 2 : if ( MAP_PIXEL == aGraphic.GetPrefMapMode().GetMapUnit() )
1652 : {
1653 : aSize = Application::GetDefaultDevice()->PixelToLogic(
1654 1 : aSize, aMap100mm );
1655 : }
1656 : else
1657 : {
1658 : aSize = OutputDevice::LogicToLogic( aSize,
1659 1 : aGraphic.GetPrefMapMode(), aMap100mm );
1660 : }
1661 :
1662 2 : Point aEmptyPoint = Point();
1663 2 : Rectangle aRect( aEmptyPoint, aSize );
1664 :
1665 2 : sal_uInt32 nBlibId = mxGlobal->GetBlibID( *QueryPictureStream(),
1666 2 : aUniqueId, aRect, NULL, 0 );
1667 2 : if (nBlibId)
1668 2 : aPropOpt.AddOpt(ESCHER_Prop_pib, nBlibId, true);
1669 2 : }
1670 : }
1671 :
1672 2 : aPropOpt.AddOpt( ESCHER_Prop_pibFlags, nFlags );
1673 2 : nBorderThick = WriteFlyFrameAttr(rFmt,mso_sptPictureFrame,aPropOpt);
1674 2 : WriteGrfAttr(*pGrfNd, aPropOpt);
1675 :
1676 2 : aPropOpt.Commit( GetStream() );
1677 :
1678 : // store anchor attribute
1679 2 : WriteFrmExtraData( rFmt );
1680 :
1681 2 : CloseContainer(); // ESCHER_SpContainer
1682 2 : return nBorderThick;
1683 : }
1684 :
1685 2 : void SwBasicEscherEx::WriteGrfAttr(const SwNoTxtNode& rNd,
1686 : EscherPropertyContainer& rPropOpt)
1687 : {
1688 : const SfxPoolItem* pItem;
1689 2 : sal_uInt32 nMode = GRAPHICDRAWMODE_STANDARD;
1690 2 : sal_Int32 nContrast = 0;
1691 2 : sal_Int16 nBrightness = 0;
1692 :
1693 4 : if (SFX_ITEM_SET == rNd.GetSwAttrSet().GetItemState(RES_GRFATR_CONTRAST,
1694 2 : true, &pItem))
1695 : {
1696 1 : nContrast = ((SfxInt16Item*)pItem)->GetValue();
1697 : }
1698 :
1699 4 : if (SFX_ITEM_SET == rNd.GetSwAttrSet().GetItemState(RES_GRFATR_LUMINANCE,
1700 2 : true, &pItem))
1701 : {
1702 1 : nBrightness = ((SfxInt16Item*)pItem)->GetValue();
1703 : }
1704 :
1705 4 : if (SFX_ITEM_SET == rNd.GetSwAttrSet().GetItemState(RES_GRFATR_DRAWMODE,
1706 2 : true, &pItem))
1707 : {
1708 1 : nMode = ((SfxEnumItem*)pItem)->GetValue();
1709 1 : if (nMode == GRAPHICDRAWMODE_WATERMARK)
1710 : {
1711 : /*
1712 : There is no real watermark mode in word, we must use standard
1713 : mode and modify our ones by 70% extra brightness and 70% less
1714 : contrast. This means that unmodified default OOo watermark
1715 : will turn back into watermark, and modified OOo watermark will
1716 : change into a close visual representation in standardmode
1717 : */
1718 0 : nBrightness += 70;
1719 0 : if (nBrightness > 100)
1720 0 : nBrightness = 100;
1721 0 : nContrast -= 70;
1722 0 : if (nContrast < -100)
1723 0 : nContrast = -100;
1724 0 : nMode = GRAPHICDRAWMODE_STANDARD;
1725 : }
1726 : }
1727 :
1728 2 : if (nMode == GRAPHICDRAWMODE_GREYS)
1729 0 : nMode = 0x40004;
1730 2 : else if (nMode == GRAPHICDRAWMODE_MONO)
1731 0 : nMode = 0x60006;
1732 : else
1733 2 : nMode = 0;
1734 2 : rPropOpt.AddOpt( ESCHER_Prop_pictureActive, nMode );
1735 :
1736 2 : if (nContrast != 0)
1737 : {
1738 0 : nContrast+=100;
1739 0 : if (nContrast == 100)
1740 0 : nContrast = 0x10000;
1741 0 : else if (nContrast < 100)
1742 : {
1743 0 : nContrast *= 0x10000;
1744 0 : nContrast /= 100;
1745 : }
1746 0 : else if (nContrast < 200)
1747 0 : nContrast = (100 * 0x10000) / (200-nContrast);
1748 : else
1749 0 : nContrast = 0x7fffffff;
1750 0 : rPropOpt.AddOpt( ESCHER_Prop_pictureContrast, nContrast);
1751 : }
1752 :
1753 2 : if (nBrightness != 0)
1754 0 : rPropOpt.AddOpt( ESCHER_Prop_pictureBrightness, nBrightness * 327 );
1755 :
1756 4 : if (SFX_ITEM_SET == rNd.GetSwAttrSet().GetItemState(RES_GRFATR_CROPGRF,
1757 2 : true, &pItem))
1758 : {
1759 1 : const Size aSz( rNd.GetTwipSize() );
1760 : sal_Int32 nVal;
1761 1 : if( 0 != ( nVal = ((SwCropGrf*)pItem )->GetLeft() ) )
1762 0 : rPropOpt.AddOpt( ESCHER_Prop_cropFromLeft, ToFract16( nVal, aSz.Width()) );
1763 1 : if( 0 != ( nVal = ((SwCropGrf*)pItem )->GetRight() ) )
1764 0 : rPropOpt.AddOpt( ESCHER_Prop_cropFromRight, ToFract16( nVal, aSz.Width()));
1765 1 : if( 0 != ( nVal = ((SwCropGrf*)pItem )->GetTop() ) )
1766 0 : rPropOpt.AddOpt( ESCHER_Prop_cropFromTop, ToFract16( nVal, aSz.Height()));
1767 1 : if( 0 != ( nVal = ((SwCropGrf*)pItem )->GetBottom() ) )
1768 0 : rPropOpt.AddOpt( ESCHER_Prop_cropFromBottom, ToFract16( nVal, aSz.Height()));
1769 : }
1770 2 : }
1771 :
1772 0 : void SwBasicEscherEx::SetPicId(const SdrObject &, sal_uInt32,
1773 : EscherPropertyContainer &)
1774 : {
1775 0 : }
1776 :
1777 1 : void SwEscherEx::SetPicId(const SdrObject &rSdrObj, sal_uInt32 nShapeId,
1778 : EscherPropertyContainer &rPropOpt)
1779 : {
1780 1 : pTxtBxs->Append(rSdrObj, nShapeId);
1781 1 : sal_uInt32 nPicId = pTxtBxs->Count();
1782 1 : nPicId *= 0x10000;
1783 1 : rPropOpt.AddOpt( ESCHER_Prop_pictureId, nPicId );
1784 1 : }
1785 :
1786 0 : sal_Int32 SwBasicEscherEx::WriteOLEFlyFrame(const SwFrmFmt& rFmt, sal_uInt32 nShapeId)
1787 : {
1788 0 : sal_Int32 nBorderThick = 0;
1789 0 : if (const SdrObject* pSdrObj = rFmt.FindRealSdrObject())
1790 : {
1791 0 : SwNodeIndex aIdx(*rFmt.GetCntnt().GetCntntIdx(), 1);
1792 0 : SwOLENode& rOLENd = *aIdx.GetNode().GetOLENode();
1793 0 : sal_Int64 nAspect = rOLENd.GetAspect();
1794 :
1795 0 : uno::Reference < embed::XEmbeddedObject > xObj(rOLENd.GetOLEObj().GetOleRef());
1796 :
1797 : // the rectangle is used to transport the size of the object
1798 : // the left, top corner is set to ( 0, 0 ) by default constructor,
1799 : // if the width and height are set correctly bRectIsSet should be set to true
1800 0 : awt::Rectangle aRect;
1801 0 : bool bRectIsSet = false;
1802 :
1803 : // TODO/LATER: should the icon size be stored in case of iconified object?
1804 0 : if ( xObj.is() && nAspect != embed::Aspects::MSOLE_ICON )
1805 : {
1806 : try
1807 : {
1808 0 : awt::Size aSize = xObj->getVisualAreaSize( nAspect );
1809 0 : aRect.Width = aSize.Width;
1810 0 : aRect.Height = aSize.Height;
1811 0 : bRectIsSet = true;
1812 : }
1813 0 : catch( const uno::Exception& )
1814 : {}
1815 : }
1816 :
1817 : /*
1818 : #i5970#
1819 : Export floating ole2 .doc ver 8+ wmf ole2 previews as emf previews
1820 : instead ==> allows unicode text to be preserved
1821 : */
1822 : #ifdef OLE_PREVIEW_AS_EMF
1823 0 : const Graphic* pGraphic = rOLENd.GetGraphic();
1824 : #endif
1825 0 : OpenContainer(ESCHER_SpContainer);
1826 :
1827 0 : EscherPropertyContainer aPropOpt;
1828 0 : const SwMirrorGrf &rMirror = rOLENd.GetSwAttrSet().GetMirrorGrf();
1829 : WriteOLEPicture(aPropOpt, AddMirrorFlags(0xa00 | SHAPEFLAG_OLESHAPE,
1830 0 : rMirror), pGraphic ? *pGraphic : Graphic(), *pSdrObj, nShapeId, bRectIsSet ? &aRect : NULL );
1831 :
1832 0 : nBorderThick = WriteFlyFrameAttr(rFmt, mso_sptPictureFrame, aPropOpt);
1833 0 : WriteGrfAttr(rOLENd, aPropOpt);
1834 0 : aPropOpt.Commit(GetStream());
1835 :
1836 : // store anchor attribute
1837 0 : WriteFrmExtraData( rFmt );
1838 :
1839 0 : CloseContainer(); // ESCHER_SpContainer
1840 : }
1841 0 : return nBorderThick;
1842 : }
1843 :
1844 5 : void SwBasicEscherEx::WriteBrushAttr(const SvxBrushItem &rBrush,
1845 : EscherPropertyContainer& rPropOpt)
1846 : {
1847 5 : bool bSetOpacity = false;
1848 5 : sal_uInt32 nOpaque = 0;
1849 5 : if (const GraphicObject *pGraphicObject = rBrush.GetGraphicObject())
1850 : {
1851 0 : OString aUniqueId = pGraphicObject->GetUniqueID();
1852 0 : if (!aUniqueId.isEmpty())
1853 : {
1854 0 : const Graphic &rGraphic = pGraphicObject->GetGraphic();
1855 0 : Size aSize(rGraphic.GetPrefSize());
1856 0 : const MapMode aMap100mm(MAP_100TH_MM);
1857 0 : if (MAP_PIXEL == rGraphic.GetPrefMapMode().GetMapUnit())
1858 : {
1859 : aSize = Application::GetDefaultDevice()->PixelToLogic(
1860 0 : aSize, aMap100mm);
1861 : }
1862 : else
1863 : {
1864 : aSize = OutputDevice::LogicToLogic(aSize,
1865 0 : rGraphic.GetPrefMapMode(), aMap100mm);
1866 : }
1867 :
1868 0 : Point aEmptyPoint = Point();
1869 0 : Rectangle aRect(aEmptyPoint, aSize);
1870 :
1871 0 : sal_uInt32 nBlibId = mxGlobal->GetBlibID( *QueryPictureStream(),
1872 0 : aUniqueId, aRect, NULL, 0);
1873 0 : if (nBlibId)
1874 0 : rPropOpt.AddOpt(ESCHER_Prop_fillBlip,nBlibId,true);
1875 : }
1876 :
1877 0 : if (0 != (nOpaque = pGraphicObject->GetAttr().GetTransparency()))
1878 0 : bSetOpacity = true;
1879 :
1880 0 : rPropOpt.AddOpt( ESCHER_Prop_fillType, ESCHER_FillPicture );
1881 0 : rPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x140014 );
1882 0 : rPropOpt.AddOpt( ESCHER_Prop_fillBackColor, 0 );
1883 : }
1884 : else
1885 : {
1886 5 : sal_uInt32 nFillColor = GetColor(rBrush.GetColor(), false);
1887 5 : rPropOpt.AddOpt( ESCHER_Prop_fillColor, nFillColor );
1888 5 : rPropOpt.AddOpt( ESCHER_Prop_fillBackColor, nFillColor ^ 0xffffff );
1889 5 : rPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x100010 );
1890 :
1891 5 : if (0 != (nOpaque = rBrush.GetColor().GetTransparency()))
1892 1 : bSetOpacity = true;
1893 : }
1894 :
1895 5 : if (bSetOpacity)
1896 : {
1897 1 : nOpaque = (nOpaque * 100) / 0xFE;
1898 1 : nOpaque = ((100 - nOpaque) << 16) / 100;
1899 1 : rPropOpt.AddOpt(ESCHER_Prop_fillOpacity, nOpaque);
1900 : }
1901 5 : }
1902 :
1903 4 : static bool lcl_isInHeader(const SwFrmFmt& rFmt)
1904 : {
1905 4 : const SwFlyFrmFmt* pFlyFrmFmt = dynamic_cast<const SwFlyFrmFmt*>(&rFmt);
1906 4 : if (!pFlyFrmFmt)
1907 1 : return false;
1908 3 : SwFlyFrm* pFlyFrm = const_cast<SwFlyFrm*>(pFlyFrmFmt->GetFrm());
1909 3 : if (!pFlyFrm) // fdo#54648: "hidden" drawing object has no layout frame
1910 : {
1911 0 : return false;
1912 : }
1913 3 : SwPageFrm* pPageFrm = pFlyFrm->FindPageFrmOfAnchor();
1914 3 : SwFrm* pHeader = pPageFrm->Lower();
1915 3 : if (pHeader->GetType() == FRM_HEADER)
1916 : {
1917 2 : const SwFrm* pFrm = pFlyFrm->GetAnchorFrm();
1918 9 : while (pFrm)
1919 : {
1920 6 : if (pFrm == pHeader)
1921 1 : return true;
1922 5 : pFrm = pFrm->GetUpper();
1923 : }
1924 : }
1925 2 : return false;
1926 : }
1927 :
1928 4 : sal_Int32 SwBasicEscherEx::WriteFlyFrameAttr(const SwFrmFmt& rFmt,
1929 : MSO_SPT eShapeType, EscherPropertyContainer& rPropOpt)
1930 : {
1931 4 : sal_Int32 nLineWidth=0;
1932 : const SfxPoolItem* pItem;
1933 4 : bool bFirstLine = true;
1934 4 : if (SFX_ITEM_SET == rFmt.GetItemState(RES_BOX, true, &pItem))
1935 : {
1936 : static const sal_uInt16 aExhperProp[4] =
1937 : {
1938 : ESCHER_Prop_dyTextTop, ESCHER_Prop_dyTextBottom,
1939 : ESCHER_Prop_dxTextLeft, ESCHER_Prop_dxTextRight
1940 : };
1941 : const SvxBorderLine* pLine;
1942 :
1943 15 : for( sal_uInt16 n = 0; n < 4; ++n )
1944 12 : if( 0 != ( pLine = ((SvxBoxItem*)pItem)->GetLine( n )) )
1945 : {
1946 4 : if( bFirstLine )
1947 : {
1948 1 : sal_uInt32 nLineColor = GetColor(pLine->GetColor(), false);
1949 1 : rPropOpt.AddOpt( ESCHER_Prop_lineColor, nLineColor );
1950 : rPropOpt.AddOpt( ESCHER_Prop_lineBackColor,
1951 1 : nLineColor ^ 0xffffff );
1952 :
1953 : MSO_LineStyle eStyle;
1954 1 : if( pLine->isDouble() )
1955 : {
1956 : // double line
1957 0 : nLineWidth = pLine->GetWidth();
1958 0 : if( pLine->GetInWidth() == pLine->GetOutWidth() )
1959 0 : eStyle = mso_lineDouble;
1960 0 : else if( pLine->GetInWidth() < pLine->GetOutWidth() )
1961 0 : eStyle = mso_lineThickThin;
1962 : else
1963 0 : eStyle = mso_lineThinThick;
1964 : }
1965 : else
1966 : {
1967 : // simple line
1968 1 : eStyle = mso_lineSimple;
1969 1 : nLineWidth = pLine->GetWidth();
1970 : }
1971 :
1972 1 : rPropOpt.AddOpt( ESCHER_Prop_lineStyle, eStyle );
1973 : rPropOpt.AddOpt( ESCHER_Prop_lineWidth,
1974 1 : DrawModelToEmu( nLineWidth ));
1975 :
1976 1 : MSO_LineDashing eDashing = mso_lineSolid;
1977 1 : switch (pLine->GetBorderLineStyle())
1978 : {
1979 : case table::BorderLineStyle::DASHED:
1980 0 : eDashing = mso_lineDashGEL;
1981 0 : break;
1982 : case table::BorderLineStyle::DOTTED:
1983 1 : eDashing = mso_lineDotGEL;
1984 1 : break;
1985 : case table::BorderLineStyle::SOLID:
1986 : default:
1987 0 : break;
1988 : }
1989 1 : rPropOpt.AddOpt( ESCHER_Prop_lineDashing, eDashing );
1990 1 : rPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x8000E );
1991 :
1992 : //Use import logic to determine how much of border will go
1993 : //outside graphic
1994 : nLineWidth = SwMSDffManager::GetEscherLineMatch(
1995 1 : eStyle,eShapeType,nLineWidth);
1996 1 : bFirstLine = false;
1997 : }
1998 4 : rPropOpt.AddOpt( aExhperProp[ n ], DrawModelToEmu(
1999 8 : ((SvxBoxItem*)pItem)->GetDistance( n ) ));
2000 : }
2001 : else
2002 : // MM If there is no line the distance should be set to 0
2003 8 : rPropOpt.AddOpt( aExhperProp[ n ], DrawModelToEmu(0));
2004 : }
2005 4 : if( bFirstLine ) // no valid line found
2006 : {
2007 3 : rPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x80000 );
2008 3 : rPropOpt.AddOpt( ESCHER_Prop_dyTextTop, 0 );
2009 3 : rPropOpt.AddOpt( ESCHER_Prop_dyTextBottom, 0 );
2010 3 : rPropOpt.AddOpt( ESCHER_Prop_dxTextLeft, 0 );
2011 3 : rPropOpt.AddOpt( ESCHER_Prop_dxTextRight, 0 );
2012 : }
2013 4 : const SwAttrSet& rAttrSet = rFmt.GetAttrSet();
2014 4 : if (SFX_ITEM_ON == rAttrSet.GetItemState(RES_BOX, false, &pItem))
2015 : {
2016 3 : const SvxBoxItem* pBox = (const SvxBoxItem*)pItem;
2017 3 : if( pBox )
2018 : {
2019 : const SfxPoolItem* pShadItem;
2020 3 : if (SFX_ITEM_ON
2021 3 : == rAttrSet.GetItemState(RES_SHADOW, true, &pShadItem))
2022 : {
2023 0 : const SvxShadowItem* pSI = (const SvxShadowItem*)pShadItem;
2024 :
2025 0 : const sal_uInt16 nCstScale = 635; // unit scale between AOO and MS Word
2026 0 : const sal_uInt32 nShadowType = 131074; // shadow type of ms word. need to set the default value.
2027 :
2028 0 : sal_uInt32 nColor = (sal_uInt32)(pSI->GetColor().GetColor()) ;
2029 0 : sal_Int32 nOffX = pSI->GetWidth() * nCstScale;
2030 0 : sal_Int32 nOffY = pSI->GetWidth() * nCstScale;
2031 0 : sal_uInt32 nShadow = nShadowType;
2032 :
2033 0 : SvxShadowLocation eLocation = pSI->GetLocation();
2034 0 : if( (eLocation!=SVX_SHADOW_NONE) && (pSI->GetWidth()!=0) )
2035 : {
2036 0 : switch( eLocation )
2037 : {
2038 : case SVX_SHADOW_TOPLEFT:
2039 : {
2040 0 : nOffX = -nOffX;
2041 0 : nOffY = -nOffY;
2042 : }
2043 0 : break;
2044 : case SVX_SHADOW_TOPRIGHT:
2045 : {
2046 0 : nOffY = -nOffY;
2047 : }
2048 0 : break;
2049 : case SVX_SHADOW_BOTTOMLEFT:
2050 : {
2051 0 : nOffX = -nOffX;
2052 : }
2053 0 : break;
2054 : case SVX_SHADOW_BOTTOMRIGHT:
2055 0 : break;
2056 : default:
2057 0 : break;
2058 : }
2059 :
2060 0 : rPropOpt.AddOpt( DFF_Prop_shadowColor, wwUtility::RGBToBGR((nColor)));
2061 0 : rPropOpt.AddOpt( DFF_Prop_shadowOffsetX, nOffX );
2062 0 : rPropOpt.AddOpt( DFF_Prop_shadowOffsetY, nOffY );
2063 0 : rPropOpt.AddOpt( DFF_Prop_fshadowObscured, nShadow );
2064 : }
2065 : }
2066 : }
2067 : }
2068 :
2069 : // SwWW8ImplReader::Read_GrafLayer() imports these as opaque
2070 : // unconditionally, so if both are true, don't export the property.
2071 4 : bool bIsInHeader = lcl_isInHeader(rFmt);
2072 4 : bool bIsThrought = rFmt.GetSurround().GetValue() == SURROUND_THROUGHT;
2073 :
2074 4 : if (bIsInHeader)
2075 : {
2076 1 : const SvxBrushItem& rBrush(rFmt.GetBackground());
2077 1 : WriteBrushAttr(rBrush, rPropOpt);
2078 : }
2079 : else
2080 : {
2081 3 : SvxBrushItem aBrush(rWrt.TrueFrameBgBrush(rFmt));
2082 3 : WriteBrushAttr(aBrush, rPropOpt);
2083 : }
2084 :
2085 4 : const SdrObject* pObj = rFmt.FindRealSdrObject();
2086 :
2087 11 : if( pObj && (pObj->GetLayer() == GetHellLayerId() ||
2088 8 : pObj->GetLayer() == GetInvisibleHellId() ) && !(bIsInHeader && bIsThrought))
2089 : {
2090 0 : rPropOpt.AddOpt( ESCHER_Prop_fPrint, 0x200020 );
2091 : }
2092 :
2093 4 : PreWriteHyperlinkWithinFly(rFmt,rPropOpt);
2094 :
2095 4 : return nLineWidth;
2096 : }
2097 :
2098 3 : sal_Int32 SwEscherEx::WriteFlyFrameAttr(const SwFrmFmt& rFmt, MSO_SPT eShapeType,
2099 : EscherPropertyContainer& rPropOpt)
2100 : {
2101 : sal_Int32 nLineWidth = SwBasicEscherEx::WriteFlyFrameAttr(rFmt, eShapeType,
2102 3 : rPropOpt);
2103 :
2104 : /*
2105 : These are not in SwBasicEscherEx::WriteFlyFrameAttr because inline objs
2106 : can't do it in word and it hacks it in by stretching the graphic that
2107 : way, perhaps we should actually draw in this space into the graphic we
2108 : are exporting!
2109 : */
2110 : const SfxPoolItem* pItem;
2111 3 : if (SFX_ITEM_SET == rFmt.GetItemState(RES_LR_SPACE, true, &pItem))
2112 : {
2113 : rPropOpt.AddOpt( ESCHER_Prop_dxWrapDistLeft,
2114 2 : DrawModelToEmu( ((SvxLRSpaceItem*)pItem)->GetLeft() ) );
2115 : rPropOpt.AddOpt( ESCHER_Prop_dxWrapDistRight,
2116 2 : DrawModelToEmu( ((SvxLRSpaceItem*)pItem)->GetRight() ) );
2117 : }
2118 : else
2119 : {
2120 1 : rPropOpt.AddOpt( ESCHER_Prop_dxWrapDistLeft, 0 );
2121 1 : rPropOpt.AddOpt( ESCHER_Prop_dxWrapDistRight, 0 );
2122 : }
2123 :
2124 3 : if (SFX_ITEM_SET == rFmt.GetItemState(RES_UL_SPACE, true, &pItem))
2125 : {
2126 : rPropOpt.AddOpt( ESCHER_Prop_dyWrapDistTop,
2127 0 : DrawModelToEmu( ((SvxULSpaceItem*)pItem)->GetUpper() ) );
2128 : rPropOpt.AddOpt( ESCHER_Prop_dyWrapDistBottom,
2129 0 : DrawModelToEmu( ((SvxULSpaceItem*)pItem)->GetLower() ) );
2130 : }
2131 :
2132 3 : if (rFmt.GetSurround().IsContour())
2133 : {
2134 0 : if (const SwNoTxtNode *pNd = GetNoTxtNodeFromSwFrmFmt(rFmt))
2135 : {
2136 0 : const PolyPolygon *pPolyPoly = pNd->HasContour();
2137 0 : if (pPolyPoly && pPolyPoly->Count())
2138 : {
2139 0 : Polygon aPoly(PolygonFromPolyPolygon(*pPolyPoly));
2140 0 : const Size &rOrigSize = pNd->GetGraphic().GetPrefSize();
2141 0 : Fraction aMapPolyX(ww::nWrap100Percent, rOrigSize.Width());
2142 0 : Fraction aMapPolyY(ww::nWrap100Percent, rOrigSize.Height());
2143 0 : aPoly.Scale(aMapPolyX, aMapPolyY);
2144 :
2145 : /*
2146 : a) stretch right bound by 15twips
2147 : b) shrink bottom bound to where it would have been in word
2148 : c) Move it to the left by 15twips
2149 :
2150 : See the import for details
2151 : */
2152 0 : const Size &rSize = pNd->GetTwipSize();
2153 0 : Fraction aMoveHack(ww::nWrap100Percent, rSize.Width());
2154 0 : aMoveHack *= Fraction(15, 1);
2155 0 : long nMove(aMoveHack);
2156 :
2157 : Fraction aHackX(ww::nWrap100Percent + nMove,
2158 0 : ww::nWrap100Percent);
2159 : Fraction aHackY(ww::nWrap100Percent - nMove,
2160 0 : ww::nWrap100Percent);
2161 0 : aPoly.Scale(aHackX, aHackY);
2162 :
2163 0 : aPoly.Move(-nMove, 0);
2164 :
2165 0 : SvMemoryStream aPolyDump;
2166 0 : aPolyDump.SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN);
2167 :
2168 0 : sal_uInt16 nLen = aPoly.GetSize();
2169 0 : aPolyDump.WriteUInt16( nLen );
2170 0 : aPolyDump.WriteUInt16( nLen );
2171 0 : aPolyDump.WriteUInt16( sal_uInt16(8) );
2172 0 : for (sal_uInt16 nI = 0; nI < nLen; ++nI)
2173 : {
2174 0 : aPolyDump.WriteUInt32( sal_uInt32(aPoly[nI].X()) );
2175 0 : aPolyDump.WriteUInt32( sal_uInt32(aPoly[nI].Y()) );
2176 : }
2177 :
2178 0 : sal_uInt16 nArrLen = msword_cast<sal_uInt16>(aPolyDump.Tell());
2179 0 : void *pArr = const_cast<void *>(aPolyDump.GetData());
2180 : //PropOpt wants to own the buffer
2181 0 : aPolyDump.ObjectOwnsMemory(false);
2182 : rPropOpt.AddOpt(DFF_Prop_pWrapPolygonVertices, false,
2183 0 : nArrLen, static_cast<sal_uInt8 *>(pArr), nArrLen);
2184 : }
2185 : }
2186 : }
2187 :
2188 3 : PreWriteHyperlinkWithinFly(rFmt,rPropOpt);
2189 :
2190 3 : return nLineWidth;
2191 : }
2192 :
2193 4 : void SwBasicEscherEx::Init()
2194 : {
2195 4 : MapUnit eMap = MAP_TWIP;
2196 4 : if (SdrModel *pModel = rWrt.pDoc->GetDrawModel())
2197 : {
2198 : // PPT arbeitet nur mit Einheiten zu 576DPI
2199 : // WW hingegen verwendet twips, dh. 1440DPI.
2200 4 : eMap = pModel->GetScaleUnit();
2201 : }
2202 :
2203 : // MS-DFF-Properties sind grossteils in EMU (English Metric Units) angegeben
2204 : // 1mm=36000emu, 1twip=635emu
2205 4 : Fraction aFact(360, 1);
2206 4 : aFact /= GetMapFactor(MAP_100TH_MM, eMap).X();
2207 : // create little values
2208 4 : aFact = Fraction(aFact.GetNumerator(), aFact.GetDenominator());
2209 4 : mnEmuMul = aFact.GetNumerator();
2210 4 : mnEmuDiv = aFact.GetDenominator();
2211 :
2212 4 : SetHellLayerId(rWrt.pDoc->GetHellId());
2213 4 : }
2214 :
2215 0 : sal_Int32 SwBasicEscherEx::ToFract16(sal_Int32 nVal, sal_uInt32 nMax) const
2216 : {
2217 0 : if (nMax)
2218 : {
2219 0 : sal_Int32 nMSVal = (nVal / 65536) * nMax;
2220 0 : nMSVal += (nVal * 65536 ) / nMax;
2221 0 : return nMSVal;
2222 : }
2223 0 : return 0;
2224 : }
2225 :
2226 3 : SdrLayerID SwBasicEscherEx::GetInvisibleHellId() const
2227 : {
2228 3 : return rWrt.pDoc->GetInvisibleHellId();
2229 : }
2230 :
2231 1 : void SwBasicEscherEx::WritePictures()
2232 : {
2233 1 : if( SvStream* pPicStrm = static_cast< SwEscherExGlobal& >( *mxGlobal ).GetPictureStream() )
2234 : {
2235 : // set the blip - entries to the correct stream pos
2236 1 : sal_Int32 nEndPos = pPicStrm->Tell();
2237 1 : mxGlobal->WriteBlibStoreEntry(*pEscherStrm, 1, true, nEndPos);
2238 :
2239 1 : pPicStrm->Seek(0);
2240 1 : pEscherStrm->WriteStream( *pPicStrm );
2241 : }
2242 1 : }
2243 :
2244 3 : SwEscherEx::SwEscherEx(SvStream* pStrm, WW8Export& rWW8Wrt)
2245 : : SwBasicEscherEx(pStrm, rWW8Wrt),
2246 3 : pTxtBxs(0)
2247 : {
2248 3 : aHostData.SetClientData(&aWinwordAnchoring);
2249 3 : OpenContainer( ESCHER_DggContainer );
2250 :
2251 3 : sal_uInt16 nColorCount = 4;
2252 3 : pStrm ->WriteUInt16( (sal_uInt16)( nColorCount << 4 ) ) // instance
2253 3 : .WriteUInt16( (sal_uInt16)ESCHER_SplitMenuColors ) // record type
2254 6 : .WriteUInt32( (sal_uInt32)( nColorCount * 4 ) ) // size
2255 3 : .WriteUInt32( (sal_uInt32)0x08000004 )
2256 3 : .WriteUInt32( (sal_uInt32)0x08000001 )
2257 3 : .WriteUInt32( (sal_uInt32)0x08000002 )
2258 3 : .WriteUInt32( (sal_uInt32)0x100000f7 );
2259 :
2260 3 : CloseContainer(); // ESCHER_DggContainer
2261 :
2262 3 : sal_uInt8 i = 2; // for header/footer and the other
2263 3 : PlcDrawObj *pSdrObjs = rWrt.pHFSdrObjs;
2264 3 : pTxtBxs = rWrt.pHFTxtBxs;
2265 :
2266 : // if no header/footer -> skip over
2267 3 : if (!pSdrObjs->size())
2268 : {
2269 2 : --i;
2270 2 : pSdrObjs = rWrt.pSdrObjs;
2271 2 : pTxtBxs = rWrt.pTxtBxs;
2272 : }
2273 :
2274 7 : for( ; i--; pSdrObjs = rWrt.pSdrObjs, pTxtBxs = rWrt.pTxtBxs )
2275 : {
2276 : // "dummy char" (or any Count ?) - why? This knows only M$
2277 4 : GetStream().WriteChar( (sal_Char)i );
2278 :
2279 4 : OpenContainer( ESCHER_DgContainer );
2280 :
2281 4 : EnterGroup( 0 );
2282 :
2283 4 : sal_uLong nSecondShapeId = pSdrObjs == rWrt.pSdrObjs ? GenerateShapeId() : 0;
2284 :
2285 : // write now all Writer-/DrawObjects
2286 4 : DrawObjPointerVector aSorted;
2287 4 : MakeZOrderArrAndFollowIds(pSdrObjs->GetObjArr(), aSorted);
2288 :
2289 4 : sal_uInt32 nShapeId=0;
2290 4 : DrawObjPointerIter aEnd = aSorted.end();
2291 13 : for (DrawObjPointerIter aIter = aSorted.begin(); aIter != aEnd; ++aIter)
2292 : {
2293 9 : sal_Int32 nBorderThick=0;
2294 9 : DrawObj *pObj = (*aIter);
2295 : OSL_ENSURE(pObj, "impossible");
2296 9 : if (!pObj)
2297 0 : continue;
2298 9 : const sw::Frame &rFrame = pObj->maCntnt;
2299 9 : const SwFrmFmt& rFmt = rFrame.GetFrmFmt();
2300 :
2301 9 : switch (rFrame.GetWriterType())
2302 : {
2303 : case sw::Frame::eTxtBox:
2304 : case sw::Frame::eOle:
2305 : case sw::Frame::eGraphic:
2306 2 : nBorderThick = WriteFlyFrm(*pObj, nShapeId, aSorted);
2307 2 : break;
2308 : case sw::Frame::eFormControl:
2309 1 : WriteOCXControl(rFmt, nShapeId = GenerateShapeId());
2310 1 : break;
2311 : case sw::Frame::eDrawing:
2312 : {
2313 6 : aWinwordAnchoring.SetAnchoring(rFmt);
2314 6 : const SdrObject* pSdrObj = rFmt.FindRealSdrObject();
2315 6 : if (pSdrObj)
2316 : {
2317 6 : bool bSwapInPage = false;
2318 6 : if (!pSdrObj->GetPage())
2319 : {
2320 0 : if (SdrModel* pModel = rWrt.pDoc->GetDrawModel())
2321 : {
2322 0 : if (SdrPage *pPage = pModel->GetPage(0))
2323 : {
2324 0 : bSwapInPage = true;
2325 0 : (const_cast<SdrObject*>(pSdrObj))->SetPage(pPage);
2326 : }
2327 : }
2328 : }
2329 :
2330 6 : nShapeId = AddSdrObject(*pSdrObj);
2331 :
2332 6 : if (bSwapInPage)
2333 0 : (const_cast<SdrObject*>(pSdrObj))->SetPage(0);
2334 : }
2335 : #if OSL_DEBUG_LEVEL > 0
2336 : else
2337 : OSL_ENSURE( !this, "Where is the SDR-Object?" );
2338 : #endif
2339 : }
2340 6 : break;
2341 : default:
2342 0 : break;
2343 : }
2344 :
2345 9 : if( !nShapeId )
2346 : {
2347 0 : nShapeId = AddDummyShape();
2348 : }
2349 :
2350 9 : pObj->SetShapeDetails(nShapeId, nBorderThick);
2351 : }
2352 :
2353 4 : EndSdrObjectPage(); // ???? Bugfix for 74724
2354 :
2355 4 : if( nSecondShapeId )
2356 : {
2357 3 : OpenContainer( ESCHER_SpContainer );
2358 :
2359 3 : AddShape( ESCHER_ShpInst_Rectangle, 0xe00, nSecondShapeId );
2360 :
2361 3 : EscherPropertyContainer aPropOpt;
2362 3 : const SwFrmFmt &rFmt = rWrt.pDoc->GetPageDesc(0).GetMaster();
2363 3 : const SfxPoolItem* pItem = 0;
2364 : SfxItemState eState = rFmt.GetItemState(RES_BACKGROUND, true,
2365 3 : &pItem);
2366 3 : if (SFX_ITEM_SET == eState && pItem)
2367 : {
2368 1 : const SvxBrushItem* pBrush = (const SvxBrushItem*)pItem;
2369 1 : WriteBrushAttr(*pBrush, aPropOpt);
2370 :
2371 1 : SvxGraphicPosition ePos = pBrush->GetGraphicPos();
2372 1 : if( ePos != GPOS_NONE && ePos != GPOS_AREA )
2373 : {
2374 : /* #i56806# 0x033F parameter specifies a 32-bit field of shape boolean properties.
2375 : 0x10001 means fBackground and fUsefBackground flag are true thus background
2376 : picture will be shown as "tiled" fill.*/
2377 0 : aPropOpt.AddOpt( ESCHER_Prop_fBackground, 0x10001 );
2378 : }
2379 : }
2380 3 : aPropOpt.AddOpt( ESCHER_Prop_lineColor, 0x8000001 );
2381 3 : aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x00080008 );
2382 3 : aPropOpt.AddOpt( ESCHER_Prop_shadowColor, 0x8000002 );
2383 3 : aPropOpt.AddOpt( ESCHER_Prop_lineWidth, 0 );
2384 :
2385 3 : aPropOpt.Commit( *pStrm );
2386 :
2387 3 : AddAtom( 4, ESCHER_ClientData );
2388 3 : GetStream().WriteInt32( static_cast<sal_Int32>(1) );
2389 :
2390 3 : CloseContainer(); // ESCHER_SpContainer
2391 : }
2392 4 : CloseContainer(); // ESCHER_DgContainer
2393 4 : }
2394 3 : }
2395 :
2396 6 : SwEscherEx::~SwEscherEx()
2397 : {
2398 6 : }
2399 :
2400 3 : void SwEscherEx::FinishEscher()
2401 : {
2402 3 : pEscherStrm->Seek(0);
2403 3 : rWrt.pTableStrm->WriteStream( *pEscherStrm );
2404 3 : delete pEscherStrm, pEscherStrm = 0;
2405 3 : }
2406 :
2407 : /** method to perform conversion of positioning attributes with the help
2408 : of corresponding layout information
2409 :
2410 : #i30669#
2411 : Because most of the Writer object positions doesn't correspond to the
2412 : object positions in WW8, this method converts the positioning
2413 : attributes. For this conversion the corresponding layout information
2414 : is needed. If no layout information exists - e.g. no layout exists - no
2415 : conversion is performed.
2416 : No conversion is performed for as-character anchored objects. Whose
2417 : object positions are already treated special in method <WriteData(..)>.
2418 :
2419 : @param _iorHoriOri
2420 : input/output parameter - containing the current horizontal position
2421 : attributes, which are converted by this method.
2422 :
2423 : @param _iorVertOri
2424 : input/output parameter - containing the current vertical position
2425 : attributes, which are converted by this method.
2426 :
2427 : @param _rFrmFmt
2428 : input parameter - frame format of the anchored object
2429 :
2430 : @return boolean, indicating, if a conversion has been performed.
2431 : */
2432 18 : bool WinwordAnchoring::ConvertPosition( SwFmtHoriOrient& _iorHoriOri,
2433 : SwFmtVertOrient& _iorVertOri,
2434 : const SwFrmFmt& _rFrmFmt )
2435 : {
2436 18 : const RndStdIds eAnchor = _rFrmFmt.GetAnchor().GetAnchorId();
2437 :
2438 18 : if ( (FLY_AS_CHAR == eAnchor) || (FLY_AT_FLY == eAnchor) )
2439 : {
2440 : // no conversion for as-character or at frame anchored objects
2441 0 : return false;
2442 : }
2443 :
2444 : // determine anchored object
2445 18 : SwAnchoredObject* pAnchoredObj( 0L );
2446 : {
2447 18 : const SwContact* pContact = _rFrmFmt.FindContactObj();
2448 18 : if ( pContact )
2449 : {
2450 18 : std::list<SwAnchoredObject*> aAnchoredObjs;
2451 18 : pContact->GetAnchoredObjs( aAnchoredObjs );
2452 18 : if ( !aAnchoredObjs.empty() )
2453 : {
2454 18 : pAnchoredObj = aAnchoredObjs.front();
2455 18 : }
2456 : }
2457 : }
2458 18 : if ( !pAnchoredObj )
2459 : {
2460 : // no anchored object found. Thus, the needed layout information can't
2461 : // be determined. --> no conversion
2462 0 : return false;
2463 : }
2464 : // no conversion for anchored drawing object, which aren't attached to an
2465 : // anchor frame.
2466 : // This is the case for drawing objects, which are anchored inside a page
2467 : // header/footer of an *unused* page style.
2468 32 : if ( dynamic_cast<SwAnchoredDrawObject*>(pAnchoredObj) &&
2469 36 : !pAnchoredObj->GetAnchorFrm() )
2470 : {
2471 0 : return false;
2472 : }
2473 :
2474 18 : bool bConverted( false );
2475 :
2476 : // determine value of attribute 'Follow text flow', because positions aligned
2477 : // at page areas have to be converted, if it's set.
2478 18 : const bool bFollowTextFlow = _rFrmFmt.GetFollowTextFlow().GetValue();
2479 :
2480 : // check, if horizontal and vertical position have to be converted due to
2481 : // the fact, that the object is anchored at a paragraph, which has a "column
2482 : // break before" attribute
2483 18 : bool bConvDueToAnchoredAtColBreakPara( false );
2484 52 : if ( ( (eAnchor == FLY_AT_PARA) || (eAnchor == FLY_AT_CHAR) ) &&
2485 54 : _rFrmFmt.GetAnchor().GetCntntAnchor() &&
2486 18 : _rFrmFmt.GetAnchor().GetCntntAnchor()->nNode.GetNode().IsTxtNode() )
2487 : {
2488 : SwTxtNode& rAnchorTxtNode =
2489 18 : dynamic_cast<SwTxtNode&>(_rFrmFmt.GetAnchor().GetCntntAnchor()->nNode.GetNode());
2490 18 : const SvxFmtBreakItem* pBreak = &(ItemGet<SvxFmtBreakItem>(rAnchorTxtNode, RES_BREAK));
2491 36 : if ( pBreak &&
2492 18 : pBreak->GetBreak() == SVX_BREAK_COLUMN_BEFORE )
2493 : {
2494 0 : bConvDueToAnchoredAtColBreakPara = true;
2495 : }
2496 : }
2497 :
2498 : // convert horizontal position, if needed
2499 : {
2500 : enum HoriConv { NO_CONV, CONV2PG, CONV2COL, CONV2CHAR };
2501 18 : HoriConv eHoriConv( NO_CONV );
2502 :
2503 : // determine, if conversion has to be performed due to the position orientation
2504 18 : bool bConvDueToOrientation( false );
2505 : {
2506 18 : const sal_Int16 eHOri = _iorHoriOri.GetHoriOrient();
2507 18 : bConvDueToOrientation = eHOri == text::HoriOrientation::LEFT || eHOri == text::HoriOrientation::RIGHT ||
2508 36 : eHOri == text::HoriOrientation::INSIDE || eHOri == text::HoriOrientation::OUTSIDE ||
2509 36 : ( eHOri != text::HoriOrientation::CENTER && _iorHoriOri.IsPosToggle() );
2510 : }
2511 :
2512 : // determine conversion type due to the position relation
2513 18 : if ( bConvDueToAnchoredAtColBreakPara )
2514 : {
2515 0 : eHoriConv = CONV2PG;
2516 : }
2517 36 : else if ( _iorHoriOri.IsPosToggle()
2518 18 : && _iorHoriOri.GetHoriOrient() == text::HoriOrientation::RIGHT )
2519 : {
2520 0 : eHoriConv = NO_CONV;
2521 0 : _iorHoriOri.SetHoriOrient( text::HoriOrientation::OUTSIDE );
2522 : }
2523 : else
2524 : {
2525 18 : switch ( _iorHoriOri.GetRelationOrient() )
2526 : {
2527 : case text::RelOrientation::PAGE_FRAME:
2528 : case text::RelOrientation::PAGE_PRINT_AREA:
2529 : {
2530 0 : if ( bConvDueToOrientation || bFollowTextFlow )
2531 0 : eHoriConv = CONV2PG;
2532 : }
2533 0 : break;
2534 : case text::RelOrientation::PAGE_LEFT:
2535 : case text::RelOrientation::PAGE_RIGHT:
2536 : {
2537 : // relation not supported by WW8. Thus, conversion always needed.
2538 0 : eHoriConv = CONV2PG;
2539 : }
2540 0 : break;
2541 : case text::RelOrientation::FRAME:
2542 : {
2543 18 : if ( bConvDueToOrientation )
2544 0 : eHoriConv = CONV2COL;
2545 : }
2546 18 : break;
2547 : case text::RelOrientation::PRINT_AREA:
2548 : case text::RelOrientation::FRAME_LEFT:
2549 : case text::RelOrientation::FRAME_RIGHT:
2550 : {
2551 : // relation not supported by WW8. Thus, conversion always needed.
2552 0 : eHoriConv = CONV2COL;
2553 : }
2554 0 : break;
2555 : case text::RelOrientation::CHAR:
2556 : {
2557 0 : if ( bConvDueToOrientation )
2558 0 : eHoriConv = CONV2CHAR;
2559 : }
2560 0 : break;
2561 : default:
2562 : OSL_FAIL( "<WinwordAnchoring::ConvertPosition(..)> - unknown horizontal relation" );
2563 : }
2564 : }
2565 18 : if ( eHoriConv != NO_CONV )
2566 : {
2567 0 : _iorHoriOri.SetHoriOrient( text::HoriOrientation::NONE );
2568 0 : SwTwips nPosX( 0L );
2569 : {
2570 0 : Point aPos;
2571 0 : if ( eHoriConv == CONV2PG )
2572 : {
2573 0 : _iorHoriOri.SetRelationOrient( text::RelOrientation::PAGE_FRAME );
2574 : // #i33818#
2575 0 : bool bRelToTableCell( false );
2576 : aPos = pAnchoredObj->GetRelPosToPageFrm( bFollowTextFlow,
2577 0 : bRelToTableCell );
2578 0 : if ( bRelToTableCell )
2579 : {
2580 0 : _iorHoriOri.SetRelationOrient( text::RelOrientation::PAGE_PRINT_AREA );
2581 : }
2582 : }
2583 0 : else if ( eHoriConv == CONV2COL )
2584 : {
2585 0 : _iorHoriOri.SetRelationOrient( text::RelOrientation::FRAME );
2586 0 : aPos = pAnchoredObj->GetRelPosToAnchorFrm();
2587 : }
2588 0 : else if ( eHoriConv == CONV2CHAR )
2589 : {
2590 0 : _iorHoriOri.SetRelationOrient( text::RelOrientation::CHAR );
2591 0 : aPos = pAnchoredObj->GetRelPosToChar();
2592 : }
2593 : // No distinction between layout directions, because of missing
2594 : // information about WW8 in vertical layout.
2595 0 : nPosX = aPos.X();
2596 : }
2597 0 : _iorHoriOri.SetPos( nPosX );
2598 0 : bConverted = true;
2599 : }
2600 : }
2601 :
2602 : // convert vertical position, if needed
2603 : {
2604 : enum VertConv { NO_CONV, CONV2PG, CONV2PARA, CONV2LINE };
2605 18 : VertConv eVertConv( NO_CONV );
2606 :
2607 : // determine, if conversion has to be performed due to the position orientation
2608 18 : bool bConvDueToOrientation( false );
2609 : {
2610 18 : const sal_Int16 eVOri = _iorVertOri.GetVertOrient();
2611 18 : bConvDueToOrientation = ( eVOri == text::VertOrientation::TOP ||
2612 18 : eVOri == text::VertOrientation::BOTTOM ||
2613 18 : eVOri == text::VertOrientation::CHAR_TOP ||
2614 18 : eVOri == text::VertOrientation::CHAR_BOTTOM ||
2615 18 : eVOri == text::VertOrientation::CHAR_CENTER ||
2616 18 : eVOri == text::VertOrientation::LINE_TOP ||
2617 36 : eVOri == text::VertOrientation::LINE_BOTTOM ||
2618 18 : eVOri == text::VertOrientation::LINE_CENTER );
2619 : }
2620 :
2621 : // determine conversion type due to the position relation
2622 18 : if ( bConvDueToAnchoredAtColBreakPara )
2623 : {
2624 0 : eVertConv = CONV2PG;
2625 : }
2626 : else
2627 : {
2628 18 : switch ( _iorVertOri.GetRelationOrient() )
2629 : {
2630 : case text::RelOrientation::PAGE_FRAME:
2631 : case text::RelOrientation::PAGE_PRINT_AREA:
2632 : {
2633 0 : if ( bConvDueToOrientation || bFollowTextFlow )
2634 0 : eVertConv = CONV2PG;
2635 : }
2636 0 : break;
2637 : case text::RelOrientation::FRAME:
2638 : {
2639 36 : if ( bConvDueToOrientation ||
2640 18 : _iorVertOri.GetVertOrient() == text::VertOrientation::CENTER )
2641 : {
2642 0 : eVertConv = CONV2PARA;
2643 : }
2644 : }
2645 18 : break;
2646 : case text::RelOrientation::PRINT_AREA:
2647 : {
2648 : // relation not supported by WW8. Thus, conversion always needed.
2649 0 : eVertConv = CONV2PARA;
2650 : }
2651 0 : break;
2652 : case text::RelOrientation::CHAR:
2653 : {
2654 : // relation not supported by WW8. Thus, conversion always needed.
2655 0 : eVertConv = CONV2PARA;
2656 : }
2657 0 : break;
2658 : case text::RelOrientation::TEXT_LINE:
2659 : {
2660 0 : if ( bConvDueToOrientation ||
2661 0 : _iorVertOri.GetVertOrient() == text::VertOrientation::NONE )
2662 : {
2663 0 : eVertConv = CONV2LINE;
2664 : }
2665 : }
2666 0 : break;
2667 : case text::RelOrientation::PAGE_LEFT:
2668 : case text::RelOrientation::PAGE_RIGHT:
2669 : case text::RelOrientation::FRAME_LEFT:
2670 : case text::RelOrientation::FRAME_RIGHT:
2671 : default:
2672 : OSL_FAIL( "<WinwordAnchoring::ConvertPosition(..)> - unknown vertical relation" );
2673 : }
2674 : }
2675 :
2676 18 : if ( eVertConv != NO_CONV )
2677 : {
2678 0 : _iorVertOri.SetVertOrient( text::VertOrientation::NONE );
2679 0 : SwTwips nPosY( 0L );
2680 : {
2681 0 : Point aPos;
2682 0 : if ( eVertConv == CONV2PG )
2683 : {
2684 0 : _iorVertOri.SetRelationOrient( text::RelOrientation::PAGE_FRAME );
2685 : // #i33818#
2686 0 : bool bRelToTableCell( false );
2687 : aPos = pAnchoredObj->GetRelPosToPageFrm( bFollowTextFlow,
2688 0 : bRelToTableCell );
2689 0 : if ( bRelToTableCell )
2690 : {
2691 0 : _iorVertOri.SetRelationOrient( text::RelOrientation::PAGE_PRINT_AREA );
2692 : }
2693 : }
2694 0 : else if ( eVertConv == CONV2PARA )
2695 : {
2696 0 : _iorVertOri.SetRelationOrient( text::RelOrientation::FRAME );
2697 0 : aPos = pAnchoredObj->GetRelPosToAnchorFrm();
2698 : }
2699 0 : else if ( eVertConv == CONV2LINE )
2700 : {
2701 0 : _iorVertOri.SetRelationOrient( text::RelOrientation::TEXT_LINE );
2702 0 : aPos = pAnchoredObj->GetRelPosToLine();
2703 : }
2704 : // No distinction between layout directions, because of missing
2705 : // information about WW8 in vertical layout.
2706 0 : nPosY = aPos.Y();
2707 : }
2708 0 : _iorVertOri.SetPos( nPosY );
2709 0 : bConverted = true;
2710 : }
2711 : }
2712 :
2713 18 : return bConverted;
2714 : }
2715 :
2716 9 : void WinwordAnchoring::SetAnchoring(const SwFrmFmt& rFmt)
2717 : {
2718 9 : const RndStdIds eAnchor = rFmt.GetAnchor().GetAnchorId();
2719 9 : mbInline = (eAnchor == FLY_AS_CHAR);
2720 :
2721 9 : SwFmtHoriOrient rHoriOri = rFmt.GetHoriOrient();
2722 18 : SwFmtVertOrient rVertOri = rFmt.GetVertOrient();
2723 :
2724 : // #i30669# - convert the positioning attributes.
2725 : // Most positions are converted, if layout information exists.
2726 9 : const bool bPosConverted = ConvertPosition( rHoriOri, rVertOri, rFmt );
2727 :
2728 9 : const sal_Int16 eHOri = rHoriOri.GetHoriOrient();
2729 9 : const sal_Int16 eVOri = rVertOri.GetVertOrient(); // #i22673#
2730 :
2731 9 : const sal_Int16 eHRel = rHoriOri.GetRelationOrient();
2732 9 : const sal_Int16 eVRel = rVertOri.GetRelationOrient();
2733 :
2734 : // horizontal Adjustment
2735 9 : switch (eHOri)
2736 : {
2737 : default:
2738 : case text::HoriOrientation::NONE:
2739 9 : mnXAlign = 0;
2740 9 : break;
2741 : case text::HoriOrientation::LEFT:
2742 0 : mnXAlign = 1;
2743 0 : break;
2744 : case text::HoriOrientation::CENTER:
2745 0 : mnXAlign = 2;
2746 0 : break;
2747 : case text::HoriOrientation::RIGHT:
2748 0 : mnXAlign = 3;
2749 0 : break;
2750 : case text::HoriOrientation::INSIDE:
2751 0 : mnXAlign = 4;
2752 0 : break;
2753 : case text::HoriOrientation::OUTSIDE:
2754 0 : mnXAlign = 5;
2755 0 : break;
2756 : }
2757 :
2758 : // vertical Adjustment
2759 : // #i22673#
2760 : // When adjustment is vertically relative to line or to char
2761 : // bottom becomes top and vice versa
2762 9 : const bool bVertSwap = !bPosConverted &&
2763 9 : ( (eVRel == text::RelOrientation::CHAR) ||
2764 9 : (eVRel == text::RelOrientation::TEXT_LINE) );
2765 9 : switch (eVOri)
2766 : {
2767 : default:
2768 : case text::VertOrientation::NONE:
2769 9 : mnYAlign = 0;
2770 9 : break;
2771 : case text::VertOrientation::TOP:
2772 : case text::VertOrientation::LINE_TOP:
2773 : case text::VertOrientation::CHAR_TOP:
2774 0 : mnYAlign = bVertSwap ? 3 : 1;
2775 0 : break;
2776 : case text::VertOrientation::CENTER:
2777 : case text::VertOrientation::LINE_CENTER:
2778 0 : mnYAlign = 2;
2779 0 : break;
2780 : case text::VertOrientation::BOTTOM:
2781 : case text::VertOrientation::LINE_BOTTOM:
2782 : case text::VertOrientation::CHAR_BOTTOM:
2783 0 : mnYAlign = bVertSwap ? 1 : 3;
2784 0 : break;
2785 : }
2786 :
2787 : // Adjustment is horizontally relative to...
2788 9 : switch (eHRel)
2789 : {
2790 : case text::RelOrientation::PAGE_PRINT_AREA:
2791 0 : mnXRelTo = 0;
2792 0 : break;
2793 : case text::RelOrientation::PAGE_FRAME:
2794 : case text::RelOrientation::PAGE_LEFT: //:-(
2795 : case text::RelOrientation::PAGE_RIGHT: //:-(
2796 0 : mnXRelTo = 1;
2797 0 : break;
2798 : case text::RelOrientation::FRAME:
2799 : case text::RelOrientation::FRAME_LEFT: //:-(
2800 : case text::RelOrientation::FRAME_RIGHT: //:-(
2801 9 : if (eAnchor == FLY_AT_PAGE)
2802 0 : mnXRelTo = 1;
2803 : else
2804 9 : mnXRelTo = 2;
2805 9 : break;
2806 : case text::RelOrientation::PRINT_AREA:
2807 0 : if (eAnchor == FLY_AT_PAGE)
2808 0 : mnXRelTo = 0;
2809 : else
2810 0 : mnXRelTo = 2;
2811 0 : break;
2812 : case text::RelOrientation::CHAR:
2813 0 : mnXRelTo = 3;
2814 0 : break;
2815 : case text::RelOrientation::TEXT_LINE:
2816 0 : break;
2817 : }
2818 :
2819 : // Adjustment is vertically relative to...
2820 9 : switch (eVRel)
2821 : {
2822 : case text::RelOrientation::PAGE_PRINT_AREA:
2823 0 : mnYRelTo = 0;
2824 0 : break;
2825 : case text::RelOrientation::PAGE_FRAME:
2826 0 : mnYRelTo = 1;
2827 0 : break;
2828 : case text::RelOrientation::PRINT_AREA:
2829 0 : if (eAnchor == FLY_AT_PAGE)
2830 0 : mnYRelTo = 0;
2831 : else
2832 0 : mnYRelTo = 2;
2833 0 : break;
2834 : case text::RelOrientation::FRAME:
2835 9 : if (eAnchor == FLY_AT_PAGE)
2836 0 : mnYRelTo = 1;
2837 : else
2838 9 : mnYRelTo = 2;
2839 9 : break;
2840 : case text::RelOrientation::CHAR:
2841 : case text::RelOrientation::TEXT_LINE: // #i22673# - vertical alignment at top of line
2842 : case text::RelOrientation::PAGE_LEFT: //nonsense
2843 : case text::RelOrientation::PAGE_RIGHT: //nonsense
2844 : case text::RelOrientation::FRAME_LEFT: //nonsense
2845 : case text::RelOrientation::FRAME_RIGHT: //nonsense
2846 0 : mnYRelTo = 3;
2847 0 : break;
2848 9 : }
2849 9 : }
2850 :
2851 3 : void SwEscherEx::WriteFrmExtraData( const SwFrmFmt& rFmt )
2852 : {
2853 3 : aWinwordAnchoring.SetAnchoring(rFmt);
2854 3 : aWinwordAnchoring.WriteData(*this);
2855 :
2856 3 : AddAtom(4, ESCHER_ClientAnchor);
2857 3 : GetStream().WriteInt32( static_cast<sal_Int32>(0) );
2858 :
2859 3 : AddAtom(4, ESCHER_ClientData);
2860 3 : GetStream().WriteInt32( static_cast<sal_Int32>(1) );
2861 3 : }
2862 :
2863 2 : sal_Int32 SwEscherEx::WriteFlyFrm(const DrawObj &rObj, sal_uInt32 &rShapeId,
2864 : DrawObjPointerVector &rPVec)
2865 : {
2866 2 : const SwFrmFmt &rFmt = rObj.maCntnt.GetFrmFmt();
2867 :
2868 : // check for textflyframe and if it is the first in a Chain
2869 2 : sal_Int32 nBorderThick = 0;
2870 2 : const SwNodeIndex* pNdIdx = rFmt.GetCntnt().GetCntntIdx();
2871 2 : if( pNdIdx )
2872 : {
2873 2 : SwNodeIndex aIdx( *pNdIdx, 1 );
2874 2 : switch( aIdx.GetNode().GetNodeType() )
2875 : {
2876 : case ND_GRFNODE:
2877 1 : nBorderThick = WriteGrfFlyFrame( rFmt, rShapeId = GenerateShapeId() );
2878 1 : break;
2879 : case ND_OLENODE:
2880 0 : nBorderThick = WriteOLEFlyFrame( rFmt, rShapeId = GenerateShapeId() );
2881 0 : break;
2882 : default:
2883 1 : if (const SdrObject* pObj = rFmt.FindRealSdrObject())
2884 : {
2885 : // check for the first in a Chain
2886 : sal_uInt32 nTxtId;
2887 1 : sal_uInt16 nOff = 0;
2888 1 : const SwFrmFmt* pFmt = &rFmt, *pPrev;
2889 2 : while( 0 != ( pPrev = pFmt->GetChain().GetPrev() ))
2890 : {
2891 0 : ++nOff;
2892 0 : pFmt = pPrev;
2893 : }
2894 :
2895 1 : rShapeId = GetFlyShapeId(rFmt, rObj.mnHdFtIndex, rPVec);
2896 1 : if( !nOff )
2897 : {
2898 1 : nTxtId = pTxtBxs->GetPos( pObj );
2899 1 : if( USHRT_MAX == nTxtId )
2900 : {
2901 1 : pTxtBxs->Append( *pObj, rShapeId );
2902 1 : nTxtId = pTxtBxs->Count();
2903 : }
2904 : else
2905 0 : ++nTxtId;
2906 : }
2907 : else
2908 : {
2909 0 : const SdrObject* pPrevObj = pFmt->FindRealSdrObject();
2910 0 : nTxtId = pTxtBxs->GetPos( pPrevObj );
2911 0 : if( USHRT_MAX == nTxtId )
2912 : {
2913 : sal_uInt32 nPrevShapeId =
2914 0 : GetFlyShapeId(*pFmt, rObj.mnHdFtIndex, rPVec);
2915 0 : pTxtBxs->Append( *pPrevObj, nPrevShapeId );
2916 0 : nTxtId = pTxtBxs->Count();
2917 : }
2918 : else
2919 0 : ++nTxtId;
2920 : }
2921 1 : nTxtId *= 0x10000;
2922 1 : nTxtId += nOff;
2923 :
2924 1 : nBorderThick = WriteTxtFlyFrame(rObj, rShapeId, nTxtId, rPVec);
2925 : }
2926 :
2927 : //In browse mode the sdr object doesn't always exist. For example, the
2928 : //object is in the hidden header/footer. We save the fmt directly
2929 : //in such cases; we copy most of the logic from the block above
2930 1 : const bool bBrowseMode = (rFmt.getIDocumentSettingAccess())->get(IDocumentSettingAccess::BROWSE_MODE);
2931 1 : if( bBrowseMode && rFmt.GetDoc())
2932 : {
2933 0 : if( !rFmt.GetChain().GetPrev() )//obj in header/footer?
2934 : {
2935 0 : rShapeId = GetFlyShapeId(rFmt, rObj.mnHdFtIndex, rPVec);
2936 0 : pTxtBxs->Append( &rFmt, rShapeId );
2937 0 : sal_uInt32 nTxtId = pTxtBxs->Count();
2938 :
2939 0 : nTxtId *= 0x10000;
2940 0 : nBorderThick = WriteTxtFlyFrame(rObj, rShapeId, nTxtId, rPVec);
2941 : }
2942 : }
2943 :
2944 2 : }
2945 : }
2946 2 : return nBorderThick;
2947 : }
2948 :
2949 1 : sal_uInt16 FindPos(const SwFrmFmt &rFmt, unsigned int nHdFtIndex,
2950 : DrawObjPointerVector &rPVec)
2951 : {
2952 1 : DrawObjPointerIter aEnd = rPVec.end();
2953 1 : for (DrawObjPointerIter aIter = rPVec.begin(); aIter != aEnd; ++aIter)
2954 : {
2955 1 : const DrawObj *pObj = (*aIter);
2956 : OSL_ENSURE(pObj, "Impossible");
2957 1 : if (!pObj)
2958 0 : continue;
2959 1 : if (
2960 2 : nHdFtIndex == pObj->mnHdFtIndex &&
2961 1 : &rFmt == (&pObj->maCntnt.GetFrmFmt())
2962 : )
2963 : {
2964 1 : return static_cast< sal_uInt16 >(aIter - rPVec.begin());
2965 : }
2966 : }
2967 0 : return USHRT_MAX;
2968 : }
2969 :
2970 1 : sal_Int32 SwEscherEx::WriteTxtFlyFrame(const DrawObj &rObj, sal_uInt32 nShapeId,
2971 : sal_uInt32 nTxtBox, DrawObjPointerVector &rPVec)
2972 : {
2973 1 : const SwFrmFmt &rFmt = rObj.maCntnt.GetFrmFmt();
2974 1 : short nDirection = rObj.mnDirection;
2975 :
2976 1 : sal_Int32 nBorderThick=0;
2977 1 : OpenContainer( ESCHER_SpContainer );
2978 :
2979 1 : AddShape( ESCHER_ShpInst_TextBox, 0xa00, nShapeId );
2980 1 : EscherPropertyContainer aPropOpt;
2981 1 : aPropOpt.AddOpt(ESCHER_Prop_lTxid, nTxtBox);
2982 1 : if (const SwFrmFmt *pNext = rFmt.GetChain().GetNext())
2983 : {
2984 0 : sal_uInt16 nPos = FindPos(*pNext, rObj.mnHdFtIndex, rPVec);
2985 0 : if (USHRT_MAX != nPos && aFollowShpIds[nPos])
2986 0 : aPropOpt.AddOpt(ESCHER_Prop_hspNext, aFollowShpIds[nPos]);
2987 : }
2988 1 : nBorderThick = WriteFlyFrameAttr( rFmt, mso_sptTextBox, aPropOpt );
2989 :
2990 : MSO_TextFlow nFlow;
2991 :
2992 1 : switch (nDirection)
2993 : {
2994 : default:
2995 : OSL_ENSURE(!this, "unknown direction type");
2996 : //fall-through
2997 : case FRMDIR_HORI_LEFT_TOP:
2998 1 : nFlow=mso_txflHorzN;
2999 1 : break;
3000 : case FRMDIR_HORI_RIGHT_TOP:
3001 0 : nFlow=mso_txflHorzN;
3002 0 : break;
3003 : case FRMDIR_VERT_TOP_LEFT: //not really possible in word
3004 : case FRMDIR_VERT_TOP_RIGHT:
3005 0 : nFlow=mso_txflTtoBA;
3006 0 : break;
3007 : }
3008 1 : aPropOpt.AddOpt( ESCHER_Prop_txflTextFlow, nFlow );
3009 :
3010 1 : aPropOpt.Commit( GetStream() );
3011 :
3012 : // store anchor attribute
3013 1 : WriteFrmExtraData( rFmt );
3014 :
3015 1 : AddAtom( 4, ESCHER_ClientTextbox ); GetStream().WriteUInt32( nTxtBox );
3016 :
3017 1 : CloseContainer(); // ESCHER_SpContainer
3018 1 : return nBorderThick;
3019 : }
3020 :
3021 1 : void SwBasicEscherEx::WriteOLEPicture(EscherPropertyContainer &rPropOpt,
3022 : sal_uInt32 nShapeFlags, const Graphic &rGraphic, const SdrObject &rObj,
3023 : sal_uInt32 nShapeId, const awt::Rectangle* pVisArea )
3024 : {
3025 : //nShapeFlags == 0xA00 + flips and ole active
3026 1 : AddShape(ESCHER_ShpInst_PictureFrame, nShapeFlags, nShapeId);
3027 :
3028 1 : GraphicObject aGraphicObject(rGraphic);
3029 2 : OString aId = aGraphicObject.GetUniqueID();
3030 1 : if (!aId.isEmpty())
3031 : {
3032 1 : Rectangle aRect = rObj.GetLogicRect();
3033 1 : aRect.SetPos(Point(0,0));
3034 1 : aRect.Right() = DrawModelToEmu(aRect.Right());
3035 1 : aRect.Bottom() = DrawModelToEmu(aRect.Bottom());
3036 1 : sal_uInt32 nBlibId = mxGlobal->GetBlibID( *QueryPictureStream(),
3037 1 : aId, aRect, pVisArea, 0); // SJ: the fourth parameter (VisArea) should be set..
3038 1 : if (nBlibId)
3039 1 : rPropOpt.AddOpt(ESCHER_Prop_pib, nBlibId, true);
3040 : }
3041 :
3042 1 : SetPicId(rObj, nShapeId, rPropOpt);
3043 2 : rPropOpt.AddOpt( ESCHER_Prop_pictureActive, 0x10000 );
3044 1 : }
3045 :
3046 1 : void SwEscherEx::WriteOCXControl( const SwFrmFmt& rFmt, sal_uInt32 nShapeId )
3047 : {
3048 1 : if (const SdrObject* pSdrObj = rFmt.FindRealSdrObject())
3049 : {
3050 1 : OpenContainer( ESCHER_SpContainer );
3051 :
3052 1 : SdrModel *pModel = rWrt.pDoc->GetDrawModel();
3053 1 : OutputDevice *pDevice = Application::GetDefaultDevice();
3054 : OSL_ENSURE(pModel && pDevice, "no model or device");
3055 :
3056 : // #i71538# use complete SdrViews
3057 : // SdrExchangeView aExchange(pModel, pDevice);
3058 1 : SdrView aExchange(pModel, pDevice);
3059 :
3060 2 : Graphic aGraphic(aExchange.GetObjGraphic(pModel, pSdrObj));
3061 :
3062 2 : EscherPropertyContainer aPropOpt;
3063 : WriteOLEPicture(aPropOpt, 0xa00 | SHAPEFLAG_OLESHAPE, aGraphic,
3064 1 : *pSdrObj, nShapeId, NULL );
3065 :
3066 1 : WriteFlyFrameAttr( rFmt, mso_sptPictureFrame , aPropOpt );
3067 1 : aPropOpt.Commit( GetStream() );
3068 :
3069 : // store anchor attribute
3070 1 : WriteFrmExtraData( rFmt );
3071 :
3072 2 : CloseContainer(); // ESCHER_SpContainer
3073 : }
3074 1 : }
3075 :
3076 4 : void SwEscherEx::MakeZOrderArrAndFollowIds(
3077 : std::vector<DrawObj>& rSrcArr, std::vector<DrawObj*>&rDstArr)
3078 : {
3079 4 : ::lcl_makeZOrderArray(rWrt, rSrcArr, rDstArr);
3080 :
3081 : //Now set up the follow IDs
3082 4 : aFollowShpIds.clear();
3083 :
3084 13 : for (size_t n = 0; n < rDstArr.size(); ++n)
3085 : {
3086 9 : const SwFrmFmt &rFmt = rDstArr[n]->maCntnt.GetFrmFmt();
3087 9 : bool bNeedsShapeId = false;
3088 :
3089 9 : if (RES_FLYFRMFMT == rFmt.Which())
3090 : {
3091 2 : const SwFmtChain &rChain = rFmt.GetChain();
3092 2 : if (rChain.GetPrev() || rChain.GetNext())
3093 0 : bNeedsShapeId = true;
3094 : }
3095 :
3096 9 : sal_uLong nShapeId = bNeedsShapeId ? GenerateShapeId() : 0;
3097 :
3098 9 : aFollowShpIds.push_back(nShapeId);
3099 : }
3100 4 : }
3101 :
3102 1 : sal_uInt32 SwEscherEx::GetFlyShapeId(const SwFrmFmt& rFmt,
3103 : unsigned int nHdFtIndex, DrawObjPointerVector &rpVec)
3104 : {
3105 1 : sal_uInt16 nPos = FindPos(rFmt, nHdFtIndex, rpVec);
3106 : sal_uInt32 nShapeId;
3107 1 : if (USHRT_MAX != nPos)
3108 : {
3109 1 : if (0 == (nShapeId = aFollowShpIds[nPos]))
3110 : {
3111 1 : nShapeId = GenerateShapeId();
3112 1 : aFollowShpIds[ nPos ] = nShapeId;
3113 : }
3114 : }
3115 : else
3116 0 : nShapeId = GenerateShapeId();
3117 1 : return nShapeId;
3118 : }
3119 :
3120 0 : sal_uInt32 SwEscherEx::QueryTextID(
3121 : const uno::Reference< drawing::XShape>& xXShapeRef, sal_uInt32 nShapeId )
3122 : {
3123 0 : sal_uInt32 nId = 0;
3124 0 : if (SdrObject* pObj = GetSdrObjectFromXShape(xXShapeRef))
3125 : {
3126 0 : pTxtBxs->Append( *pObj, nShapeId );
3127 0 : nId = pTxtBxs->Count();
3128 0 : nId *= 0x10000;
3129 : }
3130 0 : return nId;
3131 : }
3132 :
3133 379 : SwMSConvertControls::SwMSConvertControls( SfxObjectShell *pDSh,SwPaM *pP ) : oox
3134 379 : ::ole::MSConvertOCXControls( pDSh ? pDSh->GetModel() : NULL ), pPaM( pP ), mnObjectId(0)
3135 : {
3136 379 : }
3137 :
3138 1 : sal_uInt32 SwMSConvertControls::GenerateObjectID()
3139 : {
3140 1 : return ++mnObjectId;
3141 : }
3142 :
3143 : // in transitioning away old filter for ole/ocx controls, ReadOCXStream has been made pure virtual in
3144 : // filter/source/msocximex.cxx, so.. we need an implementation here
3145 16 : sal_Bool SwMSConvertControls::ReadOCXStream( SotStorageRef& rSrc1,
3146 : com::sun::star::uno::Reference< com::sun::star::drawing::XShape > *pShapeRef,
3147 : sal_Bool bFloatingCtrl )
3148 : {
3149 16 : uno::Reference< form::XFormComponent > xFComp;
3150 16 : sal_Bool bRes = oox::ole::MSConvertOCXControls::ReadOCXStorage( rSrc1, xFComp );
3151 16 : if ( bRes && xFComp.is() )
3152 : {
3153 1 : com::sun::star::awt::Size aSz; // not used in import
3154 1 : bRes = InsertControl( xFComp, aSz,pShapeRef,bFloatingCtrl);
3155 : }
3156 16 : return bRes;
3157 : }
3158 :
3159 1 : bool SwMSConvertControls::ExportControl(WW8Export &rWW8Wrt, const SdrObject *pObj)
3160 : {
3161 1 : if (!rWW8Wrt.bWrtWW8)
3162 0 : return false;
3163 :
3164 1 : SdrUnoObj *pFormObj = PTR_CAST(SdrUnoObj,pObj);
3165 : uno::Reference< awt::XControlModel > xControlModel =
3166 1 : pFormObj->GetUnoControlModel();
3167 :
3168 : //Why oh lord do we use so many different units ?
3169 : //I think I painted myself into a little bit of a
3170 : //corner by trying to use the uno interface for
3171 : //controls export
3172 1 : Rectangle aRect = pFormObj->GetLogicRect();
3173 1 : aRect.SetPos(Point(0,0));
3174 1 : awt::Size aSize;
3175 1 : aSize.Width = TWIPS_TO_MM(aRect.Right());
3176 1 : aSize.Height = TWIPS_TO_MM(aRect.Bottom());
3177 :
3178 : //Open the ObjectPool
3179 1 : SvStorageRef xObjPool = rWW8Wrt.GetWriter().GetStorage().OpenSotStorage(
3180 : OUString(SL::aObjectPool), STREAM_READWRITE |
3181 3 : STREAM_SHARE_DENYALL);
3182 :
3183 : //Create a destination storage for the microsoft control
3184 2 : OUStringBuffer sStorageName;
3185 1 : sal_uInt32 nObjId = GenerateObjectID();
3186 1 : sStorageName.append('_').append( static_cast<sal_Int64>( nObjId ));
3187 : SvStorageRef xOleStg = xObjPool->OpenSotStorage(sStorageName.makeStringAndClear(),
3188 2 : STREAM_READWRITE|STREAM_SHARE_DENYALL);
3189 :
3190 1 : if (!xOleStg.Is())
3191 0 : return false;
3192 :
3193 2 : OUString sUName;
3194 1 : if (!WriteOCXStream( mxModel, xOleStg,xControlModel,aSize,sUName))
3195 0 : return false;
3196 :
3197 : sal_uInt8 aSpecOLE[] =
3198 : {
3199 : 0x03, 0x6a, 0xFF, 0xFF, 0xFF, 0xFF, // sprmCPicLocation
3200 : 0x0a, 0x08, 1, // sprmCFOLE2
3201 : 0x55, 0x08, 1, // sprmCFSpec
3202 : 0x56, 0x08, 1 // sprmCFObj
3203 1 : };
3204 : //Set the obj id into the sprmCPicLocation
3205 1 : sal_uInt8 *pData = aSpecOLE+2;
3206 1 : Set_UInt32(pData,nObjId );
3207 :
3208 2 : OUString sFld = FieldString(ww::eCONTROL) + "Forms." + sUName + ".1 \\s ";
3209 :
3210 : rWW8Wrt.OutputField(0, ww::eCONTROL, sFld,
3211 1 : WRITEFIELD_START|WRITEFIELD_CMD_START|WRITEFIELD_CMD_END);
3212 :
3213 1 : rWW8Wrt.pChpPlc->AppendFkpEntry(rWW8Wrt.Strm().Tell(),sizeof(aSpecOLE),
3214 1 : aSpecOLE);
3215 1 : rWW8Wrt.WriteChar( 0x1 );
3216 1 : rWW8Wrt.OutputField(0, ww::eCONTROL, OUString(), WRITEFIELD_END | WRITEFIELD_CLOSE);
3217 2 : return true;
3218 33 : }
3219 :
3220 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|