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