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