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