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