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