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