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