update dev300-m58
[ooovba.git] / sw / source / filter / rtf / rtfatr.cxx
blobd64b58c99f64b4046e23d068d4cf17c7af2a9713
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: rtfatr.cxx,v $
10 * $Revision: 1.75.136.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
33 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
36 * Dieses File enthaelt alle Ausgabe-Funktionen des RTF-Writers;
37 * fuer alle Nodes, Attribute, Formate und Chars.
39 #include <hintids.hxx>
41 #ifndef _COM_SUN_STAR_I18N_SCRIPTTYPE_HDL_
42 #include <com/sun/star/i18n/ScriptType.hdl>
43 #endif
44 #include <vcl/cvtgrf.hxx>
45 #include <svtools/urihelper.hxx>
46 #include <svtools/stritem.hxx>
47 #include <svtools/rtfkeywd.hxx>
48 #include <svtools/whiter.hxx>
49 #include <svtools/rtfout.hxx>
50 #include <svtools/itemiter.hxx>
51 #include <svx/fontitem.hxx>
52 #include <svx/hyznitem.hxx>
53 #ifndef _SVX_TSTPITEM_HXX //autogen
54 #include <svx/tstpitem.hxx>
55 #endif
56 #include <svx/lspcitem.hxx>
57 #include <svx/langitem.hxx>
58 #include <svx/keepitem.hxx>
59 #include <svx/udlnitem.hxx>
60 #include <svx/shaditem.hxx>
61 #include <svx/cmapitem.hxx>
62 #include <svx/brshitem.hxx>
63 #include <svx/protitem.hxx>
64 #include <svx/opaqitem.hxx>
65 #include <svx/ulspitem.hxx>
66 #include <svx/prntitem.hxx>
67 #include <svx/colritem.hxx>
68 #include <svx/escpitem.hxx>
69 #include <svx/fhgtitem.hxx>
70 #include <svx/spltitem.hxx>
71 #include <svx/adjitem.hxx>
72 #include <svx/lrspitem.hxx>
73 #include <svx/boxitem.hxx>
74 #include <svx/crsditem.hxx>
75 #ifndef _SVX_CNTRITEM_HXX //autogen
76 #include <svx/cntritem.hxx>
77 #endif
78 #include <svx/postitem.hxx>
79 #include <svx/shdditem.hxx>
80 #include <svx/wghtitem.hxx>
81 #include <svx/wrlmitem.hxx>
82 #ifndef _SVX_EMPHITEM_HXX
83 #include <svx/emphitem.hxx>
84 #endif
85 #include <svx/twolinesitem.hxx>
86 #include <svx/charscaleitem.hxx>
87 #include <svx/charrotateitem.hxx>
88 #include <svx/charreliefitem.hxx>
89 #include <svx/xoutbmp.hxx>
90 #include <svx/paravertalignitem.hxx>
91 #include <svx/hngpnctitem.hxx>
92 #include <svx/scriptspaceitem.hxx>
93 #include <svx/forbiddenruleitem.hxx>
94 #include <svx/frmdiritem.hxx>
95 #include <svx/charhiddenitem.hxx>
96 #include <unotools/charclass.hxx>
97 #include <reffld.hxx>
98 #include <frmatr.hxx>
99 #include <charatr.hxx>
100 #include <fmtfsize.hxx>
101 #include <fmtpdsc.hxx>
102 #include <fmtfld.hxx>
103 #include <fmtflcnt.hxx>
104 #include <fmtftn.hxx>
105 #include <fmthbsh.hxx>
106 #include <fchrfmt.hxx>
107 #include <fmtautofmt.hxx>
108 #include <fmtcntnt.hxx>
109 #include <fmthdft.hxx>
110 #include <fmtclds.hxx>
111 #include <txtftn.hxx>
112 #include <fmtsrnd.hxx>
113 #include <fmtanchr.hxx>
114 #include <charfmt.hxx>
115 #include <fmtinfmt.hxx>
116 #include <txtinet.hxx>
117 #include <doc.hxx>
118 #include <docary.hxx>
119 #include <ndtxt.hxx>
120 #include <pam.hxx>
121 #include <paratr.hxx>
122 #include <fldbas.hxx> // fuer SwField ...
123 #include <wrtrtf.hxx>
124 #include <rtf.hxx> // fuer SwPictureType
125 #include <ndgrf.hxx>
126 #include <grfatr.hxx>
127 #include <docufld.hxx>
128 #include <flddat.hxx>
129 #include <pagedesc.hxx> // fuer SwPageDesc ...
130 #include <swtable.hxx> // fuer SwPageDesc ...
131 #ifndef _DOCSH_HXX
132 #include <docsh.hxx>
133 #endif
134 #include <swrect.hxx>
135 #include <section.hxx>
136 #include <wrtswtbl.hxx>
137 #include <htmltbl.hxx>
138 #include <fmtclbl.hxx>
139 #include <breakit.hxx>
140 #include <fmtruby.hxx>
141 #include <txtatr.hxx>
142 #include <fltini.hxx>
143 #include <fmtrowsplt.hxx>
146 * um nicht immer wieder nach einem Update festzustellen, das irgendwelche
147 * Hint-Ids dazugekommen sind, wird hier definiert, die Groesse der Tabelle
148 * definiert und mit der akt. verglichen. Bei unterschieden wird der
149 * Compiler schon meckern.
151 * diese Section und die dazugeherigen Tabellen muessen in folgenden Files
152 * gepflegt werden: rtf\rtfatr.cxx, sw6\sw6atr.cxx, w4w\w4watr.cxx
154 #if !defined(UNX) && !defined(MSC) && !defined(PPC) && !defined(CSET) && !defined(__MWERKS__) && !defined(WTC) && !defined(__MINGW32__) && !defined(OS2)
156 #define ATTRFNTAB_SIZE 130
157 #if ATTRFNTAB_SIZE != POOLATTR_END - POOLATTR_BEGIN
158 #error Attribut-Tabelle ist ungueltigt. Wurden neue Hint-IDs zugefuegt ??
159 #endif
161 #ifdef FORMAT_TABELLE
162 // da sie nicht benutzt wird!
163 #define FORMATTAB_SIZE 7
164 #if FORMATTAB_SIZE != RES_FMT_END - RES_FMT_BEGIN
165 #error Format-Tabelle ist ungueltigt. Wurden neue Hint-IDs zugefuegt ??
166 #endif
167 #endif
169 #define NODETAB_SIZE 3
170 #if NODETAB_SIZE != RES_NODE_END - RES_NODE_BEGIN
171 #error Node-Tabelle ist ungueltigt. Wurden neue Hint-IDs zugefuegt ??
172 #endif
174 #endif
176 #ifdef WNT
177 // ueber xoutbmp.hxx wird das winuser.h angezogen. Dort gibt es ein
178 // define GetProp das mit unserem SvxEscapement kollidiert!
179 #undef GetProp
180 #endif
183 using namespace com::sun::star;
185 //-----------------------------------------------------------------------
187 static Writer& OutRTF_SwFmtCol( Writer& rWrt, const SfxPoolItem& rHt );
189 //-----------------------------------------------------------------------
191 SvStream& OutComment( Writer& rWrt, const sal_Char* pStr )
193 return (rWrt.Strm() << '{' << OOO_STRING_SVTOOLS_RTF_IGNORE << pStr);
196 SvStream& OutComment( Writer& rWrt, const char* pStr, BOOL bSetFlag )
198 // setze Flag, damit bei der Ausgabe von Attributen zu erkennen,
199 // ob ueberhaupt etwas ausgegeben wurde.
200 ((SwRTFWriter&)rWrt).bOutFmtAttr = bSetFlag;
201 return (rWrt.Strm() << '{' << OOO_STRING_SVTOOLS_RTF_IGNORE << pStr);
204 Writer& OutRTF_AsByteString( Writer& rWrt, const String& rStr, rtl_TextEncoding eEncoding)
206 ByteString sOutStr( rStr, eEncoding );
207 rWrt.Strm() << sOutStr.GetBuffer();
208 return rWrt;
211 void OutRTF_SfxItemSet( SwRTFWriter& rWrt, const SfxItemSet& rSet,
212 BOOL bDeep )
214 bool bFrameDirOut=false;
215 bool bAdjustOut=false;
216 // erst die eigenen Attribute ausgeben
217 SvPtrarr aAsian( 0, 5 ), aCmplx( 0, 5 ), aLatin( 0, 5 );
219 const SfxItemPool& rPool = *rSet.GetPool();
220 SfxWhichIter aIter( rSet );
221 const SfxPoolItem* pItem;
222 FnAttrOut pOut;
223 USHORT nWhich = aIter.FirstWhich();
224 while( nWhich )
226 if( SFX_ITEM_SET == rSet.GetItemState( nWhich, bDeep, &pItem ))
228 pOut = aRTFAttrFnTab[ nWhich - RES_CHRATR_BEGIN];
229 if( pOut &&
230 ( *pItem != rPool.GetDefaultItem( nWhich )
231 || ( rSet.GetParent() &&
232 *pItem != rSet.GetParent()->Get( nWhich ) )
233 || ( rWrt.GetAttrSet() &&
234 *pItem != rWrt.GetAttrSet()->Get( nWhich ) )
237 else
238 pOut = 0;
240 else if( !bDeep )
241 pOut = 0;
242 else if( 0 != ( pItem = rPool.GetPoolDefaultItem( nWhich )) )
243 pOut = aRTFAttrFnTab[ nWhich - RES_CHRATR_BEGIN];
244 else
245 pOut = 0;
247 if (!pOut && bDeep)
249 switch( nWhich )
251 case RES_CHRATR_FONTSIZE:
252 case RES_CHRATR_CJK_FONTSIZE:
253 case RES_CHRATR_CTL_FONTSIZE:
254 case RES_CHRATR_LANGUAGE:
255 case RES_CHRATR_CJK_LANGUAGE:
256 case RES_CHRATR_CTL_LANGUAGE:
257 pItem = &rPool.GetDefaultItem( nWhich );
258 pOut = aRTFAttrFnTab[ nWhich - RES_CHRATR_BEGIN];
259 break;
260 default:
261 break;
265 if( pOut )
267 void* pVoidItem = (void*)pItem;
268 switch( nWhich )
270 case RES_CHRATR_FONT:
271 case RES_CHRATR_FONTSIZE:
272 case RES_CHRATR_LANGUAGE:
273 case RES_CHRATR_POSTURE:
274 case RES_CHRATR_WEIGHT:
275 aLatin.Insert( pVoidItem, aLatin.Count() );
276 pOut = 0;
277 break;
279 case RES_CHRATR_CJK_FONT:
280 case RES_CHRATR_CJK_FONTSIZE:
281 case RES_CHRATR_CJK_LANGUAGE:
282 case RES_CHRATR_CJK_POSTURE:
283 case RES_CHRATR_CJK_WEIGHT:
284 aAsian.Insert( pVoidItem, aAsian.Count() );
285 pOut = 0;
286 break;
288 case RES_CHRATR_CTL_FONT:
289 case RES_CHRATR_CTL_FONTSIZE:
290 case RES_CHRATR_CTL_LANGUAGE:
291 case RES_CHRATR_CTL_POSTURE:
292 case RES_CHRATR_CTL_WEIGHT:
293 aCmplx.Insert( pVoidItem, aCmplx.Count() );
294 pOut = 0;
295 break;
297 case RES_FRAMEDIR:
298 bFrameDirOut=true;
299 break;
300 case RES_PARATR_ADJUST:
301 bAdjustOut=true;
302 break;
306 if (pOut)
307 (*pOut)( rWrt, *pItem );
308 nWhich = aIter.NextWhich();
311 //If rtlpar set and no following alignment. And alignment is not rtl then
312 //output alignment
313 if (bFrameDirOut && !bAdjustOut && !rWrt.pFlyFmt && !rWrt.bOutPageDesc)
315 pOut = aRTFAttrFnTab[ static_cast< USHORT >(RES_PARATR_ADJUST) - RES_CHRATR_BEGIN];
316 if (pOut)
317 (*pOut)(rWrt, rSet.Get(RES_PARATR_ADJUST));
319 if (rWrt.pFlyFmt && !rWrt.bOutPageDesc && !bFrameDirOut)
321 pOut = aRTFAttrFnTab[ static_cast< USHORT >(RES_FRAMEDIR) - RES_CHRATR_BEGIN];
322 if (pOut)
323 (*pOut)(rWrt, rSet.Get(RES_FRAMEDIR));
326 if (aAsian.Count() || aCmplx.Count() || aLatin.Count())
328 SvPtrarr* aArr[4];
329 switch (rWrt.GetCurrScriptType())
331 case i18n::ScriptType::LATIN:
332 aArr[ 0 ] = &aCmplx;
333 aArr[ 1 ] = &aAsian;
334 aArr[ 2 ] = &aLatin;
335 aArr[ 3 ] = &aLatin;
336 break;
338 case i18n::ScriptType::ASIAN:
339 aArr[ 0 ] = &aCmplx;
340 aArr[ 1 ] = &aLatin;
341 aArr[ 2 ] = &aLatin;
342 aArr[ 3 ] = &aAsian;
343 break;
345 case i18n::ScriptType::COMPLEX:
346 aArr[ 0 ] = &aLatin;
347 aArr[ 1 ] = &aLatin;
348 aArr[ 2 ] = &aAsian;
349 aArr[ 3 ] = &aCmplx;
350 break;
352 default:
353 return ;
356 //The final entry is the one that is actually in use
357 //so it uses e.g. \b \i \fs, the others are not in
358 //use and so are "associated". Both asian and western
359 //are ltr runs, with asian being the dbch varient
360 //and western being the loch/hich varient
361 bool bOutLTOR = true;
362 bool bLowLTOR = false;
363 for( int nArrCnt = 0; nArrCnt < 4; ++nArrCnt )
365 SvPtrarr* pCurArr = aArr[ nArrCnt ];
366 if (pCurArr->Count())
368 bool bInUse = (aArr[nArrCnt] == aArr[3]);
369 rWrt.SetAssociatedFlag(!bInUse);
370 if (pCurArr == &aLatin)
372 if (bOutLTOR)
374 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_LTRCH;
375 bOutLTOR = false;
378 if (bLowLTOR)
379 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_LOCH;
380 else
382 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_HICH;
383 bLowLTOR = true;
386 else if( pCurArr == &aAsian )
388 if( bOutLTOR )
390 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_LTRCH;
391 bOutLTOR = false;
393 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_DBCH;
395 else
396 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_RTLCH;
398 for (USHORT n = 0; n < pCurArr->Count(); ++n)
400 pItem = (const SfxPoolItem*)(*pCurArr)[ n ];
401 pOut = aRTFAttrFnTab[ pItem->Which() - RES_CHRATR_BEGIN];
402 (*pOut)( rWrt, *pItem );
409 // fuer die Formate muesste eine einzige Ausgabe-Funktion genuegen !
411 * Formate wie folgt ausgeben:
412 * - gebe alle Attribute vom Format aus
415 bool SwFmtToSet(SwRTFWriter& rWrt, const SwFmt& rFmt, SfxItemSet &rSet)
417 bool bOutItemSet = true;
418 rSet.SetParent(rFmt.GetAttrSet().GetParent());
420 switch( rFmt.Which() )
422 case RES_CONDTXTFMTCOLL:
423 case RES_TXTFMTCOLL:
425 USHORT nId = rWrt.GetId( (const SwTxtFmtColl&)rFmt );
426 if (0 == nId )
427 return false; // Default-TextStyle nicht ausgeben !!
429 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_S;
430 rWrt.OutULong( nId );
431 rWrt.bOutFmtAttr = TRUE;
432 // BYTE nLvl = ((const SwTxtFmtColl&)rFmt).GetOutlineLevel(); //#outline level,zhaojianwei
433 // if( MAXLEVEL > nLvl )
434 // {
435 if(((const SwTxtFmtColl&)rFmt).IsAssignedToListLevelOfOutlineStyle())
437 int nLvl = ((const SwTxtFmtColl&)rFmt).GetAssignedOutlineStyleLevel(); //<-end,zhaojianwei
438 USHORT nNumId = rWrt.GetNumRuleId(
439 *rWrt.pDoc->GetOutlineNumRule() );
440 if( USHRT_MAX != nNumId )
442 BYTE nWWLvl = 8 >= nLvl ? static_cast<BYTE>(nLvl) : 8;
443 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_LS;
444 rWrt.OutULong( nNumId );
445 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_ILVL; rWrt.OutULong( nWWLvl );
446 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_OUTLINELEVEL; rWrt.OutULong( nWWLvl );
447 if( nWWLvl != nLvl ) // RTF-kennt nur 9 Ebenen
449 OutComment( rWrt, OOO_STRING_SVTOOLS_RTF_SOUTLVL );
450 rWrt.OutULong( nLvl ) << '}';
454 const SwNumFmt* pNFmt = &rWrt.pDoc->GetOutlineNumRule()->Get( static_cast<USHORT>(nLvl) );
455 if( pNFmt->GetAbsLSpace() )
457 SfxItemSet aSet( *rFmt.GetAttrSet().GetPool(),
458 rFmt.GetAttrSet().GetRanges() );
459 aSet.SetParent( &rFmt.GetAttrSet() );
460 SvxLRSpaceItem aLR( (SvxLRSpaceItem&)aSet.Get( RES_LR_SPACE ) );
462 aLR.SetTxtLeft( aLR.GetTxtLeft() + pNFmt->GetAbsLSpace() );
463 aLR.SetTxtFirstLineOfst( pNFmt->GetFirstLineOffset() );
465 aSet.Put(aLR);
466 rSet.Put(aSet);
467 bOutItemSet = false;
471 break;
472 case RES_CHRFMT:
474 USHORT nId = rWrt.GetId( (const SwCharFmt&)rFmt );
475 if (0 == nId)
476 return false; // Default-CharStyle nicht ausgeben !!
478 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_IGNORE << OOO_STRING_SVTOOLS_RTF_CS;
479 rWrt.OutULong( nId );
480 rWrt.bOutFmtAttr = TRUE;
482 break;
484 // case RES_GRFFMTCOLL:
485 // ?????
488 if (bOutItemSet)
489 rSet.Put(rFmt.GetAttrSet());
491 return true;
494 Writer& OutRTF_SwFmt(Writer& rWrt, const SwFmt& rFmt)
496 SwRTFWriter & rRTFWrt = (SwRTFWriter&)rWrt;
498 SfxItemSet aSet(*rFmt.GetAttrSet().GetPool(),
499 rFmt.GetAttrSet().GetRanges() );
500 if (SwFmtToSet(rRTFWrt, rFmt, aSet))
501 OutRTF_SfxItemSet(rRTFWrt, aSet, TRUE);
503 return rWrt;
506 void OutRTF_SwFlyFrmFmt( SwRTFWriter& rRTFWrt )
508 // ist der aktuelle Absatz in einem freifliegenden Rahmen ? Dann
509 // muessen noch die Attribute dafuer ausgegeben werden.
510 ASSERT( rRTFWrt.pFlyFmt, "wo ist das Fly-Format?" );
512 if( rRTFWrt.bOutFmtAttr )
514 rRTFWrt.Strm() << ' ';
515 rRTFWrt.bOutFmtAttr = false;
517 // gebe erstmal alle RTF-Spezifischen Attribute aus
518 rRTFWrt.bRTFFlySyntax = TRUE;
519 OutRTF_SwFmt( rRTFWrt, *rRTFWrt.pFlyFmt );
521 // dann gebe alle eigenen Attribute aus
523 // dazu erzeuge einen temp strstream, um festzustellen ob es
524 // ueberhaupt eigene Attribute gibt !
525 SvMemoryStream aTmpStrm;
526 SvStream* pSaveStrm = &rRTFWrt.Strm();
527 rRTFWrt.SetStrm( aTmpStrm );
529 rRTFWrt.bRTFFlySyntax = false;
530 OutRTF_SwFmt( rRTFWrt, *rRTFWrt.pFlyFmt );
532 rRTFWrt.SetStrm( *pSaveStrm ); // Stream-Pointer wieder zurueck
534 if( aTmpStrm.GetSize() ) // gibt es SWG spezifische Attribute ??
536 aTmpStrm.Seek( 0L );
537 rRTFWrt.Strm() << '{' << OOO_STRING_SVTOOLS_RTF_IGNORE << aTmpStrm << '}';
540 // rRTFWrt.pFlyFmt = 0; // wieder zuruecksetzen !!
543 /* Ausgabe der Nodes */
546 * Ausgabe der Texte-Attribute:
547 * Die Text-Attribute sind in einem VarArray nach ihren Start-Positionen
548 * sortiert. Fuer den RTF-Writer ist aber auch das Ende von Bedeutung.
549 * Darum die Idee, sobald im SwpHints-Array ein Attribut mit der Start-
550 * Position gefunden wurde, in einem Sortierten-Array die Endposition
551 * zu speichern. Sobald der Writer die Position erreicht hat, wird die
552 * schliessende Klammer ausgegeben und die Position aus dem Sort.Array
553 * geloescht.
554 * 15.3.93: Es reicht leider nicht aus nur Start und End zuspeichern, denn
555 * im SwpHints Array stehen sie nicht nach Ende sortiert, so dass
556 * Attribute die falsche schliessende Klammer bekommen. (z.B
557 * Bold von 0..3, dann folgt Underline von 0..4. Dann bekommt Underline
558 * die schliessende Klammer von Bold !!)
559 * Also muessen erst alle Attribute einer Position gesammelt, nach
560 * Ende sortiert und dann erst ausgegeben werden.
563 SV_DECL_PTRARR( SfxPoolItems, SfxPoolItem*, 4, 4 )
564 class RTFEndPosLst;
566 class SttEndPos
568 // falls mehrere Attribute den gleichen Bereich umspannen, sammeln
569 SfxPoolItems aArr;
570 xub_StrLen nStart, nEnd;
572 SttEndPos( const SttEndPos & rSEPos );
574 public:
575 SttEndPos( const SfxPoolItem& rAttr, xub_StrLen nStt, xub_StrLen nEnd );
576 ~SttEndPos();
578 xub_StrLen GetStart() const { return nStart; }
579 xub_StrLen GetEnd() const { return nEnd; }
581 const SfxPoolItems& GetAttrs() const { return aArr; }
582 void AddAttr( const SfxPoolItem& rAttr );
583 BOOL HasScriptChange() const;
587 SV_DECL_PTRARR_DEL( _EndPosLst, SttEndPos*, 5, 5 )
588 SV_IMPL_PTRARR( _EndPosLst, SttEndPos* )
590 class RTFEndPosLst : private _EndPosLst
592 const SwTxtNode& rNode;
593 SwRTFWriter& rWrt;
594 RTFEndPosLst* pOldPosLst;
595 xub_StrLen nCurPos;
596 USHORT nCurScript;
598 public:
599 using _EndPosLst::Count;
600 using _EndPosLst::operator[];
601 using _EndPosLst::DeleteAndDestroy;
603 RTFEndPosLst( SwRTFWriter& rWrt, const SwTxtNode& rNd, xub_StrLen nStart );
604 ~RTFEndPosLst();
606 USHORT GetCurScript() const { return nCurScript; }
607 BOOL MatchScriptToId( USHORT nId ) const;
608 int Insert( const SfxPoolItem& rAttr, xub_StrLen nStt, xub_StrLen nEnd );
610 void OutAttrs( xub_StrLen nStrPos );
611 void EndAttrs( xub_StrLen nStrPos );
612 void OutScriptChange( xub_StrLen nStrPos );
614 const SfxPoolItem* HasItem( USHORT nWhich ) const;
615 const SfxPoolItem& GetItem( USHORT nWhich ) const;
616 void OutFontAttrs(const SfxPoolItem &rItem);
617 void OutFontAttrs(USHORT nScript, bool bRTL);
619 SfxItemPool& GetPool() {return *rNode.GetSwAttrSet().GetPool(); }
623 SttEndPos::SttEndPos( const SfxPoolItem& rAttr,
624 xub_StrLen nStt, xub_StrLen nEd )
625 : nStart( nStt ), nEnd( nEd )
627 AddAttr( rAttr );
630 SttEndPos::~SttEndPos()
632 for( USHORT n = 0, nCount = aArr.Count(); n < nCount; ++n )
633 if( RES_FLTRATTR_BEGIN <= aArr[ n ]->Which() )
634 delete aArr[ n ];
637 BOOL SttEndPos::HasScriptChange() const
639 for( USHORT n = 0, nCount = aArr.Count(); n < nCount; ++n )
640 if( RES_FLTR_SCRIPTTYPE == aArr[ n ]->Which() )
641 return TRUE;
642 return FALSE;
645 void SttEndPos::AddAttr( const SfxPoolItem& rAttr )
647 const SfxPoolItem* pI = &rAttr;
648 aArr.Insert(pI, aArr.Count());
651 RTFEndPosLst::RTFEndPosLst(SwRTFWriter& rWriter, const SwTxtNode& rNd,
652 xub_StrLen nStart)
653 : rNode(rNd), rWrt(rWriter), nCurPos(STRING_NOTFOUND)
655 pOldPosLst = rWrt.pCurEndPosLst;
656 rWrt.pCurEndPosLst = this;
658 using namespace sw::util;
659 CharRuns aCharRuns(GetPseudoCharRuns(rNd, nStart));
660 cCharRunIter aEnd = aCharRuns.end();
661 xub_StrLen nSttPos = nStart;
662 for (cCharRunIter aI = aCharRuns.begin(); aI != aEnd; ++aI)
664 if (nSttPos != aI->mnEndPos)
666 SfxPoolItem* pChg = new SfxUInt32Item(RES_FLTR_SCRIPTTYPE,
667 (sal_uInt32(aI->mnScript) << 16) | static_cast<sal_uInt32>(aI->mbRTL));
668 Insert(*pChg, nSttPos, aI->mnEndPos);
669 nSttPos = aI->mnEndPos;
674 RTFEndPosLst::~RTFEndPosLst()
676 rWrt.pCurEndPosLst = pOldPosLst;
679 int RTFEndPosLst::Insert( const SfxPoolItem& rAttr, xub_StrLen nStt,
680 xub_StrLen nEnd )
682 if (rAttr.Which() == RES_TXTATR_INETFMT)
683 return false;
685 if( nStt == nEnd )
686 return false;
688 USHORT nPos;
689 for( nPos = 0; nPos < Count(); ++nPos )
691 SttEndPos* pTmp = GetObject( nPos );
692 if( pTmp->GetStart() == nStt && pTmp->GetEnd() == nEnd )
694 pTmp->AddAttr( rAttr );
695 return false; // schon vorhanden
697 if( nEnd < pTmp->GetEnd() )
699 SttEndPos* pNew = new SttEndPos( rAttr, nStt, nEnd );
700 _EndPosLst::C40_INSERT( SttEndPos, pNew, nPos );
701 return TRUE;
705 SttEndPos* pNew = new SttEndPos( rAttr, nStt, nEnd );
706 _EndPosLst::C40_INSERT( SttEndPos, pNew, nPos );
707 return TRUE;
710 void RTFEndPosLst::OutScriptChange( xub_StrLen nStrPos )
712 SttEndPos* pStt;
713 for( USHORT n = 0, nEnd = Count(); n < nEnd; ++n )
714 if( nStrPos == (pStt = GetObject( n ))->GetStart())
716 if( pStt->HasScriptChange() )
717 OutAttrs( nStrPos );
718 break;
722 void RTFEndPosLst::OutAttrs( xub_StrLen nStrPos )
724 SttEndPos* pStt;
725 nCurPos = nStrPos;
726 for( USHORT n = Count(); n ; )
727 if( nStrPos == (pStt = (*this)[ --n ])->GetStart() )
729 rWrt.Strm() << '{';
730 for( USHORT i = 0; i < pStt->GetAttrs().Count(); ++i )
732 const SfxPoolItem* pItem = pStt->GetAttrs()[i];
733 if( RES_FLTR_SCRIPTTYPE == pItem->Which() )
734 OutFontAttrs(*pItem);
735 else
736 Out( aRTFAttrFnTab, *pItem, rWrt );
740 nCurPos = STRING_NOTFOUND;
743 //Just a little decoding hack for the RES_FLTR_SCRIPTTYPE thing
744 void RTFEndPosLst::OutFontAttrs(const SfxPoolItem &rItem)
746 sal_uInt32 nValue = ((const SfxUInt32Item&)rItem).GetValue();
747 sal_uInt16 nScript = static_cast<sal_uInt16>(nValue >> 16);
748 bool bBiDi = nValue & 0x1;
749 OutFontAttrs(nScript, bBiDi);
752 void RTFEndPosLst::OutFontAttrs(USHORT nScript, bool bRTL)
754 // script change, write the correct attributes:
755 // start first with the Fontname
757 rWrt.bOutFmtAttr = TRUE;
758 nCurScript = nScript;
759 rWrt.SetCurrScriptType( nScript );
760 rWrt.SetAssociatedFlag(false);
762 // the font MUST be at the first position !!!
763 static const USHORT aLatinIds[] =
765 RES_CHRATR_FONT,
766 RES_CHRATR_FONTSIZE, RES_CHRATR_LANGUAGE,
767 RES_CHRATR_POSTURE, RES_CHRATR_WEIGHT,
770 static const USHORT aAsianIds[] =
772 RES_CHRATR_CJK_FONT,
773 RES_CHRATR_CJK_FONTSIZE, RES_CHRATR_CJK_LANGUAGE,
774 RES_CHRATR_CJK_POSTURE, RES_CHRATR_CJK_WEIGHT,
777 static const USHORT aCmplxIds[] =
779 RES_CHRATR_CTL_FONT,
780 RES_CHRATR_CTL_FONTSIZE, RES_CHRATR_CTL_LANGUAGE,
781 RES_CHRATR_CTL_POSTURE, RES_CHRATR_CTL_WEIGHT,
786 You would have thought that
787 rWrt.Strm() << (bRTL ? OOO_STRING_SVTOOLS_RTF_RTLCH : OOO_STRING_SVTOOLS_RTF_LTRCH); would be sufficent here ,
788 but looks like word needs to see the other directional token to be
789 satisified that all is kosher, otherwise it seems in ver 2003 to go and
790 semi-randomlyly stick strike through about the place. Perhaps
791 strikethrough is some ms developers "something is wrong signal" debugging
792 code that we're triggering ?
794 if (bRTL)
796 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_LTRCH;
797 rWrt.Strm() << ' ';
798 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_RTLCH;
800 else
802 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_RTLCH;
803 rWrt.Strm() << ' ';
804 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_LTRCH;
807 // size/weight/posture optional
808 const USHORT* pIdArr = 0;
809 ByteString sOut;
810 switch (nScript)
812 default: //fall through
813 ASSERT(pIdArr, "unknown script, strange");
814 case i18n::ScriptType::LATIN:
815 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_LOCH;
816 pIdArr = aLatinIds;
817 break;
818 case i18n::ScriptType::ASIAN:
819 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_DBCH;
820 pIdArr = aAsianIds;
821 break;
822 case i18n::ScriptType::COMPLEX:
823 pIdArr = aCmplxIds;
824 break;
827 for (const USHORT* pId = pIdArr; *pId; ++pId)
829 if (FnAttrOut pOut = aRTFAttrFnTab[ *pId - RES_CHRATR_BEGIN])
831 const SfxPoolItem* pItem = HasItem(*pId);
832 if (!pItem)
833 pItem = &GetPool().GetDefaultItem(*pId);
834 (*pOut)(rWrt, *pItem);
839 void RTFEndPosLst::EndAttrs( xub_StrLen nStrPos )
841 xub_StrLen nClipStart=STRING_MAXLEN;
842 bool bClosed=false;
843 SttEndPos* pSEPos;
844 while( 0 != Count() && 0 != (pSEPos = GetObject( 0 )) &&
845 ( STRING_MAXLEN == nStrPos || nStrPos == pSEPos->GetEnd() ))
847 const SfxPoolItems& rAttrs = pSEPos->GetAttrs();
848 for( USHORT nAttr = rAttrs.Count(); nAttr; )
850 switch( rAttrs[ --nAttr ]->Which() )
852 case RES_TXTATR_CJK_RUBY:
853 rWrt.Strm() << ")}{" << OOO_STRING_SVTOOLS_RTF_FLDRSLT << " }}";
854 break;
858 rWrt.Strm() << '}'; // end of all attributes from this position
859 if (pSEPos->GetStart() < nClipStart)
860 nClipStart = pSEPos->GetStart();
861 bClosed=true;
862 DeleteAndDestroy( 0, 1 );
865 if (bClosed)
867 //If there are open ranges whose start is before this point, and whose
868 //start is after the cliping start then they have been closed whether
869 //we wanted this or not. So accept that fact and then restart then
870 //again
871 USHORT nSize = Count();
872 while (nSize > 0)
874 pSEPos = GetObject(--nSize);
875 if ( pSEPos->GetStart() < nStrPos &&
876 pSEPos->GetStart() >= nClipStart)
878 rWrt.Strm() << '}';
882 nSize = Count();
883 USHORT n = 0;
884 while (n < nSize)
886 SttEndPos* pStt = (*this)[n++];
887 if (pStt->GetStart() < nStrPos && pStt->GetStart() >= nClipStart)
889 rWrt.Strm() << '{';
890 for( USHORT i = 0; i < pStt->GetAttrs().Count(); ++i )
892 const SfxPoolItem* pItem = pStt->GetAttrs()[i];
893 if( RES_FLTR_SCRIPTTYPE == pItem->Which() )
894 OutFontAttrs(*pItem);
895 else
896 Out( aRTFAttrFnTab, *pItem, rWrt );
903 BOOL RTFEndPosLst::MatchScriptToId( USHORT nWhich ) const
905 BOOL bRet = false;
906 switch( nWhich )
908 case RES_CHRATR_FONT:
909 case RES_CHRATR_FONTSIZE:
910 case RES_CHRATR_LANGUAGE:
911 case RES_CHRATR_POSTURE:
912 case RES_CHRATR_WEIGHT:
913 bRet = nCurScript == i18n::ScriptType::LATIN;
914 break;
915 case RES_CHRATR_CJK_FONT:
916 case RES_CHRATR_CJK_FONTSIZE:
917 case RES_CHRATR_CJK_LANGUAGE:
918 case RES_CHRATR_CJK_POSTURE:
919 case RES_CHRATR_CJK_WEIGHT:
920 bRet = nCurScript == i18n::ScriptType::ASIAN;
921 break;
922 case RES_CHRATR_CTL_FONT:
923 case RES_CHRATR_CTL_FONTSIZE:
924 case RES_CHRATR_CTL_LANGUAGE:
925 case RES_CHRATR_CTL_POSTURE:
926 case RES_CHRATR_CTL_WEIGHT:
927 bRet = nCurScript == i18n::ScriptType::COMPLEX;
928 break;
930 return bRet;
933 const SfxPoolItem& RTFEndPosLst::GetItem( USHORT nWhich ) const
935 const SfxPoolItem* pItem = HasItem( nWhich );
936 if( !pItem )
937 pItem = &rNode.GetSwAttrSet().GetPool()->GetDefaultItem( nWhich );
938 return *pItem;
941 const SfxPoolItem* RTFEndPosLst::HasItem( USHORT nWhich ) const
943 const SfxPoolItem* pItem;
944 if( RES_TXTATR_END > nWhich )
946 // it's a character/text attribute so look into the item array
947 for( USHORT n = Count(); n; )
949 SttEndPos* pTmp = GetObject( --n );
950 for( USHORT i = pTmp->GetAttrs().Count(); i; )
952 pItem = pTmp->GetAttrs()[ --i ];
953 if( pItem->Which() == nWhich )
954 return pItem;
956 // look into the charfmt?
957 if( RES_TXTATR_CHARFMT == pItem->Which() &&
958 ((SwFmtCharFmt*) pItem)->GetCharFmt() &&
959 SFX_ITEM_SET == ((SwFmtCharFmt*) pItem)->GetCharFmt()->
960 GetItemState( nWhich, TRUE, &pItem ))
961 return pItem;
966 if( SFX_ITEM_SET != rNode.GetSwAttrSet().GetItemState(
967 nWhich, TRUE, &pItem ))
968 pItem = 0;
969 return pItem;
972 const SfxPoolItem& SwRTFWriter::GetItem( USHORT nWhich ) const
974 if( pCurEndPosLst )
975 return pCurEndPosLst->GetItem( nWhich );
976 if( pAttrSet )
977 return pAttrSet->Get( nWhich );
979 return pDoc->GetAttrPool().GetDefaultItem( nWhich );
982 static void OutSvxFrmDir(SwRTFWriter& rRTFWrt, const SfxPoolItem& rHt )
984 // write it only for pasgedesc's - not for frames
985 SvxFrameDirectionItem aItem((const SvxFrameDirectionItem&)rHt);
986 USHORT nVal = 0;
987 const sal_Char* pStr = 0;
988 bool bRTL = false;
990 if (rRTFWrt.pFlyFmt)
991 aItem.SetValue(rRTFWrt.TrueFrameDirection(*rRTFWrt.pFlyFmt));
993 switch (aItem.GetValue())
995 case FRMDIR_ENVIRONMENT:
996 ASSERT(0, "Not expected to see FRMDIR_ENVIRONMENT here");
997 break;
998 case FRMDIR_VERT_TOP_RIGHT:
999 nVal = 1;
1000 pStr = OOO_STRING_SVTOOLS_RTF_FRMTXTBRLV;
1001 break;
1002 case FRMDIR_HORI_RIGHT_TOP:
1003 bRTL = true;
1004 // nVal = 3;
1005 // A val of three isn't working as expected in word :-( so leave it
1006 // as normal ltr 0 textflow with rtl sect property, neither does
1007 // the frame textflow
1008 // pStr = OOO_STRING_SVTOOLS_RTF_FRMTXTBRL;
1009 break;
1010 case FRMDIR_VERT_TOP_LEFT:
1011 nVal = 4;
1012 pStr = OOO_STRING_SVTOOLS_RTF_FRMTXLRTBV;
1013 break;
1016 if( rRTFWrt.pFlyFmt && rRTFWrt.bRTFFlySyntax && pStr )
1018 rRTFWrt.Strm() << pStr;
1019 rRTFWrt.bOutFmtAttr = TRUE;
1021 else if( rRTFWrt.bOutPageDesc)
1023 if (nVal)
1025 rRTFWrt.Strm() << OOO_STRING_SVTOOLS_RTF_STEXTFLOW;
1026 rRTFWrt.OutULong( nVal );
1028 if (bRTL)
1029 rRTFWrt.Strm() << OOO_STRING_SVTOOLS_RTF_RTLSECT;
1030 rRTFWrt.bOutFmtAttr = TRUE;
1032 else if (!rRTFWrt.pFlyFmt && !rRTFWrt.bOutPageDesc)
1034 rRTFWrt.Strm() << (bRTL ? OOO_STRING_SVTOOLS_RTF_RTLPAR : OOO_STRING_SVTOOLS_RTF_LTRPAR);
1035 rRTFWrt.bOutFmtAttr = TRUE;
1039 void OutRTF_SwRTL(SwRTFWriter& rWrt, const SwTxtNode *pNd)
1041 if (!pNd)
1042 return;
1043 SvxFrameDirection eDir = FRMDIR_ENVIRONMENT;
1044 if (const SvxFrameDirectionItem* pItem = (const SvxFrameDirectionItem*)
1045 pNd->GetSwAttrSet().GetItem(RES_FRAMEDIR))
1047 eDir = static_cast<SvxFrameDirection>(pItem->GetValue());
1049 if (eDir == FRMDIR_ENVIRONMENT)
1051 SwPosition aPos(*pNd);
1052 eDir =
1053 static_cast<SvxFrameDirection>(rWrt.pDoc->GetTextDirection(aPos));
1055 OutSvxFrmDir(rWrt, SvxFrameDirectionItem(eDir, RES_FRAMEDIR));
1058 static Writer& OutRTF_SwTxtINetFmt( Writer& rWrt, const SfxPoolItem& rHt )
1060 const SwFmtINetFmt& rURL = (const SwFmtINetFmt&)rHt;
1061 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
1062 if( rURL.GetValue().Len() )
1064 rWrt.Strm() << '{' << OOO_STRING_SVTOOLS_RTF_FIELD << '{' << OOO_STRING_SVTOOLS_RTF_IGNORE
1065 << OOO_STRING_SVTOOLS_RTF_FLDINST << " HYPERLINK ";
1067 String sURL( rURL.GetValue() );
1068 if( INET_MARK_TOKEN != sURL.GetChar(0) )
1070 INetURLObject aTmp( URIHelper::simpleNormalizedMakeRelative(rWrt.GetBaseURL(),
1071 sURL));
1074 sURL = aTmp.GetURLNoMark( INetURLObject::DECODE_UNAMBIGUOUS);
1075 /* if( INET_PROT_FILE == aTmp.GetProtocol() )
1077 // WW97 wollen keine FILE-URL haben, sondern einen normalen
1078 // Dateinamen. Aber ab WW2000 kennen sie FileURLs.
1079 sURL = aTmp.GetFull();
1081 */ rWrt.Strm() << '\"';
1082 RTFOutFuncs::Out_String( rWrt.Strm(), sURL, rRTFWrt.eCurrentEncoding,
1083 rRTFWrt.bWriteHelpFmt ) << "\" ";
1084 sURL = aTmp.GetMark();
1087 if( sURL.Len() )
1089 rWrt.Strm() << "\\\\l \"";
1090 sURL.Erase( 0, 1 );
1091 RTFOutFuncs::Out_String( rWrt.Strm(), sURL, rRTFWrt.eCurrentEncoding,
1092 rRTFWrt.bWriteHelpFmt ) << "\" ";
1095 if( rURL.GetTargetFrame().Len() )
1097 rWrt.Strm() << "\\\\t \"";
1098 RTFOutFuncs::Out_String( rWrt.Strm(), rURL.GetTargetFrame(),
1099 rRTFWrt.eDefaultEncoding, rRTFWrt.bWriteHelpFmt ) << "\" ";
1102 rWrt.Strm() << "}{" << OOO_STRING_SVTOOLS_RTF_FLDRSLT << ' ';
1103 rRTFWrt.bOutFmtAttr = false;
1105 // und dann noch die Attributierung ausgeben
1106 const SwCharFmt* pFmt;
1107 const SwTxtINetFmt* pTxtAtr = rURL.GetTxtINetFmt();
1108 if( pTxtAtr && 0 != ( pFmt = pTxtAtr->GetCharFmt() ))
1109 OutRTF_SwFmt( rWrt, *pFmt );
1111 return rWrt;
1114 void HandleHyperlinks(Writer& rWrt, const SwpHints* pTxtAttrs, xub_StrLen nPos )
1116 USHORT nCount = pTxtAttrs ? pTxtAttrs->Count() : 0;
1117 for(USHORT i = 0; i < nCount; ++i )
1119 const SwTxtAttr* pHt = (*pTxtAttrs)[i];
1120 const SfxPoolItem &rItem = pHt->GetAttr();
1121 if (rItem.Which() == RES_TXTATR_INETFMT)
1123 const xub_StrLen* pEnd;
1124 if (nPos == *pHt->GetStart())
1125 OutRTF_SwTxtINetFmt(rWrt, rItem);
1126 if (0 != ( pEnd = pHt->GetEnd() ) && nPos == *pEnd)
1128 // Hyperlinks werden als Felder geschrieben, aber der
1129 // "FieldResult" // steht als Text im TextNode. Also muss bei
1130 // diesen Attributen am // Ende 2 Klammern stehen!
1131 rWrt.Strm() << "}}";
1137 static Writer& OutRTF_SwTxtNode( Writer& rWrt, SwCntntNode& rNode )
1139 SwTxtNode * pNd = &((SwTxtNode&)rNode);
1140 SwRTFWriter & rRTFWrt = (SwRTFWriter&)rWrt;
1141 xub_StrLen nStrPos = rRTFWrt.pCurPam->GetPoint()->nContent.GetIndex();
1142 RTFEndPosLst aEndPosLst( rRTFWrt, *pNd, nStrPos );
1143 USHORT nAttrPos = 0;
1145 const String& rStr = pNd->GetTxt();
1146 xub_StrLen nEnde = rStr.Len();
1147 if( rRTFWrt.pCurPam->GetPoint()->nNode == rRTFWrt.pCurPam->GetMark()->nNode )
1148 nEnde = Min( nEnde, rRTFWrt.pCurPam->GetMark()->nContent.GetIndex() );
1150 int bNewFmts = rRTFWrt.GetAttrSet() != &pNd->GetSwAttrSet();
1151 if( bNewFmts )
1153 // harte Attributierung am Node und am Vorgaenger ?
1154 const SfxItemSet* pNdSet = pNd->GetpSwAttrSet();
1155 if( pNdSet && rRTFWrt.GetAttrSet() && rRTFWrt.bAutoAttrSet &&
1156 pNdSet->GetParent() == rRTFWrt.GetAttrSet()->GetParent() &&
1157 pNdSet->Count() == rRTFWrt.GetAttrSet()->Count() )
1159 // die beiden Parents sind gleich, dann teste doch mal die
1160 // Attribute im Set
1162 int bEqual = TRUE;
1163 if( pNdSet->Count() )
1165 SfxItemIter aIter( *rRTFWrt.GetAttrSet() );
1166 const SfxPoolItem *pItem, *pCurr = aIter.GetCurItem();
1167 while( TRUE )
1169 if( SFX_ITEM_SET != pNdSet->GetItemState( pCurr->Which(),
1170 false, &pItem ) || *pItem != *pCurr )
1172 bEqual = false;
1173 break;
1176 if( aIter.IsAtEnd() )
1177 break;
1178 pCurr = aIter.NextItem();
1181 if (bEqual)
1182 bNewFmts = false;
1184 rRTFWrt.SetAttrSet( &pNd->GetSwAttrSet() );
1185 rRTFWrt.bAutoAttrSet = 0 != pNdSet;
1188 // Flag zuruecksetzen, damit nach der Ausgabe der Collection
1189 // getestet werden kann, ob noch ein Blank auszugeben ist
1190 rRTFWrt.bOutFmtAttr = false;
1192 // in der Ausgabe eines Flys? Dann vorm ausgeben der AbsatzAttribute
1193 // den Format-Pointer auf 0 setzen!
1194 const SwFlyFrmFmt* pSaveFmt = rRTFWrt.pFlyFmt;
1196 SfxItemSet aMergedSet(rRTFWrt.pDoc->GetAttrPool(), POOLATTR_BEGIN,
1197 POOLATTR_END-1);
1198 bool bDeep = false;
1200 if( rRTFWrt.bWriteAll )
1202 rRTFWrt.Strm() << OOO_STRING_SVTOOLS_RTF_PARD << OOO_STRING_SVTOOLS_RTF_PLAIN << ' '; // alle Attribute zuruecksetzen
1203 if( rRTFWrt.bOutTable )
1204 rRTFWrt.Strm() << OOO_STRING_SVTOOLS_RTF_INTBL;
1206 // ist der aktuelle Absatz in einem freifliegenden Rahmen ? Dann
1207 // muessen noch die Attribute dafuer ausgegeben werden.
1208 if( pSaveFmt )
1210 OutRTF_SwFlyFrmFmt( rRTFWrt );
1211 rRTFWrt.pFlyFmt = 0;
1214 rRTFWrt.OutListNum( *pNd );
1215 OutRTF_SwRTL(rRTFWrt, pNd);
1216 SwFmtToSet(rRTFWrt, pNd->GetAnyFmtColl(), aMergedSet);
1217 bDeep = true;
1219 else if( !rRTFWrt.bWriteAll && rRTFWrt.bFirstLine )
1221 OutRTF_SwRTL(rRTFWrt, pNd);
1222 SwFmtToSet(rRTFWrt, pNd->GetAnyFmtColl(), aMergedSet);
1223 bDeep = true;
1226 // gibt es harte Attributierung ?
1227 if( bNewFmts && pNd->HasSwAttrSet())
1229 rRTFWrt.pFlyFmt = 0;
1231 const SfxItemSet& rNdSet = pNd->GetSwAttrSet();
1233 const SwNumRule* pRule = pNd->GetNumRule();
1234 // --> OD 2008-03-19 #refactorlists#
1235 if ( pRule && pNd->IsInList() )
1236 // <--
1238 // --> OD 2008-03-18 #refactorlists#
1239 ASSERT( pNd->GetActualListLevel() >= 0 && pNd->GetActualListLevel() < MAXLEVEL,
1240 "<OutRTF_SwTxtNode(..)> - text node does not have valid list level. Serious defect -> please inform OD" );
1241 // <--
1242 BYTE nLvl = static_cast< BYTE >(pNd->GetActualListLevel());
1243 const SwNumFmt* pFmt = pRule->GetNumFmt( nLvl );
1244 if( !pFmt )
1245 pFmt = &pRule->Get( nLvl );
1247 SfxItemSet aSet( rNdSet );
1248 SvxLRSpaceItem aLR( (SvxLRSpaceItem&)rNdSet.Get( RES_LR_SPACE ) );
1250 aLR.SetTxtLeft( aLR.GetTxtLeft() + pFmt->GetAbsLSpace() );
1251 if( MAXLEVEL > pNd->GetActualListLevel() )
1252 aLR.SetTxtFirstLineOfst( pFmt->GetFirstLineOffset() );
1253 else
1254 aSet.ClearItem( RES_PARATR_NUMRULE );
1255 aSet.Put( aLR );
1256 aMergedSet.Put(aSet);
1258 else
1259 aMergedSet.Put(rNdSet);
1262 SwTxtNode *txtNode=rNode.GetTxtNode();
1263 if (txtNode!=NULL && !txtNode->IsNumbered())
1265 aMergedSet.ClearItem(RES_PARATR_NUMRULE);
1267 OutRTF_SfxItemSet(rRTFWrt, aMergedSet, bDeep);
1269 rRTFWrt.pFlyFmt = pSaveFmt;
1271 rRTFWrt.bTxtAttr = true;
1272 // erstmal den Start berichtigen. D.h. wird nur ein Teil vom Satz
1273 // ausgegeben, so muessen auch da die Attribute stimmen!!
1274 const SwTxtAttr * pHt = 0;
1275 USHORT nCntAttr = pNd->HasHints() ? pNd->GetSwpHints().Count() : 0;
1276 if( nCntAttr && nStrPos > *( pHt = pNd->GetSwpHints()[ 0 ] )->GetStart() )
1278 // Ok, es gibt vorher Attribute, die ausgegeben werden muessen
1279 do {
1280 nAttrPos++;
1281 if( RES_TXTATR_FIELD == pHt->Which() ) // Felder nicht
1282 continue; // ausgeben
1284 if( pHt->GetEnd() )
1286 xub_StrLen nHtEnd = *pHt->GetEnd(), nHtStt = *pHt->GetStart();
1287 if( !rRTFWrt.bWriteAll && nHtEnd <= nStrPos )
1288 continue;
1290 // leere Hints am Anfang nicht beachten, oder ??
1291 if( nHtEnd == nHtStt )
1292 continue;
1294 // Attribut in die Liste aufnehemen
1295 if( !rRTFWrt.bWriteAll )
1297 if( nHtStt < nStrPos ) nHtStt = nStrPos;
1298 if( nHtEnd >= nEnde ) nHtEnd = nEnde;
1300 aEndPosLst.Insert( pHt->GetAttr(), nHtStt, nHtEnd );
1301 continue;
1302 // aber nicht ausgeben, das erfolgt spaeter !!
1304 Out( aRTFAttrFnTab, pHt->GetAttr(), rRTFWrt );
1306 } while( nAttrPos < nCntAttr && nStrPos >
1307 *( pHt = pNd->GetSwpHints()[ nAttrPos ] )->GetStart() );
1309 // dann gebe mal alle gesammelten Attribute von der String-Pos aus
1310 aEndPosLst.OutAttrs( nStrPos );
1313 if( rRTFWrt.bOutFmtAttr &&
1314 ( nAttrPos < nCntAttr ? *pHt->GetStart() != nStrPos : TRUE ))
1315 rRTFWrt.Strm() << ' ';
1317 // das Flag gibt an, ob das SwTxtFld am Ende vom Absatz steht. Denn
1318 // dann ist vor dem Absatzumbruch die schliessende Klammer auszugeben
1319 xub_StrLen nChrCnt = 0;
1320 for( ; nStrPos <= nEnde; nStrPos++ )
1322 rRTFWrt.bOutFmtAttr = false;
1323 if( nStrPos != nEnde && aEndPosLst.Count() )
1324 aEndPosLst.EndAttrs( nStrPos );
1326 // versuche nach ungefaehr 255 Zeichen eine neue Zeile zu beginnen
1327 if( nChrCnt != ( nStrPos & 0xff00 ))
1329 rWrt.Strm() << SwRTFWriter::sNewLine;
1330 nChrCnt = nStrPos & 0xff00;
1333 if( nAttrPos < nCntAttr && *pHt->GetStart() == nStrPos
1334 && nStrPos != nEnde )
1336 do {
1337 BOOL bEmpty = false;
1338 if( pHt->GetEnd() )
1340 if (false == (bEmpty = *pHt->GetEnd() == nStrPos))
1342 aEndPosLst.Insert( pHt->GetAttr(), nStrPos,
1343 *pHt->GetEnd() );
1344 continue;
1346 rRTFWrt.Strm() << '{';
1348 Out( aRTFAttrFnTab, pHt->GetAttr(), rRTFWrt );
1349 if( bEmpty )
1351 rRTFWrt.Strm() << '}';
1352 rRTFWrt.bOutFmtAttr = false;
1354 } while( ++nAttrPos < nCntAttr && nStrPos ==
1355 *( pHt = pNd->GetSwpHints()[ nAttrPos ] )->GetStart() );
1357 // dann gebe mal alle gesammelten Attribute von der String-Pos aus
1358 aEndPosLst.OutAttrs( nStrPos );
1361 else
1362 aEndPosLst.OutScriptChange( nStrPos );
1364 HandleHyperlinks(rWrt, pNd->GetpSwpHints(), nStrPos);
1366 if( rRTFWrt.bOutFmtAttr )
1367 rRTFWrt.Strm() << ' ';
1369 rRTFWrt.OutBookmarks( nStrPos );
1371 rRTFWrt.OutRedline( nStrPos);
1373 if (nStrPos != nEnde)
1375 RTFOutFuncs::Out_String(rWrt.Strm(), String(rStr.GetChar(nStrPos)),
1376 rRTFWrt.eCurrentEncoding, rRTFWrt.bWriteHelpFmt);
1380 rRTFWrt.bTxtAttr = false;
1382 // noch eine schliesende Klammer da ??
1383 if( aEndPosLst.Count() )
1384 aEndPosLst.EndAttrs( USHRT_MAX );
1386 // wenn bis zum Ende vom Node, dann auch das AbsatzEnde ausgeben
1387 if( rRTFWrt.pCurPam->GetMark()->nNode.GetIndex() ==
1388 rRTFWrt.pCurPam->GetPoint()->nNode.GetIndex() )
1390 if( pNd->Len() != rRTFWrt.pCurPam->GetMark()->nContent.GetIndex() )
1391 return rWrt;
1393 if( rRTFWrt.bOutTable )
1395 rRTFWrt.Strm() << SwRTFWriter::sNewLine;
1396 return rWrt;
1400 rRTFWrt.Strm() << SwRTFWriter::sNewLine << OOO_STRING_SVTOOLS_RTF_PAR << ' ';
1401 return rRTFWrt;
1404 bool IsEMF(const sal_uInt8 *pGraphicAry, unsigned long nSize)
1406 if (pGraphicAry && (nSize > 0x2c ))
1408 // check the magic number
1409 if (
1410 (pGraphicAry[0x28] == 0x20 ) && (pGraphicAry[0x29] == 0x45) &&
1411 (pGraphicAry[0x2a] == 0x4d ) && (pGraphicAry[0x2b] == 0x46)
1414 //emf detected
1415 return true;
1418 return false;
1421 bool StripMetafileHeader(const sal_uInt8 *&rpGraphicAry, unsigned long &rSize)
1423 if (rpGraphicAry && (rSize > 0x22))
1425 if (
1426 (rpGraphicAry[0] == 0xd7) && (rpGraphicAry[1] == 0xcd) &&
1427 (rpGraphicAry[2] == 0xc6) && (rpGraphicAry[3] == 0x9a)
1429 { // we have to get rid of the metafileheader
1430 rpGraphicAry += 22;
1431 rSize -= 22;
1432 return true;
1435 return false;
1438 void ExportPICT(const Size &rOrig, const Size &rRendered, const Size &rMapped,
1439 const SwCropGrf &rCr, const char *pBLIPType, const sal_uInt8 *pGraphicAry,
1440 unsigned long nSize, SwRTFWriter &rWrt)
1442 bool bIsWMF = (const char *)pBLIPType == (const char *)OOO_STRING_SVTOOLS_RTF_WMETAFILE ? true : false;
1443 if (pBLIPType && nSize && pGraphicAry)
1445 rWrt.Strm() << '{' << OOO_STRING_SVTOOLS_RTF_PICT;
1447 long nXCroppedSize = rOrig.Width()-(rCr.GetLeft() + rCr.GetRight());
1448 long nYCroppedSize = rOrig.Height()-(rCr.GetTop() + rCr.GetBottom());
1449 /* #127543#: Graphic with a zero height or width, typically copied from webpages, caused
1450 crashes. */
1451 if( !nXCroppedSize )
1452 nXCroppedSize = 100;
1453 if( !nYCroppedSize )
1454 nYCroppedSize = 100;
1456 //Given the original size and taking cropping into account
1457 //first, how much has the original been scaled to get the
1458 //final rendered size
1459 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_PICSCALEX;
1460 rWrt.OutLong((100 * rRendered.Width()) / nXCroppedSize);
1461 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_PICSCALEY;
1462 rWrt.OutLong((100 * rRendered.Height()) / nYCroppedSize);
1464 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_PICCROPL;
1465 rWrt.OutLong(rCr.GetLeft());
1466 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_PICCROPR;
1467 rWrt.OutLong(rCr.GetRight());
1468 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_PICCROPT;
1469 rWrt.OutLong(rCr.GetTop());
1470 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_PICCROPB;
1471 rWrt.OutLong(rCr.GetBottom());
1473 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_PICW;
1474 rWrt.OutLong(rMapped.Width());
1475 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_PICH;
1476 rWrt.OutLong(rMapped.Height());
1478 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_PICWGOAL;
1479 rWrt.OutLong(rOrig.Width());
1480 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_PICHGOAL;
1481 rWrt.OutLong(rOrig.Height());
1483 rWrt.Strm() << pBLIPType;
1484 if (bIsWMF)
1486 rWrt.OutLong(8);
1487 StripMetafileHeader(pGraphicAry, nSize);
1489 rWrt.Strm() << SwRTFWriter::sNewLine;
1491 sal_uInt32 nBreak = 0;
1492 for (sal_uInt32 nI = 0; nI < nSize; ++nI)
1494 ByteString sNo = ByteString::CreateFromInt32(pGraphicAry[nI], 16);
1495 if (sNo.Len() < 2)
1496 rWrt.Strm() << '0';
1497 rWrt.Strm() << sNo.GetBuffer();
1498 if (++nBreak == 64)
1500 rWrt.Strm() << SwRTFWriter::sNewLine;
1501 nBreak = 0;
1505 rWrt.Strm() << '}';
1509 static Writer& OutRTF_SwGrfNode(Writer& rWrt, SwCntntNode & rNode)
1511 SwRTFWriter & rRTFWrt = (SwRTFWriter&)rWrt;
1512 SwGrfNode &rNd = (SwGrfNode&)rNode;
1514 // ist der aktuelle Absatz in einem freifliegenden Rahmen ? Dann
1515 // muessen noch die Attribute dafuer ausgegeben werden.
1516 if (rRTFWrt.pFlyFmt && !ExportAsInline(*rRTFWrt.pFlyFmt))
1517 OutRTF_SwFlyFrmFmt(rRTFWrt); //"classic" positioning and size export
1519 #if 1
1520 SvMemoryStream aStream;
1521 const sal_uInt8* pGraphicAry = 0;
1522 sal_uInt32 nSize = 0;
1524 Graphic aGraphic(rNd.GetGrf());
1526 // If there is no graphic there is not much point in parsing it
1527 if(aGraphic.GetType()==GRAPHIC_NONE)
1528 return rRTFWrt;
1530 GfxLink aGraphicLink;
1531 const sal_Char* pBLIPType = 0;
1532 if (aGraphic.IsLink())
1534 aGraphicLink = aGraphic.GetLink();
1535 nSize = aGraphicLink.GetDataSize();
1536 pGraphicAry = aGraphicLink.GetData();
1537 switch (aGraphicLink.GetType())
1539 case GFX_LINK_TYPE_NATIVE_JPG:
1540 pBLIPType = OOO_STRING_SVTOOLS_RTF_JPEGBLIP;
1541 break;
1542 case GFX_LINK_TYPE_NATIVE_PNG:
1543 pBLIPType = OOO_STRING_SVTOOLS_RTF_PNGBLIP;
1544 case GFX_LINK_TYPE_NATIVE_WMF:
1545 pBLIPType =
1546 IsEMF(pGraphicAry, nSize) ? OOO_STRING_SVTOOLS_RTF_EMFBLIP : OOO_STRING_SVTOOLS_RTF_WMETAFILE;
1547 break;
1548 default:
1549 break;
1553 GraphicType eGraphicType = aGraphic.GetType();
1554 if (!pGraphicAry)
1556 if (ERRCODE_NONE == GraphicConverter::Export(aStream, aGraphic,
1557 (eGraphicType == GRAPHIC_BITMAP) ? CVT_PNG : CVT_WMF))
1559 pBLIPType = (eGraphicType == GRAPHIC_BITMAP) ?
1560 OOO_STRING_SVTOOLS_RTF_PNGBLIP : OOO_STRING_SVTOOLS_RTF_WMETAFILE;
1561 aStream.Seek(STREAM_SEEK_TO_END);
1562 nSize = aStream.Tell();
1563 pGraphicAry = (sal_uInt8*)aStream.GetData();
1567 Size aMapped(eGraphicType == GRAPHIC_BITMAP ? aGraphic.GetSizePixel() : aGraphic.GetPrefSize());
1569 const SwCropGrf &rCr = (const SwCropGrf &)rNd.GetAttr(RES_GRFATR_CROPGRF);
1571 //Get original size in twips
1572 Size aSize(sw::util::GetSwappedInSize(rNd));
1573 Size aRendered(aSize);
1574 if (rRTFWrt.pFlyFmt)
1576 const SwFmtFrmSize& rS = rRTFWrt.pFlyFmt->GetFrmSize();
1577 aRendered.Width() = rS.GetWidth();
1578 aRendered.Height() = rS.GetHeight();
1582 If the graphic is not of type WMF then we will have to store two
1583 graphics, one in the native format wrapped in shppict, and the other in
1584 the wmf format wrapped in nonshppict, so as to keep wordpad happy. If its
1585 a wmf already then we don't need any such wrapping
1587 bool bIsWMF = (const sal_Char*)pBLIPType == (const sal_Char*)OOO_STRING_SVTOOLS_RTF_WMETAFILE ? true : false;
1588 if (!bIsWMF)
1589 OutComment(rRTFWrt, OOO_STRING_SVTOOLS_RTF_SHPPICT);
1591 if (pBLIPType)
1592 ExportPICT(aSize, aRendered, aMapped, rCr, pBLIPType, pGraphicAry, nSize, rRTFWrt);
1593 else
1595 aStream.Seek(0);
1596 GraphicConverter::Export(aStream, aGraphic, CVT_WMF);
1597 pBLIPType = OOO_STRING_SVTOOLS_RTF_WMETAFILE;
1598 aStream.Seek(STREAM_SEEK_TO_END);
1599 nSize = aStream.Tell();
1600 pGraphicAry = (sal_uInt8*)aStream.GetData();
1602 ExportPICT(aSize, aRendered, aMapped, rCr, pBLIPType, pGraphicAry, nSize,
1603 rRTFWrt);
1606 if (!bIsWMF)
1608 rRTFWrt.Strm() << '}' << '{' << OOO_STRING_SVTOOLS_RTF_NONSHPPICT;
1610 aStream.Seek(0);
1611 GraphicConverter::Export(aStream, aGraphic, CVT_WMF);
1612 pBLIPType = OOO_STRING_SVTOOLS_RTF_WMETAFILE;
1613 aStream.Seek(STREAM_SEEK_TO_END);
1614 nSize = aStream.Tell();
1615 pGraphicAry = (sal_uInt8*)aStream.GetData();
1617 ExportPICT(aSize, aRendered, aMapped, rCr, pBLIPType, pGraphicAry, nSize,
1618 rRTFWrt);
1620 rRTFWrt.Strm() << '}';
1624 rRTFWrt.Strm() << SwRTFWriter::sNewLine;
1625 #else
1626 rRTFWrt.Strm() << "{{";
1628 // damit die eigenen Grafik-Attribute nach der PICT / import Anweisung
1629 // stehen, muessen die am Anfang ausgegeben werden.
1630 rRTFWrt.bOutFmtAttr = false;
1631 OutRTF_SwFmt( rRTFWrt, *pNd->GetFmtColl() );
1633 if( rRTFWrt.bOutFmtAttr ) // wurde ueberhaupt ein Attrribut
1634 rRTFWrt.Strm() << "}{"; // ausgegeben ??
1636 String aGrfNm;
1637 const SwMirrorGrf& rMirror = pNd->GetSwAttrSet().GetMirrorGrf();
1638 if( !pNd->IsLinkedFile() || RES_MIRROR_GRAPH_DONT != rMirror.GetValue() )
1640 USHORT nErr = 1;
1641 // Grafik als File-Referenz speichern (als JPEG-Grafik speichern)
1642 // but only if we save into a file and have a URL
1643 if( rWrt.GetOrigFileName() )
1645 aGrfNm = *rWrt.GetOrigFileName();
1646 pNd->SwapIn( TRUE );
1647 ULONG nFlags = XOUTBMP_USE_NATIVE_IF_POSSIBLE;
1648 switch( rMirror.GetValue() )
1650 case RES_MIRROR_GRAPH_VERT: nFlags = XOUTBMP_MIRROR_HORZ; break;
1651 case RES_MIRROR_GRAPH_HOR: nFlags = XOUTBMP_MIRROR_VERT; break;
1652 case RES_MIRROR_GRAPH_BOTH:
1653 nFlags = XOUTBMP_MIRROR_VERT | XOUTBMP_MIRROR_HORZ;
1654 break;
1657 Size aMM100Size;
1658 Size* pMM100Size = 0;
1659 if( rRTFWrt.pFlyFmt )
1661 const SwFmtFrmSize& rSize = rRTFWrt.pFlyFmt->GetFrmSize();
1662 aMM100Size = OutputDevice::LogicToLogic( rSize.GetSize(),
1663 MapMode( MAP_TWIP ), MapMode( MAP_100TH_MM ));
1664 pMM100Size = &aMM100Size;
1667 nErr = XOutBitmap::WriteGraphic( pNd->GetGrf(), aGrfNm,
1668 String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "JPG" )),
1669 nFlags, pMM100Size );
1671 if( nErr ) // fehlerhaft, da ist nichts auszugeben
1673 rRTFWrt.Strm() << "}}";
1674 return rWrt;
1677 else
1678 pNd->GetFileFilterNms( &aGrfNm, 0 );
1680 // MIB->JP: Warum erst AbsToRel und dann das URL-Objekt? So
1681 // kommt bei relativierbaren URLs als Protokoll "unknown" raus.
1682 // Ist das Absicht?
1683 aGrfNm = INetURLObject::AbsToRel( aGrfNm, INetURLObject::WAS_ENCODED,
1684 INetURLObject::DECODE_UNAMBIGUOUS);
1685 INetURLObject aUrl( aGrfNm );
1686 if( aUrl.GetProtocol() == INET_PROT_FILE )
1687 aGrfNm = aUrl.PathToFileName();
1689 // Bitmap als File-Referenz speichern
1690 rRTFWrt.Strm() << OOO_STRING_SVTOOLS_RTF_FIELD << OOO_STRING_SVTOOLS_RTF_FLDPRIV;
1691 OutComment( rRTFWrt, OOO_STRING_SVTOOLS_RTF_FLDINST ) << "{\\\\import ";
1692 RTFOutFuncs::Out_String( rWrt.Strm(), aGrfNm, rRTFWrt.eDefaultEncoding,
1693 rRTFWrt.bWriteHelpFmt );
1694 rRTFWrt.Strm() << "}}{" << OOO_STRING_SVTOOLS_RTF_FLDRSLT << " }}";
1695 rRTFWrt.Strm() << '}' << SwRTFWriter::sNewLine;
1696 #endif
1697 return rRTFWrt;
1700 static Writer& OutRTF_SwOLENode( Writer& rWrt, SwCntntNode & /*rNode*/ )
1702 SwRTFWriter & rRTFWrt = (SwRTFWriter&)rWrt;
1704 // ist der aktuelle Absatz in einem freifliegenden Rahmen ? Dann
1705 // muessen noch die Attribute dafuer ausgegeben werden.
1706 if( rRTFWrt.pFlyFmt )
1707 OutRTF_SwFlyFrmFmt( rRTFWrt );
1709 rWrt.Strm() << SwRTFWriter::sNewLine << OOO_STRING_SVTOOLS_RTF_PAR;
1710 return rWrt;
1713 static void OutTBLBorderLine(SwRTFWriter& rWrt, const SvxBorderLine* pLine,
1714 const sal_Char* pStr)
1716 ByteString sLineStr;
1717 if( pLine->GetInWidth() )
1719 // doppelte Linie
1720 sLineStr = OOO_STRING_SVTOOLS_RTF_BRDRDB;
1721 switch( pLine->GetInWidth() )
1723 case DEF_LINE_WIDTH_0:
1724 ( sLineStr += OOO_STRING_SVTOOLS_RTF_BRDRW ) += "15";
1725 break;
1726 case DEF_LINE_WIDTH_1:
1727 ( sLineStr += OOO_STRING_SVTOOLS_RTF_BRDRW ) += "30";
1728 break;
1729 case DEF_LINE_WIDTH_2:
1730 case DEF_LINE_WIDTH_3:
1731 ( sLineStr += OOO_STRING_SVTOOLS_RTF_BRDRW ) += "45";
1732 break;
1735 else
1737 // einfache Linie
1738 if( DEF_LINE_WIDTH_1 >= pLine->GetOutWidth() )
1739 (( sLineStr = OOO_STRING_SVTOOLS_RTF_BRDRS ) += OOO_STRING_SVTOOLS_RTF_BRDRW ) +=
1740 ByteString::CreateFromInt32( pLine->GetOutWidth() );
1741 else
1742 (( sLineStr = OOO_STRING_SVTOOLS_RTF_BRDRTH ) += OOO_STRING_SVTOOLS_RTF_BRDRW ) +=
1743 ByteString::CreateFromInt32( pLine->GetOutWidth() / 2 );
1746 rWrt.Strm() << pStr << sLineStr.GetBuffer() << OOO_STRING_SVTOOLS_RTF_BRDRCF;
1747 rWrt.OutULong( rWrt.GetId( pLine->GetColor() ) );
1750 static void OutBorderLine(SwRTFWriter& rWrt, const SvxBorderLine* pLine,
1751 const sal_Char* pStr, USHORT nDist)
1753 OutTBLBorderLine(rWrt, pLine, pStr);
1754 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_BRSP;
1755 rWrt.OutULong( nDist );
1758 static void OutSwTblBorder(SwRTFWriter& rWrt, const SvxBoxItem& rBox,
1759 const SvxBoxItem *pDefault)
1761 static const USHORT aBorders[] =
1763 BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT
1765 #ifdef __MINGW32__
1766 static const char* aBorderNames[] __attribute__((section(".data"))) =
1767 #else
1768 static const char* aBorderNames[] =
1769 #endif
1771 OOO_STRING_SVTOOLS_RTF_CLBRDRT, OOO_STRING_SVTOOLS_RTF_CLBRDRL, OOO_STRING_SVTOOLS_RTF_CLBRDRB, OOO_STRING_SVTOOLS_RTF_CLBRDRR
1773 //Yes left and top are swapped with eachother for cell padding! Because
1774 //that's what the thunderingly annoying rtf export/import word xp does.
1775 #ifdef __MINGW32__
1776 static const char* aCellPadNames[] __attribute__((section(".data"))) =
1777 #else
1778 static const char* aCellPadNames[] =
1779 #endif
1781 OOO_STRING_SVTOOLS_RTF_CLPADL, OOO_STRING_SVTOOLS_RTF_CLPADT, OOO_STRING_SVTOOLS_RTF_CLPADB, OOO_STRING_SVTOOLS_RTF_CLPADR
1783 #ifdef __MINGW32__
1784 static const char* aCellPadUnits[] __attribute__((section(".data"))) =
1785 #else
1786 static const char* aCellPadUnits[] =
1787 #endif
1789 OOO_STRING_SVTOOLS_RTF_CLPADFL, OOO_STRING_SVTOOLS_RTF_CLPADFT, OOO_STRING_SVTOOLS_RTF_CLPADFB, OOO_STRING_SVTOOLS_RTF_CLPADFR
1791 for (int i = 0; i < 4; ++i)
1793 if (const SvxBorderLine* pLn = rBox.GetLine(aBorders[i]))
1794 OutTBLBorderLine(rWrt, pLn, aBorderNames[i]);
1795 if (!pDefault || pDefault->GetDistance(aBorders[i]) !=
1796 rBox.GetDistance(aBorders[i]))
1798 rWrt.Strm() << aCellPadUnits[i];
1799 rWrt.OutULong(3);
1800 rWrt.Strm() << aCellPadNames[i];
1801 rWrt.OutULong(rBox.GetDistance(aBorders[i]));
1806 static void OutSwTblBackground( SwRTFWriter& rWrt, const SvxBrushItem& rBack )
1808 if( !rBack.GetColor().GetTransparency() )
1810 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_CLCBPAT;
1811 rWrt.OutULong( rWrt.GetId( rBack.GetColor() ) );
1816 Writer& OutRTF_SwTblNode(Writer& rWrt, const SwTableNode & rNode)
1818 SwRTFWriter & rRTFWrt = (SwRTFWriter&)rWrt;
1819 const SwTable& rTbl = rNode.GetTable();
1820 SwTwips nPageSize = 0, nTblOffset = 0;
1821 const bool bNewTableModel = rTbl.IsNewModel();
1824 //!!!!!!!!!!!!! for clipboard create any view if the table is complex !!!
1825 if( rTbl.IsTblComplex() )
1827 // then we have to create any layout
1828 SFX_APP()->CreateViewFrame( *xDocSh, 0, TRUE );
1832 const SwFrmFmt *pFmt = rTbl.GetFrmFmt();
1833 ASSERT(pFmt, "Impossible");
1835 Point aPt;
1836 SwRect aRect( pFmt->FindLayoutRect( false, &aPt ));
1837 if( aRect.IsEmpty() )
1839 // dann besorge mal die Seitenbreite ohne Raender !!
1840 const SwFrmFmt* pFrmFmt = rRTFWrt.pFlyFmt ? rRTFWrt.pFlyFmt :
1841 const_cast<const SwDoc *>(rWrt.pDoc)
1842 ->GetPageDesc(0).GetPageFmtOfNode(rNode, false);
1844 aRect = pFrmFmt->FindLayoutRect( TRUE );
1845 if( 0 == ( nPageSize = aRect.Width() ))
1847 const SvxLRSpaceItem& rLR = pFrmFmt->GetLRSpace();
1848 nPageSize = pFrmFmt->GetFrmSize().GetWidth() -
1849 rLR.GetLeft() - rLR.GetRight();
1852 else
1853 nPageSize = aRect.Width();
1856 SwTwips nTblSz = pFmt->GetFrmSize().GetWidth();
1858 ByteString aTblAdjust( OOO_STRING_SVTOOLS_RTF_TRQL );
1859 switch (pFmt->GetHoriOrient().GetHoriOrient())
1861 case text::HoriOrientation::CENTER:
1862 aTblAdjust = OOO_STRING_SVTOOLS_RTF_TRQC;
1863 break;
1864 case text::HoriOrientation::RIGHT:
1865 aTblAdjust = OOO_STRING_SVTOOLS_RTF_TRQR;
1866 break;
1867 case text::HoriOrientation::NONE:
1868 case text::HoriOrientation::LEFT_AND_WIDTH:
1870 const SvxLRSpaceItem& rLRSp = pFmt->GetLRSpace();
1871 nTblOffset = rLRSp.GetLeft();
1872 nPageSize -= (nTblOffset + rLRSp.GetRight());
1873 aTblAdjust += OOO_STRING_SVTOOLS_RTF_TRLEFT;
1874 aTblAdjust += ByteString::CreateFromInt32( nTblOffset );
1876 break;
1877 default:
1878 break;
1881 if (rRTFWrt.TrueFrameDirection(*pFmt) == FRMDIR_HORI_RIGHT_TOP)
1882 aTblAdjust += OOO_STRING_SVTOOLS_RTF_RTLROW;
1884 // ist die Tabelle wesentlich (PageSize + 10%) groesser als die Seite,
1885 // dann sind die Box-Breiten relative Angaben.
1886 BOOL bRelBoxSize = TRUE /*ALWAYS relativ (nPageSize + ( nPageSize / 10 )) < nTblSz*/;
1888 SwWriteTable* pTableWrt;
1889 const SwHTMLTableLayout *pLayout = rTbl.GetHTMLTableLayout();
1890 if( pLayout && pLayout->IsExportable() )
1891 pTableWrt = new SwWriteTable( pLayout );
1892 else
1893 pTableWrt = new SwWriteTable(rTbl.GetTabLines(), (USHORT)nPageSize,
1894 (USHORT)nTblSz, false);
1896 // rCols are the array of all cols of the table
1897 const SwWriteTableCols& rCols = pTableWrt->GetCols();
1898 USHORT nColCnt = rCols.Count();
1899 SwWriteTableCellPtr* pBoxArr = new SwWriteTableCellPtr[ nColCnt ];
1900 USHORT* pRowSpans = new USHORT[ nColCnt ];
1901 memset( pBoxArr, 0, sizeof( pBoxArr[0] ) * nColCnt );
1902 memset( pRowSpans, 0, sizeof( pRowSpans[0] ) * nColCnt );
1903 const SwWriteTableRows& rRows = pTableWrt->GetRows();
1904 for( USHORT nLine = 0; nLine < rRows.Count(); ++nLine )
1906 USHORT nBox;
1908 const SwWriteTableRow *pRow = rRows[ nLine ];
1909 const SwWriteTableCells& rCells = pRow->GetCells();
1911 BOOL bFixRowHeight = false;
1913 USHORT nBoxes = rCells.Count();
1914 if (nColCnt < nBoxes)
1915 nBoxes = nColCnt;
1917 for( nColCnt = 0, nBox = 0; nBox < rCells.Count() && nColCnt < nBoxes; ++nColCnt )
1919 SwWriteTableCell* pCell = rCells[ nBox ];
1920 const bool bProcessCoveredCell = bNewTableModel && 0 == pCell->GetRowSpan();
1922 if( !pRowSpans[ nColCnt ] || bProcessCoveredCell )
1924 // set new BoxPtr
1925 nBox++;
1926 pBoxArr[ nColCnt ] = pCell;
1927 if ( !bProcessCoveredCell )
1928 pRowSpans[ nColCnt ] = pCell->GetRowSpan();
1929 for( USHORT nCellSpan = pCell->GetColSpan(), nCS = 1;
1930 nCS < nCellSpan; ++nCS, ++nColCnt )
1932 ASSERT( nColCnt+1 < rCols.Count(), "More colspan than columns" );
1933 if( nColCnt+1 < rCols.Count() ) // robust against wrong colspans
1935 pBoxArr[ nColCnt+1 ] = pBoxArr[ nColCnt ];
1936 pRowSpans[ nColCnt+1 ] = pRowSpans[ nColCnt ];
1940 if( 1 != pRowSpans[ nColCnt ] && !bNewTableModel )
1941 bFixRowHeight = TRUE;
1944 for( ; nColCnt < rCols.Count() && pRowSpans[ nColCnt ]; ++nColCnt )
1945 bFixRowHeight = TRUE;
1947 nColCnt = rCols.Count(); // A wrong cellspan-value could cause a nColCnt > rCols.Count()
1949 // Start Tabellendefinition
1950 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_TROWD << aTblAdjust.GetBuffer();
1952 if( rTbl.GetRowsToRepeat() > nLine )
1953 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_TRHDR;
1955 const SwTableLine* pLine = pBoxArr[ 0 ]->GetBox()->GetUpper();
1956 // Zeilenhoehe ausgeben
1957 long nHeight = 0;
1958 if( bFixRowHeight && rWrt.pDoc->GetRootFrm() )
1960 nHeight = -pRow->GetPos(); //neg. => abs. height!
1961 if( nLine )
1962 nHeight += rRows[ nLine - 1 ]->GetPos();
1964 else
1966 const SwFmtFrmSize& rLSz = pLine->GetFrmFmt()->GetFrmSize();
1967 if( ATT_VAR_SIZE != rLSz.GetHeightSizeType() && rLSz.GetHeight() )
1968 nHeight = ATT_MIN_SIZE == rLSz.GetHeightSizeType()
1969 ? rLSz.GetHeight()
1970 : -rLSz.GetHeight();
1973 //The rtf default is to allow a row to break, so if we are not
1974 //splittable export TRKEEP
1975 const SwFrmFmt *pLineFmt = pLine ? pLine->GetFrmFmt() : 0;
1976 if (!pLineFmt || pLineFmt->GetRowSplit().GetValue() == 0)
1977 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_TRKEEP;
1979 if( nHeight )
1981 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_TRRH;
1982 rWrt.OutLong( nHeight );
1985 const SvxBoxItem *pDefaultBox = 0;
1986 if (nColCnt)
1988 pDefaultBox = &(pBoxArr[0]->GetBox()->GetFrmFmt()->GetBox());
1990 static const USHORT aBorders[] =
1992 BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT
1994 #ifdef __MINGW32__
1995 static const char* aRowPadNames[] __attribute__((section(".data"))) =
1996 #else
1997 static const char* aRowPadNames[] =
1998 #endif
2000 OOO_STRING_SVTOOLS_RTF_TRPADDT, OOO_STRING_SVTOOLS_RTF_TRPADDL, OOO_STRING_SVTOOLS_RTF_TRPADDB, OOO_STRING_SVTOOLS_RTF_TRPADDR
2002 static const char* aRowPadUnits[] =
2004 OOO_STRING_SVTOOLS_RTF_TRPADDFT, OOO_STRING_SVTOOLS_RTF_TRPADDFL, OOO_STRING_SVTOOLS_RTF_TRPADDFB, OOO_STRING_SVTOOLS_RTF_TRPADDFR
2006 for (int i = 0; i < 4; ++i)
2008 rWrt.Strm() << aRowPadUnits[i];
2009 rWrt.OutULong(3);
2010 rWrt.Strm() << aRowPadNames[i];
2011 rWrt.OutULong(pDefaultBox->GetDistance(aBorders[i]));
2015 // Breite der Boxen ausgeben
2016 SwTwips nSz = 0, nCalc;
2017 for( nBox = 0; nBox < nColCnt; ++nBox )
2019 SwWriteTableCell* pCell = pBoxArr[ nBox ];
2020 if( (nBox && pBoxArr[ nBox-1 ] == pBoxArr[ nBox ]) || (pCell == NULL) )
2021 continue;
2023 const SwFrmFmt& rFmt = *pCell->GetBox()->GetFrmFmt();
2024 if( 1 < pCell->GetRowSpan() || 0 == pCell->GetRowSpan() )
2025 rWrt.Strm() << ( pCell->GetRowSpan() == pRowSpans[ nBox ]
2026 ? OOO_STRING_SVTOOLS_RTF_CLVMGF
2027 : OOO_STRING_SVTOOLS_RTF_CLVMRG );
2029 const SfxPoolItem* pItem;
2030 if (SFX_ITEM_SET == rFmt.GetAttrSet().GetItemState(RES_BOX, TRUE,
2031 &pItem))
2033 OutSwTblBorder(rRTFWrt, (SvxBoxItem&)*pItem, pDefaultBox);
2036 // RTF kennt Schattierung in unserem Sinne nicht!
2037 // if( SFX_ITEM_SET == pBoxFmt->GetAttrSet().GetItemState(
2038 // RES_SHADOW, TRUE, &pItem ) )
2039 // OutSwTblShadow( rRTFWrt, *pItem );
2041 if( SFX_ITEM_SET == rFmt.GetAttrSet().GetItemState(
2042 RES_BACKGROUND, TRUE, &pItem )
2043 || 0 != ( pItem = pCell->GetBackground() )
2044 || 0 != ( pItem = pRow->GetBackground() ) )
2045 OutSwTblBackground( rRTFWrt, (SvxBrushItem&)*pItem );
2047 if( SFX_ITEM_SET == rFmt.GetAttrSet().GetItemState(
2048 RES_VERT_ORIENT, TRUE, &pItem ) )
2049 switch( ((SwFmtVertOrient*)pItem)->GetVertOrient() )
2051 case text::VertOrientation::CENTER: rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_CLVERTALC; break;
2052 case text::VertOrientation::BOTTOM: rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_CLVERTALB; break;
2053 default: rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_CLVERTALT; break;
2056 const SwFmtFrmSize& rLSz = rFmt.GetFrmSize();
2057 nSz += rLSz.GetWidth();
2058 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_CELLX;
2060 nCalc = nSz;
2061 if( bRelBoxSize )
2063 nCalc *= nPageSize;
2064 nCalc /= nTblSz;
2066 rWrt.OutLong( nTblOffset + nCalc );
2069 // Inhalt der Boxen ausgeben
2070 rWrt.Strm() << SwRTFWriter::sNewLine << OOO_STRING_SVTOOLS_RTF_PARD << OOO_STRING_SVTOOLS_RTF_INTBL;
2071 for( nBox = 0; nBox < nBoxes; ++nBox )
2073 SwWriteTableCell * pCell = pBoxArr[nBox];
2075 if( (nBox && pBoxArr[ nBox-1 ] == pBoxArr[ nBox ]) || pCell == NULL)
2076 continue;
2078 if( pCell->GetRowSpan() == pRowSpans[ nBox ] )
2080 // new Box
2081 const SwStartNode* pSttNd = pCell->GetBox()->GetSttNd();
2082 RTFSaveData aSaveData( rRTFWrt,
2083 pSttNd->GetIndex()+1, pSttNd->EndOfSectionIndex() );
2084 rRTFWrt.bOutTable = TRUE;
2085 rRTFWrt.Out_SwDoc( rRTFWrt.pCurPam );
2087 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_CELL;
2090 // das wars mit der Line
2091 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_ROW << OOO_STRING_SVTOOLS_RTF_PARD << ' ';
2093 for( nBox = 0; nBox < nColCnt; ++nBox )
2094 --pRowSpans[ nBox ];
2097 delete pTableWrt;
2098 delete[] pBoxArr;
2099 delete[] pRowSpans;
2101 // Pam hinter die Tabelle verschieben
2102 rRTFWrt.pCurPam->GetPoint()->nNode = *rNode.EndOfSectionNode();
2103 rRTFWrt.SetAttrSet( 0 );
2105 return rWrt;
2108 Writer& OutRTF_SwSectionNode( Writer& rWrt, SwSectionNode& rNode )
2110 SwRTFWriter & rRTFWrt = (SwRTFWriter&)rWrt;
2111 const SwSection& rSect = rNode.GetSection();
2113 // folgt dahinter noch ein SectionNode? Dann wird erst die innere
2114 // Section aktiv. Hier wird die Verschachtelung aufgebrochen, weil
2115 // RTF das nicht kennt
2116 BOOL bPgDscWrite = false;
2118 SwNodeIndex aIdx( rNode, 1 );
2119 const SwNode& rNd = aIdx.GetNode();
2120 if( rNd.IsSectionNode() /*&& CONTENT_SECTION ==
2121 aIdx.GetNode().GetSectionNode()->GetSection().GetType()*/ )
2122 return rWrt;
2124 // falls als erstes Position ein Content- oder Tabellen-Node steht,
2125 // dann kann dieser einen PageDesc gesetzt haben und der muss vor
2126 // der Bereichsbeschreibung geschrieben werden!
2127 // Umgekehrt muss im OutBreaks dann
2128 if( rNd.IsCntntNode() )
2130 bPgDscWrite = rRTFWrt.OutBreaks( ((SwCntntNode&)rNd).GetSwAttrSet() );
2131 rRTFWrt.bIgnoreNextPgBreak = TRUE;
2133 else if( rNd.IsTableNode() )
2135 bPgDscWrite = rRTFWrt.OutBreaks( ((SwTableNode&)rNd).GetTable().
2136 GetFrmFmt()->GetAttrSet() );
2137 rRTFWrt.bIgnoreNextPgBreak = TRUE;
2142 // if( CONTENT_SECTION == rSect.GetType() )
2144 // als fortlaufenden Abschnittwechsel heraus schreiben
2145 if( !bPgDscWrite )
2146 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_SECT << OOO_STRING_SVTOOLS_RTF_SBKNONE;
2147 //JP 19.03.99 - es muss fuer den Import auf jedenfall das Cols
2148 // Token geschrieben werden. Sonst kann nicht erkannt
2149 // werden, wann ein PageDesc & eine Section gueltig ist
2150 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_COLS << '1';
2151 rRTFWrt.bOutFmtAttr = TRUE;
2152 const SfxPoolItem* pItem;
2153 const SwFrmFmt *pFmt = rSect.GetFmt();
2154 ASSERT(pFmt, "Impossible");
2155 const SfxItemSet& rSet = pFmt->GetAttrSet();
2156 if( SFX_ITEM_SET == rSet.GetItemState( RES_COL, false, &pItem ))
2157 OutRTF_SwFmtCol( rWrt, *pItem );
2158 else
2160 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_COLS << '1' << OOO_STRING_SVTOOLS_RTF_COLSX;
2161 rWrt.OutULong(709);
2164 if( SFX_ITEM_SET == rSet.GetItemState( RES_COLUMNBALANCE,
2165 false, &pItem ) && ((SwFmtNoBalancedColumns*)pItem)->GetValue() )
2166 OutComment( rWrt, OOO_STRING_SVTOOLS_RTF_BALANCEDCOLUMN ) << '}';
2168 if (FRMDIR_HORI_RIGHT_TOP == rRTFWrt.TrueFrameDirection(*pFmt))
2169 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_RTLSECT;
2170 else
2171 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_LTRSECT;
2173 rWrt.Strm() << SwRTFWriter::sNewLine;
2176 return rWrt;
2180 /* File CHRATR.HXX: */
2182 static Writer& OutRTF_SwFont( Writer& rWrt, const SfxPoolItem& rHt )
2184 /* trage den Font in die Font-Liste vom Writer ein und gebe hier nur
2185 * die entsprechende Nummer aus. Der Font wird spaeter ueber diese
2186 * Tabelle im RTF-Dokument referenziert.
2188 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2190 if( !rRTFWrt.bTxtAttr ||
2191 ( rRTFWrt.GetEndPosLst() &&
2192 rRTFWrt.GetEndPosLst()->MatchScriptToId( rHt.Which() ) ))
2194 rRTFWrt.bOutFmtAttr = true;
2195 const SvxFontItem&rFont = (const SvxFontItem&)rHt;
2196 bool bAssoc = rRTFWrt.IsAssociatedFlag();
2198 #109522#
2199 Word is a bit of a silly bugger of a program when its comes to symbol
2200 font useage. If a symbol font is actually being used, i.e. exported
2201 here with bTxtAttr true then both AF and F must be set to the same
2202 value
2204 if (rRTFWrt.bTxtAttr && (rFont.GetCharSet() == RTL_TEXTENCODING_SYMBOL))
2206 const sal_Char* pCmd = !bAssoc ? OOO_STRING_SVTOOLS_RTF_AF : OOO_STRING_SVTOOLS_RTF_F;
2207 rWrt.Strm() << pCmd;
2209 const sal_Char* pCmd = bAssoc ? OOO_STRING_SVTOOLS_RTF_AF : OOO_STRING_SVTOOLS_RTF_F;
2210 rWrt.Strm() << pCmd;
2211 rWrt.OutULong(rRTFWrt.GetId(rFont));
2212 rRTFWrt.eCurrentEncoding = rtl_getTextEncodingFromWindowsCharset(sw::ms::rtl_TextEncodingToWinCharset(rFont.GetCharSet()));
2214 return rWrt;
2217 static Writer& OutRTF_SwPosture( Writer& rWrt, const SfxPoolItem& rHt )
2219 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2221 if( !rRTFWrt.bTxtAttr ||
2222 ( rRTFWrt.GetEndPosLst() &&
2223 rRTFWrt.GetEndPosLst()->MatchScriptToId( rHt.Which() ) ))
2225 if (rRTFWrt.IsAssociatedFlag() && rHt.Which() == RES_CHRATR_CJK_POSTURE)
2228 #i21422#
2229 Sadly in word rtf we can't retain CJK italic when we are not
2230 exporting asian text as it doesn't have a seperate italic for
2231 western and asian.
2233 return rWrt;
2236 const FontItalic nPosture = ((const SvxPostureItem&)rHt).GetPosture();
2237 int bTxtOut = rRTFWrt.bTxtAttr && ITALIC_NONE == nPosture;
2238 if( ITALIC_NORMAL == nPosture || bTxtOut )
2240 rRTFWrt.bOutFmtAttr = TRUE;
2241 const sal_Char* pCmd = rRTFWrt.IsAssociatedFlag() ? OOO_STRING_SVTOOLS_RTF_AI : OOO_STRING_SVTOOLS_RTF_I;
2242 rWrt.Strm() << pCmd;
2244 if( bTxtOut )
2245 rWrt.Strm() << '0'; // wieder abschalten
2247 return rWrt;
2251 static Writer& OutRTF_SwWeight( Writer& rWrt, const SfxPoolItem& rHt )
2253 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2254 if( !rRTFWrt.bTxtAttr ||
2255 ( rRTFWrt.GetEndPosLst() &&
2256 rRTFWrt.GetEndPosLst()->MatchScriptToId( rHt.Which() ) ))
2258 if (rRTFWrt.IsAssociatedFlag() && rHt.Which() == RES_CHRATR_CJK_WEIGHT)
2261 #i21422#
2262 Sadly in word rtf we can't retain CJK bold when we are not
2263 exporting asian text as it doesn't have a seperate bold for western
2264 and asian.
2266 return rWrt;
2269 const FontWeight nBold = ((const SvxWeightItem&)rHt).GetWeight();
2270 int bTxtOut = rRTFWrt.bTxtAttr && WEIGHT_NORMAL == nBold;
2271 if( WEIGHT_BOLD == nBold || bTxtOut )
2273 rRTFWrt.bOutFmtAttr = TRUE;
2274 const sal_Char* pCmd = rRTFWrt.IsAssociatedFlag() ? OOO_STRING_SVTOOLS_RTF_AB : OOO_STRING_SVTOOLS_RTF_B;
2275 rWrt.Strm() << pCmd;
2277 if( bTxtOut )
2278 rWrt.Strm() << '0';
2280 return rWrt;
2283 static Writer& OutRTF_SwEmphasisMark( Writer& rWrt, const SfxPoolItem& rHt )
2285 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2286 const sal_Char* pStr;
2287 switch( ((const SvxEmphasisMarkItem&)rHt).GetEmphasisMark())
2289 case EMPHASISMARK_NONE: pStr = OOO_STRING_SVTOOLS_RTF_ACCNONE; break;
2290 case EMPHASISMARK_SIDE_DOTS: pStr = OOO_STRING_SVTOOLS_RTF_ACCCOMMA; break;
2291 default: pStr = OOO_STRING_SVTOOLS_RTF_ACCDOT; break;
2294 rRTFWrt.bOutFmtAttr = TRUE;
2295 rWrt.Strm() << pStr;
2296 return rWrt;
2299 static Writer& OutRTF_SwTwoInOne( Writer& rWrt, const SfxPoolItem& rHt )
2301 if( ((SvxTwoLinesItem&)rHt).GetValue() )
2303 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2305 sal_Unicode cStart = ((SvxTwoLinesItem&)rHt).GetStartBracket();
2306 sal_Unicode cEnd = ((SvxTwoLinesItem&)rHt).GetStartBracket();
2308 USHORT nType;
2309 if( !cStart && !cEnd )
2310 nType = 0;
2311 else if( '{' == cStart || '}' == cEnd )
2312 nType = 4;
2313 else if( '<' == cStart || '>' == cEnd )
2314 nType = 3;
2315 else if( '[' == cStart || ']' == cEnd )
2316 nType = 2;
2317 else // all other kind of brackets
2318 nType = 1;
2320 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_TWOINONE;
2321 rWrt.OutULong( nType );
2322 rRTFWrt.bOutFmtAttr = TRUE;
2324 return rWrt;
2327 static Writer& OutRTF_SwCharRotate( Writer& rWrt, const SfxPoolItem& rHt )
2329 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2330 rRTFWrt.bOutFmtAttr = TRUE;
2331 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_HORZVERT;
2332 rWrt.OutLong( ((SvxCharRotateItem&)rHt).IsFitToLine() ? 1 : 0 );
2333 return rWrt;
2335 static Writer& OutRTF_SwCharScaleW( Writer& rWrt, const SfxPoolItem& rHt )
2337 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2338 rRTFWrt.bOutFmtAttr = TRUE;
2339 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_CHARSCALEX;
2340 rWrt.OutLong( ((SvxCharScaleWidthItem&)rHt).GetValue() );
2341 return rWrt;
2344 static Writer& OutRTF_SwCharRelief(Writer& rWrt, const SfxPoolItem& rHt)
2346 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2347 const SvxCharReliefItem& rAttr = (const SvxCharReliefItem&)rHt;
2348 const sal_Char* pStr;
2349 switch (rAttr.GetValue())
2351 case RELIEF_EMBOSSED:
2352 pStr = OOO_STRING_SVTOOLS_RTF_EMBO;
2353 break;
2354 case RELIEF_ENGRAVED:
2355 pStr = OOO_STRING_SVTOOLS_RTF_IMPR;
2356 break;
2357 default:
2358 pStr = 0;
2359 break;
2362 if (pStr)
2364 rRTFWrt.bOutFmtAttr = TRUE;
2365 rWrt.Strm() << pStr;
2367 return rWrt;
2371 static Writer& OutRTF_SwChrBckgrnd( Writer& rWrt, const SfxPoolItem& rHt )
2373 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2374 const SvxBrushItem& rBack = (const SvxBrushItem&)rHt;
2375 if( !rBack.GetColor().GetTransparency() )
2377 ByteString sOut( OOO_STRING_SVTOOLS_RTF_CHCBPAT );
2378 sOut += ByteString::CreateFromInt32(
2379 rRTFWrt.GetId( rBack.GetColor() ));
2381 rRTFWrt.bOutFmtAttr = TRUE;
2382 rWrt.Strm() << sOut.GetBuffer();
2384 return rWrt;
2387 static Writer& OutRTF_SwShadowed( Writer& rWrt, const SfxPoolItem& rHt )
2389 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2390 const BOOL bShadow = ((const SvxShadowedItem&)rHt).GetValue();
2391 int bTxtOut = rRTFWrt.bTxtAttr && !bShadow;
2392 if( bShadow || bTxtOut )
2394 rRTFWrt.bOutFmtAttr = TRUE;
2395 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_SHAD;
2397 if( bTxtOut )
2398 rWrt.Strm() << '0';
2399 return rWrt;
2404 static Writer& OutRTF_SwContour( Writer& rWrt, const SfxPoolItem& rHt )
2406 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2407 const BOOL bContour = ((const SvxContourItem&)rHt).GetValue();
2408 int bTxtOut = rRTFWrt.bTxtAttr && !bContour;
2409 if( bContour || bTxtOut )
2411 rRTFWrt.bOutFmtAttr = TRUE;
2412 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_OUTL;
2414 if( bTxtOut )
2415 rWrt.Strm() << '0';
2416 return rWrt;
2419 static Writer& OutRTF_SwCrossedOut( Writer& rWrt, const SfxPoolItem& rHt )
2421 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2422 const FontStrikeout nStrike = ((const SvxCrossedOutItem&)rHt).GetStrikeout();
2423 int bTxtOut = rRTFWrt.bTxtAttr && STRIKEOUT_NONE == nStrike;
2425 if( (STRIKEOUT_NONE != nStrike && STRIKEOUT_DONTKNOW != nStrike) || bTxtOut )
2427 rRTFWrt.bOutFmtAttr = TRUE;
2428 if( STRIKEOUT_DOUBLE == nStrike )
2430 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_STRIKED;
2431 if( !bTxtOut )
2432 rWrt.Strm() << '1';
2434 else
2435 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_STRIKE;
2437 if( bTxtOut )
2438 rWrt.Strm() << '0';
2439 return rWrt;
2444 static Writer& OutRTF_SwCaseMap( Writer& rWrt, const SfxPoolItem& rHt )
2446 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2447 switch( ((const SvxCaseMapItem&)rHt).GetValue() )
2449 case SVX_CASEMAP_KAPITAELCHEN:
2450 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_SCAPS;
2451 break;
2453 case SVX_CASEMAP_VERSALIEN:
2454 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_CAPS;
2455 break;
2457 case SVX_CASEMAP_NOT_MAPPED:
2458 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_CAPS << '0' << OOO_STRING_SVTOOLS_RTF_SCAPS << '0'; // beide aus !!
2459 break;
2461 default:
2462 return rWrt;
2465 rRTFWrt.bOutFmtAttr = TRUE;
2466 return rWrt;
2470 static Writer& OutRTF_SwUnderline( Writer& rWrt, const SfxPoolItem& rHt )
2472 const char* pStr = 0;
2473 switch( ((const SvxUnderlineItem&)rHt).GetLineStyle() )
2475 case UNDERLINE_SINGLE:
2476 pStr = OOO_STRING_SVTOOLS_RTF_UL;
2477 break;
2478 case UNDERLINE_DOUBLE:
2479 pStr = OOO_STRING_SVTOOLS_RTF_ULDB;
2480 break;
2481 case UNDERLINE_NONE:
2482 pStr = OOO_STRING_SVTOOLS_RTF_ULNONE;
2483 break;
2484 case UNDERLINE_DOTTED:
2485 pStr = OOO_STRING_SVTOOLS_RTF_ULD;
2486 break;
2487 case UNDERLINE_DASH:
2488 pStr = OOO_STRING_SVTOOLS_RTF_ULDASH;
2489 break;
2490 case UNDERLINE_DASHDOT:
2491 pStr = OOO_STRING_SVTOOLS_RTF_ULDASHD;
2492 break;
2493 case UNDERLINE_DASHDOTDOT:
2494 pStr = OOO_STRING_SVTOOLS_RTF_ULDASHDD;
2495 break;
2496 case UNDERLINE_BOLD:
2497 pStr = OOO_STRING_SVTOOLS_RTF_ULTH;
2498 break;
2499 case UNDERLINE_WAVE:
2500 pStr = OOO_STRING_SVTOOLS_RTF_ULWAVE;
2501 break;
2502 case UNDERLINE_BOLDDOTTED:
2503 pStr = OOO_STRING_SVTOOLS_RTF_ULTHD;
2504 break;
2505 case UNDERLINE_BOLDDASH:
2506 pStr = OOO_STRING_SVTOOLS_RTF_ULTHDASH;
2507 break;
2508 case UNDERLINE_LONGDASH:
2509 pStr = OOO_STRING_SVTOOLS_RTF_ULLDASH;
2510 break;
2511 case UNDERLINE_BOLDLONGDASH:
2512 pStr = OOO_STRING_SVTOOLS_RTF_ULTHLDASH;
2513 break;
2514 case UNDERLINE_BOLDDASHDOT:
2515 pStr = OOO_STRING_SVTOOLS_RTF_ULTHDASHD;
2516 break;
2517 case UNDERLINE_BOLDDASHDOTDOT:
2518 pStr = OOO_STRING_SVTOOLS_RTF_ULTHDASHDD;
2519 break;
2520 case UNDERLINE_BOLDWAVE:
2521 pStr = OOO_STRING_SVTOOLS_RTF_ULHWAVE;
2522 break;
2523 case UNDERLINE_DOUBLEWAVE:
2524 pStr = OOO_STRING_SVTOOLS_RTF_ULULDBWAVE;
2525 break;
2526 default:
2527 break;
2530 if( pStr )
2532 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2534 if( UNDERLINE_SINGLE == ((const SvxUnderlineItem&)rHt).GetLineStyle()
2535 && ((SvxWordLineModeItem&)rRTFWrt.GetItem(
2536 RES_CHRATR_WORDLINEMODE )).GetValue() )
2537 pStr = OOO_STRING_SVTOOLS_RTF_ULW;
2539 rRTFWrt.Strm() << pStr;
2540 rRTFWrt.bOutFmtAttr = TRUE;
2542 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_ULC;
2543 rWrt.OutULong( rRTFWrt.GetId(((const SvxUnderlineItem&)rHt).GetColor()) );
2547 return rWrt;
2552 static Writer& OutRTF_SwOverline( Writer& rWrt, const SfxPoolItem& rHt )
2554 const char* pStr = 0;
2555 switch( ((const SvxOverlineItem&)rHt).GetLineStyle() )
2557 case UNDERLINE_SINGLE:
2558 pStr = OOO_STRING_SVTOOLS_RTF_OL;
2559 break;
2560 case UNDERLINE_DOUBLE:
2561 pStr = OOO_STRING_SVTOOLS_RTF_OLDB;
2562 break;
2563 case UNDERLINE_NONE:
2564 pStr = OOO_STRING_SVTOOLS_RTF_OLNONE;
2565 break;
2566 case UNDERLINE_DOTTED:
2567 pStr = OOO_STRING_SVTOOLS_RTF_OLD;
2568 break;
2569 case UNDERLINE_DASH:
2570 pStr = OOO_STRING_SVTOOLS_RTF_OLDASH;
2571 break;
2572 case UNDERLINE_DASHDOT:
2573 pStr = OOO_STRING_SVTOOLS_RTF_OLDASHD;
2574 break;
2575 case UNDERLINE_DASHDOTDOT:
2576 pStr = OOO_STRING_SVTOOLS_RTF_OLDASHDD;
2577 break;
2578 case UNDERLINE_BOLD:
2579 pStr = OOO_STRING_SVTOOLS_RTF_OLTH;
2580 break;
2581 case UNDERLINE_WAVE:
2582 pStr = OOO_STRING_SVTOOLS_RTF_OLWAVE;
2583 break;
2584 case UNDERLINE_BOLDDOTTED:
2585 pStr = OOO_STRING_SVTOOLS_RTF_OLTHD;
2586 break;
2587 case UNDERLINE_BOLDDASH:
2588 pStr = OOO_STRING_SVTOOLS_RTF_OLTHDASH;
2589 break;
2590 case UNDERLINE_LONGDASH:
2591 pStr = OOO_STRING_SVTOOLS_RTF_OLLDASH;
2592 break;
2593 case UNDERLINE_BOLDLONGDASH:
2594 pStr = OOO_STRING_SVTOOLS_RTF_OLTHLDASH;
2595 break;
2596 case UNDERLINE_BOLDDASHDOT:
2597 pStr = OOO_STRING_SVTOOLS_RTF_OLTHDASHD;
2598 break;
2599 case UNDERLINE_BOLDDASHDOTDOT:
2600 pStr = OOO_STRING_SVTOOLS_RTF_OLTHDASHDD;
2601 break;
2602 case UNDERLINE_BOLDWAVE:
2603 pStr = OOO_STRING_SVTOOLS_RTF_OLHWAVE;
2604 break;
2605 case UNDERLINE_DOUBLEWAVE:
2606 pStr = OOO_STRING_SVTOOLS_RTF_OLOLDBWAVE;
2607 break;
2608 default:
2609 break;
2612 if( pStr )
2614 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2615 if ( rRTFWrt.bNonStandard )
2617 if( UNDERLINE_SINGLE == ((const SvxOverlineItem&)rHt).GetLineStyle()
2618 && ((SvxWordLineModeItem&)rRTFWrt.GetItem(
2619 RES_CHRATR_WORDLINEMODE )).GetValue() )
2620 pStr = OOO_STRING_SVTOOLS_RTF_OLW;
2622 rRTFWrt.Strm() << pStr;
2623 rRTFWrt.bOutFmtAttr = TRUE;
2625 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_OLC;
2626 rWrt.OutULong( rRTFWrt.GetId(((const SvxOverlineItem&)rHt).GetColor()) );
2631 return rWrt;
2636 static Writer& OutRTF_SwLanguage( Writer& rWrt, const SfxPoolItem& rHt )
2638 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2639 if( !rRTFWrt.bTxtAttr ||
2640 ( rRTFWrt.GetEndPosLst() &&
2641 rRTFWrt.GetEndPosLst()->MatchScriptToId( rHt.Which() ) ))
2644 rRTFWrt.bOutFmtAttr = TRUE;
2645 const sal_Char* p = RES_CHRATR_CJK_LANGUAGE == rHt.Which()
2646 ? OOO_STRING_SVTOOLS_RTF_LANGFE : OOO_STRING_SVTOOLS_RTF_LANG;
2647 rWrt.Strm() << p;
2648 rWrt.OutULong( ((const SvxLanguageItem&)rHt).GetLanguage() );
2650 return rWrt;
2655 static Writer& OutRTF_SwEscapement( Writer& rWrt, const SfxPoolItem& rHt )
2657 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2658 const SvxEscapementItem& rEsc = (const SvxEscapementItem&)rHt;
2659 const char * pUpDn;
2661 SwTwips nH = ((SvxFontHeightItem&)rRTFWrt.GetItem(
2662 RES_CHRATR_FONTSIZE )).GetHeight();
2664 if( 0 < rEsc.GetEsc() )
2665 pUpDn = OOO_STRING_SVTOOLS_RTF_UP;
2666 else if( 0 > rEsc.GetEsc() )
2668 pUpDn = OOO_STRING_SVTOOLS_RTF_DN;
2669 nH = -nH; // den negativen Wert herrausrechnen
2671 else
2672 return rWrt;
2674 // prozentuale Veraenderung speichern !
2675 short nEsc = rEsc.GetEsc();
2676 short nProp = rEsc.GetProp() * 100;
2677 if( DFLT_ESC_AUTO_SUPER == nEsc )
2679 nEsc = 100 - rEsc.GetProp();
2680 ++nProp;
2682 else if( DFLT_ESC_AUTO_SUB == nEsc )
2684 nEsc = - 100 + rEsc.GetProp();
2685 ++nProp;
2688 OutComment( rWrt, OOO_STRING_SVTOOLS_RTF_UPDNPROP, TRUE );
2689 rWrt.OutULong( nProp ) << '}' << pUpDn;
2692 * berechne aus der akt. FontSize und dem ProzentWert die Verschiebung,
2693 * wobei im RTF File 1/2 Points stehen muessen, waehrend intern
2694 * mit Twips gerechnet wird.
2695 * Formel : (FontSize * 1/20 ) pts x * 2
2696 * ----------------------- = ------------
2697 * 100% Escapement
2700 rWrt.OutULong( ( (long( nEsc ) * nH) + 500L ) / 1000L );
2701 // 500L zum Aufrunden !!
2702 return rWrt;
2707 static Writer& OutRTF_SwSize( Writer& rWrt, const SfxPoolItem& rHt )
2709 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2710 if( !rRTFWrt.bTxtAttr ||
2711 ( rRTFWrt.GetEndPosLst() &&
2712 rRTFWrt.GetEndPosLst()->MatchScriptToId( rHt.Which() ) ))
2714 if (
2715 rRTFWrt.IsAssociatedFlag() &&
2716 rHt.Which() == RES_CHRATR_CJK_FONTSIZE
2720 #i21422#
2721 Sadly in word rtf we can't retain CJK fontsize when we are not
2722 exporting asian text as it doesn't have a seperate fontsize for
2723 western and asian.
2725 return rWrt;
2728 rRTFWrt.bOutFmtAttr = TRUE;
2730 const sal_Char* pCmd = rRTFWrt.IsAssociatedFlag() ? OOO_STRING_SVTOOLS_RTF_AFS : OOO_STRING_SVTOOLS_RTF_FS;
2731 rWrt.Strm() << pCmd;
2732 rWrt.OutULong( ((const SvxFontHeightItem&)rHt).GetHeight() / 10 );
2734 return rWrt;
2739 static Writer& OutRTF_SwColor( Writer& rWrt, const SfxPoolItem& rHt )
2741 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2742 /* trage die Color in die Color-Liste vom Writer ein und gebe hier nur
2743 * die entsprechende Nummer aus. Die Color wird spaeter ueber diese
2744 * Tabelle im RTF-Dokument referenziert.
2746 rRTFWrt.bOutFmtAttr = TRUE;
2747 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_CF;
2748 rWrt.OutULong( rRTFWrt.GetId( ((const SvxColorItem&)rHt).GetValue() ));
2749 return rWrt;
2752 static Writer& OutRTF_SvxCharHiddenItem(Writer& rWrt, const SfxPoolItem& rHt)
2754 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2755 rRTFWrt.bOutFmtAttr = true;
2756 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_V;
2757 if (!((const SvxCharHiddenItem&)rHt).GetValue())
2758 rWrt.OutULong(0);
2759 return rWrt;
2762 extern void sw3io_ConvertToOldField( const SwField* pFld, USHORT& rWhich,
2763 ULONG& rFmt, ULONG nFFVersion );
2765 static Writer& OutRTF_SwField( Writer& rWrt, const SfxPoolItem& rHt )
2767 SwFmtFld & rFld = (SwFmtFld&)rHt;
2768 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
2770 const SwField* pFld = rFld.GetFld();
2772 ByteString aFldStt( '{' );
2773 ((((aFldStt += OOO_STRING_SVTOOLS_RTF_FIELD) += '{' ) += OOO_STRING_SVTOOLS_RTF_IGNORE) += OOO_STRING_SVTOOLS_RTF_FLDINST) += ' ';
2774 switch( pFld->GetTyp()->Which() )
2776 case RES_COMBINED_CHARS:
2779 We need a font size to fill in the defaults, if these are overridden
2780 (as they generally are) by character properties then those properties
2781 win.
2783 The fontsize that is used in MS for determing the defaults is always
2784 the CJK fontsize even if the text is not in that language, in OOo the
2785 largest fontsize used in the field is the one we should take, but
2786 whatever we do, word will actually render using the fontsize set for
2787 CJK text. Nevertheless we attempt to guess whether the script is in
2788 asian or western text based up on the first character and use the
2789 font size of that script as our default.
2791 const String& rFldPar1 = pFld->GetPar1();
2792 USHORT nScript;
2793 if( pBreakIt->GetBreakIter().is() )
2794 nScript = pBreakIt->GetBreakIter()->getScriptType( rFldPar1, 0);
2795 else
2796 nScript = i18n::ScriptType::ASIAN;
2798 long nHeight = ((SvxFontHeightItem&)rRTFWrt.GetItem(
2799 GetWhichOfScript(RES_CHRATR_FONTSIZE, nScript ))).GetHeight();
2800 nHeight = (nHeight + 10) / 20; //Font Size in points;
2803 Divide the combined char string into its up and down part. Get the
2804 font size and fill in the defaults as up == half the font size and
2805 down == a fifth the font size
2807 xub_StrLen nAbove = (rFldPar1.Len()+1)/2;
2808 rWrt.Strm() << aFldStt.GetBuffer() << "EQ \\\\o (\\\\s\\\\up ";
2809 rWrt.OutLong( nHeight/2 ) << '(';
2810 RTFOutFuncs::Out_String( rWrt.Strm(), rFldPar1.Copy(0,nAbove),
2811 rRTFWrt.eDefaultEncoding, rRTFWrt.bWriteHelpFmt );
2812 rWrt.Strm() << "), \\\\s\\\\do ";
2813 rWrt.OutLong( nHeight/5 ) << '(';
2814 RTFOutFuncs::Out_String( rWrt.Strm(), rFldPar1.Copy( nAbove ),
2815 rRTFWrt.eDefaultEncoding, rRTFWrt.bWriteHelpFmt )
2816 << "))";
2818 break;
2820 case RES_DBFLD:
2821 aFldStt += "MERGEFIELD ";
2822 // kein break !!
2823 case RES_USERFLD:
2824 rWrt.Strm() << aFldStt.GetBuffer();
2825 RTFOutFuncs::Out_String( rWrt.Strm(), pFld->GetTyp()->GetName(),
2826 rRTFWrt.eDefaultEncoding, rRTFWrt.bWriteHelpFmt );
2827 break;
2828 case RES_GETREFFLD:
2830 BYTE nFldTyp = 0;
2831 rWrt.Strm() << aFldStt.GetBuffer() << " REF ";
2832 const SwGetRefField& rRFld = *(SwGetRefField*)pFld;
2833 switch( pFld->GetSubType() )
2835 case REF_SETREFATTR:
2836 case REF_BOOKMARK:
2837 RTFOutFuncs::Out_String( rWrt.Strm(), rRFld.GetSetRefName(),
2838 rRTFWrt.eDefaultEncoding, rRTFWrt.bWriteHelpFmt );
2839 nFldTyp = 3;
2840 break;
2843 if( nFldTyp )
2845 switch( pFld->GetFormat() )
2847 case REF_PAGE_PGDESC:
2848 case REF_PAGE:
2849 rWrt.Strm() << "SEITEN";
2850 nFldTyp = 37;
2851 break;
2852 case REF_UPDOWN:
2853 rWrt.Strm() << " \\p";
2854 nFldTyp = 3;
2855 break;
2856 case REF_CHAPTER:
2857 rWrt.Strm() << " \\n";
2858 break;
2859 case REF_ONLYNUMBER:
2860 case REF_ONLYCAPTION:
2861 case REF_ONLYSEQNO:
2862 break;
2863 // default:
2864 // case REF_CONTENT:
2866 rWrt.Strm() << " \\\\h "; // insert hyperlink
2869 break;
2870 // case RES_CHAPTERFLD:
2871 // rWrt.Strm() << ' ';
2872 // break;
2873 case RES_PAGENUMBERFLD:
2874 rWrt.Strm() << aFldStt.GetBuffer() << "\\\\page";
2876 char __READONLY_DATA
2877 sNType0[] = "ALPHABETIC", /* CHARS_UPPER_LETTER*/
2878 sNType1[] = "alphabetic", /* CHARS_LOWER_LETTER*/
2879 sNType2[] = "ROMAN", /* ROMAN_UPPER */
2880 sNType3[] = "roman", /* ROMAN_LOWER */
2881 sNType4[] = "ARABIC"; /* ARABIC */
2883 const char* pFmtStr = 0;
2884 switch( pFld->GetFormat() )
2886 case SVX_NUM_CHARS_UPPER_LETTER:
2887 case SVX_NUM_CHARS_UPPER_LETTER_N: pFmtStr = sNType0; break;
2888 case SVX_NUM_CHARS_LOWER_LETTER:
2889 case SVX_NUM_CHARS_LOWER_LETTER_N: pFmtStr = sNType1; break;
2890 case SVX_NUM_ROMAN_UPPER: pFmtStr = sNType2; break;
2891 case SVX_NUM_ROMAN_LOWER: pFmtStr = sNType3; break;
2892 case SVX_NUM_ARABIC: pFmtStr = sNType4; break;
2895 if( pFmtStr )
2896 rWrt.Strm() << "\\\\* " << pFmtStr;
2898 break;
2899 case RES_FILENAMEFLD:
2900 rWrt.Strm() << aFldStt.GetBuffer() << "\\\\filename ";
2901 break;
2902 case RES_DBNAMEFLD:
2904 rWrt.Strm() << aFldStt.GetBuffer() << "\\\\data ";
2905 SwDBData aData = rWrt.pDoc->GetDBData();
2906 String sOut(aData.sDataSource);
2907 sOut += DB_DELIM;
2908 sOut += (String)aData.sCommand;
2909 RTFOutFuncs::Out_String( rWrt.Strm(), sOut,
2910 rRTFWrt.eDefaultEncoding, rRTFWrt.bWriteHelpFmt );
2912 break;
2913 case RES_AUTHORFLD:
2914 rWrt.Strm() << aFldStt.GetBuffer() << "\\\\author ";
2915 break;
2917 case RES_HIDDENTXTFLD:
2918 if( TYP_CONDTXTFLD == ((SwHiddenTxtField*)pFld)->GetSubType() )
2919 RTFOutFuncs::Out_String( rWrt.Strm(), pFld->Expand(),
2920 rRTFWrt.eDefaultEncoding, rRTFWrt.bWriteHelpFmt );
2921 else
2923 rWrt.Strm() << '{' << OOO_STRING_SVTOOLS_RTF_V << ' ';
2924 OutRTF_AsByteString( rWrt, pFld->GetPar2(), rRTFWrt.eDefaultEncoding ).Strm()
2925 << '}' << SwRTFWriter::sNewLine;
2927 return rWrt; // nicht bis zum Ende, kein RTF-Feld !!
2929 case RES_DATETIMEFLD:
2930 if (!(pFld->GetSubType() & FIXEDFLD))
2932 USHORT nWhich = RES_DATETIMEFLD;
2933 ULONG nFmt = pFld->GetFormat();
2934 sw3io_ConvertToOldField(pFld, nWhich, nFmt, SOFFICE_FILEFORMAT_40 );
2935 if (pFld->GetSubType() & DATEFLD)
2937 rWrt.Strm() << aFldStt.GetBuffer() << "\\\\date \\\\@\"";
2938 switch( nFmt )
2940 case DF_SSYS: rWrt.Strm() << "tt.MM.yy"; break;
2941 case DF_LSYS: rWrt.Strm() << "tttt, t. MMMM yyyy"; break;
2942 case DF_SHORT: rWrt.Strm() << "tt.MM.yy"; break;
2943 case DF_SCENT: rWrt.Strm() << "tt.MM.yyyy"; break;
2944 case DF_LMON: rWrt.Strm() << "t. MMM yyyy"; break;
2945 case DF_LMONTH: rWrt.Strm() << "t. MMMM yyyy"; break;
2946 case DF_LDAYMON: rWrt.Strm() << "ttt, t. MMMM yyyy"; break;
2947 case DF_LDAYMONTH: rWrt.Strm() << "tttt, t. MMMM yyyy"; break;
2950 else
2952 rWrt.Strm() << aFldStt.GetBuffer() << "\\\\date \\\\@\"";
2953 switch( nFmt )
2955 case TF_SSMM_24: rWrt.Strm() << "HH:mm"; break;
2956 case TF_SSMM_12: rWrt.Strm() << "hh:mm"; break; // ???
2957 case TF_SYSTEM: rWrt.Strm() << "HH:mm"; break;
2960 rWrt.Strm() << '\"';
2961 break;
2963 // Kein break: in default-Zweig laufen!
2965 default:
2967 aFldStt.Erase();
2969 // JP 20.07.95: warum nicht das Expandierte rausschreiben ?
2970 sal_Char cCh;
2971 rWrt.Strm().SeekRel(-1);
2972 rWrt.Strm() >> cCh;
2973 if( ' ' != cCh ) // vorweg immer einen Trenner
2974 rWrt.Strm() << ' ';
2975 RTFOutFuncs::Out_String( rWrt.Strm(), pFld->Expand(),
2976 rRTFWrt.eDefaultEncoding, rRTFWrt.bWriteHelpFmt );
2978 break;
2981 if( aFldStt.Len() )
2983 rWrt.Strm() << "}{" << OOO_STRING_SVTOOLS_RTF_FLDRSLT << ' ';
2984 RTFOutFuncs::Out_String( rWrt.Strm(), pFld->Expand(),
2985 rRTFWrt.eDefaultEncoding, rRTFWrt.bWriteHelpFmt );
2986 rWrt.Strm() << "}}";
2987 rRTFWrt.bOutFmtAttr = FALSE;
2990 return rWrt;
2993 static Writer& OutRTF_SwFlyCntnt( Writer& rWrt, const SfxPoolItem& rHt )
2995 SwFrmFmt* pFmt = ((SwFmtFlyCnt&)rHt).GetFrmFmt();
2996 if (RES_DRAWFRMFMT != pFmt->Which())
2998 ((SwRTFWriter&)rWrt).OutRTFFlyFrms( *((SwFlyFrmFmt*)pFmt) );
2999 ((SwRTFWriter&)rWrt).bOutFmtAttr = false;
3001 return rWrt;
3004 static Writer& OutRTF_SwFtn( Writer& rWrt, const SfxPoolItem& rHt )
3006 const SwFmtFtn& rFtn = (const SwFmtFtn&)rHt;
3007 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
3009 do { // middle-check-loop
3010 if( !rFtn.GetTxtFtn() || !rFtn.GetTxtFtn()->GetStartNode() )
3011 break; // es gibt keine Kopf-/Fusszeile/Fussnote
3013 // Hole vom Node und vom letzten Node die Position in der Section
3014 ULONG nStart = rFtn.GetTxtFtn()->GetStartNode()->GetIndex()+1,
3015 nEnd = rWrt.pDoc->GetNodes()[ nStart-1 ]->EndOfSectionIndex();
3017 // kein Bereich also kein gueltiger Node
3018 if( nStart >= nEnd )
3019 break;
3021 rWrt.Strm() << '{' << OOO_STRING_SVTOOLS_RTF_SUPER << ' ';
3022 if( !rFtn.GetNumStr().Len() )
3024 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_CHFTN;
3025 OutComment( rWrt, OOO_STRING_SVTOOLS_RTF_FOOTNOTE );
3026 if( rFtn.IsEndNote() )
3027 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_FTNALT;
3028 rWrt.Strm() << ' ' << OOO_STRING_SVTOOLS_RTF_CHFTN;
3030 else
3032 OutRTF_AsByteString( rWrt, rFtn.GetNumStr(), rRTFWrt.eDefaultEncoding );
3033 OutComment( rWrt, OOO_STRING_SVTOOLS_RTF_FOOTNOTE );
3034 if( rFtn.IsEndNote() )
3035 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_FTNALT;
3036 rWrt.Strm() << ' ';
3037 OutRTF_AsByteString( rWrt, rFtn.GetNumStr(), rRTFWrt.eDefaultEncoding );
3039 RTFSaveData aSaveData( rRTFWrt, nStart, nEnd );
3040 // damit kein \par ausgegeben wird !!
3041 rRTFWrt.pCurPam->GetMark()->nContent++;
3042 rRTFWrt.Out_SwDoc( rRTFWrt.pCurPam );
3044 rWrt.Strm() << "}}" << SwRTFWriter::sNewLine;
3045 rRTFWrt.bOutFmtAttr = FALSE;
3047 } while( FALSE );
3048 return rWrt;
3051 static Writer& OutRTF_SwHardBlank( Writer& rWrt, const SfxPoolItem& rHt)
3053 RTFOutFuncs::Out_String(rWrt.Strm(),
3054 String(((SwFmtHardBlank&)rHt).GetChar()), ((SwRTFWriter&)rWrt).eDefaultEncoding,
3055 ((SwRTFWriter&)rWrt).bWriteHelpFmt);
3056 return rWrt;
3059 static Writer& OutRTF_SwTxtCharFmt( Writer& rWrt, const SfxPoolItem& rHt )
3061 const SwFmtCharFmt& rChrFmt = (const SwFmtCharFmt&)rHt;
3062 const SwCharFmt* pFmt = rChrFmt.GetCharFmt();
3064 if( pFmt )
3065 OutRTF_SwFmt( rWrt, *pFmt );
3066 return rWrt;
3069 static Writer& OutRTF_SwTxtAutoFmt( Writer& rWrt, const SfxPoolItem& rHt )
3071 const SwFmtAutoFmt& rAutoFmt = (const SwFmtAutoFmt&)rHt;
3072 const boost::shared_ptr<SfxItemSet> pSet = rAutoFmt.GetStyleHandle();
3074 if( pSet.get() )
3076 SwRTFWriter & rRTFWrt = (SwRTFWriter&)rWrt;
3077 OutRTF_SfxItemSet( rRTFWrt, *pSet.get(), FALSE );
3079 return rWrt;
3082 static Writer& OutRTF_SwTxtRuby( Writer& rWrt, const SfxPoolItem& rHt )
3084 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
3085 const SwFmtRuby& rRuby = (const SwFmtRuby&)rHt;
3086 const SwTxtRuby* pRubyTxt = rRuby.GetTxtRuby();
3087 const SwTxtNode* pNd;
3089 if( !pRubyTxt || 0 == (pNd = pRubyTxt->GetpTxtNode() ))
3090 return rWrt;
3092 sal_Char cDirective = 0, cJC = '0';
3093 switch( rRuby.GetAdjustment() )
3095 case 0: cJC = '3'; cDirective = 'l'; break;
3096 case 2: cJC = '4'; cDirective = 'r'; break;
3097 case 3: cJC = '1'; cDirective = 'd'; break;
3098 case 4: cJC = '2'; cDirective = 'd'; break;
3099 case 1: break; //defaults to 0
3100 default:
3101 ASSERT( FALSE, "Unhandled Ruby justication code" );
3102 break;
3106 MS needs to know the name and size of the font used in the ruby item,
3107 but we coud have written it in a mixture of asian and western
3108 scripts, and each of these can be a different font and size than the
3109 other, so we make a guess based upon the first character of the text,
3110 defaulting to asian.
3112 USHORT nScript;
3113 if( pBreakIt->GetBreakIter().is() )
3114 nScript = pBreakIt->GetBreakIter()->getScriptType( rRuby.GetText(), 0);
3115 else
3116 nScript = i18n::ScriptType::ASIAN;
3118 const SwCharFmt* pFmt = pRubyTxt->GetCharFmt();
3119 const SvxFontItem *pFont;
3120 long nHeight;
3122 if( pFmt )
3124 const SwAttrSet& rSet = pFmt->GetAttrSet();
3125 pFont = &(const SvxFontItem&)rSet.Get( GetWhichOfScript(
3126 RES_CHRATR_FONT, nScript ));
3128 nHeight = ((SvxFontHeightItem&)rSet.Get(
3129 GetWhichOfScript( RES_CHRATR_FONTSIZE, nScript ))).GetHeight();
3131 else
3133 /*Get document defaults if no formatting on ruby text*/
3134 const SfxItemPool *pPool = pNd->GetSwAttrSet().GetPool();
3135 pFont = &(const SvxFontItem&)pPool->GetDefaultItem(
3136 GetWhichOfScript( RES_CHRATR_FONT, nScript ));
3138 nHeight = ((SvxFontHeightItem&)pPool->GetDefaultItem(
3139 GetWhichOfScript( RES_CHRATR_FONTSIZE, nScript ))).GetHeight();
3141 ( nHeight += 5 ) /= 10;
3143 // don't change " EQ " to any other without changing the code in RTFFLD.CXX
3144 rWrt.Strm() << '{' << OOO_STRING_SVTOOLS_RTF_FIELD << '{' << OOO_STRING_SVTOOLS_RTF_IGNORE << OOO_STRING_SVTOOLS_RTF_FLDINST
3145 << " EQ \\\\* jc" << cJC
3146 << " \\\\* \"Font:";
3147 RTFOutFuncs::Out_String( rWrt.Strm(), pFont->GetFamilyName(),
3148 rRTFWrt.eDefaultEncoding, rRTFWrt.bWriteHelpFmt );
3149 rWrt.Strm() << "\" \\\\* hps";
3150 rWrt.OutLong( nHeight );
3151 rWrt.Strm() << " \\\\o";
3152 if( cDirective )
3153 rWrt.Strm() << "\\\\a" << cDirective;
3154 rWrt.Strm() << "(\\\\s\\\\up ";
3156 if( pBreakIt->GetBreakIter().is() )
3157 nScript = pBreakIt->GetBreakIter()->getScriptType( pNd->GetTxt(),
3158 *pRubyTxt->GetStart() );
3159 else
3160 nScript = i18n::ScriptType::ASIAN;
3162 const SwAttrSet& rSet = pNd->GetSwAttrSet();
3163 nHeight = ((SvxFontHeightItem&)rSet.Get(
3164 GetWhichOfScript( RES_CHRATR_FONTSIZE, nScript ))).GetHeight();
3165 (nHeight += 10) /= 20-1;
3166 rWrt.OutLong( nHeight ) << '(';
3168 if( pFmt )
3170 rWrt.Strm() << '{';
3171 OutRTF_SwFmt( rWrt, *pFmt );
3172 if( rRTFWrt.bOutFmtAttr )
3173 rWrt.Strm() << ' ';
3175 RTFOutFuncs::Out_String( rWrt.Strm(), rRuby.GetText(),
3176 rRTFWrt.eDefaultEncoding, rRTFWrt.bWriteHelpFmt );
3177 if( pFmt )
3178 rWrt.Strm() << '}';
3180 rWrt.Strm() << "),";
3181 rRTFWrt.bOutFmtAttr = FALSE;
3183 return rWrt;
3187 /* File FRMATR.HXX */
3189 static Writer& OutRTF_SwFrmSize( Writer& rWrt, const SfxPoolItem& rHt )
3191 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
3192 const SwFmtFrmSize& rSz = (const SwFmtFrmSize&)rHt;
3193 if( rRTFWrt.pFlyFmt ) // wird das FlyFrmFmt ausgegeben ?
3195 if( !rRTFWrt.bRTFFlySyntax )
3196 return rWrt;
3198 if( rSz.GetWidth() )
3200 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_ABSW;
3201 rWrt.OutLong( rSz.GetWidth() );
3202 rRTFWrt.bOutFmtAttr = TRUE;
3205 if( rSz.GetHeight() )
3207 long nH = rSz.GetHeight();
3208 if( ATT_FIX_SIZE == rSz.GetHeightSizeType() )
3209 nH = -nH;
3210 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_ABSH;
3211 rWrt.OutLong( nH );
3212 rRTFWrt.bOutFmtAttr = TRUE;
3215 else if( rRTFWrt.bOutPageDesc )
3217 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_PGWSXN;
3218 rWrt.OutLong( rSz.GetWidth() );
3219 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_PGHSXN;
3220 rWrt.OutLong( rSz.GetHeight() );
3221 rRTFWrt.bOutFmtAttr = TRUE;
3223 return rWrt;
3226 static Writer& OutRTF_SwFmtLRSpace( Writer& rWrt, const SfxPoolItem& rHt )
3228 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
3229 const SvxLRSpaceItem & rLR = (const SvxLRSpaceItem&) rHt;
3230 if( !rRTFWrt.pFlyFmt )
3232 if( rRTFWrt.bOutPageDesc )
3234 if( rLR.GetLeft() )
3236 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_MARGLSXN;
3237 rWrt.OutLong( rLR.GetLeft() );
3238 rRTFWrt.bOutFmtAttr = TRUE;
3240 if( rLR.GetRight() )
3242 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_MARGRSXN;
3243 rWrt.OutLong( rLR.GetRight() );
3244 rRTFWrt.bOutFmtAttr = TRUE;
3247 else
3249 rRTFWrt.bOutFmtAttr = TRUE;
3250 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_LI;
3251 rWrt.OutLong( rLR.GetTxtLeft() ) << OOO_STRING_SVTOOLS_RTF_RI;
3252 rWrt.OutLong( rLR.GetRight() );
3253 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_LIN;
3254 rWrt.OutLong( rLR.GetTxtLeft() ) << OOO_STRING_SVTOOLS_RTF_RIN;
3255 rWrt.OutLong( rLR.GetRight() );
3256 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_FI;
3257 rWrt.OutLong( rLR.GetTxtFirstLineOfst() );
3260 else if( rLR.GetLeft() == rLR.GetRight() && rRTFWrt.bRTFFlySyntax )
3262 rRTFWrt.bOutFmtAttr = TRUE;
3263 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_DFRMTXTX;
3264 rWrt.OutLong( rLR.GetLeft() );
3266 return rWrt;
3269 static Writer& OutRTF_SwFmtULSpace( Writer& rWrt, const SfxPoolItem& rHt )
3271 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
3272 const SvxULSpaceItem & rUL = (const SvxULSpaceItem&) rHt;
3273 if( rRTFWrt.pFlyFmt )
3275 if( rUL.GetUpper() == rUL.GetLower() && rRTFWrt.bRTFFlySyntax )
3277 rRTFWrt.bOutFmtAttr = TRUE;
3278 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_DFRMTXTY;
3279 rWrt.OutLong( rUL.GetLower() );
3282 else
3284 const char* p;
3285 USHORT nValue = rUL.GetUpper();
3286 if( rRTFWrt.bOutPageDesc )
3288 p = OOO_STRING_SVTOOLS_RTF_MARGTSXN;
3289 if( !rRTFWrt.bOutPageDescTbl )
3291 SwRect aRect;
3292 const SwFmtHeader* pHdr;
3293 if( SFX_ITEM_SET == rRTFWrt.pAktPageDesc->GetMaster().
3294 GetItemState( RES_HEADER, FALSE,
3295 (const SfxPoolItem**)&pHdr ) && pHdr->IsActive() )
3297 aRect = pHdr->GetHeaderFmt()->FindLayoutRect( FALSE );
3298 if( aRect.Height() )
3299 nValue = nValue + static_cast< USHORT >(aRect.Height());
3300 else
3302 const SwFmtFrmSize& rSz = pHdr->GetHeaderFmt()->GetFrmSize();
3303 if( ATT_VAR_SIZE != rSz.GetHeightSizeType() )
3304 nValue = nValue + static_cast< USHORT >(rSz.GetHeight());
3305 else
3306 nValue = nValue + 274; // defaulten fuer 12pt Schrift
3307 nValue = nValue + pHdr->GetHeaderFmt()->GetULSpace().GetLower();
3312 else
3313 p = OOO_STRING_SVTOOLS_RTF_SB;
3315 if( rRTFWrt.bOutPageDesc || nValue )
3317 rRTFWrt.bOutFmtAttr = TRUE;
3318 rWrt.Strm() << p;
3319 rWrt.OutLong( nValue );
3323 nValue = rUL.GetLower();
3324 if( rRTFWrt.bOutPageDesc )
3326 p = OOO_STRING_SVTOOLS_RTF_MARGBSXN;
3327 if( !rRTFWrt.bOutPageDescTbl )
3329 SwRect aRect;
3330 const SwFmtFooter* pFtr;
3331 if( SFX_ITEM_SET == rRTFWrt.pAktPageDesc->GetMaster().
3332 GetItemState( RES_FOOTER, FALSE,
3333 (const SfxPoolItem**)&pFtr ) && pFtr->IsActive() )
3335 aRect = pFtr->GetFooterFmt()->FindLayoutRect( FALSE );
3336 if( aRect.Height() )
3337 nValue = nValue + static_cast< USHORT >(aRect.Height());
3338 else
3340 const SwFmtFrmSize& rSz = pFtr->GetFooterFmt()->GetFrmSize();
3341 if( ATT_VAR_SIZE != rSz.GetHeightSizeType() )
3342 nValue = nValue + static_cast< USHORT >(rSz.GetHeight());
3343 else
3344 nValue += 274; // defaulten fuer 12pt Schrift
3345 nValue = nValue + pFtr->GetFooterFmt()->GetULSpace().GetUpper();
3350 else
3351 p = OOO_STRING_SVTOOLS_RTF_SA;
3353 if( rRTFWrt.bOutPageDesc || nValue )
3355 rRTFWrt.bOutFmtAttr = TRUE;
3356 rWrt.Strm() << p;
3357 rWrt.OutLong( nValue );
3360 return rWrt;
3363 // Header-Footer werden auch vom RTF-Writer direkt gerufen, also kein static!
3366 Writer& OutRTF_SwFmtHeader( Writer& rWrt, const SfxPoolItem& rHt )
3368 const SwFmtHeader& rHd = (const SwFmtHeader&)rHt;
3369 if( !rHd.IsActive() ) // nicht aktiv, dann nichts weiter ausgeben
3370 return rWrt;
3372 // hole einen Node zu dem Request
3373 SwStartNode *pSttNode = 0;
3374 const SwFmtCntnt& rCntnt = rHd.GetHeaderFmt()->GetCntnt();
3375 if( rCntnt.GetCntntIdx() )
3376 pSttNode = rCntnt.GetCntntIdx()->GetNode().GetStartNode();
3378 do { // middle-check-loop
3379 if( !pSttNode )
3380 break; // es gibt keine Kopf-/Fusszeile/Fussnote
3382 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
3384 // Hole vom Node und vom letzten Node die Position in der Section
3385 ULONG nStart = pSttNode->GetIndex() + 1,
3386 nEnd = pSttNode->EndOfSectionIndex();
3388 // kein Bereich also kein gueltiger Node
3389 if( nStart >= nEnd )
3390 break;
3391 ASSERT( rRTFWrt.pAktPageDesc, "Header-Attribut ohne PageDesc" );
3393 const sal_Char * pHdNm = OOO_STRING_SVTOOLS_RTF_HEADER;
3394 rWrt.Strm() << pHdNm << 'y';
3395 if( rRTFWrt.bOutPageDescTbl )
3397 // hole die Ober-/Unterkanten vom Header
3398 const SvxULSpaceItem& rUL = rHd.GetHeaderFmt()->GetULSpace();
3399 const SvxLRSpaceItem& rLR = rHd.GetHeaderFmt()->GetLRSpace();
3400 const SwFmtFrmSize& rSz = rHd.GetHeaderFmt()->GetFrmSize();
3402 rWrt.OutLong( rUL.GetUpper() );
3403 OutComment( rWrt, pHdNm ) << "yb";
3404 rWrt.OutLong( rUL.GetLower() ) << pHdNm << "xl";
3405 rWrt.OutLong( rLR.GetLeft() ) << pHdNm << "xr";
3406 rWrt.OutLong( rLR.GetRight() ) << pHdNm << "yh";
3407 rWrt.OutLong( ATT_FIX_SIZE == rSz.GetHeightSizeType()
3408 ? -rSz.GetHeight()
3409 : rSz.GetHeight() ) << '}';
3411 else
3412 rWrt.OutLong( rRTFWrt.pAktPageDesc->GetMaster().
3413 GetULSpace().GetUpper() );
3415 // wird nicht die PageDesc-Tabelle ausgegeben und gibt es einen
3416 // Nachfolger, dann handelt es sich um die "1.Seite" nach RTF.
3417 sal_Char cTyp = 0;
3418 if( rRTFWrt.pAktPageDesc->GetFollow() &&
3419 rRTFWrt.pAktPageDesc->GetFollow() != rRTFWrt.pAktPageDesc )
3421 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_TITLEPG; //i13107
3422 cTyp = 'f'; // dann FirstPage-Header
3424 else if( !rRTFWrt.pAktPageDesc->IsHeaderShared() )
3426 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_FACINGP; //i13107
3427 cTyp = rRTFWrt.bOutLeftHeadFoot ? 'l' : 'r';
3430 rWrt.Strm() << '{'<< pHdNm;
3431 if( cTyp ) rWrt.Strm() << cTyp;
3432 rWrt.Strm() << ' ';
3435 RTFSaveData aSaveData( rRTFWrt, nStart, nEnd );
3436 rRTFWrt.Out_SwDoc( rRTFWrt.pCurPam );
3439 rWrt.Strm() << '}' << SwRTFWriter::sNewLine;
3441 } while( FALSE );
3442 return rWrt;
3444 // Header-Footer werden auch vom RTF-Writer direkt gerufen, also kein static!
3447 Writer& OutRTF_SwFmtFooter( Writer& rWrt, const SfxPoolItem& rHt )
3449 const SwFmtFooter& rFt = (const SwFmtFooter&)rHt;
3450 if( !rFt.IsActive() ) // nicht aktiv, dann nichts weiter ausgeben
3451 return rWrt;
3453 SwStartNode *pSttNode = 0;
3454 const SwFmtCntnt& rCntnt = rFt.GetFooterFmt()->GetCntnt();
3455 if( rCntnt.GetCntntIdx() )
3456 pSttNode = rCntnt.GetCntntIdx()->GetNode().GetStartNode();
3458 do { // middle-check-loop
3459 if( !pSttNode )
3460 break; // es gibt keine Kopf-/Fusszeile/Fussnote
3462 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
3464 // Hole vom Node und vom letzten Node die Position in der Section
3465 ULONG nStart = pSttNode->GetIndex()+1,
3466 nEnd = pSttNode->EndOfSectionIndex();
3468 // kein Bereich also kein gueltiger Node
3469 if( nStart >= nEnd )
3470 break;
3471 ASSERT( rRTFWrt.pAktPageDesc, "Footer-Attribut ohne PageDesc" );
3473 const sal_Char * pFtNm = OOO_STRING_SVTOOLS_RTF_FOOTER;
3474 rWrt.Strm() << pFtNm << 'y';
3475 if( rRTFWrt.bOutPageDescTbl )
3477 // hole die Ober-/Unterkanten vom Footer
3478 const SvxULSpaceItem& rUL = rFt.GetFooterFmt()->GetULSpace();
3479 const SvxLRSpaceItem& rLR = rFt.GetFooterFmt()->GetLRSpace();
3480 const SwFmtFrmSize& rSz = rFt.GetFooterFmt()->GetFrmSize();
3482 rWrt.OutLong( rUL.GetLower() );
3483 OutComment( rWrt, pFtNm ) << "yt";
3484 rWrt.OutLong( rUL.GetUpper() ) << pFtNm << "xl";
3485 rWrt.OutLong( rLR.GetLeft() ) << pFtNm << "xr";
3486 rWrt.OutLong( rLR.GetRight() ) << pFtNm << "yh";
3487 rWrt.OutLong( ATT_FIX_SIZE == rSz.GetHeightSizeType()
3488 ? -rSz.GetHeight()
3489 : rSz.GetHeight() ) << '}';
3491 else
3492 rWrt.OutLong( rRTFWrt.pAktPageDesc->GetMaster().
3493 GetULSpace().GetLower() );
3495 // wird nicht die PageDesc-Tabelle ausgegeben und gibt es einen
3496 // Nachfolger, dann handelt es sich um die "1.Seite" nach RTF.
3497 sal_Char cTyp = 0;
3498 if( !rRTFWrt.bOutPageDesc && rRTFWrt.pAktPageDesc->GetFollow() &&
3499 rRTFWrt.pAktPageDesc->GetFollow() != rRTFWrt.pAktPageDesc )
3501 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_TITLEPG; //i13107
3502 cTyp = 'f'; // dann FirstPage-Header
3504 else if( !rRTFWrt.pAktPageDesc->IsFooterShared() )
3506 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_FACINGP; //i13107
3507 cTyp = rRTFWrt.bOutLeftHeadFoot ? 'l' : 'r';
3510 rWrt.Strm() << '{'<< pFtNm;
3511 if( cTyp ) rWrt.Strm() << cTyp;
3512 rWrt.Strm() << ' ';
3515 RTFSaveData aSaveData( rRTFWrt, nStart, nEnd );
3516 rRTFWrt.Out_SwDoc( rRTFWrt.pCurPam );
3519 rWrt.Strm() << '}' << SwRTFWriter::sNewLine;
3521 } while( FALSE );
3522 return rWrt;
3525 static Writer& OutRTF_SwFmtPrint( Writer& rWrt, const SfxPoolItem& rHt )
3527 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
3528 if( !rRTFWrt.bRTFFlySyntax && !((const SvxPrintItem&)rHt).GetValue() )
3530 rRTFWrt.bOutFmtAttr = TRUE;
3531 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_FLYPRINT;
3533 return rWrt;
3537 static Writer& OutRTF_SwFmtOpaque( Writer& rWrt, const SfxPoolItem& rHt )
3539 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
3540 if( !rRTFWrt.bRTFFlySyntax && !((const SvxOpaqueItem&)rHt).GetValue() )
3542 rRTFWrt.bOutFmtAttr = TRUE;
3543 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_FLYOPAQUE;
3545 return rWrt;
3549 static Writer& OutRTF_SwFmtProtect( Writer& rWrt, const SfxPoolItem& rHt )
3551 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
3552 if( !rRTFWrt.bRTFFlySyntax )
3554 const SvxProtectItem & rFlyProtect = (const SvxProtectItem&) rHt;
3555 RTFProtect aP( rFlyProtect.IsCntntProtected(),
3556 rFlyProtect.IsSizeProtected(),
3557 rFlyProtect.IsPosProtected() );
3558 rRTFWrt.bOutFmtAttr = TRUE;
3559 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_FLYPRTCTD;
3560 rWrt.OutULong( aP.GetValue() );
3562 return rWrt;
3566 static Writer& OutRTF_SwFmtSurround( Writer& rWrt, const SfxPoolItem& rHt )
3568 const SwFmtSurround& rFlySurround = (const SwFmtSurround&) rHt;
3569 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
3570 if( rRTFWrt.bRTFFlySyntax )
3572 if( SURROUND_NONE == rFlySurround.GetSurround() )
3574 rRTFWrt.bOutFmtAttr = TRUE;
3575 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_NOWRAP;
3578 else
3580 SwSurround eSurround = rFlySurround.GetSurround();
3581 BOOL bGold = SURROUND_IDEAL == eSurround;
3582 if( bGold )
3583 eSurround = SURROUND_PARALLEL;
3584 RTFSurround aMC( bGold, static_cast< BYTE >(eSurround) );
3585 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_FLYMAINCNT;
3586 rWrt.OutULong( aMC.GetValue() );
3587 rRTFWrt.bOutFmtAttr = TRUE;
3589 return rWrt;
3592 static Writer& OutRTF_SwFmtVertOrient ( Writer& rWrt, const SfxPoolItem& rHt )
3594 const SwFmtVertOrient& rFlyVert = (const SwFmtVertOrient&) rHt;
3595 RTFVertOrient aVO( static_cast< USHORT >(rFlyVert.GetVertOrient()), static_cast< USHORT >(rFlyVert.GetRelationOrient()) );
3596 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
3598 if( rRTFWrt.bRTFFlySyntax && rRTFWrt.pFlyFmt )
3600 rRTFWrt.bOutFmtAttr = TRUE;
3601 const char* pOrient;
3602 RndStdIds eAnchor = rRTFWrt.pFlyFmt->GetAnchor().GetAnchorId();
3603 sal_Int16 eOrient = rFlyVert.GetRelationOrient();
3604 if( FLY_PAGE == eAnchor )
3606 if( text::RelOrientation::PAGE_FRAME == eOrient || text::RelOrientation::FRAME == eOrient )
3607 pOrient = OOO_STRING_SVTOOLS_RTF_PVPG;
3608 else
3609 pOrient = OOO_STRING_SVTOOLS_RTF_PVMRG;
3611 else
3612 pOrient = OOO_STRING_SVTOOLS_RTF_PVPARA;
3613 rWrt.Strm() << pOrient;
3615 switch (rFlyVert.GetVertOrient())
3617 case text::VertOrientation::TOP:
3618 case text::VertOrientation::LINE_TOP:
3619 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_POSYT;
3620 break;
3621 case text::VertOrientation::BOTTOM:
3622 case text::VertOrientation::LINE_BOTTOM:
3623 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_POSYB;
3624 break;
3625 case text::VertOrientation::CENTER:
3626 case text::VertOrientation::LINE_CENTER:
3627 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_POSYC;
3628 break;
3629 case text::VertOrientation::NONE:
3630 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_POSY;
3631 rWrt.OutULong(rFlyVert.GetPos());
3632 break;
3633 default:
3634 break;
3637 else if( !rRTFWrt.bRTFFlySyntax )
3639 rRTFWrt.bOutFmtAttr = TRUE;
3640 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_FLYVERT;
3641 rWrt.OutULong( aVO.GetValue() );
3644 return rWrt;
3647 static Writer& OutRTF_SwFmtHoriOrient( Writer& rWrt, const SfxPoolItem& rHt )
3649 const SwFmtHoriOrient& rFlyHori = (const SwFmtHoriOrient&) rHt;
3650 RTFHoriOrient aHO( static_cast< USHORT >(rFlyHori.GetHoriOrient()),
3651 static_cast< USHORT >(rFlyHori.GetRelationOrient()) );
3653 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
3654 if( rRTFWrt.bRTFFlySyntax && rRTFWrt.pFlyFmt )
3656 rRTFWrt.bOutFmtAttr = TRUE;
3657 const char* pS;
3658 RndStdIds eAnchor = rRTFWrt.pFlyFmt->GetAnchor().GetAnchorId();
3659 sal_Int16 eOrient = rFlyHori.GetRelationOrient();
3660 if( FLY_PAGE == eAnchor )
3662 if( text::RelOrientation::PAGE_FRAME == eOrient || text::RelOrientation::FRAME == eOrient )
3663 pS = OOO_STRING_SVTOOLS_RTF_PHPG;
3664 else
3665 pS = OOO_STRING_SVTOOLS_RTF_PHMRG;
3667 else
3668 pS = OOO_STRING_SVTOOLS_RTF_PHCOL;
3669 rWrt.Strm() << pS;
3671 pS = 0;
3672 switch(rFlyHori.GetHoriOrient())
3674 case text::HoriOrientation::RIGHT:
3675 pS = rFlyHori.IsPosToggle() ? OOO_STRING_SVTOOLS_RTF_POSXO : OOO_STRING_SVTOOLS_RTF_POSXR;
3676 break;
3677 case text::HoriOrientation::LEFT:
3678 pS = rFlyHori.IsPosToggle() ? OOO_STRING_SVTOOLS_RTF_POSXI : OOO_STRING_SVTOOLS_RTF_POSXL;
3679 break;
3680 case text::HoriOrientation::CENTER:
3681 pS = OOO_STRING_SVTOOLS_RTF_POSXC;
3682 break;
3683 case text::HoriOrientation::NONE:
3684 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_POSX;
3685 rWrt.OutULong( rFlyHori.GetPos() );
3686 break;
3687 default:
3688 break;
3690 if (pS)
3691 rWrt.Strm() << pS;
3693 else
3695 rRTFWrt.bOutFmtAttr = TRUE;
3696 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_FLYHORZ;
3697 rWrt.OutULong( aHO.GetValue() );
3699 return rWrt;
3702 static Writer& OutRTF_SwFmtAnchor( Writer& rWrt, const SfxPoolItem& rHt )
3704 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
3705 if( !rRTFWrt.bRTFFlySyntax )
3707 const SwFmtAnchor& rAnchor = (const SwFmtAnchor&) rHt;
3708 USHORT nId = static_cast< USHORT >(rAnchor.GetAnchorId());
3709 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_FLYANCHOR;
3710 rWrt.OutULong( nId );
3711 rRTFWrt.bOutFmtAttr = TRUE;
3712 switch( nId )
3714 case FLY_PAGE:
3715 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_FLYPAGE;
3716 rWrt.OutULong( rAnchor.GetPageNum() );
3717 break;
3718 case FLY_AT_CNTNT:
3719 case FLY_IN_CNTNT:
3720 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_FLYCNTNT;
3721 break;
3724 return rWrt;
3729 static Writer& OutRTF_SwFmtBackground( Writer& rWrt, const SfxPoolItem& rHt )
3731 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
3732 // wird das FlyFrmFmt ausgegeben, dann Background nur ausgeben, wenn
3733 // RTF-Syntax gesetzt ist !
3734 if( !rRTFWrt.pFlyFmt || !rRTFWrt.bRTFFlySyntax )
3736 const SvxBrushItem& rBack = (const SvxBrushItem&)rHt;
3737 if( !rBack.GetColor().GetTransparency() )
3739 ByteString sOut( OOO_STRING_SVTOOLS_RTF_CBPAT );
3740 sOut += ByteString::CreateFromInt32(
3741 rRTFWrt.GetId( rBack.GetColor() ));
3743 if( rRTFWrt.pFlyFmt || rRTFWrt.bOutPageDesc )
3745 rWrt.Strm() << '{' << sOut.GetBuffer() << '}';
3747 else
3749 rRTFWrt.bOutFmtAttr = TRUE;
3750 rWrt.Strm() << sOut.GetBuffer();
3754 return rWrt;
3758 static Writer& OutRTF_SwFmtShadow( Writer& rWrt, const SfxPoolItem& rHt )
3760 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
3761 // wird das FlyFrmFmt ausgegeben, dann Schatten nur ausgeben, wenn
3762 // nicht RTF-Syntax gesetzt ist !
3763 if( rRTFWrt.pFlyFmt && rRTFWrt.bRTFFlySyntax )
3764 return rWrt;
3766 const SvxShadowItem& rShadow = (const SvxShadowItem&)rHt;
3767 // FALSE wegen schliessender Klammer !!
3768 OutComment( rWrt, OOO_STRING_SVTOOLS_RTF_SHADOW, FALSE );
3769 rWrt.OutULong( rShadow.GetLocation() ) << OOO_STRING_SVTOOLS_RTF_SHDWDIST;
3770 rWrt.OutULong( rShadow.GetWidth() ) << OOO_STRING_SVTOOLS_RTF_SHDWSTYLE;
3771 const Color& rColor = rShadow.GetColor();
3772 rWrt.OutULong( rColor.GetTransparency() ? SW_SV_BRUSH_NULL : SW_SV_BRUSH_SOLID );
3773 rWrt.OutULong( rRTFWrt.GetId( rColor ) ) << OOO_STRING_SVTOOLS_RTF_SHDWFCOL;
3774 rWrt.OutULong( 0 ) << '}';
3775 return rWrt;
3779 static void OutBorderLine( SwRTFWriter& rWrt, const SvxBorderLine* pLine,
3780 const char* pStr )
3782 rWrt.Strm() << pStr << OOO_STRING_SVTOOLS_RTF_BRDLNCOL;
3783 rWrt.OutULong( rWrt.GetId( pLine->GetColor() ) ) << OOO_STRING_SVTOOLS_RTF_BRDLNIN;
3784 rWrt.OutULong( pLine->GetInWidth() ) << OOO_STRING_SVTOOLS_RTF_BRDLNOUT;
3785 rWrt.OutULong( pLine->GetOutWidth() ) << OOO_STRING_SVTOOLS_RTF_BRDLNDIST;
3786 rWrt.OutULong( pLine->GetDistance() );
3790 static Writer& OutRTF_SwFmtBox( Writer& rWrt, const SfxPoolItem& rHt )
3792 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
3794 const SvxBoxItem& rBox = (const SvxBoxItem&)rHt;
3796 static USHORT __READONLY_DATA aBorders[] = {
3797 BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT };
3798 #ifdef __MINGW32__ // for runtime pseudo reloc
3799 static const sal_Char* aBorderNames[] = {
3800 #else
3801 static const sal_Char* __READONLY_DATA aBorderNames[] = {
3802 #endif
3803 OOO_STRING_SVTOOLS_RTF_BRDRT, OOO_STRING_SVTOOLS_RTF_BRDRL, OOO_STRING_SVTOOLS_RTF_BRDRB, OOO_STRING_SVTOOLS_RTF_BRDRR };
3805 USHORT nDist = rBox.GetDistance();
3807 // wird das FlyFrmFmt ausgegeben, dann Border nur ausgeben, wenn
3808 // nicht RTF-Syntax gesetzt ist!
3809 if( rRTFWrt.pFlyFmt && rRTFWrt.bRTFFlySyntax )
3812 RTF kennt keine Rahmen Umrandung!
3813 // die normale RTF-Definition
3814 if( rBox.GetTop() && rBox.GetBottom() &&
3815 rBox.GetLeft() && rBox.GetRight() &&
3816 *rBox.GetTop() == *rBox.GetBottom() &&
3817 *rBox.GetTop() == *rBox.GetLeft() &&
3818 *rBox.GetTop() == *rBox.GetRight() )
3819 OutBorderLine( rRTFWrt, rBox.GetTop(), OOO_STRING_SVTOOLS_RTF_BOX, nDist );
3820 else
3822 OUT_BRDLINE( rBox.GetTop(), OOO_STRING_SVTOOLS_RTF_BRDRT, nDist );
3823 OUT_BRDLINE( rBox.GetBottom(), OOO_STRING_SVTOOLS_RTF_BRDRB, nDist );
3824 OUT_BRDLINE( rBox.GetLeft(), OOO_STRING_SVTOOLS_RTF_BRDRL, nDist );
3825 OUT_BRDLINE( rBox.GetRight(), OOO_STRING_SVTOOLS_RTF_BRDRR, nDist );
3828 return rWrt;
3830 else if( !rRTFWrt.pFlyFmt )
3832 // erst die normale RTF-Definition, dann unsere eigene
3833 if( rBox.GetTop() && rBox.GetBottom() &&
3834 rBox.GetLeft() && rBox.GetRight() &&
3835 *rBox.GetTop() == *rBox.GetBottom() &&
3836 *rBox.GetTop() == *rBox.GetLeft() &&
3837 *rBox.GetTop() == *rBox.GetRight() &&
3838 nDist == rBox.GetDistance( BOX_LINE_TOP ) &&
3839 nDist == rBox.GetDistance( BOX_LINE_LEFT ) &&
3840 nDist == rBox.GetDistance( BOX_LINE_BOTTOM ) &&
3841 nDist == rBox.GetDistance( BOX_LINE_RIGHT ))
3842 OutBorderLine( rRTFWrt, rBox.GetTop(), OOO_STRING_SVTOOLS_RTF_BOX, nDist );
3843 else
3845 const USHORT* pBrd = aBorders;
3846 const sal_Char** pBrdNms = (const sal_Char**)aBorderNames;
3847 for(int i = 0; i < 4; ++i, ++pBrd, ++pBrdNms)
3849 if (const SvxBorderLine* pLn = rBox.GetLine(*pBrd))
3851 OutBorderLine(rRTFWrt, pLn, *pBrdNms,
3852 rBox.GetDistance(*pBrd));
3858 const USHORT* pBrd = aBorders;
3859 const sal_Char** pBrdNms = (const sal_Char**)aBorderNames;
3860 for( int i = 0; i < 4; ++i, ++pBrd, ++pBrdNms )
3862 const SvxBorderLine* pLn = rBox.GetLine( *pBrd );
3863 if( pLn )
3865 rWrt.Strm() << '{' << OOO_STRING_SVTOOLS_RTF_IGNORE;
3866 OutBorderLine( rRTFWrt, pLn, *pBrdNms );
3867 rWrt.Strm() << '}' << OOO_STRING_SVTOOLS_RTF_BRSP;
3868 rWrt.OutULong( rBox.GetDistance( *pBrd ));
3872 rRTFWrt.bOutFmtAttr = FALSE;
3873 return rWrt;
3876 static Writer& OutRTF_SwFmtCol( Writer& rWrt, const SfxPoolItem& rHt )
3878 SwRTFWriter& rRTFWrt = ((SwRTFWriter&)rWrt);
3879 if( rRTFWrt.pFlyFmt && rRTFWrt.bRTFFlySyntax )
3880 return rWrt;
3882 const SwFmtCol& rCol = (const SwFmtCol&)rHt;
3883 const SwColumns& rColumns = rCol.GetColumns();
3885 USHORT nCols = rColumns.Count();
3886 if( 1 < nCols )
3888 // dann besorge mal die Seitenbreite ohne Raender !!
3889 const SwFrmFmt* pFmt;
3891 if( rRTFWrt.pFlyFmt )
3892 pFmt = rRTFWrt.pFlyFmt;
3893 else if( rRTFWrt.pAktPageDesc )
3894 pFmt = &rRTFWrt.pAktPageDesc->GetMaster();
3895 else
3896 pFmt = &const_cast<const SwDoc *>(rWrt.pDoc)
3897 ->GetPageDesc(0).GetMaster();
3899 const SvxLRSpaceItem& rLR = pFmt->GetLRSpace();
3901 USHORT nPageSize = static_cast< USHORT >( pFmt->GetFrmSize().GetWidth() -
3902 rLR.GetLeft() - rLR.GetRight() );
3904 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_COLS;
3905 rWrt.OutLong( nCols );
3907 if( rCol.IsOrtho() )
3909 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_COLSX;
3910 rWrt.OutLong( rCol.GetGutterWidth( TRUE ) );
3912 else
3913 for( USHORT n = 0; n < nCols; )
3915 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_COLNO;
3916 rWrt.OutLong( n+1 );
3918 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_COLW;
3919 rWrt.OutLong( rCol.CalcPrtColWidth( n, nPageSize ) );
3920 if( ++n != nCols )
3922 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_COLSR;
3923 rWrt.OutLong( rColumns[ n-1 ]->GetRight() +
3924 rColumns[ n ]->GetLeft() );
3927 ((SwRTFWriter&)rWrt).bOutFmtAttr = TRUE;
3929 return rWrt;
3932 static Writer& OutRTF_SvxFmtKeep( Writer& rWrt, const SfxPoolItem& rHt )
3934 const SvxFmtKeepItem& rItem = (const SvxFmtKeepItem&)rHt;
3935 if( rItem.GetValue() )
3937 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_KEEPN;
3938 ((SwRTFWriter&)rWrt).bOutFmtAttr = TRUE;
3940 return rWrt;
3943 static Writer& OutRTF_SvxFrmDir( Writer& rWrt, const SfxPoolItem& rHt )
3945 SwRTFWriter& rRTFWrt = ((SwRTFWriter&)rWrt);
3946 if (rRTFWrt.pFlyFmt || rRTFWrt.bOutPageDesc)
3947 OutSvxFrmDir(rRTFWrt, rHt);
3948 return rWrt;
3951 /* File GRFATR.HXX */
3953 static Writer& OutRTF_SwMirrorGrf( Writer& rWrt, const SfxPoolItem& rHt )
3955 const SwMirrorGrf & rMirror = (const SwMirrorGrf&)rHt;
3956 if( RES_MIRROR_GRAPH_DONT == rMirror.GetValue() )
3957 return rWrt;
3959 ((SwRTFWriter&)rWrt).bOutFmtAttr = TRUE;
3960 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_IGNORE << OOO_STRING_SVTOOLS_RTF_GRFMIRROR;
3961 rWrt.OutULong( rMirror.GetValue() );
3962 return rWrt;
3965 static Writer& OutRTF_SwCropGrf( Writer& rWrt, const SfxPoolItem& rHt )
3967 const SwCropGrf & rCrop = (const SwCropGrf&)rHt;
3968 ByteString aStr;
3969 if( rCrop.GetLeft() )
3970 ( aStr += OOO_STRING_SVTOOLS_RTF_PICCROPL ) +=
3971 ByteString::CreateFromInt32( (short)rCrop.GetLeft() );
3972 if( rCrop.GetRight() )
3973 ( aStr += OOO_STRING_SVTOOLS_RTF_PICCROPR ) +=
3974 ByteString::CreateFromInt32( (short)rCrop.GetRight() );
3975 if( rCrop.GetTop() )
3976 ( aStr += OOO_STRING_SVTOOLS_RTF_PICCROPT ) +=
3977 ByteString::CreateFromInt32( (short)rCrop.GetTop() );
3978 if( rCrop.GetBottom() )
3979 ( aStr += OOO_STRING_SVTOOLS_RTF_PICCROPB ) +=
3980 ByteString::CreateFromInt32( (short)rCrop.GetBottom() );
3981 if( aStr.Len() )
3983 ((SwRTFWriter&)rWrt).bOutFmtAttr = TRUE;
3984 rWrt.Strm() << aStr.GetBuffer();
3986 return rWrt;
3991 /* File PARATR.HXX */
3993 static Writer& OutRTF_SwLineSpacing( Writer& rWrt, const SfxPoolItem& rHt )
3995 const SvxLineSpacingItem &rLs = (const SvxLineSpacingItem&)rHt;
3997 switch (rLs.GetLineSpaceRule())
3999 default:
4000 break;
4001 case SVX_LINE_SPACE_AUTO:
4002 case SVX_LINE_SPACE_FIX:
4003 case SVX_LINE_SPACE_MIN:
4005 ((SwRTFWriter&)rWrt).bOutFmtAttr = TRUE;
4006 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_SL;
4007 sal_Char cMult = '0';
4008 switch (rLs.GetInterLineSpaceRule())
4010 case SVX_INTER_LINE_SPACE_FIX:
4011 // unser Durchschuss gibt es aber nicht in WW - also wie
4012 // kommt man an die MaxLineHeight heran?
4013 rWrt.OutLong((short)rLs.GetInterLineSpace());
4014 break;
4015 case SVX_INTER_LINE_SPACE_PROP:
4016 rWrt.OutLong((240L * rLs.GetPropLineSpace()) / 100L);
4017 cMult = '1';
4018 break;
4019 default:
4020 if (SVX_LINE_SPACE_FIX == rLs.GetLineSpaceRule())
4021 rWrt.Strm() << '-';
4022 rWrt.OutLong( rLs.GetLineHeight() );
4023 break;
4025 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_SLMULT << cMult;
4027 break;
4029 return rWrt;
4032 static Writer& OutRTF_SwAdjust( Writer& rWrt, const SfxPoolItem& rHt )
4034 const SvxAdjustItem & rAdjust = ((const SvxAdjustItem&)rHt);
4035 ByteString aAttr( "\\q" );
4036 switch( rAdjust.GetAdjust() )
4038 case SVX_ADJUST_LEFT: aAttr += 'l'; break;
4039 case SVX_ADJUST_RIGHT: aAttr += 'r'; break;
4040 case SVX_ADJUST_BLOCKLINE:
4041 case SVX_ADJUST_BLOCK: aAttr += 'j'; break;
4042 case SVX_ADJUST_CENTER: aAttr += 'c'; break;
4044 default:
4045 return rWrt; // kein gueltiges Attriut, also returnen
4047 ((SwRTFWriter&)rWrt).bOutFmtAttr = TRUE;
4048 rWrt.Strm() << aAttr.GetBuffer();
4049 return rWrt;
4052 static Writer& OutRTF_SvxFmtSplit( Writer& rWrt, const SfxPoolItem& rHt )
4054 const SvxFmtSplitItem& rItem = (const SvxFmtSplitItem&)rHt;
4055 if( !rItem.GetValue() )
4057 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_KEEP;
4058 ((SwRTFWriter&)rWrt).bOutFmtAttr = TRUE;
4060 return rWrt;
4063 static Writer& OutRTF_SwTabStop( Writer& rWrt, const SfxPoolItem& rHt )
4065 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
4066 const SvxTabStopItem & rTStops = (const SvxTabStopItem&)rHt;
4067 long nOffset = ((SvxLRSpaceItem&)rRTFWrt.GetItem( RES_LR_SPACE )).GetTxtLeft();
4068 for( USHORT n = 0; n < rTStops.Count(); n++ )
4070 const SvxTabStop & rTS = rTStops[ n ];
4071 if( SVX_TAB_ADJUST_DEFAULT != rTS.GetAdjustment() )
4073 BOOL bOutDecimal = TRUE;
4074 const char* pFill = 0;
4075 switch( rTS.GetFill() )
4077 case cDfltFillChar:
4078 break;
4080 case '.': pFill = OOO_STRING_SVTOOLS_RTF_TLDOT; break;
4081 case '_': pFill = OOO_STRING_SVTOOLS_RTF_TLUL; break;
4082 case '-': pFill = OOO_STRING_SVTOOLS_RTF_TLTH; break;
4083 case '=': pFill = OOO_STRING_SVTOOLS_RTF_TLEQ; break;
4084 default:
4085 if( !rRTFWrt.bWriteHelpFmt )
4087 OutComment( rWrt, OOO_STRING_SVTOOLS_RTF_TLSWG, FALSE );
4088 rWrt.OutULong( (((USHORT)rTS.GetFill()) << 8 ) +
4089 rTS.GetDecimal() )
4090 << '}';
4091 bOutDecimal = FALSE;
4094 if( pFill )
4095 rWrt.Strm() << pFill;
4097 if( !rRTFWrt.bWriteHelpFmt && bOutDecimal &&
4098 rTS.GetDecimal() != ((SvxTabStopItem&)*GetDfltAttr(
4099 RES_PARATR_TABSTOP ))[ 0 ].GetDecimal() )
4101 OutComment( rWrt, OOO_STRING_SVTOOLS_RTF_TLSWG, FALSE );
4102 rWrt.OutULong( (((USHORT)rTS.GetFill()) << 8 ) +
4103 rTS.GetDecimal() ) << '}';
4106 const sal_Char* pAdjStr = 0;
4107 switch (rTS.GetAdjustment())
4109 case SVX_TAB_ADJUST_RIGHT:
4110 pAdjStr = OOO_STRING_SVTOOLS_RTF_TQR;
4111 break;
4112 case SVX_TAB_ADJUST_DECIMAL:
4113 pAdjStr = OOO_STRING_SVTOOLS_RTF_TQDEC;
4114 break;
4115 case SVX_TAB_ADJUST_CENTER:
4116 pAdjStr = OOO_STRING_SVTOOLS_RTF_TQC;
4117 break;
4118 default:
4119 break;
4121 if (pAdjStr)
4122 rWrt.Strm() << pAdjStr;
4123 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_TX;
4124 rWrt.OutLong(rTS.GetTabPos() + nOffset);
4127 rRTFWrt.bOutFmtAttr = TRUE;
4128 return rWrt;
4131 static Writer& OutRTF_SwHypenZone( Writer& rWrt, const SfxPoolItem& rHt )
4133 if( !((SwRTFWriter&)rWrt).bWriteHelpFmt )
4135 const SvxHyphenZoneItem& rAttr = (const SvxHyphenZoneItem&)rHt;
4136 USHORT nFlags = rAttr.IsHyphen() ? 1 : 0;
4137 if( rAttr.IsPageEnd() ) nFlags += 2;
4139 OutComment( rWrt, OOO_STRING_SVTOOLS_RTF_HYPHEN, FALSE );
4140 rWrt.OutULong( nFlags ) << OOO_STRING_SVTOOLS_RTF_HYPHLEAD;
4141 rWrt.OutULong( rAttr.GetMinLead() ) << OOO_STRING_SVTOOLS_RTF_HYPHTRAIL;
4142 rWrt.OutULong( rAttr.GetMinTrail() ) << OOO_STRING_SVTOOLS_RTF_HYPHMAX;
4143 rWrt.OutULong( rAttr.GetMaxHyphens() ) << '}';
4145 return rWrt;
4148 static Writer& OutRTF_SwNumRule( Writer& rWrt, const SfxPoolItem& rHt )
4150 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
4151 if( !rRTFWrt.bOutListNumTxt )
4153 const SwNumRuleItem& rAttr = (const SwNumRuleItem&)rHt;
4154 USHORT nId;
4155 if( rAttr.GetValue().Len() &&
4156 USHRT_MAX != (nId = rRTFWrt.GetId( rAttr ) ))
4158 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_LS;
4159 rWrt.OutULong( nId );
4160 rRTFWrt.bOutFmtAttr = TRUE;
4163 return rWrt;
4166 static Writer& OutRTF_SwScriptSpace( Writer& rWrt, const SfxPoolItem& rHt )
4168 if( ((const SvxScriptSpaceItem&)rHt).GetValue() )
4170 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_ASPALPHA;
4171 ((SwRTFWriter&)rWrt).bOutFmtAttr = TRUE;
4173 return rWrt;
4175 static Writer& OutRTF_SwHangPunctuation( Writer& rWrt, const SfxPoolItem& rHt )
4177 if( !((const SvxHangingPunctuationItem&)rHt).GetValue() )
4179 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_NOOVERFLOW;
4180 ((SwRTFWriter&)rWrt).bOutFmtAttr = TRUE;
4182 return rWrt;
4184 static Writer& OutRTF_SwForbiddenRule( Writer& rWrt, const SfxPoolItem& rHt )
4186 if( !((const SvxForbiddenRuleItem&)rHt).GetValue() )
4188 rWrt.Strm() << OOO_STRING_SVTOOLS_RTF_NOCWRAP;
4189 ((SwRTFWriter&)rWrt).bOutFmtAttr = TRUE;
4191 return rWrt;
4194 static Writer& OutRTF_SwFontAlign( Writer& rWrt, const SfxPoolItem& rHt )
4196 SwRTFWriter& rRTFWrt = (SwRTFWriter&)rWrt;
4197 const SvxParaVertAlignItem & rAttr = (const SvxParaVertAlignItem &)rHt;
4198 const char* pStr;
4199 switch ( rAttr.GetValue() )
4201 case SvxParaVertAlignItem::TOP: pStr = OOO_STRING_SVTOOLS_RTF_FAHANG; break;
4202 case SvxParaVertAlignItem::BOTTOM: pStr = OOO_STRING_SVTOOLS_RTF_FAVAR; break;
4203 case SvxParaVertAlignItem::CENTER: pStr = OOO_STRING_SVTOOLS_RTF_FACENTER; break;
4204 case SvxParaVertAlignItem::BASELINE: pStr = OOO_STRING_SVTOOLS_RTF_FAROMAN; break;
4206 // case SvxParaVertAlignItem::AUTOMATIC:
4207 default: pStr = OOO_STRING_SVTOOLS_RTF_FAAUTO; break;
4209 rWrt.Strm() << pStr;
4210 rRTFWrt.bOutFmtAttr = TRUE;
4211 return rWrt;
4215 * lege hier die Tabellen fuer die RTF-Funktions-Pointer auf
4216 * die Ausgabe-Funktionen an.
4217 * Es sind lokale Strukturen, die nur innerhalb der RTF-DLL
4218 * bekannt sein muessen.
4221 SwAttrFnTab aRTFAttrFnTab = {
4222 /* RES_CHRATR_CASEMAP */ OutRTF_SwCaseMap,
4223 /* RES_CHRATR_CHARSETCOLOR */ 0,
4224 /* RES_CHRATR_COLOR */ OutRTF_SwColor,
4225 /* RES_CHRATR_CONTOUR */ OutRTF_SwContour,
4226 /* RES_CHRATR_CROSSEDOUT */ OutRTF_SwCrossedOut,
4227 /* RES_CHRATR_ESCAPEMENT */ OutRTF_SwEscapement,
4228 /* RES_CHRATR_FONT */ OutRTF_SwFont,
4229 /* RES_CHRATR_FONTSIZE */ OutRTF_SwSize,
4230 /* RES_CHRATR_KERNING */ 0, // NOT USED!! OutRTF_SwKerning,
4231 /* RES_CHRATR_LANGUAGE */ OutRTF_SwLanguage,
4232 /* RES_CHRATR_POSTURE */ OutRTF_SwPosture,
4233 /* RES_CHRATR_PROPORTIONALFONTSIZE*/0,
4234 /* RES_CHRATR_SHADOWED */ OutRTF_SwShadowed,
4235 /* RES_CHRATR_UNDERLINE */ OutRTF_SwUnderline,
4236 /* RES_CHRATR_WEIGHT */ OutRTF_SwWeight,
4237 /* RES_CHRATR_WORDLINEMODE */ 0, // Neu: Wortweises Unter-/Durchstreichen
4238 /* RES_CHRATR_AUTOKERN */ 0, // Neu: Automatisches Pairkerning
4239 /* RES_CHRATR_BLINK */ 0, // Neu: Blinkender Text
4240 /* RES_CHRATR_NOHYPHEN */ 0, // Neu: nicht trennen
4241 /* RES_CHRATR_NOLINEBREAK */ 0, // Neu: nicht umbrechen
4242 /* RES_CHRATR_BACKGROUND */ OutRTF_SwChrBckgrnd, // Neu: Zeichenhintergrund
4243 /* RES_CHRATR_CJK_FONT */ OutRTF_SwFont,
4244 /* RES_CHRATR_CJK_FONTSIZE */ OutRTF_SwSize,
4245 /* RES_CHRATR_CJK_LANGUAGE */ OutRTF_SwLanguage,
4246 /* RES_CHRATR_CJK_POSTURE */ OutRTF_SwPosture,
4247 /* RES_CHRATR_CJK_WEIGHT */ OutRTF_SwWeight,
4248 /* RES_CHRATR_CTL_FONT */ OutRTF_SwFont,
4249 /* RES_CHRATR_CTL_FONTSIZE */ OutRTF_SwSize,
4250 /* RES_CHRATR_CTL_LANGUAGE */ OutRTF_SwLanguage,
4251 /* RES_CHRATR_CTL_POSTURE */ OutRTF_SwPosture,
4252 /* RES_CHRATR_CTL_WEIGHT */ OutRTF_SwWeight,
4253 /* RES_CHRATR_ROTATE */ OutRTF_SwCharRotate,
4254 /* RES_CHRATR_EMPHASIS_MARK */ OutRTF_SwEmphasisMark,
4255 /* RES_CHRATR_TWO_LINES */ OutRTF_SwTwoInOne,
4256 /* RES_CHRATR_SCALEW */ OutRTF_SwCharScaleW,
4257 /* RES_CHRATR_RELIEF */ OutRTF_SwCharRelief,
4258 /* RES_CHRATR_HIDDEN */ OutRTF_SvxCharHiddenItem,
4259 /* RES_CHRATR_OVERLINE */ OutRTF_SwOverline,
4260 /* RES_CHRATR_DUMMY1 */ 0,
4261 /* RES_CHRATR_DUMMY2 */ 0,
4263 /* RES_TXTATR_AUTOFMT */ OutRTF_SwTxtAutoFmt,
4264 /* RES_TXTATR_INETFMT */ OutRTF_SwTxtINetFmt, // Dummy
4265 /* RES_TXTATR_REFMARK*/ 0, // NOT USED!! OutRTF_SwRefMark,
4266 /* RES_TXTATR_TOXMARK */ 0, // NOT USED!! OutRTF_SwTOXMark,
4267 /* RES_TXTATR_CHARFMT */ OutRTF_SwTxtCharFmt,
4268 /* RES_TXTATR_TWO_LINES */ 0,
4269 /* RES_TXTATR_CJK_RUBY */ OutRTF_SwTxtRuby,
4270 /* RES_TXTATR_UNKNOWN_CONTAINER */ 0,
4271 /* RES_TXTATR_DUMMY5 */ 0,
4272 /* RES_TXTATR_DUMMY6 */ 0,
4274 /* RES_TXTATR_FIELD */ OutRTF_SwField,
4275 /* RES_TXTATR_FLYCNT */ OutRTF_SwFlyCntnt,
4276 /* RES_TXTATR_FTN */ OutRTF_SwFtn,
4277 /* RES_TXTATR_SOFTHYPH */ 0, // old attr. - coded now by character
4278 /* RES_TXTATR_HARDBLANK*/ OutRTF_SwHardBlank,
4279 /* RES_TXTATR_DUMMY1 */ 0, // Dummy:
4280 /* RES_TXTATR_DUMMY2 */ 0, // Dummy:
4282 /* RES_PARATR_LINESPACING */ OutRTF_SwLineSpacing,
4283 /* RES_PARATR_ADJUST */ OutRTF_SwAdjust,
4284 /* RES_PARATR_SPLIT */ OutRTF_SvxFmtSplit,
4285 /* RES_PARATR_WIDOWS */ 0, // NOT USED!! OutRTF_SwWidows,
4286 /* RES_PARATR_ORPHANS */ 0, // NOT USED!! OutRTF_SwOrphans,
4287 /* RES_PARATR_TABSTOP */ OutRTF_SwTabStop,
4288 /* RES_PARATR_HYPHENZONE*/ OutRTF_SwHypenZone,
4289 /* RES_PARATR_DROP */ 0,
4290 /* RES_PARATR_REGISTER */ 0, // neu: Registerhaltigkeit
4291 /* RES_PARATR_NUMRULE */ OutRTF_SwNumRule,
4292 /* RES_PARATR_SCRIPTSPACE */ OutRTF_SwScriptSpace,
4293 /* RES_PARATR_HANGINGPUNCTUATION */ OutRTF_SwHangPunctuation,
4294 /* RES_PARATR_FORBIDDEN_RULE*/ OutRTF_SwForbiddenRule,
4295 /* RES_PARATR_VERTALIGN */ OutRTF_SwFontAlign,
4296 /* RES_PARATR_SNAPTOGRID*/ 0, // new
4297 /* RES_PARATR_CONNECT_TO_BORDER */ 0, // new
4298 /* RES_PARATR_OUTLINELEVEL */ 0, // new - outlinelevel
4300 /* RES_PARATR_LIST_ID */ 0, // new
4301 /* RES_PARATR_LIST_LEVEL */ 0, // new
4302 /* RES_PARATR_LIST_ISRESTART */ 0, // new
4303 /* RES_PARATR_LIST_RESTARTVALUE */ 0, // new
4304 /* RES_PARATR_LIST_ISCOUNTED */ 0, // new
4306 /* RES_FILL_ORDER */ 0, // NOT USED!! OutRTF_SwFillOrder,
4307 /* RES_FRM_SIZE */ OutRTF_SwFrmSize,
4308 /* RES_PAPER_BIN */ 0, // NOT USED!! OutRTF_SwFmtPaperBin,
4309 /* RES_LR_SPACE */ OutRTF_SwFmtLRSpace,
4310 /* RES_UL_SPACE */ OutRTF_SwFmtULSpace,
4311 /* RES_PAGEDESC */ 0,
4312 /* RES_BREAK */ 0,
4313 /* RES_CNTNT */ 0,
4314 /* RES_HEADER */ OutRTF_SwFmtHeader,
4315 /* RES_FOOTER */ OutRTF_SwFmtFooter,
4316 /* RES_PRINT */ OutRTF_SwFmtPrint,
4317 /* RES_OPAQUE */ OutRTF_SwFmtOpaque,
4318 /* RES_PROTECT */ OutRTF_SwFmtProtect,
4319 /* RES_SURROUND */ OutRTF_SwFmtSurround,
4320 /* RES_VERT_ORIENT */ OutRTF_SwFmtVertOrient,
4321 /* RES_HORI_ORIENT */ OutRTF_SwFmtHoriOrient,
4322 /* RES_ANCHOR */ OutRTF_SwFmtAnchor,
4323 /* RES_BACKGROUND */ OutRTF_SwFmtBackground,
4324 /* RES_BOX */ OutRTF_SwFmtBox,
4325 /* RES_SHADOW */ OutRTF_SwFmtShadow,
4326 /* RES_FRMMACRO */ 0, // NOT USED!! OutRTF_SwFmtFrmMacro,
4327 /* RES_COL */ OutRTF_SwFmtCol,
4328 /* RES_KEEP */ OutRTF_SvxFmtKeep,
4329 /* RES_URL */ 0, // URL
4330 /* RES_EDIT_IN_READONLY */ 0,
4331 /* RES_LAYOUT_SPLIT */ 0,
4332 /* RES_FRMATR_DUMMY1 */ 0, // Dummy:
4333 /* RES_FRMATR_DUMMY2 */ 0, // Dummy:
4334 /* RES_AUTO_STYLE */ 0, // Dummy:
4335 /* RES_FRMATR_DUMMY4 */ 0, // Dummy:
4336 /* RES_FRMATR_DUMMY5 */ 0, // Dummy:
4337 /* RES_FRMATR_DUMMY6 */ 0, // Dummy:
4338 /* RES_FRAMEDIR*/ OutRTF_SvxFrmDir,
4339 /* RES_FRMATR_DUMMY8 */ 0, // Dummy:
4340 /* RES_FRMATR_DUMMY9 */ 0, // Dummy:
4341 /* RES_FOLLOW_TEXT_FLOW */ 0,
4342 /* RES_WRAP_INFLUENCE_ON_OBJPOS */ 0,
4343 /* RES_FRMATR_DUMMY2 */ 0, // Dummy:
4344 /* RES_AUTO_STYLE */ 0, // Dummy:
4345 /* RES_FRMATR_DUMMY4 */ 0, // Dummy:
4346 /* RES_FRMATR_DUMMY5 */ 0, // Dummy:
4348 /* RES_GRFATR_MIRRORGRF */ OutRTF_SwMirrorGrf,
4349 /* RES_GRFATR_CROPGRF */ OutRTF_SwCropGrf,
4350 /* RES_GRFATR_ROTATION */ 0,
4351 /* RES_GRFATR_LUMINANCE */ 0,
4352 /* RES_GRFATR_CONTRAST */ 0,
4353 /* RES_GRFATR_CHANNELR */ 0,
4354 /* RES_GRFATR_CHANNELG */ 0,
4355 /* RES_GRFATR_CHANNELB */ 0,
4356 /* RES_GRFATR_GAMMA */ 0,
4357 /* RES_GRFATR_INVERT */ 0,
4358 /* RES_GRFATR_TRANSPARENCY */ 0,
4359 /* RES_GRFATR_DRWAMODE */ 0,
4360 /* RES_GRFATR_DUMMY1 */ 0,
4361 /* RES_GRFATR_DUMMY2 */ 0,
4362 /* RES_GRFATR_DUMMY3 */ 0,
4363 /* RES_GRFATR_DUMMY4 */ 0,
4364 /* RES_GRFATR_DUMMY5 */ 0,
4366 /* RES_BOXATR_FORMAT */ 0,
4367 /* RES_BOXATR_FORMULA */ 0,
4368 /* RES_BOXATR_VALUE */ 0,
4370 /* RES_UNKNOWNATR_CONTAINER */ 0
4373 SwNodeFnTab aRTFNodeFnTab = {
4374 /* RES_TXTNODE */ OutRTF_SwTxtNode,
4375 /* RES_GRFNODE */ OutRTF_SwGrfNode,
4376 /* RES_OLENODE */ OutRTF_SwOLENode
4379 /* vi:set tabstop=4 shiftwidth=4 expandtab: */